andrymodeste 4 months ago
parent
commit
2bccb7a3b4
  1. 19
      lib/main.dart
  2. 424
      lib/pages/login_screen.dart
  3. 499
      lib/pages/menus_screen.dart
  4. 28
      lib/widgets/bottom_navigation.dart

19
lib/main.dart

@ -2,7 +2,8 @@ import 'package:flutter/material.dart';
import 'layouts/main_layout.dart'; import 'layouts/main_layout.dart';
import 'pages/tables.dart'; import 'pages/tables.dart';
import 'pages/categorie.dart'; // Import de votre page de catégories import 'pages/categorie.dart'; // Import de votre page de catégories
// import 'pages/commandes_screen.dart'; import 'pages/commandes_screen.dart';
import 'pages/login_screen.dart';
// import 'pages/menus_screen.dart'; // import 'pages/menus_screen.dart';
void main() { void main() {
@ -20,16 +21,24 @@ class MyApp extends StatelessWidget {
primarySwatch: Colors.green, primarySwatch: Colors.green,
visualDensity: VisualDensity.adaptivePlatformDensity, visualDensity: VisualDensity.adaptivePlatformDensity,
), ),
initialRoute: '/tables', initialRoute: '/login',
routes: { routes: {
'/tables': (context) => const MainLayout( '/login': (context) => const LoginScreen(),
'/tables':
(context) => const MainLayout(
currentRoute: '/tables', currentRoute: '/tables',
child: TablesScreen(), child: TablesScreen(),
), ),
'/categories': (context) => const MainLayout( '/categories':
(context) => const MainLayout(
currentRoute: '/categories', currentRoute: '/categories',
child: CategoriesPage(), child: CategoriesPage(),
), ),
'/commandes':
(context) => const MainLayout(
currentRoute: '/commandes',
child: CategoriesPage(),
),
// Uncomment and update these as needed: // Uncomment and update these as needed:
// '/commandes': (context) => const MainLayout( // '/commandes': (context) => const MainLayout(
// currentRoute: '/commandes', // currentRoute: '/commandes',
@ -42,4 +51,4 @@ class MyApp extends StatelessWidget {
}, },
); );
} }
} }

424
lib/pages/login_screen.dart

@ -0,0 +1,424 @@
import 'package:flutter/material.dart';
import './tables.dart';
import '../layouts/main_layout.dart';
void main() {
runApp(const RestaurantApp());
}
class RestaurantApp extends StatelessWidget {
const RestaurantApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Restaurant App',
theme: ThemeData(primarySwatch: Colors.green),
home: const LoginScreen(),
);
}
}
class LoginScreen extends StatefulWidget {
const LoginScreen({Key? key}) : super(key: key);
@override
State<LoginScreen> createState() => _LoginScreenState();
}
class _LoginScreenState extends State<LoginScreen> {
// Static credentials for both Serveur and Admin
static const String serveurEmail = 'serveur@restaurant.com';
static const String serveurPassword = 'serveur123';
static const String adminEmail = 'admin@restaurant.com';
static const String adminPassword = 'admin123';
final TextEditingController emailController = TextEditingController();
final TextEditingController passwordController = TextEditingController();
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
bool _isLoading = false;
String? _errorMessage;
@override
void initState() {
super.initState();
// Pre-fill with serveur email as shown in design
emailController.text = 'serveur@restaurant.com';
}
@override
void dispose() {
emailController.dispose();
passwordController.dispose();
super.dispose();
}
void _login() async {
if (!_formKey.currentState!.validate()) return;
setState(() {
_isLoading = true;
_errorMessage = null;
});
// Simulate network delay
await Future.delayed(const Duration(seconds: 1));
setState(() {
_isLoading = false;
});
// Check credentials
String email = emailController.text.trim();
String password = passwordController.text;
if ((email == serveurEmail && password == serveurPassword) ||
(email == adminEmail && password == adminPassword)) {
// Login successful - navigate to home/dashboard
if (mounted) {
String userType = email == adminEmail ? 'Admin' : 'Serveur';
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder:
(context) => const MainLayout(
currentRoute: '/tables',
child: TablesScreen(),
),
),
);
}
} else {
// Login failed
setState(() {
_errorMessage = 'Email ou mot de passe incorrect';
});
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: const Color(0xFFF5F5F5), // Light gray background
body: Center(
child: SingleChildScrollView(
padding: const EdgeInsets.all(24.0),
child: Card(
elevation: 2,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
),
child: Container(
width: 400,
padding: const EdgeInsets.all(40.0),
child: Form(
key: _formKey,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
// Logo - Chef hat icon in green circle
Container(
width: 64,
height: 64,
decoration: const BoxDecoration(
color: Colors.green,
shape: BoxShape.circle,
),
child: const Icon(
Icons.restaurant_menu,
color: Colors.white,
size: 32,
),
),
const SizedBox(height: 24),
// Title
const Text(
'Restaurant App',
style: TextStyle(
fontSize: 24,
fontWeight: FontWeight.bold,
color: Colors.black87,
),
),
const SizedBox(height: 8),
// Subtitle
const Text(
'Connectez-vous pour accéder au système de commandes',
style: TextStyle(color: Colors.grey, fontSize: 14),
textAlign: TextAlign.center,
),
const SizedBox(height: 32),
// Error message
if (_errorMessage != null)
Container(
width: double.infinity,
padding: const EdgeInsets.all(12),
margin: const EdgeInsets.only(bottom: 16),
decoration: BoxDecoration(
color: Colors.red.shade50,
border: Border.all(color: Colors.red.shade200),
borderRadius: BorderRadius.circular(4),
),
child: Text(
_errorMessage!,
style: TextStyle(
color: Colors.red.shade600,
fontSize: 14,
),
textAlign: TextAlign.center,
),
),
// Email label
const Align(
alignment: Alignment.centerLeft,
child: Text(
'Email',
style: TextStyle(
fontSize: 14,
color: Colors.black87,
fontWeight: FontWeight.w500,
),
),
),
const SizedBox(height: 8),
// Email field
TextFormField(
controller: emailController,
decoration: InputDecoration(
prefixIcon: const Icon(
Icons.email_outlined,
color: Colors.grey,
size: 20,
),
hintText: 'serveur@restaurant.com',
hintStyle: const TextStyle(color: Colors.grey),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(4),
borderSide: BorderSide(color: Colors.grey.shade300),
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(4),
borderSide: BorderSide(color: Colors.grey.shade300),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(4),
borderSide: const BorderSide(color: Colors.green),
),
contentPadding: const EdgeInsets.symmetric(
horizontal: 12,
vertical: 16,
),
),
keyboardType: TextInputType.emailAddress,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Veuillez entrer votre email';
}
return null;
},
),
const SizedBox(height: 16),
// Password label
const Align(
alignment: Alignment.centerLeft,
child: Text(
'Mot de passe',
style: TextStyle(
fontSize: 14,
color: Colors.black87,
fontWeight: FontWeight.w500,
),
),
),
const SizedBox(height: 8),
// Password field
TextFormField(
controller: passwordController,
decoration: InputDecoration(
prefixIcon: const Icon(
Icons.lock_outline,
color: Colors.grey,
size: 20,
),
hintText: '••••••••',
hintStyle: const TextStyle(color: Colors.grey),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(4),
borderSide: BorderSide(color: Colors.grey.shade300),
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(4),
borderSide: BorderSide(color: Colors.grey.shade300),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(4),
borderSide: const BorderSide(color: Colors.green),
),
contentPadding: const EdgeInsets.symmetric(
horizontal: 12,
vertical: 16,
),
),
obscureText: true,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Veuillez entrer votre mot de passe';
}
return null;
},
),
const SizedBox(height: 24),
// Login button
SizedBox(
width: double.infinity,
height: 48,
child: ElevatedButton(
onPressed: _isLoading ? null : _login,
style: ElevatedButton.styleFrom(
backgroundColor: Colors.green,
foregroundColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(4),
),
elevation: 0,
),
child:
_isLoading
? const SizedBox(
height: 20,
width: 20,
child: CircularProgressIndicator(
color: Colors.white,
strokeWidth: 2,
),
)
: const Text(
'Se connecter',
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w500,
),
),
),
),
const SizedBox(height: 24),
// Demo accounts section
Container(
width: double.infinity,
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: Colors.grey.shade100,
borderRadius: BorderRadius.circular(4),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
'Comptes de démonstration :',
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.w500,
color: Colors.black87,
),
),
const SizedBox(height: 8),
RichText(
text: const TextSpan(
style: TextStyle(
fontSize: 13,
color: Colors.grey,
height: 1.4,
),
children: [
TextSpan(
text: 'Serveur : ',
style: TextStyle(fontWeight: FontWeight.w500),
),
TextSpan(
text: 'serveur@restaurant.com / serveur123\n',
),
TextSpan(
text: 'Admin : ',
style: TextStyle(fontWeight: FontWeight.w500),
),
TextSpan(
text: 'admin@restaurant.com / admin123',
),
],
),
),
],
),
),
],
),
),
),
),
),
),
);
}
}
// Updated home screen to show user type
class HomeScreen extends StatelessWidget {
final String userType;
const HomeScreen({Key? key, required this.userType}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Restaurant Dashboard - $userType'),
backgroundColor: Colors.green,
foregroundColor: Colors.white,
automaticallyImplyLeading: false,
actions: [
IconButton(
icon: const Icon(Icons.logout),
onPressed: () {
Navigator.pushReplacement(
context,
MaterialPageRoute(builder: (context) => const LoginScreen()),
);
},
),
],
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(Icons.check_circle, color: Colors.green, size: 80),
const SizedBox(height: 16),
Text(
'Connexion réussie!',
style: TextStyle(
fontSize: 24,
fontWeight: FontWeight.bold,
color: Colors.green,
),
),
const SizedBox(height: 8),
Text(
'Bienvenue $userType',
style: TextStyle(fontSize: 18, color: Colors.grey),
),
],
),
),
);
}
}

499
lib/pages/menus_screen.dart

@ -1 +1,500 @@
// TODO Implement this library. // TODO Implement this library.
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
class MenuPage extends StatefulWidget {
final int? tableId;
final int? personne;
const MenuPage({Key? key, required this.tableId, required this.personne})
: super(key: key);
@override
State<MenuPage> createState() => _MenuPageState();
}
class _MenuPageState extends State<MenuPage> {
int? _selectedCategory;
List<dynamic> _categories = [];
List<dynamic> _menus = [];
List<dynamic> _cart = [];
@override
void initState() {
super.initState();
fetchCategories();
}
Future<void> fetchCategories() async {
try {
final url = Uri.parse(
"https://restaurant.careeracademy.mg/api/menu-categories",
);
final response = await http.get(url);
if (response.statusCode == 200) {
final jsonResponse = json.decode(response.body);
final categoriesList =
(jsonResponse['data']?['categories'] ?? []) as List<dynamic>;
setState(() {
_categories = categoriesList;
if (_categories.isNotEmpty) {
_selectedCategory = _categories[0]['id'];
fetchMenus(_selectedCategory!);
}
});
} else {
print("Erreur API catégories: ${response.statusCode}");
}
} catch (e) {
print("Exception fetchCategories: $e");
}
}
Future<void> fetchMenus(int categoryId) async {
try {
final url = Uri.parse(
"https://restaurant.careeracademy.mg/api/menus/category/$categoryId?disponible=true",
);
final response = await http.get(url);
if (response.statusCode == 200) {
final jsonResponse = json.decode(response.body);
final List<dynamic> menusList =
jsonResponse is List ? jsonResponse : (jsonResponse['data'] ?? []);
setState(() {
_menus = menusList;
});
} else {
print("Erreur API menus: ${response.statusCode}");
}
} catch (e) {
print("Exception fetchMenus: $e");
}
}
void changeCategory(int id) {
setState(() {
_selectedCategory = id;
_menus = [];
});
fetchMenus(id);
}
void addToCart(dynamic item, int quantity, String notes) {
setState(() {
for (int i = 0; i < quantity; i++) {
Map<String, dynamic> cartItem = Map<String, dynamic>.from(item);
if (notes.isNotEmpty) {
cartItem['notes'] = notes;
}
_cart.add(cartItem);
}
});
}
void showAddToCartModal(dynamic item) {
showDialog(
context: context,
builder: (BuildContext context) {
return AddToCartModal(item: item, onAddToCart: addToCart);
},
);
}
/// Conversion sécurisée du prix en string avec 2 décimales
String formatPrix(dynamic prix) {
if (prix == null) return "";
double? val;
if (prix is num) {
val = prix.toDouble();
} else if (prix is String) {
val = double.tryParse(prix);
}
return val != null ? val.toStringAsFixed(2) : "";
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Menu"),
actions: [
IconButton(
onPressed: () {
if (_selectedCategory != null) fetchMenus(_selectedCategory!);
},
icon: Icon(Icons.refresh),
),
],
),
body: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
"Table ${widget.tableId}${widget.personne} personne${widget.personne! > 1 ? 's' : ''}",
style: TextStyle(fontSize: 16),
),
),
if (_categories.isNotEmpty)
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children:
_categories.map<Widget>((cat) {
return buildCategoryButton(cat['nom'], cat['id']);
}).toList(),
)
else
Center(child: CircularProgressIndicator()),
Expanded(
child:
_menus.isNotEmpty
? ListView.builder(
itemCount: _menus.length,
itemBuilder: (context, index) {
final item = _menus[index];
return Card(
margin: EdgeInsets.all(8),
child: ListTile(
onTap:
() => showAddToCartModal(
item,
), // Clic sur tout l'item
leading: Container(
width: 60,
height: 60,
decoration: BoxDecoration(
color: Colors.green[100],
borderRadius: BorderRadius.circular(8),
),
child: Icon(
Icons.restaurant_menu,
color: Colors.green[700],
size: 30,
),
),
title: Text(
item['nom'] ?? 'Nom non disponible',
style: TextStyle(fontWeight: FontWeight.bold),
),
subtitle: Text(item['commentaire'] ?? ''),
trailing: Text(
"${formatPrix(item['prix'])}",
style: TextStyle(
color: Colors.green[700],
fontWeight: FontWeight.bold,
fontSize: 16,
),
),
),
);
},
)
: Center(child: Text("Aucun menu disponible")),
),
Container(
width: double.infinity,
padding: EdgeInsets.symmetric(vertical: 12),
color: Colors.green[700],
child: Center(
child: TextButton(
onPressed: () {
// TODO: Naviguer vers la page panier
},
child: Text(
"Voir le panier (${_cart.length})",
style: TextStyle(color: Colors.white, fontSize: 16),
),
),
),
),
],
),
);
}
Widget buildCategoryButton(String label, int id) {
final selected = _selectedCategory == id;
return Expanded(
child: GestureDetector(
onTap: () => changeCategory(id),
child: Container(
padding: EdgeInsets.symmetric(vertical: 10),
color: selected ? Colors.grey[300] : Colors.grey[100],
child: Center(
child: Text(
label,
style: TextStyle(
fontWeight: selected ? FontWeight.bold : FontWeight.normal,
),
),
),
),
),
);
}
}
// Modal pour ajouter au panier
class AddToCartModal extends StatefulWidget {
final dynamic item;
final Function(dynamic, int, String) onAddToCart;
const AddToCartModal({
Key? key,
required this.item,
required this.onAddToCart,
}) : super(key: key);
@override
State<AddToCartModal> createState() => _AddToCartModalState();
}
class _AddToCartModalState extends State<AddToCartModal> {
int _quantity = 1;
final TextEditingController _notesController = TextEditingController();
String formatPrix(dynamic prix) {
if (prix == null) return "0.00";
double? val;
if (prix is num) {
val = prix.toDouble();
} else if (prix is String) {
val = double.tryParse(prix);
}
return val != null ? val.toStringAsFixed(2) : "0.00";
}
double calculateTotal() {
double prix = 0.0;
if (widget.item['prix'] is num) {
prix = widget.item['prix'].toDouble();
} else if (widget.item['prix'] is String) {
prix = double.tryParse(widget.item['prix']) ?? 0.0;
}
return prix * _quantity;
}
@override
Widget build(BuildContext context) {
return Dialog(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)),
child: Container(
padding: EdgeInsets.all(20),
constraints: BoxConstraints(maxWidth: 400),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Header
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
widget.item['nom'] ?? 'Menu',
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
),
IconButton(
onPressed: () => Navigator.of(context).pop(),
icon: Icon(Icons.close),
padding: EdgeInsets.zero,
constraints: BoxConstraints(),
),
],
),
SizedBox(height: 16),
// Image placeholder
Container(
width: double.infinity,
height: 150,
decoration: BoxDecoration(
color: Colors.green[100],
borderRadius: BorderRadius.circular(12),
),
child: Icon(
Icons.restaurant_menu,
size: 60,
color: Colors.green[700],
),
),
SizedBox(height: 16),
// Description
if (widget.item['commentaire'] != null &&
widget.item['commentaire'].toString().isNotEmpty)
Text(
widget.item['commentaire'],
style: TextStyle(fontSize: 14, color: Colors.grey[600]),
),
SizedBox(height: 16),
// Prix unitaire
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
"Prix unitaire",
style: TextStyle(fontSize: 16, fontWeight: FontWeight.w500),
),
Text(
"${formatPrix(widget.item['prix'])}",
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
color: Colors.green[700],
),
),
],
),
SizedBox(height: 20),
// Quantité
Text(
"Quantité",
style: TextStyle(fontSize: 16, fontWeight: FontWeight.w500),
),
SizedBox(height: 8),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
IconButton(
onPressed:
_quantity > 1
? () {
setState(() {
_quantity--;
});
}
: null,
icon: Icon(Icons.remove),
style: IconButton.styleFrom(
backgroundColor: Colors.grey[200],
),
),
SizedBox(width: 20),
Text(
_quantity.toString(),
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
),
SizedBox(width: 20),
IconButton(
onPressed: () {
setState(() {
_quantity++;
});
},
icon: Icon(Icons.add),
style: IconButton.styleFrom(
backgroundColor: Colors.grey[200],
),
),
],
),
SizedBox(height: 20),
// Notes
Text(
"Notes (optionnel)",
style: TextStyle(fontSize: 16, fontWeight: FontWeight.w500),
),
SizedBox(height: 8),
TextField(
controller: _notesController,
maxLines: 3,
decoration: InputDecoration(
hintText: "Commentaires spéciaux (sans oignons, bien cuit...)",
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8),
),
contentPadding: EdgeInsets.all(12),
),
),
SizedBox(height: 24),
// Total et bouton d'ajout
Container(
width: double.infinity,
padding: EdgeInsets.all(16),
decoration: BoxDecoration(
color: Colors.grey[50],
borderRadius: BorderRadius.circular(12),
),
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
"Total",
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
Text(
"${calculateTotal().toStringAsFixed(2)}",
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
color: Colors.green[700],
),
),
],
),
SizedBox(height: 16),
SizedBox(
width: double.infinity,
child: ElevatedButton(
onPressed: () {
widget.onAddToCart(
widget.item,
_quantity,
_notesController.text,
);
Navigator.of(context).pop();
// Afficher un snackbar de confirmation
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
"${widget.item['nom']} ajouté au panier",
),
backgroundColor: Colors.green,
duration: Duration(seconds: 2),
),
);
},
style: ElevatedButton.styleFrom(
backgroundColor: Colors.green[700],
foregroundColor: Colors.white,
padding: EdgeInsets.symmetric(vertical: 16),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
),
),
child: Text(
"Ajouter au panier",
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
),
),
),
),
],
),
),
],
),
),
);
}
}

28
lib/widgets/bottom_navigation.dart

@ -1,4 +1,5 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:itrimobe/pages/login_screen.dart';
class AppBottomNavigation extends StatelessWidget { class AppBottomNavigation extends StatelessWidget {
final int? selectedIndex; final int? selectedIndex;
@ -12,6 +13,8 @@ class AppBottomNavigation extends StatelessWidget {
this.isDesktop = false, this.isDesktop = false,
}); });
BuildContext? get context => null;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
if (isDesktop) return const SizedBox.shrink(); if (isDesktop) return const SizedBox.shrink();
@ -116,7 +119,8 @@ class AppBottomNavigation extends StatelessWidget {
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
decoration: BoxDecoration( decoration: BoxDecoration(
color: color:
selectedIndex == 2 // Index 2 pour catégories selectedIndex ==
2 // Index 2 pour catégories
? Colors.green.shade700 ? Colors.green.shade700
: Colors.transparent, : Colors.transparent,
borderRadius: BorderRadius.circular(20), borderRadius: BorderRadius.circular(20),
@ -125,7 +129,8 @@ class AppBottomNavigation extends StatelessWidget {
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
Icon( Icon(
Icons.category_outlined, // Icône plus appropriée pour catégories Icons
.category_outlined, // Icône plus appropriée pour catégories
color: color:
selectedIndex == 2 selectedIndex == 2
? Colors.white ? Colors.white
@ -154,21 +159,26 @@ class AppBottomNavigation extends StatelessWidget {
const Spacer(), const Spacer(),
// User Profile Section // User Profile Section
_buildUserProfile(), _buildUserProfile(context),
], ],
), ),
); );
} }
Widget _buildUserProfile() { Widget _buildUserProfile(context) {
return Row( return Row(
children: [ children: [
Icon(Icons.person_outline, color: Colors.grey.shade600, size: 16),
const SizedBox(width: 6), const SizedBox(width: 6),
Text('Chef Pierre', style: TextStyle(color: Colors.grey.shade600)), IconButton(
const SizedBox(width: 8), icon: const Icon(Icons.logout),
Icon(Icons.expand_more, color: Colors.grey.shade600, size: 16), onPressed: () {
Navigator.pushReplacement(
context!,
MaterialPageRoute(builder: (context) => const LoginScreen()),
);
},
),
], ],
); );
} }
} }

Loading…
Cancel
Save