Files
pawol.nu/components/sesyon/koneksyon.js
T

466 lines
15 KiB
JavaScript
Raw Normal View History

2022-01-22 03:39:46 +04:00
import {useEffect, useState, forwardRef} from 'react'
2022-02-03 01:59:49 +04:00
import {signIn} from 'next-auth/react'
import {useRouter} from 'next/navigation'
import PropTypes from 'prop-types'
2022-02-06 18:40:47 +04:00
import Box from '@mui/material/Box'
import Button from '@mui/material/Button'
import Container from '@mui/material/Container'
import FormControl from '@mui/material/FormControl'
import IconButton from '@mui/material/IconButton'
import Input from '@mui/material/Input'
import InputAdornment from '@mui/material/InputAdornment'
import InputLabel from '@mui/material/InputLabel'
import LinearProgress from '@mui/material/LinearProgress'
import Snackbar from '@mui/material/Snackbar'
import Tab from '@mui/material/Tab'
import Tabs from '@mui/material/Tabs'
import Typography from '@mui/material/Typography'
import Grid from '@mui/material/Unstable_Grid2'
2022-02-06 18:40:47 +04:00
import Visibility from '@mui/icons-material/Visibility'
import VisibilityOff from '@mui/icons-material/VisibilityOff'
2022-01-19 07:06:26 +04:00
import MuiAlert from '@mui/material/Alert'
2022-02-06 18:40:47 +04:00
import LoginIcon from '@mui/icons-material/Login'
import AppRegistrationRoundedIcon from '@mui/icons-material/AppRegistrationRounded'
import axios from 'axios'
2021-05-22 23:38:56 +02:00
import {validateEmail} from '../../lib/utils/emails'
import ResetPassword from '../password/reset-password'
import ResetDialog from '../password/reset-dialog'
2022-10-23 23:24:43 +04:00
import LoginProvider from './login-provider'
2021-05-22 23:38:56 +02:00
2022-10-26 00:33:01 +04:00
const siteUrl = process.env.NEXT_PUBLIC_SITE_URL || 'http://localhost:3001'
2022-02-06 18:40:47 +04:00
const apiUrl = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:1337'
2022-10-23 23:24:43 +04:00
const PROVIDERS = [
2022-10-26 00:33:01 +04:00
{
id: 'google',
title: 'Google',
2022-10-31 23:01:33 +04:00
width: 16,
height: 16
2022-10-26 00:33:01 +04:00
},
2022-10-23 23:24:43 +04:00
{
id: 'twitter',
title: 'Twitter',
2022-10-31 23:01:33 +04:00
width: 16,
height: 13
2022-10-28 08:28:35 +04:00
},
{
id: 'github',
title: 'GitHub',
2022-10-31 23:01:33 +04:00
width: 16,
height: 15
2022-10-23 23:24:43 +04:00
}
]
2022-02-06 18:40:47 +04:00
function TabPanel(props) {
const {children, value, index, ...other} = props
return (
<div
role='tabpanel'
hidden={value !== index}
id={`simple-tabpanel-${index}`}
aria-labelledby={`simple-tab-${index}`}
{...other}
>
{value === index && (
<Box sx={{p: 3}}>
{children}
</Box>
)}
</div>
)
}
TabPanel.propTypes = {
children: PropTypes.node,
index: PropTypes.number.isRequired,
value: PropTypes.number.isRequired,
}
function a11yProps(index) {
return {
id: `simple-tab-${index}`,
'aria-controls': `simple-tabpanel-${index}`,
}
}
2022-01-22 18:10:25 +04:00
const Alert = forwardRef(function Alert(props, ref) {
2022-01-22 03:39:46 +04:00
return <MuiAlert ref={ref} elevation={6} variant='filled' {...props} />
})
2022-02-06 18:40:47 +04:00
function Koneksyon({chimen}) {
const [error, setError] = useState('')
2022-02-06 18:40:47 +04:00
const [loginCredentials, setLoginCredentials] = useState({username: '', password: ''})
const [registerCredentials, setRegisterCredentials] = useState({username: '', email: '', password: ''})
const [passwordVerification, setPasswordVerification] = useState('')
2021-05-22 23:38:56 +02:00
const [showPassword, setShowPassword] = useState(false)
2022-02-06 18:40:47 +04:00
const [showRegisterPassword, setShowRegisterPassword] = useState(false)
const [showVerificationPassword, setShowVerificationPassword] = useState(false)
const [loading, setLoading] = useState(false)
2021-05-22 23:38:56 +02:00
const [open, setOpen] = useState(true)
const [success, setSuccess] = useState(false)
const [openDialog, setOpenDialog] = useState(false)
2022-02-06 18:40:47 +04:00
const [value, setValue] = useState(0)
2021-05-22 23:38:56 +02:00
const router = useRouter()
const handleUpdate = update => {
2022-02-06 18:40:47 +04:00
setLoginCredentials({...loginCredentials, ...update})
}
const handleRegisterUpdate = update => {
setRegisterCredentials({...registerCredentials, ...update})
}
const handleChange = (event, newValue) => {
setValue(newValue)
}
const register = async () => {
try {
const response = await axios.post(`${apiUrl}/auth/local/register`, {
...registerCredentials
}, {
headers: {
'content-type': 'application/json'
}
})
2022-05-17 00:31:13 +04:00
localStorage.setItem('username', `${response?.data?.user?.username}`)
setSuccess(true)
2022-02-06 18:40:47 +04:00
resetRegisterForm()
2022-02-19 21:41:07 +04:00
} catch (error_) {
if (error_.message.endsWith(400)) {
setError('E-mail ou utilisateur déjà enregistré')
2022-02-06 18:40:47 +04:00
} else {
setError('Une erreur sest produite')
}
}
2021-05-22 23:38:56 +02:00
}
2022-02-06 18:40:47 +04:00
const resetRegisterForm = () => {
setRegisterCredentials({username: '', email: '', password: ''})
setPasswordVerification('')
}
const handleClickLogin = async () => {
if (!validateEmail(loginCredentials.username) || loginCredentials.password === '') {
2021-05-31 20:34:25 +02:00
return
}
setLoading(true)
2021-05-22 23:38:56 +02:00
const response = await signIn('credentials', {
callbackUrl: `${siteUrl}${chimen}`,
2021-05-22 23:38:56 +02:00
redirect: false,
2022-02-06 18:40:47 +04:00
...loginCredentials
2021-05-22 23:38:56 +02:00
})
if (response.error) {
setError(response.error)
setLoading(false)
2021-05-22 23:38:56 +02:00
} else if (response.ok) {
setLoading(false)
router.push(chimen)
2021-05-22 23:38:56 +02:00
}
}
2022-02-06 18:40:47 +04:00
const handleClickRegister = async () => {
setLoading(true)
if (!validateEmail(registerCredentials.email) || registerCredentials.password === '') {
return
}
if (registerCredentials.password !== passwordVerification) {
setError('Les 2 mots de passe de correspondent pas')
setLoading(false)
return
}
if (registerCredentials.username.length < 3) {
setError('Le nom dutilisateur est trop court, 3 caratères minimum')
setLoading(false)
return
}
2022-02-06 18:55:58 +04:00
if (registerCredentials.password.length < 6) {
setError('Le mot de passe est trop court, 6 caratères minimum')
setLoading(false)
return
}
2022-02-06 18:40:47 +04:00
await register()
setLoading(false)
}
2021-05-22 23:38:56 +02:00
const handleClose = (event, reason) => {
if (reason === 'clickaway') {
return
}
setOpen(false)
setSuccess(false)
2021-05-22 23:38:56 +02:00
setError('')
}
useEffect(() => {
if (error) {
2021-05-22 23:38:56 +02:00
setOpen(true)
}
return () => {
setLoading(false)
}
}, [error])
2021-05-22 23:38:56 +02:00
const handleClickShowPassword = () => {
setShowPassword(!showPassword)
}
2022-02-06 18:40:47 +04:00
const handleClickShowRegisterPassword = () => {
setShowRegisterPassword(!showRegisterPassword)
}
const handleClickShowVerificationPassword = () => {
setShowVerificationPassword(!showVerificationPassword)
}
2021-05-22 23:38:56 +02:00
const handleMouseDownPassword = event => {
event.preventDefault()
}
2022-02-06 18:40:47 +04:00
const handleMouseDownRegisterPassword = event => {
event.preventDefault()
}
const handleMouseDownVerificationPassword = event => {
event.preventDefault()
}
const handleKeyUpLogin = event => {
if (event.keyCode === 13) {
handleClickLogin()
}
}
const handleKeyUpRegister = event => {
2021-05-31 20:34:25 +02:00
if (event.keyCode === 13) {
2022-02-06 18:40:47 +04:00
handleClickRegister()
2021-05-31 20:34:25 +02:00
}
}
2021-05-22 23:38:56 +02:00
return (
2022-02-06 18:40:47 +04:00
<Container sx={{marginTop: 2}} maxWidth='sm'>
2021-05-24 13:33:17 +02:00
2022-02-06 18:40:47 +04:00
<Box sx={{width: '100%'}}>
<Tabs centered value={value} aria-label='basic tabs example' onChange={handleChange}>
<Tab icon={<LoginIcon />} label='Se connecter' {...a11yProps(0)} />
<Tab icon={<AppRegistrationRoundedIcon />} label='Sinscrire' {...a11yProps(1)} />
</Tabs>
<TabPanel value={value} index={0}>
2022-10-23 23:24:43 +04:00
<Box sx={{textAlign: 'center', marginBottom: 3}}>
2022-10-26 00:33:01 +04:00
<Typography gutterBottom textAlign='center'>Connectez-vous avec</Typography>
2022-10-31 23:01:33 +04:00
<Grid container alignItems='center' justifyContent='center' columnSpacing={{xs: 1, sm: 2, md: 3}}>
2022-10-26 00:33:01 +04:00
{PROVIDERS.map(({id, title, width, height}) => (
<Grid key={id} item marginTop={1}>
<LoginProvider id={id} title={title} width={width} height={height} callbackUrl={`${siteUrl}${chimen}`} />
</Grid>
))}
</Grid>
2022-10-23 23:24:43 +04:00
</Box>
<Box sx={{textAlign: 'center', marginBottom: 3}}>
<Typography>ou utilisez votre e-mail pour vous identifier</Typography>
</Box>
2022-02-06 18:40:47 +04:00
<FormControl fullWidth autoComplete='off'>
2022-02-19 21:41:07 +04:00
<InputLabel htmlFor='username'>E-mail</InputLabel>
2022-02-06 18:40:47 +04:00
<Input
2022-10-23 23:22:48 +04:00
autoComplete='new-password'
2022-02-06 18:40:47 +04:00
value={loginCredentials.username}
name='username'
type='email'
id='email'
onChange={event => handleUpdate({username: event.target.value})}
onKeyUp={handleKeyUpLogin}
/>
</FormControl>
2021-05-22 23:38:56 +02:00
2022-02-06 18:40:47 +04:00
<FormControl fullWidth style={{marginTop: '1em'}}>
<InputLabel htmlFor='password'>Mot de passe</InputLabel>
<Input
2022-10-23 23:22:48 +04:00
autoComplete='new-password'
2022-02-06 18:40:47 +04:00
value={loginCredentials.password}
name='password'
type={showPassword ? 'text' : 'password'}
id='password'
endAdornment={
<InputAdornment position='end'>
<IconButton
aria-label='password visibility'
size='large'
onClick={handleClickShowPassword}
onMouseDown={handleMouseDownPassword}
>
{showPassword ? <Visibility /> : <VisibilityOff />}
</IconButton>
</InputAdornment>
}
onChange={event => handleUpdate({password: event.target.value})}
onKeyUp={handleKeyUpLogin}
/>
</FormControl>
2022-02-06 18:40:47 +04:00
<Button
fullWidth
disabled={loading || !validateEmail(loginCredentials.username) || loginCredentials.password === ''}
style={{marginTop: 20}}
variant='contained'
color='primary'
onClick={handleClickLogin}
>
<Typography style={{fontWeight: 'bold'}}>
Connexion
</Typography>
</Button>
<ResetPassword />
2022-02-06 18:40:47 +04:00
</TabPanel>
<TabPanel value={value} index={1}>
2022-02-06 19:03:12 +04:00
<FormControl fullWidth>
2022-02-19 21:41:07 +04:00
<InputLabel htmlFor='register-email'>E-mail</InputLabel>
2022-02-06 18:40:47 +04:00
<Input
2022-02-06 19:34:52 +04:00
autoComplete='email'
2022-02-06 18:40:47 +04:00
value={registerCredentials.email}
name='register-email'
type='email'
id='register-email'
onChange={event => handleRegisterUpdate({email: event.target.value})}
onKeyUp={handleKeyUpRegister}
/>
</FormControl>
2022-02-06 19:03:12 +04:00
<FormControl fullWidth style={{marginTop: '1em'}}>
2022-02-06 18:59:32 +04:00
<InputLabel htmlFor='register-username'>Nom dutilisateur</InputLabel>
<Input
2022-02-06 19:34:52 +04:00
autoComplete='username'
2022-02-06 18:59:32 +04:00
value={registerCredentials.username}
name='register-username'
type='text'
id='register-username'
onChange={event => handleRegisterUpdate({username: event.target.value})}
onKeyUp={handleKeyUpRegister}
/>
</FormControl>
2022-02-06 18:40:47 +04:00
<FormControl fullWidth style={{marginTop: '1em'}}>
<InputLabel htmlFor='password'>Mot de passe</InputLabel>
<Input
2022-10-23 05:16:47 +04:00
autoComplete='new-password' // Disable auto complete
2022-02-06 18:40:47 +04:00
value={registerCredentials.password}
name='register-password'
type={showRegisterPassword ? 'text' : 'password'}
id='register-password'
endAdornment={
<InputAdornment position='end'>
<IconButton
aria-label='password visibility'
size='large'
onClick={handleClickShowRegisterPassword}
onMouseDown={handleMouseDownRegisterPassword}
>
{showRegisterPassword ? <Visibility /> : <VisibilityOff />}
</IconButton>
</InputAdornment>
}
onChange={event => handleRegisterUpdate({password: event.target.value})}
onKeyUp={handleKeyUpRegister}
/>
</FormControl>
<FormControl fullWidth style={{marginTop: '1em'}}>
<InputLabel htmlFor='password'>Vérification du mot de passe</InputLabel>
<Input
value={passwordVerification}
name='verification-password'
type={showVerificationPassword ? 'text' : 'password'}
id='verification-password'
error={registerCredentials.password !== passwordVerification}
endAdornment={
<InputAdornment position='end'>
<IconButton
aria-label='password visibility'
size='large'
onClick={handleClickShowVerificationPassword}
onMouseDown={handleMouseDownVerificationPassword}
>
{showVerificationPassword ? <Visibility /> : <VisibilityOff />}
</IconButton>
</InputAdornment>
}
onChange={event => setPasswordVerification(event.target.value)}
onKeyUp={handleKeyUpRegister}
/>
</FormControl>
<Button
fullWidth
disabled={loading || !validateEmail(registerCredentials.email) || registerCredentials.username === '' || registerCredentials.password === ''}
style={{marginTop: 20}}
variant='contained'
color='primary'
onClick={handleClickRegister}
>
<Typography style={{fontWeight: 'bold'}}>
Inscription
</Typography>
</Button>
<Button
fullWidth
style={{marginTop: 20}}
variant='outlined'
color='warning'
onClick={() => setOpenDialog(true)}
>
<Typography style={{fontWeight: 'bold'}}>
2022-02-19 21:41:07 +04:00
Renvoyer le-mail de confirmation
</Typography>
</Button>
2022-02-06 18:40:47 +04:00
</TabPanel>
</Box>
<ResetDialog
activation
lyen='send-email-confirmation'
2022-02-19 21:41:07 +04:00
title='Envoi de le-mail de confirmation'
content='Si vous navez pas reçu le-mail de confirmation, renseignez le champ et validez le formulaire.'
open={openDialog}
setOpen={setOpenDialog}
setLoading={setLoading}
setError={setError}
setSuccess={setSuccess}
/>
{loading && <LinearProgress size={24} style={{width: '100%'}} />}
{error && (
2021-05-22 23:38:56 +02:00
<Snackbar
open={open}
autoHideDuration={6000}
onClose={handleClose}
>
<Alert severity='error' onClose={handleClose}><strong>{error}</strong></Alert>
2021-05-22 23:38:56 +02:00
</Snackbar>
)}
2022-02-06 18:40:47 +04:00
{success && (
2022-02-06 18:40:47 +04:00
<Snackbar
open={success}
2022-02-06 18:40:47 +04:00
autoHideDuration={15_000}
onClose={handleClose}
>
2022-02-19 21:41:07 +04:00
<Alert severity='success' onClose={handleClose}><strong>Veuillez confirmer votre adresse e-mail via le lien qui vous a été envoyé.</strong></Alert>
2022-02-06 18:40:47 +04:00
</Snackbar>
)}
2021-05-22 23:38:56 +02:00
</Container>
)
}
Koneksyon.propTypes = {
chimen: PropTypes.string.isRequired
}
2021-05-22 23:38:56 +02:00
export default Koneksyon