|
|
|
@ -1,4 +1,6 @@ |
|
|
|
import 'package:flutter/material.dart'; |
|
|
|
import 'package:http/http.dart' as http; |
|
|
|
import 'dart:convert'; |
|
|
|
|
|
|
|
class CartPage extends StatefulWidget { |
|
|
|
final int tableId; |
|
|
|
@ -18,6 +20,7 @@ class CartPage extends StatefulWidget { |
|
|
|
|
|
|
|
class _CartPageState extends State<CartPage> { |
|
|
|
List<CartItemModel> _cartItems = []; |
|
|
|
bool _isValidating = false; |
|
|
|
|
|
|
|
@override |
|
|
|
void initState() { |
|
|
|
@ -81,21 +84,171 @@ class _CartPageState extends State<CartPage> { |
|
|
|
return _cartItems.fold(0, (sum, item) => sum + item.quantity); |
|
|
|
} |
|
|
|
|
|
|
|
void _validateOrder() { |
|
|
|
// TODO: Implémenter la validation de commande |
|
|
|
void _showConfirmationDialog() { |
|
|
|
showDialog( |
|
|
|
context: context, |
|
|
|
barrierDismissible: false, |
|
|
|
builder: (BuildContext context) { |
|
|
|
return AlertDialog( |
|
|
|
title: Text('Commande validée'), |
|
|
|
content: Text('Votre commande a été envoyée en cuisine !'), |
|
|
|
title: Text( |
|
|
|
'Confirmer la commande', |
|
|
|
style: TextStyle(fontWeight: FontWeight.bold), |
|
|
|
), |
|
|
|
content: Column( |
|
|
|
mainAxisSize: MainAxisSize.min, |
|
|
|
crossAxisAlignment: CrossAxisAlignment.start, |
|
|
|
children: [ |
|
|
|
Text('Êtes-vous sûr de vouloir valider cette commande ?'), |
|
|
|
SizedBox(height: 16), |
|
|
|
Text( |
|
|
|
'Récapitulatif:', |
|
|
|
style: TextStyle(fontWeight: FontWeight.bold), |
|
|
|
), |
|
|
|
Text('• Table: ${widget.tableId}'), |
|
|
|
Text('• Personnes: ${widget.personne}'), |
|
|
|
Text('• Articles: ${_getTotalArticles()}'), |
|
|
|
Text('• Total: ${_calculateTotal().toStringAsFixed(2)} €'), |
|
|
|
], |
|
|
|
), |
|
|
|
actions: [ |
|
|
|
TextButton( |
|
|
|
onPressed: () => Navigator.of(context).pop(), |
|
|
|
child: Text( |
|
|
|
'Annuler', |
|
|
|
style: TextStyle(color: Colors.grey[600]), |
|
|
|
), |
|
|
|
), |
|
|
|
ElevatedButton( |
|
|
|
onPressed: _isValidating ? null : () { |
|
|
|
Navigator.of(context).pop(); |
|
|
|
_validateOrder(); |
|
|
|
}, |
|
|
|
style: ElevatedButton.styleFrom( |
|
|
|
backgroundColor: Colors.green[700], |
|
|
|
foregroundColor: Colors.white, |
|
|
|
), |
|
|
|
child: _isValidating |
|
|
|
? SizedBox( |
|
|
|
width: 16, |
|
|
|
height: 16, |
|
|
|
child: CircularProgressIndicator( |
|
|
|
strokeWidth: 2, |
|
|
|
valueColor: AlwaysStoppedAnimation<Color>(Colors.white), |
|
|
|
), |
|
|
|
) |
|
|
|
: Text('Valider'), |
|
|
|
), |
|
|
|
], |
|
|
|
); |
|
|
|
}, |
|
|
|
); |
|
|
|
} |
|
|
|
|
|
|
|
Future<void> _validateOrder() async { |
|
|
|
setState(() { |
|
|
|
_isValidating = true; |
|
|
|
}); |
|
|
|
|
|
|
|
try { |
|
|
|
// Préparer les données de la commande |
|
|
|
final orderData = { |
|
|
|
"client_id": 1, // Valeur par défaut comme demandé |
|
|
|
"table_id": widget.tableId, |
|
|
|
"reservation_id": 1, // Peut être null si pas de réservation |
|
|
|
"serveur": "Serveur par défaut", // Valeur par défaut comme demandé |
|
|
|
"commentaires": _getOrderComments(), |
|
|
|
"items": _cartItems.map((item) => { |
|
|
|
"menu_id": item.id, |
|
|
|
"quantite": item.quantity, |
|
|
|
"commentaires": item.notes.isNotEmpty ? item.notes : null, |
|
|
|
}).toList(), |
|
|
|
}; |
|
|
|
|
|
|
|
// Appel API pour créer la commande |
|
|
|
final response = await http.post( |
|
|
|
Uri.parse('https://restaurant.careeracademy.mg/api/commandes'), // Remplacez par votre URL d'API |
|
|
|
headers: { |
|
|
|
'Content-Type': 'application/json', |
|
|
|
}, |
|
|
|
body: json.encode(orderData), |
|
|
|
); |
|
|
|
print(orderData); |
|
|
|
|
|
|
|
if (response.statusCode == 200 || response.statusCode == 201) { |
|
|
|
// Succès |
|
|
|
_showSuccessDialog(); |
|
|
|
} else { |
|
|
|
// Erreur |
|
|
|
_showErrorDialog('Erreur lors de l\'enregistrement de la commande (${response.statusCode})'); |
|
|
|
} |
|
|
|
} catch (e) { |
|
|
|
_showErrorDialog('Erreur de connexion: $e'); |
|
|
|
} finally { |
|
|
|
setState(() { |
|
|
|
_isValidating = false; |
|
|
|
}); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
String _getOrderComments() { |
|
|
|
// Concaténer toutes les notes des articles pour les commentaires généraux |
|
|
|
List<String> allNotes = _cartItems |
|
|
|
.where((item) => item.notes.isNotEmpty) |
|
|
|
.map((item) => '${item.nom}: ${item.notes}') |
|
|
|
.toList(); |
|
|
|
|
|
|
|
return allNotes.join('; '); |
|
|
|
} |
|
|
|
|
|
|
|
void _showSuccessDialog() { |
|
|
|
showDialog( |
|
|
|
context: context, |
|
|
|
barrierDismissible: false, |
|
|
|
builder: (BuildContext context) { |
|
|
|
return AlertDialog( |
|
|
|
title: Row( |
|
|
|
children: [ |
|
|
|
Icon(Icons.check_circle, color: Colors.green[700]), |
|
|
|
SizedBox(width: 8), |
|
|
|
Text('Commande validée'), |
|
|
|
], |
|
|
|
), |
|
|
|
content: Text('Votre commande a été envoyée en cuisine avec succès !'), |
|
|
|
actions: [ |
|
|
|
ElevatedButton( |
|
|
|
onPressed: () { |
|
|
|
Navigator.of(context).pop(); // Fermer le dialog |
|
|
|
Navigator.of(context).pop(); // Retourner au menu |
|
|
|
Navigator.of(context).pop(); // Retourner aux tables |
|
|
|
}, |
|
|
|
style: ElevatedButton.styleFrom( |
|
|
|
backgroundColor: Colors.green[700], |
|
|
|
foregroundColor: Colors.white, |
|
|
|
), |
|
|
|
child: Text('OK'), |
|
|
|
), |
|
|
|
], |
|
|
|
); |
|
|
|
}, |
|
|
|
); |
|
|
|
} |
|
|
|
|
|
|
|
void _showErrorDialog(String message) { |
|
|
|
showDialog( |
|
|
|
context: context, |
|
|
|
builder: (BuildContext context) { |
|
|
|
return AlertDialog( |
|
|
|
title: Row( |
|
|
|
children: [ |
|
|
|
Icon(Icons.error, color: Colors.red), |
|
|
|
SizedBox(width: 8), |
|
|
|
Text('Erreur'), |
|
|
|
], |
|
|
|
), |
|
|
|
content: Text(message), |
|
|
|
actions: [ |
|
|
|
TextButton( |
|
|
|
onPressed: () => Navigator.of(context).pop(), |
|
|
|
child: Text('OK'), |
|
|
|
), |
|
|
|
], |
|
|
|
@ -369,7 +522,9 @@ class _CartPageState extends State<CartPage> { |
|
|
|
SizedBox( |
|
|
|
width: double.infinity, |
|
|
|
child: ElevatedButton( |
|
|
|
onPressed: _cartItems.isNotEmpty ? _validateOrder : null, |
|
|
|
onPressed: _cartItems.isNotEmpty && !_isValidating |
|
|
|
? _showConfirmationDialog |
|
|
|
: null, |
|
|
|
style: ElevatedButton.styleFrom( |
|
|
|
backgroundColor: Colors.green[700], |
|
|
|
foregroundColor: Colors.white, |
|
|
|
@ -382,6 +537,24 @@ class _CartPageState extends State<CartPage> { |
|
|
|
child: Row( |
|
|
|
mainAxisAlignment: MainAxisAlignment.center, |
|
|
|
children: [ |
|
|
|
if (_isValidating) ...[ |
|
|
|
SizedBox( |
|
|
|
width: 20, |
|
|
|
height: 20, |
|
|
|
child: CircularProgressIndicator( |
|
|
|
strokeWidth: 2, |
|
|
|
valueColor: AlwaysStoppedAnimation<Color>(Colors.white), |
|
|
|
), |
|
|
|
), |
|
|
|
SizedBox(width: 8), |
|
|
|
Text( |
|
|
|
'Validation en cours...', |
|
|
|
style: TextStyle( |
|
|
|
fontSize: 16, |
|
|
|
fontWeight: FontWeight.bold, |
|
|
|
), |
|
|
|
), |
|
|
|
] else ...[ |
|
|
|
Icon(Icons.check, size: 20), |
|
|
|
SizedBox(width: 8), |
|
|
|
Text( |
|
|
|
@ -392,6 +565,7 @@ class _CartPageState extends State<CartPage> { |
|
|
|
), |
|
|
|
), |
|
|
|
], |
|
|
|
], |
|
|
|
), |
|
|
|
), |
|
|
|
), |
|
|
|
|