import 'dart:io'; import 'package:intl/intl.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:youmazgestion/Services/stock_managementDatabase.dart'; import 'package:youmazgestion/Views/particles.dart' show ParticleBackground; import 'package:youmazgestion/Views/produitsCard.dart'; import 'Components/appDrawer.dart'; import 'Components/app_bar.dart'; import 'Components/cartItem.dart'; import 'Models/produit.dart'; import 'Services/OrderDatabase.dart'; //import 'Services/productDatabase.dart'; import 'Views/ticketPage.dart'; import 'controller/userController.dart'; import 'my_app.dart'; import 'Services/workDatabase.dart'; class AccueilPage extends StatefulWidget { const AccueilPage({super.key}); @override _AccueilPageState createState() => _AccueilPageState(); } class _AccueilPageState extends State { final UserController userController = Get.put(UserController()); final AppDatabase productDatabase = AppDatabase.instance; late Future>> productsFuture; final OrderDatabase orderDatabase = OrderDatabase.instance; final WorkDatabase workDatabase = WorkDatabase.instance; String? username; String? role; DateTime? startDate; int orderId = 0; List selectedProducts = []; int selectedQuantity = 1; double totalCartPrice = 0; double amountPaid = 0; final TextEditingController _amountController = TextEditingController(); @override void initState() { super.initState(); _initializeDatabases(); loadUserData(); productsFuture = _initDatabaseAndFetchProducts(); } Future _initializeDatabases() async { await orderDatabase.initDatabase(); await workDatabase.initDatabase(); await _initializeRegister(); } Future _initializeRegister() async { if (!MyApp.isRegisterOpen) { setState(() { MyApp.isRegisterOpen = true; String formattedDate = DateFormat('yyyy-MM-dd').format(DateTime.now()); startDate = DateFormat('yyyy-MM-dd').parse(formattedDate); MyApp.startDate = startDate; workDatabase.insertDate(formattedDate); }); } } Future loadUserData() async { final prefs = await SharedPreferences.getInstance(); setState(() { username = prefs.getString('username') ?? 'Nom inconnu'; role = prefs.getString('role') ?? 'Rôle inconnu'; }); } Future saveOrderToDatabase() async { final totalPrice = calculateTotalPrice(); final dateTime = DateTime.now().toString(); String user = userController.username; if (selectedProducts.isEmpty) { Get.snackbar( 'Panier vide', 'Ajoutez des produits avant de passer commande.', snackPosition: SnackPosition.BOTTOM, duration: const Duration(seconds: 3), backgroundColor: Colors.red, colorText: Colors.white, ); return; } if (amountPaid < totalPrice) { Get.snackbar( 'Paiement incomplet', 'Le montant payé est insuffisant.', snackPosition: SnackPosition.BOTTOM, duration: const Duration(seconds: 3), backgroundColor: Colors.red, colorText: Colors.white, ); return; } orderId = await orderDatabase.insertOrder( totalPrice, dateTime, MyApp.startDate!, user); for (final cartItem in selectedProducts) { final product = cartItem.product; final quantity = cartItem.quantity; final price = product.price * quantity; await orderDatabase.insertOrderItem( orderId, product.name, quantity, price); final updatedStock = product.stock! - quantity; await productDatabase.updateStock(product.id!, updatedStock); } // Afficher le ticket et réinitialiser le panier showTicketPage(); setState(() { selectedProducts.clear(); _amountController.clear(); amountPaid = 0; }); } Future>> _initDatabaseAndFetchProducts() async { await productDatabase.initDatabase(); final categories = await productDatabase.getCategories(); final productsByCategory = >{}; categories.sort(); for (final categoryName in categories) { final products = await productDatabase.getProductsByCategory(categoryName); productsByCategory[categoryName] = products; } return productsByCategory; } double calculateTotalPrice() { double totalPrice = 0; for (final cartItem in selectedProducts) { totalPrice += cartItem.product.price * cartItem.quantity; } return totalPrice; } void addToCartWithDetails(Product product, int quantity) { setState(() { final existingCartItem = selectedProducts.firstWhere( (cartItem) => cartItem.product.id == product.id, orElse: () => CartItem(product, 0), ); if (existingCartItem.quantity == 0) { selectedProducts.add(CartItem(product, quantity)); } else { existingCartItem.quantity += quantity; } }); Get.snackbar( 'Produit ajouté', '${product.name} (x$quantity) ajouté au panier', snackPosition: SnackPosition.TOP, duration: const Duration(seconds: 1), backgroundColor: Colors.green, colorText: Colors.white, ); } void showTicketPage() { Get.offAll(TicketPage( businessName: 'Youmaz', businessAddress: 'quartier escale, Diourbel, Sénégal, en face de Sonatel', businessPhoneNumber: '77 446 92 68', cartItems: selectedProducts, totalCartPrice: calculateTotalPrice(), amountPaid: amountPaid, )); } @override Widget build(BuildContext context) { return Scaffold( appBar: CustomAppBar( title: "Accueil", subtitle: Text('Bienvenue $username ! (Rôle: $role)', style: const TextStyle(color: Colors.white70, fontSize: 14)), ), drawer: CustomDrawer(), body: ParticleBackground( child: Container( decoration: const BoxDecoration( gradient: LinearGradient( begin: Alignment.topLeft, end: Alignment.bottomRight, colors: [Colors.white, Color.fromARGB(255, 4, 54, 95)]), ), child: FutureBuilder>>( future: productsFuture, builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.waiting) { return const Center( child: CircularProgressIndicator( valueColor: AlwaysStoppedAnimation( Color.fromARGB(255, 4, 54, 95), ), )); } else if (snapshot.hasError) { return const Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon(Icons.error, color: Colors.red, size: 48), SizedBox(height: 16), Text("Erreur de chargement des produits", style: TextStyle(fontSize: 16, color: Colors.white)), ], )); } else if (snapshot.hasData) { final productsByCategory = snapshot.data!; final categories = productsByCategory.keys.toList(); return Row( children: [ // Section produits Expanded( flex: 3, child: Container( padding: const EdgeInsets.all(8), decoration: BoxDecoration( color: Colors.white.withOpacity(0.9), borderRadius: const BorderRadius.only( topRight: Radius.circular(20), ), ), child: ListView.builder( itemCount: categories.length, itemBuilder: (context, index) { final category = categories[index]; final products = productsByCategory[category]!; return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( margin: const EdgeInsets.symmetric(vertical: 8), padding: const EdgeInsets.all(12), decoration: BoxDecoration( color: Color.fromARGB(255, 4, 54, 95), borderRadius: BorderRadius.circular(12), boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.1), blurRadius: 4, offset: Offset(0, 2), ) ], ), child: Center( child: Text( category, style: const TextStyle( fontSize: 22, fontWeight: FontWeight.bold, color: Colors.white, ), ), ), ), GridView.builder( gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 4, childAspectRatio: 0.9, crossAxisSpacing: 8, mainAxisSpacing: 8, ), shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), itemCount: products.length, itemBuilder: (context, index) { final product = products[index]; return ProductCard( product: product, onAddToCart: (product, quantity) { addToCartWithDetails(product, quantity); }, ); }, ), ], ); }, ), ), // Section panier ), Expanded( flex: 1, child: Container( decoration: BoxDecoration( color: Colors.grey[200], borderRadius: const BorderRadius.only( topLeft: Radius.circular(20), ), boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.2), blurRadius: 10, spreadRadius: 2, ), ], ), padding: EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ Container( padding: EdgeInsets.all(12), decoration: BoxDecoration( color: Color.fromARGB(255, 4, 54, 95), borderRadius: BorderRadius.circular(12), ), child: const Text( 'Panier', style: TextStyle( fontSize: 20, fontWeight: FontWeight.bold, color: Colors.white, ), textAlign: TextAlign.center, ), ), SizedBox(height: 16), // Liste des produits dans le panier Expanded( child: selectedProducts.isEmpty ? const Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon(Icons.shopping_cart, size: 48, color: Colors.grey), SizedBox(height: 16), Text( "Votre panier est vide", style: TextStyle( fontSize: 16, color: Colors.grey), ), ], ), ) : ListView.builder( itemCount: selectedProducts.length, itemBuilder: (context, index) { final cartItem = selectedProducts[index]; return Card( margin: EdgeInsets.symmetric(vertical: 4), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(10), ), elevation: 2, child: ListTile( contentPadding: EdgeInsets.symmetric( horizontal: 12, vertical: 4), leading: Icon( Icons.shopping_basket, color: Color.fromARGB( 255, 4, 54, 95), ), title: Text( cartItem.product.name, style: const TextStyle( fontWeight: FontWeight.bold), ), subtitle: Text( '${NumberFormat('#,##0').format(cartItem.product.price)} MGA x ${cartItem.quantity}', style: const TextStyle(fontSize: 14), ), trailing: Row( mainAxisSize: MainAxisSize.min, children: [ Text( '${NumberFormat('#,##0').format(cartItem.product.price * cartItem.quantity)}', style: const TextStyle( fontWeight: FontWeight.bold), ), const SizedBox(width: 8), IconButton( icon: const Icon(Icons.delete, color: Colors.red), onPressed: () { setState(() { selectedProducts .removeAt(index); }); }, ), ], ), ), ); }, ), ), // Total et paiement Container( padding: EdgeInsets.all(12), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(12), boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.1), blurRadius: 4, offset: Offset(0, 2), ) ], ), child: Column( children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ const Text('Total:', style: TextStyle( fontSize: 16, fontWeight: FontWeight.bold)), Text( '${NumberFormat('#,##0.00').format(calculateTotalPrice())} MGA', style: TextStyle( fontSize: 18, fontWeight: FontWeight.bold, color: Color.fromARGB(255, 4, 54, 95), ), ), ], ), const SizedBox(height: 12), TextField( controller: _amountController, keyboardType: TextInputType.number, decoration: InputDecoration( labelText: 'Montant payé', prefixIcon: Icon(Icons.attach_money), border: OutlineInputBorder( borderRadius: BorderRadius.circular(10), ), filled: true, fillColor: Colors.grey[100], ), onChanged: (value) { setState(() { amountPaid = double.tryParse(value) ?? 0; }); }, ), SizedBox(height: 16), ElevatedButton.icon( style: ElevatedButton.styleFrom( backgroundColor: Colors.green, padding: EdgeInsets.symmetric(vertical: 16), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(10), ), ), onPressed: saveOrderToDatabase, icon: const Icon(Icons.check_circle), label: const Text( 'Valider la commande', style: TextStyle( fontSize: 16, fontWeight: FontWeight.bold, color: Colors.white), ), ), ], ), ), ], ), ), ) ], ); } else { return const Center( child: Text("Aucun produit disponible", style: TextStyle(color: Colors.white)), ); } }, ), ), ), ); } @override void dispose() { _amountController.dispose(); super.dispose(); } }