From f7e85fec9989f75ab17d9f0be7b023eea9739938 Mon Sep 17 00:00:00 2001 From: bender Date: Wed, 11 Mar 2026 19:32:10 +0000 Subject: [PATCH] Add src/app/signup/page.tsx --- src/app/signup/page.tsx | 404 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 404 insertions(+) create mode 100644 src/app/signup/page.tsx diff --git a/src/app/signup/page.tsx b/src/app/signup/page.tsx new file mode 100644 index 0000000..70df99a --- /dev/null +++ b/src/app/signup/page.tsx @@ -0,0 +1,404 @@ +"use client"; + +import { ThemeProvider } from "@/providers/themeProvider/ThemeProvider"; +import NavbarStyleCentered from '@/components/navbar/NavbarStyleCentered/NavbarStyleCentered'; +import { useState } from 'react'; +import { Mail, Lock, User, Eye, EyeOff, ArrowRight, CheckCircle } from 'lucide-react'; + +export default function SignupPage() { + const [formData, setFormData] = useState({ + fullName: '', + email: '', + password: '', + confirmPassword: '' + }); + const [showPassword, setShowPassword] = useState(false); + const [showConfirmPassword, setShowConfirmPassword] = useState(false); + const [errors, setErrors] = useState>({}); + const [isSubmitting, setIsSubmitting] = useState(false); + const [passwordStrength, setPasswordStrength] = useState(0); + const [agreedToTerms, setAgreedToTerms] = useState(false); + + const calculatePasswordStrength = (pwd: string) => { + let strength = 0; + if (pwd.length >= 8) strength++; + if (pwd.match(/[a-z]/) && pwd.match(/[A-Z]/)) strength++; + if (pwd.match(/[0-9]/)) strength++; + if (pwd.match(/[^a-zA-Z0-9]/)) strength++; + setPasswordStrength(strength); + }; + + const validateForm = () => { + const newErrors: Record = {}; + + if (!formData.fullName.trim()) { + newErrors.fullName = 'Full name is required'; + } + + if (!formData.email) { + newErrors.email = 'Email is required'; + } else if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(formData.email)) { + newErrors.email = 'Please enter a valid email'; + } + + if (!formData.password) { + newErrors.password = 'Password is required'; + } else if (formData.password.length < 8) { + newErrors.password = 'Password must be at least 8 characters'; + } else if (passwordStrength < 2) { + newErrors.password = 'Password is too weak'; + } + + if (!formData.confirmPassword) { + newErrors.confirmPassword = 'Please confirm your password'; + } else if (formData.password !== formData.confirmPassword) { + newErrors.confirmPassword = 'Passwords do not match'; + } + + if (!agreedToTerms) { + newErrors.terms = 'You must agree to the terms'; + } + + setErrors(newErrors); + return Object.keys(newErrors).length === 0; + }; + + const handleChange = (e: React.ChangeEvent) => { + const { name, value } = e.target; + setFormData(prev => ({ ...prev, [name]: value })); + + if (name === 'password') { + calculatePasswordStrength(value); + } + }; + + const handleSubmit = async (e: React.FormEvent) => { + e.preventDefault(); + + if (!validateForm()) { + return; + } + + setIsSubmitting(true); + try { + // Simulated API call + await new Promise(resolve => setTimeout(resolve, 1000)); + console.log('Signup attempt:', { ...formData, confirmPassword: undefined }); + // In a real app, you would create account and redirect + } finally { + setIsSubmitting(false); + } + }; + + const getPasswordStrengthColor = () => { + if (passwordStrength <= 1) return '#ef4444'; + if (passwordStrength <= 2) return '#eab308'; + if (passwordStrength <= 3) return '#f97316'; + return '#22c55e'; + }; + + const getPasswordStrengthText = () => { + if (!formData.password) return ''; + if (passwordStrength <= 1) return 'Weak'; + if (passwordStrength <= 2) return 'Fair'; + if (passwordStrength <= 3) return 'Good'; + return 'Strong'; + }; + + return ( + + + +
+
+
+ {/* Header */} +
+

+ Create Account +

+

+ Join 150k+ athletes transforming their bodies +

+
+ + {/* Form */} +
+ {/* Full Name Field */} +
+ +
+ + +
+ {errors.fullName && ( +

+ {errors.fullName} +

+ )} +
+ + {/* Email Field */} +
+ +
+ + +
+ {errors.email && ( +

+ {errors.email} +

+ )} +
+ + {/* Password Field */} +
+ +
+ + + +
+ + {/* Password Strength Indicator */} + {formData.password && ( +
+
+
+
+ + {getPasswordStrengthText()} + +
+ )} + + {errors.password && ( +

+ {errors.password} +

+ )} +
+ + {/* Confirm Password Field */} +
+ +
+ + + +
+ {errors.confirmPassword && ( +

+ {errors.confirmPassword} +

+ )} +
+ + {/* Terms Agreement */} +
+
+ + ); +} \ No newline at end of file