Add register validation

This commit is contained in:
Benjamin Sherriff
2023-10-18 22:52:59 -04:00
parent 616a43dba9
commit 0bda10c23b
2 changed files with 93 additions and 14 deletions

View File

@@ -26,6 +26,7 @@ import { useForm } from '@mantine/form';
import { login, register, logout, me, refresh } from '@/api/auth';
import { User } from '@/api/auth.types';
import { useToggle } from '@mantine/hooks';
import { notifications } from '@mantine/notifications';
interface HeaderItem {
name: string;
@@ -187,6 +188,41 @@ interface LoginModalProps {
}
function LoginModal({ type, toggle, setUser }: LoginModalProps) {
function passwordValidator(value: string) {
if (value.trim().length < 10) {
return 'Password must be at least 10 characters';
}
if (value.trim().length >= 128) {
return 'Password must be at most 128 characters';
}
if (!/(\d)/.test(value)) {
return 'Password must contain at least one number';
}
if (!/[a-z]/.test(value)) {
return 'Password must contain at least one lowercase letter';
}
if (!/[A-Z]/.test(value)) {
return 'Password must contain at least one uppercase letter';
}
if (!/[!@#$%^&*]/.test(value)) {
return 'Password must contain at least one special character';
}
if (/(.)\1\1/.test(value)) {
return 'Password must not contain more than 2 repeating characters';
}
return null;
}
function emailValidator(value: string) {
if (value.trim().length == 0) {
return 'Email is required';
}
if (!/^\S+@\S+$/.test(value)) {
return 'Invalid email';
}
return null;
}
const form = useForm({
initialValues: {
firstName: '',
@@ -194,6 +230,12 @@ function LoginModal({ type, toggle, setUser }: LoginModalProps) {
email: '',
password: '',
remember: false
},
validate: {
firstName: (value) => (value.trim().length > 0 ? null : 'First name is required'),
lastName: (value) => (value.trim().length > 0 ? null : 'Last name is required'),
email: emailValidator,
password: passwordValidator
}
});
@@ -210,18 +252,13 @@ function LoginModal({ type, toggle, setUser }: LoginModalProps) {
<Container>
<Title ta='center'>Reset password</Title>
<Text c='dimmed' size='sm' ta='center' mt={5}>
Enter your email and we will send you a link to reset your password
Enter your email and we will send you a link to reset your password.{' '}
<Anchor size='sm' component='a' onClick={() => toggle('login')}>
Go Back
</Anchor>
</Text>
<Paper withBorder shadow='md' p={30} mt={30} radius='md'>
<form
onSubmit={form.onSubmit(async (values) => {
const response = await login(values.email, values.password);
if (response) {
setUser(response.user);
onClose();
}
})}
>
<form onSubmit={form.onSubmit(async (values) => console.log(values))}>
<TextInput label='Email' placeholder='you@example.com' required {...form.getInputProps('email')} />
<Button type='submit' fullWidth mt='xl'>
Reset password
@@ -234,7 +271,7 @@ function LoginModal({ type, toggle, setUser }: LoginModalProps) {
<Title ta='center'>Create account</Title>
<Text c='dimmed' size='sm' ta='center' mt={5}>
Already have an account?{' '}
<Anchor size='sm' component='button' onClick={() => toggle('login')}>
<Anchor size='sm' component='a' onClick={() => toggle('login')}>
Sign in
</Anchor>
</Text>
@@ -242,6 +279,13 @@ function LoginModal({ type, toggle, setUser }: LoginModalProps) {
<Paper withBorder shadow='md' p={30} mt={30} radius='md'>
<form
onSubmit={form.onSubmit(async (values) => {
const id = notifications.show({
loading: true,
title: `Creating account`,
message: `Please wait...`,
autoClose: false,
withCloseButton: false
});
const registerResponse = await register({
first_name: values.firstName,
last_name: values.lastName,
@@ -253,7 +297,33 @@ function LoginModal({ type, toggle, setUser }: LoginModalProps) {
if (loginResponse) {
setUser(loginResponse.user);
onClose();
notifications.update({
id,
title: `Account created`,
message: `Welcome ${loginResponse.user.first_name}!`,
color: 'green',
autoClose: 2000,
loading: false
});
} else {
notifications.update({
id,
title: `Unable to Login`,
message: `Please try again.`,
color: 'red',
autoClose: 2000,
loading: false
});
}
} else {
notifications.update({
id,
title: `Unable to Register`,
message: `Please try again.`,
color: 'error',
autoClose: 2000,
loading: false
});
}
})}
>
@@ -262,6 +332,7 @@ function LoginModal({ type, toggle, setUser }: LoginModalProps) {
<TextInput label='Email' placeholder='you@example.com' required {...form.getInputProps('email')} />
<PasswordInput
label='Password'
description='Passwords must be at least 10 characters long, contain at least one number, one uppercase letter, one lowercase letter, and one special character.'
placeholder='Your password'
required
mt='md'
@@ -278,7 +349,7 @@ function LoginModal({ type, toggle, setUser }: LoginModalProps) {
<Title ta='center'>Welcome back!</Title>
<Text c='dimmed' size='sm' ta='center' mt={5}>
Do not have an account yet?{' '}
<Anchor size='sm' component='button' onClick={() => toggle('register')}>
<Anchor size='sm' component='a' onClick={() => toggle('register')}>
Create account
</Anchor>
</Text>
@@ -290,6 +361,13 @@ function LoginModal({ type, toggle, setUser }: LoginModalProps) {
if (response) {
setUser(response.user);
onClose();
} else {
notifications.show({
title: `Unable to Login`,
message: `Please try again.`,
color: 'red',
autoClose: 2000
});
}
})}
>
@@ -303,7 +381,7 @@ function LoginModal({ type, toggle, setUser }: LoginModalProps) {
/>
<Group justify='space-between' mt='lg'>
<Checkbox label='Remember me' {...form.getInputProps('remember')} />
<Anchor component='button' size='sm' onClick={() => toggle('reset')}>
<Anchor component='a' size='sm' onClick={() => toggle('reset')}>
Forgot password?
</Anchor>
</Group>