This commit is contained in:
Phuoc Nguyen
2025-10-24 17:35:39 +07:00
parent 82ce30961b
commit 860a8788b6
17 changed files with 2572 additions and 32 deletions

View File

@@ -0,0 +1,121 @@
/// Loyalty Points Provider
///
/// State management for user's loyalty points and balance information.
library;
import 'package:riverpod_annotation/riverpod_annotation.dart';
part 'loyalty_points_provider.g.dart';
/// Loyalty Points State
///
/// Contains user's available points and expiration information.
class LoyaltyPointsState {
/// Current available points
final int availablePoints;
/// Points that will expire soon
final int expiringPoints;
/// Expiration date for expiring points
final DateTime? expirationDate;
/// Points earned this month
final int earnedThisMonth;
/// Points spent this month
final int spentThisMonth;
const LoyaltyPointsState({
required this.availablePoints,
required this.expiringPoints,
this.expirationDate,
required this.earnedThisMonth,
required this.spentThisMonth,
});
/// Factory for initial state
factory LoyaltyPointsState.initial() {
return const LoyaltyPointsState(
availablePoints: 0,
expiringPoints: 0,
expirationDate: null,
earnedThisMonth: 0,
spentThisMonth: 0,
);
}
/// Copy with method
LoyaltyPointsState copyWith({
int? availablePoints,
int? expiringPoints,
DateTime? expirationDate,
int? earnedThisMonth,
int? spentThisMonth,
}) {
return LoyaltyPointsState(
availablePoints: availablePoints ?? this.availablePoints,
expiringPoints: expiringPoints ?? this.expiringPoints,
expirationDate: expirationDate ?? this.expirationDate,
earnedThisMonth: earnedThisMonth ?? this.earnedThisMonth,
spentThisMonth: spentThisMonth ?? this.spentThisMonth,
);
}
}
/// Loyalty Points Provider
///
/// Manages user's loyalty points balance.
/// Currently returns mock data matching the HTML design.
@riverpod
class LoyaltyPoints extends _$LoyaltyPoints {
@override
LoyaltyPointsState build() {
// Mock data matching HTML design: 9,750 points available
// 1,200 points expiring on 31/12/2023
return LoyaltyPointsState(
availablePoints: 9750,
expiringPoints: 1200,
expirationDate: DateTime(2023, 12, 31),
earnedThisMonth: 2500,
spentThisMonth: 800,
);
}
/// Refresh points data
Future<void> refresh() async {
// TODO: Fetch from API
// For now, just reset to mock data
state = build();
}
/// Deduct points after redemption
void deductPoints(int points) {
if (state.availablePoints >= points) {
state = state.copyWith(
availablePoints: state.availablePoints - points,
spentThisMonth: state.spentThisMonth + points,
);
}
}
/// Add points (e.g., from earning activity)
void addPoints(int points) {
state = state.copyWith(
availablePoints: state.availablePoints + points,
earnedThisMonth: state.earnedThisMonth + points,
);
}
/// Check if user has enough points for a redemption
bool hasEnoughPoints(int requiredPoints) {
return state.availablePoints >= requiredPoints;
}
}
/// Provider to check if user has enough points for a specific amount
@riverpod
bool hasEnoughPoints(Ref ref, int requiredPoints) {
final points = ref.watch(loyaltyPointsProvider).availablePoints;
return points >= requiredPoints;
}