feat: Add user-specific group retrieval and enhance UI with dynamic theming

This commit is contained in:
Dayron
2025-10-11 20:45:14 +02:00
parent 7f4fd610c5
commit 9eb55c358e
5 changed files with 64 additions and 25 deletions

View File

@@ -22,11 +22,11 @@ class _GroupContentState extends State<GroupContent> {
if (user == null || user.id == null) { if (user == null || user.id == null) {
return const Center( return const Center(
child: Text('Utilisateur non connecté'), child: Text('Utilisateur non connecté'),
); );
} }
return StreamBuilder<List<Group>>( return StreamBuilder<List<Group>>(
stream: GroupService().getGroupsStream(), stream: GroupService().getGroupsStreamByUser(user.id!), // Filtrer par utilisateur
builder: (context, snapshot) { builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) { if (snapshot.connectionState == ConnectionState.waiting) {
return _buildLoadingState(); return _buildLoadingState();
@@ -52,11 +52,11 @@ class _GroupContentState extends State<GroupContent> {
} }
final groups = snapshot.data ?? []; final groups = snapshot.data ?? [];
print("Groupes reçus: ${groups.length}"); print("Groupes reçus pour l'utilisateur ${user.id}: ${groups.length}");
return RefreshIndicator( return RefreshIndicator(
onRefresh: () async { onRefresh: () async {
setState() {}; setState(() {});
}, },
child: SingleChildScrollView( child: SingleChildScrollView(
physics: const AlwaysScrollableScrollPhysics(), physics: const AlwaysScrollableScrollPhysics(),
@@ -74,13 +74,15 @@ class _GroupContentState extends State<GroupContent> {
), ),
const SizedBox(height: 20), const SizedBox(height: 20),
groups.isEmpty ? _buildEmptyState() : _buildGroupList(groups), groups.isEmpty ? _buildEmptyState() : _buildGroupList(groups),
const SizedBox(height: 80),
], ],
), ),
), ),
); );
}, },
); );
}), },
),
); );
} }

View File

@@ -287,12 +287,19 @@ class _CreateTripContentState extends State<CreateTripContent> {
required DateTime? date, required DateTime? date,
required VoidCallback onTap, required VoidCallback onTap,
}) { }) {
// Détecter le thème actuel
final isDarkMode = Theme.of(context).brightness == Brightness.dark;
final textColor = isDarkMode ? Colors.white : Colors.black;
final labelColor = isDarkMode ? Colors.white70 : Colors.grey[600];
final iconColor = isDarkMode ? Colors.white70 : Colors.grey[600];
final placeholderColor = isDarkMode ? Colors.white38 : Colors.grey[500];
return InkWell( return InkWell(
onTap: onTap, onTap: onTap,
child: Container( child: Container(
padding: EdgeInsets.all(16), padding: EdgeInsets.all(16),
decoration: BoxDecoration( decoration: BoxDecoration(
border: Border.all(color: Colors.grey[400]!), border: Border.all(color: isDarkMode ? Colors.white24 : Colors.grey[400]!),
borderRadius: BorderRadius.circular(12), borderRadius: BorderRadius.circular(12),
), ),
child: Column( child: Column(
@@ -300,12 +307,12 @@ class _CreateTripContentState extends State<CreateTripContent> {
children: [ children: [
Text( Text(
label, label,
style: TextStyle(fontSize: 12, color: Colors.grey[600]), style: TextStyle(fontSize: 12, color: labelColor),
), ),
SizedBox(height: 8), SizedBox(height: 8),
Row( Row(
children: [ children: [
Icon(Icons.calendar_today, size: 16, color: Colors.grey[600]), Icon(Icons.calendar_today, size: 16, color: iconColor),
SizedBox(width: 8), SizedBox(width: 8),
Text( Text(
date != null date != null
@@ -313,7 +320,7 @@ class _CreateTripContentState extends State<CreateTripContent> {
: 'Sélectionner', : 'Sélectionner',
style: TextStyle( style: TextStyle(
fontSize: 16, fontSize: 16,
color: date != null ? Colors.black : Colors.grey[500], color: date != null ? textColor : placeholderColor,
), ),
), ),
], ],
@@ -403,25 +410,35 @@ class _CreateTripContentState extends State<CreateTripContent> {
}); });
} }
Future<bool> _saveGroup() async { Future<bool> _saveGroup(String currentUserId) async {
if (!_formKey.currentState!.validate()) { if (!_formKey.currentState!.validate()) {
return false; return false;
} }
setState(() { // Convertir les emails en IDs
_isLoading = true; final participantIds = await _changeUserEmailById(_participants);
});
// Créer la liste des membres incluant le créateur
List<String> allMembers = [currentUserId];
// Ajouter tous les participants (éviter les doublons)
for (String participantId in participantIds) {
if (!allMembers.contains(participantId)) {
allMembers.add(participantId);
}
}
final members = await _changeUserEmailById(_participants); print('Membres du groupe: $allMembers');
final group = Group( final group = Group(
id: '', id: '',
name: _titleController.text.trim(), name: _titleController.text.trim(),
members: members, members: allMembers, // Contient le créateur + tous les participants
); );
final groupService = GroupService(); final groupService = GroupService();
bool success = await groupService.createGroup(group); bool success = await groupService.createGroup(group);
print('Groupe créé avec succès: $success');
return success; return success;
} }
@@ -474,19 +491,21 @@ class _CreateTripContentState extends State<CreateTripContent> {
final userProvider = Provider.of<UserProvider>(context, listen: false); final userProvider = Provider.of<UserProvider>(context, listen: false);
final currentUser = userProvider.currentUser; final currentUser = userProvider.currentUser;
if (currentUser == null) { if (currentUser == null || currentUser.id == null) {
throw Exception('Utilisateur non connecté'); throw Exception('Utilisateur non connecté');
} }
print('Création du voyage par: ${currentUser.id} (${currentUser.email})'); print('Création du voyage par: ${currentUser.id} (${currentUser.email})');
// Convertir les emails en IDs utilisateur // Convertir les emails en IDs utilisateur
List<String> participantIds = []; List<String> participantIds = await _changeUserEmailById(_participants);
if (currentUser.id != null) {
participantIds.add(currentUser.id!); // Ajouter le créateur aux participants s'il n'y est pas déjà
if (!participantIds.contains(currentUser.id!)) {
participantIds.insert(0, currentUser.id!);
} }
participantIds = await _changeUserEmailById(_participants); print('Participants IDs (avec créateur): $participantIds');
// Créer l'objet Trip avec les IDs des participants // Créer l'objet Trip avec les IDs des participants
final trip = Trip( final trip = Trip(
@@ -497,8 +516,8 @@ class _CreateTripContentState extends State<CreateTripContent> {
startDate: _startDate!, startDate: _startDate!,
endDate: _endDate!, endDate: _endDate!,
budget: double.tryParse(_budgetController.text) ?? 0.0, budget: double.tryParse(_budgetController.text) ?? 0.0,
createdBy: currentUser.id ?? '', createdBy: currentUser.id!,
participants: participantIds, // Contient uniquement les IDs participants: participantIds, // Contient le créateur + tous les participants
createdAt: DateTime.now(), createdAt: DateTime.now(),
updatedAt: DateTime.now(), updatedAt: DateTime.now(),
); );
@@ -509,11 +528,11 @@ class _CreateTripContentState extends State<CreateTripContent> {
final tripService = TripService(); final tripService = TripService();
final success = await tripService.addTrip(trip); final success = await tripService.addTrip(trip);
//Créer le groupe associé au voyage // Créer le groupe associé au voyage avec le créateur inclus
final successGroup = await _saveGroup(); final successGroup = await _saveGroup(currentUser.id!);
if (success && successGroup && mounted) { if (success && successGroup && mounted) {
print('Voyage créé avec succès !'); print('Voyage et groupe créés avec succès !');
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(
SnackBar( SnackBar(
content: Text('Voyage créé avec succès !'), content: Text('Voyage créé avec succès !'),

View File

@@ -3,11 +3,13 @@ class Message {
final DateTime timestamp; final DateTime timestamp;
final String senderId; final String senderId;
final String senderName; final String senderName;
final String groupId;
Message({ Message({
required this.text, required this.text,
required this.timestamp, required this.timestamp,
required this.senderId, required this.senderId,
required this.senderName, required this.senderName,
required this.groupId,
}); });
} }

View File

@@ -41,4 +41,20 @@ class GroupService {
return false; return false;
} }
} }
// Stream pour obtenir les groupes d'un utilisateur spécifique
Stream<List<Group>> getGroupsStreamByUser(String userId) {
return _firestore
.collection('groups')
.where('members', arrayContains: userId)
.snapshots()
.map((snapshot) {
print('Groupes trouvés pour l\'utilisateur $userId: ${snapshot.docs.length}');
return snapshot.docs.map((doc) {
final group = Group.fromMap(doc.data(), doc.id);
print('Groupe: ${group.name}, Membres: ${group.members.length}');
return group;
}).toList();
});
}
} }

View File