diff --git a/frontend/app/components/popup/SignUpForm.tsx b/frontend/app/components/popup/SignUpForm.tsx new file mode 100644 index 0000000..f33d69c --- /dev/null +++ b/frontend/app/components/popup/SignUpForm.tsx @@ -0,0 +1,317 @@ +"use client"; + +import React, { useState } from "react"; +import Image from "next/image"; +import Link from "next/link"; +import navLogo from "@/app/public/signupNavLogo.svg"; +import signupLogo from "@/app/public/signupLogo.svg"; +import signupWallpaper from "@/app/public/signupWallpaper.png"; +import googleIcon from "@/app/public/googleIcon.svg"; +import showPasswordIcon from "@/app/public/showPasswordIcon.svg"; + +/** + * The SignUpForm component renders a sign up form with fields for email, password, + * checkbox for accepting terms and conditions, and an optional checkbox for + * receiving updates. The form also includes a button to sign up with Google. + * The component handles form submission and validation. + * + * @returns The SignUpForm component. + */ +export default function SignUpForm() { + const [formData, setFormData] = useState({ + email: "", + password: "", + acceptTerms: false, + receiveUpdates: false, + }); + + const [passwordError, setPasswordError] = useState(""); + const [generalError, setGeneralError] = useState(""); + const [passwordVisible, setPasswordVisible] = useState(false); + + /** + * Handles input change events by updating the formData state with the new + * value of the input element. If the input element is the password field, + * it also validates the password and sets the passwordError state + * accordingly. + * + * @param {React.ChangeEvent} e - The input change event. + */ + const handleInputChange = (e: React.ChangeEvent) => { + const { name, value, type, checked } = e.target; + setFormData({ + ...formData, + [name]: type === "checkbox" ? checked : value, + }); + + if (name === "password") { + validatePassword(value); + } + }; + + /** + * Validates the provided password against a set of criteria. + * Sets an error message if the password does not meet the requirements. + * Criteria: Password must be at least 8 characters long, include at least + * one uppercase letter, one lowercase letter, one number, and one special character. + * + * @param {string} password - The password to validate. + */ + const validatePassword = (password: string) => { + const passwordRegex = + /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[A-Za-z\d!@#$%^&*(),.?":{}|<>]{8,}$/; + + if (!passwordRegex.test(password)) { + setPasswordError( + "Password must be at least 8 characters long, include one uppercase letter, one lowercase letter, and one number." + ); + } else { + setPasswordError(""); + } + }; + + /** + * Handles the sign up form submission by preventing the default form submission + * behavior, validating the password, and attempting to submit the form data + * to a mock API (or actual API call). If the password is invalid, it logs a + * message to the console and returns early. If the API call is successful, it + * resets any previous error and resets the form data. If the API call fails, + * it sets a general error message. + * + * @param {React.FormEvent} e - The form submission event. + */ + const handleSignUp = async (e: React.FormEvent) => { + e.preventDefault(); + + if (passwordError) { + console.log("Fix password issues before submitting."); + return; + } + + try { + // Mock API call or form submission logic + console.log("Form data:", formData); + setGeneralError(""); // Reset any previous error on successful submission + // Reset the form data upon success (you can adjust this according to your needs) + setFormData({ + email: "", + password: "", + acceptTerms: false, + receiveUpdates: false, + }); + } catch (error) { + setGeneralError( + "An error occurred while submitting the form. Please try again later." + ); + } + }; + + /** + * Redirects the user to the Google Sign-In page. This function is called + * when the user clicks the "Sign up with Google" button. + */ + const handleGoogleSignUp = () => { + console.log("Redirecting to Google Sign-In..."); + }; + + /** + * Toggles the visibility of the password input field. When the user clicks the + * "Show password" button, this function is called to toggle the state of the + * `passwordVisible` state variable. + */ + const togglePasswordVisibility = () => { + setPasswordVisible(!passwordVisible); + }; + + return ( +
+ {/* Navbar */} +
+ Logo linking to the homepage +
+ +
+ +
+ {/* Left Form Section */} +
+
+
+

Welcome to

+
+ Signup logo +
+

+ Let’s sign up quickly to get started. +

+
+ + + +
+
+ or +
+
+ + {generalError && ( +
+ {generalError} +
+ )} + +
+
+ + + {formData.email && !/\S+@\S+\.\S+/.test(formData.email) && ( + + )} +
+ +
+ +
+ +
+ Toggle password visibility +
+
+ {passwordError && ( + + )} +
+ +
+ +
+ +
+ +
+ + +
+ +

+ Already have an account?{" "} + + Login + +

+
+
+ + {/* Right Image Section */} +
+ Signup background wallpaper +
+
+
+ ); +} diff --git a/frontend/app/components/popup/index.ts b/frontend/app/components/popup/index.ts index 87fad05..68fefc1 100644 --- a/frontend/app/components/popup/index.ts +++ b/frontend/app/components/popup/index.ts @@ -1,2 +1,2 @@ -export {default as LogIn} from './login' -export {default as Signup} from './signup' \ No newline at end of file +export { default as LogIn } from "./login"; +export { default as Signup } from "./signup"; diff --git a/frontend/app/components/popup/signup.tsx b/frontend/app/components/popup/signup.tsx index 4847197..96eea9d 100644 --- a/frontend/app/components/popup/signup.tsx +++ b/frontend/app/components/popup/signup.tsx @@ -1,11 +1,7 @@ -import React from 'react' +import React from "react"; const signup = () => { - return ( -
- -
- ) -} + return
; +}; -export default signup +export default signup; diff --git a/frontend/app/public/googleIcon.svg b/frontend/app/public/googleIcon.svg new file mode 100644 index 0000000..749da77 --- /dev/null +++ b/frontend/app/public/googleIcon.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/frontend/app/public/showPasswordIcon.svg b/frontend/app/public/showPasswordIcon.svg new file mode 100644 index 0000000..505c114 --- /dev/null +++ b/frontend/app/public/showPasswordIcon.svg @@ -0,0 +1,3 @@ + + + diff --git a/frontend/app/public/signupLogo.svg b/frontend/app/public/signupLogo.svg new file mode 100644 index 0000000..d054df4 --- /dev/null +++ b/frontend/app/public/signupLogo.svg @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/app/public/signupNavLogo.svg b/frontend/app/public/signupNavLogo.svg new file mode 100644 index 0000000..117f6e0 --- /dev/null +++ b/frontend/app/public/signupNavLogo.svg @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/app/public/signupWallpaper.png b/frontend/app/public/signupWallpaper.png new file mode 100644 index 0000000..71233af Binary files /dev/null and b/frontend/app/public/signupWallpaper.png differ diff --git a/frontend/app/public/signupWallpaper.svg b/frontend/app/public/signupWallpaper.svg new file mode 100644 index 0000000..3e244e6 --- /dev/null +++ b/frontend/app/public/signupWallpaper.svg @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/app/sign-up/page.tsx b/frontend/app/sign-up/page.tsx new file mode 100644 index 0000000..237db51 --- /dev/null +++ b/frontend/app/sign-up/page.tsx @@ -0,0 +1,11 @@ +"use client"; + +import SignUpForm from "../components/popup/SignUpForm"; + +export default function SignUpPage() { + return ( +
+ +
+ ); +}