@@ -8,7 +8,7 @@ import { Input } from "@/components/ui/input"
88import { Label } from "@/components/ui/label"
99import Link from "next/link"
1010import { motion , AnimatePresence } from "framer-motion"
11- import { signInWithEmail , checkRememberMe } from "@/lib/features/auth"
11+ import { signIn , checkRememberMe } from "@/lib/features/auth"
1212import { getTranslations , getUserLanguage } from "@/lib/config"
1313import { LanguageSwitcher } from "@/components/language-switcher"
1414import {
@@ -26,8 +26,10 @@ import {
2626export default function LoginPage ( ) {
2727 const router = useRouter ( )
2828 const [ email , setEmail ] = useState ( "" )
29+ const [ password , setPassword ] = useState ( "" )
30+ const [ rememberMe , setRememberMe ] = useState ( false )
2931 const [ error , setError ] = useState ( "" )
30- const [ message , setMessage ] = useState ( "" )
32+ const [ showPassword , setShowPassword ] = useState ( false )
3133 const [ t , setT ] = useState ( getTranslations ( "en" ) )
3234
3335 useEffect ( ( ) => {
@@ -46,17 +48,16 @@ export default function LoginPage() {
4648 const handleLogin = async ( e : React . FormEvent ) => {
4749 e . preventDefault ( )
4850 setError ( "" )
49- setMessage ( "" )
5051
51- if ( ! email ) {
52- setError ( t . auth . email + " is required")
52+ if ( ! email || ! password ) {
53+ setError ( "Email and password are required")
5354 return
5455 }
5556
56- const result = await signInWithEmail ( email )
57+ const result = await signIn ( email , password , rememberMe )
5758
5859 if ( result . success ) {
59- setMessage ( "Check your email for the magic link to sign in! ")
60+ router . push ( "/dashboard ")
6061 } else {
6162 setError ( result . error || "Login failed" )
6263 }
@@ -177,19 +178,6 @@ export default function LoginPage() {
177178 </ div >
178179 </ motion . div >
179180 ) }
180- { message && (
181- < motion . div
182- initial = { { opacity : 0 , height : 0 } }
183- animate = { { opacity : 1 , height : "auto" } }
184- exit = { { opacity : 0 , height : 0 } }
185- className = "rounded-2xl border border-green-500/50 bg-green-500/5 p-4 text-sm text-green-400 overflow-hidden"
186- >
187- < div className = "flex items-center gap-3" >
188- < div className = "w-1.5 h-6 bg-green-500 rounded-full" > </ div >
189- < p className = "font-medium" > { message } </ p >
190- </ div >
191- </ motion . div >
192- ) }
193181 </ AnimatePresence >
194182
195183 < div className = "space-y-5" >
@@ -212,13 +200,60 @@ export default function LoginPage() {
212200 />
213201 </ div >
214202 </ div >
203+
204+ < div className = "space-y-2" >
205+ < Label htmlFor = "password" className = "text-xs font-bold uppercase tracking-widest text-slate-500 ml-1" >
206+ { t . auth . password }
207+ </ Label >
208+ < div className = "relative group" >
209+ < div className = "absolute left-4 top-1/2 -translate-y-1/2 flex items-center justify-center" >
210+ < LockClosedIcon className = "h-5 w-5 text-slate-500 group-focus-within:text-primary transition-colors" />
211+ </ div >
212+ < Input
213+ id = "password"
214+ type = { showPassword ? "text" : "password" }
215+ placeholder = "••••••••"
216+ value = { password }
217+ onChange = { ( e ) => setPassword ( e . target . value ) }
218+ className = "pl-12 pr-12 h-14 bg-white/[0.03] border-white/5 hover:border-white/10 focus:border-primary/50 transition-all rounded-2xl text-lg placeholder:text-slate-600 focus:ring-0 focus:bg-white/[0.05]"
219+ required
220+ />
221+ < button
222+ type = "button"
223+ onClick = { ( ) => setShowPassword ( ! showPassword ) }
224+ className = "absolute right-4 top-1/2 -translate-y-1/2 text-slate-500 hover:text-white transition-colors"
225+ >
226+ { showPassword ? < EyeSlashIcon className = "h-5 w-5" /> : < EyeIcon className = "h-5 w-5" /> }
227+ </ button >
228+ </ div >
229+ </ div >
230+ </ div >
231+
232+ < div className = "flex items-center justify-between px-1" >
233+ < label className = "flex items-center gap-3 cursor-pointer group" >
234+ < div className = "relative" >
235+ < input
236+ type = "checkbox"
237+ checked = { rememberMe }
238+ onChange = { ( e ) => setRememberMe ( e . target . checked ) }
239+ className = "peer appearance-none w-5 h-5 rounded-md border border-white/10 checked:bg-primary checked:border-primary transition-all cursor-pointer"
240+ />
241+ < CheckCircleIcon className = "absolute top-0.5 left-0.5 w-4 h-4 text-slate-950 opacity-0 peer-checked:opacity-100 transition-opacity pointer-events-none" />
242+ </ div >
243+ < span className = "text-sm font-medium text-slate-400 group-hover:text-slate-300 transition-colors" >
244+ { t . auth . rememberMe }
245+ </ span >
246+ </ label >
247+ < Link href = "#" className = "text-sm text-primary hover:text-white font-bold transition-colors" >
248+ Forgot password?
249+ </ Link >
215250 </ div >
216251
217252 < Button
218253 type = "submit"
219254 className = "w-full h-14 text-lg font-black uppercase tracking-widest bg-primary hover:bg-primary/90 text-slate-950 shadow-[0_0_20px_rgba(var(--primary-rgb),0.3)] hover:shadow-[0_0_30px_rgba(var(--primary-rgb),0.5)] transition-all group rounded-2xl"
220255 >
221- Send Magic Link
256+ Sign In
222257 < ArrowRightIcon className = "ml-3 h-5 w-5 group-hover:translate-x-1.5 transition-transform" />
223258 </ Button >
224259 </ form >
0 commit comments