Modifs MVVM
This commit is contained in:
@ -1,5 +1,5 @@
|
||||
import 'package:em2rp/providers/users_provider.dart';
|
||||
import 'package:em2rp/utils/auth_guard_widget.dart';
|
||||
import 'package:em2rp/view_model/user_management_view_model.dart';
|
||||
import 'package:em2rp/views/calendar_page.dart';
|
||||
import 'package:em2rp/views/login_page.dart';
|
||||
import 'package:firebase_auth/firebase_auth.dart';
|
||||
@ -10,8 +10,7 @@ import 'utils/colors.dart';
|
||||
import 'views/my_account_page.dart';
|
||||
import 'views/user_management_page.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'providers/user_provider.dart';
|
||||
import 'providers/local_auth_provider.dart'; // Ajout de l'AuthProvider
|
||||
import 'providers/local_user_provider.dart';
|
||||
import 'services/user_service.dart';
|
||||
|
||||
void main() async {
|
||||
@ -27,18 +26,13 @@ void main() async {
|
||||
// Injection du service UserService
|
||||
Provider<UserService>(create: (_) => UserService()),
|
||||
|
||||
// AuthProvider pour la gestion de l'authentification
|
||||
ChangeNotifierProvider<LocalAuthProvider>(
|
||||
create: (context) => LocalAuthProvider()),
|
||||
// LocalUserProvider pour la gestion de l'authentification
|
||||
ChangeNotifierProvider<LocalUserProvider>(
|
||||
create: (context) => LocalUserProvider()),
|
||||
|
||||
// UserProvider déjà existant
|
||||
ChangeNotifierProvider<UserProvider>(
|
||||
create: (context) => UserProvider()),
|
||||
|
||||
// Injection des ViewModels en utilisant UserService et AuthProvider
|
||||
ChangeNotifierProvider<UserManagementViewModel>(
|
||||
create: (context) =>
|
||||
UserManagementViewModel(context.read<UserService>()),
|
||||
// // Injection des Providers en utilisant UserService
|
||||
ChangeNotifierProvider<UsersProvider>(
|
||||
create: (context) => UsersProvider(context.read<UserService>()),
|
||||
),
|
||||
],
|
||||
child: const MyApp(),
|
||||
|
@ -41,4 +41,23 @@ class UserModel {
|
||||
'phoneNumber': phoneNumber,
|
||||
};
|
||||
}
|
||||
|
||||
UserModel copyWith({
|
||||
String? firstName,
|
||||
String? lastName,
|
||||
String? role,
|
||||
String? profilePhotoUrl,
|
||||
String? email,
|
||||
String? phoneNumber,
|
||||
}) {
|
||||
return UserModel(
|
||||
uid: uid, // L'UID ne change pas
|
||||
firstName: firstName ?? this.firstName,
|
||||
lastName: lastName ?? this.lastName,
|
||||
role: role ?? this.role,
|
||||
profilePhotoUrl: profilePhotoUrl ?? this.profilePhotoUrl,
|
||||
email: email ?? this.email,
|
||||
phoneNumber: phoneNumber ?? this.phoneNumber,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,46 +0,0 @@
|
||||
import 'package:cloud_firestore/cloud_firestore.dart';
|
||||
import 'package:firebase_auth/firebase_auth.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import '../models/user_model.dart';
|
||||
|
||||
class LocalAuthProvider with ChangeNotifier {
|
||||
UserModel? _currentUser;
|
||||
|
||||
UserModel? get currentUser => _currentUser;
|
||||
String? get role => _currentUser?.role;
|
||||
|
||||
void setUser(UserModel user) {
|
||||
_currentUser = user;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
void clearUser() {
|
||||
_currentUser = null;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
Future<UserCredential> signInWithEmailAndPassword(
|
||||
String email, String password) async {
|
||||
try {
|
||||
UserCredential userCredential = await FirebaseAuth.instance
|
||||
.signInWithEmailAndPassword(email: email, password: password);
|
||||
|
||||
DocumentSnapshot userDoc = await FirebaseFirestore.instance
|
||||
.collection('users')
|
||||
.doc(userCredential.user!.uid)
|
||||
.get();
|
||||
|
||||
if (userDoc.exists) {
|
||||
setUser(UserModel.fromMap(
|
||||
userDoc.data() as Map<String, dynamic>, userDoc.id));
|
||||
} else {
|
||||
throw FirebaseAuthException(
|
||||
code: 'user-not-found',
|
||||
message: "Aucune donnée utilisateur trouvée.");
|
||||
}
|
||||
return userCredential;
|
||||
} on FirebaseAuthException catch (e) {
|
||||
throw FirebaseAuthException(code: e.code, message: e.message);
|
||||
}
|
||||
}
|
||||
}
|
108
em2rp/lib/providers/local_user_provider.dart
Normal file
108
em2rp/lib/providers/local_user_provider.dart
Normal file
@ -0,0 +1,108 @@
|
||||
import 'package:cloud_firestore/cloud_firestore.dart';
|
||||
import 'package:firebase_auth/firebase_auth.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:image_picker/image_picker.dart';
|
||||
import '../models/user_model.dart';
|
||||
import '../utils/firebase_storage_manager.dart';
|
||||
|
||||
class LocalUserProvider with ChangeNotifier {
|
||||
UserModel? _currentUser;
|
||||
final FirebaseAuth _auth = FirebaseAuth.instance;
|
||||
final FirebaseFirestore _firestore = FirebaseFirestore.instance;
|
||||
final FirebaseStorageManager _storageManager = FirebaseStorageManager();
|
||||
|
||||
UserModel? get currentUser => _currentUser;
|
||||
String? get uid => _currentUser?.uid;
|
||||
String? get firstName => _currentUser?.firstName;
|
||||
String? get lastName => _currentUser?.lastName;
|
||||
String? get role => _currentUser?.role ?? 'USER';
|
||||
String? get profilePhotoUrl => _currentUser?.profilePhotoUrl;
|
||||
String? get email => _currentUser?.email;
|
||||
String? get phoneNumber => _currentUser?.phoneNumber;
|
||||
|
||||
/// Charge les données de l'utilisateur actuel
|
||||
Future<void> loadUserData() async {
|
||||
if (_auth.currentUser == null) return;
|
||||
DocumentSnapshot userDoc =
|
||||
await _firestore.collection('users').doc(_auth.currentUser!.uid).get();
|
||||
if (userDoc.exists) {
|
||||
setUser(UserModel.fromMap(
|
||||
userDoc.data() as Map<String, dynamic>, userDoc.id));
|
||||
}
|
||||
}
|
||||
|
||||
/// Met à jour l'utilisateur
|
||||
void setUser(UserModel user) {
|
||||
_currentUser = user;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
/// Efface les données utilisateur
|
||||
void clearUser() {
|
||||
_currentUser = null;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
/// Mise à jour des informations utilisateur
|
||||
Future<void> updateUserData(
|
||||
{String? firstName, String? lastName, String? phoneNumber}) async {
|
||||
if (_currentUser == null) return;
|
||||
try {
|
||||
await _firestore.collection('users').doc(_currentUser!.uid).set({
|
||||
'firstName': firstName ?? _currentUser!.firstName,
|
||||
'lastName': lastName ?? _currentUser!.lastName,
|
||||
'phone': phoneNumber ?? _currentUser!.phoneNumber,
|
||||
}, SetOptions(merge: true));
|
||||
|
||||
_currentUser = _currentUser!.copyWith(
|
||||
firstName: firstName ?? _currentUser!.firstName,
|
||||
lastName: lastName ?? _currentUser!.lastName,
|
||||
phoneNumber: phoneNumber ?? _currentUser!.phoneNumber,
|
||||
);
|
||||
notifyListeners();
|
||||
} catch (e) {
|
||||
debugPrint('Erreur mise à jour utilisateur : $e');
|
||||
}
|
||||
}
|
||||
|
||||
/// Changement de photo de profil
|
||||
Future<void> changeProfilePicture(XFile image) async {
|
||||
if (_currentUser == null) return;
|
||||
try {
|
||||
String? newProfilePhotoUrl = await _storageManager.sendProfilePicture(
|
||||
imageFile: image,
|
||||
uid: _currentUser!.uid,
|
||||
);
|
||||
if (newProfilePhotoUrl != null) {
|
||||
_firestore
|
||||
.collection('users')
|
||||
.doc(_currentUser!.uid)
|
||||
.update({'profilePhotoUrl': newProfilePhotoUrl});
|
||||
_currentUser =
|
||||
_currentUser!.copyWith(profilePhotoUrl: newProfilePhotoUrl);
|
||||
notifyListeners();
|
||||
}
|
||||
} catch (e) {
|
||||
debugPrint('Erreur mise à jour photo de profil : $e');
|
||||
}
|
||||
}
|
||||
|
||||
/// Connexion
|
||||
Future<UserCredential> signInWithEmailAndPassword(
|
||||
String email, String password) async {
|
||||
try {
|
||||
UserCredential userCredential = await _auth.signInWithEmailAndPassword(
|
||||
email: email, password: password);
|
||||
await loadUserData();
|
||||
return userCredential;
|
||||
} catch (e) {
|
||||
throw FirebaseAuthException(code: 'login-failed', message: e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
/// Déconnexion
|
||||
Future<void> signOut() async {
|
||||
await _auth.signOut();
|
||||
clearUser();
|
||||
}
|
||||
}
|
@ -1,58 +0,0 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class UserProvider extends ChangeNotifier {
|
||||
String? _uid;
|
||||
String? _firstName;
|
||||
String? _lastName;
|
||||
String? _role;
|
||||
String? _profilePictureUrl;
|
||||
String? _email;
|
||||
String? _phoneNumber;
|
||||
|
||||
String? get uid => _uid;
|
||||
String? get firstName => _firstName;
|
||||
String? get lastName => _lastName;
|
||||
String? get role => _role;
|
||||
String? get profilePhotoUrl => _profilePictureUrl;
|
||||
String? get email => _email;
|
||||
String? get phoneNumber => _phoneNumber;
|
||||
|
||||
void setUserData(Map<String, dynamic> userData, String uid) {
|
||||
_uid = uid;
|
||||
_firstName = userData['firstName'];
|
||||
_lastName = userData['lastName'];
|
||||
_role = userData['role'] ?? 'USER';
|
||||
if (userData['profilePhotoUrl'] != "") {
|
||||
_profilePictureUrl = userData['profilePhotoUrl'];
|
||||
}
|
||||
_email = userData['email'];
|
||||
_phoneNumber = userData['phoneNumber'];
|
||||
notifyListeners(); // Notify listeners that state has changed
|
||||
}
|
||||
|
||||
void clearUserData() {
|
||||
_uid = null;
|
||||
_firstName = null;
|
||||
_lastName = null;
|
||||
_role = null;
|
||||
_profilePictureUrl = null;
|
||||
_email = null;
|
||||
_phoneNumber = null;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
void setUserFirstName(String text) {
|
||||
_firstName = text;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
void setUserLastName(String text) {
|
||||
_lastName = text;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
void setUserPhoneNumber(String text) {
|
||||
_phoneNumber = text;
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
@ -1,8 +1,9 @@
|
||||
import 'package:cloud_firestore/cloud_firestore.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import '../models/user_model.dart';
|
||||
import '../services/user_service.dart';
|
||||
|
||||
class UserManagementViewModel extends ChangeNotifier {
|
||||
class UsersProvider with ChangeNotifier {
|
||||
final UserService _userService;
|
||||
List<UserModel> _users = [];
|
||||
bool _isLoading = false;
|
||||
@ -10,28 +11,33 @@ class UserManagementViewModel extends ChangeNotifier {
|
||||
List<UserModel> get users => _users;
|
||||
bool get isLoading => _isLoading;
|
||||
|
||||
UserManagementViewModel(this._userService);
|
||||
UsersProvider(this._userService);
|
||||
|
||||
/// Récupération de tous les utilisateurs
|
||||
Future<void> fetchUsers() async {
|
||||
_isLoading = true;
|
||||
notifyListeners();
|
||||
|
||||
_users = await _userService.fetchUsers();
|
||||
|
||||
_isLoading = false;
|
||||
notifyListeners();
|
||||
try {
|
||||
_users = await _userService.fetchUsers();
|
||||
} finally {
|
||||
_isLoading = false;
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
|
||||
/// Mise à jour d'un utilisateur
|
||||
Future<void> updateUser(UserModel user) async {
|
||||
await _userService.updateUser(user);
|
||||
fetchUsers();
|
||||
await fetchUsers();
|
||||
}
|
||||
|
||||
/// Suppression d'un utilisateur
|
||||
Future<void> deleteUser(String uid) async {
|
||||
await _userService.deleteUser(uid);
|
||||
fetchUsers();
|
||||
await fetchUsers();
|
||||
}
|
||||
|
||||
/// Réinitialisation du mot de passe
|
||||
Future<void> resetPassword(String email) async {
|
||||
await _userService.resetPassword(email);
|
||||
}
|
@ -1,7 +1,6 @@
|
||||
import 'package:em2rp/providers/local_auth_provider.dart';
|
||||
import 'package:em2rp/providers/local_user_provider.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:em2rp/providers/user_provider.dart';
|
||||
import 'package:em2rp/views/login_page.dart';
|
||||
|
||||
class AuthGuard extends StatelessWidget {
|
||||
@ -17,7 +16,7 @@ class AuthGuard extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final localAuthProvider = Provider.of<LocalAuthProvider>(context);
|
||||
final localAuthProvider = Provider.of<LocalUserProvider>(context);
|
||||
|
||||
// Si l'utilisateur n'est pas connecté
|
||||
if (localAuthProvider.currentUser == null) {
|
||||
|
@ -1,6 +1,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:firebase_auth/firebase_auth.dart';
|
||||
import '../providers/local_auth_provider.dart';
|
||||
import '../providers/local_user_provider.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class LoginViewModel extends ChangeNotifier {
|
||||
@ -19,7 +19,7 @@ class LoginViewModel extends ChangeNotifier {
|
||||
|
||||
Future<void> signIn(BuildContext context) async {
|
||||
final localAuthProvider =
|
||||
Provider.of<LocalAuthProvider>(context, listen: false);
|
||||
Provider.of<LocalUserProvider>(context, listen: false);
|
||||
isLoading = true;
|
||||
errorMessage = '';
|
||||
highlightPasswordField = false;
|
||||
|
@ -1,8 +1,7 @@
|
||||
import 'package:em2rp/providers/local_auth_provider.dart';
|
||||
import 'package:em2rp/providers/local_user_provider.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:em2rp/views/widgets/nav/main_drawer.dart';
|
||||
import 'package:provider/provider.dart'; // Import Provider
|
||||
import 'package:em2rp/providers/user_provider.dart'; // Import UserProvider
|
||||
import 'package:em2rp/utils/colors.dart';
|
||||
|
||||
class CalendarPage extends StatelessWidget {
|
||||
@ -10,7 +9,7 @@ class CalendarPage extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final localAuthProvider = Provider.of<LocalAuthProvider>(context);
|
||||
final localAuthProvider = Provider.of<LocalUserProvider>(context);
|
||||
|
||||
return Scaffold(
|
||||
appBar: AppBar(title: const Text('Calendrier')),
|
||||
|
@ -1,240 +1,106 @@
|
||||
import 'package:em2rp/providers/local_auth_provider.dart';
|
||||
import 'package:em2rp/providers/user_provider.dart';
|
||||
import 'package:em2rp/utils/firebase_storage_manager.dart';
|
||||
import 'package:em2rp/providers/local_user_provider.dart';
|
||||
import 'package:em2rp/providers/users_provider.dart';
|
||||
import 'package:em2rp/views/widgets/image/profile_picture.dart';
|
||||
import 'package:em2rp/views/widgets/nav/main_drawer.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:firebase_auth/firebase_auth.dart';
|
||||
import 'package:cloud_firestore/cloud_firestore.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:image_picker/image_picker.dart';
|
||||
import 'package:em2rp/views/widgets/inputs/styled_text_field.dart';
|
||||
|
||||
class MyAccountPage extends StatefulWidget {
|
||||
class MyAccountPage extends StatelessWidget {
|
||||
const MyAccountPage({super.key});
|
||||
@override
|
||||
_MyAccountPageState createState() => _MyAccountPageState();
|
||||
}
|
||||
|
||||
class _MyAccountPageState extends State<MyAccountPage> {
|
||||
final User? user = FirebaseAuth.instance.currentUser;
|
||||
final TextEditingController _firstNameController = TextEditingController();
|
||||
final TextEditingController _lastNameController = TextEditingController();
|
||||
final TextEditingController _phoneController = TextEditingController();
|
||||
String? profilePhotoUrl;
|
||||
bool _isHoveringProfilePic = false;
|
||||
final FirebaseStorageManager _storageManager =
|
||||
FirebaseStorageManager(); // Instance of FirebaseStorageManager
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_loadUserData();
|
||||
}
|
||||
|
||||
Future<void> _loadUserData() async {
|
||||
if (user != null) {
|
||||
DocumentSnapshot userData = await FirebaseFirestore.instance
|
||||
.collection('users')
|
||||
.doc(user!.uid)
|
||||
.get();
|
||||
|
||||
if (userData.exists) {
|
||||
if (!mounted) return;
|
||||
setState(() {
|
||||
_firstNameController.text = userData['firstName'] ?? '';
|
||||
_lastNameController.text = userData['lastName'] ?? '';
|
||||
_phoneController.text = userData['phone'] ?? '';
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _updateUserData() async {
|
||||
if (user != null) {
|
||||
try {
|
||||
await FirebaseFirestore.instance.collection('users').doc(user!.uid).set(
|
||||
{
|
||||
'firstName': _firstNameController.text,
|
||||
'lastName': _lastNameController.text,
|
||||
'phone': _phoneController.text,
|
||||
},
|
||||
SetOptions(merge: true),
|
||||
);
|
||||
|
||||
// **MISE À JOUR DU USERPROVIDER APRÈS SUCCÈS**
|
||||
final userProvider = Provider.of<UserProvider>(context, listen: false);
|
||||
userProvider.setUserFirstName(_firstNameController.text);
|
||||
userProvider.setUserLastName(_lastNameController.text);
|
||||
userProvider.setUserPhoneNumber(_phoneController.text);
|
||||
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(
|
||||
content:
|
||||
Text('Informations personnelles mises à jour avec succès!'),
|
||||
backgroundColor: Colors.green,
|
||||
),
|
||||
);
|
||||
} catch (e) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(
|
||||
'Erreur lors de la mise à jour des informations personnelles: ${e.toString()}',
|
||||
),
|
||||
backgroundColor: Colors.red,
|
||||
),
|
||||
);
|
||||
print(
|
||||
'Erreur lors de la mise à jour des informations utilisateur: ${e.toString()}');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _changeProfilePicture() async {
|
||||
final ImagePicker picker = ImagePicker();
|
||||
final XFile? image = await picker.pickImage(
|
||||
source: ImageSource.gallery,
|
||||
); // You can also use ImageSource.camera
|
||||
|
||||
if (image != null) {
|
||||
// Call FirebaseStorageManager to send the profile picture
|
||||
String? newProfilePhotoUrl = await _storageManager.sendProfilePicture(
|
||||
imageFile: image,
|
||||
uid: user!.uid,
|
||||
);
|
||||
if (newProfilePhotoUrl != null) {
|
||||
if (!mounted) return;
|
||||
setState(() {
|
||||
profilePhotoUrl =
|
||||
newProfilePhotoUrl; // Update the profilePhotoUrl to refresh the UI
|
||||
});
|
||||
// Optionally, update the UserProvider if you are using it to manage user data globally
|
||||
// Provider.of<UserProvider>(context, listen: false).setUserProfilePhotoUrl(newProfilePhotoUrl);
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(
|
||||
content: Text('Photo de profil mise à jour avec succès!'),
|
||||
backgroundColor: Colors.green, // Optional: Style for success
|
||||
),
|
||||
);
|
||||
} else {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(
|
||||
content: Text(
|
||||
'Erreur lors de la mise à jour de la photo de profil.',
|
||||
),
|
||||
backgroundColor: Colors.red, // Optional: Style for error
|
||||
),
|
||||
);
|
||||
}
|
||||
} else {
|
||||
// User cancelled image picking
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(content: Text('Sélection de photo annulée.')),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final localAuthProvider = Provider.of<LocalAuthProvider>(
|
||||
context,
|
||||
); // Get UserProvider instance
|
||||
|
||||
return Scaffold(
|
||||
appBar:
|
||||
AppBar(title: const Text('Mon Compte')), // More user-friendly title
|
||||
drawer: MainDrawer(
|
||||
currentPage: '/my_account'), // Pass UserProvider to MainDrawer
|
||||
body: SingleChildScrollView(
|
||||
// Added SingleChildScrollView for better responsiveness
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(
|
||||
24.0), // Increased padding around the main content
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
MouseRegion(
|
||||
onEnter: (_) => setState(() => _isHoveringProfilePic = true),
|
||||
onExit: (_) => setState(() => _isHoveringProfilePic = false),
|
||||
cursor: SystemMouseCursors.click,
|
||||
child: GestureDetector(
|
||||
onTap:
|
||||
_changeProfilePicture, // Call _changeProfilePicture on tap
|
||||
child: Stack(
|
||||
alignment: Alignment.center,
|
||||
children: [
|
||||
ProfilePictureWidget(
|
||||
userId: user!.uid,
|
||||
radius:
|
||||
80), // Increased radius for larger profile picture
|
||||
if (_isHoveringProfilePic)
|
||||
Container(
|
||||
width: 160, // Slightly larger hover overlay
|
||||
height: 160,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.black54,
|
||||
shape: BoxShape.circle,
|
||||
),
|
||||
child: const Center(
|
||||
child: Icon(
|
||||
Icons.edit,
|
||||
color: Colors.white,
|
||||
size: 36, // Slightly larger edit icon
|
||||
),
|
||||
appBar: AppBar(title: const Text('Mon Compte')),
|
||||
drawer: MainDrawer(currentPage: '/my_account'),
|
||||
body: Consumer<LocalUserProvider>(
|
||||
builder: (context, userProvider, child) {
|
||||
final user = userProvider.currentUser;
|
||||
final usersProvider = context.read<UsersProvider>();
|
||||
|
||||
if (user == null) {
|
||||
return const Center(child: CircularProgressIndicator());
|
||||
}
|
||||
|
||||
final firstNameController =
|
||||
TextEditingController(text: user.firstName);
|
||||
final lastNameController = TextEditingController(text: user.lastName);
|
||||
final phoneController = TextEditingController(text: user.phoneNumber);
|
||||
|
||||
return SingleChildScrollView(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(24.0),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
GestureDetector(
|
||||
//onTap: () => userProvider.changeProfilePicture(); TODO
|
||||
child: Stack(
|
||||
alignment: Alignment.center,
|
||||
children: [
|
||||
ProfilePictureWidget(
|
||||
userId: user.uid,
|
||||
radius: 80,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Center(
|
||||
child: Card(
|
||||
elevation: 4.0,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(12.0),
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(24.0),
|
||||
child: ConstrainedBox(
|
||||
constraints: const BoxConstraints(maxWidth: 500),
|
||||
child: Column(
|
||||
children: [
|
||||
StyledTextField(
|
||||
labelText: 'Prénom',
|
||||
controller: firstNameController,
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
StyledTextField(
|
||||
labelText: 'Nom',
|
||||
controller: lastNameController,
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
StyledTextField(
|
||||
labelText: 'Numéro de téléphone',
|
||||
controller: phoneController,
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
StyledTextField(
|
||||
labelText: 'Email',
|
||||
controller:
|
||||
TextEditingController(text: user.email),
|
||||
enabled: false,
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
ElevatedButton(
|
||||
onPressed: () {
|
||||
userProvider.updateUserData(
|
||||
firstName: firstNameController.text,
|
||||
lastName: lastNameController.text,
|
||||
phoneNumber: phoneController.text,
|
||||
);
|
||||
},
|
||||
child: const Text('Enregistrer'),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
Center(
|
||||
child: Card(
|
||||
elevation: 4.0, // Ajouter un léger relief
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius:
|
||||
BorderRadius.circular(12.0)), // Bords arrondis
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(
|
||||
24.0), // Padding intérieur de la carte
|
||||
child: ConstrainedBox(
|
||||
// Limiter la largeur des inputs dans la carte
|
||||
constraints: BoxConstraints(
|
||||
maxWidth:
|
||||
500), // Ajustez la largeur maximale souhaitée
|
||||
child: Column(
|
||||
children: [
|
||||
StyledTextField(
|
||||
labelText: 'Prénom',
|
||||
controller: _firstNameController),
|
||||
const SizedBox(height: 16),
|
||||
StyledTextField(
|
||||
labelText: 'Nom',
|
||||
controller: _lastNameController),
|
||||
const SizedBox(height: 16),
|
||||
StyledTextField(
|
||||
labelText: 'Numéro de téléphone',
|
||||
controller: _phoneController),
|
||||
const SizedBox(height: 16),
|
||||
StyledTextField(
|
||||
labelText: 'Email',
|
||||
controller:
|
||||
TextEditingController(text: user?.email ?? ''),
|
||||
enabled: false,
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
ElevatedButton(
|
||||
onPressed: _updateUserData,
|
||||
child: const Text('Enregistrer'),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
@ -1,15 +1,14 @@
|
||||
import 'package:em2rp/providers/local_auth_provider.dart';
|
||||
import 'package:em2rp/providers/local_user_provider.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import '../view_model/user_management_view_model.dart';
|
||||
|
||||
class UserManagementPage extends StatelessWidget {
|
||||
const UserManagementPage({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final userViewModel = Provider.of<UserManagementViewModel>(context);
|
||||
final authProvider = Provider.of<LocalAuthProvider>(context);
|
||||
// final userViewModel = Provider.of<UserManagementViewModel>(context);
|
||||
final authProvider = Provider.of<LocalUserProvider>(context);
|
||||
|
||||
if (authProvider.role != 'ADMIN') {
|
||||
return Scaffold(
|
||||
@ -22,46 +21,46 @@ class UserManagementPage extends StatelessWidget {
|
||||
|
||||
return Scaffold(
|
||||
appBar: AppBar(title: const Text('Gestion des Utilisateurs')),
|
||||
body: userViewModel.isLoading
|
||||
? const Center(child: CircularProgressIndicator())
|
||||
: ListView.builder(
|
||||
itemCount: userViewModel.users.length,
|
||||
itemBuilder: (context, index) {
|
||||
final user = userViewModel.users[index];
|
||||
return ListTile(
|
||||
leading: CircleAvatar(
|
||||
backgroundImage: NetworkImage(user.profilePhotoUrl)),
|
||||
title: Text('${user.firstName} ${user.lastName}'),
|
||||
subtitle: Text(user.email),
|
||||
trailing: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
IconButton(
|
||||
icon: const Icon(Icons.edit),
|
||||
onPressed: () {
|
||||
// Afficher la pop-up d'édition
|
||||
},
|
||||
),
|
||||
IconButton(
|
||||
icon: const Icon(Icons.lock_reset),
|
||||
onPressed: () =>
|
||||
userViewModel.resetPassword(user.email),
|
||||
),
|
||||
IconButton(
|
||||
icon: const Icon(Icons.delete, color: Colors.red),
|
||||
onPressed: () => userViewModel.deleteUser(user.uid),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
floatingActionButton: FloatingActionButton(
|
||||
onPressed: () {
|
||||
// Ajouter un utilisateur
|
||||
},
|
||||
child: const Icon(Icons.add),
|
||||
),
|
||||
// body: userViewModel.isLoading
|
||||
// ? const Center(child: CircularProgressIndicator())
|
||||
// : ListView.builder(
|
||||
// itemCount: userViewModel.users.length,
|
||||
// itemBuilder: (context, index) {
|
||||
// final user = userViewModel.users[index];
|
||||
// return ListTile(
|
||||
// leading: CircleAvatar(
|
||||
// backgroundImage: NetworkImage(user.profilePhotoUrl)),
|
||||
// title: Text('${user.firstName} ${user.lastName}'),
|
||||
// subtitle: Text(user.email),
|
||||
// trailing: Row(
|
||||
// mainAxisSize: MainAxisSize.min,
|
||||
// children: [
|
||||
// IconButton(
|
||||
// icon: const Icon(Icons.edit),
|
||||
// onPressed: () {
|
||||
// // Afficher la pop-up d'édition
|
||||
// },
|
||||
// ),
|
||||
// IconButton(
|
||||
// icon: const Icon(Icons.lock_reset),
|
||||
// onPressed: () =>
|
||||
// userViewModel.resetPassword(user.email),
|
||||
// ),
|
||||
// IconButton(
|
||||
// icon: const Icon(Icons.delete, color: Colors.red),
|
||||
// onPressed: () => userViewModel.deleteUser(user.uid),
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// );
|
||||
// },
|
||||
// ),
|
||||
// floatingActionButton: FloatingActionButton(
|
||||
// onPressed: () {
|
||||
// // Ajouter un utilisateur
|
||||
// },
|
||||
// child: const Icon(Icons.add),
|
||||
// ),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
import 'package:em2rp/providers/local_auth_provider.dart';
|
||||
import 'package:em2rp/providers/local_user_provider.dart';
|
||||
import 'package:em2rp/utils/colors.dart';
|
||||
import 'package:em2rp/views/calendar_page.dart';
|
||||
import 'package:em2rp/views/my_account_page.dart';
|
||||
@ -14,7 +14,7 @@ class MainDrawer extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Consumer<LocalAuthProvider>(
|
||||
return Consumer<LocalUserProvider>(
|
||||
builder: (context, userProvider, child) {
|
||||
final hasUser = userProvider.currentUser != null;
|
||||
|
||||
|
Reference in New Issue
Block a user