picshop/src/components/forms/login.jsx
2025-02-24 10:47:56 +09:00

212 lines
7.9 KiB
JavaScript

'use client';
import * as Yup from 'yup';
import { useEffect, useState } from 'react';
import { useMutation } from 'react-query';
import RouterLink from 'next/link';
import { useSearchParams } from 'next/navigation';
import { useRouter } from 'next-nprogress-bar';
import toast from 'react-hot-toast';
// formik
import { useFormik, Form, FormikProvider } from 'formik';
// cookies
import { createCookies } from 'src/hooks/cookies';
// redux
import { useDispatch } from 'react-redux';
import { setWishlist } from 'src/redux/slices/wishlist';
import { setLogin } from 'src/redux/slices/user';
// api
import * as api from 'src/services';
// mui
import {
Link,
Typography,
Stack,
Checkbox,
TextField,
IconButton,
InputAdornment,
FormControl,
FormControlLabel,
Select,
MenuItem,
Button
} from '@mui/material';
import { LoadingButton } from '@mui/lab';
// icons
import { MdOutlineVisibility, MdLock, MdOutlineVisibilityOff } from 'react-icons/md';
import { IoMdMail } from 'react-icons/io';
import { lang, langen, langjp } from '../lang/kr';
import getCookies from '../lang/langUtil';
import { Row } from '../customElements';
export default function LoginForm() {
const langIs = getCookies('lang');
const { push } = useRouter();
const dispatch = useDispatch();
const searchParam = useSearchParams();
const redirect = searchParam.get('redirect');
const [loading, setloading] = useState(false);
const [showPassword, setShowPassword] = useState(false);
const [langState, setLangState] = useState(langIs ? langIs : 'kr')
const { mutate } = useMutation(api.login, {
onSuccess: async (data) => {
dispatch(setLogin(data.user));
dispatch(setWishlist(data.user.wishlist));
await createCookies('token', data.token);
setloading(false);
toast.success(lang['Logged in successfully!']);
const isAdmin = data.user.role.includes('admin');
const isVendor = data.user.role.includes('vendor');
push(redirect || isAdmin ? '/admin/dashboard' : isVendor ? '/vendor/dashboard' : '/');
},
onError: (err) => {
setloading(false);
toast.error(err.response.data.message);
}
});
const LoginSchema = Yup.object().shape({
email: Yup.string().email(lang['Enter valid email']).required(lang['Email is required']),
password: Yup.string()
.required(lang['Password is required'])
.min(8, lang['Password should be 8 characters or longer'])
});
const formik = useFormik({
initialValues: {
email: '',
password: '',
remember: true
},
validationSchema: LoginSchema,
onSubmit: async (values) => {
const { email, password } = values;
setloading(true);
mutate({ email, password });
}
});
const { errors, touched, values, handleSubmit, getFieldProps } = formik;
useEffect(() => {
createCookies('lang', langState)
}, [langState]);
return (
<>
<Stack mb={5}>
<Typography textAlign="center" variant="h4" component="h1" textTransform="uppercase" gutterBottom>
{({ kr: lang, en: langen, jp: langjp }[langIs] || lang).login}
</Typography>
</Stack>
<FormControl fullWidth sx={{ mb: '10px' }}>
<Typography variant="overline" color="text.primary" htmlFor="email" component={'label'}>
{({ kr: lang, en: langen, jp: langjp }[langIs] || lang)["Select Language"]}
</Typography>
<Select
onChange={(e) => setLangState(e.target.value)}
value={langIs}
>
<MenuItem value="kr">KOREAN</MenuItem>
<MenuItem value="jp">JAPANESE</MenuItem>
<MenuItem value="en">ENGLISH</MenuItem>
</Select>
</FormControl>
<FormikProvider value={formik}>
<Form autoComplete="off" noValidate onSubmit={handleSubmit}>
<Stack spacing={3}>
<Stack gap={0.5} width={1}>
<Typography variant="overline" color="text.primary" htmlFor="email" component={'label'}>
{({ kr: lang, en: langen, jp: langjp }[langIs] || lang).Email}
</Typography>
<TextField
id="email"
fullWidth
autoComplete="username"
type="email"
{...getFieldProps('email')}
error={Boolean(touched.email && errors.email)}
helperText={touched.email && errors.email}
InputProps={{
startAdornment: (
<InputAdornment position="start">
<IoMdMail size={24} />
</InputAdornment>
)
}}
/>
</Stack>
<Stack gap={0.5} width={1}>
<Typography variant="overline" color="text.primary" htmlFor="password" component={'label'}>
{({ kr: lang, en: langen, jp: langjp }[langIs] || lang).Password}
</Typography>
<TextField
id="password"
fullWidth
autoComplete="current-password"
type={showPassword ? 'text' : 'password'}
{...getFieldProps('password')}
InputProps={{
startAdornment: (
<InputAdornment position="start">
<MdLock size={24} />
</InputAdornment>
),
endAdornment: (
<InputAdornment position="end">
<IconButton edge="end" onClick={() => setShowPassword((prev) => !prev)}>
{showPassword ? <MdOutlineVisibility size={24} /> : <MdOutlineVisibilityOff size={24} />}
</IconButton>
</InputAdornment>
)
}}
error={Boolean(touched.password && errors.password)}
helperText={touched.password && errors.password}
/>
</Stack>
</Stack>
<Stack direction="row" alignItems="center" justifyContent="space-between" sx={{ my: 2 }}>
<FormControlLabel
control={<Checkbox {...getFieldProps('remember')} checked={values.remember} />}
label={({ kr: lang, en: langen, jp: langjp }[langIs] || lang)['Remember me']}
/>
<Link component={RouterLink} variant="subtitle2" href="/auth/forget-password">
{({ kr: lang, en: langen, jp: langjp }[langIs] || lang)['Forgot password']}
</Link>
</Stack>
<LoadingButton fullWidth size="large" type="submit" variant="contained" loading={loading}>
{({ kr: lang, en: langen, jp: langjp }[langIs] || lang).login}
</LoadingButton>
<Row sx={{justifyContent:'space-around'}}>
<Typography variant="subtitle2" mt={3} textAlign="center">
<Link href='/auth/register/?redirect=/create-shop' component={RouterLink}>
{({ kr: lang, en: langen, jp: langjp }[langIs] || lang).vendor}
{' '}
{({ kr: lang, en: langen, jp: langjp }[langIs] || lang).Register}
</Link>
</Typography>
<Typography variant="subtitle2" mt={3} textAlign="center">
<Link href={`/auth/register${redirect ? '?redirect=' + redirect : ''}`} component={RouterLink}>
{({ kr: lang, en: langen, jp: langjp }[langIs] || lang).buyer}
{' '}
{({ kr: lang, en: langen, jp: langjp }[langIs] || lang).Register}
</Link>
</Typography>
</Row>
<Typography variant="subtitle2" mt={3} textAlign="center">
<Link href="https://www.picshop.co.kr" target='_blank'>
{({ kr: lang, en: langen, jp: langjp }[langIs] || lang)['customer service']}
</Link>
</Typography>
</Form>
</FormikProvider>
<Button onClick={window.open('http://pf.kakao.com/_PrwzG/chat', '_blank')}>kakao</Button>
</>
);
}