From e61cd760bdab6914bf3847fde054373d0ff2725e Mon Sep 17 00:00:00 2001 From: Stephane Date: Sun, 3 Aug 2025 18:29:12 +0300 Subject: [PATCH] paier directement --- android/app/build.gradle.kts | 2 +- android/app/src/main/AndroidManifest.xml | 19 +- lib/pages/caisse_screen.dart | 16 +- lib/pages/cart_page.dart | 912 ++++++++++++------ lib/pages/commandes_screen.dart | 38 +- lib/pages/encaissement_screen.dart | 34 +- lib/pages/menu.dart | 11 +- lib/pages/tables.dart | 3 +- macos/Podfile.lock | 35 + macos/Runner.xcodeproj/project.pbxproj | 98 +- .../contents.xcworkspacedata | 3 + pubspec.lock | 48 + .../flutter/generated_plugin_registrant.cc | 3 + windows/flutter/generated_plugins.cmake | 1 + 14 files changed, 870 insertions(+), 353 deletions(-) create mode 100644 macos/Podfile.lock diff --git a/android/app/build.gradle.kts b/android/app/build.gradle.kts index 61d0533..fc8142f 100644 --- a/android/app/build.gradle.kts +++ b/android/app/build.gradle.kts @@ -8,7 +8,7 @@ plugins { android { namespace = "com.example.itrimobe" compileSdk = flutter.compileSdkVersion - ndkVersion = flutter.ndkVersion + ndkVersion = "27.0.12077973" compileOptions { sourceCompatibility = JavaVersion.VERSION_11 diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index b804609..82be408 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -10,10 +10,21 @@ - - - - + + + + + + + + + + + + _CaisseScreenState(); @@ -26,26 +26,26 @@ class _CaisseScreenState extends State { bool isProcessingPayment = false; final List paymentMethods = [ - PaymentMethod( + const PaymentMethod( id: 'mvola', name: 'MVola', description: 'Paiement mobile MVola', icon: Icons.phone, - color: const Color(0xFF4285F4), + color: Color(0xFF4285F4), ), - PaymentMethod( + const PaymentMethod( id: 'carte', name: 'Carte Bancaire', description: 'Paiement par carte', icon: Icons.credit_card, - color: const Color(0xFF28A745), + color: Color(0xFF28A745), ), - PaymentMethod( + const PaymentMethod( id: 'especes', name: 'Espèces', description: 'Paiement en liquide', icon: Icons.attach_money, - color: const Color(0xFFFF9500), + color: Color(0xFFFF9500), ), ]; diff --git a/lib/pages/cart_page.dart b/lib/pages/cart_page.dart index bd68637..37f7bc1 100644 --- a/lib/pages/cart_page.dart +++ b/lib/pages/cart_page.dart @@ -1,3 +1,4 @@ +import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:http/http.dart' as http; import 'dart:convert'; @@ -9,14 +10,16 @@ import '../layouts/main_layout.dart'; class CartPage extends StatefulWidget { final int tableId; final int personne; + final String? tablename; final List cartItems; const CartPage({ - Key? key, + super.key, required this.tableId, required this.personne, required this.cartItems, - }) : super(key: key); + this.tablename, + }); @override State createState() => _CartPageState(); @@ -47,7 +50,7 @@ class _CartPageState extends State { nom: item['nom'] ?? 'Article', prix: _parsePrice(item['prix']), quantity: 1, - notes: item['notes'] ?? '', + commentaire: item['commentaire'] ?? '', ); } } @@ -97,7 +100,7 @@ class _CartPageState extends State { barrierDismissible: false, builder: (BuildContext context) { return AlertDialog( - title: Text( + title: const Text( 'Confirmer la commande', style: TextStyle(fontWeight: FontWeight.bold), ), @@ -105,9 +108,9 @@ class _CartPageState extends State { mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ - Text('Êtes-vous sûr de vouloir valider cette commande ?'), - SizedBox(height: 16), - Text( + const Text('Êtes-vous sûr de vouloir valider cette commande ?'), + const SizedBox(height: 16), + const Text( 'Récapitulatif:', style: TextStyle(fontWeight: FontWeight.bold), ), @@ -123,28 +126,30 @@ class _CartPageState extends State { child: Text('Annuler', style: TextStyle(color: Colors.grey[600])), ), ElevatedButton( - onPressed: _isValidating - ? null - : () { - Navigator.of(context).pop(); - _validateOrder(); - }, + 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( - Colors.white, + child: + _isValidating + ? const SizedBox( + width: 16, + height: 16, + child: CircularProgressIndicator( + strokeWidth: 2, + valueColor: AlwaysStoppedAnimation( + Colors.white, + ), ), - ), - ) - : Text('Valider'), + ) + : const Text('Valider'), ), ], ); @@ -165,15 +170,17 @@ class _CartPageState extends State { "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(), + "items": + _cartItems + .map( + (item) => { + "menu_id": item.id, + "quantite": item.quantity, + "commentaires": + item.commentaire.isNotEmpty ? item.commentaire : null, + }, + ) + .toList(), }; // Appel API pour créer la commande @@ -207,10 +214,11 @@ class _CartPageState extends State { String _getOrderComments() { // Concaténer toutes les notes des articles pour les commentaires généraux - List allNotes = _cartItems - .where((item) => item.notes.isNotEmpty) - .map((item) => '${item.nom}: ${item.notes}') - .toList(); + List allNotes = + _cartItems + .where((item) => item.commentaire.isNotEmpty) + .map((item) => '${item.nom}: ${item.commentaire}') + .toList(); return allNotes.join('; '); } @@ -225,11 +233,11 @@ class _CartPageState extends State { title: Row( children: [ Icon(Icons.check_circle, color: Colors.green[700]), - SizedBox(width: 8), - Text('Commande validée'), + const SizedBox(width: 8), + const Text('Commande validée'), ], ), - content: Text( + content: const Text( 'Votre commande a été envoyée en cuisine avec succès !', ), actions: [ @@ -237,12 +245,13 @@ class _CartPageState extends State { onPressed: () { Navigator.of(context).pushAndRemoveUntil( MaterialPageRoute( - builder: (context) => MainLayout(child: TablesScreen()), + builder: + (context) => const MainLayout(child: TablesScreen()), ), (route) => false, ); }, - child: Text('OK'), + child: const Text('OK'), ), ], ); @@ -252,14 +261,17 @@ class _CartPageState extends State { Future _updateTableStatus() async { try { - final updateResponse = await http.put( + final _ = await http.put( Uri.parse( - 'https://restaurant.careeracademy.mg/api/tables/${widget.tableId}'), + 'https://restaurant.careeracademy.mg/api/tables/${widget.tableId}', + ), headers: {'Content-Type': 'application/json'}, body: json.encode({"status": "occupied"}), ); } catch (e) { - print("Erreur lors de la mise à jour du statut de la table: $e"); + if (kDebugMode) { + print("Erreur lors de la mise à jour du statut de la table: $e"); + } } } @@ -268,7 +280,7 @@ class _CartPageState extends State { context: context, builder: (BuildContext context) { return AlertDialog( - title: Row( + title: const Row( children: [ Icon(Icons.error, color: Colors.red), SizedBox(width: 8), @@ -279,7 +291,7 @@ class _CartPageState extends State { actions: [ TextButton( onPressed: () => Navigator.of(context).pop(), - child: Text('OK'), + child: const Text('OK'), ), ], ); @@ -287,6 +299,225 @@ class _CartPageState extends State { ); } + Future _payerDirectement() async { + if (_cartItems.isEmpty) { + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar( + content: Text('Aucun article dans le panier'), + backgroundColor: Colors.red, + ), + ); + return; + } + + // Calculer le total + double total = _cartItems.fold(0.0, (sum, item) { + return sum + (item.prix * item.quantity); + }); + + // Confirmer le paiement + final bool? confirm = await showDialog( + context: context, + builder: + (context) => AlertDialog( + title: const Text('Confirmer le paiement'), + content: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text('${widget.tablename}'), + const SizedBox(height: 8), + Text('Articles: ${_cartItems.length}'), + const SizedBox(height: 8), + Text( + 'Total: ${total.toStringAsFixed(0)} MGA', + style: const TextStyle( + fontSize: 18, + fontWeight: FontWeight.bold, + ), + ), + const SizedBox(height: 16), + const Text('Valider et payer cette commande ?'), + ], + ), + actions: [ + TextButton( + onPressed: () => Navigator.of(context).pop(false), + child: const Text('Annuler'), + ), + ElevatedButton( + onPressed: () => Navigator.of(context).pop(true), + style: ElevatedButton.styleFrom( + backgroundColor: Colors.orange[600], + ), + child: const Text('Confirmer le paiement'), + ), + ], + ), + ); + + if (confirm != true) return; + + setState(() { + _isValidating = true; + }); + + try { + // 1. Créer la commande avec les items du panier + final response = await http.post( + Uri.parse('https://restaurant.careeracademy.mg/api/commandes'), + headers: {'Content-Type': 'application/json'}, + body: jsonEncode({ + 'table_id': widget.tableId, + 'statut': 'payee', // Directement payée + 'items': + _cartItems + .map( + (item) => { + 'menu_id': item.id, + 'quantite': item.quantity, + 'prix_unitaire': item.prix, + 'commentaire': item.commentaire, + // Pas de réservation + }, + ) + .toList(), + 'methode_paiement': 'especes', + 'montant_paye': total, + 'date_paiement': DateTime.now().toIso8601String(), + 'client_id': 1, // Valeur par défaut + 'reservation_id': 1, + 'serveur': 'Serveur par défaut', // Valeur par défaut + }), + ); + + if (response.statusCode == 201) { + final commandeData = jsonDecode(response.body); + + // 2. Libérer la table + await http.patch( + Uri.parse( + 'https://restaurant.careeracademy.mg/api/tables/${widget.tableId}', + ), + headers: {'Content-Type': 'application/json'}, + body: jsonEncode({'statut': 'libre'}), + ); + + // 3. Succès + Navigator.of(context).pushAndRemoveUntil( + MaterialPageRoute( + builder: (context) => const MainLayout(child: TablesScreen()), + ), + (route) => false, + ); + } else { + throw Exception('Erreur lors du paiement'); + } + } catch (e) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('Erreur: ${e.toString()}'), + backgroundColor: Colors.red, + ), + ); + } finally { + setState(() { + _isValidating = false; + }); + } + } + + void _showPaymentSuccessDialog( + Map commandeData, + double total, + ) { + showDialog( + context: context, + barrierDismissible: false, + builder: + (context) => AlertDialog( + title: const Row( + children: [ + Icon(Icons.check_circle, color: Colors.green, size: 28), + SizedBox(width: 8), + Text('Paiement confirmé'), + ], + ), + content: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Text('Commande #${commandeData['numeroCommande']}'), + const SizedBox(height: 8), + Text('${widget.tablename} libérée'), + const SizedBox(height: 8), + Text( + 'Montant: ${total.toStringAsFixed(2)} €', + style: const TextStyle(fontWeight: FontWeight.bold), + ), + const SizedBox(height: 16), + const Text('Voulez-vous imprimer un reçu ?'), + ], + ), + actions: [ + TextButton( + onPressed: () { + Navigator.of(context).pop(); + Navigator.of(context).pop(); // Retour au menu principal + }, + child: const Text('Non merci'), + ), + ElevatedButton( + onPressed: () async { + Navigator.of(context).pop(); + await _imprimerTicketPaiement(commandeData, total); + Navigator.of(context).pop(); // Retour au menu principal + }, + child: const Text('Imprimer'), + ), + ], + ), + ); + } + + Future _imprimerTicketPaiement( + Map commandeData, + double total, + ) async { + try { + // Préparer les données pour l'impression + _cartItems + .map( + (item) => { + 'nom': item.nom, + 'quantite': item.quantity, + 'prix_unitaire': item.prix, + 'sous_total': item.prix * item.quantity, + }, + ) + .toList(); + + // Appeler le service d'impression + // await PlatformPrintService.printFacture( + // commande: widget.commande, + // paymentMethod: widget.paymentMethod, + // ); + + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar( + content: Text('Ticket imprimé avec succès'), + backgroundColor: Colors.green, + ), + ); + } catch (e) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('Erreur d\'impression: ${e.toString()}'), + backgroundColor: Colors.orange, + ), + ); + } + } + @override Widget build(BuildContext context) { return Scaffold( @@ -296,9 +527,9 @@ class _CartPageState extends State { elevation: 0, leading: IconButton( onPressed: () => Navigator.pop(context), - icon: Icon(Icons.arrow_back, color: Colors.black), + icon: const Icon(Icons.arrow_back, color: Colors.black), ), - title: Text( + title: const Text( 'Panier', style: TextStyle( color: Colors.black, @@ -309,298 +540,371 @@ class _CartPageState extends State { actions: [ TextButton( onPressed: () => Navigator.pop(context), - child: Text( + child: const Text( 'Retour au menu', style: TextStyle(color: Colors.black, fontSize: 16), ), ), - SizedBox(width: 16), + const SizedBox(width: 16), ], ), - body: _cartItems.isEmpty - ? Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, + body: + _cartItems.isEmpty + ? Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon( + Icons.shopping_cart_outlined, + size: 80, + color: Colors.grey[400], + ), + const SizedBox(height: 16), + Text( + 'Votre panier est vide', + style: TextStyle(fontSize: 18, color: Colors.grey[600]), + ), + ], + ), + ) + : Column( 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]), + // Header avec infos table + Container( + width: double.infinity, + padding: const EdgeInsets.all(20), + color: Colors.white, + child: Text( + '${widget.tablename} • ${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, + // Liste des articles + Expanded( + child: ListView.separated( + padding: const EdgeInsets.all(16), + itemCount: _cartItems.length, + separatorBuilder: + (context, index) => const SizedBox(height: 12), + itemBuilder: (context, index) { + final item = _cartItems[index]; + return Container( + padding: const EdgeInsets.all(16), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(12), + boxShadow: [ + BoxShadow( + color: Colors.black.withOpacity(0.05), + blurRadius: 5, + offset: const Offset(0, 2), + ), + ], + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Expanded( + child: Text( + item.nom, + style: const TextStyle( + fontSize: 18, + fontWeight: FontWeight.bold, + ), ), ), - ), - IconButton( - onPressed: () => _removeItem(index), - icon: Icon( - Icons.delete_outline, - color: Colors.red, + IconButton( + onPressed: () => _removeItem(index), + icon: const Icon( + Icons.delete_outline, + color: Colors.red, + ), + constraints: const BoxConstraints(), + padding: EdgeInsets.zero, ), - constraints: BoxConstraints(), - padding: EdgeInsets.zero, - ), - ], - ), - Text( - '${item.prix.toStringAsFixed(2)} MGA l\'unité', - style: TextStyle( - fontSize: 14, - color: Colors.grey[600], + ], ), - ), - if (item.notes.isNotEmpty) ...[ - SizedBox(height: 8), Text( - 'Notes: ${item.notes}', + '${item.prix.toStringAsFixed(2)} MGA l\'unité', 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 + if (item.commentaire.isNotEmpty) ...[ + const SizedBox(height: 8), Text( - '${(item.prix * item.quantity).toStringAsFixed(2)} MGA', + 'Notes: ${item.commentaire}', style: TextStyle( - fontSize: 18, - fontWeight: FontWeight.bold, - color: Colors.green[700], + fontSize: 14, + color: Colors.grey[600], + fontStyle: FontStyle.italic, ), ), ], + const SizedBox(height: 16), + Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + // Contrôles de quantité + Row( + children: [ + IconButton( + onPressed: + () => _updateQuantity( + index, + item.quantity - 1, + ), + icon: const Icon(Icons.remove), + style: IconButton.styleFrom( + backgroundColor: Colors.grey[200], + minimumSize: const Size(40, 40), + ), + ), + const SizedBox(width: 16), + Text( + item.quantity.toString(), + style: const TextStyle( + fontSize: 18, + fontWeight: FontWeight.bold, + ), + ), + const SizedBox(width: 16), + IconButton( + onPressed: + () => _updateQuantity( + index, + item.quantity + 1, + ), + icon: const Icon(Icons.add), + style: IconButton.styleFrom( + backgroundColor: Colors.grey[200], + minimumSize: const Size(40, 40), + ), + ), + ], + ), + // Prix total de l'article + Text( + '${(item.prix * item.quantity).toStringAsFixed(2)} MGA', + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.bold, + color: Colors.green[700], + ), + ), + ], + ), + ], + ), + ); + }, + ), + ), + + // Récapitulatif + Container( + padding: const EdgeInsets.all(20), + decoration: BoxDecoration( + color: Colors.white, + border: Border(top: BorderSide(color: Colors.grey[200]!)), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const Text( + 'Récapitulatif', + style: TextStyle( + fontSize: 20, + fontWeight: FontWeight.bold, + ), + ), + const SizedBox(height: 16), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + const Text( + 'Articles:', + style: TextStyle(fontSize: 16), + ), + Text( + _getTotalArticles().toString(), + style: const TextStyle(fontSize: 16), ), ], ), - ); - }, - ), - ), - - // 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, + const SizedBox(height: 8), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + const Text( + 'Table:', + style: TextStyle(fontSize: 16), + ), + Text( + widget.tableId.toString(), + style: const TextStyle(fontSize: 16), + ), + ], ), - ), - 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, + const SizedBox(height: 8), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + const Text( + 'Personnes:', + style: TextStyle(fontSize: 16), ), - ), - Text( - '${_calculateTotal().toStringAsFixed(2)} MGA', - style: TextStyle( - fontSize: 18, - fontWeight: FontWeight.bold, + Text( + widget.personne.toString(), + style: const TextStyle(fontSize: 16), ), - ), - ], - ), - SizedBox(height: 20), - SizedBox( - width: double.infinity, - child: ElevatedButton( - onPressed: _cartItems.isNotEmpty && !_isValidating - ? _showConfirmationDialog - : null, - style: ElevatedButton.styleFrom( - backgroundColor: Colors.green[700], - foregroundColor: Colors.white, - padding: EdgeInsets.symmetric(vertical: 16), - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(12), + ], + ), + const SizedBox(height: 16), + const Divider(), + const SizedBox(height: 8), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + const Text( + 'Total:', + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.bold, + ), + ), + Text( + '${_calculateTotal().toStringAsFixed(2)} MGA', + style: const TextStyle( + fontSize: 18, + fontWeight: FontWeight.bold, + ), + ), + ], + ), + const SizedBox(height: 20), + SizedBox( + width: double.infinity, + child: ElevatedButton( + onPressed: + _cartItems.isNotEmpty && !_isValidating + ? _showConfirmationDialog + : null, + style: ElevatedButton.styleFrom( + backgroundColor: Colors.green[700], + foregroundColor: Colors.white, + padding: const EdgeInsets.symmetric(vertical: 16), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + ), + disabledBackgroundColor: Colors.grey[300], + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + if (_isValidating) ...[ + const SizedBox( + width: 20, + height: 20, + child: CircularProgressIndicator( + strokeWidth: 2, + valueColor: AlwaysStoppedAnimation( + Colors.white, + ), + ), + ), + const SizedBox(width: 8), + const Text( + 'Validation en cours...', + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.bold, + ), + ), + ] else ...[ + const Icon(Icons.check, size: 20), + const SizedBox(width: 8), + const Text( + 'Valider la commande', + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.bold, + ), + ), + ], + ], ), - disabledBackgroundColor: Colors.grey[300], ), - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - if (_isValidating) ...[ - SizedBox( - width: 20, - height: 20, - child: CircularProgressIndicator( - strokeWidth: 2, - valueColor: AlwaysStoppedAnimation( - Colors.white, + ), + + const SizedBox(height: 12), + + // Bouton Payer directement + SizedBox( + width: double.infinity, + child: ElevatedButton( + onPressed: + _cartItems.isNotEmpty && !_isValidating + ? _payerDirectement + : null, + style: ElevatedButton.styleFrom( + backgroundColor: Colors.orange[600], + foregroundColor: Colors.white, + padding: const EdgeInsets.symmetric(vertical: 16), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + ), + disabledBackgroundColor: Colors.grey[300], + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + if (_isValidating) ...[ + const SizedBox( + width: 20, + height: 20, + child: CircularProgressIndicator( + strokeWidth: 2, + valueColor: AlwaysStoppedAnimation( + Colors.white, + ), ), ), - ), - SizedBox(width: 8), - Text( - 'Validation en cours...', - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.bold, + const SizedBox(width: 8), + const Text( + 'Traitement...', + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.bold, + ), ), - ), - ] else ...[ - Icon(Icons.check, size: 20), - SizedBox(width: 8), - Text( - 'Valider la commande', - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.bold, + ] else ...[ + const Icon(Icons.payment, size: 20), + const SizedBox(width: 8), + const Text( + 'Payer directement', + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.bold, + ), ), - ), + ], ], - ], + ), ), ), - ), - ], + ], + ), ), - ), - ], - ), + ], + ), ); } } @@ -610,13 +914,13 @@ class CartItemModel { final String nom; final double prix; int quantity; - final String notes; + final String commentaire; CartItemModel({ required this.id, required this.nom, required this.prix, required this.quantity, - required this.notes, + required this.commentaire, }); -} \ No newline at end of file +} diff --git a/lib/pages/commandes_screen.dart b/lib/pages/commandes_screen.dart index 23b787e..2c3b9d0 100644 --- a/lib/pages/commandes_screen.dart +++ b/lib/pages/commandes_screen.dart @@ -311,7 +311,7 @@ class _OrdersManagementScreenState extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - 'Table ${order.tableId} - ${order.totalTtc.toStringAsFixed(2)} MGA', + '${order.tablename} - ${order.totalTtc.toStringAsFixed(2)} MGA', ), ], ), @@ -515,7 +515,6 @@ class _OrdersManagementScreenState extends State { } } - class OrderCard extends StatelessWidget { final Order order; final Function(Order, String, {String? modePaiement}) onStatusUpdate; @@ -587,7 +586,7 @@ class OrderCard extends StatelessWidget { GestureDetector( onTap: onViewDetails, child: Text( - 'Table ${order.tableId}', + '${order.tablename}', style: const TextStyle( fontSize: 18, fontWeight: FontWeight.bold, @@ -655,14 +654,13 @@ class OrderCard extends StatelessWidget { color: Colors.black87, ), ), - Text( - '${(item.pu ?? 0) * item.quantite} MGA', - style: const TextStyle( - fontSize: 14, - color: Colors.black87, - ), - ), - + Text( + '${(item.pu ?? 0) * item.quantite} MGA', + style: const TextStyle( + fontSize: 14, + color: Colors.black87, + ), + ), ], ), ), @@ -861,6 +859,7 @@ class Order { final DateTime createdAt; DateTime updatedAt; final List items; + final String? tablename; Order({ required this.id, @@ -880,6 +879,7 @@ class Order { required this.createdAt, required this.updatedAt, this.items = const [], + this.tablename = '', }); factory Order.fromJson(Map json) { @@ -912,6 +912,7 @@ class Order { createdAt: DateTime.parse(json['created_at']), updatedAt: DateTime.parse(json['updated_at']), items: orderItems, + tablename: json['tablename'] ?? '', ); } @@ -925,7 +926,13 @@ class OrderItem { final String? nom; final double? pu; - OrderItem({required this.menuId, required this.quantite, this.commentaires, this.nom, this.pu}); + OrderItem({ + required this.menuId, + required this.quantite, + this.commentaires, + this.nom, + this.pu, + }); factory OrderItem.fromJson(Map json) { return OrderItem( @@ -933,9 +940,10 @@ class OrderItem { quantite: json['quantite'], commentaires: json['commentaires'], nom: json['menu_nom'], - pu: json['menu_prix_actuel'] != null - ? double.tryParse(json['menu_prix_actuel'].toString()) - : null, + pu: + json['menu_prix_actuel'] != null + ? double.tryParse(json['menu_prix_actuel'].toString()) + : null, ); } } diff --git a/lib/pages/encaissement_screen.dart b/lib/pages/encaissement_screen.dart index f420817..b733777 100644 --- a/lib/pages/encaissement_screen.dart +++ b/lib/pages/encaissement_screen.dart @@ -116,23 +116,23 @@ class _EncaissementScreenState extends State { ), const Spacer(), // Bouton Commande Directe - ElevatedButton.icon( - onPressed: _showCommandeDirecteDialog, - icon: const Icon(Icons.add_shopping_cart, size: 20), - label: const Text('Commande Directe'), - style: ElevatedButton.styleFrom( - backgroundColor: const Color(0xFF007BFF), - foregroundColor: Colors.white, - elevation: 2, - padding: const EdgeInsets.symmetric( - horizontal: 16, - vertical: 12, - ), - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(8), - ), - ), - ), + // ElevatedButton.icon( + // onPressed: _showCommandeDirecteDialog, + // icon: const Icon(Icons.add_shopping_cart, size: 20), + // label: const Text('Commande Directe'), + // style: ElevatedButton.styleFrom( + // backgroundColor: const Color(0xFF007BFF), + // foregroundColor: Colors.white, + // elevation: 2, + // padding: const EdgeInsets.symmetric( + // horizontal: 16, + // vertical: 12, + // ), + // shape: RoundedRectangleBorder( + // borderRadius: BorderRadius.circular(8), + // ), + // ), + // ), ], ), ), diff --git a/lib/pages/menu.dart b/lib/pages/menu.dart index f948be6..c23b1c8 100644 --- a/lib/pages/menu.dart +++ b/lib/pages/menu.dart @@ -9,8 +9,14 @@ import 'cart_page.dart'; // Assurez-vous que le fichier cart_page.dart est dans class MenuPage extends StatefulWidget { final int tableId; final int personne; + final String? tablename; - const MenuPage({super.key, required this.tableId, required this.personne}); + const MenuPage({ + super.key, + required this.tableId, + required this.personne, + this.tablename, + }); @override State createState() => _MenuPageState(); @@ -126,6 +132,7 @@ class _MenuPageState extends State { (context) => CartPage( tableId: widget.tableId, personne: widget.personne, + tablename: widget.tablename, cartItems: List.from( _cart, ), // Copie de la liste pour éviter les modifications @@ -169,7 +176,7 @@ class _MenuPageState extends State { Padding( padding: const EdgeInsets.all(8.0), child: Text( - "Table ${widget.tableId} • ${widget.personne} personne${widget.personne > 1 ? 's' : ''}", + "${widget.tablename} • ${widget.personne} personne${widget.personne > 1 ? 's' : ''}", style: const TextStyle(fontSize: 16), ), ), diff --git a/lib/pages/tables.dart b/lib/pages/tables.dart index 9583403..190ef68 100644 --- a/lib/pages/tables.dart +++ b/lib/pages/tables.dart @@ -470,6 +470,7 @@ class _TablesScreenState extends State { tableId: table.id, personne: table.capacity, + tablename: table.nom, ), ), ); @@ -668,4 +669,4 @@ class _AddEditTableDialogState extends State<_AddEditTableDialog> { ], ); } -} \ No newline at end of file +} diff --git a/macos/Podfile.lock b/macos/Podfile.lock new file mode 100644 index 0000000..776d5ca --- /dev/null +++ b/macos/Podfile.lock @@ -0,0 +1,35 @@ +PODS: + - FlutterMacOS (1.0.0) + - path_provider_foundation (0.0.1): + - Flutter + - FlutterMacOS + - printing (1.0.0): + - FlutterMacOS + - share_plus (0.0.1): + - FlutterMacOS + +DEPENDENCIES: + - FlutterMacOS (from `Flutter/ephemeral`) + - path_provider_foundation (from `Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin`) + - printing (from `Flutter/ephemeral/.symlinks/plugins/printing/macos`) + - share_plus (from `Flutter/ephemeral/.symlinks/plugins/share_plus/macos`) + +EXTERNAL SOURCES: + FlutterMacOS: + :path: Flutter/ephemeral + path_provider_foundation: + :path: Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin + printing: + :path: Flutter/ephemeral/.symlinks/plugins/printing/macos + share_plus: + :path: Flutter/ephemeral/.symlinks/plugins/share_plus/macos + +SPEC CHECKSUMS: + FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24 + path_provider_foundation: 080d55be775b7414fd5a5ef3ac137b97b097e564 + printing: c4cf83c78fd684f9bc318e6aadc18972aa48f617 + share_plus: 3c787998077d6b31e839225a282e9e27edf99274 + +PODFILE CHECKSUM: 7eb978b976557c8c1cd717d8185ec483fd090a82 + +COCOAPODS: 1.16.2 diff --git a/macos/Runner.xcodeproj/project.pbxproj b/macos/Runner.xcodeproj/project.pbxproj index 80a8bfb..677bc41 100644 --- a/macos/Runner.xcodeproj/project.pbxproj +++ b/macos/Runner.xcodeproj/project.pbxproj @@ -27,6 +27,8 @@ 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F22044A3C60003C045 /* Assets.xcassets */; }; 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F42044A3C60003C045 /* MainMenu.xib */; }; 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */; }; + DE662059A3043873D5913CE6 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9E5CC0BE35805CF999512F9F /* Pods_Runner.framework */; }; + E133F2EBD00FFD072B98FDDB /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A24478FD7BC43A261DE1A80C /* Pods_RunnerTests.framework */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -60,11 +62,13 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + 14210005D136C1BAFBE864EC /* Pods-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig"; sourceTree = ""; }; + 18B2FC21174471F9C0659F43 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; 331C80D5294CF71000263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 331C80D7294CF71000263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = ""; }; 333000ED22D3DE5D00554162 /* Warnings.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Warnings.xcconfig; sourceTree = ""; }; 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GeneratedPluginRegistrant.swift; sourceTree = ""; }; - 33CC10ED2044A3C60003C045 /* itrimobe.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "itrimobe.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 33CC10ED2044A3C60003C045 /* itrimobe.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = itrimobe.app; sourceTree = BUILT_PRODUCTS_DIR; }; 33CC10F02044A3C60003C045 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 33CC10F22044A3C60003C045 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = Runner/Assets.xcassets; sourceTree = ""; }; 33CC10F52044A3C60003C045 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = ""; }; @@ -76,8 +80,14 @@ 33E51913231747F40026EE4D /* DebugProfile.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DebugProfile.entitlements; sourceTree = ""; }; 33E51914231749380026EE4D /* Release.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = Release.entitlements; sourceTree = ""; }; 33E5194F232828860026EE4D /* AppInfo.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AppInfo.xcconfig; sourceTree = ""; }; + 563FC2B968AB0F12C9DFF280 /* Pods-RunnerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release.xcconfig"; sourceTree = ""; }; + 68DB5BB89EB253D2BA9F24BE /* Pods-RunnerTests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.profile.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.profile.xcconfig"; sourceTree = ""; }; + 6DD58FF68D2F20F4B6E1A319 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = ""; }; 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = ""; }; + 9E5CC0BE35805CF999512F9F /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + A24478FD7BC43A261DE1A80C /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + C3C31231CF22309AF942A4DA /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -85,6 +95,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + E133F2EBD00FFD072B98FDDB /* Pods_RunnerTests.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -92,6 +103,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + DE662059A3043873D5913CE6 /* Pods_Runner.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -125,6 +137,7 @@ 331C80D6294CF71000263BE5 /* RunnerTests */, 33CC10EE2044A3C60003C045 /* Products */, D73912EC22F37F3D000D13A0 /* Frameworks */, + 3FC6292619E15A3F1F8BC3FA /* Pods */, ); sourceTree = ""; }; @@ -172,9 +185,25 @@ path = Runner; sourceTree = ""; }; + 3FC6292619E15A3F1F8BC3FA /* Pods */ = { + isa = PBXGroup; + children = ( + 6DD58FF68D2F20F4B6E1A319 /* Pods-Runner.debug.xcconfig */, + 18B2FC21174471F9C0659F43 /* Pods-Runner.release.xcconfig */, + C3C31231CF22309AF942A4DA /* Pods-Runner.profile.xcconfig */, + 14210005D136C1BAFBE864EC /* Pods-RunnerTests.debug.xcconfig */, + 563FC2B968AB0F12C9DFF280 /* Pods-RunnerTests.release.xcconfig */, + 68DB5BB89EB253D2BA9F24BE /* Pods-RunnerTests.profile.xcconfig */, + ); + name = Pods; + path = Pods; + sourceTree = ""; + }; D73912EC22F37F3D000D13A0 /* Frameworks */ = { isa = PBXGroup; children = ( + 9E5CC0BE35805CF999512F9F /* Pods_Runner.framework */, + A24478FD7BC43A261DE1A80C /* Pods_RunnerTests.framework */, ); name = Frameworks; sourceTree = ""; @@ -186,6 +215,7 @@ isa = PBXNativeTarget; buildConfigurationList = 331C80DE294CF71000263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */; buildPhases = ( + B4AE9C55067DCB5B2D32CDF9 /* [CP] Check Pods Manifest.lock */, 331C80D1294CF70F00263BE5 /* Sources */, 331C80D2294CF70F00263BE5 /* Frameworks */, 331C80D3294CF70F00263BE5 /* Resources */, @@ -204,11 +234,13 @@ isa = PBXNativeTarget; buildConfigurationList = 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */; buildPhases = ( + D48CC48A091064CAD0F566B8 /* [CP] Check Pods Manifest.lock */, 33CC10E92044A3C60003C045 /* Sources */, 33CC10EA2044A3C60003C045 /* Frameworks */, 33CC10EB2044A3C60003C045 /* Resources */, 33CC110E2044A8840003C045 /* Bundle Framework */, 3399D490228B24CF009A79C7 /* ShellScript */, + 842D90427A1F831501B6294C /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); @@ -329,6 +361,67 @@ shellPath = /bin/sh; shellScript = "\"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh && touch Flutter/ephemeral/tripwire"; }; + 842D90427A1F831501B6294C /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + B4AE9C55067DCB5B2D32CDF9 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-RunnerTests-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + D48CC48A091064CAD0F566B8 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -380,6 +473,7 @@ /* Begin XCBuildConfiguration section */ 331C80DB294CF71000263BE5 /* Debug */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 14210005D136C1BAFBE864EC /* Pods-RunnerTests.debug.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CURRENT_PROJECT_VERSION = 1; @@ -394,6 +488,7 @@ }; 331C80DC294CF71000263BE5 /* Release */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 563FC2B968AB0F12C9DFF280 /* Pods-RunnerTests.release.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CURRENT_PROJECT_VERSION = 1; @@ -408,6 +503,7 @@ }; 331C80DD294CF71000263BE5 /* Profile */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 68DB5BB89EB253D2BA9F24BE /* Pods-RunnerTests.profile.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CURRENT_PROJECT_VERSION = 1; diff --git a/macos/Runner.xcworkspace/contents.xcworkspacedata b/macos/Runner.xcworkspace/contents.xcworkspacedata index 1d526a1..21a3cc1 100644 --- a/macos/Runner.xcworkspace/contents.xcworkspacedata +++ b/macos/Runner.xcworkspace/contents.xcworkspacedata @@ -4,4 +4,7 @@ + + diff --git a/pubspec.lock b/pubspec.lock index 66457ed..38b74ee 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -312,6 +312,54 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.4" + permission_handler: + dependency: "direct main" + description: + name: permission_handler + sha256: "59adad729136f01ea9e35a48f5d1395e25cba6cea552249ddbe9cf950f5d7849" + url: "https://pub.dev" + source: hosted + version: "11.4.0" + permission_handler_android: + dependency: transitive + description: + name: permission_handler_android + sha256: d3971dcdd76182a0c198c096b5db2f0884b0d4196723d21a866fc4cdea057ebc + url: "https://pub.dev" + source: hosted + version: "12.1.0" + permission_handler_apple: + dependency: transitive + description: + name: permission_handler_apple + sha256: f000131e755c54cf4d84a5d8bd6e4149e262cc31c5a8b1d698de1ac85fa41023 + url: "https://pub.dev" + source: hosted + version: "9.4.7" + permission_handler_html: + dependency: transitive + description: + name: permission_handler_html + sha256: "38f000e83355abb3392140f6bc3030660cfaef189e1f87824facb76300b4ff24" + url: "https://pub.dev" + source: hosted + version: "0.1.3+5" + permission_handler_platform_interface: + dependency: transitive + description: + name: permission_handler_platform_interface + sha256: eb99b295153abce5d683cac8c02e22faab63e50679b937fa1bf67d58bb282878 + url: "https://pub.dev" + source: hosted + version: "4.3.0" + permission_handler_windows: + dependency: transitive + description: + name: permission_handler_windows + sha256: "1a790728016f79a41216d88672dbc5df30e686e811ad4e698bfc51f76ad91f1e" + url: "https://pub.dev" + source: hosted + version: "0.2.1" petitparser: dependency: transitive description: diff --git a/windows/flutter/generated_plugin_registrant.cc b/windows/flutter/generated_plugin_registrant.cc index 28581cc..cb63ddc 100644 --- a/windows/flutter/generated_plugin_registrant.cc +++ b/windows/flutter/generated_plugin_registrant.cc @@ -6,11 +6,14 @@ #include "generated_plugin_registrant.h" +#include #include #include #include void RegisterPlugins(flutter::PluginRegistry* registry) { + PermissionHandlerWindowsPluginRegisterWithRegistrar( + registry->GetRegistrarForPlugin("PermissionHandlerWindowsPlugin")); PrintingPluginRegisterWithRegistrar( registry->GetRegistrarForPlugin("PrintingPlugin")); SharePlusWindowsPluginCApiRegisterWithRegistrar( diff --git a/windows/flutter/generated_plugins.cmake b/windows/flutter/generated_plugins.cmake index 98e5d06..0f8c9e2 100644 --- a/windows/flutter/generated_plugins.cmake +++ b/windows/flutter/generated_plugins.cmake @@ -3,6 +3,7 @@ # list(APPEND FLUTTER_PLUGIN_LIST + permission_handler_windows printing share_plus url_launcher_windows