Modifs MVVM

This commit is contained in:
2025-03-12 17:49:23 +01:00
parent 2b8e7085aa
commit 456d0bb4b8
12 changed files with 287 additions and 401 deletions

View File

@ -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'),
),
],
),
),
),
),
],
),
],
),
),
),
);
},
),
);
}