import 'dart:convert'; import 'dart:io' show Platform; import 'package:flutter/foundation.dart' show kIsWeb; import 'package:flutter/material.dart'; import 'package:http/http.dart' as http; import 'menu.dart'; // Assure-toi que ce fichier contient la page MenuPage 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 { const TablesScreen({super.key}); @override State createState() => _TablesScreenState(); } class _TablesScreenState extends State { List tables = []; bool isLoading = true; @override void initState() { super.initState(); fetchTables(); } Future fetchTables() async { try { 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}'); } } catch (e) { setState(() => isLoading = false); print('Erreur réseau: $e'); } } Color getStatusColor(String status) { switch (status) { case 'available': return Colors.green; case 'occupied': return Colors.red; 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 isDesktop() { if (kIsWeb) return true; try { return Platform.isWindows || Platform.isMacOS || Platform.isLinux; } catch (_) { return false; } } @override Widget build(BuildContext context) { final screenWidth = MediaQuery.of(context).size.width; final crossAxisCount = screenWidth > 1200 ? 4 : screenWidth > 800 ? 3 : 2; return Scaffold( appBar: AppBar( title: const Text('Sélectionner une table'), actions: isDesktop() ? [ IconButton( icon: const Icon(Icons.refresh), onPressed: () { setState(() => isLoading = true); fetchTables(); }, ), ] : null, ), body: isLoading ? const Center(child: CircularProgressIndicator()) : Padding( padding: const EdgeInsets.all(12.0), child: GridView.builder( itemCount: tables.length, gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: crossAxisCount, crossAxisSpacing: 12, mainAxisSpacing: 12, childAspectRatio: 2.3, ), itemBuilder: (context, index) { final table = tables[index]; final isAvailable = table.status == 'available'; return Card( shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(14), ), child: Padding( padding: const EdgeInsets.all(10), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( table.nom, style: const TextStyle( fontWeight: FontWeight.bold, fontSize: 13, ), ), Container( padding: const EdgeInsets.symmetric( horizontal: 8, vertical: 2), decoration: BoxDecoration( color: getStatusColor(table.status), borderRadius: BorderRadius.circular(50), ), child: Text( getStatusLabel(table.status), style: const TextStyle( color: Colors.white, fontSize: 10, ), ), ), ], ), const Spacer(), Row( children: [ const Icon(Icons.people_outline, size: 14, color: Colors.grey), const SizedBox(width: 4), Text( '${table.capacity} personnes', style: const TextStyle( fontSize: 11.5, color: Colors.grey, ), ), ], ), const SizedBox(height: 8), SizedBox( width: double.infinity, height: 30, child: ElevatedButton( onPressed: isAvailable ? () { Navigator.push( context, MaterialPageRoute( builder: (_) => MenuPage( tableId: table.id, personne: table.capacity, ), ), ); } : null, style: ElevatedButton.styleFrom( backgroundColor: Colors.deepOrange, padding: EdgeInsets.zero, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(6), ), ), child: const Text( "Réserver", style: TextStyle( color: Colors.white, fontSize: 12, ), ), ), ), ], ), ), ); }, ), ), ); } }