import 'package:flutter/material.dart'; class CartPage extends StatefulWidget { final int tableId; final int personne; final List cartItems; const CartPage({ Key? key, required this.tableId, required this.personne, required this.cartItems, }) : super(key: key); @override State createState() => _CartPageState(); } class _CartPageState extends State { List _cartItems = []; @override void initState() { super.initState(); _processCartItems(); } void _processCartItems() { // Grouper les articles identiques Map groupedItems = {}; for (var item in widget.cartItems) { String key = "${item['id']}_${item['notes'] ?? ''}"; if (groupedItems.containsKey(key)) { groupedItems[key]!.quantity++; } else { groupedItems[key] = CartItemModel( id: item['id'], nom: item['nom'] ?? 'Article', prix: _parsePrice(item['prix']), quantity: 1, notes: item['notes'] ?? '', ); } } setState(() { _cartItems = groupedItems.values.toList(); }); } double _parsePrice(dynamic prix) { if (prix == null) return 0.0; if (prix is num) return prix.toDouble(); if (prix is String) return double.tryParse(prix) ?? 0.0; return 0.0; } void _updateQuantity(int index, int newQuantity) { setState(() { if (newQuantity > 0) { _cartItems[index].quantity = newQuantity; } else { _cartItems.removeAt(index); } }); } void _removeItem(int index) { setState(() { _cartItems.removeAt(index); }); } double _calculateTotal() { return _cartItems.fold(0.0, (sum, item) => sum + (item.prix * item.quantity)); } int _getTotalArticles() { return _cartItems.fold(0, (sum, item) => sum + item.quantity); } void _validateOrder() { // TODO: Implémenter la validation de commande showDialog( context: context, builder: (BuildContext context) { return AlertDialog( title: Text('Commande validée'), content: Text('Votre commande a été envoyée en cuisine !'), actions: [ TextButton( onPressed: () { Navigator.of(context).pop(); // Fermer le dialog Navigator.of(context).pop(); // Retourner au menu Navigator.of(context).pop(); // Retourner aux tables }, child: Text('OK'), ), ], ); }, ); } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: Colors.grey[50], appBar: AppBar( backgroundColor: Colors.white, elevation: 0, leading: IconButton( onPressed: () => Navigator.pop(context), icon: Icon(Icons.arrow_back, color: Colors.black), ), title: Text( 'Panier', style: TextStyle( color: Colors.black, fontSize: 24, fontWeight: FontWeight.bold, ), ), actions: [ TextButton( onPressed: () => Navigator.pop(context), child: Text( 'Retour au menu', style: TextStyle( color: Colors.black, fontSize: 16, ), ), ), SizedBox(width: 16), ], ), body: _cartItems.isEmpty ? Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon( Icons.shopping_cart_outlined, size: 80, color: Colors.grey[400], ), SizedBox(height: 16), Text( 'Votre panier est vide', style: TextStyle( fontSize: 18, color: Colors.grey[600], ), ), ], ), ) : Column( children: [ // Header avec infos table Container( width: double.infinity, padding: EdgeInsets.all(20), color: Colors.white, child: Text( 'Table ${widget.tableId} • ${widget.personne} personne${widget.personne > 1 ? 's' : ''}', style: TextStyle( fontSize: 16, color: Colors.grey[600], ), ), ), // Liste des articles Expanded( child: ListView.separated( padding: EdgeInsets.all(16), itemCount: _cartItems.length, separatorBuilder: (context, index) => SizedBox(height: 12), itemBuilder: (context, index) { final item = _cartItems[index]; return Container( padding: EdgeInsets.all(16), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(12), boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.05), blurRadius: 5, offset: Offset(0, 2), ), ], ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Expanded( child: Text( item.nom, style: TextStyle( fontSize: 18, fontWeight: FontWeight.bold, ), ), ), IconButton( onPressed: () => _removeItem(index), icon: Icon( Icons.delete_outline, color: Colors.red, ), constraints: BoxConstraints(), padding: EdgeInsets.zero, ), ], ), Text( '${item.prix.toStringAsFixed(2)} € l\'unité', style: TextStyle( fontSize: 14, color: Colors.grey[600], ), ), if (item.notes.isNotEmpty) ...[ SizedBox(height: 8), Text( 'Notes: ${item.notes}', style: TextStyle( fontSize: 14, color: Colors.grey[600], fontStyle: FontStyle.italic, ), ), ], SizedBox(height: 16), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ // Contrôles de quantité Row( children: [ IconButton( onPressed: () => _updateQuantity(index, item.quantity - 1), icon: Icon(Icons.remove), style: IconButton.styleFrom( backgroundColor: Colors.grey[200], minimumSize: Size(40, 40), ), ), SizedBox(width: 16), Text( item.quantity.toString(), style: TextStyle( fontSize: 18, fontWeight: FontWeight.bold, ), ), SizedBox(width: 16), IconButton( onPressed: () => _updateQuantity(index, item.quantity + 1), icon: Icon(Icons.add), style: IconButton.styleFrom( backgroundColor: Colors.grey[200], minimumSize: Size(40, 40), ), ), ], ), // Prix total de l'article Text( '${(item.prix * item.quantity).toStringAsFixed(2)} €', style: TextStyle( fontSize: 18, fontWeight: FontWeight.bold, color: Colors.green[700], ), ), ], ), ], ), ); }, ), ), // Récapitulatif Container( padding: EdgeInsets.all(20), decoration: BoxDecoration( color: Colors.white, border: Border( top: BorderSide(color: Colors.grey[200]!), ), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'Récapitulatif', style: TextStyle( fontSize: 20, fontWeight: FontWeight.bold, ), ), SizedBox(height: 16), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text('Articles:', style: TextStyle(fontSize: 16)), Text( _getTotalArticles().toString(), style: TextStyle(fontSize: 16), ), ], ), SizedBox(height: 8), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text('Table:', style: TextStyle(fontSize: 16)), Text( widget.tableId.toString(), style: TextStyle(fontSize: 16), ), ], ), SizedBox(height: 8), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text('Personnes:', style: TextStyle(fontSize: 16)), Text( widget.personne.toString(), style: TextStyle(fontSize: 16), ), ], ), SizedBox(height: 16), Divider(), SizedBox(height: 8), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( 'Total:', style: TextStyle( fontSize: 18, fontWeight: FontWeight.bold, ), ), Text( '${_calculateTotal().toStringAsFixed(2)} €', style: TextStyle( fontSize: 18, fontWeight: FontWeight.bold, ), ), ], ), SizedBox(height: 20), SizedBox( width: double.infinity, child: ElevatedButton( onPressed: _cartItems.isNotEmpty ? _validateOrder : null, style: ElevatedButton.styleFrom( backgroundColor: Colors.green[700], foregroundColor: Colors.white, padding: EdgeInsets.symmetric(vertical: 16), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12), ), disabledBackgroundColor: Colors.grey[300], ), child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon(Icons.check, size: 20), SizedBox(width: 8), Text( 'Valider la commande', style: TextStyle( fontSize: 16, fontWeight: FontWeight.bold, ), ), ], ), ), ), ], ), ), ], ), ); } } class CartItemModel { final int id; final String nom; final double prix; int quantity; final String notes; CartItemModel({ required this.id, required this.nom, required this.prix, required this.quantity, required this.notes, }); }