/// Refine a single pile — promote / demote cards (Important Cards pattern). 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'; import '../utils/app_theme.dart'; class PileReviewScreen extends StatelessWidget { const PileReviewScreen({super.key}); @override Widget build(BuildContext context) { final sort = context.watch(); final pile = sort.reviewPile ?? ValuePile.important; final cards = sort.cardsInPile(pile); final text = Theme.of(context).textTheme; final colors = Theme.of(context).colorScheme; return PracticeScaffold( header: Padding( padding: const EdgeInsets.fromLTRB(8, 4, 12, 0), child: Row( children: [ IconButton( onPressed: sort.goToOverview, icon: const Icon(Icons.arrow_back), ), Expanded( child: Text( 'Reviewing · ${pile.label}', style: text.labelMedium, ), ), ], ), ), footer: PrimaryPillButton( label: 'Back to overview', onPressed: sort.goToOverview, ), child: ListView( children: [ Text(pile.label, style: text.displaySmall), const SizedBox(height: 6), Text( '${cards.length} values in this pile. Promote toward your core or demote when something feels less essential.', style: text.bodyMedium, ), const SizedBox(height: 12), SingleChildScrollView( scrollDirection: Axis.horizontal, child: Row( children: ValuePile.values.map((p) { return Padding( padding: const EdgeInsets.only(right: 8), child: ActionChip( avatar: CircleAvatar( backgroundColor: p.accent.withValues(alpha: 0.2), radius: 8, ), label: Text('${p.shortLabel} ${sort.countInPile(p)}'), onPressed: () => sort.openPileReview(p), backgroundColor: p == pile ? AppTheme.surfaceContainerHigh : AppTheme.surfaceContainerLow, ), ); }).toList(), ), ), const SizedBox(height: 16), if (cards.isEmpty) Padding( padding: const EdgeInsets.symmetric(vertical: 40), child: Text( 'No cards in this pile yet.', style: text.bodyLarge?.copyWith(color: colors.onSurfaceVariant), textAlign: TextAlign.center, ), ) else ...cards.map((card) { return Padding( padding: const EdgeInsets.only(bottom: 12), child: ValueCardTile( card: card, compact: true, trailing: Row( mainAxisSize: MainAxisSize.min, children: [ IconButton( tooltip: 'Promote', onPressed: () => _shift(sort, card.id, pile, up: true), icon: const Icon(Icons.arrow_upward), ), IconButton( tooltip: 'Demote', onPressed: () => _shift(sort, card.id, pile, up: false), icon: const Icon(Icons.arrow_downward), ), ], ), ), ); }), ], ), ); } void _shift( ValuesSortController sort, String id, ValuePile current, { required bool up, }) { final values = ValuePile.values; final index = values.indexOf(current); final next = up ? index - 1 : index + 1; if (next < 0 || next >= values.length) return; sort.moveCard(id, values[next]); } }