You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

234 lines
7.7 KiB

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<String, dynamic> 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<TablesScreen> createState() => _TablesScreenState();
}
class _TablesScreenState extends State<TablesScreen> {
List<TableData> tables = [];
bool isLoading = true;
@override
void initState() {
super.initState();
fetchTables();
}
Future<void> 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<dynamic> 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,
),
),
),
),
],
),
),
);
},
),
),
);
}
}