Files
unionflow-mobile-apps/unionflow-mobile-apps/lib/features/members/presentation/bloc/membres_bloc.dart
2025-09-12 03:15:21 +00:00

245 lines
6.9 KiB
Dart

import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:injectable/injectable.dart';
import '../../domain/repositories/membre_repository.dart';
import '../../../../core/errors/failures.dart';
import '../../../../core/models/membre_model.dart';
import 'membres_event.dart';
import 'membres_state.dart';
/// BLoC pour la gestion des membres
@injectable
class MembresBloc extends Bloc<MembresEvent, MembresState> {
final MembreRepository _membreRepository;
MembresBloc(this._membreRepository) : super(const MembresInitial()) {
// Enregistrement des handlers d'événements
on<LoadMembres>(_onLoadMembres);
on<RefreshMembres>(_onRefreshMembres);
on<SearchMembres>(_onSearchMembres);
on<LoadMembreById>(_onLoadMembreById);
on<CreateMembre>(_onCreateMembre);
on<UpdateMembre>(_onUpdateMembre);
on<DeleteMembre>(_onDeleteMembre);
on<LoadMembresStats>(_onLoadMembresStats);
on<ClearMembresError>(_onClearMembresError);
on<ResetMembresState>(_onResetMembresState);
}
/// Handler pour charger la liste des membres
Future<void> _onLoadMembres(
LoadMembres event,
Emitter<MembresState> emit,
) async {
emit(const MembresLoading());
try {
final membres = await _membreRepository.getMembres();
emit(MembresLoaded(membres: membres));
} catch (e) {
final failure = _mapExceptionToFailure(e);
emit(MembresError(failure: failure));
}
}
/// Handler pour rafraîchir la liste des membres
Future<void> _onRefreshMembres(
RefreshMembres event,
Emitter<MembresState> emit,
) async {
// Conserver les données actuelles pendant le refresh
final currentState = state;
List<MembreModel> currentMembres = [];
if (currentState is MembresLoaded) {
currentMembres = currentState.membres;
emit(MembresRefreshing(currentMembres));
} else {
emit(const MembresLoading());
}
try {
final membres = await _membreRepository.getMembres();
emit(MembresLoaded(membres: membres));
} catch (e) {
final failure = _mapExceptionToFailure(e);
// Si on avait des données, les conserver avec l'erreur
if (currentMembres.isNotEmpty) {
emit(MembresErrorWithData(
failure: failure,
membres: currentMembres,
));
} else {
emit(MembresError(failure: failure));
}
}
}
/// Handler pour rechercher des membres
Future<void> _onSearchMembres(
SearchMembres event,
Emitter<MembresState> emit,
) async {
if (event.query.trim().isEmpty) {
// Si la recherche est vide, recharger tous les membres
add(const LoadMembres());
return;
}
emit(const MembresLoading());
try {
final membres = await _membreRepository.searchMembres(event.query);
emit(MembresLoaded(
membres: membres,
isSearchResult: true,
searchQuery: event.query,
));
} catch (e) {
final failure = _mapExceptionToFailure(e);
emit(MembresError(failure: failure));
}
}
/// Handler pour charger un membre par ID
Future<void> _onLoadMembreById(
LoadMembreById event,
Emitter<MembresState> emit,
) async {
emit(const MembresLoading());
try {
final membre = await _membreRepository.getMembreById(event.id);
emit(MembreDetailLoaded(membre));
} catch (e) {
final failure = _mapExceptionToFailure(e);
emit(MembresError(failure: failure));
}
}
/// Handler pour créer un membre
Future<void> _onCreateMembre(
CreateMembre event,
Emitter<MembresState> emit,
) async {
emit(const MembresLoading());
try {
final nouveauMembre = await _membreRepository.createMembre(event.membre);
emit(MembreCreated(nouveauMembre));
// Recharger la liste après création
add(const LoadMembres());
} catch (e) {
final failure = _mapExceptionToFailure(e);
emit(MembresError(failure: failure));
}
}
/// Handler pour mettre à jour un membre
Future<void> _onUpdateMembre(
UpdateMembre event,
Emitter<MembresState> emit,
) async {
emit(const MembresLoading());
try {
final membreMisAJour = await _membreRepository.updateMembre(
event.id,
event.membre,
);
emit(MembreUpdated(membreMisAJour));
// Recharger la liste après mise à jour
add(const LoadMembres());
} catch (e) {
final failure = _mapExceptionToFailure(e);
emit(MembresError(failure: failure));
}
}
/// Handler pour supprimer un membre
Future<void> _onDeleteMembre(
DeleteMembre event,
Emitter<MembresState> emit,
) async {
emit(const MembresLoading());
try {
await _membreRepository.deleteMembre(event.id);
emit(MembreDeleted(event.id));
// Recharger la liste après suppression
add(const LoadMembres());
} catch (e) {
final failure = _mapExceptionToFailure(e);
emit(MembresError(failure: failure));
}
}
/// Handler pour charger les statistiques
Future<void> _onLoadMembresStats(
LoadMembresStats event,
Emitter<MembresState> emit,
) async {
emit(const MembresLoading());
try {
final stats = await _membreRepository.getMembresStats();
emit(MembresStatsLoaded(stats));
} catch (e) {
final failure = _mapExceptionToFailure(e);
emit(MembresError(failure: failure));
}
}
/// Handler pour effacer les erreurs
void _onClearMembresError(
ClearMembresError event,
Emitter<MembresState> emit,
) {
final currentState = state;
if (currentState is MembresError && currentState.previousState != null) {
emit(currentState.previousState!);
} else if (currentState is MembresErrorWithData) {
emit(MembresLoaded(
membres: currentState.membres,
isSearchResult: currentState.isSearchResult,
searchQuery: currentState.searchQuery,
));
} else {
emit(const MembresInitial());
}
}
/// Handler pour réinitialiser l'état
void _onResetMembresState(
ResetMembresState event,
Emitter<MembresState> emit,
) {
emit(const MembresInitial());
}
/// Convertit une exception en Failure approprié
Failure _mapExceptionToFailure(dynamic exception) {
if (exception is Failure) {
return exception;
}
final message = exception.toString();
if (message.contains('connexion') || message.contains('network')) {
return NetworkFailure(message: message);
} else if (message.contains('401') || message.contains('unauthorized')) {
return const AuthFailure(message: 'Session expirée. Veuillez vous reconnecter.');
} else if (message.contains('400') || message.contains('validation')) {
return ValidationFailure(message: message);
} else if (message.contains('500') || message.contains('server')) {
return ServerFailure(message: message);
}
return ServerFailure(message: message);
}
}