import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:fl_chart/fl_chart.dart'; import 'package:youmazgestion/Components/appDrawer.dart'; import 'package:youmazgestion/Services/stock_managementDatabase.dart'; import 'package:youmazgestion/controller/userController.dart'; import 'package:youmazgestion/Models/users.dart'; import 'package:youmazgestion/Models/client.dart'; import 'package:youmazgestion/Models/produit.dart'; // Ajout de l'import manquant class DashboardPage extends StatefulWidget { @override _DashboardPageState createState() => _DashboardPageState(); } class _DashboardPageState extends State with SingleTickerProviderStateMixin { final AppDatabase _database = AppDatabase.instance; final UserController _userController = Get.find(); final GlobalKey _recentClientsKey = GlobalKey(); final GlobalKey _recentOrdersKey = GlobalKey(); final GlobalKey _lowStockKey = GlobalKey(); final GlobalKey _salesChartKey = GlobalKey(); late Future> _statsFuture; late Future> _recentOrdersFuture; late Future> _lowStockProductsFuture; late Future> _recentClientsFuture; late Future> _allOrdersFuture; late Future> _productsByCategoryFuture; late AnimationController _animationController; late Animation _fadeAnimation; @override void initState() { super.initState(); _loadData(); _animationController = AnimationController( vsync: this, duration: Duration(milliseconds: 800), ); _fadeAnimation = Tween(begin: 0, end: 1).animate( CurvedAnimation( parent: _animationController, curve: Curves.easeInOut, ), ); _animationController.forward(); } @override void dispose() { _animationController.dispose(); super.dispose(); } void _loadData() { _statsFuture = _database.getStatistiques(); _recentOrdersFuture = _database.getCommandes().then((orders) => orders.take(5).toList()); _lowStockProductsFuture = _database.getProducts().then((products) { return products.where((p) => (p.stock ?? 0) < 10).toList(); }); _recentClientsFuture = _database.getClients().then((clients) => clients.take(5).toList()); _allOrdersFuture = _database.getCommandes(); _productsByCategoryFuture = _database.getProductCountByCategory(); } Future _showCategoryProductsDialog(String category) async { final products = await _database.getProductsByCategory(category); showDialog( context: context, builder: (context) => AlertDialog( title: Text('Produits dans $category'), content: Container( width: double.maxFinite, child: ListView.builder( shrinkWrap: true, itemCount: products.length, itemBuilder: (context, index) { final product = products[index]; return ListTile( leading: product.image != null && product.image!.isNotEmpty ? CircleAvatar(backgroundImage: NetworkImage(product.image!)) : CircleAvatar(child: Icon(Icons.inventory)), title: Text(product.name), subtitle: Text('Stock: ${product.stock}'), trailing: Text('${product.price.toStringAsFixed(2)} MGA'), ); }, ), ), actions: [ TextButton( onPressed: () => Navigator.pop(context), child: Text('Fermer'), ), ], ), ); } List> _groupOrdersByMonth(List orders) { final Map monthlySales = {}; for (final order in orders) { final monthYear = '${order.dateCommande.year}-${order.dateCommande.month.toString().padLeft(2, '0')}'; monthlySales.update( monthYear, (value) => value + order.montantTotal, ifAbsent: () => order.montantTotal, ); } return monthlySales.entries.map((entry) { return { 'month': entry.key, 'total': entry.value, }; }).toList(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Image.asset( 'assets/youmaz2.png', height: 40, // Ajustez la hauteur selon vos besoins ), centerTitle: true, elevation: 0, flexibleSpace: Container( decoration: BoxDecoration( gradient: LinearGradient( colors: [const Color.fromARGB(255, 15, 83, 160), const Color.fromARGB(255, 79, 165, 239)], begin: Alignment.topLeft, end: Alignment.bottomRight, ), ), ), actions: [ IconButton( icon: Icon(Icons.refresh, color: Colors.white), onPressed: () { _animationController.reset(); _loadData(); _animationController.forward(); }, ), ], ), drawer: CustomDrawer(), body: SingleChildScrollView( padding: EdgeInsets.all(16), child: FadeTransition( opacity: _fadeAnimation, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ _buildUserInfo(), SizedBox(height: 20), _buildMiniStatistics(), SizedBox(height: 20), // Graphiques en ligne Row( children: [ Expanded( child: _buildSalesChart(), ), SizedBox(width: 16), Expanded( child: _buildStockChart(), ), ], ), SizedBox(height: 20), // Histogramme des catégories de produits _buildCategoryHistogram(), SizedBox(height: 20), // Section des données récentes _buildRecentDataSection(), ], ), ), ), ); } Widget _buildCategoryHistogram() { return Card( elevation: 4, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12), ), child: Padding( padding: EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Icon(Icons.category, color: Colors.blue), SizedBox(width: 8), Text( 'Produits par Catégorie', style: TextStyle( fontSize: 16, fontWeight: FontWeight.bold, ), ), ], ), SizedBox(height: 16), Container( height: 200, child: FutureBuilder>( future: _productsByCategoryFuture, builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.waiting) { return Center(child: CircularProgressIndicator()); } if (snapshot.hasError || !snapshot.hasData || snapshot.data!.isEmpty) { return Center(child: Text('Aucune donnée disponible')); } final data = snapshot.data!; final categories = data.keys.toList(); final counts = data.values.toList(); return BarChart( BarChartData( alignment: BarChartAlignment.spaceAround, maxY: counts.reduce((a, b) => a > b ? a : b).toDouble() * 1.2, barTouchData: BarTouchData( enabled: true, touchCallback: (FlTouchEvent event, response) { if (response != null && response.spot != null && event is FlTapUpEvent) { final category = categories[response.spot!.touchedBarGroupIndex]; _showCategoryProductsDialog(category); } }, touchTooltipData: BarTouchTooltipData( tooltipBgColor: Colors.blueGrey, getTooltipItem: (group, groupIndex, rod, rodIndex) { final category = categories[groupIndex]; final count = counts[groupIndex]; return BarTooltipItem( '$category\n$count produits', TextStyle(color: Colors.white), ); }, ), ), titlesData: FlTitlesData( show: true, bottomTitles: AxisTitles( sideTitles: SideTitles( showTitles: true, getTitlesWidget: (value, meta) { final index = value.toInt(); if (index >= 0 && index < categories.length) { return Padding( padding: const EdgeInsets.only(top: 8.0), child: Text( categories[index].substring(0, 3).toUpperCase(), style: TextStyle( fontSize: 10, color: Colors.grey, ), ), ); } return Text(''); }, reservedSize: 40, ), ), leftTitles: AxisTitles( sideTitles: SideTitles( showTitles: true, getTitlesWidget: (value, meta) { return Text( value.toInt().toString(), style: TextStyle( fontSize: 10, color: Colors.grey, ), ); }, reservedSize: 40, ), ), topTitles: AxisTitles( sideTitles: SideTitles(showTitles: false), ), rightTitles: AxisTitles( sideTitles: SideTitles(showTitles: false), ), ), borderData: FlBorderData( show: true, border: Border.all( color: Colors.grey.withOpacity(0.3), width: 1, ), ), barGroups: categories.asMap().entries.map((entry) { final index = entry.key; return BarChartGroupData( x: index, barRods: [ BarChartRodData( toY: counts[index].toDouble(), color: _getCategoryColor(index), width: 16, borderRadius: BorderRadius.circular(4), backDrawRodData: BackgroundBarChartRodData( show: true, toY: counts.reduce((a, b) => a > b ? a : b).toDouble() * 1.2, color: Colors.grey.withOpacity(0.1), ), ), ], showingTooltipIndicators: [0], ); }).toList(), ), ); }, ), ), ], ), ), ); } Color _getCategoryColor(int index) { final colors = [ Colors.blue, Colors.green, Colors.orange, Colors.purple, Colors.teal, Colors.pink, Colors.indigo, ]; return colors[index % colors.length]; } Widget _buildSalesChart() { key: _salesChartKey; return Card( elevation: 4, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12), ), child: Padding( padding: EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Icon(Icons.trending_up, color: Colors.blue), SizedBox(width: 8), Text( 'Ventes par mois', style: TextStyle( fontSize: 16, fontWeight: FontWeight.bold, ), ), ], ), SizedBox(height: 16), Container( height: 200, child: FutureBuilder>( future: _allOrdersFuture, builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.waiting) { return Center(child: CircularProgressIndicator()); } if (snapshot.hasError || !snapshot.hasData || snapshot.data!.isEmpty) { return Center(child: Text('Aucune donnée disponible')); } final salesData = _groupOrdersByMonth(snapshot.data!); return BarChart( BarChartData( alignment: BarChartAlignment.spaceAround, maxY: salesData.map((e) => e['total']).reduce((a, b) => a > b ? a : b) * 1.2, barTouchData: BarTouchData( enabled: true, touchTooltipData: BarTouchTooltipData( tooltipBgColor: Colors.blueGrey, getTooltipItem: (group, groupIndex, rod, rodIndex) { final month = salesData[groupIndex]['month']; final total = salesData[groupIndex]['total']; return BarTooltipItem( '$month\n${total.toStringAsFixed(2)} MGA', TextStyle(color: Colors.white), ); }, ), ), titlesData: FlTitlesData( show: true, bottomTitles: AxisTitles( sideTitles: SideTitles( showTitles: true, getTitlesWidget: (value, meta) { final index = value.toInt(); if (index >= 0 && index < salesData.length) { return Padding( padding: const EdgeInsets.only(top: 8.0), child: Text( salesData[index]['month'].toString().split('-')[1], style: TextStyle( fontSize: 10, color: Colors.grey, ), ), ); } return Text(''); }, reservedSize: 40, ), ), leftTitles: AxisTitles( sideTitles: SideTitles( showTitles: true, getTitlesWidget: (value, meta) { return Text( value.toInt().toString(), style: TextStyle( fontSize: 10, color: Colors.grey, ), ); }, reservedSize: 40, ), ), topTitles: AxisTitles( sideTitles: SideTitles(showTitles: false), ), rightTitles: AxisTitles( sideTitles: SideTitles(showTitles: false), ), ), borderData: FlBorderData( show: true, border: Border.all( color: Colors.grey.withOpacity(0.3), width: 1, ), ), barGroups: salesData.asMap().entries.map((entry) { final index = entry.key; final data = entry.value; return BarChartGroupData( x: index, barRods: [ BarChartRodData( toY: data['total'], color: Colors.blue, width: 16, borderRadius: BorderRadius.circular(4), backDrawRodData: BackgroundBarChartRodData( show: true, toY: salesData.map((e) => e['total']).reduce((a, b) => a > b ? a : b) * 1.2, color: Colors.grey.withOpacity(0.1), ), ), ], showingTooltipIndicators: [0], ); }).toList(), ), ); }, ), ), ], ), ), ); } Widget _buildStockChart() { return Card( elevation: 4, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12), ), child: Padding( padding: EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Icon(Icons.inventory, color: Colors.blue), SizedBox(width: 8), Text( 'État du stock', style: TextStyle( fontSize: 16, fontWeight: FontWeight.bold, ), ), ], ), SizedBox(height: 16), Container( height: 200, child: FutureBuilder>( future: _database.getProducts(), builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.waiting) { return Center(child: CircularProgressIndicator()); } if (snapshot.hasError || !snapshot.hasData) { return Center(child: Text('Aucune donnée disponible')); } final products = snapshot.data!; final lowStock = products.where((p) => (p.stock ?? 0) < 10).length; final inStock = products.length - lowStock; return PieChart( PieChartData( sectionsSpace: 0, centerSpaceRadius: 40, sections: [ PieChartSectionData( color: Colors.orange, value: lowStock.toDouble(), title: '$lowStock', radius: 20, titleStyle: TextStyle( fontSize: 12, fontWeight: FontWeight.bold, color: Colors.white, ), ), PieChartSectionData( color: Colors.green, value: inStock.toDouble(), title: '$inStock', radius: 20, titleStyle: TextStyle( fontSize: 12, fontWeight: FontWeight.bold, color: Colors.white, ), ), ], pieTouchData: PieTouchData( touchCallback: (FlTouchEvent event, pieTouchResponse) {}, ), startDegreeOffset: 180, borderData: FlBorderData(show: false), ), ); }, ), ), SizedBox(height: 8), Row( mainAxisAlignment: MainAxisAlignment.center, children: [ _buildLegendItem(Colors.orange, 'Stock faible'), SizedBox(width: 16), _buildLegendItem(Colors.green, 'En stock'), ], ), ], ), ), ); } Widget _buildLegendItem(Color color, String text) { return Row( mainAxisSize: MainAxisSize.min, children: [ Container( width: 12, height: 12, decoration: BoxDecoration( shape: BoxShape.circle, color: color, ), ), SizedBox(width: 4), Text( text, style: TextStyle( fontSize: 12, color: Colors.grey, ), ), ], ); } Widget _buildUserInfo() { return FutureBuilder( future: _database.getUserById(_userController.userId), builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.waiting) { return Center(child: CircularProgressIndicator()); } if (snapshot.hasError || !snapshot.hasData) { return Text('Bienvenue'); } final user = snapshot.data!; return Row( children: [ CircleAvatar( radius: 30, backgroundColor: Colors.blue.shade100, child: Icon(Icons.person, size: 30, color: Colors.blue), ), SizedBox(width: 16), Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'Bienvenue, ${user.name}', style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold), ), SizedBox(height: 4), Text( 'Rôle: ${user.roleName ?? 'Utilisateur'}', style: TextStyle(fontSize: 14, color: Colors.grey.shade600), ), ], ), ], ); }, ); } Widget _buildMiniStatistics() { return FutureBuilder>( future: _statsFuture, builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.waiting) { return Center(child: CircularProgressIndicator()); } if (snapshot.hasError) { return Text('Erreur de chargement des statistiques'); } final stats = snapshot.data ?? {}; return Wrap( spacing: 12, runSpacing: 12, children: [ _buildMiniStatCard( title: 'Clients', value: '${stats['totalClients'] ?? 0}', icon: Icons.people, color: Colors.blue, ), _buildMiniStatCard( title: 'Commandes', value: '${stats['totalCommandes'] ?? 0}', icon: Icons.shopping_cart, color: Colors.green, ), _buildMiniStatCard( title: 'Produits', value: '${stats['totalProduits'] ?? 0}', icon: Icons.inventory, color: Colors.orange, ), _buildMiniStatCard( title: 'CA (MGA)', value: '${(stats['chiffreAffaires'] ?? 0.0).toStringAsFixed(2)}', icon: Icons.euro_symbol, color: Colors.purple, ), ], ); }, ); } Widget _buildMiniStatCard({required String title, required String value, required IconData icon, required Color color}) { return InkWell( onTap: () { // Animation au clic _animationController.reset(); _animationController.forward(); // Navigation based on the card type switch(title) { case 'Clients': // Scroll to recent clients section Scrollable.ensureVisible( _recentClientsKey.currentContext!, duration: Duration(milliseconds: 500), curve: Curves.easeInOut, ); break; case 'Commandes': // Scroll to recent orders section Scrollable.ensureVisible( _recentOrdersKey.currentContext!, duration: Duration(milliseconds: 500), curve: Curves.easeInOut, ); break; case 'Produits': // Scroll to low stock products section Scrollable.ensureVisible( _lowStockKey.currentContext!, duration: Duration(milliseconds: 500), curve: Curves.easeInOut, ); break; case 'CA (MGA)': // Scroll to sales chart Scrollable.ensureVisible( _salesChartKey.currentContext!, duration: Duration(milliseconds: 500), curve: Curves.easeInOut, ); break; } }, borderRadius: BorderRadius.circular(12), child: Container( decoration: BoxDecoration( color: color.withOpacity(0.1), borderRadius: BorderRadius.circular(12), border: Border.all(color: color.withOpacity(0.3)), ), child: Padding( padding: EdgeInsets.all(12), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon(icon, size: 32, color: color), SizedBox(height: 8), Text( value, style: TextStyle( fontSize: 24, fontWeight: FontWeight.bold, color: color, ), ), SizedBox(height: 4), Text( title, style: TextStyle( fontSize: 14, color: Colors.grey.shade600, ), ), ], ), ), ), ); } Widget _buildRecentDataSection() { return Column( children: [ Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ Expanded(child: _buildRecentOrdersCard()), SizedBox(width: 16), Expanded(child: _buildRecentClientsCard()), ], ), SizedBox(height: 16), _buildLowStockCard(), ], ); } Widget _buildRecentOrdersCard() { key: _recentOrdersKey; return Card( elevation: 4, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12), ), child: Padding( padding: EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Icon(Icons.shopping_cart, color: Colors.green), SizedBox(width: 8), Text( 'Commandes récentes', style: TextStyle( fontSize: 16, fontWeight: FontWeight.bold, ), ), ], ), SizedBox(height: 8), FutureBuilder>( future: _recentOrdersFuture, builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.waiting) { return Center(child: CircularProgressIndicator()); } if (snapshot.hasError || !snapshot.hasData || snapshot.data!.isEmpty) { return Padding( padding: EdgeInsets.all(8), child: Text('Aucune commande récente'), ); } final orders = snapshot.data!; return Column( children: orders.map((order) => FutureBuilder>( future: _database.getDetailsCommande(order.id!), builder: (context, detailsSnapshot) { if (detailsSnapshot.connectionState == ConnectionState.waiting) { return Center(child: CircularProgressIndicator()); } if (detailsSnapshot.hasError || !detailsSnapshot.hasData || detailsSnapshot.data!.isEmpty) { return Padding( padding: EdgeInsets.all(8), child: Text('Aucun détail de commande disponible'), ); } final details = detailsSnapshot.data!; return InkWell( onTap: () { _animationController.reset(); _animationController.forward(); }, borderRadius: BorderRadius.circular(8), child: Container( margin: EdgeInsets.only(bottom: 8), padding: EdgeInsets.all(8), decoration: BoxDecoration( color: Colors.grey.shade50, borderRadius: BorderRadius.circular(8), ), child: Column( children: [ ListTile( contentPadding: EdgeInsets.zero, leading: CircleAvatar( backgroundColor: _getStatusColor(order.statut).withOpacity(0.2), child: Icon(Icons.receipt, color: _getStatusColor(order.statut)), ), title: Text( '${order.clientNomComplet}', style: TextStyle(fontSize: 14), ), subtitle: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( '${order.montantTotal.toStringAsFixed(2)} MGA', style: TextStyle(fontSize: 12), ), Text( '${order.dateCommande.toString().substring(0, 10)}', style: TextStyle(fontSize: 10, color: Colors.grey), ), ], ), trailing: Container( padding: EdgeInsets.symmetric(horizontal: 8, vertical: 4), decoration: BoxDecoration( color: _getStatusColor(order.statut).withOpacity(0.2), borderRadius: BorderRadius.circular(12), ), child: Text( order.statutLibelle, style: TextStyle( fontSize: 10, color: _getStatusColor(order.statut), ), ), ), ), // Affichage des produits commandés Column( crossAxisAlignment: CrossAxisAlignment.start, children: details.map((detail) => Padding( padding: EdgeInsets.only(left: 16, top: 4), child: Text( 'Produit: ${detail.produitNom}', style: TextStyle(fontSize: 12), ), )).toList(), ), ], ), ), ); }, )).toList(), ); }, ), ], ), ), ); } Widget _buildRecentClientsCard() { key: _recentClientsKey; return Card( elevation: 4, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12), ), child: Padding( padding: EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Icon(Icons.people, color: Colors.blue), SizedBox(width: 8), Text( 'Clients récents', style: TextStyle( fontSize: 16, fontWeight: FontWeight.bold, ), ), ], ), SizedBox(height: 8), FutureBuilder>( future: _recentClientsFuture, builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.waiting) { return Center(child: CircularProgressIndicator()); } if (snapshot.hasError || !snapshot.hasData || snapshot.data!.isEmpty) { return Padding( padding: EdgeInsets.all(8), child: Text('Aucun client récent'), ); } final clients = snapshot.data!; return Column( children: clients.map((client) => InkWell( onTap: () { // Animation et action au clic _animationController.reset(); _animationController.forward(); // Vous pouvez ajouter une navigation vers le client ici }, borderRadius: BorderRadius.circular(8), child: Container( margin: EdgeInsets.only(bottom: 8), padding: EdgeInsets.all(8), decoration: BoxDecoration( color: Colors.grey.shade50, borderRadius: BorderRadius.circular(8), ), child: ListTile( contentPadding: EdgeInsets.zero, leading: CircleAvatar( backgroundColor: Colors.blue.shade100, child: Icon(Icons.person, color: Colors.blue), ), title: Text( client.nomComplet.split(' ').first, style: TextStyle(fontSize: 14), ), subtitle: Text( client.email, style: TextStyle(fontSize: 12), overflow: TextOverflow.ellipsis, ), ), ), )).toList(), ); }, ), ], ), ), ); } Widget _buildLowStockCard() { key: _lowStockKey; return Card( elevation: 4, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12), ), child: Padding( padding: EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Icon(Icons.warning, color: Colors.orange), SizedBox(width: 8), Text( 'Produits en rupture', style: TextStyle( fontSize: 16, fontWeight: FontWeight.bold, ), ), ], ), SizedBox(height: 8), FutureBuilder>( future: _lowStockProductsFuture, builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.waiting) { return Center(child: CircularProgressIndicator()); } if (snapshot.hasError || !snapshot.hasData || snapshot.data!.isEmpty) { return Padding( padding: EdgeInsets.all(8), child: Text('Aucun produit en rupture de stock'), ); } final products = snapshot.data!; return Column( children: products.map((product) => InkWell( onTap: () { // Animation et action au clic _animationController.reset(); _animationController.forward(); // Vous pouvez ajouter une navigation vers le produit ici }, borderRadius: BorderRadius.circular(8), child: Container( margin: EdgeInsets.only(bottom: 8), padding: EdgeInsets.all(8), decoration: BoxDecoration( color: Colors.orange.shade50, borderRadius: BorderRadius.circular(8), ), child: ListTile( contentPadding: EdgeInsets.zero, leading: product.image != null && product.image!.isNotEmpty ? CircleAvatar( backgroundImage: NetworkImage(product.image!), radius: 20, ) : CircleAvatar( backgroundColor: Colors.orange.shade100, child: Icon(Icons.inventory, color: Colors.orange), ), title: Text( product.name, style: TextStyle(fontSize: 14), ), subtitle: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'Stock: ${product.stock ?? 0}', style: TextStyle(fontSize: 12), ), Text( 'Catégorie: ${product.category}', style: TextStyle(fontSize: 10, color: Colors.grey), ), ], ), trailing: Text( '${product.price.toStringAsFixed(2)} MGA', style: TextStyle(fontSize: 12), ), ), ), )).toList(), ); }, ), ], ), ), ); } Color _getStatusColor(StatutCommande status) { switch (status) { case StatutCommande.enAttente: return Colors.orange; case StatutCommande.confirmee: return Colors.blue; case StatutCommande.enPreparation: return Colors.purple; case StatutCommande.expediee: return Colors.teal; case StatutCommande.livree: return Colors.green; case StatutCommande.annulee: return Colors.red; default: return Colors.grey; } } }