You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
200 lines
4.8 KiB
200 lines
4.8 KiB
import { useState, useEffect } from 'react'; |
|
import { |
|
Box, |
|
Tabs, |
|
Tab, |
|
Typography, |
|
AppBar, |
|
TextField, |
|
Stack, |
|
} from '@mui/material'; |
|
|
|
import LoadingButton from '@mui/lab/LoadingButton'; |
|
import { useSnackbar } from '../Contexts/SnackbarContext'; |
|
import { useAuth } from '../Contexts/AuthContext'; |
|
import { useNavigate } from 'react-router-dom'; |
|
|
|
export function AuthForm({ setSession }) { |
|
const [tabindex, setTabIndex] = useState(0); |
|
|
|
const handleChange = (event, newIndex) => { |
|
setTabIndex(newIndex); |
|
}; |
|
|
|
const TabPanel = (props) => { |
|
const { children, value, index, ...other } = props; |
|
|
|
return ( |
|
<div |
|
role="tabpanel" |
|
hidden={value !== index} |
|
id={`full-width-tabpanel-${index}`} |
|
aria-labelledby={`full-width-tab-${index}`} |
|
{...other} |
|
> |
|
{value === index && ( |
|
<Box sx={{ p: 3 }}> |
|
<Typography component={'div'}>{children}</Typography> |
|
</Box> |
|
)} |
|
</div> |
|
); |
|
}; |
|
|
|
const a11yProps = (index) => { |
|
return { |
|
id: `full-width-tab-${index}`, |
|
'aria-controls': `full-width-tabpanel-${index}`, |
|
}; |
|
}; |
|
|
|
return ( |
|
<Box |
|
sx={{ |
|
minWidth: 250, |
|
display: 'flex', |
|
marginTop: 5, |
|
}} |
|
> |
|
<Box |
|
sx={{ |
|
flexGrow: 1, |
|
border: 1, |
|
}} |
|
> |
|
<AppBar position="static"> |
|
<Tabs |
|
value={tabindex} |
|
onChange={handleChange} |
|
indicatorColor="secondary" |
|
textColor="inherit" |
|
variant="fullWidth" |
|
aria-label="auth-tabs" |
|
> |
|
<Tab label="login" {...a11yProps(0)} /> |
|
<Tab label="register" {...a11yProps(1)} /> |
|
</Tabs> |
|
</AppBar> |
|
<TabPanel value={tabindex} index={0}> |
|
<AuthInputs tabIndex={0} setSession={setSession} /> |
|
</TabPanel> |
|
<TabPanel value={tabindex} index={1}> |
|
<AuthInputs tabIndex={1} setTabIndex={setTabIndex} /> |
|
</TabPanel> |
|
</Box> |
|
</Box> |
|
); |
|
} |
|
|
|
const AuthInputs = ({ tabIndex, setTabIndex }) => { |
|
const initial = { email: '', password: '', confirmPassword: '' }; |
|
const [credentials, setCredentials] = useState(initial); |
|
const [loading, setLoading] = useState(false); |
|
const { showSnackBar } = useSnackbar(); |
|
const { signIn, signUp, user } = useAuth(); |
|
const navigate = useNavigate(); |
|
|
|
const handleValueChanged = ({ target: { name, value } }) => { |
|
setCredentials({ ...credentials, [name]: value }); |
|
}; |
|
|
|
useEffect(() => { |
|
if (user) navigate('/'); |
|
}, [user, navigate]); |
|
|
|
const handleSubmit = async (e) => { |
|
try { |
|
e.preventDefault(); |
|
setLoading(true); |
|
|
|
if (credentials.email === '' || credentials.password === '') { |
|
setLoading(false); |
|
return showSnackBar('error', 'missing inputs'); |
|
} |
|
|
|
if ( |
|
tabIndex === 1 && |
|
credentials.password !== credentials.confirmPassword |
|
) { |
|
setLoading(false); |
|
return showSnackBar('error', `passwords don't match`); |
|
} |
|
|
|
const { user, error } = |
|
tabIndex === 0 |
|
? await signIn(credentials.email, credentials.password) |
|
: await signUp(credentials.email, credentials.password); |
|
|
|
if (error) { |
|
setLoading(false); |
|
return showSnackBar('error', error.message); |
|
} |
|
|
|
if (user) { |
|
tabIndex === 0 |
|
? showSnackBar('success', `logged in!`) |
|
: showSnackBar( |
|
'info', |
|
`verification email sent to ${credentials.email}` |
|
); |
|
} |
|
tabIndex === 1 && setTabIndex(0); |
|
navigate('/'); |
|
} catch (error) { |
|
console.log(error); |
|
} |
|
}; |
|
|
|
return ( |
|
<Stack |
|
key="auth-stack" |
|
id="auth-stack" |
|
spacing={2} |
|
direction="column" |
|
component="form" |
|
> |
|
<Typography component={'span'} variant={'body2'}> |
|
supachat 👋 |
|
</Typography> |
|
<TextField |
|
name="email" |
|
label="email" |
|
value={credentials.email} |
|
type="email" |
|
onChange={handleValueChanged} |
|
required |
|
autoComplete="email" |
|
/> |
|
<TextField |
|
name="password" |
|
label="password" |
|
value={credentials.password} |
|
type="password" |
|
onChange={handleValueChanged} |
|
required |
|
autoComplete="current-password" |
|
/> |
|
{tabIndex === 1 ? ( |
|
<TextField |
|
name="confirmPassword" |
|
label="confirm password" |
|
value={credentials.confirmPassword} |
|
type="password" |
|
onChange={handleValueChanged} |
|
required |
|
autoComplete="new-password" |
|
/> |
|
) : null} |
|
|
|
<LoadingButton |
|
fullWidth |
|
variant="outlined" |
|
loading={loading} |
|
onClick={(e) => handleSubmit(e)} |
|
type="submit" |
|
> |
|
{tabIndex === 0 ? 'Login' : 'Register'} |
|
</LoadingButton> |
|
</Stack> |
|
); |
|
};
|
|
|