Skip to content

Instantly share code, notes, and snippets.

@onesamket
Created March 17, 2024 11:48
Show Gist options
  • Save onesamket/1d552a333c842046b4350ed38832c4a8 to your computer and use it in GitHub Desktop.
Save onesamket/1d552a333c842046b4350ed38832c4a8 to your computer and use it in GitHub Desktop.
Signin form for nextjs app router
"use client";
import { FormError } from '@/components/shared/form-error';
import Spinner from '@/components/shared/spinner';
import { Button } from '@/components/ui/button';
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from '@/components/ui/form';
import { Input } from '@/components/ui/input';
import { ToastAction } from '@/components/ui/toast';
import { toast } from '@/components/ui/use-toast';
import { zodResolver } from '@hookform/resolvers/zod';
import { signIn } from 'next-auth/react';
import Link from 'next/link';
import { useRouter } from 'next/navigation';
import { useState } from 'react';
import { useForm } from 'react-hook-form';
import { z } from 'zod';
const formSchema = z.object({
email: z.string({
required_error: "Email is required"
}).min(2, {
message: "Email must be at least 2 characters.",
}),
password: z.string({
required_error: "password is required"
}).min(1, "Password must at least 1 characters"),
})
const SignInForm = () => {
const [loading, setLoading] = useState(false);
const router = useRouter();
const [error, setError] = useState<string | undefined>(undefined);
const form = useForm<z.infer<typeof formSchema>>({
resolver: zodResolver(formSchema),
})
const submitHandler = async (data: z.infer<typeof formSchema>) => {
try {
setLoading(true);
const result = await signIn('credentials', { redirect: false, email: data.email, password: data.password })
if (result?.ok == false) {
setLoading(false);
setError(result?.error || " Invalid Email and password");
}
else router.push('/')
} catch (error) {
setLoading(false);
toast({
variant: "destructive",
title: "Uh oh! Something went wrong.",
description: "There was a problem with your request.",
action: <ToastAction altText="Try again">Try again</ToastAction>,
})
}
}
return (
<Form {...form}>
<div className='p-6'>
<FormError message={error} />
</div>
<form onSubmit={form.handleSubmit(submitHandler)} className="space-y-8">
<FormField
control={form.control}
name="email"
render={({ field }) => (
<FormItem>
<FormLabel>Email</FormLabel>
<FormControl>
<Input disabled={loading} placeholder="Email address" {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="password"
render={({ field }) => (
<FormItem>
<FormLabel>Password</FormLabel>
<FormControl>
<Input disabled={loading} type='password' placeholder="********" {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<Button className='w-full' disabled={loading} type="submit">{loading && <Spinner />} {loading ? 'Authenticating...' : 'sign in'} </Button>
<Link className='flex hover:underline justify-end text-sm ' href="/forget-password">forget your password? </Link>
</form>
</Form>
)
}
export default SignInForm
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment