242 lines
9.0 KiB
Dart
242 lines
9.0 KiB
Dart
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/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 {
|
|
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
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
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'),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|