Refactor ActivityCard UI and improve voting functionality
- Updated ActivityCard layout for better visual consistency and responsiveness. - Simplified the category badge and adjusted styles for better readability. - Enhanced the voting section with a progress bar and improved button designs. - Added a new method in Activity model to check if all trip participants approved an activity. - Improved error handling and validation in ActivityRepository for voting and fetching activities. - Implemented pagination in ActivityPlacesService for activity searches. - Removed outdated scripts for cleaning up duplicate images.
This commit is contained in:
267
lib/blocs/activity/db_activities/db_activity_bloc.dart
Normal file
267
lib/blocs/activity/db_activities/db_activity_bloc.dart
Normal file
@@ -0,0 +1,267 @@
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import '../../../models/activity.dart';
|
||||
import '../../../repositories/activity_repository.dart';
|
||||
import '../../../services/error_service.dart';
|
||||
import 'db_activity_event.dart';
|
||||
import 'db_activity_state.dart';
|
||||
|
||||
/// BLoC pour gérer les activités de la base de données
|
||||
class DbActivityBloc extends Bloc<DbActivityEvent, DbActivityState> {
|
||||
final ActivityRepository _repository;
|
||||
final ErrorService _errorService;
|
||||
|
||||
DbActivityBloc({
|
||||
required ActivityRepository repository,
|
||||
required ErrorService errorService,
|
||||
}) : _repository = repository,
|
||||
_errorService = errorService,
|
||||
super(const DbActivityInitial()) {
|
||||
|
||||
on<LoadDbActivities>(_onLoadDbActivities);
|
||||
on<SearchDbActivities>(_onSearchDbActivities);
|
||||
on<AddDbActivity>(_onAddDbActivity);
|
||||
on<AddDbActivitiesBatch>(_onAddDbActivitiesBatch);
|
||||
on<VoteForDbActivity>(_onVoteForDbActivity);
|
||||
on<DeleteDbActivity>(_onDeleteDbActivity);
|
||||
on<FilterDbActivities>(_onFilterDbActivities);
|
||||
on<RefreshDbActivities>(_onRefreshDbActivities);
|
||||
on<UpdateDbActivity>(_onUpdateDbActivity);
|
||||
on<ToggleDbActivityFavorite>(_onToggleDbActivityFavorite);
|
||||
on<ClearDbSearchResults>(_onClearDbSearchResults);
|
||||
}
|
||||
|
||||
/// Charger les activités d'un voyage
|
||||
Future<void> _onLoadDbActivities(
|
||||
LoadDbActivities event,
|
||||
Emitter<DbActivityState> emit,
|
||||
) async {
|
||||
try {
|
||||
emit(const DbActivityLoading());
|
||||
|
||||
final activities = await _repository.getActivitiesByTrip(event.tripId);
|
||||
|
||||
emit(DbActivityLoaded(
|
||||
activities: activities,
|
||||
tripParticipants: event.tripParticipants,
|
||||
));
|
||||
} catch (e) {
|
||||
_errorService.logError('db_activity_bloc', 'Erreur chargement activités DB: $e');
|
||||
emit(const DbActivityError('Impossible de charger les activités du voyage'));
|
||||
}
|
||||
}
|
||||
|
||||
/// Rechercher des activités
|
||||
Future<void> _onSearchDbActivities(
|
||||
SearchDbActivities event,
|
||||
Emitter<DbActivityState> emit,
|
||||
) async {
|
||||
try {
|
||||
emit(const DbActivitySearching());
|
||||
|
||||
// Pour l'instant, on fait une recherche simple en filtrant les activités existantes
|
||||
final allActivities = await _repository.getActivitiesByTrip(event.tripId);
|
||||
final results = allActivities
|
||||
.where((activity) =>
|
||||
activity.name.toLowerCase().contains(event.query.toLowerCase()) ||
|
||||
activity.description.toLowerCase().contains(event.query.toLowerCase()))
|
||||
.toList();
|
||||
|
||||
emit(DbActivitySearchResults(
|
||||
results: results,
|
||||
query: event.query,
|
||||
tripParticipants: event.tripParticipants,
|
||||
));
|
||||
} catch (e) {
|
||||
_errorService.logError('db_activity_bloc', 'Erreur recherche activités: $e');
|
||||
emit(const DbActivityError('Erreur lors de la recherche'));
|
||||
}
|
||||
}
|
||||
|
||||
/// Ajouter une activité
|
||||
Future<void> _onAddDbActivity(
|
||||
AddDbActivity event,
|
||||
Emitter<DbActivityState> emit,
|
||||
) async {
|
||||
try {
|
||||
await _repository.addActivity(event.activity);
|
||||
|
||||
// Recharger les activités si on est dans l'état chargé
|
||||
if (state is DbActivityLoaded) {
|
||||
final currentState = state as DbActivityLoaded;
|
||||
add(LoadDbActivities(
|
||||
tripId: event.activity.tripId,
|
||||
tripParticipants: currentState.tripParticipants,
|
||||
));
|
||||
}
|
||||
|
||||
emit(const DbActivityOperationSuccess('Activité ajoutée avec succès'));
|
||||
} catch (e) {
|
||||
_errorService.logError('db_activity_bloc', 'Erreur ajout activité: $e');
|
||||
emit(const DbActivityError('Impossible d\'ajouter l\'activité'));
|
||||
}
|
||||
}
|
||||
|
||||
/// Ajouter plusieurs activités
|
||||
Future<void> _onAddDbActivitiesBatch(
|
||||
AddDbActivitiesBatch event,
|
||||
Emitter<DbActivityState> emit,
|
||||
) async {
|
||||
try {
|
||||
await _repository.addActivitiesBatch(event.activities);
|
||||
|
||||
// Recharger les activités si on est dans l'état chargé
|
||||
if (state is DbActivityLoaded && event.activities.isNotEmpty) {
|
||||
final currentState = state as DbActivityLoaded;
|
||||
add(LoadDbActivities(
|
||||
tripId: event.activities.first.tripId,
|
||||
tripParticipants: currentState.tripParticipants,
|
||||
));
|
||||
}
|
||||
|
||||
emit(DbActivityOperationSuccess('${event.activities.length} activités ajoutées'));
|
||||
} catch (e) {
|
||||
_errorService.logError('db_activity_bloc', 'Erreur ajout batch: $e');
|
||||
emit(const DbActivityError('Impossible d\'ajouter les activités'));
|
||||
}
|
||||
}
|
||||
|
||||
/// Voter pour une activité
|
||||
Future<void> _onVoteForDbActivity(
|
||||
VoteForDbActivity event,
|
||||
Emitter<DbActivityState> emit,
|
||||
) async {
|
||||
try {
|
||||
await _repository.voteForActivity(
|
||||
event.activityId,
|
||||
event.userId,
|
||||
event.isUpvote ? 1 : -1,
|
||||
);
|
||||
|
||||
// Recharger les activités pour refléter le nouveau vote
|
||||
if (state is DbActivityLoaded) {
|
||||
final currentState = state as DbActivityLoaded;
|
||||
final activity = currentState.activities.firstWhere(
|
||||
(a) => a.id == event.activityId,
|
||||
);
|
||||
add(LoadDbActivities(
|
||||
tripId: activity.tripId,
|
||||
tripParticipants: currentState.tripParticipants,
|
||||
));
|
||||
}
|
||||
|
||||
emit(const DbActivityOperationSuccess('Vote enregistré'));
|
||||
} catch (e) {
|
||||
_errorService.logError('db_activity_bloc', 'Erreur vote: $e');
|
||||
emit(const DbActivityError('Impossible d\'enregistrer le vote'));
|
||||
}
|
||||
}
|
||||
|
||||
/// Supprimer une activité
|
||||
Future<void> _onDeleteDbActivity(
|
||||
DeleteDbActivity event,
|
||||
Emitter<DbActivityState> emit,
|
||||
) async {
|
||||
try {
|
||||
await _repository.deleteActivity(event.activityId);
|
||||
|
||||
// Mettre à jour la liste locale si on est dans l'état chargé
|
||||
if (state is DbActivityLoaded) {
|
||||
final currentState = state as DbActivityLoaded;
|
||||
final updatedActivities = currentState.activities
|
||||
.where((activity) => activity.id != event.activityId)
|
||||
.toList();
|
||||
|
||||
emit(currentState.copyWith(activities: updatedActivities));
|
||||
}
|
||||
|
||||
emit(const DbActivityOperationSuccess('Activité supprimée'));
|
||||
} catch (e) {
|
||||
_errorService.logError('db_activity_bloc', 'Erreur suppression: $e');
|
||||
emit(const DbActivityError('Impossible de supprimer l\'activité'));
|
||||
}
|
||||
}
|
||||
|
||||
/// Filtrer les activités
|
||||
Future<void> _onFilterDbActivities(
|
||||
FilterDbActivities event,
|
||||
Emitter<DbActivityState> emit,
|
||||
) async {
|
||||
if (state is! DbActivityLoaded) return;
|
||||
|
||||
final currentState = state as DbActivityLoaded;
|
||||
List<Activity> filteredActivities = List.from(currentState.activities);
|
||||
|
||||
// Filtrer par catégorie
|
||||
if (event.category != null && event.category!.isNotEmpty) {
|
||||
filteredActivities = filteredActivities
|
||||
.where((activity) => activity.category == event.category)
|
||||
.toList();
|
||||
}
|
||||
|
||||
// Note: isFavorite n'existe pas dans le modèle Activity actuel
|
||||
// if (event.showFavorites == true) {
|
||||
// filteredActivities = filteredActivities
|
||||
// .where((activity) => activity.isFavorite == true)
|
||||
// .toList();
|
||||
// }
|
||||
|
||||
emit(currentState.copyWith(activities: filteredActivities));
|
||||
}
|
||||
|
||||
/// Rafraîchir les activités
|
||||
Future<void> _onRefreshDbActivities(
|
||||
RefreshDbActivities event,
|
||||
Emitter<DbActivityState> emit,
|
||||
) async {
|
||||
add(LoadDbActivities(
|
||||
tripId: event.tripId,
|
||||
tripParticipants: event.tripParticipants,
|
||||
));
|
||||
}
|
||||
|
||||
/// Mettre à jour une activité
|
||||
Future<void> _onUpdateDbActivity(
|
||||
UpdateDbActivity event,
|
||||
Emitter<DbActivityState> emit,
|
||||
) async {
|
||||
try {
|
||||
await _repository.updateActivity(event.activity);
|
||||
|
||||
// Mettre à jour la liste locale
|
||||
if (state is DbActivityLoaded) {
|
||||
final currentState = state as DbActivityLoaded;
|
||||
final updatedActivities = currentState.activities.map((activity) {
|
||||
return activity.id == event.activity.id ? event.activity : activity;
|
||||
}).toList();
|
||||
|
||||
emit(currentState.copyWith(activities: updatedActivities));
|
||||
}
|
||||
|
||||
emit(const DbActivityOperationSuccess('Activité mise à jour'));
|
||||
} catch (e) {
|
||||
_errorService.logError('db_activity_bloc', 'Erreur mise à jour: $e');
|
||||
emit(const DbActivityError('Impossible de mettre à jour l\'activité'));
|
||||
}
|
||||
}
|
||||
|
||||
/// Basculer le favori d'une activité
|
||||
Future<void> _onToggleDbActivityFavorite(
|
||||
ToggleDbActivityFavorite event,
|
||||
Emitter<DbActivityState> emit,
|
||||
) async {
|
||||
// Note: La fonctionnalité favori n'existe pas encore dans le repository
|
||||
// Cette méthode peut être implémentée plus tard
|
||||
emit(const DbActivityError('Fonctionnalité favori non disponible'));
|
||||
}
|
||||
|
||||
/// Effacer les résultats de recherche
|
||||
Future<void> _onClearDbSearchResults(
|
||||
ClearDbSearchResults event,
|
||||
Emitter<DbActivityState> emit,
|
||||
) async {
|
||||
if (state is DbActivitySearchResults) {
|
||||
// Retourner à l'état précédent ou initial
|
||||
emit(const DbActivityInitial());
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user