mirror of
https://github.com/VaalaCat/frp-panel.git
synced 2025-10-08 08:40:31 +08:00
100 lines
3.2 KiB
TypeScript
100 lines
3.2 KiB
TypeScript
import { ZodStringSchema } from '@/lib/consts'
|
|
import { zodResolver } from '@hookform/resolvers/zod'
|
|
import { useForm } from 'react-hook-form'
|
|
import * as z from 'zod'
|
|
import { Form, FormControl, FormField, FormItem, FormMessage, FormLabel } from '@/components/ui/form'
|
|
import { Input } from './ui/input'
|
|
import { login } from '@/api/auth'
|
|
import { Button } from './ui/button'
|
|
|
|
import { ExclamationTriangleIcon } from '@radix-ui/react-icons'
|
|
|
|
import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert'
|
|
import { useState } from 'react'
|
|
import { useToast } from './ui/use-toast'
|
|
import { RespCode } from '@/lib/pb/common'
|
|
import { useRouter } from 'next/router'
|
|
import { useTranslation } from 'react-i18next';
|
|
|
|
export const LoginSchema = z.object({
|
|
username: ZodStringSchema,
|
|
password: ZodStringSchema,
|
|
})
|
|
|
|
export function LoginComponent() {
|
|
const { t } = useTranslation();
|
|
const form = useForm<z.infer<typeof LoginSchema>>({
|
|
resolver: zodResolver(LoginSchema),
|
|
})
|
|
const { toast } = useToast()
|
|
const router = useRouter()
|
|
|
|
const [loginAlert, setLoginAlert] = useState(false)
|
|
|
|
const onSubmit = async (values: z.infer<typeof LoginSchema>) => {
|
|
toast({ title: t('auth.loggingIn') })
|
|
try {
|
|
const res = await login({ ...values })
|
|
if (res.status?.code === RespCode.SUCCESS) {
|
|
toast({ title: t('auth.loginSuccess') })
|
|
setTimeout(() => {
|
|
router.push('/')
|
|
}, 3000)
|
|
setLoginAlert(false)
|
|
} else {
|
|
toast({ title: t('auth.loginFailed') })
|
|
setLoginAlert(true)
|
|
}
|
|
} catch (e) {
|
|
toast({ title: t('auth.loginFailed') })
|
|
console.log('login error', e)
|
|
setLoginAlert(true)
|
|
}
|
|
}
|
|
|
|
return (
|
|
<div className="w-full flex flex-col gap-6">
|
|
<Form {...form}>
|
|
<form onSubmit={form.handleSubmit(onSubmit)} className="flex flex-col gap-4">
|
|
<FormField
|
|
control={form.control}
|
|
name="username"
|
|
render={({ field }) => (
|
|
<FormItem>
|
|
<FormLabel>{t('auth.usernamePlaceholder')}</FormLabel>
|
|
<FormControl>
|
|
<Input type="text" placeholder={t('auth.usernamePlaceholder')} {...field} />
|
|
</FormControl>
|
|
<FormMessage />
|
|
</FormItem>
|
|
)}
|
|
/>
|
|
<FormField
|
|
control={form.control}
|
|
name="password"
|
|
render={({ field }) => (
|
|
<FormItem>
|
|
<FormLabel>{t('auth.password')}</FormLabel>
|
|
<FormControl>
|
|
<Input type="password" placeholder={t('auth.passwordPlaceholder')} {...field} />
|
|
</FormControl>
|
|
<FormMessage />
|
|
</FormItem>
|
|
)}
|
|
/>
|
|
{loginAlert && (
|
|
<Alert variant="destructive">
|
|
<ExclamationTriangleIcon className="h-4 w-4" />
|
|
<AlertTitle>{t('auth.error')}</AlertTitle>
|
|
<AlertDescription>{t('auth.loginFailed')}</AlertDescription>
|
|
</Alert>
|
|
)}
|
|
<Button className="w-full" type="submit">
|
|
{t('common.login')}
|
|
</Button>
|
|
</form>
|
|
</Form>
|
|
</div>
|
|
)
|
|
}
|