/
opt
/
mawid
/
apps
/
dashboard
/
app
/
login
/
/opt/mawid/apps/dashboard/app/login
mkdir
upload
Name
Size
Mode
Actions
page.tsx
1910
0644
edit
dl
rm
Edit:
/opt/mawid/apps/dashboard/app/login/page.tsx
(1910B)
'use client'; import { useState } from 'react'; import { useRouter } from 'next/navigation'; import { api, setToken } from '@/lib/api'; import { useLang } from '@/lib/i18n'; import { Button, Card, Field, Input } from '@/components/ui'; export default function LoginPage() { const { t } = useLang(); const router = useRouter(); const [email, setEmail] = useState(''); const [password, setPassword] = useState(''); const [error, setError] = useState<string | null>(null); const [busy, setBusy] = useState(false); async function submit(e: React.FormEvent) { e.preventDefault(); setBusy(true); setError(null); try { const result = await api<{ accessToken: string }>('/auth/login', { method: 'POST', body: JSON.stringify({ email, password }), }); setToken(result.accessToken); router.push('/'); } catch { setError(t('loginFailed')); } finally { setBusy(false); } } return ( <main className="flex min-h-screen items-center justify-center p-4"> <Card className="w-full max-w-sm"> <h1 className="mb-1 text-xl font-semibold">{t('appName')}</h1> <p className="mb-4 text-sm text-slate-500">{t('loginTitle')}</p> <form onSubmit={submit} className="space-y-3"> <Field label={t('email')}> <Input type="email" value={email} onChange={(e) => setEmail(e.target.value)} required /> </Field> <Field label={t('password')}> <Input type="password" value={password} onChange={(e) => setPassword(e.target.value)} required /> </Field> {error && <p className="text-sm text-red-600">{error}</p>} <Button type="submit" disabled={busy} className="w-full"> {t('signIn')} </Button> </form> </Card> </main> ); }
Save
cmd:
run