aboutsummaryrefslogtreecommitdiffstats
path: root/src/views/Authorization/Signup.jsx
diff options
context:
space:
mode:
authorLibravatar Mo Tarbin <mhed.t91@gmail.com>2024-06-30 18:55:39 -0400
committerLibravatar Mo Tarbin <mhed.t91@gmail.com>2024-06-30 18:55:39 -0400
commit2657469964e24ffbeb905024532120395f6e797c (patch)
tree2fe9db8a4ecfa92d854ca94f7586d81163c8bd25 /src/views/Authorization/Signup.jsx
downloaddonetick-frontend-2657469964e24ffbeb905024532120395f6e797c.tar.gz
donetick-frontend-2657469964e24ffbeb905024532120395f6e797c.tar.bz2
donetick-frontend-2657469964e24ffbeb905024532120395f6e797c.zip
move to Donetick Org, First commit frontend
Diffstat (limited to '')
-rw-r--r--src/views/Authorization/Signup.jsx243
1 files changed, 243 insertions, 0 deletions
diff --git a/src/views/Authorization/Signup.jsx b/src/views/Authorization/Signup.jsx
new file mode 100644
index 0000000..d83411f
--- /dev/null
+++ b/src/views/Authorization/Signup.jsx
@@ -0,0 +1,243 @@
+import {
+ Box,
+ Button,
+ Container,
+ Divider,
+ FormControl,
+ FormHelperText,
+ Input,
+ Sheet,
+ Typography,
+} from '@mui/joy'
+import React from 'react'
+import { useNavigate } from 'react-router-dom'
+import Logo from '../../Logo'
+import { login, signUp } from '../../utils/Fetcher'
+
+const SignupView = () => {
+ const [username, setUsername] = React.useState('')
+ const [password, setPassword] = React.useState('')
+ const Navigate = useNavigate()
+ const [displayName, setDisplayName] = React.useState('')
+ const [email, setEmail] = React.useState('')
+ const [usernameError, setUsernameError] = React.useState('')
+ const [passwordError, setPasswordError] = React.useState('')
+ const [emailError, setEmailError] = React.useState('')
+ const [displayNameError, setDisplayNameError] = React.useState('')
+ const [error, setError] = React.useState(null)
+ const handleLogin = (username, password) => {
+ login(username, password).then(response => {
+ if (response.status === 200) {
+ response.json().then(res => {
+ localStorage.setItem('ca_token', res.token)
+ localStorage.setItem('ca_expiration', res.expire)
+ setTimeout(() => {
+ // TODO: not sure if there is a race condition here
+ // but on first sign up it renavigates to login.
+ Navigate('/my/chores')
+ }, 500)
+ })
+ } else {
+ console.log('Login failed', response)
+ // Navigate('/login')
+ }
+ })
+ }
+ const handleSignUpValidation = () => {
+ // Reset errors before validation
+ setUsernameError(null)
+ setPasswordError(null)
+ setDisplayNameError(null)
+ setEmailError(null)
+
+ let isValid = true
+
+ if (!username.trim()) {
+ setUsernameError('Username is required')
+ isValid = false
+ }
+ if (username.length < 4) {
+ setUsernameError('Username must be at least 4 characters')
+ isValid = false
+ }
+ // if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) {
+ // setEmailError('Invalid email address')
+ // isValid = false
+ // }
+
+ if (password.length < 8) {
+ setPasswordError('Password must be at least 8 characters')
+ isValid = false
+ }
+
+ if (!displayName.trim()) {
+ setDisplayNameError('Display name is required')
+ isValid = false
+ }
+
+ // display name should only contain letters and spaces and numbers:
+ if (!/^[a-zA-Z0-9 ]+$/.test(displayName)) {
+ setDisplayNameError('Display name can only contain letters and numbers')
+ isValid = false
+ }
+
+ // username should only contain letters , numbers , dot and dash:
+ if (!/^[a-zA-Z0-9.-]+$/.test(username)) {
+ setUsernameError(
+ 'Username can only contain letters, numbers, dot and dash',
+ )
+ isValid = false
+ }
+
+ return isValid
+ }
+ const handleSubmit = async e => {
+ e.preventDefault()
+ if (!handleSignUpValidation()) {
+ return
+ }
+ signUp(username, password, displayName, email).then(response => {
+ if (response.status === 201) {
+ handleLogin(username, password)
+ } else {
+ console.log('Signup failed')
+ setError('Signup failed')
+ }
+ })
+ }
+
+ return (
+ <Container component='main' maxWidth='xs'>
+ <Box
+ sx={{
+ display: 'flex',
+ flexDirection: 'column',
+ alignItems: 'center',
+ marginTop: 4,
+ }}
+ >
+ <Sheet
+ component='form'
+ sx={{
+ mt: 1,
+ width: '100%',
+ display: 'flex',
+ flexDirection: 'column',
+ // alignItems: 'center',
+ padding: 2,
+ borderRadius: '8px',
+ boxShadow: 'md',
+ }}
+ >
+ <Box
+ sx={{
+ display: 'flex',
+ alignItems: 'center',
+ flexDirection: 'column',
+ }}
+ >
+ <Logo />
+ <Typography level='h2'>
+ Done
+ <span
+ style={{
+ color: '#06b6d4',
+ }}
+ >
+ tick
+ </span>
+ </Typography>
+ <Typography level='body2'>
+ Create an account to get started!
+ </Typography>
+ </Box>
+ <Typography level='body2' alignSelf={'start'} mt={4}>
+ Username
+ </Typography>
+ <Input
+ margin='normal'
+ required
+ fullWidth
+ id='email'
+ label='Email Address'
+ name='email'
+ autoComplete='email'
+ autoFocus
+ value={username}
+ onChange={e => {
+ setUsernameError(null)
+ setUsername(e.target.value.trim())
+ }}
+ />
+ <FormControl error={usernameError}>
+ <FormHelperText c>{usernameError}</FormHelperText>
+ </FormControl>
+ {/* Error message display */}
+ <Typography level='body2' alignSelf={'start'}>
+ Password:
+ </Typography>
+ <Input
+ margin='normal'
+ required
+ fullWidth
+ name='password'
+ label='Password'
+ type='password'
+ id='password'
+ value={password}
+ onChange={e => {
+ setPasswordError(null)
+ setPassword(e.target.value)
+ }}
+ />
+ <FormControl error={passwordError}>
+ <FormHelperText>{passwordError}</FormHelperText>
+ </FormControl>
+ <Typography level='body2' alignSelf={'start'}>
+ Display Name:
+ </Typography>
+ <Input
+ margin='normal'
+ required
+ fullWidth
+ name='displayName'
+ label='Display Name'
+ id='displayName'
+ value={displayName}
+ onChange={e => {
+ setDisplayNameError(null)
+ setDisplayName(e.target.value)
+ }}
+ />
+ <FormControl error={displayNameError}>
+ <FormHelperText>{displayNameError}</FormHelperText>
+ </FormControl>
+ <Button
+ // type='submit'
+ size='lg'
+ fullWidth
+ variant='solid'
+ sx={{ mt: 3, mb: 1 }}
+ onClick={handleSubmit}
+ >
+ Sign Up
+ </Button>
+ <Divider> or </Divider>
+ <Button
+ size='lg'
+ onClick={() => {
+ Navigate('/login')
+ }}
+ fullWidth
+ variant='soft'
+ // sx={{ mt: 3, mb: 2 }}
+ >
+ Login
+ </Button>
+ </Sheet>
+ </Box>
+ </Container>
+ )
+}
+
+export default SignupView