import 'package:conalep_pos/models/models.dart'; import 'package:conalep_pos/themes/themes.dart'; import 'package:conalep_pos/viewmodels/viewmodels.dart'; import 'package:conalep_pos/views/pedido_mesa/pedido_mesa_detalle.dart'; import 'package:conalep_pos/views/pedido_mesa/pedido_mesa_form.dart'; import 'package:conalep_pos/widgets/widgets.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import '../../widgets/widgets_components.dart' as clase; class PedidoMesaScreen extends StatefulWidget { const PedidoMesaScreen({Key? key}) : super(key: key); @override State createState() => _PedidoMesaScreenState(); } class _PedidoMesaScreenState extends State { final _busqueda = TextEditingController(text: ''); DateTime? fechaInicio; DateTime? fechaFin; ScrollController horizontalScrollController = ScrollController(); @override void initState() { super.initState(); WidgetsBinding.instance.addPostFrameCallback((_) { Provider.of(context, listen: false) .fetchLocalMesaPedidosForScreen(); }); } // void exportCSV() async { // final pedidosViewModel = // Provider.of(context, listen: false); // List pedidosConProductos = []; // for (Pedido pedido in pedidosViewModel.pedidos) { // Pedido? pedidoConProductos = // await pedidosViewModel.fetchPedidoConProductos(pedido.id); // if (pedidoConProductos != null) { // pedidosConProductos.add(pedidoConProductos); // } // } // if (pedidosConProductos.isNotEmpty) { // String fileName = 'Pedidos_OlivaMia_POS'; // if (fechaInicio != null && fechaFin != null) { // String startDateStr = DateFormat('dd-MM-yyyy').format(fechaInicio!); // String endDateStr = DateFormat('dd-MM-yyyy').format(fechaFin!); // fileName += '_${startDateStr}_al_${endDateStr}'; // } // fileName += '.csv'; // await exportarPedidosACSV(pedidosConProductos, fileName); // ScaffoldMessenger.of(context).showSnackBar(SnackBar( // content: Text('Archivo CSV descargado! Archivo: $fileName'))); // } else { // ScaffoldMessenger.of(context).showSnackBar( // SnackBar(content: Text('No hay pedidos para exportar.'))); // } // } void clearSearchAndReset() { setState(() { _busqueda.clear(); fechaInicio = null; fechaFin = null; Provider.of(context, listen: false) .fetchLocalPedidosForScreen(); }); } void go(Pedido item) async { Pedido? pedidoCompleto = await Provider.of(context, listen: false) .fetchPedidoConProductos(item.id); if (pedidoCompleto != null) { if (pedidoCompleto.estatus == 'EN PROCESO') { Navigator.push( context, MaterialPageRoute( builder: (context) => PedidoMesaForm(pedido: pedidoCompleto), ), ); } else { Navigator.push( context, MaterialPageRoute( builder: (context) => PedidoMesaDetalleScreen(pedido: pedidoCompleto), ), ); } } else { print("Error al cargar el pedido con productos"); } } @override Widget build(BuildContext context) { final pvm = Provider.of(context); double screenWidth = MediaQuery.of(context).size.width; final isMobile = screenWidth < 1250; final double? columnSpacing = isMobile ? null : 0; TextStyle estilo = const TextStyle(fontWeight: FontWeight.bold); List registros = []; for (Pedido item in pvm.pedidos) { registros.add(DataRow(cells: [ DataCell( Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ PopupMenuButton( itemBuilder: (context) => [ PopupMenuItem( child: const Text('Detalle'), onTap: () => go(item), ), PopupMenuItem( child: const Text('Cancelar Pedido'), onTap: () async { bool confirmado = await showDialog( context: context, builder: (context) { return AlertDialog( title: const Text("Cancelar Pedido", style: TextStyle( fontWeight: FontWeight.w500, fontSize: 22)), content: const Text( '¿Estás seguro de que deseas cancelar este pedido?', style: TextStyle(fontSize: 18)), actions: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ TextButton( onPressed: () => Navigator.of(context).pop(false), child: const Text('No', style: TextStyle(fontSize: 18)), style: ButtonStyle( padding: MaterialStatePropertyAll( EdgeInsets.fromLTRB( 20, 10, 20, 10)), backgroundColor: MaterialStatePropertyAll( Colors.red), foregroundColor: MaterialStatePropertyAll( AppTheme.secondary)), ), TextButton( onPressed: () => Navigator.of(context).pop(true), child: const Text('Sí', style: TextStyle(fontSize: 18)), style: ButtonStyle( padding: MaterialStatePropertyAll( EdgeInsets.fromLTRB( 20, 10, 20, 10)), backgroundColor: MaterialStatePropertyAll( AppTheme.tertiary), foregroundColor: MaterialStatePropertyAll( AppTheme.quaternary)), ), ], ) ], ); }, ) ?? false; if (confirmado) { await Provider.of(context, listen: false) .cancelarPedido(item.id); ScaffoldMessenger.of(context).showSnackBar(SnackBar( content: Text("Pedido cancelado correctamente"))); } }, ) ], icon: const Icon(Icons.more_vert), ) ])), DataCell( Text(item.id.toString()), onTap: () => go(item), ), DataCell( Text(item.folio.toString()), onTap: () => go(item), ), DataCell( Text(item.idLocal.toString()), onTap: () => go(item), ), DataCell( Text(item.nombreCliente ?? "Sin nombre"), onTap: () => go(item), ), DataCell( Text(item.comentarios ?? "Sin comentarios"), onTap: () => go(item), ), DataCell( Text(item.estatus ?? "Sin Estatus"), onTap: () => go(item), ), DataCell( Text(item.peticion ?? "Sin fecha"), onTap: () => go(item), ), ])); } return Scaffold( appBar: AppBar( title: Text( 'Pedidos de Mesa', style: TextStyle( color: AppTheme.secondary, fontWeight: FontWeight.w500), ), // actions: [ // IconButton( // icon: const Icon(Icons.save_alt), // onPressed: exportCSV, // tooltip: 'Exportar a CSV', // ), // ], iconTheme: IconThemeData(color: AppTheme.secondary)), floatingActionButton: FloatingActionButton.extended( onPressed: () async { await Navigator.push( context, MaterialPageRoute( builder: (context) => PedidoMesaForm(), ), ).then((_) => Provider.of(context, listen: false) .fetchLocalPedidosForScreen()); }, icon: Icon(Icons.add, size: 30, color: AppTheme.quaternary), label: Text( "Agregar Pedido", style: TextStyle(fontSize: 20, color: AppTheme.quaternary), ), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8), ), materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, backgroundColor: AppTheme.tertiary, ), body: Column( children: [ Expanded( child: ListView( padding: const EdgeInsets.fromLTRB(8, 0, 8, 0), children: [ const SizedBox(height: 8), clase.tarjeta( Padding( padding: const EdgeInsets.all(8.0), child: LayoutBuilder( builder: (context, constraints) { if (screenWidth > 1000) { return Row( crossAxisAlignment: CrossAxisAlignment.end, children: [ Expanded( flex: 7, child: _buildDateRangePicker(), ), const SizedBox(width: 5), botonBuscar() ], ); } else { return Column( children: [ Row( children: [_buildDateRangePicker()], ), Row( children: [botonBuscar()], ), ], ); } }, ), ), ), const SizedBox(height: 8), pvm.isLoading ? const Center(child: CircularProgressIndicator()) : Container(), clase.tarjeta( Column( children: [ LayoutBuilder(builder: (context, constraints) { return SingleChildScrollView( scrollDirection: Axis.vertical, child: Scrollbar( controller: horizontalScrollController, interactive: true, thumbVisibility: true, thickness: 10.0, child: SingleChildScrollView( controller: horizontalScrollController, scrollDirection: Axis.horizontal, child: ConstrainedBox( constraints: BoxConstraints( minWidth: isMobile ? constraints.maxWidth : screenWidth), child: DataTable( columnSpacing: columnSpacing, sortAscending: true, sortColumnIndex: 1, columns: [ DataColumn(label: Text(" ", style: estilo)), DataColumn( label: Text("ID", style: estilo)), DataColumn( label: Text("FOLIO", style: estilo)), DataColumn( label: Text("IDLOCAL", style: estilo)), DataColumn( label: Text("NOMBRE", style: estilo)), DataColumn( label: Text("COMENTARIOS", style: estilo)), DataColumn( label: Text("ESTATUS", style: estilo)), DataColumn( label: Text("FECHA", style: estilo)), ], rows: registros, ), ), ), ), ); }), ], ), ), const SizedBox(height: 15), if (!pvm.isLoading) Row( mainAxisAlignment: MainAxisAlignment.center, children: [ TextButton( onPressed: pvm.currentPage > 1 ? pvm.previousPage : null, child: Text('Anterior'), style: ButtonStyle( backgroundColor: MaterialStateProperty.resolveWith( (Set states) { if (states.contains(MaterialState.disabled)) { return Colors.grey; } return AppTheme.tertiary; }, ), foregroundColor: MaterialStateProperty.resolveWith( (Set states) { if (states.contains(MaterialState.disabled)) { return Colors.black; } return Colors.white; }, ), ), ), SizedBox(width: 15), Text('Página ${pvm.currentPage} de ${pvm.totalPages}'), SizedBox(width: 15), TextButton( onPressed: pvm.currentPage < pvm.totalPages ? pvm.nextPage : null, child: Text('Siguiente'), style: ButtonStyle( backgroundColor: MaterialStateProperty.resolveWith( (Set states) { if (states.contains(MaterialState.disabled)) { return Colors.grey; } return AppTheme.tertiary; }, ), foregroundColor: MaterialStateProperty.resolveWith( (Set states) { if (states.contains(MaterialState.disabled)) { return Colors.black; } return Colors.white; }, ), ), ), ], ), const SizedBox(height: 15), ], ), ), ], ), ); } Widget _buildDateRangePicker() { return Row( children: [ Expanded( flex: 3, child: AppTextField( prefixIcon: const Icon(Icons.search), etiqueta: 'Búsqueda por folio...', controller: _busqueda, hintText: 'Búsqueda por folio...', ), ), const SizedBox(width: 5), Expanded( flex: 3, child: clase.FechaSelectWidget( fecha: fechaInicio, onFechaChanged: (d) { setState(() { fechaInicio = d; }); }, etiqueta: "Fecha Inicial", context: context, ), ), const SizedBox(width: 5), Expanded( flex: 3, child: clase.FechaSelectWidget( fecha: fechaFin, onFechaChanged: (d) { setState(() { fechaFin = d; }); }, etiqueta: "Fecha Final", context: context, ), ), ], ); } Widget botonBuscar() { return Expanded( flex: 2, child: Row( children: [ Expanded( flex: 2, child: Padding( padding: const EdgeInsets.only(bottom: 5), child: ElevatedButton( onPressed: clearSearchAndReset, style: ElevatedButton.styleFrom( shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(20.0), ), backgroundColor: AppTheme.tertiary, padding: const EdgeInsets.symmetric(vertical: 25), ), child: Text('Limpiar', style: TextStyle(color: AppTheme.quaternary)), ), ), ), const SizedBox(width: 8), Expanded( flex: 2, child: Padding( padding: const EdgeInsets.only(bottom: 5), child: ElevatedButton( onPressed: () async { if (_busqueda.text.isNotEmpty) { await Provider.of(context, listen: false) .buscarPedidosPorFolio(_busqueda.text.trim()); } else if (fechaInicio != null && fechaFin != null) { await Provider.of(context, listen: false) .buscarPedidosPorFecha(fechaInicio!, fechaFin!); } else { ScaffoldMessenger.of(context).showSnackBar(const SnackBar( content: Text( 'Introduce un folio o selecciona un rango de fechas para buscar.'))); } }, style: ElevatedButton.styleFrom( shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(20.0), ), backgroundColor: AppTheme.tertiary, padding: const EdgeInsets.symmetric(vertical: 25), ), child: Text('Buscar', style: TextStyle(color: AppTheme.quaternary)), ), ), ), ], )); } }