From 549f9a7e77e753da637b44c9eb1959ecc69c71cb Mon Sep 17 00:00:00 2001 From: OomsOoms Date: Thu, 3 Oct 2024 01:47:01 +0100 Subject: [PATCH] Added validation to RegisterUserForm Added LoginPage and RegisterPage Added MainLayout --- client/src/App.jsx | 7 +- .../components/RegisterForm.jsx | 87 ++++++++----------- .../authentication/hooks/useRegister.js | 14 +-- .../services/registerService.js | 17 ++-- .../validations/registerValidations.js | 43 +++++++++ client/src/layouts/MainLayout.jsx | 11 +++ client/src/pages/LoginPage.jsx | 17 ++++ client/src/pages/RegisterPage.jsx | 17 ++++ 8 files changed, 140 insertions(+), 73 deletions(-) create mode 100644 client/src/features/authentication/validations/registerValidations.js create mode 100644 client/src/layouts/MainLayout.jsx create mode 100644 client/src/pages/LoginPage.jsx create mode 100644 client/src/pages/RegisterPage.jsx diff --git a/client/src/App.jsx b/client/src/App.jsx index abed406..ab1320d 100644 --- a/client/src/App.jsx +++ b/client/src/App.jsx @@ -1,7 +1,8 @@ import { UserProvider } from './context/userContext.jsx'; import { BrowserRouter, Routes, Route } from "react-router-dom"; import Home from "./pages/home"; -import { RegisterForm, LoginForm } from "./features/authentication"; +import LoginPage from "./pages/LoginPage"; +import RegisterPage from "./pages/RegisterPage"; import './assets/App.css' @@ -12,8 +13,8 @@ export default function App() { } /> - } /> - } /> + } /> + } /> diff --git a/client/src/features/authentication/components/RegisterForm.jsx b/client/src/features/authentication/components/RegisterForm.jsx index 9a58983..8497c94 100644 --- a/client/src/features/authentication/components/RegisterForm.jsx +++ b/client/src/features/authentication/components/RegisterForm.jsx @@ -1,27 +1,36 @@ import { useContext, useState } from 'react'; import Captcha from '../../../components/ui/Captcha.jsx'; + import { UserContext } from '../../../context/userContext.jsx'; import { useRegister } from '../hooks/useRegister.js'; -import validator from 'validator'; +import { emailValidations, passwordValidations, usernameValidations } from '../validations/registerValidations.js'; + const RegisterForm = () => { - const { user, loading } = useContext(UserContext); + // User context + const { user, loading: userContextLoading } = useContext(UserContext); + + // Register service + const { handleRegister, loading: registerLoading, error } = useRegister(); + + // Form state const [username, setUsername] = useState(''); const [email, setEmail] = useState(''); const [password, setPassword] = useState(''); const [captchaToken, setCaptchaToken] = useState(''); - const { handleRegister, loading: registerLoading, error } = useRegister(); + // Form validation const [usernameError, setUsernameError] = useState(''); const [emailError, setEmailError] = useState(''); const [passwordError, setPasswordError] = useState(''); - + const handleUsernameChange = (e) => { - const username = e.target.value; + const username = e.target.value.toLowerCase(); setUsername(username); setUsernameError(usernameValidations(username)); } + const handleEmailChange = (e) => { const email = e.target.value; setEmail(email); @@ -32,58 +41,26 @@ const RegisterForm = () => { setPassword(password); setPasswordError(passwordValidations(password)); }; - // TODO: make functions for each input field and move validations to another file - const usernameValidations = (username) => { - if (!validator.isLength(username, { min: 3 })) { - return 'Username is too short' - } else if (!validator.isLength(username, { max: 20 })) { - return 'Username is too long' - } else if (!validator.matches(username, /^[a-z0-9_.-]+$/)) { - return 'Username must contain only letters, numbers, and ._-' - } - } - const emailValidations = (email) => { - if (!validator.isEmail(email)) { - return 'Invalid email'; - } - } - const passwordValidations = (password) => { - if (!validator.isLength(password, { min: 8 })) { - return 'Password is too short'; - } else if (!/[a-z]/.test(password)) { - return 'Password must contain a lowercase letter'; - } else if (!/[A-Z]/.test(password)) { - return 'Password must contain a capital letter'; - } else if (!/\d/.test(password)) { - return 'Password must contain a number'; - } - } + const onSubmit = (e) => { e.preventDefault(); // Prevent the default form submission - if (!username) { - setUsernameError('Username is required'); - return; - } - if (!email) { - setEmailError('Email is required'); - return; - } - if (!password) { - setPasswordError('Password is required'); - return; - } - if (!captchaToken) { - alert('Please complete the captcha'); + setUsernameError(usernameValidations(username)); + setEmailError(emailValidations(email)); + setPasswordError(passwordValidations(password)); + + if (usernameValidations(username) || emailValidations(email) || passwordValidations(password) || !captchaToken) { + console.log('Form has errors'); return; } + console.log('Form is valid'); const result = handleRegister(username, email, password, captchaToken); - // Reload captcha on fail + // Reload captcha on egister fail if (result !== 201) { console.log('reset captcha') } } - if (loading) { + if (userContextLoading) { return
Loading...
; } @@ -94,34 +71,38 @@ const RegisterForm = () => { return (
- checkUsernameAvailability(username)} // possibly check username availability while typing or on blur /> - {usernameError &&
{usernameError}
} +
{usernameError || '\u00A0'}
{/* Non-breaking space */}
- - {emailError &&
{emailError}
} +
{emailError || '\u00A0'}
{/* Non-breaking space */}
- - {passwordError &&
{passwordError}
} +
{passwordError || '\u00A0'}
{/* Non-breaking space */}