1
2import { fetch } from "@marzneshin/utils"
3import { LoginSchema, useAuth } from "@marzneshin/features/auth";
4import { useNavigate } from "@tanstack/react-router";
5import { useState } from "react";
6import { FieldValues, useForm } from "react-hook-form";
7import { zodResolver } from '@hookform/resolvers/zod';
8import { Button, Form, FormControl, FormField, FormItem, FormLabel, FormMessage, Input } from "@marzneshin/components";
9import { useTranslation } from "react-i18next";
10import { FormError } from "./form-error";
11
12export const LoginForm = () => {
13 const { setAuthToken, setSudo } = useAuth();
14 const form = useForm({
15 resolver: zodResolver(LoginSchema),
16 defaultValues: {
17 username: '',
18 password: '',
19 }
20 })
21 const navigate = useNavigate({ from: '/login' });
22 const [error, setError] = useState<string>('');
23 const { t } = useTranslation();
24
25 const submit = async (values: FieldValues) => {
26 setError('');
27 const formData = new FormData();
28 formData.append('username', values.username);
29 formData.append('password', values.password);
30 formData.append('grant_type', 'password');
31
32 try {
33 const { access_token, is_sudo } = await fetch('/admins/token', { method: 'post', body: formData });
34 setAuthToken(access_token);
35 setSudo(is_sudo);
36 navigate({ to: '/' });
37 } catch (err: any) {
38 setError(err.response._data?.detail || 'An error occurred');
39 }
40 };
41
42 return (
43 <Form {...form}>
44 <form onSubmit={form.handleSubmit(submit)}>
45 <FormField
46 control={form.control}
47 name="username"
48 render={({ field }) => (
49 <FormItem>
50 <FormLabel className="font-semibold text-primary">{t('username')}</FormLabel>
51 <FormControl>
52 <Input type="text" {...field} />
53 </FormControl>
54 <FormMessage />
55 </FormItem>
56 )}
57 />
58 <FormField
59 control={form.control}
60 name="password"
61 render={({ field }) => (
62 <FormItem>
63 <FormLabel className="font-semibold text-primary">{t('password')}</FormLabel>
64 <FormControl>
65 <Input type="password" {...field} />
66 </FormControl>
67 <FormMessage />
68 </FormItem>
69 )}
70 />
71 <Button className="mt-3 w-full" type="submit">{t('login')}</Button>
72 {error && <FormError className="mt-2" title='Submission failed' desc={error} />}
73 </form>
74 </Form>
75 )
76}