import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flux/features/operations/blocs/operations_cubit.dart'; import 'package:flux/features/operations/models/service_model.dart'; import 'package:flux/features/operations/utils/service_actions.dart'; import 'package:go_router/go_router.dart'; // Importa i tuoi modelli e cubit class ServicesScreen extends StatefulWidget { const ServicesScreen({super.key}); @override State createState() => _ServicesScreenState(); } class _ServicesScreenState extends State { final ScrollController _scrollController = ScrollController(); @override void initState() { super.initState(); // Agganciamo il listener per la paginazione (Scroll Infinito) _scrollController.addListener(_onScroll); // Carichiamo i servizi iniziali context.read().loadServices(); } void _onScroll() { if (_isBottom) { context.read().loadServices(); } } bool get _isBottom { if (!_scrollController.hasClients) return false; final maxScroll = _scrollController.position.maxScrollExtent; final currentScroll = _scrollController.offset; // Carica quando mancano 200px alla fine return currentScroll >= (maxScroll * 0.9); } @override void dispose() { _scrollController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text("Gestione Servizi"), elevation: 0, actions: [ IconButton( icon: const Icon(Icons.search), onPressed: () { // Qui potrai implementare una barra di ricerca }, ), ], ), body: BlocBuilder( builder: (context, state) { // 1. Stato di caricamento iniziale if (state.status == ServicesStatus.loading && state.allServices.isEmpty) { return const Center(child: CircularProgressIndicator()); } // 2. Lista vuota if (state.allServices.isEmpty) { return Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ const Text("Nessuna pratica trovata."), const SizedBox(height: 10), ElevatedButton( onPressed: () => context.read().loadServices( refresh: true, ), child: const Text("Riprova"), ), ], ), ); } // 3. La Lista (con Pull-to-refresh) return RefreshIndicator( onRefresh: () => context.read().loadServices(refresh: true), child: ListView.builder( controller: _scrollController, padding: const EdgeInsets.only(bottom: 80), // Spazio per il FAB itemCount: state.hasReachedMax ? state.allServices.length : state.allServices.length + 1, itemBuilder: (context, index) { if (index >= state.allServices.length) { return const Center( child: Padding( padding: EdgeInsets.all(16.0), child: CircularProgressIndicator(strokeWidth: 2), ), ); } final operation = state.allServices[index]; return _buildServiceCard(context, operation); }, ), ); }, ), floatingActionButton: FloatingActionButton( onPressed: () => startNewService(context), child: const Icon(Icons.add), ), ); } Widget _buildServiceCard(BuildContext context, ServiceModel operation) { return Card( margin: const EdgeInsets.symmetric(horizontal: 12, vertical: 6), elevation: 2, shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)), child: ListTile( contentPadding: const EdgeInsets.all(12), title: Row( children: [ Expanded( child: Text( operation.customerDisplayName ?? "Cliente sconosciuto", style: const TextStyle( fontWeight: FontWeight.bold, fontSize: 16, ), ), ), if (operation.isBozza) const Chip( label: Text( "BOZZA", style: TextStyle(fontSize: 10, color: Colors.white), ), backgroundColor: Colors.orange, visualDensity: VisualDensity.compact, ), ], ), subtitle: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const SizedBox(height: 4), Text( "Pratica: ${operation.number} • ${operation.createdAt?.day}/${operation.createdAt?.month}/${operation.createdAt?.year}", ), const SizedBox(height: 8), // I nostri mini-chip per i servizi attivati Wrap( spacing: 6, children: [ if (operation.al > 0 || operation.mnp > 0) _miniBadge("📞 Tel", Colors.blue), if (operation.energyServices.isNotEmpty) _miniBadge("⚡ Energy", Colors.green), if (operation.finServices.isNotEmpty) _miniBadge("💰 Fin", Colors.purple), if (operation.entertainmentServices.isNotEmpty) _miniBadge("📺 Ent", Colors.red), ], ), ], ), trailing: const Icon(Icons.chevron_right), onTap: () => context.pushNamed( 'operation-form', extra: operation, // <-- LA MAGIA È QUI: Passa l'oggetto intero! // Teniamo anche il parametro URL per coerenza di routing queryParameters: operation.id != null ? {'serviceId': operation.id!} : {}, ), ), ); } Widget _miniBadge(String text, Color color) { return Container( padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 2), decoration: BoxDecoration( color: color.withValues(alpha: 0.1), borderRadius: BorderRadius.circular(4), border: Border.all(color: color.withValues(alpha: 0.5)), ), child: Text( text, style: TextStyle( color: color, fontSize: 10, fontWeight: FontWeight.bold, ), ), ); } }