122 lines
3.2 KiB
Dart
122 lines
3.2 KiB
Dart
/// 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;
|
|
}
|