/// Stage 1 — assign each value card into one of five reflective piles. library; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import '../models/value_pile.dart'; import '../providers/values_sort_provider.dart'; import '../widgets/practice_chrome.dart'; import '../widgets/value_card_tile.dart'; class CardSortingScreen extends StatelessWidget { const CardSortingScreen({super.key}); @override Widget build(BuildContext context) { final sort = context.watch(); final text = Theme.of(context).textTheme; final colors = Theme.of(context).colorScheme; final card = sort.currentCard; return PracticeScaffold( padding: const EdgeInsets.fromLTRB(20, 4, 20, 8), header: Padding( padding: const EdgeInsets.fromLTRB(12, 4, 12, 0), child: Row( children: [ TextButton.icon( onPressed: sort.sortedCount == 0 ? null : sort.undoLastSort, icon: const Icon(Icons.undo, size: 18), label: const Text('Undo'), ), const Spacer(), Text( 'Stage 1 · Initial Sort', style: text.labelMedium, ), ], ), ), child: Column( children: [ Row( children: [ Icon(Icons.bookmark_border, size: 18, color: colors.onSurfaceVariant), const SizedBox(width: 6), Expanded( child: Text( '${sort.sortedCount} of ${sort.totalCount} values sorted', style: text.labelMedium, ), ), Text( '${(sort.sortProgress * 100).round()}%', style: text.labelMedium?.copyWith( color: colors.primary, fontWeight: FontWeight.w700, ), ), ], ), const SizedBox(height: 8), ClipRRect( borderRadius: BorderRadius.circular(999), child: LinearProgressIndicator( value: sort.sortProgress, minHeight: 6, backgroundColor: colors.surfaceContainerHigh, color: colors.secondary, ), ), const SizedBox(height: 12), Expanded( child: AnimatedSwitcher( duration: const Duration(milliseconds: 280), child: card == null ? Center( key: const ValueKey('empty'), child: Text('All sorted', style: text.headlineMedium), ) : SingleChildScrollView( key: ValueKey(card.id), child: Column( children: [ ValueCardTile(card: card, elevation: 2), const SizedBox(height: 14), Text( 'Tap a pile to sort', style: text.labelMedium?.copyWith( color: colors.onSurfaceVariant, ), ), const SizedBox(height: 8), ...ValuePile.values.map((pile) { return Padding( padding: const EdgeInsets.only(bottom: 8), child: _PileButton( pile: pile, count: sort.countInPile(pile), onTap: () => sort.assignCurrent(pile), ), ); }), ], ), ), ), ), ], ), ); } } class _PileButton extends StatelessWidget { const _PileButton({ required this.pile, required this.count, required this.onTap, }); final ValuePile pile; final int count; final VoidCallback? onTap; @override Widget build(BuildContext context) { final text = Theme.of(context).textTheme; final colors = Theme.of(context).colorScheme; return Material( color: colors.surfaceContainerLow, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(18), side: BorderSide(color: pile.accent.withValues(alpha: 0.35)), ), child: InkWell( onTap: onTap, borderRadius: BorderRadius.circular(18), child: Padding( padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 12), child: Row( children: [ Container( width: 28, height: 28, alignment: Alignment.center, decoration: BoxDecoration( color: pile.accent.withValues(alpha: 0.15), shape: BoxShape.circle, ), child: Text( '${pile.rank}', style: text.labelMedium?.copyWith( color: pile.accent, fontWeight: FontWeight.w700, ), ), ), const SizedBox(width: 12), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( pile.label, style: text.titleMedium?.copyWith( color: colors.onSurface, ), ), Text( pile.subtitle, style: text.bodySmall?.copyWith( color: colors.onSurfaceVariant, ), ), ], ), ), Text( '$count', style: text.labelMedium?.copyWith(color: pile.accent), ), ], ), ), ), ); } }