promotion_list_page.dart 3.2 KB

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