feat: Add user-specific group retrieval and enhance UI with dynamic theming
This commit is contained in:
@@ -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),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}),
|
},
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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 !'),
|
||||||
|
|||||||
@@ -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,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -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();
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
0
lib/services/message_service.dart
Normal file
0
lib/services/message_service.dart
Normal file
Reference in New Issue
Block a user