diff --git a/lib/features/master_data/providers/blocs/provider_cubit.dart b/lib/features/master_data/providers/blocs/provider_cubit.dart index 6d1c3fd..c78e65c 100644 --- a/lib/features/master_data/providers/blocs/provider_cubit.dart +++ b/lib/features/master_data/providers/blocs/provider_cubit.dart @@ -7,15 +7,17 @@ import 'package:get_it/get_it.dart'; import '../models/provider_model.dart'; class ProvidersState extends Equatable { - final List allProviders; // Tutti i provider della company - final List - associatedIds; // ID dei provider attivi nello store selezionato + final List allProviders; + final List associatedIds; + // NUOVO CAMPO: Lista dei provider pronti per essere usati nel form pratiche + final List activeProviders; final bool isLoading; final String? errorMessage; const ProvidersState({ this.allProviders = const [], this.associatedIds = const [], + this.activeProviders = const [], // Inizializza this.isLoading = false, this.errorMessage, }); @@ -23,14 +25,18 @@ class ProvidersState extends Equatable { ProvidersState copyWith({ List? allProviders, List? associatedIds, + List? activeProviders, // Aggiungi qui bool? isLoading, String? errorMessage, }) { return ProvidersState( allProviders: allProviders ?? this.allProviders, associatedIds: associatedIds ?? this.associatedIds, + activeProviders: activeProviders ?? this.activeProviders, // Aggiungi qui isLoading: isLoading ?? this.isLoading, - errorMessage: errorMessage, + errorMessage: + errorMessage ?? + this.errorMessage, // Correzione bug: mancava "?? this.errorMessage" nel tuo originale ); } @@ -38,6 +44,7 @@ class ProvidersState extends Equatable { List get props => [ allProviders, associatedIds, + activeProviders, // Aggiungi qui isLoading, errorMessage, ]; @@ -74,6 +81,23 @@ class ProvidersCubit extends Cubit { } } + Future loadActiveProvidersForStore(String storeId) async { + emit(state.copyWith(isLoading: true)); + try { + final activeList = await _repository.fetchActiveProvidersForStore( + storeId, + ); + emit(state.copyWith(activeProviders: activeList, isLoading: false)); + } catch (e) { + emit( + state.copyWith( + isLoading: false, + errorMessage: "Errore caricamento gestori: $e", + ), + ); + } + } + // Aggiunge o rimuove l'associazione con lo store Future toggleProviderAssociation({ required String providerId, diff --git a/lib/features/services/ui/service_form_screen/action_card.dart b/lib/features/services/ui/service_form_screen/action_card.dart new file mode 100644 index 0000000..51f0b42 --- /dev/null +++ b/lib/features/services/ui/service_form_screen/action_card.dart @@ -0,0 +1,85 @@ +import 'package:flutter/material.dart'; + +class ActionCard extends StatelessWidget { + final String label; + final int count; + final IconData icon; + final Color color; + final VoidCallback onTap; + + const ActionCard({ + super.key, + required this.label, + required this.count, + required this.icon, + required this.color, + required this.onTap, + }); + + @override + Widget build(BuildContext context) { + final isActive = count > 0; + + return InkWell( + onTap: onTap, + borderRadius: BorderRadius.circular(12), + child: AnimatedContainer( + duration: const Duration(milliseconds: 200), + width: 110, // Larghezza fissa per avere una griglia ordinata + padding: const EdgeInsets.symmetric(vertical: 16, horizontal: 8), + decoration: BoxDecoration( + color: isActive + ? color.withValues(alpha: 0.15) + : Theme.of(context).cardColor, + borderRadius: BorderRadius.circular(12), + border: Border.all( + color: isActive ? color : Colors.grey.withValues(alpha: 0.3), + width: isActive ? 2 : 1, + ), + boxShadow: isActive + ? [ + BoxShadow( + color: color.withValues(alpha: 0.2), + blurRadius: 8, + spreadRadius: 1, + ), + ] + : [], + ), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Icon(icon, color: isActive ? color : Colors.grey, size: 28), + const SizedBox(height: 8), + Text( + label, + style: TextStyle( + fontWeight: isActive ? FontWeight.bold : FontWeight.normal, + color: isActive ? color : Colors.grey.shade700, + ), + textAlign: TextAlign.center, + ), + if (isActive) ...[ + const SizedBox(height: 4), + Container( + padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 2), + decoration: BoxDecoration( + color: color, + borderRadius: BorderRadius.circular(12), + ), + child: Text( + count.toString(), + style: const TextStyle( + color: Colors.white, + fontWeight: FontWeight.bold, + fontSize: 12, + ), + ), + ), + ], + ], + ), + ), + ); + } +} diff --git a/lib/features/services/ui/service_form_screen/customer_section.dart b/lib/features/services/ui/service_form_screen/customer_section.dart index 3ae401d..dd1e752 100644 --- a/lib/features/services/ui/service_form_screen/customer_section.dart +++ b/lib/features/services/ui/service_form_screen/customer_section.dart @@ -1,5 +1,4 @@ import 'package:flutter/material.dart'; -import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flux/features/customers/ui/customer_search_sheet.dart'; import 'package:flux/features/services/models/service_model.dart'; diff --git a/lib/features/services/ui/service_form_screen/energy_service_dialog.dart b/lib/features/services/ui/service_form_screen/energy_service_dialog.dart new file mode 100644 index 0000000..d08b580 --- /dev/null +++ b/lib/features/services/ui/service_form_screen/energy_service_dialog.dart @@ -0,0 +1,333 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flux/features/master_data/providers/blocs/provider_cubit.dart'; +import 'package:flux/features/master_data/providers/models/provider_model.dart'; +import 'package:flux/features/services/models/energy_service_model.dart'; // Assicurati degli import + +class EnergyServiceDialog extends StatefulWidget { + final List initialServices; + final String + currentStoreId; // Ci serve per sapere per quale negozio caricare i gestori + + const EnergyServiceDialog({ + super.key, + required this.initialServices, + required this.currentStoreId, + }); + + @override + State createState() => _EnergyServiceDialogState(); +} + +class _EnergyServiceDialogState extends State { + // Lista temporanea per non "sporcare" il cubit finché non si preme Conferma + late List _tempList; + bool _isAddingNew = false; + + @override + void initState() { + super.initState(); + _tempList = List.from(widget.initialServices); + // Al caricamento della modale, chiediamo al Cubit di recuperare i gestori veri! + context.read().loadActiveProvidersForStore( + widget.currentStoreId, + ); + } + + @override + Widget build(BuildContext context) { + return AlertDialog( + title: Row( + children: [ + Icon(Icons.bolt, color: Theme.of(context).colorScheme.primary), + const SizedBox(width: 8), + Text(_isAddingNew ? "Nuovo Contratto" : "Servizi Energia"), + ], + ), + content: AnimatedSize( + duration: const Duration(milliseconds: 300), + curve: Curves.easeInOut, + child: SizedBox( + width: double.maxFinite, + // Cambia vista in base al flag + child: _isAddingNew + ? _EnergyForm( + onSave: (newService) { + setState(() { + _tempList.add(newService); + _isAddingNew = false; // Torna alla lista + }); + }, + onCancel: () { + setState(() => _isAddingNew = false); + }, + ) + : _EnergyList( + services: _tempList, + onDelete: (index) { + setState(() => _tempList.removeAt(index)); + }, + onAddTap: () { + setState(() => _isAddingNew = true); // Passa al form + }, + activeProviders: [ + // Passiamo i provider attivi filtrati per tipo Energia + ...context + .read() + .state + .activeProviders + .where((p) => p.energia == true), + ], + ), + ), + ), + actions: [ + if (!_isAddingNew) ...[ + TextButton( + onPressed: () => Navigator.pop(context), + child: const Text("Annulla"), + ), + ElevatedButton( + onPressed: () => Navigator.pop(context, _tempList), + child: const Text("Conferma Tutti"), + ), + ], + ], + ); + } +} + +// ========================================== +// VISTA 1: LA LISTA DEI CONTRATTI +// ========================================== +class _EnergyList extends StatelessWidget { + final List services; + final List + activeProviders; // <--- NUOVO: La lista vera dal Cubit + final Function(int) onDelete; + final VoidCallback onAddTap; + + const _EnergyList({ + required this.services, + required this.activeProviders, // <--- Richiesto + required this.onDelete, + required this.onAddTap, + }); + + @override + Widget build(BuildContext context) { + return Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + if (services.isEmpty) + const Padding( + padding: EdgeInsets.symmetric(vertical: 32.0), + child: Text( + "Nessun contratto energia inserito.", + textAlign: TextAlign.center, + style: TextStyle(color: Colors.grey), + ), + ) + else + Flexible( + child: ListView.separated( + shrinkWrap: true, + itemCount: services.length, + separatorBuilder: (_, __) => const Divider(height: 1), + itemBuilder: (context, index) { + final s = services[index]; + final isLuce = s.type == EnergyType.luce; + + // LA MAGIA: Troviamo il nome partendo dall'ID salvato nel servizio + final providerIndex = activeProviders.indexWhere( + (p) => p.id == s.providerId, + ); + final providerName = providerIndex >= 0 + ? (activeProviders[providerIndex].nome ?? 'Sconosciuto') + : 'Gestore Rimosso/Sconosciuto'; + + // Formattazione data pulita (es. 04/09/2025) + final day = s.expiration.day.toString().padLeft(2, '0'); + final month = s.expiration.month.toString().padLeft(2, '0'); + final formattedDate = "$day/$month/${s.expiration.year}"; + + return ListTile( + contentPadding: EdgeInsets.zero, + leading: CircleAvatar( + backgroundColor: isLuce + ? Colors.orange.shade100 + : Colors.blue.shade100, + child: Icon( + isLuce + ? Icons.lightbulb_outline + : Icons.local_fire_department, + color: isLuce ? Colors.orange : Colors.blue, + ), + ), + title: Text( + providerName, + style: const TextStyle(fontWeight: FontWeight.bold), + ), + subtitle: Text("Scadenza: $formattedDate"), + trailing: IconButton( + icon: const Icon(Icons.delete_outline, color: Colors.red), + onPressed: () => onDelete(index), + ), + ); + }, + ), + ), + const SizedBox(height: 16), + OutlinedButton.icon( + onPressed: onAddTap, + icon: const Icon(Icons.add), + label: const Text("Aggiungi Contratto"), + ), + ], + ); + } +} + +// ========================================== +// VISTA 2: IL FORM DI INSERIMENTO +// ========================================== +class _EnergyForm extends StatefulWidget { + final Function(EnergyServiceModel) onSave; + final VoidCallback onCancel; + + const _EnergyForm({required this.onSave, required this.onCancel}); + + @override + State<_EnergyForm> createState() => _EnergyFormState(); +} + +class _EnergyFormState extends State<_EnergyForm> { + EnergyType _selectedType = EnergyType.luce; + String? _selectedProviderId; + DateTime? _selectedExpiration; + + Future _pickDate() async { + final picked = await showDatePicker( + context: context, + initialDate: DateTime.now().add( + const Duration(days: 365), + ), // Default 1 anno + firstDate: DateTime.now(), + lastDate: DateTime.now().add(const Duration(days: 365 * 10)), + ); + if (picked != null) { + setState(() => _selectedExpiration = picked); + } + } + + @override + Widget build(BuildContext context) { + return Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + // 1. Tipo (Luce o Gas) - Segmented Button stile M3 + SegmentedButton( + segments: const [ + ButtonSegment( + value: EnergyType.luce, + label: Text("Luce"), + icon: Icon(Icons.lightbulb_outline), + ), + ButtonSegment( + value: EnergyType.gas, + label: Text("Gas"), + icon: Icon(Icons.local_fire_department), + ), + ], + selected: {_selectedType}, + onSelectionChanged: (Set newSelection) { + setState(() => _selectedType = newSelection.first); + }, + ), + const SizedBox(height: 16), + + // 2. Provider Dropdown + BlocBuilder( + builder: (context, state) { + if (state.isLoading) { + return const Center( + child: LinearProgressIndicator(), + ); // Mostra una barretta di caricamento + } + + if (state.activeProviders.isEmpty) { + return const Text( + "Nessun gestore associato a questo negozio.", + style: TextStyle(color: Colors.red), + ); + } + // Filtra solo i provider di tipo Energia (Se hai una categoria nel modello) + // Se non hai una categoria nel ProviderModel, puoi rimuovere il .where + final energyProviders = state.activeProviders; + return DropdownButtonFormField( + decoration: const InputDecoration( + labelText: "Gestore / Provider", + border: OutlineInputBorder(), + ), + initialValue: _selectedProviderId, + items: energyProviders.map((p) { + return DropdownMenuItem( + value: p.id, + child: Text(p.nome ?? 'Sconosciuto'), + ); + }).toList(), + onChanged: (val) => setState(() => _selectedProviderId = val), + ); + }, + ), + const SizedBox(height: 16), + + // 3. Scadenza (DatePicker integrato in un TextField) + TextFormField( + readOnly: true, + onTap: _pickDate, + decoration: InputDecoration( + labelText: "Data Scadenza", + border: const OutlineInputBorder(), + suffixIcon: const Icon(Icons.calendar_month), + ), + // Mostra la data se selezionata, altrimenti vuoto + controller: TextEditingController( + text: _selectedExpiration != null + ? "${_selectedExpiration!.day}/${_selectedExpiration!.month}/${_selectedExpiration!.year}" + : "", + ), + ), + const SizedBox(height: 24), + + // 4. Pulsanti Interni al Form + Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + TextButton( + onPressed: widget.onCancel, + child: const Text("Indietro"), + ), + const SizedBox(width: 8), + ElevatedButton( + onPressed: + (_selectedProviderId == null || _selectedExpiration == null) + ? null // Disabilitato se mancano dati obbligatori + : () { + final newService = EnergyServiceModel( + type: _selectedType, + expiration: _selectedExpiration!, + providerId: _selectedProviderId!, + ); + widget.onSave(newService); + }, + child: const Text("Salva Contratto"), + ), + ], + ), + ], + ); + } +} diff --git a/lib/features/services/ui/service_form_screen/int_dialogs.dart b/lib/features/services/ui/service_form_screen/int_dialogs.dart new file mode 100644 index 0000000..cbda2e7 --- /dev/null +++ b/lib/features/services/ui/service_form_screen/int_dialogs.dart @@ -0,0 +1,158 @@ +import 'dart:async'; // Necessario per il Timer +import 'package:flutter/material.dart'; + +Future updateCountDialog( + BuildContext context, + String title, + int currentValue, + Function(int) onSave, +) async { + int tempValue = + currentValue; // Variabile locale per gestire il conteggio nella dialog + + final result = await showDialog( + context: context, + builder: (context) => AlertDialog( + title: Text("Imposta $title"), + content: QuickCounter( + initialValue: tempValue, + onChanged: (val) => tempValue = + val, // Aggiorna il valore locale quando il counter cambia + ), + actions: [ + TextButton( + onPressed: () => Navigator.pop(context), + child: const Text("Annulla"), + ), + ElevatedButton( + onPressed: () => Navigator.pop(context, tempValue), + child: const Text("Conferma"), + ), + ], + ), + ); + + if (result != null) { + onSave(result); + } +} + +// --- Widget Interno Specifico per il Counter Veloce --- +class QuickCounter extends StatefulWidget { + final int initialValue; + final ValueChanged + onChanged; // Callback per notificare il padre dei cambiamenti + + const QuickCounter({ + super.key, + required this.initialValue, + required this.onChanged, + }); + + @override + State createState() => _QuickCounterState(); +} + +class _QuickCounterState extends State { + late int _value; + Timer? _longPressTimer; // Il timer per l'auto-incremento + + @override + void initState() { + super.initState(); + _value = widget.initialValue; + } + + @override + void dispose() { + _longPressTimer + ?.cancel(); // IMPORTANTE: Annulla sempre il timer alla distruzione + super.dispose(); + } + + // Logica comune per incremento/decremento singolo o rapido + void _update(int delta) { + setState(() { + _value += delta; + if (_value < 0) _value = 0; // Impedisci numeri negativi + }); + widget.onChanged(_value); // Notifica il padre + } + + // Gestione dell'inizio della pressione prolungata + void _startLongPress(int delta) { + _update(delta); // Esegui subito il primo aggiornamento al tocco iniziale + _longPressTimer = Timer.periodic(const Duration(milliseconds: 100), ( + timer, + ) { + _update(delta); // Aggiorna velocemente finché la pressione continua + }); + } + + // Gestione della fine della pressione prolungata + void _stopLongPress() { + _longPressTimer?.cancel(); + } + + @override + Widget build(BuildContext context) { + final canDecrement = _value > 0; + + return Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + // --- Pulsante MENO --- + GestureDetector( + onLongPressStart: canDecrement ? (_) => _startLongPress(-1) : null, + onLongPressEnd: (_) => _stopLongPress(), + onLongPressCancel: () => _stopLongPress(), + onTap: canDecrement ? () => _update(-1) : null, + child: Opacity( + // Visivamente disabilitato se < 0 + opacity: canDecrement ? 1.0 : 0.4, + child: const ActionButton(icon: Icons.remove, color: Colors.red), + ), + ), + + // --- Valore Centrale --- + Padding( + padding: const EdgeInsets.symmetric(horizontal: 24), + child: Text( + _value.toString(), + style: const TextStyle(fontSize: 40, fontWeight: FontWeight.bold), + ), + ), + + // --- Pulsante PIU' --- + GestureDetector( + onLongPressStart: (_) => _startLongPress(1), + onLongPressEnd: (_) => _stopLongPress(), + onLongPressCancel: () => _stopLongPress(), + onTap: () => _update(1), + child: const ActionButton(icon: Icons.add, color: Colors.green), + ), + ], + ); + } +} + +// Piccolo widget di utilità per l'aspetto del pulsante +class ActionButton extends StatelessWidget { + final IconData icon; + final Color color; + + const ActionButton({super.key, required this.icon, required this.color}); + + @override + Widget build(BuildContext context) { + return Container( + padding: const EdgeInsets.all(12), + decoration: BoxDecoration( + color: color.withValues(alpha: 0.1), + shape: BoxShape.circle, + border: Border.all(color: color, width: 2), + ), + child: Icon(icon, color: color, size: 30), + ); + } +} diff --git a/lib/features/services/ui/service_form_screen/service_form_screen.dart b/lib/features/services/ui/service_form_screen/service_form_screen.dart index b91a77c..afae7f8 100644 --- a/lib/features/services/ui/service_form_screen/service_form_screen.dart +++ b/lib/features/services/ui/service_form_screen/service_form_screen.dart @@ -1,7 +1,9 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flux/features/services/blocs/services_cubit.dart'; +import 'package:flux/features/services/ui/service_form_screen/customer_section.dart'; import 'package:flux/features/services/ui/service_form_screen/general_info_section.dart'; +import 'package:flux/features/services/ui/service_form_screen/services_grid.dart'; class ServiceFormScreen extends StatelessWidget { const ServiceFormScreen({super.key}); @@ -30,7 +32,7 @@ class ServiceFormScreen extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ // SEZIONE 1: CLIENTE - const _CustomerSection(), + CustomerSection(service: service), const SizedBox(height: 24), // SEZIONE 2: INFO GENERALI (Da fare) @@ -38,13 +40,7 @@ class ServiceFormScreen extends StatelessWidget { const SizedBox(height: 24), // SEZIONE 3: I MODULI (Da fare) - Text( - "Servizi e Accessori", - style: Theme.of(context).textTheme.titleMedium, - ), - const SizedBox(height: 12), - - // const _ServicesGrid(), + ServicesGrid(service: service), const SizedBox(height: 32), // SEZIONE 4: ALLEGATI (Da fare) @@ -90,88 +86,3 @@ class _SaveButton extends StatelessWidget { ); } } - -class _CustomerSection extends StatelessWidget { - const _CustomerSection(); - - @override - Widget build(BuildContext context) { - return BlocBuilder( - builder: (context, state) { - final service = state.currentService!; - final hasCustomer = service.customerId != null; - - return Card( - elevation: 2, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(12), - ), - child: Padding( - padding: const EdgeInsets.all(16.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - children: [ - Icon( - Icons.person, - color: Theme.of(context).colorScheme.primary, - ), - const SizedBox(width: 8), - Text( - "Dati Cliente", - style: Theme.of(context).textTheme.titleMedium, - ), - ], - ), - const SizedBox(height: 16), - - // Se non c'è il cliente, mostriamo il tastone per cercarlo - if (!hasCustomer) - Center( - child: ElevatedButton.icon( - onPressed: () { - // TODO: Aprire modale/dialog per ricerca clienti - print("Apro ricerca clienti..."); - }, - icon: const Icon(Icons.search), - label: const Text("Seleziona o Crea Cliente"), - style: ElevatedButton.styleFrom( - padding: const EdgeInsets.symmetric( - horizontal: 24, - vertical: 12, - ), - ), - ), - ) - // Se c'è, mostriamo chi è e diamo la possibilità di cambiarlo - else - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Expanded( - child: Text( - service.customerDisplayName ?? "Cliente Selezionato", - style: const TextStyle( - fontSize: 16, - fontWeight: FontWeight.bold, - ), - ), - ), - TextButton.icon( - onPressed: () { - // TODO: Aprire modale/dialog per ricerca clienti - }, - icon: const Icon(Icons.edit, size: 18), - label: const Text("Cambia"), - ), - ], - ), - ], - ), - ), - ); - }, - ); - } -} diff --git a/lib/features/services/ui/service_form_screen/services_grid.dart b/lib/features/services/ui/service_form_screen/services_grid.dart new file mode 100644 index 0000000..ded2450 --- /dev/null +++ b/lib/features/services/ui/service_form_screen/services_grid.dart @@ -0,0 +1,168 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flux/features/services/blocs/services_cubit.dart'; +import 'package:flux/features/services/models/energy_service_model.dart'; +import 'package:flux/features/services/models/service_model.dart'; +import 'package:flux/features/services/ui/service_form_screen/action_card.dart'; +import 'package:flux/features/services/ui/service_form_screen/energy_service_dialog.dart'; +import 'package:flux/features/services/ui/service_form_screen/int_dialogs.dart'; // Assicurati di importare il modello + +class ServicesGrid extends StatelessWidget { + final ServiceModel service; + + const ServicesGrid({super.key, required this.service}); + + @override + Widget build(BuildContext context) { + return Card( + elevation: 2, + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)), + child: Padding( + padding: const EdgeInsets.all(16.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + + children: [ + Row( + children: [ + Icon( + Icons.layers_outlined, + color: Theme.of(context).colorScheme.primary, + ), + const SizedBox(width: 8), + Text( + "Servizi e Accessori", + style: Theme.of(context).textTheme.titleMedium, + ), + ], + ), + const SizedBox(height: 20), + SizedBox( + width: double.infinity, + child: Wrap( + spacing: 16, + runSpacing: 16, + alignment: WrapAlignment.center, + children: [ + // --- CONTATORI SEMPLICI --- + ActionCard( + label: "AL", + count: service.al, + icon: Icons.sim_card, + color: Colors.blue, + onTap: () => updateCountDialog( + context, + "AL", + service.al, + (val) => + context.read().updateField(al: val), + ), + ), + ActionCard( + label: "MNP", + count: service.mnp, + icon: Icons.phone_android, + color: Colors.indigo, + onTap: () => updateCountDialog( + context, + "MNP", + service.mnp, + (val) => + context.read().updateField(mnp: val), + ), + ), + ActionCard( + label: "NIP", + count: service.nip, + icon: Icons.compare_arrows, + color: Colors.cyan, + onTap: () => updateCountDialog( + context, + "NIP", + service.nip, + (val) => + context.read().updateField(nip: val), + ), + ), + ActionCard( + label: "Unica", + count: service.unica, + icon: Icons.all_inclusive, + color: Colors.purple, + onTap: () => updateCountDialog( + context, + "Unica", + service.unica, + (val) => + context.read().updateField(unica: val), + ), + ), + ActionCard( + label: "Telepass", + count: service.telepass, + icon: Icons.directions_car, + color: Colors.amber.shade700, + onTap: () => updateCountDialog( + context, + "Telepass", + service.telepass, + (val) => context.read().updateField( + telepass: val, + ), + ), + ), + + // --- MODULI COMPLESSI (Le liste) --- + ActionCard( + label: "Energia", + count: service.energyServices.length, + icon: Icons.bolt, + color: Colors.green, + onTap: () async { + // Apriamo la modale e aspettiamo il risultato + final result = await showDialog>( + context: context, + builder: (context) => EnergyServiceDialog( + currentStoreId: service.storeId, + initialServices: service + .energyServices, // Passiamo la lista attuale + ), + ); + + // Se l'utente ha premuto "Conferma" e non "Annulla" o tap fuori + if (result != null && context.mounted) { + context.read().updateEnergyServices( + result, + ); + } + }, + ), + ActionCard( + label: "Finanziam.", + count: service.finServices.length, + icon: Icons.euro_symbol, + color: Colors.teal, + onTap: () { + // TODO: Aprire la Dialog Finanziamenti complessa + print("Apri Fin Dialog"); + }, + ), + ActionCard( + label: "Contenuti", + count: service.entertainmentServices.length, + icon: Icons.tv, + color: Colors.redAccent, + onTap: () { + // TODO: Aprire la Dialog Contenuti complessa + print("Apri Contenuti Dialog"); + }, + ), + ], + ), + ), + ], + ), + ), + ); + } +}