// lib/ui/widgets/daily_reward_sheet.dart import 'package:flutter/material.dart'; import '../../game/daily/daily_reward.dart'; import '../../game/models/booster.dart'; import '../../l10n/gen/app_localizations.dart'; /// Presentational 7-day login calendar. [day] is today's calendar position /// (1..7); past days read as claimed, the future stays locked. [onClaim] fires /// with `false` for a plain claim and `true` for the watch-an-ad "2×" claim. class DailyRewardSheet extends StatelessWidget { const DailyRewardSheet({super.key, required this.day, required this.onClaim}); final int day; final void Function(bool doubled) onClaim; static const _cal = DailyRewardCalendar(); static const _icons = { BoosterType.hammer: Icons.gavel, BoosterType.shuffle: Icons.shuffle, BoosterType.lineBomb: Icons.clear_all, }; @override Widget build(BuildContext context) { final l10n = AppLocalizations.of(context)!; return Padding( padding: const EdgeInsets.all(20), child: Column( mainAxisSize: MainAxisSize.min, children: [ Text( l10n.dailyRewardTitle, style: Theme.of(context).textTheme.titleLarge, ), const SizedBox(height: 16), Wrap( spacing: 8, runSpacing: 8, alignment: WrapAlignment.center, children: [ for (var d = 1; d <= DailyRewardCalendar.cycle; d++) _DayCell( key: ValueKey('daily_day_$d'), day: d, reward: _cal.rewardFor(d), past: d < day, today: d == day, ), ], ), const SizedBox(height: 20), FilledButton( key: const ValueKey('daily_claim'), onPressed: () => onClaim(false), child: Text(l10n.dailyClaim), ), const SizedBox(height: 4), TextButton( key: const ValueKey('daily_double'), onPressed: () => onClaim(true), child: Text(l10n.dailyDoubleWithAd), ), ], ), ); } } class _DayCell extends StatelessWidget { const _DayCell({ super.key, required this.day, required this.reward, required this.past, required this.today, }); final int day; final Map reward; final bool past; final bool today; @override Widget build(BuildContext context) { final scheme = Theme.of(context).colorScheme; return Opacity( opacity: past ? 0.45 : 1, child: Container( width: 66, padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 4), decoration: BoxDecoration( borderRadius: BorderRadius.circular(10), color: today ? scheme.primary.withValues(alpha: 0.25) : Colors.white.withValues(alpha: 0.06), border: today ? Border.all(color: scheme.primary, width: 2) : null, ), child: Column( mainAxisSize: MainAxisSize.min, children: [ Text('$day', style: Theme.of(context).textTheme.labelMedium), const SizedBox(height: 4), Wrap( spacing: 2, runSpacing: 2, alignment: WrapAlignment.center, children: [ for (final entry in reward.entries) _RewardIcon( icon: DailyRewardSheet._icons[entry.key]!, count: entry.value, ), ], ), if (past) const Padding( padding: EdgeInsets.only(top: 2), child: Icon(Icons.check_circle, size: 14, color: Colors.greenAccent), ), ], ), ), ); } } class _RewardIcon extends StatelessWidget { const _RewardIcon({required this.icon, required this.count}); final IconData icon; final int count; @override Widget build(BuildContext context) { return Row( mainAxisSize: MainAxisSize.min, children: [ Icon(icon, size: 14), Text('$count', style: const TextStyle(fontSize: 11)), ], ); } }