Files
Hotel-Booking/docs/REGISTER_FORM_COMPLETE.md
Iliyan Angelov 93d4c1df80 update
2025-11-16 15:12:43 +02:00

12 KiB

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

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)

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

{isLoading ? (
  <>
    <Loader2 className="animate-spin" />
    Processing...
  </>
) : (
  <>
    <UserPlus />
    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

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

{
  name: string;      // "John Doe"
  email: string;     // "user@example.com"
  password: string;  // "Password123@"
  phone?: string;    // "0123456789" (optional)
}

Response (Success)

{
  "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

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

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

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

http://localhost:5173/register

Example Registration

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

  • Create RegisterPage.tsx component
  • Implement React Hook Form
  • Add Yup validation schema
  • Add 5 form fields (name, email, phone, password, confirmPassword)
  • Show/hide password toggle (2 fields)
  • Password strength indicator
  • Real-time requirements checker
  • Loading state
  • Error display (inline + global)
  • Integration with useAuthStore
  • Redirect to /login after success
  • Toast notifications
  • Add route to App.tsx
  • Responsive design
  • Purple color scheme
  • Icons integration (Lucide React)
  • Terms & Privacy links
  • 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