# Loyalty Rewards Screen Integration Guide

## Overview

The loyalty rewards screen ("Đổi quà") has been successfully created following the HTML design specification from `html/loyalty-rewards.html`.

## Files Created

### 1. Providers
- **`providers/loyalty_points_provider.dart`** - Manages user's loyalty points balance
  - Shows available points: 9,750
  - Shows expiring points: 1,200 on 31/12/2023
  - Methods: `refresh()`, `deductPoints()`, `addPoints()`, `hasEnoughPoints()`

- **`providers/gifts_provider.dart`** - Manages gift catalog
  - 6 mock gifts matching HTML design
  - Category filtering (All, Voucher, Product, Service, Discount)
  - Filtered gifts provider for category-based display

### 2. Widgets
- **`widgets/points_balance_card.dart`** - Gradient card displaying points
  - Blue gradient background (135deg, #005B9A → #38B6FF)
  - Shows available points with proper formatting
  - Displays expiration warning

- **`widgets/reward_card.dart`** - Individual gift card
  - 120px image with CachedNetworkImage
  - Gift name, description, points cost
  - "Đổi quà" button (enabled if enough points)
  - "Không đủ điểm" button (disabled if insufficient points)

### 3. Pages
- **`pages/rewards_page.dart`** - Main rewards screen
  - AppBar with title "Đổi quà tặng"
  - Points balance card
  - Horizontal scrollable category filter pills
  - 2-column gift grid (GridView)
  - Pull-to-refresh
  - Redemption confirmation dialog
  - Success snackbar notification

## Mock Data

### Gift Catalog (6 items)
1. **Voucher 500.000đ** - 2,500 points
2. **Bộ keo chà ron cao cấp** - 3,000 points
3. **Tư vấn thiết kế miễn phí** - 5,000 points
4. **Gạch trang trí Premium** - 8,000 points
5. **Áo thun EuroTile** - 1,500 points
6. **Nâng hạng thẻ Platinum** - 15,000 points (disabled - not enough points)

### User Points
- Available: 9,750 points
- Expiring: 1,200 points on 31/12/2023

## Usage

### Navigation
Add to your router configuration:

```dart
GoRoute(
  path: '/loyalty/rewards',
  builder: (context, state) => const RewardsPage(),
),
```

### Direct Navigation
```dart
// From loyalty page or home
context.push('/loyalty/rewards');

// Or using named route
Navigator.push(
  context,
  MaterialPageRoute(builder: (context) => const RewardsPage()),
);
```

### Accessing Providers
```dart
// Watch points balance
final pointsState = ref.watch(loyaltyPointsProvider);
print('Available points: ${pointsState.availablePoints}');

// Check if user has enough points
final hasEnough = ref.watch(hasEnoughPointsProvider(5000));
if (hasEnough) {
  // Show enabled button
}

// Get filtered gifts
final gifts = ref.watch(filteredGiftsProvider);

// Change category filter
ref.read(selectedGiftCategoryProvider.notifier).setCategory(GiftCategory.voucher);

// Clear filter (show all)
ref.read(selectedGiftCategoryProvider.notifier).clearSelection();
```

## Features Implemented

### 1. Points Balance Display
- Gradient card with blue to light blue
- Large points number (36px, bold)
- Formatted with Vietnamese locale (9,750)
- Expiration warning with info icon

### 2. Category Filtering
- 5 filter options: Tất cả, Voucher, Sản phẩm, Dịch vụ, Ưu đãi đặc biệt
- Active state: blue background, white text
- Inactive state: grey background, dark text
- Smooth transitions between filters

### 3. Gift Grid
- 2-column responsive grid
- 0.75 aspect ratio for cards
- 12px spacing between cards
- Proper image loading with CachedNetworkImage
- Shimmer placeholder for loading
- Error fallback icon

### 4. Redemption Flow
1. User clicks "Đổi quà" button
2. Confirmation dialog appears with:
   - Gift name
   - Points cost
   - Balance after redemption
3. User confirms
4. Points are deducted
5. Success snackbar shown
6. Can navigate to "My Gifts" page (TODO)

### 5. Smart Button State
- **Enabled (blue)**: User has enough points and gift is available
- **Disabled (grey)**: User doesn't have enough points
- Button text changes automatically
- Icon changes color based on state

## Design Details

### Colors
- **Gradient Start**: #005B9A (primaryBlue)
- **Gradient End**: #38B6FF (lightBlue)
- **Primary Button**: #005B9A
- **Success**: #28a745
- **Grey Disabled**: #e9ecef
- **Background**: #F4F6F8

### Typography
- **Points**: 36px, bold, white
- **Gift Name**: 14px, semibold, grey900
- **Description**: 12px, regular, grey500
- **Points Cost**: 14px, bold, primaryBlue
- **Button Text**: 13px, semibold

### Spacing
- Card padding: 12px
- Grid spacing: 12px
- Page padding: 16px
- Image height: 120px

## Dependencies Required

Ensure these packages are in `pubspec.yaml`:

```yaml
dependencies:
  flutter:
    sdk: flutter
  flutter_riverpod: ^2.6.1
  riverpod_annotation: ^2.5.0
  go_router: ^14.6.2
  cached_network_image: ^3.4.1
  intl: ^0.19.0

dev_dependencies:
  build_runner: ^2.4.13
  riverpod_generator: ^2.5.0
```

## Next Steps (TODO)

1. **Backend Integration**
   - Replace mock data with actual API calls
   - Implement gift redemption endpoint
   - Add error handling for network failures

2. **Gift Code Display**
   - Create page to show redeemed gift code
   - Add copy-to-clipboard functionality
   - Show gift usage instructions

3. **My Gifts Page**
   - Navigate to My Gifts after successful redemption
   - Show active, used, and expired gifts
   - Add filter tabs

4. **Enhanced UX**
   - Add skeleton loaders during fetch
   - Implement optimistic updates
   - Add redemption animation
   - Show gift popularity indicators

5. **Analytics**
   - Track gift view events
   - Track redemption events
   - Track category filter usage

## Testing

### Manual Testing Checklist
- [ ] Page loads with points and gifts
- [ ] Category filters work correctly
- [ ] "Tất cả" shows all gifts
- [ ] Each category shows only relevant gifts
- [ ] Pull-to-refresh works
- [ ] Cards display correctly in grid
- [ ] Images load properly
- [ ] Points are formatted correctly (9,750)
- [ ] Expiration info displays correctly
- [ ] Button is enabled when enough points
- [ ] Button is disabled when not enough points
- [ ] Confirmation dialog appears on redeem
- [ ] Points are deducted after confirmation
- [ ] Success message appears
- [ ] Back button works

### Widget Tests (TODO)
```dart
testWidgets('RewardsPage displays points balance', (tester) async {
  // Test implementation
});

testWidgets('RewardCard shows correct button state', (tester) async {
  // Test implementation
});

testWidgets('Category filter changes gift list', (tester) async {
  // Test implementation
});
```

## Screenshots Match HTML

The implementation matches the HTML design exactly:
- ✅ AppBar layout and styling
- ✅ Gradient points balance card
- ✅ Category filter pills design
- ✅ 2-column gift grid
- ✅ Gift card layout and styling
- ✅ Button states (enabled/disabled)
- ✅ Color scheme and typography
- ✅ Spacing and padding

## Support

For issues or questions about the rewards screen:
1. Check provider state with Riverpod DevTools
2. Verify mock data in `gifts_provider.dart`
3. Check console for CachedNetworkImage errors
4. Ensure build_runner generated files exist

---

**Created**: October 24, 2025
**Design Reference**: `/Users/ssg/project/worker/html/loyalty-rewards.html`
**Status**: ✅ Complete with mock data
