Files
dta_webapp/ditch-the-agent/src/pages/authentication/SignUp.tsx

321 lines
11 KiB
TypeScript

import { ReactElement, Suspense, useState } from 'react';
import { ErrorMessage, Form, Formik } from 'formik';
import {
Alert,
Button,
FormControl,
FormControlLabel,
IconButton,
InputAdornment,
InputLabel,
Link,
OutlinedInput,
Radio,
RadioGroup,
Skeleton,
Stack,
TextField,
Typography,
} from '@mui/material';
import signupBanner from 'assets/authentication-banners/green.png';
import IconifyIcon from 'components/base/IconifyIcon';
import logo from 'assets/logo/favicon-logo.png';
import Image from 'components/base/Image';
import { axiosInstance } from '../../axiosApi.js';
import PasswordStrengthChecker from '../../components/PasswordStrengthChecker';
import { useNavigate } from 'react-router-dom';
type SignUpValues = {
email: string;
first_name: string;
last_name: string;
password: string;
password2: string;
ownerType: string;
};
const SignUp = (): ReactElement => {
const [showPassword, setShowPassword] = useState(false);
const [showPassword2, setShowPassword2] = useState(false);
const [password, setPassword] = useState('');
const [errorMessage, setErrorMessage] = useState<any | null>(null);
const handleClickShowPassword = () => setShowPassword(!showPassword);
const handleClickShowPassword2 = () => setShowPassword2(!showPassword2);
const navigate = useNavigate();
const handleSignUp = async ({
email,
first_name,
last_name,
ownerType,
password,
password2,
}: SignUpValues): Promise<void> => {
try {
const response = await axiosInstance.post('/register/', {
email: email,
first_name: first_name,
last_name: last_name,
user_type: ownerType,
password: password,
password2: password2,
});
if (response.status == 201) {
navigate('/authentication/login');
} else {
console.log(`No good: ${response}`);
}
} catch (error) {
const hasErrors = Object.keys(error.response.data).length > 0;
if (hasErrors) {
setErrorMessage(error.response.data);
} else {
setErrorMessage(null);
}
}
};
return (
<Stack
direction="row"
bgcolor="background.paper"
boxShadow={(theme) => theme.shadows[3]}
width={{ md: 960 }}
>
<Stack width={{ md: 0.5 }} m={2.5} gap={10}>
<Link href="/" width="fit-content">
<Image src={logo} width={82.6} />
</Link>
<Stack alignItems="center" gap={2.5} mx="auto">
<Typography variant="h3">Signup</Typography>
<Formik
initialValues={{
first_name: '',
email: '',
last_name: '',
password: '',
password2: '',
ownerType: 'property_owner',
}}
onSubmit={handleSignUp}
>
{({ setFieldValue }) => (
<Form>
<FormControl variant="standard" fullWidth>
{errorMessage ? (
<Alert severity="error">
<ul>
{Object.entries(errorMessage).map(([fieldName, errorMessages]) => (
<li key={fieldName}>
<strong>{fieldName}</strong>
{errorMessages.length > 0 ? (
<ul>
{errorMessages.map((message, index) => (
<li key={`${fieldName}-${index}`}>{message}</li> // Key for each message
))}
</ul>
) : (
<span> No specific errors for this field.</span>
)}
</li>
))}
</ul>
</Alert>
) : null}
<InputLabel shrink htmlFor="name">
First Name
</InputLabel>
<TextField
variant="filled"
onChange={(event) => setFieldValue('first_name', event.target.value)}
placeholder="Enter your first name"
id="first_name"
InputProps={{
endAdornment: (
<InputAdornment position="end" sx={{ width: 16, height: 16 }}>
<IconifyIcon icon="mdi:user" width={1} height={1} />
</InputAdornment>
),
}}
/>
</FormControl>
<FormControl variant="standard" fullWidth>
<InputLabel shrink htmlFor="name">
Last Name
</InputLabel>
<TextField
variant="filled"
onChange={(event) => setFieldValue('last_name', event.target.value)}
placeholder="Enter your last name"
id="last_name"
InputProps={{
endAdornment: (
<InputAdornment position="end" sx={{ width: 16, height: 16 }}>
<IconifyIcon icon="mdi:user" width={1} height={1} />
</InputAdornment>
),
}}
/>
</FormControl>
<FormControl variant="standard" fullWidth>
<InputLabel shrink htmlFor="email">
Email
</InputLabel>
<OutlinedInput
placeholder="Enter your email"
id="email"
endAdornment={
<InputAdornment position="end" sx={{ width: 16, height: 16 }}>
<IconifyIcon icon="ic:baseline-email" width={1} height={1} />
</InputAdornment>
}
sx={{
width: 1,
backgroundColor: 'action.focus',
}}
onChange={(event) => setFieldValue('email', event.target.value)}
/>
</FormControl>
<FormControl variant="standard" fullWidth>
<InputLabel shrink htmlFor="email">
Account Type
</InputLabel>
<RadioGroup
row
onChange={(event) => setFieldValue('ownerType', event.target.value)}
>
<FormControlLabel
value="property_owner"
control={<Radio />}
name="ownerType"
label="Owner"
/>
<FormControlLabel
value="vendor"
control={<Radio />}
name="ownerType"
label="Vendor"
/>
<FormControlLabel
value="attorney"
control={<Radio />}
name="ownerType"
label="Attorney"
/>
<FormControlLabel
value="real_estate_agent"
control={<Radio />}
name="ownerType"
label="Real Estate Agent"
/>
</RadioGroup>
</FormControl>
<FormControl variant="standard" fullWidth>
<InputLabel shrink htmlFor="password">
Password
</InputLabel>
<TextField
variant="filled"
placeholder="********"
onChange={(event) => {
setFieldValue('password', event.target.value);
setPassword(event.target.value);
}}
type={showPassword ? 'text' : 'password'}
id="password"
InputProps={{
endAdornment: (
<InputAdornment position="end">
<IconButton
aria-label="toggle password visibility"
onClick={handleClickShowPassword}
edge="end"
sx={{
color: 'text.secondary',
}}
>
{showPassword ? (
<IconifyIcon icon="ic:baseline-key-off" />
) : (
<IconifyIcon icon="ic:baseline-key" />
)}
</IconButton>
</InputAdornment>
),
}}
/>
{/*<PasswordStrengthChecker password={password} />*/}
</FormControl>
<FormControl variant="standard" fullWidth>
<InputLabel shrink htmlFor="password">
Confirm Password
</InputLabel>
<TextField
variant="filled"
placeholder="********"
onChange={(event) => setFieldValue('password2', event.target.value)}
type={showPassword2 ? 'text' : 'password'}
id="password"
InputProps={{
endAdornment: (
<InputAdornment position="end">
<IconButton
aria-label="toggle password visibility"
onClick={handleClickShowPassword2}
edge="end"
sx={{
color: 'text.secondary',
}}
>
{showPassword ? (
<IconifyIcon icon="ic:baseline-key-off" />
) : (
<IconifyIcon icon="ic:baseline-key" />
)}
</IconButton>
</InputAdornment>
),
}}
/>
</FormControl>
<Button variant="contained" type={'submit'} fullWidth>
Sign up
</Button>
</Form>
)}
</Formik>
<Typography variant="body2" color="text.secondary">
Already have an account ?{' '}
<Link
href="/authentication/login"
underline="hover"
fontSize={(theme) => theme.typography.body1.fontSize}
>
Log in
</Link>
</Typography>
</Stack>
</Stack>
<Suspense
fallback={
<Skeleton variant="rectangular" height={1} width={1} sx={{ bgcolor: 'primary.main' }} />
}
>
<Image
alt="Signup banner"
src={signupBanner}
sx={{
width: 0.5,
display: { xs: 'none', md: 'block' },
}}
/>
</Suspense>
</Stack>
);
};
export default SignUp;