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