# Function 5: Register Form - Completed โœ… ## ๐Ÿ“ฆ Files Created/Updated ### 1. **RegisterPage.tsx** - Register form component **Path:** `client/src/pages/auth/RegisterPage.tsx` ### 2. **index.ts** - Export module **Path:** `client/src/pages/auth/index.ts` - Added export RegisterPage ### 3. **App.tsx** - Routing updated **Path:** `client/src/App.tsx` - Added route `/register` ## โœจ Main Features ### 1. Form Fields (5 fields) โœ… **Full Name** (name) - Required, 2-50 characters - Icon: User - Placeholder: "John Doe" โœ… **Email** - Required, valid email format - Icon: Mail - Placeholder: "email@example.com" โœ… **Phone Number** (phone) - Optional - 10-11 digits - Icon: Phone - Placeholder: "0123456789" โœ… **Password** (password) - Required, min 8 chars - Must contain: uppercase, lowercase, number, special char - Show/hide toggle with Eye icon - Icon: Lock โœ… **Confirm Password** (confirmPassword) - Must match password - Show/hide toggle with Eye icon - Icon: Lock ### 2. Password Strength Indicator โœ… **Visual Progress Bar** with 5 levels: 1. ๐Ÿ”ด Very weak (0/5) 2. ๐ŸŸ  Weak (1/5) 3. ๐ŸŸก Medium (2/5) 4. ๐Ÿ”ต Strong (3/5) 5. ๐ŸŸข Very strong (5/5) โœ… **Real-time Requirements Checker:** - โœ…/โŒ At least 8 characters - โœ…/โŒ Lowercase (a-z) - โœ…/โŒ Uppercase (A-Z) - โœ…/โŒ Number (0-9) - โœ…/โŒ Special character (@$!%*?&) ### 3. Validation Rules (Yup Schema) ```typescript name: - Required: "Full name is required" - Min 2 chars: "Full name must be at least 2 characters" - Max 50 chars: "Full name must not exceed 50 characters" - Trim whitespace email: - Required: "Email is required" - Valid format: "Invalid email format" - Trim whitespace phone (optional): - Pattern /^[0-9]{10,11}$/ - Error: "Invalid phone number" password: - Required: "Password is required" - Min 8 chars - Pattern: /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])/ - Error: "Password must contain uppercase, lowercase, number and special characters" confirmPassword: - Required: "Please confirm password" - Must match password: "Passwords do not match" ``` ### 4. UX Features โœ… **Loading State** ```tsx {isLoading ? ( <> Processing... ) : ( <> Register )} ``` โœ… **Show/Hide Password** (2 toggles) - Eye/EyeOff icons - Separate toggle for password and confirmPassword - Visual feedback on hover โœ… **Error Display** - Inline validation errors under each field - Global error message at top of form - Red border for fields with errors โœ… **Success Flow** ```typescript 1. Submit form 2. Validation passes 3. Call useAuthStore.register() 4. Show toast: "Registration successful! Please login." 5. Navigate to /login ``` ### 5. Design & Styling **Color Scheme:** - Primary: purple-600, purple-700 - Background: gradient from-purple-50 to-pink-100 - Success: green-500, green-600 - Error: red-50, red-200, red-600 - Text: gray-600, gray-700, gray-900 **Layout:** ``` โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ ๐Ÿจ Hotel Icon (Purple) โ”‚ โ”‚ Register Account โ”‚ โ”‚ Create a new account to book... โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ โ”‚ โ”‚ [Error message if any] โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚ โ”‚ โ”‚ Full Name โ”‚ โ”‚ โ”‚ โ”‚ [๐Ÿ‘ค John Doe ] โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚ โ”‚ โ”‚ Email โ”‚ โ”‚ โ”‚ โ”‚ [๐Ÿ“ง email@example.com ] โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚ โ”‚ โ”‚ Phone Number (Optional) โ”‚ โ”‚ โ”‚ โ”‚ [๐Ÿ“ฑ 0123456789 ] โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚ โ”‚ โ”‚ Password โ”‚ โ”‚ โ”‚ โ”‚ [๐Ÿ”’ โ€ขโ€ขโ€ขโ€ขโ€ขโ€ขโ€ขโ€ข ๐Ÿ‘๏ธ] โ”‚ โ”‚ โ”‚ โ”‚ โ–“โ–“โ–“โ–“โ–“โ–‘โ–‘โ–‘โ–‘โ–‘ Very strong โ”‚ โ”‚ โ”‚ โ”‚ โœ… At least 8 characters โ”‚ โ”‚ โ”‚ โ”‚ โœ… Lowercase (a-z) โ”‚ โ”‚ โ”‚ โ”‚ โœ… Uppercase (A-Z) โ”‚ โ”‚ โ”‚ โ”‚ โœ… Number (0-9) โ”‚ โ”‚ โ”‚ โ”‚ โœ… Special character โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚ โ”‚ โ”‚ Confirm Password โ”‚ โ”‚ โ”‚ โ”‚ [๐Ÿ”’ โ€ขโ€ขโ€ขโ€ขโ€ขโ€ขโ€ขโ€ข ๐Ÿ‘๏ธ] โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ”‚ โ”‚ โ”‚ [๐Ÿ‘ค Register] โ”‚ โ”‚ โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ โ”‚ Already have an account? Login now โ”‚ โ”‚ โ”‚ โ”‚ Terms & Privacy Policy โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ ``` ## ๐Ÿ”— Integration ### API Endpoint ``` POST /api/auth/register ``` ### Request Body ```typescript { name: string; // "John Doe" email: string; // "user@example.com" password: string; // "Password123@" phone?: string; // "0123456789" (optional) } ``` ### Response (Success) ```json { "status": "success", "message": "User registered successfully", "data": { "user": { "id": 1, "name": "John Doe", "email": "user@example.com", "phone": "0123456789", "role": "customer" }, "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", "refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." } } ``` ### useAuthStore Integration ```typescript const { register: registerUser, isLoading, error, clearError } = useAuthStore(); await registerUser({ name: data.name, email: data.email, password: data.password, phone: data.phone, }); // After success: navigate('/login', { replace: true }); ``` ## ๐Ÿงช Test Scenarios ### 1. Validation Tests **Test Case 1: Empty form** ``` Action: Submit empty form Expected: Show validation errors for name, email, password ``` **Test Case 2: Invalid email** ``` Input: email = "notanemail" Expected: "Invalid email format" ``` **Test Case 3: Short name** ``` Input: name = "A" Expected: "Full name must be at least 2 characters" ``` **Test Case 4: Weak password** ``` Input: password = "abc123" Expected: "Password must contain uppercase, lowercase, number and special characters" Password strength: Weak/Medium ``` **Test Case 5: Password mismatch** ``` Input: password = "Password123@" confirmPassword = "Password456@" Expected: "Passwords do not match" ``` **Test Case 6: Invalid phone** ``` Input: phone = "123" Expected: "Invalid phone number" ``` ### 2. UX Tests **Test Case 7: Password strength indicator** ``` Input: Type password character by character Expected: - Progress bar animates - Color changes: red โ†’ orange โ†’ yellow โ†’ blue โ†’ green - Checkmarks appear as requirements met ``` **Test Case 8: Show/hide password** ``` Action: Click eye icon on password field Expected: Password text becomes visible/hidden Action: Click eye icon on confirmPassword field Expected: Confirm password text becomes visible/hidden ``` **Test Case 9: Loading state** ``` Action: Submit valid form Expected: - Button disabled - Spinner shows - Text changes to "Processing..." ``` ### 3. Integration Tests **Test Case 10: Successful registration** ``` Input: All valid data Expected: 1. API POST /api/auth/register called 2. Toast: "Registration successful! Please login." 3. Redirect to /login ``` **Test Case 11: Email already exists** ``` Input: email = "existing@example.com" Expected: - Error message: "Email already registered" - Toast error displayed - Form remains on page ``` **Test Case 12: Network error** ``` Scenario: Server offline Expected: - Error message: "Registration failed. Please try again." - Toast error displayed ``` ## ๐Ÿ“Š Password Strength Algorithm ```typescript function getPasswordStrength(pwd: string) { let strength = 0; if (pwd.length >= 8) strength++; // +1 if (/[a-z]/.test(pwd)) strength++; // +1 if (/[A-Z]/.test(pwd)) strength++; // +1 if (/\d/.test(pwd)) strength++; // +1 if (/[@$!%*?&]/.test(pwd)) strength++; // +1 return { strength: 0-5, label: ['Very weak', 'Weak', 'Medium', 'Strong', 'Very strong'][strength], color: ['bg-red-500', 'bg-orange-500', 'bg-yellow-500', 'bg-blue-500', 'bg-green-500'][strength] }; } ``` ## ๐ŸŽจ Component Structure ```tsx RegisterPage/ โ”œโ”€โ”€ Header Section โ”‚ โ”œโ”€โ”€ Hotel Icon (purple) โ”‚ โ”œโ”€โ”€ Title: "Register Account" โ”‚ โ””โ”€โ”€ Subtitle โ”‚ โ”œโ”€โ”€ Form Container (white card) โ”‚ โ”œโ”€โ”€ Error Alert (conditional) โ”‚ โ”œโ”€โ”€ Name Input โ”‚ โ”œโ”€โ”€ Email Input โ”‚ โ”œโ”€โ”€ Phone Input (optional) โ”‚ โ”œโ”€โ”€ Password Input โ”‚ โ”‚ โ”œโ”€โ”€ Show/Hide Toggle โ”‚ โ”‚ โ”œโ”€โ”€ Strength Indicator โ”‚ โ”‚ โ””โ”€โ”€ Requirements Checklist โ”‚ โ”œโ”€โ”€ Confirm Password Input โ”‚ โ”‚ โ””โ”€โ”€ Show/Hide Toggle โ”‚ โ””โ”€โ”€ Submit Button (with loading) โ”‚ โ”œโ”€โ”€ Login Link โ”‚ โ””โ”€โ”€ "Already have an account? Login now" โ”‚ โ””โ”€โ”€ Footer Links โ”œโ”€โ”€ Terms of Service โ””โ”€โ”€ Privacy Policy ``` ## ๐Ÿ” Security Features ### 1. Password Validation - Min 8 characters - Requires: uppercase, lowercase, number, special char - Visual feedback for strength ### 2. Confirm Password - Must match original password - Prevents typos ### 3. Client-side Validation - Immediate feedback - Prevents invalid API calls - Better UX ### 4. Server-side Validation - Backend also validates all fields - Checks email uniqueness - Password hashed with bcrypt ## ๐Ÿ“ Code Quality โœ… **TypeScript**: Full type safety โœ… **React Hook Form**: Optimized re-renders โœ… **Yup Validation**: Schema-based validation โœ… **Component Composition**: Reusable PasswordRequirement component โœ… **Accessibility**: Proper labels, IDs, autocomplete โœ… **Error Handling**: Try-catch, user-friendly messages โœ… **Loading States**: Visual feedback during async operations โœ… **Responsive Design**: Works on mobile and desktop โœ… **80 chars/line**: Code formatting standard ## ๐Ÿš€ Usage ### Navigate to Register Page ```bash http://localhost:5173/register ``` ### Example Registration ```typescript Name: "John Doe" Email: "nguyenvana@example.com" Phone: "0123456789" Password: "Password123@" Confirm: "Password123@" Submit โ†’ Success โ†’ Redirect to /login ``` ## ๐Ÿ”„ Flow Diagram ``` User visits /register โ†“ Fill in form fields โ†“ Real-time validation (Yup) โ†“ Password strength updates live โ†“ Submit button clicked โ†“ Frontend validation passes โ†“ Call useAuthStore.register() โ†“ API POST /api/auth/register โ†“ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ†“ โ†“ Success Failure โ†“ โ†“ Toast success Toast error โ†“ โ†“ Navigate Stay on page to /login Show errors ``` ## โœ… Checklist - [x] โœ… Create RegisterPage.tsx component - [x] โœ… Implement React Hook Form - [x] โœ… Add Yup validation schema - [x] โœ… Add 5 form fields (name, email, phone, password, confirmPassword) - [x] โœ… Show/hide password toggle (2 fields) - [x] โœ… Password strength indicator - [x] โœ… Real-time requirements checker - [x] โœ… Loading state - [x] โœ… Error display (inline + global) - [x] โœ… Integration with useAuthStore - [x] โœ… Redirect to /login after success - [x] โœ… Toast notifications - [x] โœ… Add route to App.tsx - [x] โœ… Responsive design - [x] โœ… Purple color scheme - [x] โœ… Icons integration (Lucide React) - [x] โœ… Terms & Privacy links ## ๐Ÿ“š Related Files - `client/src/pages/auth/LoginPage.tsx` - Login form (same design pattern) - `client/src/utils/validationSchemas.ts` - Validation schemas - `client/src/store/useAuthStore.ts` - Auth state management - `client/src/services/api/authService.ts` - API calls - `client/src/App.tsx` - Route configuration --- **Status:** โœ… Function 5 completed **Next:** Function 6 - Forgot Password **Test URL:** http://localhost:5173/register