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