Files
Eventify-frontend/lib/features/gamification/providers/gamification_provider.dart
Sicherhaven 50caad21a5 release: bump version to 1.4(p) (versionCode 14)
- Update versionCode 12 → 14, versionName 1.3(p) → 1.4(p)
- Update pubspec.yaml version to 1.4.0+14
- Add CHANGELOG.md with full version history
- Update README.md: version badge + changelog section
- Desktop Contribute Dashboard rebuilt to match web version
  - Contributor Dashboard title, 3-tab nav (Contribute/Leaderboard/Achievements)
  - Two-column submit form, tier milestone progress bar
  - Desktop leaderboard with podium, filters, rank table (green points)
  - Desktop achievements 3-column badge grid
  - Inline Reward Shop with RP balance
- Gamification feature module (EP, RP, leaderboard, achievements, shop)
- Profile screen redesigned to match web app layout with animations
- Home screen bottom sheet date filter chips
- Updated API endpoints, login/event detail screens, theme colors
- Added Gilroy font suite, responsive layout improvements
2026-03-18 11:10:56 +05:30

125 lines
4.1 KiB
Dart

// lib/features/gamification/providers/gamification_provider.dart
import 'package:flutter/foundation.dart';
import '../models/gamification_models.dart';
import '../services/gamification_service.dart';
class GamificationProvider extends ChangeNotifier {
final GamificationService _service = GamificationService();
// State
UserGamificationProfile? profile;
List<LeaderboardEntry> leaderboard = [];
List<ShopItem> shopItems = [];
List<AchievementBadge> achievements = [];
// Leaderboard filters — matches web version
String leaderboardDistrict = 'Overall Kerala';
String leaderboardTimePeriod = 'all_time'; // 'all_time' | 'this_month'
bool isLoading = false;
String? error;
// ---------------------------------------------------------------------------
// Load everything at once (called when ContributeScreen is mounted)
// ---------------------------------------------------------------------------
Future<void> loadAll() async {
isLoading = true;
error = null;
notifyListeners();
try {
final results = await Future.wait([
_service.getProfile(),
_service.getLeaderboard(district: leaderboardDistrict, timePeriod: leaderboardTimePeriod),
_service.getShopItems(),
_service.getAchievements(),
]);
profile = results[0] as UserGamificationProfile;
leaderboard = results[1] as List<LeaderboardEntry>;
shopItems = results[2] as List<ShopItem>;
achievements = results[3] as List<AchievementBadge>;
} catch (e) {
error = e.toString();
} finally {
isLoading = false;
notifyListeners();
}
}
// ---------------------------------------------------------------------------
// Change district filter
// ---------------------------------------------------------------------------
Future<void> setDistrict(String district) async {
if (leaderboardDistrict == district) return;
leaderboardDistrict = district;
notifyListeners();
try {
leaderboard = await _service.getLeaderboard(district: district, timePeriod: leaderboardTimePeriod);
} catch (e) {
error = e.toString();
}
notifyListeners();
}
// ---------------------------------------------------------------------------
// Change time period filter
// ---------------------------------------------------------------------------
Future<void> setTimePeriod(String period) async {
if (leaderboardTimePeriod == period) return;
leaderboardTimePeriod = period;
notifyListeners();
try {
leaderboard = await _service.getLeaderboard(district: leaderboardDistrict, timePeriod: period);
} catch (e) {
error = e.toString();
}
notifyListeners();
}
// ---------------------------------------------------------------------------
// Redeem a shop item — deducts RP locally optimistically, returns voucher code
// ---------------------------------------------------------------------------
Future<String> redeemItem(String itemId) async {
final item = shopItems.firstWhere((s) => s.id == itemId);
// Optimistically deduct RP
if (profile != null) {
profile = UserGamificationProfile(
userId: profile!.userId,
lifetimeEp: profile!.lifetimeEp,
currentEp: profile!.currentEp,
currentRp: profile!.currentRp - item.rpCost,
tier: profile!.tier,
);
notifyListeners();
}
try {
final record = await _service.redeemItem(itemId);
return record.voucherCode;
} catch (e) {
// Rollback on failure
if (profile != null) {
profile = UserGamificationProfile(
userId: profile!.userId,
lifetimeEp: profile!.lifetimeEp,
currentEp: profile!.currentEp,
currentRp: profile!.currentRp + item.rpCost,
tier: profile!.tier,
);
notifyListeners();
}
rethrow;
}
}
// ---------------------------------------------------------------------------
// Submit a contribution
// ---------------------------------------------------------------------------
Future<void> submitContribution(Map<String, dynamic> data) async {
await _service.submitContribution(data);
}
}