# GoodGo Frontend: Tham chiếu nhanh triển khai i18n + A11y

## 🎯 Những phát hiện chính trong nháy mắt

### Trạng thái hiện tại
- ✅ **Next.js 15** với App Router (cấu trúc tốt)
- ✅ **React 18** + TypeScript (an toàn kiểu)
- ✅ **Tailwind CSS** với hỗ trợ dark mode (theme dựa trên HSL)
- ✅ **Thư viện component tốt** (~35 component)
- ✅ **Một số kiến thức cơ bản về A11y** đã có (HTML ngữ nghĩa, ARIA labels, skip link)
- ❌ **CHƯA thiết lập i18n** (tất cả tiếng Việt được hardcode)
- ❌ **Thiếu sót A11y** (quản lý focus, một số ARIA còn thiếu, tương phản màu chưa xác định)

### Điểm vào chiến lược cho việc triển khai

#### 1. **Điểm vào i18n** (Ưu tiên 1)
```
Files to modify for i18n:
├── app/layout.tsx                    → Add i18n provider
├── middleware.ts                     → Add locale routing
├── app/(public)/layout.tsx           → Navigation text
├── app/(auth)/login/page.tsx         → Form labels + errors
├── app/(auth)/register/page.tsx      → Form labels + errors
├── components/listings/listing-form-steps.tsx → Multi-step form labels
├── components/search/filter-bar.tsx  → Filter options + city names
├── lib/validations/*.ts             → Zod error messages
└── [All other components with text]

Total files to update: ~25-30 files with hardcoded strings
```

#### 2. **Sửa lỗi A11y quan trọng** (Ưu tiên 1.5)
```
Components needing A11y updates:
├── components/ui/dialog.tsx         → Focus trapping + focus restoration
├── components/listings/image-gallery.tsx → Keyboard nav + ARIA
├── components/search/filter-bar.tsx  → Proper labeling + ARIA
├── app/(dashboard)/layout.tsx        → Tab focus management
└── Across all forms                 → Error message association

Tasks:
- Add focus trapping in modals
- Verify color contrast (WCAG AA)
- Add aria-busy to loading states
- Add proper aria-label to icon buttons
- Link form errors to inputs with aria-describedby
```

#### 3. **Cấu trúc file Message cho i18n**
```
public/locales/
├── en.json
│   ├── common: { home, search, dashboard, logout, ... }
│   ├── auth: { login, register, email, password, ... }
│   ├── property: { apartment, house, villa, ... }
│   ├── transaction: { sale, rent, ... }
│   ├── directions: { north, south, east, ... }
│   ├── status: { draft, active, sold, ... }
│   ├── validation: { required, min_length, ... }
│   └── errors: { oauth_failed, access_denied, ... }
└── vi.json
    └── [Same structure]
```

---

## 📋 Checklist triển khai

### Giai đoạn 1: Thiết lập (2-3 giờ)
- [ ] Cài đặt gói `next-intl`
- [ ] Tạo các file message (en.json, vi.json)
- [ ] Cập nhật next.config.js cho routing i18n
- [ ] Tạo cấu hình i18n (config.ts)
- [ ] Cập nhật middleware.ts để phát hiện locale
- [ ] Bao bọc root layout bằng provider i18n

### Giai đoạn 2: Tái cấu trúc cốt lõi (6-8 giờ)
- [ ] Cập nhật root layout & metadata
- [ ] Tái cấu trúc tất cả validation (Zod) để sử dụng messages
- [ ] Trích xuất chuỗi component sang useTranslations()
- [ ] Cập nhật tất cả các enum (TRANSACTION_TYPES, PROPERTY_TYPES, v.v.) để sử dụng i18n
- [ ] Cập nhật các page layout (public, auth, dashboard)
- [ ] Cập nhật toàn bộ nội dung trang

### Giai đoạn 3: Cập nhật component (4-6 giờ)
- [ ] Cập nhật tất cả các component UI
- [ ] Cập nhật các component form
- [ ] Cập nhật các component navigation
- [ ] Cập nhật các component search/filter
- [ ] Cập nhật form đăng tin (listing form)

### Giai đoạn 4: Sửa lỗi A11y (4-6 giờ)
- [ ] Sửa quản lý focus trong dialog
- [ ] Thêm focus trapping
- [ ] Cập nhật liên kết lỗi form (aria-describedby)
- [ ] Thêm aria-busy cho trạng thái loading
- [ ] Thêm aria-label cho các nút biểu tượng
- [ ] Xác minh tương phản màu
- [ ] Cập nhật thiết lập test cho i18n

### Giai đoạn 5: Test & QA (3-4 giờ)
- [ ] Test cả hai locale trên tất cả các trang
- [ ] Chạy kiểm tra khả năng tiếp cận bằng axe DevTools
- [ ] Test điều hướng bằng bàn phím
- [ ] Test tương thích screen reader
- [ ] Cập nhật unit test cho i18n

---

## 🗣️ Kiểm kê nội dung văn bản

### Navigation & Layout (~15 mục)
| Vị trí | Văn bản | Trạng thái |
|----------|------|--------|
| Public header | Trang chủ, Tìm kiếm, Đăng nhập, Đăng ký | ❌ Hardcoded |
| Dashboard nav | 8 mục nav | ❌ Hardcoded |
| Footer | 4 phần | ❌ Hardcoded |

### Forms & Validation (~40+ mục)
| Vị trí | Loại | Số lượng | Trạng thái |
|----------|------|-------|--------|
| Login form | Nhãn + lỗi | 8 | ❌ Hardcoded |
| Register form | Nhãn + lỗi | 10 | ❌ Hardcoded |
| Listing form | Nhãn đa bước | 25+ | ❌ Hardcoded |
| Search filters | Nhãn tùy chọn | 30+ | ❌ Hardcoded |
| Zod validation | Thông báo lỗi | 20+ | ❌ Hardcoded |

### Enum & Hằng số (~50+ mục)
| File | Mục | Trạng thái |
|------|-------|--------|
| TRANSACTION_TYPES | 2 nhãn | ❌ Hardcoded |
| PROPERTY_TYPES | 6 nhãn | ❌ Hardcoded |
| LISTING_STATUSES | 8 nhãn | ❌ Hardcoded |
| DIRECTIONS | 8 nhãn | ❌ Hardcoded |
| CITIES | 13 tên | ❌ Hardcoded |
| PRICE_RANGES | 6 khoảng | ❌ Hardcoded |

### Nội dung trang (~30 mục)
| Trang | Phần | Trạng thái |
|------|----------|--------|
| Trang landing | Hero, search, stats, CTA | ❌ Hardcoded |
| Kết quả tìm kiếm | Không có kết quả, loading, header | ❌ Hardcoded |
| Dashboard | Tiêu đề phần, trạng thái rỗng | ❌ Hardcoded |

---

## 🔑 Các file quan trọng cho i18n

### Các file phải cập nhật (Blocker)
1. **middleware.ts** — Định tuyến locale
2. **app/layout.tsx** — Thiết lập provider i18n
3. **lib/validations/*.ts** — Tích hợp messages
4. **lib/*.ts** — Bất kỳ xử lý thông báo lỗi API nào

### Các file ưu tiên cao
1. **app/(public)/layout.tsx** — Navigation
2. **app/(auth)/login/page.tsx** — Form xác thực
3. **components/listings/listing-form-steps.tsx** — Forms
4. **components/search/filter-bar.tsx** — Bộ lọc

### Các file ưu tiên trung bình
1. Tất cả các component trang
2. Tất cả các component UI có văn bản
3. Các component error boundary

---

## ♿ Ưu tiên triển khai A11y

### Sửa lỗi quan trọng WCAG 2.1 AA
1. **Quản lý focus** (Cấp A)
   - Thêm focus trap trong `dialog.tsx`
   - Khôi phục focus khi đóng dialog
   - Chỉ báo focus rõ ràng trên tất cả các nút

2. **Tương phản màu** (Cấp AA)
   - Chạy kiểm tra axe DevTools
   - Sửa văn bản có tỷ lệ < 4.5:1
   - Sửa đồ họa có tỷ lệ < 3:1

3. **Khả năng tiếp cận form** (Cấp A)
   - Liên kết tất cả thông báo lỗi với aria-describedby
   - Gắn nhãn đúng cách với htmlFor
   - Nhóm fieldset cho các form phức tạp

4. **Trạng thái Loading** (Cấp A)
   - Thêm aria-busy cho spinner
   - Thêm aria-label kèm ngữ cảnh

5. **Nút biểu tượng** (Cấp A)
   - Tất cả các nút chỉ có biểu tượng cần aria-label
   - Nút bật/tắt theme đã có nhãn ✓

### Các cải tiến A11y nên có
- Skip link đã có sẵn ✓
- HTML ngữ nghĩa đã được sử dụng ✓
- Role="alert" trên lỗi ✓
- aria-invalid trên các trường form ✓

---

## 📦 Các phụ thuộc cần thêm

```bash
npm install next-intl

# No new devDependencies needed if using next-intl
# Testing with mocked i18n available
```

**Tổng kích thước cài đặt:** ~500KB đã minify

---

## 🧪 Chiến lược test

### Unit Tests
```typescript
// vitest.setup.ts - Mock i18n
vi.mock('next-intl', () => ({
  useTranslations: () => (key) => mockMessages[key]
}));
```

### Component Tests
```typescript
// Test both locales
describe('LoginForm', () => {
  it('renders Vietnamese labels', () => { ... });
  it('renders English labels', () => { ... });
});
```

### E2E Tests
```typescript
// Test locale switching
- /en/login → English
- /vi/login → Vietnamese
- /en/dashboard → English dashboard
```

---

## 📊 Lộ trình ước tính

| Giai đoạn | Thời gian | Công sức |
|-------|----------|--------|
| Thiết lập | 2-3h | Thấp |
| Tái cấu trúc cốt lõi | 6-8h | Trung bình |
| Components | 4-6h | Trung bình |
| Sửa lỗi A11y | 4-6h | Thấp-Trung bình |
| Testing | 3-4h | Trung bình |
| **Tổng** | **19-27h** | **~3-4 ngày** |

---

## 🚀 Thứ tự triển khai (Khuyến nghị)

1. **Thiết lập hạ tầng i18n** (tạo nền tảng)
2. **Cập nhật middleware + root layout** (kích hoạt routing)
3. **Trích xuất & tập trung tất cả văn bản** (công việc chính)
4. **Sửa các vấn đề A11y** (song song với #3)
5. **Test kỹ lưỡng** (xác minh cuối cùng)

---

## 💡 Cơ hội thắng nhanh

Những việc có thể làm ngay:
1. Tạo cấu trúc file message (30 phút)
2. Thêm focus trap cho dialog (30 phút)
3. Thêm aria-busy cho spinner (20 phút)
4. Kiểm tra tương phản màu (1 giờ)
5. Aria-label cho nút biểu tượng (30 phút)

---

## 📝 Ghi chú khi triển khai

### Phát hiện locale (middleware)
```typescript
// Check in order: URL > cookie > header > default
function getLocale(request) {
  // 1. URL pathname: /en/* or /vi/*
  // 2. Cookie: goodgo_locale
  // 3. Header: Accept-Language
  // 4. Default: vi
}
```

### Chiến lược dự phòng Message
```typescript
// If translation missing, use English as fallback
// Otherwise fallback to Vietnamese (primary)
```

### Cân nhắc về hiệu năng
- Giữ các file message < 100KB mỗi file
- Lazy load message theo trang nếu cần
- Static generation cho các trang quan trọng về SEO

---

**Cập nhật lần cuối:** Ngày 9 tháng 4 năm 2026  
**Phiên bản:** 1.0 - Trước triển khai  
**Độ tin cậy:** Cao
