| 1 |
a47eb4c |
Dawsh |
2y ago |
import { |
| 2 |
a47eb4c |
Dawsh |
2y ago |
Alert, |
| 3 |
a47eb4c |
Dawsh |
2y ago |
AlertDescription, |
| 4 |
a47eb4c |
Dawsh |
2y ago |
AlertIcon, |
| 5 |
a47eb4c |
Dawsh |
2y ago |
Box, |
| 6 |
a47eb4c |
Dawsh |
2y ago |
Button, |
| 7 |
a47eb4c |
Dawsh |
2y ago |
chakra, |
| 8 |
a47eb4c |
Dawsh |
2y ago |
FormControl, |
| 9 |
a47eb4c |
Dawsh |
2y ago |
HStack, |
| 10 |
a47eb4c |
Dawsh |
2y ago |
Text, |
| 11 |
a47eb4c |
Dawsh |
2y ago |
VStack, |
| 12 |
bf7c131 |
Mardin |
2y ago |
} from '@chakra-ui/react'; |
| 13 |
bedeeff |
Mardin |
2y ago |
import { ArrowRightStartOnRectangleIcon } from '@heroicons/react/24/outline'; |
| 14 |
bf7c131 |
Mardin |
2y ago |
import { zodResolver } from '@hookform/resolvers/zod'; |
| 15 |
bf7c131 |
Mardin |
2y ago |
import { FC, useEffect, useState } from 'react'; |
| 16 |
bf7c131 |
Mardin |
2y ago |
import { FieldValues, useForm } from 'react-hook-form'; |
| 17 |
bf7c131 |
Mardin |
2y ago |
import { useLocation, useNavigate } from 'react-router-dom'; |
| 18 |
bf7c131 |
Mardin |
2y ago |
import { z } from 'zod'; |
| 19 |
5825ea4 |
Mardin |
2y ago |
import { Footer } from 'components/footer'; |
| 20 |
5825ea4 |
Mardin |
2y ago |
import { Input } from 'components/input'; |
| 21 |
bf7c131 |
Mardin |
2y ago |
import { fetch } from 'service/http'; |
| 22 |
bf7c131 |
Mardin |
2y ago |
import { ReactComponent as Logo } from 'assets/logo.svg'; |
| 23 |
bf7c131 |
Mardin |
2y ago |
import { useTranslation } from 'react-i18next'; |
| 24 |
5825ea4 |
Mardin |
2y ago |
import { Language } from 'components/language'; |
| 25 |
89f8f93 |
Mardin |
2y ago |
import { useAdmin } from 'stores'; |
| 26 |
a47eb4c |
Dawsh |
2y ago |
|
| 27 |
a47eb4c |
Dawsh |
2y ago |
const schema = z.object({ |
| 28 |
bf7c131 |
Mardin |
2y ago |
username: z.string().min(1, 'login.fieldRequired'), |
| 29 |
bf7c131 |
Mardin |
2y ago |
password: z.string().min(1, 'login.fieldRequired'), |
| 30 |
a47eb4c |
Dawsh |
2y ago |
}); |
| 31 |
a47eb4c |
Dawsh |
2y ago |
|
| 32 |
a47eb4c |
Dawsh |
2y ago |
export const LogoIcon = chakra(Logo, { |
| 33 |
a47eb4c |
Dawsh |
2y ago |
baseStyle: { |
| 34 |
bf7c131 |
Mardin |
2y ago |
strokeWidth: '10px', |
| 35 |
a47eb4c |
Dawsh |
2y ago |
w: 12, |
| 36 |
a47eb4c |
Dawsh |
2y ago |
h: 12, |
| 37 |
a47eb4c |
Dawsh |
2y ago |
}, |
| 38 |
a47eb4c |
Dawsh |
2y ago |
}); |
| 39 |
a47eb4c |
Dawsh |
2y ago |
|
| 40 |
bedeeff |
Mardin |
2y ago |
const LoginIcon = chakra(ArrowRightStartOnRectangleIcon, { |
| 41 |
a47eb4c |
Dawsh |
2y ago |
baseStyle: { |
| 42 |
a47eb4c |
Dawsh |
2y ago |
w: 5, |
| 43 |
a47eb4c |
Dawsh |
2y ago |
h: 5, |
| 44 |
bf7c131 |
Mardin |
2y ago |
strokeWidth: '2px', |
| 45 |
a47eb4c |
Dawsh |
2y ago |
}, |
| 46 |
a47eb4c |
Dawsh |
2y ago |
}); |
| 47 |
a47eb4c |
Dawsh |
2y ago |
|
| 48 |
a47eb4c |
Dawsh |
2y ago |
export const Login: FC = () => { |
| 49 |
bf7c131 |
Mardin |
2y ago |
const [error, setError] = useState(''); |
| 50 |
a47eb4c |
Dawsh |
2y ago |
const [loading, setLoading] = useState(false); |
| 51 |
a47eb4c |
Dawsh |
2y ago |
const navigate = useNavigate(); |
| 52 |
d459492 |
Mardin |
2y ago |
const { setAuthToken, removeAuthToken } = useAdmin(); |
| 53 |
a47eb4c |
Dawsh |
2y ago |
const { t } = useTranslation(); |
| 54 |
a47eb4c |
Dawsh |
2y ago |
let location = useLocation(); |
| 55 |
a47eb4c |
Dawsh |
2y ago |
const { |
| 56 |
a47eb4c |
Dawsh |
2y ago |
register, |
| 57 |
a47eb4c |
Dawsh |
2y ago |
formState: { errors }, |
| 58 |
a47eb4c |
Dawsh |
2y ago |
handleSubmit, |
| 59 |
a47eb4c |
Dawsh |
2y ago |
} = useForm({ |
| 60 |
a47eb4c |
Dawsh |
2y ago |
resolver: zodResolver(schema), |
| 61 |
a47eb4c |
Dawsh |
2y ago |
}); |
| 62 |
a47eb4c |
Dawsh |
2y ago |
useEffect(() => { |
| 63 |
a47eb4c |
Dawsh |
2y ago |
removeAuthToken(); |
| 64 |
bf7c131 |
Mardin |
2y ago |
if (location.pathname !== '/login') { |
| 65 |
bf7c131 |
Mardin |
2y ago |
navigate('/login', { replace: true }); |
| 66 |
a47eb4c |
Dawsh |
2y ago |
} |
| 67 |
a47eb4c |
Dawsh |
2y ago |
}, []); |
| 68 |
a47eb4c |
Dawsh |
2y ago |
const login = (values: FieldValues) => { |
| 69 |
bf7c131 |
Mardin |
2y ago |
setError(''); |
| 70 |
a47eb4c |
Dawsh |
2y ago |
const formData = new FormData(); |
| 71 |
bf7c131 |
Mardin |
2y ago |
formData.append('username', values.username); |
| 72 |
bf7c131 |
Mardin |
2y ago |
formData.append('password', values.password); |
| 73 |
bf7c131 |
Mardin |
2y ago |
formData.append('grant_type', 'password'); |
| 74 |
a47eb4c |
Dawsh |
2y ago |
setLoading(true); |
| 75 |
5bb2712 |
Mardin |
2y ago |
fetch('/admins/token', { method: 'post', body: formData }) |
| 76 |
a47eb4c |
Dawsh |
2y ago |
.then(({ access_token: token }) => { |
| 77 |
a47eb4c |
Dawsh |
2y ago |
setAuthToken(token); |
| 78 |
bf7c131 |
Mardin |
2y ago |
navigate('/'); |
| 79 |
a47eb4c |
Dawsh |
2y ago |
}) |
| 80 |
a47eb4c |
Dawsh |
2y ago |
.catch((err) => { |
| 81 |
a47eb4c |
Dawsh |
2y ago |
setError(err.response._data.detail); |
| 82 |
a47eb4c |
Dawsh |
2y ago |
}) |
| 83 |
a47eb4c |
Dawsh |
2y ago |
.finally(setLoading.bind(null, false)); |
| 84 |
a47eb4c |
Dawsh |
2y ago |
}; |
| 85 |
a47eb4c |
Dawsh |
2y ago |
return ( |
| 86 |
a47eb4c |
Dawsh |
2y ago |
<VStack justifyContent="space-between" minH="100vh" p="6" w="full"> |
| 87 |
a47eb4c |
Dawsh |
2y ago |
<Box w="full"> |
| 88 |
a47eb4c |
Dawsh |
2y ago |
<HStack justifyContent="end" w="full"> |
| 89 |
a47eb4c |
Dawsh |
2y ago |
<Language /> |
| 90 |
a47eb4c |
Dawsh |
2y ago |
</HStack> |
| 91 |
a47eb4c |
Dawsh |
2y ago |
<HStack w="full" justifyContent="center" alignItems="center"> |
| 92 |
a47eb4c |
Dawsh |
2y ago |
<Box w="full" maxW="340px" mt="6"> |
| 93 |
a47eb4c |
Dawsh |
2y ago |
<VStack alignItems="center" w="full"> |
| 94 |
a47eb4c |
Dawsh |
2y ago |
<LogoIcon /> |
| 95 |
a47eb4c |
Dawsh |
2y ago |
<Text fontSize="2xl" fontWeight="semibold"> |
| 96 |
bf7c131 |
Mardin |
2y ago |
{t('login.loginYourAccount')} |
| 97 |
a47eb4c |
Dawsh |
2y ago |
</Text> |
| 98 |
bf7c131 |
Mardin |
2y ago |
<Text color="gray.600" _dark={{ color: 'gray.400' }}> |
| 99 |
bf7c131 |
Mardin |
2y ago |
{t('login.welcomeBack')} |
| 100 |
a47eb4c |
Dawsh |
2y ago |
</Text> |
| 101 |
a47eb4c |
Dawsh |
2y ago |
</VStack> |
| 102 |
a47eb4c |
Dawsh |
2y ago |
<Box w="full" maxW="300px" m="auto" pt="4"> |
| 103 |
a47eb4c |
Dawsh |
2y ago |
<form onSubmit={handleSubmit(login)}> |
| 104 |
a47eb4c |
Dawsh |
2y ago |
<VStack mt={4} rowGap={2}> |
| 105 |
a47eb4c |
Dawsh |
2y ago |
<FormControl> |
| 106 |
a47eb4c |
Dawsh |
2y ago |
<Input |
| 107 |
a47eb4c |
Dawsh |
2y ago |
w="full" |
| 108 |
bf7c131 |
Mardin |
2y ago |
placeholder={t('username')} |
| 109 |
bf7c131 |
Mardin |
2y ago |
{...register('username')} |
| 110 |
a47eb4c |
Dawsh |
2y ago |
error={t(errors?.username?.message as string)} |
| 111 |
a47eb4c |
Dawsh |
2y ago |
/> |
| 112 |
a47eb4c |
Dawsh |
2y ago |
</FormControl> |
| 113 |
a47eb4c |
Dawsh |
2y ago |
<FormControl> |
| 114 |
a47eb4c |
Dawsh |
2y ago |
<Input |
| 115 |
a47eb4c |
Dawsh |
2y ago |
w="full" |
| 116 |
a47eb4c |
Dawsh |
2y ago |
type="password" |
| 117 |
bf7c131 |
Mardin |
2y ago |
placeholder={t('password')} |
| 118 |
bf7c131 |
Mardin |
2y ago |
{...register('password')} |
| 119 |
a47eb4c |
Dawsh |
2y ago |
error={t(errors?.password?.message as string)} |
| 120 |
a47eb4c |
Dawsh |
2y ago |
/> |
| 121 |
a47eb4c |
Dawsh |
2y ago |
</FormControl> |
| 122 |
a47eb4c |
Dawsh |
2y ago |
{error && ( |
| 123 |
a47eb4c |
Dawsh |
2y ago |
<Alert status="error" rounded="md"> |
| 124 |
a47eb4c |
Dawsh |
2y ago |
<AlertIcon /> |
| 125 |
a47eb4c |
Dawsh |
2y ago |
<AlertDescription>{error}</AlertDescription> |
| 126 |
a47eb4c |
Dawsh |
2y ago |
</Alert> |
| 127 |
a47eb4c |
Dawsh |
2y ago |
)} |
| 128 |
a47eb4c |
Dawsh |
2y ago |
<Button |
| 129 |
a47eb4c |
Dawsh |
2y ago |
isLoading={loading} |
| 130 |
a47eb4c |
Dawsh |
2y ago |
type="submit" |
| 131 |
a47eb4c |
Dawsh |
2y ago |
w="full" |
| 132 |
a47eb4c |
Dawsh |
2y ago |
colorScheme="primary" |
| 133 |
a47eb4c |
Dawsh |
2y ago |
> |
| 134 |
a47eb4c |
Dawsh |
2y ago |
{<LoginIcon marginRight={1} />} |
| 135 |
912788f |
Mardin |
2y ago |
{t('login.login')} |
| 136 |
a47eb4c |
Dawsh |
2y ago |
</Button> |
| 137 |
a47eb4c |
Dawsh |
2y ago |
</VStack> |
| 138 |
a47eb4c |
Dawsh |
2y ago |
</form> |
| 139 |
a47eb4c |
Dawsh |
2y ago |
</Box> |
| 140 |
a47eb4c |
Dawsh |
2y ago |
</Box> |
| 141 |
a47eb4c |
Dawsh |
2y ago |
</HStack> |
| 142 |
a47eb4c |
Dawsh |
2y ago |
</Box> |
| 143 |
57a4cf7 |
Mrdn |
2y ago |
<Footer bottom={3} /> |
| 144 |
a47eb4c |
Dawsh |
2y ago |
</VStack> |
| 145 |
a47eb4c |
Dawsh |
2y ago |
); |
| 146 |
a47eb4c |
Dawsh |
2y ago |
}; |
| 147 |
a47eb4c |
Dawsh |
2y ago |
|
| 148 |
a47eb4c |
Dawsh |
2y ago |
export default Login; |