Completed Change to ReactJS

This commit is contained in:
2024-09-02 14:28:35 +00:00
parent 953edb3d0c
commit 6264778ea0
89 changed files with 4190 additions and 3866 deletions

View File

@ -1,90 +1,130 @@
import { useSiteContext } from '@context/SiteContext'
import { createForm } from '@felte/solid'
import { validator } from '@felte/validator-yup'
import useLanguage from '@hooks/useLanguage'
import { useNavigate } from '@solidjs/router'
import { IconKey, IconUser } from '@tabler/icons-solidjs'
import { onMount } from 'solid-js'
import * as yup from 'yup'
import './login.scss'
import Logo from '@assets/images/logo.svg'
import TextInput from '@components/common/TextInput'
import useAuth from '@hooks/useAuth'
import useToast from '@hooks/useToast'
const loginSchema = (language, isRequired) =>
yup.object({
username: yup.string().required(isRequired(language.ui.username)),
password: yup.string().required(isRequired(language.ui.password)),
})
import { errorTip, labelWithIcon } from '@components/Common'
import { useAuth, useSignInUp } from '@hooks/useAuth'
import {
Box,
Button,
Card,
Center,
Container,
Group,
Image,
PasswordInput,
TextInput,
Title,
} from '@mantine/core'
import { isNotEmpty, useForm } from '@mantine/form'
import { notifications } from '@mantine/notifications'
import {
IconCircleCheck,
IconCircleXFilled,
IconKeyFilled,
IconUserFilled,
} from '@tabler/icons-react'
import { useEffect } from 'react'
import { useTranslation } from 'react-i18next'
import { useNavigate } from 'react-router-dom'
import { s_logo, s_wrapper } from './Login.module.scss'
export default function Login() {
const { store, setAuth } = useSiteContext()
const { language, isRequired } = useLanguage()
const {
auth: { isLogged },
setAuth,
} = useAuth()
const { t } = useTranslation()
const navigate = useNavigate()
const { clickLogIn } = useAuth(setAuth)
const notify = useToast()
const { form, errors } = createForm({
extend: [validator({ schema: loginSchema(language, isRequired) })],
onSubmit: async (values) => {
try {
const { username, password } = values
return await clickLogIn(username, password)
} catch (error) {
notify.error({
title: 'Login fail!',
description: error?.data
? language.message[error.data]
: 'Your username or password input is wrong!',
closable: true,
})
}
const { onLogin } = useSignInUp(setAuth)
const form = useForm({
initialValues: {
username: '',
password: '',
},
validate: {
username: isNotEmpty(
t('message_is_required', { field: t('ui_username') }),
),
password: isNotEmpty(
t('message_is_required', { field: t('ui_password') }),
),
},
enhanceGetInputProps: (payload) => ({
error: errorTip(payload.inputProps.error),
}),
})
onMount(() => {
if (store.auth) {
useEffect(() => {
if (isLogged) {
navigate('/', { replace: true })
}
})
const onSubmitLogin = async (values) => {
try {
await onLogin(values)
notifications.show({
color: 'green.5',
icon: <IconCircleCheck />,
title: t('message_login_success'),
message: t('message_welcom_back'),
})
} catch (error) {
notifications.show({
color: 'red.5',
icon: <IconCircleXFilled />,
title: t('message_login_fail'),
message: error?.data ? t(error.data) : t('message_login_wrong'),
})
}
}
return (
<div class="login-page">
<div class="card glass card-compact login-wrap shadow-xl">
<div class="h-44">
<picture class="logo">
<source srcSet={Logo} type="image/png" media="(min-width: 600px)" />
<img src={Logo} alt="logo" />
</picture>
</div>
<div class="card-body">
<h1 class="card-title">{language.ui.login}</h1>
<form autoComplete="off" use:form>
<TextInput
name="username"
placeholder={language.ui.username}
icon={IconUser}
label={language.ui.username}
error={errors('username')}
/>
<TextInput
name="password"
type="password"
placeholder={language.ui.password}
icon={IconKey}
label={language.ui.password}
error={errors('password')}
/>
<div class="card-actions justify-end mt-2">
<button type="submit" class="btn btn-primary">
{language.ui.login}
</button>
</div>
<Container
fluid
style={{
background: '#fff url(/images/bg-login.jpg) no-repeat fixed center',
backgroundSize: 'cover',
}}
h="100svh"
>
<Center h="100svh">
<Card
shadow="xl"
radius={20}
w="40%"
maw={500}
miw={320}
className={s_wrapper}
>
<Card.Section>
<Image src={Logo} className={s_logo} alt="logo" />
</Card.Section>
<form onSubmit={form.onSubmit(onSubmitLogin)}>
<Box pos="relative" style={{ zIndex: 4 }}>
<Title order={1} fz={18} mb="sm" mt="sm">
{t('ui_login')}
</Title>
<TextInput
withAsterisk
label={labelWithIcon(t('ui_username'), IconUserFilled)}
placeholder={t('ui_username')}
key={form.key('username')}
{...form.getInputProps('username')}
/>
<PasswordInput
withAsterisk
label={labelWithIcon(t('ui_password'), IconKeyFilled)}
placeholder={t('ui_password')}
mt="sm"
key={form.key('password')}
{...form.getInputProps('password')}
/>
<Group justify="flex-end" mt="md">
<Button type="submit">{t('ui_login')}</Button>
</Group>
</Box>
</form>
</div>
</div>
</div>
</Card>
</Center>
</Container>
)
}