|
|
@ -77,7 +77,10 @@ class _CartPageState extends State<CartPage> { |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
double _calculateTotal() { |
|
|
double _calculateTotal() { |
|
|
return _cartItems.fold(0.0, (sum, item) => sum + (item.prix * item.quantity)); |
|
|
return _cartItems.fold( |
|
|
|
|
|
0.0, |
|
|
|
|
|
(sum, item) => sum + (item.prix * item.quantity), |
|
|
|
|
|
); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
int _getTotalArticles() { |
|
|
int _getTotalArticles() { |
|
|
@ -113,13 +116,13 @@ class _CartPageState extends State<CartPage> { |
|
|
actions: [ |
|
|
actions: [ |
|
|
TextButton( |
|
|
TextButton( |
|
|
onPressed: () => Navigator.of(context).pop(), |
|
|
onPressed: () => Navigator.of(context).pop(), |
|
|
child: Text( |
|
|
child: Text('Annuler', style: TextStyle(color: Colors.grey[600])), |
|
|
'Annuler', |
|
|
|
|
|
style: TextStyle(color: Colors.grey[600]), |
|
|
|
|
|
), |
|
|
|
|
|
), |
|
|
), |
|
|
ElevatedButton( |
|
|
ElevatedButton( |
|
|
onPressed: _isValidating ? null : () { |
|
|
onPressed: |
|
|
|
|
|
_isValidating |
|
|
|
|
|
? null |
|
|
|
|
|
: () { |
|
|
Navigator.of(context).pop(); |
|
|
Navigator.of(context).pop(); |
|
|
_validateOrder(); |
|
|
_validateOrder(); |
|
|
}, |
|
|
}, |
|
|
@ -127,13 +130,16 @@ class _CartPageState extends State<CartPage> { |
|
|
backgroundColor: Colors.green[700], |
|
|
backgroundColor: Colors.green[700], |
|
|
foregroundColor: Colors.white, |
|
|
foregroundColor: Colors.white, |
|
|
), |
|
|
), |
|
|
child: _isValidating |
|
|
child: |
|
|
|
|
|
_isValidating |
|
|
? SizedBox( |
|
|
? SizedBox( |
|
|
width: 16, |
|
|
width: 16, |
|
|
height: 16, |
|
|
height: 16, |
|
|
child: CircularProgressIndicator( |
|
|
child: CircularProgressIndicator( |
|
|
strokeWidth: 2, |
|
|
strokeWidth: 2, |
|
|
valueColor: AlwaysStoppedAnimation<Color>(Colors.white), |
|
|
valueColor: AlwaysStoppedAnimation<Color>( |
|
|
|
|
|
Colors.white, |
|
|
|
|
|
), |
|
|
), |
|
|
), |
|
|
) |
|
|
) |
|
|
: Text('Valider'), |
|
|
: Text('Valider'), |
|
|
@ -157,29 +163,36 @@ class _CartPageState extends State<CartPage> { |
|
|
"reservation_id": 1, // Peut être null si pas de réservation |
|
|
"reservation_id": 1, // Peut être null si pas de réservation |
|
|
"serveur": "Serveur par défaut", // Valeur par défaut comme demandé |
|
|
"serveur": "Serveur par défaut", // Valeur par défaut comme demandé |
|
|
"commentaires": _getOrderComments(), |
|
|
"commentaires": _getOrderComments(), |
|
|
"items": _cartItems.map((item) => { |
|
|
"items": |
|
|
|
|
|
_cartItems |
|
|
|
|
|
.map( |
|
|
|
|
|
(item) => { |
|
|
"menu_id": item.id, |
|
|
"menu_id": item.id, |
|
|
"quantite": item.quantity, |
|
|
"quantite": item.quantity, |
|
|
"commentaires": item.notes.isNotEmpty ? item.notes : null, |
|
|
"commentaires": item.notes.isNotEmpty ? item.notes : null, |
|
|
}).toList(), |
|
|
}, |
|
|
|
|
|
) |
|
|
|
|
|
.toList(), |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
// Appel API pour créer la commande |
|
|
// Appel API pour créer la commande |
|
|
final response = await http.post( |
|
|
final response = await http.post( |
|
|
Uri.parse('https://restaurant.careeracademy.mg/api/commandes'), // Remplacez par votre URL d'API |
|
|
Uri.parse( |
|
|
headers: { |
|
|
'https://restaurant.careeracademy.mg/api/commandes', |
|
|
'Content-Type': 'application/json', |
|
|
), // Remplacez par votre URL d'API |
|
|
}, |
|
|
headers: {'Content-Type': 'application/json'}, |
|
|
body: json.encode(orderData), |
|
|
body: json.encode(orderData), |
|
|
); |
|
|
); |
|
|
print(orderData); |
|
|
print('response body: ${response.body}'); |
|
|
|
|
|
|
|
|
if (response.statusCode == 200 || response.statusCode == 201) { |
|
|
if (response.statusCode == 200 || response.statusCode == 201) { |
|
|
// Succès |
|
|
// Succès |
|
|
_showSuccessDialog(); |
|
|
_showSuccessDialog(); |
|
|
} else { |
|
|
} else { |
|
|
// Erreur |
|
|
// Erreur |
|
|
_showErrorDialog('Erreur lors de l\'enregistrement de la commande (${response.statusCode})'); |
|
|
_showErrorDialog( |
|
|
|
|
|
'Erreur lors de l\'enregistrement de la commande (${response.statusCode})', |
|
|
|
|
|
); |
|
|
} |
|
|
} |
|
|
} catch (e) { |
|
|
} catch (e) { |
|
|
_showErrorDialog('Erreur de connexion: $e'); |
|
|
_showErrorDialog('Erreur de connexion: $e'); |
|
|
@ -192,7 +205,8 @@ class _CartPageState extends State<CartPage> { |
|
|
|
|
|
|
|
|
String _getOrderComments() { |
|
|
String _getOrderComments() { |
|
|
// Concaténer toutes les notes des articles pour les commentaires généraux |
|
|
// Concaténer toutes les notes des articles pour les commentaires généraux |
|
|
List<String> allNotes = _cartItems |
|
|
List<String> allNotes = |
|
|
|
|
|
_cartItems |
|
|
.where((item) => item.notes.isNotEmpty) |
|
|
.where((item) => item.notes.isNotEmpty) |
|
|
.map((item) => '${item.nom}: ${item.notes}') |
|
|
.map((item) => '${item.nom}: ${item.notes}') |
|
|
.toList(); |
|
|
.toList(); |
|
|
@ -213,7 +227,9 @@ class _CartPageState extends State<CartPage> { |
|
|
Text('Commande validée'), |
|
|
Text('Commande validée'), |
|
|
], |
|
|
], |
|
|
), |
|
|
), |
|
|
content: Text('Votre commande a été envoyée en cuisine avec succès !'), |
|
|
content: Text( |
|
|
|
|
|
'Votre commande a été envoyée en cuisine avec succès !', |
|
|
|
|
|
), |
|
|
actions: [ |
|
|
actions: [ |
|
|
ElevatedButton( |
|
|
ElevatedButton( |
|
|
onPressed: () { |
|
|
onPressed: () { |
|
|
@ -281,16 +297,14 @@ class _CartPageState extends State<CartPage> { |
|
|
onPressed: () => Navigator.pop(context), |
|
|
onPressed: () => Navigator.pop(context), |
|
|
child: Text( |
|
|
child: Text( |
|
|
'Retour au menu', |
|
|
'Retour au menu', |
|
|
style: TextStyle( |
|
|
style: TextStyle(color: Colors.black, fontSize: 16), |
|
|
color: Colors.black, |
|
|
|
|
|
fontSize: 16, |
|
|
|
|
|
), |
|
|
|
|
|
), |
|
|
), |
|
|
), |
|
|
), |
|
|
SizedBox(width: 16), |
|
|
SizedBox(width: 16), |
|
|
], |
|
|
], |
|
|
), |
|
|
), |
|
|
body: _cartItems.isEmpty |
|
|
body: |
|
|
|
|
|
_cartItems.isEmpty |
|
|
? Center( |
|
|
? Center( |
|
|
child: Column( |
|
|
child: Column( |
|
|
mainAxisAlignment: MainAxisAlignment.center, |
|
|
mainAxisAlignment: MainAxisAlignment.center, |
|
|
@ -303,10 +317,7 @@ class _CartPageState extends State<CartPage> { |
|
|
SizedBox(height: 16), |
|
|
SizedBox(height: 16), |
|
|
Text( |
|
|
Text( |
|
|
'Votre panier est vide', |
|
|
'Votre panier est vide', |
|
|
style: TextStyle( |
|
|
style: TextStyle(fontSize: 18, color: Colors.grey[600]), |
|
|
fontSize: 18, |
|
|
|
|
|
color: Colors.grey[600], |
|
|
|
|
|
), |
|
|
|
|
|
), |
|
|
), |
|
|
], |
|
|
], |
|
|
), |
|
|
), |
|
|
@ -320,10 +331,7 @@ class _CartPageState extends State<CartPage> { |
|
|
color: Colors.white, |
|
|
color: Colors.white, |
|
|
child: Text( |
|
|
child: Text( |
|
|
'Table ${widget.tableId} • ${widget.personne} personne${widget.personne > 1 ? 's' : ''}', |
|
|
'Table ${widget.tableId} • ${widget.personne} personne${widget.personne > 1 ? 's' : ''}', |
|
|
style: TextStyle( |
|
|
style: TextStyle(fontSize: 16, color: Colors.grey[600]), |
|
|
fontSize: 16, |
|
|
|
|
|
color: Colors.grey[600], |
|
|
|
|
|
), |
|
|
|
|
|
), |
|
|
), |
|
|
), |
|
|
), |
|
|
|
|
|
|
|
|
@ -332,7 +340,8 @@ class _CartPageState extends State<CartPage> { |
|
|
child: ListView.separated( |
|
|
child: ListView.separated( |
|
|
padding: EdgeInsets.all(16), |
|
|
padding: EdgeInsets.all(16), |
|
|
itemCount: _cartItems.length, |
|
|
itemCount: _cartItems.length, |
|
|
separatorBuilder: (context, index) => SizedBox(height: 12), |
|
|
separatorBuilder: |
|
|
|
|
|
(context, index) => SizedBox(height: 12), |
|
|
itemBuilder: (context, index) { |
|
|
itemBuilder: (context, index) { |
|
|
final item = _cartItems[index]; |
|
|
final item = _cartItems[index]; |
|
|
return Container( |
|
|
return Container( |
|
|
@ -352,7 +361,8 @@ class _CartPageState extends State<CartPage> { |
|
|
crossAxisAlignment: CrossAxisAlignment.start, |
|
|
crossAxisAlignment: CrossAxisAlignment.start, |
|
|
children: [ |
|
|
children: [ |
|
|
Row( |
|
|
Row( |
|
|
mainAxisAlignment: MainAxisAlignment.spaceBetween, |
|
|
mainAxisAlignment: |
|
|
|
|
|
MainAxisAlignment.spaceBetween, |
|
|
children: [ |
|
|
children: [ |
|
|
Expanded( |
|
|
Expanded( |
|
|
child: Text( |
|
|
child: Text( |
|
|
@ -394,13 +404,18 @@ class _CartPageState extends State<CartPage> { |
|
|
], |
|
|
], |
|
|
SizedBox(height: 16), |
|
|
SizedBox(height: 16), |
|
|
Row( |
|
|
Row( |
|
|
mainAxisAlignment: MainAxisAlignment.spaceBetween, |
|
|
mainAxisAlignment: |
|
|
|
|
|
MainAxisAlignment.spaceBetween, |
|
|
children: [ |
|
|
children: [ |
|
|
// Contrôles de quantité |
|
|
// Contrôles de quantité |
|
|
Row( |
|
|
Row( |
|
|
children: [ |
|
|
children: [ |
|
|
IconButton( |
|
|
IconButton( |
|
|
onPressed: () => _updateQuantity(index, item.quantity - 1), |
|
|
onPressed: |
|
|
|
|
|
() => _updateQuantity( |
|
|
|
|
|
index, |
|
|
|
|
|
item.quantity - 1, |
|
|
|
|
|
), |
|
|
icon: Icon(Icons.remove), |
|
|
icon: Icon(Icons.remove), |
|
|
style: IconButton.styleFrom( |
|
|
style: IconButton.styleFrom( |
|
|
backgroundColor: Colors.grey[200], |
|
|
backgroundColor: Colors.grey[200], |
|
|
@ -417,7 +432,11 @@ class _CartPageState extends State<CartPage> { |
|
|
), |
|
|
), |
|
|
SizedBox(width: 16), |
|
|
SizedBox(width: 16), |
|
|
IconButton( |
|
|
IconButton( |
|
|
onPressed: () => _updateQuantity(index, item.quantity + 1), |
|
|
onPressed: |
|
|
|
|
|
() => _updateQuantity( |
|
|
|
|
|
index, |
|
|
|
|
|
item.quantity + 1, |
|
|
|
|
|
), |
|
|
icon: Icon(Icons.add), |
|
|
icon: Icon(Icons.add), |
|
|
style: IconButton.styleFrom( |
|
|
style: IconButton.styleFrom( |
|
|
backgroundColor: Colors.grey[200], |
|
|
backgroundColor: Colors.grey[200], |
|
|
@ -449,9 +468,7 @@ class _CartPageState extends State<CartPage> { |
|
|
padding: EdgeInsets.all(20), |
|
|
padding: EdgeInsets.all(20), |
|
|
decoration: BoxDecoration( |
|
|
decoration: BoxDecoration( |
|
|
color: Colors.white, |
|
|
color: Colors.white, |
|
|
border: Border( |
|
|
border: Border(top: BorderSide(color: Colors.grey[200]!)), |
|
|
top: BorderSide(color: Colors.grey[200]!), |
|
|
|
|
|
), |
|
|
|
|
|
), |
|
|
), |
|
|
child: Column( |
|
|
child: Column( |
|
|
crossAxisAlignment: CrossAxisAlignment.start, |
|
|
crossAxisAlignment: CrossAxisAlignment.start, |
|
|
@ -522,7 +539,8 @@ class _CartPageState extends State<CartPage> { |
|
|
SizedBox( |
|
|
SizedBox( |
|
|
width: double.infinity, |
|
|
width: double.infinity, |
|
|
child: ElevatedButton( |
|
|
child: ElevatedButton( |
|
|
onPressed: _cartItems.isNotEmpty && !_isValidating |
|
|
onPressed: |
|
|
|
|
|
_cartItems.isNotEmpty && !_isValidating |
|
|
? _showConfirmationDialog |
|
|
? _showConfirmationDialog |
|
|
: null, |
|
|
: null, |
|
|
style: ElevatedButton.styleFrom( |
|
|
style: ElevatedButton.styleFrom( |
|
|
@ -543,7 +561,9 @@ class _CartPageState extends State<CartPage> { |
|
|
height: 20, |
|
|
height: 20, |
|
|
child: CircularProgressIndicator( |
|
|
child: CircularProgressIndicator( |
|
|
strokeWidth: 2, |
|
|
strokeWidth: 2, |
|
|
valueColor: AlwaysStoppedAnimation<Color>(Colors.white), |
|
|
valueColor: AlwaysStoppedAnimation<Color>( |
|
|
|
|
|
Colors.white, |
|
|
|
|
|
), |
|
|
), |
|
|
), |
|
|
), |
|
|
), |
|
|
SizedBox(width: 8), |
|
|
SizedBox(width: 8), |
|
|
|