33import Link from "next/link"
44import { useSearchParams } from "next/navigation"
55
6+ import { zodResolver } from "@hookform/resolvers/zod"
7+ import { signIn } from "configs/auth"
68import { Github } from "lucide-react"
7- import { signIn } from "next-auth/react"
9+ import { useTranslations } from "next-intl"
10+ import { useForm } from "react-hook-form"
811import {
912 Button ,
1013 Card ,
@@ -18,21 +21,34 @@ import {
1821 TabsTrigger ,
1922 Typography ,
2023} from "ui"
24+ import { z } from "zod"
25+
26+ import { signInWithCredentials , signInWithGithub } from "@/actions/auth"
27+
28+ type FormData = {
29+ email : string
30+ password : string
31+ }
2132
2233export default function SignInForm ( ) {
23- const searchParams = useSearchParams ( )
34+ const t = useTranslations ( "auth" )
2435
25- const onSignIn = async ( e ) => {
26- e . preventDefault ( )
27- await signIn ( "github" , {
28- redirect : true ,
29- callbackUrl : ( searchParams . get ( "callbackUrl" ) as string ) || "/" ,
30- } )
36+ const { register, handleSubmit } = useForm < FormData > ( {
37+ resolver : zodResolver (
38+ z . object ( {
39+ email : z . string ( ) . email ( ) ,
40+ password : z . string ( ) . min ( 8 ) ,
41+ } )
42+ ) ,
43+ } )
44+
45+ const onSignIn = async ( data : FormData ) => {
46+ await signInWithCredentials ( data . email , data . password )
3147 }
3248
3349 return (
3450 < div className = "mt-16 w-full max-w-md flex-1 rounded-md p-8" >
35- < div >
51+ < div className = "text-center" >
3652 < Typography variant = "h1" > Sign In</ Typography >
3753
3854 < Typography
@@ -44,99 +60,76 @@ export default function SignInForm() {
4460 </ div >
4561
4662 < div className = "grid-6 mt-8 grid w-full" >
47- < form >
48- < Card >
49- < CardContent className = "pt-6" >
50- < Tabs >
51- < div className = "mb-1" >
52- < Label > Sign in mode</ Label >
63+ < Card >
64+ < CardContent className = "pt-6" >
65+ < form onSubmit = { handleSubmit ( onSignIn ) } >
66+ < div className = "grid gap-4" >
67+ < div className = "grid gap-2" >
68+ < Label htmlFor = "email" > Email</ Label >
69+ < Input
70+ id = "email"
71+ placeholder = "name@example.com"
72+ type = "email"
73+ autoCapitalize = "none"
74+ autoComplete = "email"
75+ autoCorrect = "off"
76+ { ...register ( "email" , { required : true } ) }
77+ />
78+ </ div >
79+ < div className = "grid gap-2" >
80+ < Label htmlFor = "password" > Password</ Label >
81+ < Input
82+ id = "password"
83+ placeholder = "********"
84+ type = "password"
85+ autoCapitalize = "none"
86+ autoCorrect = "off"
87+ { ...register ( "password" , { required : true } ) }
88+ />
5389 </ div >
54- < TabsList className = "grid w-full grid-cols-2" >
55- < TabsTrigger value = "magic" > Magic Link</ TabsTrigger >
56- < TabsTrigger value = "username_password" > Username/Password</ TabsTrigger >
57- </ TabsList >
58- < TabsContent value = "username_password" >
59- < div className = "grid gap-4" >
60- < div className = "grid gap-1" >
61- < Label className = "" > Email</ Label >
62- < Input
63- id = "email"
64- placeholder = "name@example.com"
65- type = "email"
66- autoCapitalize = "none"
67- autoComplete = "email"
68- autoCorrect = "off"
69- />
70- </ div >
71- < div className = "grid gap-1" >
72- < Label className = "" > Password</ Label >
73- < Input
74- id = "password"
75- placeholder = "********"
76- type = "password"
77- autoCapitalize = "none"
78- autoCorrect = "off"
79- />
80- </ div >
81- < Button > Sign In</ Button >
82- </ div >
83- </ TabsContent >
84- < TabsContent value = "magic" >
85- < div className = "grid gap-4" >
86- < div className = "grid gap-1" >
87- < Label className = "" > Email</ Label >
88- < Input
89- id = "email"
90- placeholder = "name@example.com"
91- type = "email"
92- autoCapitalize = "none"
93- autoComplete = "email"
94- autoCorrect = "off"
95- />
96- </ div >
97- < Button > Sign In With Email</ Button >
98- </ div >
99- </ TabsContent >
100- </ Tabs >
101- </ CardContent >
102- < CardFooter >
103- < div className = "flex w-full flex-col" >
104- < div className = "relative" >
105- < div className = "absolute inset-0 flex items-center" >
106- < span className = "w-full border-t" />
107- </ div >
108- < div className = "relative flex justify-center py-4 text-xs uppercase" >
109- < span className = "bg-background px-2 text-muted-foreground" >
110- Or continue with
111- </ span >
112- </ div >
90+ < Button type = "submit" > { t ( "sign_in.title" ) } </ Button >
91+ </ div >
92+ </ form >
93+ </ CardContent >
94+ < CardFooter >
95+ < div className = "flex w-full flex-col" >
96+ < div className = "relative" >
97+ < div className = "absolute inset-0 flex items-center" >
98+ < span className = "w-full border-t" />
99+ </ div >
100+ < div className = "relative flex justify-center py-4 text-xs uppercase" >
101+ < span className = "bg-background px-2 text-muted-foreground" >
102+ { t ( "or_continue_with" ) }
103+ </ span >
113104 </ div >
105+ </ div >
106+
107+ < form action = { signInWithGithub } >
114108 < Button
115109 variant = "outline"
116- type = "button"
117- onClick = { onSignIn }
110+ type = "submit"
118111 >
119112 < Github size = { 16 } />
120- < span className = "ml-2" > GitHub </ span >
113+ < span className = "ml-2" > { t ( "github" ) } </ span >
121114 </ Button >
122- </ div >
123- </ CardFooter >
124- </ Card >
125- </ form >
115+ </ form >
116+ </ div >
117+ </ CardFooter >
118+ </ Card >
126119 </ div >
127120
128121 < div className = "mt-4 text-center" >
129- < Link href = "register " >
122+ < Link href = "/signup " >
130123 < Typography
131124 variant = "span"
132125 className = "mt-4"
133126 >
134- Don't have an account? { " " }
127+ { t ( "dont_have_an_account" ) }
135128 < Typography
136129 className = "font-bold hover:underline"
137130 variant = "span"
138131 >
139- Sign Up
132+ { t ( "sign_up.title" ) }
140133 </ Typography >
141134 </ Typography >
142135 </ Link >
0 commit comments