import 'package:flutter/material.dart'; import 'package:http/http.dart' as http; import 'dart:convert'; class TableData { final int id; final String nom; final int capacity; final String status; TableData({ required this.id, required this.nom, required this.capacity, required this.status, }); factory TableData.fromJson(Map json) { return TableData( id: json['id'], nom: json['nom'], capacity: json['capacity'], status: json['status'], ); } } class TablesScreen extends StatefulWidget { @override _TablesScreenState createState() => _TablesScreenState(); } class _TablesScreenState extends State { List tables = []; bool isLoading = true; @override void initState() { super.initState(); fetchTables(); } Future fetchTables() async { final url = Uri.parse("https://restaurant.careeracademy.mg/api/tables"); final response = await http.get(url); if (response.statusCode == 200) { final List data = json.decode(response.body)['data']; setState(() { tables = data.map((json) => TableData.fromJson(json)).toList(); isLoading = false; }); } else { setState(() => isLoading = false); print('Erreur API: ${response.statusCode}'); } } Color getStatusColor(String status) { switch (status) { case 'available': return Colors.green; case 'occupied': return Colors.orange; case 'reserved': return Colors.orange; default: return Colors.grey; } } String getStatusLabel(String status) { switch (status) { case 'available': return 'Disponible'; case 'occupied': return 'Occupée'; case 'reserved': return 'Réservée'; default: return 'Indisponible'; } } bool isTableSelectable(String status) { return status == 'available'; } @override Widget build(BuildContext context) { final screenWidth = MediaQuery.of(context).size.width; int crossAxisCount = 2; if (screenWidth > 1200) { crossAxisCount = 4; } else if (screenWidth > 800) { crossAxisCount = 3; } return Scaffold( backgroundColor: Colors.grey.shade50, body: Column( children: [ // Header Container( width: double.infinity, color: Colors.white, padding: const EdgeInsets.symmetric(vertical: 24, horizontal: 20), child: Column( children: [ const Text( 'Sélectionner une table', style: TextStyle( fontSize: 24, fontWeight: FontWeight.bold, color: Colors.black87, ), ), const SizedBox(height: 8), Text( 'Choisissez une table pour commencer une nouvelle commande', style: TextStyle(fontSize: 14, color: Colors.grey.shade600), ), ], ), ), // Tables Grid Expanded( child: isLoading ? const Center(child: CircularProgressIndicator()) : Padding( padding: const EdgeInsets.all(20.0), child: Column( children: [ Expanded( child: GridView.builder( itemCount: tables.length, gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: crossAxisCount, crossAxisSpacing: 16, mainAxisSpacing: 16, childAspectRatio: 1.3, ), itemBuilder: (context, index) { final table = tables[index]; final isSelectable = isTableSelectable( table.status, ); return Container( decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(12), border: Border.all( color: Colors.grey.shade200, ), boxShadow: [ BoxShadow( color: Colors.grey.shade100, blurRadius: 4, offset: const Offset(0, 2), ), ], ), child: Padding( padding: const EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // Table name and status badge Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( table.nom, style: const TextStyle( fontWeight: FontWeight.bold, fontSize: 16, color: Colors.black87, ), ), Container( padding: const EdgeInsets.symmetric( horizontal: 12, vertical: 4, ), decoration: BoxDecoration( color: getStatusColor( table.status, ), borderRadius: BorderRadius.circular(20), ), child: Text( getStatusLabel(table.status), style: const TextStyle( color: Colors.white, fontSize: 9, fontWeight: FontWeight.w500, ), ), ), ], ), const SizedBox(height: 12), // Capacity Row( children: [ Icon( Icons.people_outline, size: 16, color: Colors.grey.shade600, ), const SizedBox(width: 6), Text( 'Capacité: ${table.capacity} personnes', style: TextStyle( fontSize: 13, color: Colors.grey.shade600, ), ), ], ), const Spacer(), // Button SizedBox( width: double.infinity, height: 36, child: ElevatedButton( onPressed: isSelectable ? () {} : null, style: ElevatedButton.styleFrom( backgroundColor: isSelectable ? Colors.green.shade700 : Colors.grey.shade300, foregroundColor: Colors.white, elevation: 0, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8), ), ), child: Text( isSelectable ? "Sélectionner" : "Indisponible", style: TextStyle( fontSize: 10, fontWeight: FontWeight.w500, color: isSelectable ? Colors.white : Colors.grey.shade600, ), ), ), ), ], ), ), ); }, ), ), // Legend const SizedBox(height: 20), Row( mainAxisAlignment: MainAxisAlignment.center, children: [ _buildLegendItem('Disponible', Colors.green), const SizedBox(width: 24), _buildLegendItem( 'Occupée', Colors.green.shade800, ), const SizedBox(width: 24), _buildLegendItem('Réservée', Colors.orange), ], ), ], ), ), ), // Bottom Navigation Container( color: Colors.white, padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 12), child: Row( children: [ Container( padding: const EdgeInsets.symmetric( horizontal: 16, vertical: 8, ), decoration: BoxDecoration( color: Colors.green.shade700, borderRadius: BorderRadius.circular(20), ), child: const Row( mainAxisSize: MainAxisSize.min, children: [ Icon( Icons.table_restaurant, color: Colors.white, size: 16, ), SizedBox(width: 6), Text( 'Tables', style: TextStyle( color: Colors.white, fontWeight: FontWeight.w500, ), ), ], ), ), const SizedBox(width: 20), Row( children: [ Icon( Icons.receipt_long_outlined, color: Colors.grey.shade600, size: 16, ), const SizedBox(width: 6), Text( 'Commandes', style: TextStyle(color: Colors.grey.shade600), ), ], ), const Spacer(), Row( children: [ Icon( Icons.person_outline, color: Colors.grey.shade600, size: 16, ), const SizedBox(width: 6), Text( 'Chef Pierre', style: TextStyle(color: Colors.grey.shade600), ), const SizedBox(width: 8), Icon( Icons.expand_more, color: Colors.grey.shade600, size: 16, ), ], ), ], ), ), ], ), ); } Widget _buildLegendItem(String label, Color color) { return Row( mainAxisSize: MainAxisSize.min, children: [ Container( width: 12, height: 12, decoration: BoxDecoration(color: color, shape: BoxShape.circle), ), const SizedBox(width: 6), Text( label, style: TextStyle(fontSize: 13, color: Colors.grey.shade700), ), ], ); } }