summaryrefslogtreecommitdiff
path: root/src/components/header/authdialog/LoginForm.tsx
blob: ceadbcda751624d143f539ae07b79ece2a1ae0f0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
'use client';
import { useState } from 'react';
import { Button } from '@/components/ui/button';
import GoogleIcon from '../../../../public/icons/google.svg';
import { InputField } from '@/components/ui/inputfield';
import { useAuthContext } from '@/lib/contexts/Auth.context';

export default function LoginForm() {
    const [errors, setErrors] = useState<any>({});
    const [loading, setLoading] = useState(false);
    const { setUser } = useAuthContext();

    const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
        e.preventDefault();
        setLoading(true);
        setErrors({});

        const formData = new FormData(e.currentTarget);
        const emailOrUsername =
            formData.get('emailOrUsername')?.toString() || '';
        const password = formData.get('password')?.toString() || '';

        const newErrors: any = {};
        if (!emailOrUsername)
            newErrors.emailOrUsername = 'Введите никнейм или email';
        if (!password) newErrors.password = 'Введите пароль';

        if (Object.keys(newErrors).length > 0) {
            setErrors(newErrors);
            setLoading(false);
            return;
        }

        const body = new URLSearchParams();
        body.append('username', emailOrUsername);
        body.append('password', password);

        try {
            const res = await fetch('http://localhost:8000/api/auth/login', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded',
                },
                body: body.toString(),
            });

            const data = await res.json();

            if (!res.ok) {
                setErrors({ general: 'Неверный логин или пароль' });
            } else if (data.access_token) {
                localStorage.setItem('token', data.access_token);

                const meRes = await fetch('http://localhost:8000/api/me', {
                    headers: { Authorization: `Bearer ${data.access_token}` },
                });
                const meData = await meRes.json();
                setUser(meData);
            }
        } finally {
            setLoading(false);
        }
    };

    return (
        <form
            onSubmit={handleSubmit}
            className="flex flex-col gap-5 min-w-[310px] w-fit"
        >
            <Button className="w-full bg-white hover:bg-white hover:text-black">
                <GoogleIcon />
                <span className="text-black text-sm">Войти через Google</span>
            </Button>

            <div className="flex flex-col gap-2.5">
                <div className="flex flex-col">
                    <InputField
                        placeholder="Никнейм или почта"
                        name="emailOrUsername"
                    />
                    {errors.emailOrUsername && (
                        <p className="text-red pl-5 text-[12px] leading-[16px] mt-[5px]">
                            {errors.emailOrUsername}
                        </p>
                    )}
                </div>

                <div className="flex flex-col">
                    <InputField
                        isPassword
                        placeholder="Пароль"
                        name="password"
                    />
                    {errors.password && (
                        <p className="text-red pl-5 text-[12px] leading-[16px] mt-[5px]">
                            {errors.password}
                        </p>
                    )}
                    {!errors.password && errors.general && (
                        <p className="text-red pl-5 text-[12px] leading-[16px] mt-[5px]">
                            {errors.general}
                        </p>
                    )}
                </div>
            </div>

            <Button type="submit" className="w-full" disabled={loading}>
                {loading ? 'Вход...' : 'Войти'}
            </Button>
        </form>
    );
}