push 03082025
This commit is contained in:
parent
c2cd893835
commit
c9f4a0ce45
@ -16,6 +16,7 @@ class CommandeDetail {
|
|||||||
final DateTime? dateService;
|
final DateTime? dateService;
|
||||||
final DateTime createdAt;
|
final DateTime createdAt;
|
||||||
final DateTime updatedAt;
|
final DateTime updatedAt;
|
||||||
|
final String tablename;
|
||||||
final List<CommandeItem> items;
|
final List<CommandeItem> items;
|
||||||
|
|
||||||
CommandeDetail({
|
CommandeDetail({
|
||||||
@ -36,6 +37,7 @@ class CommandeDetail {
|
|||||||
required this.createdAt,
|
required this.createdAt,
|
||||||
required this.updatedAt,
|
required this.updatedAt,
|
||||||
required this.items,
|
required this.items,
|
||||||
|
required this.tablename,
|
||||||
});
|
});
|
||||||
|
|
||||||
factory CommandeDetail.fromJson(Map<String, dynamic> json) {
|
factory CommandeDetail.fromJson(Map<String, dynamic> json) {
|
||||||
@ -54,6 +56,7 @@ class CommandeDetail {
|
|||||||
totalTtc: double.tryParse(data['total_ttc']?.toString() ?? '0') ?? 0.0,
|
totalTtc: double.tryParse(data['total_ttc']?.toString() ?? '0') ?? 0.0,
|
||||||
modePaiement: data['mode_paiement'],
|
modePaiement: data['mode_paiement'],
|
||||||
commentaires: data['commentaires'],
|
commentaires: data['commentaires'],
|
||||||
|
tablename: json['tablename'] ?? 'Inconnue',
|
||||||
serveur: data['serveur'] ?? 'Serveur par défaut',
|
serveur: data['serveur'] ?? 'Serveur par défaut',
|
||||||
dateCommande:
|
dateCommande:
|
||||||
data['date_commande'] != null
|
data['date_commande'] != null
|
||||||
|
|||||||
@ -10,7 +10,8 @@ class TableOrder {
|
|||||||
final double? total; // Optionnel pour les commandes en cours
|
final double? total; // Optionnel pour les commandes en cours
|
||||||
final bool isEncashed;
|
final bool isEncashed;
|
||||||
final String? time; // Heure de la commande si applicable
|
final String? time; // Heure de la commande si applicable
|
||||||
final String? date; // Date de la commande si applicable
|
final DateTime? date; // Date de la commande si applicable
|
||||||
|
final String? tablename; // Date de la commande si applicable
|
||||||
// final int? persons; // Nombre de personnes si applicable
|
// final int? persons; // Nombre de personnes si applicable
|
||||||
|
|
||||||
TableOrder({
|
TableOrder({
|
||||||
@ -25,31 +26,34 @@ class TableOrder {
|
|||||||
this.isEncashed = false,
|
this.isEncashed = false,
|
||||||
this.time,
|
this.time,
|
||||||
this.date,
|
this.date,
|
||||||
|
this.tablename,
|
||||||
// this.persons,
|
// this.persons,
|
||||||
});
|
});
|
||||||
|
factory TableOrder.fromJson(Map<String, dynamic> json) {
|
||||||
factory TableOrder.fromJson(Map<String, dynamic> json) {
|
|
||||||
return TableOrder(
|
return TableOrder(
|
||||||
id: json['id'] ?? 0,
|
id: json['id'] ?? 0,
|
||||||
nom: json['nom'] ?? '',
|
nom: json['nom'] ?? '',
|
||||||
capacity: json['capacity'] ?? 1,
|
capacity: json['capacity'] ?? 1,
|
||||||
status: json['status'] ?? 'available',
|
status: json['statut'] ?? 'available',
|
||||||
location: json['location'] ?? '',
|
location: json['location'] ?? '',
|
||||||
createdAt:
|
tablename: json['tablename'] ?? '',
|
||||||
json['created_at'] != null
|
createdAt: json['created_at'] != null
|
||||||
? DateTime.parse(json['created_at'])
|
? DateTime.parse(json['created_at'])
|
||||||
: DateTime.now(),
|
: DateTime.now(),
|
||||||
updatedAt:
|
updatedAt: json['updated_at'] != null
|
||||||
json['updated_at'] != null
|
|
||||||
? DateTime.parse(json['updated_at'])
|
? DateTime.parse(json['updated_at'])
|
||||||
: DateTime.now(),
|
: DateTime.now(),
|
||||||
total: json['total'] != null ? (json['total'] as num).toDouble() : null,
|
total: json['total_ht'] != null
|
||||||
|
? double.tryParse(json['total_ht'].toString())
|
||||||
|
: null,
|
||||||
isEncashed: json['is_encashed'] ?? false,
|
isEncashed: json['is_encashed'] ?? false,
|
||||||
time: json['time'],
|
time: json['time'],
|
||||||
date: json['date'],
|
date: json['date_commande'] != null
|
||||||
// persons: json['persons'],
|
? DateTime.parse(json['date_commande']) // tu avais mis updated_at ici par erreur
|
||||||
|
: null,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Map<String, dynamic> toJson() {
|
Map<String, dynamic> toJson() {
|
||||||
return {
|
return {
|
||||||
@ -58,6 +62,7 @@ class TableOrder {
|
|||||||
'capacity': capacity,
|
'capacity': capacity,
|
||||||
'status': status,
|
'status': status,
|
||||||
'location': location,
|
'location': location,
|
||||||
|
'tablename': tablename,
|
||||||
'created_at': createdAt.toIso8601String(),
|
'created_at': createdAt.toIso8601String(),
|
||||||
'updated_at': updatedAt.toIso8601String(),
|
'updated_at': updatedAt.toIso8601String(),
|
||||||
if (total != null) 'total': total,
|
if (total != null) 'total': total,
|
||||||
@ -122,7 +127,7 @@ class TableOrder {
|
|||||||
double? total,
|
double? total,
|
||||||
bool? isEncashed,
|
bool? isEncashed,
|
||||||
String? time,
|
String? time,
|
||||||
String? date,
|
DateTime? date,
|
||||||
int? persons,
|
int? persons,
|
||||||
}) {
|
}) {
|
||||||
return TableOrder(
|
return TableOrder(
|
||||||
@ -153,6 +158,10 @@ class TableOrder {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
int get hashCode => id.hashCode;
|
int get hashCode => id.hashCode;
|
||||||
|
|
||||||
|
get items => null;
|
||||||
|
|
||||||
|
where(bool Function(dynamic commande) param0) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Énumération pour les statuts (optionnel, pour plus de type safety)
|
// Énumération pour les statuts (optionnel, pour plus de type safety)
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
import './tables.dart';
|
import './tables.dart';
|
||||||
import '../layouts/main_layout.dart';
|
import '../layouts/main_layout.dart';
|
||||||
|
|
||||||
@ -54,6 +55,15 @@ class _LoginScreenState extends State<LoginScreen> {
|
|||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Méthode pour gérer la touche Entrée
|
||||||
|
void _handleKeyPress(KeyEvent event) {
|
||||||
|
if (event is KeyDownEvent && event.logicalKey == LogicalKeyboardKey.enter) {
|
||||||
|
if (!_isLoading) {
|
||||||
|
_login();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void _login() async {
|
void _login() async {
|
||||||
if (!_formKey.currentState!.validate()) return;
|
if (!_formKey.currentState!.validate()) return;
|
||||||
|
|
||||||
@ -99,7 +109,10 @@ class _LoginScreenState extends State<LoginScreen> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return KeyboardListener(
|
||||||
|
focusNode: FocusNode(),
|
||||||
|
onKeyEvent: _handleKeyPress,
|
||||||
|
child: Scaffold(
|
||||||
backgroundColor: const Color(0xFFF5F5F5), // Light gray background
|
backgroundColor: const Color(0xFFF5F5F5), // Light gray background
|
||||||
body: Center(
|
body: Center(
|
||||||
child: SingleChildScrollView(
|
child: SingleChildScrollView(
|
||||||
@ -227,6 +240,7 @@ class _LoginScreenState extends State<LoginScreen> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
keyboardType: TextInputType.emailAddress,
|
keyboardType: TextInputType.emailAddress,
|
||||||
|
textInputAction: TextInputAction.next,
|
||||||
validator: (value) {
|
validator: (value) {
|
||||||
if (value == null || value.isEmpty) {
|
if (value == null || value.isEmpty) {
|
||||||
return 'Veuillez entrer votre email';
|
return 'Veuillez entrer votre email';
|
||||||
@ -279,6 +293,8 @@ class _LoginScreenState extends State<LoginScreen> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
obscureText: true,
|
obscureText: true,
|
||||||
|
textInputAction: TextInputAction.done,
|
||||||
|
onFieldSubmitted: (_) => _login(), // Validation quand on appuie sur Entrée
|
||||||
validator: (value) {
|
validator: (value) {
|
||||||
if (value == null || value.isEmpty) {
|
if (value == null || value.isEmpty) {
|
||||||
return 'Veuillez entrer votre mot de passe';
|
return 'Veuillez entrer votre mot de passe';
|
||||||
@ -368,6 +384,15 @@ class _LoginScreenState extends State<LoginScreen> {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
const Text(
|
||||||
|
'Astuce : Appuyez sur Entrée pour vous connecter',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12,
|
||||||
|
color: Colors.grey,
|
||||||
|
fontStyle: FontStyle.italic,
|
||||||
|
),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -378,6 +403,7 @@ class _LoginScreenState extends State<LoginScreen> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -21,7 +21,7 @@ class RestaurantApiService {
|
|||||||
static Future<List<TableOrder>> getCommandes() async {
|
static Future<List<TableOrder>> getCommandes() async {
|
||||||
try {
|
try {
|
||||||
final response = await http
|
final response = await http
|
||||||
.get(Uri.parse('$baseUrl/api/commandes'), headers: _headers)
|
.get(Uri.parse('$baseUrl/api/commandes?statut=servie'), headers: _headers)
|
||||||
.timeout(
|
.timeout(
|
||||||
const Duration(seconds: 30),
|
const Duration(seconds: 30),
|
||||||
onTimeout: () => throw TimeoutException('Délai d\'attente dépassé'),
|
onTimeout: () => throw TimeoutException('Délai d\'attente dépassé'),
|
||||||
@ -171,6 +171,7 @@ class RestaurantApiService {
|
|||||||
totalTtc: 14.00,
|
totalTtc: 14.00,
|
||||||
modePaiement: null,
|
modePaiement: null,
|
||||||
commentaires: null,
|
commentaires: null,
|
||||||
|
tablename: 'a',
|
||||||
serveur: "Serveur par défaut",
|
serveur: "Serveur par défaut",
|
||||||
dateCommande: DateTime.parse("2025-08-02T15:03:44.000Z"),
|
dateCommande: DateTime.parse("2025-08-02T15:03:44.000Z"),
|
||||||
dateService: null,
|
dateService: null,
|
||||||
@ -234,7 +235,6 @@ class RestaurantApiService {
|
|||||||
updatedAt: DateTime.now(),
|
updatedAt: DateTime.now(),
|
||||||
total: 27.00,
|
total: 27.00,
|
||||||
time: '00:02',
|
time: '00:02',
|
||||||
date: '02/08/2025',
|
|
||||||
),
|
),
|
||||||
// Ajoutez d'autres tables de test...
|
// Ajoutez d'autres tables de test...
|
||||||
];
|
];
|
||||||
|
|||||||
@ -12,8 +12,13 @@ class CommandeCard extends StatelessWidget {
|
|||||||
required this.onAllerCaisse,
|
required this.onAllerCaisse,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
String _formatTime(DateTime dateTime) {
|
||||||
|
return '${dateTime.hour.toString().padLeft(2, '0')}:${dateTime.minute.toString().padLeft(2, '0')} ${dateTime.day.toString().padLeft(2, '0')}/${dateTime.month.toString().padLeft(2, '0')}/${dateTime.year}';
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
|
||||||
return Container(
|
return Container(
|
||||||
margin: EdgeInsets.only(bottom: 16),
|
margin: EdgeInsets.only(bottom: 16),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
@ -38,7 +43,7 @@ class CommandeCard extends StatelessWidget {
|
|||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
'Table ${commande.tableNumber}',
|
' ${commande.tablename}',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 18,
|
fontSize: 18,
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
@ -57,7 +62,7 @@ class CommandeCard extends StatelessWidget {
|
|||||||
Icon(Icons.check_circle, color: Colors.white, size: 16),
|
Icon(Icons.check_circle, color: Colors.white, size: 16),
|
||||||
SizedBox(width: 4),
|
SizedBox(width: 4),
|
||||||
Text(
|
Text(
|
||||||
'À encaisser',
|
'Près à encaisser',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
@ -78,7 +83,8 @@ class CommandeCard extends StatelessWidget {
|
|||||||
Icon(Icons.access_time, size: 16, color: Colors.grey[600]),
|
Icon(Icons.access_time, size: 16, color: Colors.grey[600]),
|
||||||
SizedBox(width: 6),
|
SizedBox(width: 6),
|
||||||
Text(
|
Text(
|
||||||
'${commande.time} • ${commande.date} ',
|
// Fixed: Pass DateTime directly, not as string
|
||||||
|
commande.date != null ? _formatTime(commande.date!) : 'Date non disponible',
|
||||||
style: TextStyle(color: Colors.grey[600], fontSize: 14),
|
style: TextStyle(color: Colors.grey[600], fontSize: 14),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@ -99,7 +105,7 @@ class CommandeCard extends StatelessWidget {
|
|||||||
style: TextStyle(color: Colors.grey[600], fontSize: 14),
|
style: TextStyle(color: Colors.grey[600], fontSize: 14),
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
'${commande.total?.toStringAsFixed(2)} MGA',
|
'${commande.total?.toStringAsFixed(2) ?? '0.00'} MGA',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 20,
|
fontSize: 20,
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user