From ad9393a9259a15398083228d3c3e3eb2c22147dd Mon Sep 17 00:00:00 2001 From: Van Leemput Dayron Date: Wed, 1 Oct 2025 12:21:00 +0200 Subject: [PATCH] Add profile in parameters, initialized page map, group, count. --- lib/components/count/count_content.dart | 13 + lib/components/group/group_content.dart | 13 + lib/components/map/map_content.dart | 24 ++ lib/components/profile/profile_content.dart | 246 ++++++++++++++++-- lib/components/settings/settings_content.dart | 24 +- lib/main.dart | 10 +- lib/pages/home.dart | 66 +++-- lib/pages/login.dart | 3 + lib/providers/user_provider.dart | 20 ++ 9 files changed, 377 insertions(+), 42 deletions(-) create mode 100644 lib/components/count/count_content.dart create mode 100644 lib/components/group/group_content.dart create mode 100644 lib/components/map/map_content.dart create mode 100644 lib/providers/user_provider.dart diff --git a/lib/components/count/count_content.dart b/lib/components/count/count_content.dart new file mode 100644 index 0000000..ce20735 --- /dev/null +++ b/lib/components/count/count_content.dart @@ -0,0 +1,13 @@ +import 'package:flutter/material.dart'; + +class CountContent extends StatelessWidget { + const CountContent({super.key}); + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar(title: const Text('Count Page')), + body: const Center(child: Text('This is the Count Page')), + ); + } +} diff --git a/lib/components/group/group_content.dart b/lib/components/group/group_content.dart new file mode 100644 index 0000000..3aaff9b --- /dev/null +++ b/lib/components/group/group_content.dart @@ -0,0 +1,13 @@ +import 'package:flutter/material.dart'; + +class GroupContent extends StatelessWidget { + const GroupContent({super.key}); + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar(title: const Text('Group Page')), + body: const Center(child: Text('This is the Group Page')), + ); + } +} diff --git a/lib/components/map/map_content.dart b/lib/components/map/map_content.dart new file mode 100644 index 0000000..cc7b517 --- /dev/null +++ b/lib/components/map/map_content.dart @@ -0,0 +1,24 @@ +import 'package:flutter/material.dart'; + +class MapContent extends StatelessWidget { + const MapContent({super.key}); + + @override + Widget build(BuildContext context) { + return Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon(Icons.map, size: 80, color: Colors.green), + SizedBox(height: 20), + Text( + 'Page de la Carte', + style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold), + ), + SizedBox(height: 10), + Text('Ici sera intégrée Google Maps'), + ], + ), + ); + } +} diff --git a/lib/components/profile/profile_content.dart b/lib/components/profile/profile_content.dart index 389ad2d..4431e52 100644 --- a/lib/components/profile/profile_content.dart +++ b/lib/components/profile/profile_content.dart @@ -1,32 +1,242 @@ import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; +import '../../providers/user_provider.dart'; class ProfileContent extends StatelessWidget { const ProfileContent({super.key}); @override Widget build(BuildContext context) { - return Padding( - padding: EdgeInsets.all(16), - child: Center( - child: Column( + return Consumer( + builder: (context, userProvider, child) { + final user = userProvider.currentUser; + + if (user == null) { + return Center(child: Text('Aucun utilisateur connecté')); + } + + return Column( children: [ - CircleAvatar( - radius: 50, - backgroundColor: Colors.blue, - child: Icon(Icons.person, size: 50, color: Colors.white), + // Section titre + Padding( + padding: EdgeInsets.symmetric(horizontal: 16, vertical: 8), + child: Row( + children: [ + Text( + 'Profil utilisateur', + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.bold, + color: Colors.grey[600], + ), + ), + ], + ), ), - SizedBox(height: 20), - Text( - 'Nom d\'utilisateur', - style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold), + + // Card du profil + Card( + margin: EdgeInsets.symmetric(horizontal: 16, vertical: 8), + child: Padding( + padding: EdgeInsets.all(16), + child: Column( + children: [ + // Photo de profil + CircleAvatar( + radius: 40, + backgroundColor: Theme.of(context).colorScheme.primary, + child: Text( + user.prenom[0].toUpperCase() + + user.nom[0].toUpperCase(), + style: TextStyle( + fontSize: 24, + fontWeight: FontWeight.bold, + color: Colors.white, + ), + ), + ), + + SizedBox(height: 16), + + // Nom complet + Text( + user.fullName, + style: TextStyle( + fontSize: 20, + fontWeight: FontWeight.bold, + ), + ), + + SizedBox(height: 8), + + // Email + Text( + user.email, + style: TextStyle(fontSize: 14, color: Colors.grey[600]), + ), + ], + ), + ), + ), + + // Actions du profil + ListTile( + leading: Icon(Icons.edit), + title: Text('Modifier le profil'), + trailing: Icon(Icons.arrow_forward_ios), + onTap: () { + _showEditProfileDialog(context, user); + }, + ), + + ListTile( + leading: Icon(Icons.lock), + title: Text('Changer le mot de passe'), + trailing: Icon(Icons.arrow_forward_ios), + onTap: () { + _showChangePasswordDialog(context); + }, + ), + + Divider(), + + ListTile( + leading: Icon(Icons.delete, color: Colors.red), + title: Text('Supprimer le compte'), + trailing: Icon(Icons.arrow_forward_ios), + onTap: () { + _showDeleteAccountDialog(context); + }, ), - SizedBox(height: 10), - Text('email@example.com'), - SizedBox(height: 30), - ElevatedButton(onPressed: () {}, child: Text('Modifier le profil')), ], - ), - ), + ); + }, + ); + } + + void _showEditProfileDialog(BuildContext context, user) { + final nomController = TextEditingController(text: user.nom); + final prenomController = TextEditingController(text: user.prenom); + + showDialog( + context: context, + builder: (BuildContext context) { + return AlertDialog( + title: Text('Modifier le profil'), + content: Column( + mainAxisSize: MainAxisSize.min, + children: [ + TextField( + controller: prenomController, + decoration: InputDecoration(labelText: 'Prénom'), + ), + SizedBox(height: 16), + TextField( + controller: nomController, + decoration: InputDecoration(labelText: 'Nom'), + ), + ], + ), + actions: [ + TextButton( + onPressed: () => Navigator.of(context).pop(), + child: Text('Annuler'), + ), + TextButton( + onPressed: () { + // TODO: Implémenter la mise à jour + Navigator.of(context).pop(); + ScaffoldMessenger.of( + context, + ).showSnackBar(SnackBar(content: Text('Profil mis à jour !'))); + }, + child: Text('Sauvegarder'), + ), + ], + ); + }, + ); + } + + void _showChangePasswordDialog(BuildContext context) { + showDialog( + context: context, + builder: (BuildContext context) { + return AlertDialog( + title: Text('Changer le mot de passe'), + content: Column( + mainAxisSize: MainAxisSize.min, + children: [ + TextField( + obscureText: true, + decoration: InputDecoration(labelText: 'Mot de passe actuel'), + ), + SizedBox(height: 16), + TextField( + obscureText: true, + decoration: InputDecoration(labelText: 'Nouveau mot de passe'), + ), + SizedBox(height: 16), + TextField( + obscureText: true, + decoration: InputDecoration( + labelText: 'Confirmer le mot de passe', + ), + ), + ], + ), + actions: [ + TextButton( + onPressed: () => Navigator.of(context).pop(), + child: Text('Annuler'), + ), + TextButton( + onPressed: () { + // TODO: Implémenter le changement de mot de passe + Navigator.of(context).pop(); + ScaffoldMessenger.of(context).showSnackBar( + SnackBar(content: Text('Mot de passe changé !')), + ); + }, + child: Text('Changer'), + ), + ], + ); + }, + ); + } + + void _showDeleteAccountDialog(BuildContext context) { + showDialog( + context: context, + builder: (BuildContext context) { + return AlertDialog( + title: Text('Supprimer le compte'), + content: Text( + 'Êtes-vous sûr de vouloir supprimer votre compte ? Cette action est irréversible.', + ), + actions: [ + TextButton( + onPressed: () => Navigator.of(context).pop(), + child: Text('Annuler'), + ), + TextButton( + onPressed: () { + Navigator.of(context).pop(); + // TODO: Implémenter la suppression + Provider.of(context, listen: false).logout(); + Navigator.pushNamedAndRemoveUntil( + context, + '/login', + (route) => false, + ); + }, + style: TextButton.styleFrom(foregroundColor: Colors.red), + child: Text('Supprimer'), + ), + ], + ); + }, ); } } diff --git a/lib/components/settings/settings_content.dart b/lib/components/settings/settings_content.dart index fa0959f..4291bbf 100644 --- a/lib/components/settings/settings_content.dart +++ b/lib/components/settings/settings_content.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'settings_theme_content.dart'; +import '../profile/profile_content.dart'; class SettingsContent extends StatelessWidget { const SettingsContent({super.key}); @@ -15,6 +16,22 @@ class SettingsContent extends StatelessWidget { ), SizedBox(height: 20), + // Section Profil intégrée + ProfileContent(), + + SizedBox(height: 20), + + // Autres paramètres + Text( + 'Préférences', + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.bold, + color: Colors.grey[600], + ), + ), + SizedBox(height: 8), + ListTile( leading: Icon(Icons.palette), title: Text('Thème'), @@ -28,13 +45,6 @@ class SettingsContent extends StatelessWidget { }, ), - ListTile( - leading: Icon(Icons.person), - title: Text('Profil'), - trailing: Icon(Icons.arrow_forward_ios), - onTap: () {}, - ), - ListTile( leading: Icon(Icons.notifications), title: Text('Notifications'), diff --git a/lib/main.dart b/lib/main.dart index 94559f0..7ff439c 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -5,11 +5,17 @@ import 'package:travel_mate/pages/signup.dart'; import 'pages/login.dart'; import 'pages/home.dart'; import 'providers/theme_provider.dart'; +import 'providers/user_provider.dart'; void main() { runApp( - ChangeNotifierProvider( - create: (context) => ThemeProvider(), + MultiProvider( + providers: [ + ChangeNotifierProvider(create: (context) => ThemeProvider()), + ChangeNotifierProvider( + create: (context) => UserProvider(), + ), // Ajoutez cette ligne + ], child: const MyApp(), ), ); diff --git a/lib/pages/home.dart b/lib/pages/home.dart index 1bfa91d..5d9947f 100644 --- a/lib/pages/home.dart +++ b/lib/pages/home.dart @@ -1,7 +1,9 @@ import 'package:flutter/material.dart'; import '../components/home/home_content.dart'; import '../components/settings/settings_content.dart'; -import '../components/profile/profile_content.dart'; +import '../components/map/map_content.dart'; +import '../components/group/group_content.dart'; +import '../components/count/count_content.dart'; class HomePage extends StatefulWidget { const HomePage({super.key}); @@ -13,21 +15,28 @@ class HomePage extends StatefulWidget { class _HomePageState extends State { int _currentIndex = 0; - // Liste des composants à afficher - final List _pages = [ - HomeContent(), - SettingsContent(), - ProfileContent(), - ]; - - // Titres correspondants - final List _titles = ['Accueil', 'Paramètres', 'Profil']; - @override Widget build(BuildContext context) { + // Définir les pages directement dans le build pour éviter les erreurs + final List pages = [ + HomeContent(), // 0 + SettingsContent(), // 1 + MapContent(), // 2 + GroupContent(), // 3 + CountContent(), // 4 + ]; + + final List titles = [ + 'Accueil', // 0 + 'Paramètres', // 1 + 'Carte', // 2 + 'Mes groupes', // 3 + 'Comptes', // 4 + ]; + return Scaffold( appBar: AppBar( - title: Text(_titles[_currentIndex]), + title: Text(titles[_currentIndex]), // Debug backgroundColor: Theme.of(context).colorScheme.inversePrimary, foregroundColor: Colors.white, ), @@ -49,6 +58,7 @@ class _HomePageState extends State { title: Text("Accueil"), selected: _currentIndex == 0, onTap: () { + print('Clicked Accueil - Setting index to 0'); // Debug setState(() { _currentIndex = 0; }); @@ -60,6 +70,7 @@ class _HomePageState extends State { title: Text("Paramètres"), selected: _currentIndex == 1, onTap: () { + print('Clicked Paramètres - Setting index to 1'); // Debug setState(() { _currentIndex = 1; }); @@ -67,16 +78,41 @@ class _HomePageState extends State { }, ), ListTile( - leading: Icon(Icons.person), - title: Text("Profil"), + leading: Icon(Icons.map), + title: Text("Carte"), selected: _currentIndex == 2, onTap: () { + print('Clicked Carte - Setting index to 2'); // Debug setState(() { _currentIndex = 2; }); Navigator.pop(context); }, ), + ListTile( + leading: Icon(Icons.group), + title: Text("Mes groupes"), + selected: _currentIndex == 3, + onTap: () { + print('Clicked Groupes - Setting index to 3'); // Debug + setState(() { + _currentIndex = 3; + }); + Navigator.pop(context); + }, + ), + ListTile( + leading: Icon(Icons.account_balance_wallet), + title: Text("Comptes"), + selected: _currentIndex == 4, + onTap: () { + print('Clicked Comptes - Setting index to 4'); // Debug + setState(() { + _currentIndex = 4; + }); + Navigator.pop(context); + }, + ), Divider(), ListTile( leading: Icon(Icons.logout, color: Colors.red), @@ -93,7 +129,7 @@ class _HomePageState extends State { ], ), ), - body: _pages[_currentIndex], + body: pages[_currentIndex], ); } } diff --git a/lib/pages/login.dart b/lib/pages/login.dart index e7fc4b0..741bd49 100644 --- a/lib/pages/login.dart +++ b/lib/pages/login.dart @@ -1,6 +1,8 @@ import 'package:flutter/material.dart'; import '../models/user.dart'; import '../services/user_service.dart'; +import 'package:provider/provider.dart'; +import '../providers/user_provider.dart'; class LoginPage extends StatefulWidget { const LoginPage({super.key}); @@ -63,6 +65,7 @@ class _LoginPageState extends State { if (user != null) { // Naviguer vers la page d'accueil + Provider.of(context, listen: false).setCurrentUser(user); Navigator.pushReplacementNamed(context, '/home'); } else { // Échec de la connexion diff --git a/lib/providers/user_provider.dart b/lib/providers/user_provider.dart new file mode 100644 index 0000000..9a8b455 --- /dev/null +++ b/lib/providers/user_provider.dart @@ -0,0 +1,20 @@ +import 'package:flutter/material.dart'; +import '../models/user.dart'; + +class UserProvider extends ChangeNotifier { + User? _currentUser; + + User? get currentUser => _currentUser; + + void setCurrentUser(User user) { + _currentUser = user; + notifyListeners(); + } + + void logout() { + _currentUser = null; + notifyListeners(); + } + + bool get isLoggedIn => _currentUser != null; +}