feat: sign in page

This commit is contained in:
Dex404 2024-04-19 12:07:24 +00:00
parent bb8bf01e33
commit 66b99099b3
10 changed files with 379 additions and 100 deletions

View file

@ -0,0 +1,129 @@
"use client"
import { zodResolver } from "@hookform/resolvers/zod"
import { useRouter } from "next/router"
import { useForm } from "react-hook-form"
import * as z from "zod"
import { loginSchema } from "zodSchema/login"
type FormData = z.infer<typeof loginSchema>
export default function LoginForm() {
const router = useRouter()
const {
handleSubmit,
register,
formState: { errors, isSubmitting, isDirty, isValid },
} = useForm<FormData>({
resolver: zodResolver(loginSchema),
})
async function onSubmit(data: FormData) {
console.log(isSubmitting)
console.log(data)
// Replace this with a server action or fetch an API endpoint to authenticate
await new Promise<void>((resolve) => {
setTimeout(() => {
resolve()
}, 2000) // 2 seconds in milliseconds
})
router.push("/tweets")
}
return (
<div className="selection:bg-rose-500 selection:text-white">
<div className="flex min-h-screen items-center justify-center bg-rose-100">
<div className="flex-1 p-8">
<div className="mx-auto w-80 overflow-hidden rounded-3xl bg-white shadow-xl">
{/* Form Header */}
<div className="rounded-bl-4xl relative h-44 bg-rose-500">
<svg className="absolute bottom-0" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1440 320">
<path
fill="#ffffff"
fillOpacity="1"
d="M0,64L48,80C96,96,192,128,288,128C384,128,480,96,576,85.3C672,75,768,85,864,122.7C960,160,1056,224,1152,245.3C1248,267,1344,245,1392,234.7L1440,224L1440,320L1392,320C1344,320,1248,320,1152,320C1056,320,960,320,864,320C768,320,672,320,576,320C480,320,384,320,288,320C192,320,96,320,48,320L0,320Z"
></path>
</svg>
</div>
{/* Form Body */}
<div className="rounded-tr-4xl bg-white px-10 pb-8 pt-4">
<h1 className="text-2xl font-semibold text-gray-900">Welcome back!</h1>
<form className="mt-12" action="" method="POST" onSubmit={handleSubmit(onSubmit)}>
{/* Email Input */}
<div className="relative">
<input
{...register("email", { required: true })}
id="email"
name="email"
type="text"
className="peer h-10 w-full border-b-2 border-gray-300 text-gray-900 placeholder-transparent focus:border-rose-600 focus:outline-none"
placeholder="john@doe.com"
autoComplete="off"
/>
{errors?.email && <p className="text-sm text-red-600">{errors?.email?.message}</p>}
<label
htmlFor="email"
className="absolute -top-3.5 left-0 text-sm text-gray-600 transition-all peer-placeholder-shown:top-2 peer-placeholder-shown:text-base peer-placeholder-shown:text-gray-400 peer-focus:-top-3.5 peer-focus:text-sm peer-focus:text-gray-600"
>
Email address
</label>
</div>
{/* Password Input */}
<div className="relative mt-10">
<input
{...register("password", { required: true })}
id="password"
type="password"
name="password"
className="peer h-10 w-full border-b-2 border-gray-300 text-gray-900 placeholder-transparent focus:border-rose-600 focus:outline-none"
placeholder="Password"
autoComplete="off"
/>
{errors?.password && <p className="text-sm text-red-600">{errors?.password?.message}</p>}
<label
htmlFor="password"
className="absolute -top-3.5 left-0 text-sm text-gray-600 transition-all peer-placeholder-shown:top-2 peer-placeholder-shown:text-base peer-placeholder-shown:text-gray-400 peer-focus:-top-3.5 peer-focus:text-sm peer-focus:text-gray-600"
>
Password
</label>
</div>
{/* Submit Button */}
<button
type="submit"
disabled={!isDirty || !isValid || isSubmitting}
className="mt-20 block w-full cursor-pointer rounded bg-rose-500 px-4 py-2 text-center font-semibold text-white hover:bg-rose-400 focus:outline-none focus:ring focus:ring-rose-500 focus:ring-opacity-80 focus:ring-offset-2 disabled:opacity-70"
>
{isSubmitting ? (
<div role="status">
<svg
aria-hidden="true"
className="mr-2 inline h-6 w-6 animate-spin fill-rose-600 text-white opacity-100"
viewBox="0 0 100 101"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
{/* SVG for Spinner Animation */}
</svg>
</div>
) : (
"Sign In"
)}
</button>
</form>
{/* Forgot Password Link */}
<a
href="#"
className="mt-4 block text-center text-sm font-medium text-rose-600 hover:underline focus:outline-none focus:ring-2 focus:ring-rose-500"
>
Forgot your password?
</a>
</div>
</div>
</div>
</div>
</div>
)
}

View file

@ -101,11 +101,7 @@ const Navbar: React.FC<NavbarProps> = ({ logoSrc }) => {
</a>
<div className="flex space-x-3 rtl:space-x-reverse md:order-3 md:space-x-0">
<li className="hidden md:block">
<Button
href="https://vercel.com/new/git/external?repository-url=https://github.com/Blazity/next-enterprise"
intent="navSignIn"
size="hero1"
>
<Button href="/auth/SignIn" intent="navSignIn" size="hero1">
Sign In
</Button>
</li>
@ -143,7 +139,7 @@ const Navbar: React.FC<NavbarProps> = ({ logoSrc }) => {
>
<path
stroke="currentColor"
stroke-linecap="round"
strokeLinecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M1 1h15M1 7h15M1 13h15"

View file

@ -49,7 +49,7 @@ export default function OurServices() {
<svg
fill="none"
stroke="currentColor"
stroke-linecap="round"
strokeLinecap="round"
stroke-linejoin="round"
strokeWidth="2"
className="ml-2 h-4 w-4"
@ -90,7 +90,7 @@ export default function OurServices() {
<svg
fill="none"
stroke="currentColor"
stroke-linecap="round"
strokeLinecap="round"
stroke-linejoin="round"
strokeWidth="2"
className="ml-2 h-4 w-4"
@ -130,7 +130,7 @@ export default function OurServices() {
<svg
fill="none"
stroke="currentColor"
stroke-linecap="round"
strokeLinecap="round"
stroke-linejoin="round"
strokeWidth="2"
className="ml-2 h-4 w-4"
@ -171,7 +171,7 @@ export default function OurServices() {
<svg
fill="none"
stroke="currentColor"
stroke-linecap="round"
strokeLinecap="round"
stroke-linejoin="round"
strokeWidth="2"
className="ml-2 h-4 w-4"