gitscope
← marzneshin / v0.6.2 / dashboard/src/features/auth/login/form.tsx
https://dev.kronoz.win/r/marzneshin.git
dashboard/src/features/auth/login/form.tsx · TypeScript
Blame Raw
 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}