promotion_list_page.dart 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. import 'package:flutter/material.dart';
  2. import 'package:flutter_riverpod/flutter_riverpod.dart';
  3. import '../../../database/daos/promozioni_dao.dart';
  4. import '../../../providers/database_provider.dart';
  5. import '../../../database/database.dart';
  6. import '../../widgets/empty_state.dart';
  7. class PromotionListPage extends ConsumerWidget {
  8. const PromotionListPage({super.key});
  9. @override
  10. Widget build(BuildContext context, WidgetRef ref) {
  11. final promoDao = ref.read(promozioniDaoProvider);
  12. final promosAsync = promoDao.getActivePromos(DateTime.now().toIso8601String());
  13. final theme = Theme.of(context);
  14. return Scaffold(
  15. appBar: AppBar(title: const Text('Promozioni')),
  16. body: SafeArea(
  17. child: FutureBuilder(
  18. future: promosAsync,
  19. builder: (_, snap) {
  20. if (!snap.hasData) return const Center(child: CircularProgressIndicator());
  21. final promos = snap.data!;
  22. if (promos.isEmpty) return const EmptyState(icon: Icons.local_offer_outlined, title: 'Nessuna promozione attiva');
  23. return ListView.builder(
  24. itemCount: promos.length,
  25. itemBuilder: (_, i) => _PromoCard(promo: promos[i], promoDao: promoDao, theme: theme),
  26. );
  27. },
  28. ),
  29. ),
  30. );
  31. }
  32. }
  33. class _PromoCard extends StatelessWidget {
  34. final Promozione promo;
  35. final PromozioniDao promoDao;
  36. final ThemeData theme;
  37. const _PromoCard({required this.promo, required this.promoDao, required this.theme});
  38. @override
  39. Widget build(BuildContext context) {
  40. final tipoLabel = switch (promo.tipoPromozione) {
  41. 2 => 'Articolo Omaggio',
  42. 3 => 'Listino Omaggio',
  43. 4 => 'Omaggio a Scelta',
  44. 5 => 'Omaggio Automatico',
  45. 6 => 'Omaggio per Importo',
  46. 9 => 'Sconto Quantità',
  47. _ => 'Tipo ${promo.tipoPromozione}',
  48. };
  49. return Card(
  50. margin: const EdgeInsets.symmetric(horizontal: 12, vertical: 4),
  51. child: ExpansionTile(
  52. leading: Icon(Icons.local_offer, color: theme.colorScheme.primary),
  53. title: Text(promo.descrizione ?? 'Promozione'),
  54. subtitle: Text(tipoLabel, style: theme.textTheme.bodySmall),
  55. children: [
  56. Padding(
  57. padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
  58. child: Column(
  59. crossAxisAlignment: CrossAxisAlignment.start,
  60. children: [
  61. _detail('Priorità', promo.priorita.toString()),
  62. if (promo.limiteQta != null) _detail('Limite Qtà', promo.limiteQta.toString()),
  63. if (promo.quantitaOmaggio != null) _detail('Qtà Omaggio', promo.quantitaOmaggio.toString()),
  64. if (promo.limiteImporto != null) _detail('Limite Importo', promo.limiteImporto.toString()),
  65. if (promo.dataInizio != null) _detail('Da', promo.dataInizio!),
  66. if (promo.dataFine != null) _detail('A', promo.dataFine!),
  67. ],
  68. ),
  69. ),
  70. ],
  71. ),
  72. );
  73. }
  74. Widget _detail(String label, String value) {
  75. return Padding(
  76. padding: const EdgeInsets.symmetric(vertical: 2),
  77. child: Row(
  78. children: [
  79. SizedBox(width: 120, child: Text(label, style: theme.textTheme.bodySmall?.copyWith(color: theme.colorScheme.outline))),
  80. Text(value),
  81. ],
  82. ),
  83. );
  84. }
  85. }