207 lines
7.4 KiB
TypeScript
207 lines
7.4 KiB
TypeScript
/* ---------------------------------- @mui ---------------------------------- */
|
|
import { styled } from '@mui/material/styles';
|
|
import { Box, Card, Divider, Grid, Link, Stack, Typography, IconButton } from '@mui/material';
|
|
/* ------------------------------- components ------------------------------- */
|
|
import Page from '../../components/Page';
|
|
import Logo from '../../components/Logo';
|
|
import Iconify from '../../components/Iconify';
|
|
/* ---------------------------------- hooks --------------------------------- */
|
|
import useLocalStorage from '../../hooks/useLocalStorage';
|
|
/* -------------------------------- sections -------------------------------- */
|
|
import { LoginEmailForm, LoginPhoneForm, VerifyCodeForm } from '../../sections/auth/login';
|
|
import React, { useState, useEffect } from 'react';
|
|
import axios from '../../utils/axios';
|
|
|
|
import { enqueueSnackbar } from 'notistack';
|
|
/* --------------------------------- styled --------------------------------- */
|
|
|
|
const RootStyle = styled('div')(({ theme }) => ({
|
|
[theme.breakpoints.up('md')]: {
|
|
display: 'flex',
|
|
},
|
|
minHeight: '100vh',
|
|
flexDirection: 'column',
|
|
justifyContent: 'center',
|
|
alignItems: 'center',
|
|
}));
|
|
|
|
const ContentStyle = styled(Card)(({ theme }) => ({
|
|
[theme.breakpoints.up('md')]: {
|
|
maxHeight: '600px',
|
|
maxWidth: '1000px',
|
|
},
|
|
}));
|
|
|
|
// ----------------------------------------------------------------------
|
|
|
|
export default function Login() {
|
|
const [emailOrPhone, setEmailOrPhone] = useLocalStorage('emailOrPhone', '');
|
|
const [emailOrPhoneForm, setEmailOrPhoneForm] = useLocalStorage('emailOrPhoneForm', false);
|
|
const [loginOrVerifyCode, setLoginOrVerifyCode] = useLocalStorage('loginOrVerifyCode', false);
|
|
|
|
const [lastSentTime, setLastSentTime] = useState(null);
|
|
const [canSendOTP, setCanSendOTP] = useState(true);
|
|
|
|
useEffect(() => {
|
|
let timer;
|
|
if (lastSentTime) {
|
|
timer = setInterval(() => {
|
|
const timeDiff = Math.floor((new Date() - lastSentTime) / 1000);
|
|
if (timeDiff >= 60) {
|
|
setCanSendOTP(true);
|
|
clearInterval(timer);
|
|
}
|
|
}, 1000);
|
|
}
|
|
|
|
return () => clearInterval(timer);
|
|
}, [lastSentTime]);
|
|
|
|
const sendOTP = (phoneOrEmail: string) => {
|
|
if (canSendOTP) {
|
|
// Logic untuk mengirim OTP
|
|
axios
|
|
.post('/login', { phoneOrEmail })
|
|
.then(() => {
|
|
enqueueSnackbar('Kode OTP telah dikirim, silahkan cek email dan spam folder', {
|
|
variant: 'success',
|
|
autoHideDuration: 5000,
|
|
});
|
|
})
|
|
.catch((error) => {
|
|
if (error.response.status !== 404) throw error.response;
|
|
if (error.response.status !== 422) throw error.response;
|
|
});
|
|
|
|
setLastSentTime(new Date());
|
|
setCanSendOTP(false);
|
|
} else {
|
|
alert('You can only send OTP once every minute.');
|
|
}
|
|
}
|
|
return (
|
|
<Page title="Login">
|
|
<RootStyle>
|
|
<ContentStyle>
|
|
<Grid container>
|
|
<Grid item xs={6}>
|
|
<video
|
|
autoPlay={true}
|
|
loop={true}
|
|
muted={true}
|
|
playsInline={true}
|
|
style={{ width: '100%' }}
|
|
>
|
|
<source src="/images/login-image.webm" type="video/webm" />
|
|
<source src="/images/login-image.mp4" type="video/mp4" />
|
|
</video>
|
|
</Grid>
|
|
<Grid item xs={6} sx={{ padding: 3 }}>
|
|
{loginOrVerifyCode && emailOrPhone ? (
|
|
<>
|
|
<Stack direction="column" sx={{ mb: 5 }}>
|
|
<Stack direction="row" alignItems="center">
|
|
<IconButton
|
|
onClick={() => {
|
|
localStorage.removeItem('emailOrPhone');
|
|
setLoginOrVerifyCode(false);
|
|
}}
|
|
>
|
|
<Iconify
|
|
icon="heroicons-outline:arrow-narrow-left"
|
|
sx={{ marginRight: '10px' }}
|
|
/>
|
|
</IconButton>
|
|
<Typography variant="h4" gutterBottom>
|
|
Verifikasi OTP
|
|
</Typography>
|
|
</Stack>
|
|
<Box sx={{ flexGrow: 1 }}>
|
|
<Typography
|
|
variant="body1"
|
|
sx={{ color: 'text.secondary', textAlign: 'left' }}
|
|
>
|
|
Masukkan kode OTP anda disini
|
|
</Typography>
|
|
</Box>
|
|
</Stack>
|
|
|
|
<VerifyCodeForm emailOrPhone={emailOrPhone} />
|
|
|
|
<Stack sx={{ marginTop: 5 }} spacing={1} alignItems="center">
|
|
<Typography>Tidak mendapatkan kode?</Typography>
|
|
<Link
|
|
sx={{ cursor: 'pointer' }}
|
|
onClick={() => {
|
|
sendOTP(emailOrPhone);
|
|
}}
|
|
>Kirim Ulang Kode OTP</Link>
|
|
</Stack>
|
|
</>
|
|
) : (
|
|
<>
|
|
<Stack direction="row" alignItems="center" sx={{ mb: 5 }}>
|
|
<Logo sx={{ width: 90, height: 90 }} />
|
|
<Box sx={{ flexGrow: 1 }}>
|
|
<Typography variant="h4" gutterBottom>
|
|
Sign in to LinkSehat
|
|
</Typography>
|
|
<Typography variant="body1" sx={{ color: 'text.secondary' }}>
|
|
Enter your details below.
|
|
</Typography>
|
|
</Box>
|
|
</Stack>
|
|
|
|
{emailOrPhoneForm ? (
|
|
<LoginPhoneForm
|
|
setEmailOrPhone={setEmailOrPhone}
|
|
setLoginOrVerifyCode={setLoginOrVerifyCode}
|
|
/>
|
|
) : (
|
|
<LoginEmailForm
|
|
setEmailOrPhone={setEmailOrPhone}
|
|
setLoginOrVerifyCode={setLoginOrVerifyCode}
|
|
/>
|
|
)}
|
|
</>
|
|
)}
|
|
|
|
{/* <Divider sx={{ marginTop: 5 }}>Atau</Divider>
|
|
|
|
<Stack sx={{ marginTop: 5 }}>
|
|
{emailOrPhoneForm ? (
|
|
<Link
|
|
align="center"
|
|
underline="hover"
|
|
onClick={() => {
|
|
setEmailOrPhone('');
|
|
setLoginOrVerifyCode(false);
|
|
setEmailOrPhoneForm(false);
|
|
}}
|
|
sx={{ cursor: 'pointer' }}
|
|
>
|
|
Masuk menggunakan email
|
|
</Link>
|
|
) : (
|
|
<Link
|
|
align="center"
|
|
underline="hover"
|
|
onClick={() => {
|
|
setEmailOrPhone('');
|
|
setLoginOrVerifyCode(false);
|
|
setEmailOrPhoneForm(true);
|
|
}}
|
|
sx={{ cursor: 'pointer' }}
|
|
>
|
|
Masuk menggunakan nomor handphone
|
|
</Link>
|
|
)}
|
|
</Stack> */}
|
|
</Grid>
|
|
</Grid>
|
|
</ContentStyle>
|
|
</RootStyle>
|
|
</Page>
|
|
);
|
|
}
|