Add functionality to manage account members: implement add and remove member events, update account repository methods, and integrate with trip details for participant management.
This commit is contained in:
@@ -11,6 +11,9 @@ import 'package:travel_mate/components/map/map_content.dart';
|
||||
import 'package:travel_mate/services/error_service.dart';
|
||||
import 'package:travel_mate/services/activity_cache_service.dart';
|
||||
import 'package:travel_mate/repositories/group_repository.dart';
|
||||
import 'package:travel_mate/repositories/user_repository.dart';
|
||||
import 'package:travel_mate/repositories/account_repository.dart';
|
||||
import 'package:travel_mate/models/group_member.dart';
|
||||
import 'package:travel_mate/components/activities/activities_page.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
|
||||
@@ -26,6 +29,8 @@ class _ShowTripDetailsContentState extends State<ShowTripDetailsContent> {
|
||||
final ErrorService _errorService = ErrorService();
|
||||
final ActivityCacheService _cacheService = ActivityCacheService();
|
||||
final GroupRepository _groupRepository = GroupRepository();
|
||||
final UserRepository _userRepository = UserRepository();
|
||||
final AccountRepository _accountRepository = AccountRepository();
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
@@ -683,6 +688,11 @@ class _ShowTripDetailsContentState extends State<ShowTripDetailsContent> {
|
||||
);
|
||||
},
|
||||
),
|
||||
// Bouton "+" pour ajouter un participant
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(right: 12),
|
||||
child: _buildAddParticipantButton(),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
@@ -738,6 +748,196 @@ class _ShowTripDetailsContentState extends State<ShowTripDetailsContent> {
|
||||
);
|
||||
}
|
||||
|
||||
/// Construire le bouton pour ajouter un participant
|
||||
Widget _buildAddParticipantButton() {
|
||||
final theme = Theme.of(context);
|
||||
|
||||
return Tooltip(
|
||||
message: 'Ajouter un participant',
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
border: Border.all(
|
||||
color: theme.colorScheme.primary.withValues(alpha: 0.3),
|
||||
width: 2,
|
||||
),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.black.withValues(alpha: 0.1),
|
||||
blurRadius: 4,
|
||||
offset: const Offset(0, 2),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: GestureDetector(
|
||||
onTap: _showAddParticipantDialog,
|
||||
child: CircleAvatar(
|
||||
radius: 28,
|
||||
backgroundColor: theme.colorScheme.primary.withValues(alpha: 0.1),
|
||||
child: Icon(
|
||||
Icons.add,
|
||||
color: theme.colorScheme.primary,
|
||||
size: 28,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/// Afficher le dialogue pour ajouter un participant
|
||||
void _showAddParticipantDialog() {
|
||||
final theme = Theme.of(context);
|
||||
final TextEditingController emailController = TextEditingController();
|
||||
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return AlertDialog(
|
||||
backgroundColor: theme.dialogBackgroundColor,
|
||||
title: Text(
|
||||
'Ajouter un participant',
|
||||
style: theme.textTheme.titleLarge?.copyWith(
|
||||
color: theme.colorScheme.onSurface,
|
||||
),
|
||||
),
|
||||
content: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text(
|
||||
'Entrez l\'email du participant à ajouter :',
|
||||
style: theme.textTheme.bodyMedium?.copyWith(
|
||||
color: theme.colorScheme.onSurface,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
TextField(
|
||||
controller: emailController,
|
||||
keyboardType: TextInputType.emailAddress,
|
||||
decoration: InputDecoration(
|
||||
hintText: 'participant@example.com',
|
||||
hintStyle: TextStyle(
|
||||
color: theme.colorScheme.onSurface.withValues(alpha: 0.5),
|
||||
),
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
contentPadding: const EdgeInsets.symmetric(
|
||||
horizontal: 16,
|
||||
vertical: 12,
|
||||
),
|
||||
),
|
||||
style: TextStyle(color: theme.colorScheme.onSurface),
|
||||
),
|
||||
],
|
||||
),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () => Navigator.pop(context),
|
||||
child: Text(
|
||||
'Annuler',
|
||||
style: TextStyle(color: theme.colorScheme.primary),
|
||||
),
|
||||
),
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
if (emailController.text.isNotEmpty) {
|
||||
_addParticipantByEmail(emailController.text);
|
||||
Navigator.pop(context);
|
||||
} else {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(
|
||||
content: Text('Veuillez entrer un email valide'),
|
||||
backgroundColor: Colors.red,
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
child: Text(
|
||||
'Ajouter',
|
||||
style: TextStyle(color: theme.colorScheme.primary),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/// Ajouter un participant par email
|
||||
Future<void> _addParticipantByEmail(String email) async {
|
||||
try {
|
||||
// Chercher l'utilisateur par email
|
||||
final user = await _userRepository.getUserByEmail(email);
|
||||
|
||||
if (user == null) {
|
||||
_errorService.showError(
|
||||
message: 'Utilisateur non trouvé avec cet email',
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (user.id == null) {
|
||||
_errorService.showError(
|
||||
message: 'ID utilisateur invalide',
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// Ajouter l'utilisateur au groupe
|
||||
if (widget.trip.id != null) {
|
||||
final group = await _groupRepository.getGroupByTripId(widget.trip.id!);
|
||||
if (group != null) {
|
||||
// Créer un GroupMember à partir du User
|
||||
final newMember = GroupMember(
|
||||
userId: user.id!,
|
||||
firstName: user.prenom,
|
||||
pseudo: user.prenom,
|
||||
profilePictureUrl: user.profilePictureUrl,
|
||||
);
|
||||
|
||||
// Ajouter le membre au groupe
|
||||
await _groupRepository.addMember(group.id, newMember);
|
||||
|
||||
// Ajouter le membre au compte
|
||||
final account = await _accountRepository.getAccountByTripId(widget.trip.id!);
|
||||
if (account != null) {
|
||||
await _accountRepository.addMemberToAccount(account.id, newMember);
|
||||
}
|
||||
|
||||
// Mettre à jour la liste des participants du voyage
|
||||
final newParticipants = [
|
||||
...widget.trip.participants,
|
||||
user.id!,
|
||||
];
|
||||
final updatedTrip = widget.trip.copyWith(
|
||||
participants: newParticipants,
|
||||
);
|
||||
|
||||
if (mounted) {
|
||||
context.read<TripBloc>().add(
|
||||
TripUpdateRequested(trip: updatedTrip),
|
||||
);
|
||||
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text('${user.prenom} a été ajouté au voyage'),
|
||||
backgroundColor: Colors.green,
|
||||
),
|
||||
);
|
||||
|
||||
// Rafraîchir la page
|
||||
setState(() {});
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
_errorService.showError(
|
||||
message: 'Erreur lors de l\'ajout du participant: $e',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void _navigateToActivities() {
|
||||
Navigator.push(
|
||||
context,
|
||||
|
||||
Reference in New Issue
Block a user