Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 11 additions & 4 deletions next.config.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
import type { NextConfig } from "next";
import type { NextConfig } from "next"

const nextConfig: NextConfig = {
/* config options here */
};
async rewrites() {
return [
{
source: "/api/:path*",
destination: "http://localhost:300/:path*",
},
]
},
}

export default nextConfig;
export default nextConfig
10 changes: 9 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,17 @@
"lint": "eslint"
},
"dependencies": {
"@iconify/react": "^6.0.2",
"axios": "^1.13.2",
"framer-motion": "^12.23.24",
"ionicons": "^8.0.13",
"motion": "^12.23.24",
"next": "16.0.3",
"react": "19.2.0",
"react-dom": "19.2.0"
"react-dom": "19.2.0",
"react-form-stepper": "^2.0.3",
"swiper": "^12.0.3",
"utils": "link:@/lib/utils"
},
"devDependencies": {
"@tailwindcss/postcss": "^4",
Expand Down
562 changes: 562 additions & 0 deletions pnpm-lock.yaml

Large diffs are not rendered by default.

19 changes: 19 additions & 0 deletions src/app/(auth)/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { ImageSlider } from "@/src/components/common/ImageSlider/ImageSlider"
import { RadialDecorator } from "@/src/components/common/RadialDecorator/RadialDecorator"
import React from "react"

const Layout = ({ children }: { children: React.ReactNode }) => {
return (
<div className="relative">
<RadialDecorator />
<section className="max-w-screen h-screen grid grid-cols-2 gap-10 mx-10 my-10 px-20 absolute top-0">
<ImageSlider />
<div className="bg-[#448850] h-[90%] rounded-3xl shadow-2xl shadow-lime-950 ">
<div>{children}</div>
</div>
</section>
</div>
)
}

export default Layout
12 changes: 12 additions & 0 deletions src/app/(auth)/login/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { Container } from "@/src/components/common/Container/Container"
import { LoginComponent } from "@/src/components/login/LoginComponent"

const Login = () => {
return (
<Container>
<LoginComponent />
</Container>
)
}

export default Login
12 changes: 12 additions & 0 deletions src/app/(auth)/register/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { Container } from "@/src/components/common/Container/Container"
import { RegisterComponent } from "@/src/components/register/RegisterComponent"

const Register = () => {
return (
<Container>
<RegisterComponent />
</Container>
)
}

export default Register
5 changes: 4 additions & 1 deletion src/app/globals.css
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
@import "tailwindcss";
/* to use the different swiper js modules */
@import "swiper/css/pagination";
@import "swiper/css";

:root {
--background: #ffffff;
Expand All @@ -14,7 +17,7 @@

@media (prefers-color-scheme: dark) {
:root {
--background: #0a0a0a;
--background: #e0e1d8;
--foreground: #ededed;
}
}
Expand Down
14 changes: 7 additions & 7 deletions src/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,26 @@
import type { Metadata } from "next";
import { Geist, Geist_Mono } from "next/font/google";
import "./globals.css";
import type { Metadata } from "next"
import { Geist, Geist_Mono } from "next/font/google"
import "./globals.css"

const primary = Geist({
variable: "--font-geist-sans",
subsets: ["latin"],
});
})

const secondary = Geist_Mono({
variable: "--font-geist-mono",
subsets: ["latin"],
});
})

export const metadata: Metadata = {
title: "URL Shortener Frontend",
description: "Created the frontend for the URL Shortener Project",
};
}

export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
children: React.ReactNode
}>) {
return (
<html lang="en">
Expand Down
6 changes: 4 additions & 2 deletions src/app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
export default function Home() {
return (
<>Login Page</>
);
<>
Hello User
</>
)
}
7 changes: 7 additions & 0 deletions src/components/common/Button/Button.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export const Button = ({ children }: { children: React.ReactNode }) => {
return (
<button className="bg-[#2F2E43] border-2 border-cyan-800 text-white border-l rounded-3xl px-10 py-2 w-40 h-14 mx-auto">
{children}
</button>
)
}
7 changes: 7 additions & 0 deletions src/components/common/Container/Container.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import React from "react"

export const Container = ({ children }: { children: React.ReactNode }) => {
return (
<article className="flex flex-col gap-5 py-10 px-20">{children}</article>
)
}
44 changes: 44 additions & 0 deletions src/components/common/ImageSlider/ImageSlider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
"use client"
import Image from "next/image"
import { Autoplay, Pagination } from "swiper/modules"
import { Swiper, SwiperSlide } from "swiper/react"
import { motion } from "framer-motion"

const slide = [
{ image: "/login.svg", alt: "login" },
{ image: "/enter.svg", alt: "entry" },
{ image: "/welcome.svg", alt: "welcome" },
{ image: "/join.svg", alt: "join" },
]

export const ImageSlider = () => {
return (
<motion.div
className="w-full max-w-[600px] min-w-[300px] h-[800px] min-h-[500px] lg:h-[90vh] 2xl:h-[80vh] rounded-[20px] overflow-hidden"
initial={{ x: -50, opacity: 0.5 }}
animate={{ x: 0, opacity: 1 }}
transition={{ duration: 0.6, delay: 0.3, ease: "easeOut" }}
>
<Swiper
modules={[Autoplay, Pagination]}
autoplay={{ delay: 1500, disableOnInteraction: false }}
pagination={{ clickable: true }}
loop={true}
>
{slide.map((slide) => (
<SwiperSlide key={slide.alt}>
<div className="w-full h-full">
<Image
width={500}
height={950}
src={slide.image}
alt={slide.alt}
/>
</div>
</SwiperSlide>
))}
</Swiper>
</motion.div>
)
}

33 changes: 33 additions & 0 deletions src/components/common/InputField/InputField.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { Icon } from "@iconify/react"

export const InputField = ({
labelName,
name,
type,
icon,
placeholder,
}: {
name: string
labelName: string
icon: string
type?: string
placeholder: string
}) => {
return (
<div>
<label
htmlFor={name}
className="text-shadow-md text-shadow-lime-950 flex flex-row gap-2 items-center"
>
<Icon icon={icon} width={16} height={16} className="text-[#2F2E43]" />
{labelName}
</label>
<input
name={name}
type={type}
placeholder={placeholder}
className="flex h-12 w-full my-2 rounded-md border-2 border-[#2F2E43] shadow-md shadow-lime-950 bg-[#e0e1d8] text-[#2F2E43] font-light px-3 py-2 text-sm placeholder:text-[#716f91] placeholder:text-xs"
/>
</div>
)
}
70 changes: 70 additions & 0 deletions src/components/common/RadialDecorator/RadialDecorator.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
"use client"
import { motion } from "framer-motion"

export const RadialDecorator = () => {
return (
<section className="relative">
<div className="absolute top-0">
<motion.article
initial={{ scale: 1, opacity: 0 }}
animate={{ scale: [1, 0.8, 1], opacity: 1, rotate: [0, 360] }}
transition={{
duration: 5,
delay: 0,
ease: "easeInOut",
repeat: Infinity,
repeatType: "loop",
}}
className="relative min-w-screen min-h-screen"
>
<div className="size-18 rounded-full bg-radial-[at_50%_50%] from-[#e0e1d8] via-[#e5e7d6] to-[#448850] to-90% absolute left-10 top-15 z-0"></div>
<div className="size-50 rounded-full bg-radial-[at_50%_50%] from-[#e0e1d8] via-[#e5e7d6] to-[#448850] to-90% absolute left-20 top-55 z-0"></div>
<div className="size-30 rounded-full bg-radial-[at_50%_50%] from-[#e0e1d8] via-[#e5e7d6] to-[#448850] to-90% absolute right-50 top-5 z-0"></div>
<div className="size-10 rounded-full bg-radial-[at_50%_50%] from-[#e0e1d8] via-[#e5e7d6] to-[#448850] to-90% absolute right-0 top-35 z-0"></div>
<div className="size-50 rounded-full bg-radial-[at_50%_50%] from-[#e0e1d8] via-[#e5e7d6] to-[#448850] to-90% absolute left-100 top-0 z-0"></div>
<div className="size-15 rounded-full bg-radial-[at_50%_50%] from-[#e0e1d8] via-[#e5e7d6] to-[#448850] to-90% absolute right-70 top-85 z-0"></div>
<div className="size-5 rounded-full bg-radial-[at_50%_50%] from-[#e0e1d8] via-[#e5e7d6] to-[#448850] to-90% absolute right-40 top-100 z-0"></div>
<div className="size-5 rounded-full bg-radial-[at_50%_50%] from-[#e0e1d8] via-[#e5e7d6] to-[#448850] to-90% absolute left-60 top-13 z-0"></div>
<div className="size-70 rounded-full bg-radial-[at_50%_50%] from-[#e0e1d8] via-[#e5e7d6] to-[#448850] to-90% absolute right-100 top-65 z-0"></div>
<div className="size-35 rounded-full bg-radial-[at_50%_50%] from-[#e0e1d8] via-[#e5e7d6] to-[#448850] to-90% absolute left-80 top-90 z-0"></div>
<div className="size-25 rounded-full bg-radial-[at_50%_50%] from-[#e0e1d8] via-[#e5e7d6] to-[#448850] to-90% absolute right-30 top-66 z-0"></div>
<div className="size-45 rounded-full bg-radial-[at_50%_50%] from-[#e0e1d8] via-[#e5e7d6] to-[#448850] to-90% absolute right-55 bottom-20 z-0"></div>
<div className="size-18 rounded-full bg-radial-[at_50%_50%] from-[#e0e1d8] via-[#e5e7d6] to-[#448850] to-90% absolute right-10 top-15 z-0"></div>
<div className="size-18 rounded-full bg-radial-[at_50%_50%] from-[#e0e1d8] via-[#e5e7d6] to-[#448850] to-90% absolute right-10 top-100 z-0"></div>
<div className="size-25 rounded-full bg-radial-[at_50%_50%] from-[#e0e1d8] via-[#e5e7d6] to-[#448850] to-90% absolute left-30 bottom-10 z-0"></div>
</motion.article>
</div>
<div className="absolute top-0">
<motion.article
initial={{ scale: 1, opacity: 1 }}
animate={{ scale: [1, 0.5, 1], opacity: 0, rotate: [360, 0] }}
transition={{
duration: 8,
delay: 0,
ease: "easeInOut",
repeat: Infinity,
repeatType: "loop",
}}
className="relative min-w-screen min-h-screen"
>
<div className="size-18 rounded-full bg-radial-[at_50%_50%] from-[#e0e1d8] via-[#e5e7d6] to-[#448850] to-90% absolute left-10 top-15 z-0"></div>
<div className="size-50 rounded-full bg-radial-[at_50%_50%] from-[#e0e1d8] via-[#e5e7d6] to-[#448850] to-90% absolute left-20 top-55 z-0"></div>
<div className="size-30 rounded-full bg-radial-[at_50%_50%] from-[#e0e1d8] via-[#e5e7d6] to-[#448850] to-90% absolute right-50 top-5 z-0"></div>
<div className="size-10 rounded-full bg-radial-[at_50%_50%] from-[#e0e1d8] via-[#e5e7d6] to-[#448850] to-90% absolute right-0 top-35 z-0"></div>
<div className="size-50 rounded-full bg-radial-[at_50%_50%] from-[#e0e1d8] via-[#e5e7d6] to-[#448850] to-90% absolute left-100 top-0 z-0"></div>
<div className="size-15 rounded-full bg-radial-[at_50%_50%] from-[#e0e1d8] via-[#e5e7d6] to-[#448850] to-90% absolute right-70 top-85 z-0"></div>
<div className="size-5 rounded-full bg-radial-[at_50%_50%] from-[#e0e1d8] via-[#e5e7d6] to-[#448850] to-90% absolute right-40 top-100 z-0"></div>
<div className="size-5 rounded-full bg-radial-[at_50%_50%] from-[#e0e1d8] via-[#e5e7d6] to-[#448850] to-90% absolute left-60 top-13 z-0"></div>
<div className="size-70 rounded-full bg-radial-[at_50%_50%] from-[#e0e1d8] via-[#e5e7d6] to-[#448850] to-90% absolute right-100 top-65 z-0"></div>
<div className="size-35 rounded-full bg-radial-[at_50%_50%] from-[#e0e1d8] via-[#e5e7d6] to-[#448850] to-90% absolute left-80 top-90 z-0"></div>
<div className="size-25 rounded-full bg-radial-[at_50%_50%] from-[#e0e1d8] via-[#e5e7d6] to-[#448850] to-90% absolute right-30 top-66 z-0"></div>
<div className="size-45 rounded-full bg-radial-[at_50%_50%] from-[#e0e1d8] via-[#e5e7d6] to-[#448850] to-90% absolute right-55 bottom-20 z-0"></div>
<div className="size-18 rounded-full bg-radial-[at_50%_50%] from-[#e0e1d8] via-[#e5e7d6] to-[#448850] to-90% absolute right-10 top-15 z-0"></div>
<div className="size-18 rounded-full bg-radial-[at_50%_50%] from-[#e0e1d8] via-[#e5e7d6] to-[#448850] to-90% absolute right-10 top-100 z-0"></div>
<div className="size-25 rounded-full bg-radial-[at_50%_50%] from-[#e0e1d8] via-[#e5e7d6] to-[#448850] to-90% absolute left-30 bottom-10 z-0"></div>
</motion.article>
</div>
</section>
)
}

38 changes: 38 additions & 0 deletions src/components/login/LoginComponent.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
"use client"
import { InputField } from "../common/InputField/InputField"
import { Button } from "../common/Button/Button"
import { Icon } from "@iconify/react"

export const LoginComponent = () => {
return (
<form className="flex flex-col mx-auto w-[85%] gap-3 place-content-center">
<p className="text-2xl font-extrabold text-shadow-2xs text-shadow-[#2F2E43]">
LOG IN
</p>
<InputField
name="username"
type="text"
icon="akar-icons:person"
placeholder="Enter your username"
labelName="User Name"
/>
<InputField
name="password"
type="text"
icon="tdesign:user-password"
placeholder="Enter password"
labelName="Password"
/>

<span className="flex flex-row items-center gap-1 mx-auto text-gray-400 text-sm my-5">
Forgot Password?
</span>

<Button>
<span className="flex flex-row items-center gap-1">
Log In <Icon icon="pepicons-print:enter" width={16} height={16} />
</span>
</Button>
</form>
)
}
Loading