Clean project: remove test files, debug logs, and add documentation
This commit is contained in:
@@ -0,0 +1,488 @@
|
||||
/// BLoC pour la gestion des organisations
|
||||
library organisations_bloc;
|
||||
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import '../data/models/organisation_model.dart';
|
||||
import '../data/services/organisation_service.dart';
|
||||
import 'organisations_event.dart';
|
||||
import 'organisations_state.dart';
|
||||
|
||||
/// BLoC principal pour la gestion des organisations
|
||||
class OrganisationsBloc extends Bloc<OrganisationsEvent, OrganisationsState> {
|
||||
final OrganisationService _organisationService;
|
||||
|
||||
OrganisationsBloc(this._organisationService) : super(const OrganisationsInitial()) {
|
||||
// Enregistrement des handlers d'événements
|
||||
on<LoadOrganisations>(_onLoadOrganisations);
|
||||
on<LoadMoreOrganisations>(_onLoadMoreOrganisations);
|
||||
on<SearchOrganisations>(_onSearchOrganisations);
|
||||
on<AdvancedSearchOrganisations>(_onAdvancedSearchOrganisations);
|
||||
on<LoadOrganisationById>(_onLoadOrganisationById);
|
||||
on<CreateOrganisation>(_onCreateOrganisation);
|
||||
on<UpdateOrganisation>(_onUpdateOrganisation);
|
||||
on<DeleteOrganisation>(_onDeleteOrganisation);
|
||||
on<ActivateOrganisation>(_onActivateOrganisation);
|
||||
on<FilterOrganisationsByStatus>(_onFilterOrganisationsByStatus);
|
||||
on<FilterOrganisationsByType>(_onFilterOrganisationsByType);
|
||||
on<SortOrganisations>(_onSortOrganisations);
|
||||
on<LoadOrganisationsStats>(_onLoadOrganisationsStats);
|
||||
on<ClearOrganisationsFilters>(_onClearOrganisationsFilters);
|
||||
on<RefreshOrganisations>(_onRefreshOrganisations);
|
||||
on<ResetOrganisationsState>(_onResetOrganisationsState);
|
||||
}
|
||||
|
||||
/// Charge la liste des organisations
|
||||
Future<void> _onLoadOrganisations(
|
||||
LoadOrganisations event,
|
||||
Emitter<OrganisationsState> emit,
|
||||
) async {
|
||||
try {
|
||||
if (event.refresh || state is! OrganisationsLoaded) {
|
||||
emit(const OrganisationsLoading());
|
||||
}
|
||||
|
||||
final organisations = await _organisationService.getOrganisations(
|
||||
page: event.page,
|
||||
size: event.size,
|
||||
recherche: event.recherche,
|
||||
);
|
||||
|
||||
emit(OrganisationsLoaded(
|
||||
organisations: organisations,
|
||||
filteredOrganisations: organisations,
|
||||
hasReachedMax: organisations.length < event.size,
|
||||
currentPage: event.page,
|
||||
currentSearch: event.recherche,
|
||||
));
|
||||
} catch (e) {
|
||||
emit(OrganisationsError(
|
||||
'Erreur lors du chargement des organisations',
|
||||
details: e.toString(),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/// Charge plus d'organisations (pagination)
|
||||
Future<void> _onLoadMoreOrganisations(
|
||||
LoadMoreOrganisations event,
|
||||
Emitter<OrganisationsState> emit,
|
||||
) async {
|
||||
final currentState = state;
|
||||
if (currentState is! OrganisationsLoaded || currentState.hasReachedMax) {
|
||||
return;
|
||||
}
|
||||
|
||||
emit(OrganisationsLoadingMore(currentState.organisations));
|
||||
|
||||
try {
|
||||
final nextPage = currentState.currentPage + 1;
|
||||
final newOrganisations = await _organisationService.getOrganisations(
|
||||
page: nextPage,
|
||||
size: 20,
|
||||
recherche: currentState.currentSearch,
|
||||
);
|
||||
|
||||
final allOrganisations = [...currentState.organisations, ...newOrganisations];
|
||||
final filteredOrganisations = _applyCurrentFilters(allOrganisations, currentState);
|
||||
|
||||
emit(currentState.copyWith(
|
||||
organisations: allOrganisations,
|
||||
filteredOrganisations: filteredOrganisations,
|
||||
hasReachedMax: newOrganisations.length < 20,
|
||||
currentPage: nextPage,
|
||||
));
|
||||
} catch (e) {
|
||||
emit(OrganisationsError(
|
||||
'Erreur lors du chargement de plus d\'organisations',
|
||||
details: e.toString(),
|
||||
previousOrganisations: currentState.organisations,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/// Recherche des organisations
|
||||
Future<void> _onSearchOrganisations(
|
||||
SearchOrganisations event,
|
||||
Emitter<OrganisationsState> emit,
|
||||
) async {
|
||||
final currentState = state;
|
||||
if (currentState is! OrganisationsLoaded) {
|
||||
// Si pas encore chargé, charger avec recherche
|
||||
add(LoadOrganisations(recherche: event.query, refresh: true));
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
if (event.query.isEmpty) {
|
||||
// Recherche vide, afficher toutes les organisations
|
||||
final filteredOrganisations = _applyCurrentFilters(
|
||||
currentState.organisations,
|
||||
currentState.copyWith(clearSearch: true),
|
||||
);
|
||||
emit(currentState.copyWith(
|
||||
filteredOrganisations: filteredOrganisations,
|
||||
clearSearch: true,
|
||||
));
|
||||
} else {
|
||||
// Recherche locale d'abord
|
||||
final localResults = _organisationService.searchLocal(
|
||||
currentState.organisations,
|
||||
event.query,
|
||||
);
|
||||
|
||||
emit(currentState.copyWith(
|
||||
filteredOrganisations: localResults,
|
||||
currentSearch: event.query,
|
||||
));
|
||||
|
||||
// Puis recherche serveur pour plus de résultats
|
||||
final serverResults = await _organisationService.getOrganisations(
|
||||
page: 0,
|
||||
size: 50,
|
||||
recherche: event.query,
|
||||
);
|
||||
|
||||
final filteredResults = _applyCurrentFilters(serverResults, currentState);
|
||||
emit(currentState.copyWith(
|
||||
organisations: serverResults,
|
||||
filteredOrganisations: filteredResults,
|
||||
currentSearch: event.query,
|
||||
currentPage: 0,
|
||||
hasReachedMax: true,
|
||||
));
|
||||
}
|
||||
} catch (e) {
|
||||
emit(OrganisationsError(
|
||||
'Erreur lors de la recherche',
|
||||
details: e.toString(),
|
||||
previousOrganisations: currentState.organisations,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/// Recherche avancée
|
||||
Future<void> _onAdvancedSearchOrganisations(
|
||||
AdvancedSearchOrganisations event,
|
||||
Emitter<OrganisationsState> emit,
|
||||
) async {
|
||||
emit(const OrganisationsLoading());
|
||||
|
||||
try {
|
||||
final organisations = await _organisationService.searchOrganisations(
|
||||
nom: event.nom,
|
||||
type: event.type,
|
||||
statut: event.statut,
|
||||
ville: event.ville,
|
||||
region: event.region,
|
||||
pays: event.pays,
|
||||
page: event.page,
|
||||
size: event.size,
|
||||
);
|
||||
|
||||
emit(OrganisationsLoaded(
|
||||
organisations: organisations,
|
||||
filteredOrganisations: organisations,
|
||||
hasReachedMax: organisations.length < event.size,
|
||||
currentPage: event.page,
|
||||
typeFilter: event.type,
|
||||
statusFilter: event.statut,
|
||||
));
|
||||
} catch (e) {
|
||||
emit(OrganisationsError(
|
||||
'Erreur lors de la recherche avancée',
|
||||
details: e.toString(),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/// Charge une organisation par ID
|
||||
Future<void> _onLoadOrganisationById(
|
||||
LoadOrganisationById event,
|
||||
Emitter<OrganisationsState> emit,
|
||||
) async {
|
||||
emit(OrganisationLoading(event.id));
|
||||
|
||||
try {
|
||||
final organisation = await _organisationService.getOrganisationById(event.id);
|
||||
if (organisation != null) {
|
||||
emit(OrganisationLoaded(organisation));
|
||||
} else {
|
||||
emit(OrganisationError('Organisation non trouvée', organisationId: event.id));
|
||||
}
|
||||
} catch (e) {
|
||||
emit(OrganisationError(
|
||||
'Erreur lors du chargement de l\'organisation',
|
||||
organisationId: event.id,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/// Crée une nouvelle organisation
|
||||
Future<void> _onCreateOrganisation(
|
||||
CreateOrganisation event,
|
||||
Emitter<OrganisationsState> emit,
|
||||
) async {
|
||||
emit(const OrganisationCreating());
|
||||
|
||||
try {
|
||||
final createdOrganisation = await _organisationService.createOrganisation(event.organisation);
|
||||
emit(OrganisationCreated(createdOrganisation));
|
||||
|
||||
// Recharger la liste si elle était déjà chargée
|
||||
if (state is OrganisationsLoaded) {
|
||||
add(const RefreshOrganisations());
|
||||
}
|
||||
} catch (e) {
|
||||
emit(OrganisationsError(
|
||||
'Erreur lors de la création de l\'organisation',
|
||||
details: e.toString(),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/// Met à jour une organisation
|
||||
Future<void> _onUpdateOrganisation(
|
||||
UpdateOrganisation event,
|
||||
Emitter<OrganisationsState> emit,
|
||||
) async {
|
||||
emit(OrganisationUpdating(event.id));
|
||||
|
||||
try {
|
||||
final updatedOrganisation = await _organisationService.updateOrganisation(
|
||||
event.id,
|
||||
event.organisation,
|
||||
);
|
||||
emit(OrganisationUpdated(updatedOrganisation));
|
||||
|
||||
// Mettre à jour la liste si elle était déjà chargée
|
||||
final currentState = state;
|
||||
if (currentState is OrganisationsLoaded) {
|
||||
final updatedList = currentState.organisations.map((org) {
|
||||
return org.id == event.id ? updatedOrganisation : org;
|
||||
}).toList();
|
||||
|
||||
final filteredList = _applyCurrentFilters(updatedList, currentState);
|
||||
emit(currentState.copyWith(
|
||||
organisations: updatedList,
|
||||
filteredOrganisations: filteredList,
|
||||
));
|
||||
}
|
||||
} catch (e) {
|
||||
emit(OrganisationsError(
|
||||
'Erreur lors de la mise à jour de l\'organisation',
|
||||
details: e.toString(),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/// Supprime une organisation
|
||||
Future<void> _onDeleteOrganisation(
|
||||
DeleteOrganisation event,
|
||||
Emitter<OrganisationsState> emit,
|
||||
) async {
|
||||
emit(OrganisationDeleting(event.id));
|
||||
|
||||
try {
|
||||
await _organisationService.deleteOrganisation(event.id);
|
||||
emit(OrganisationDeleted(event.id));
|
||||
|
||||
// Retirer de la liste si elle était déjà chargée
|
||||
final currentState = state;
|
||||
if (currentState is OrganisationsLoaded) {
|
||||
final updatedList = currentState.organisations.where((org) => org.id != event.id).toList();
|
||||
final filteredList = _applyCurrentFilters(updatedList, currentState);
|
||||
emit(currentState.copyWith(
|
||||
organisations: updatedList,
|
||||
filteredOrganisations: filteredList,
|
||||
));
|
||||
}
|
||||
} catch (e) {
|
||||
emit(OrganisationsError(
|
||||
'Erreur lors de la suppression de l\'organisation',
|
||||
details: e.toString(),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/// Active une organisation
|
||||
Future<void> _onActivateOrganisation(
|
||||
ActivateOrganisation event,
|
||||
Emitter<OrganisationsState> emit,
|
||||
) async {
|
||||
emit(OrganisationActivating(event.id));
|
||||
|
||||
try {
|
||||
final activatedOrganisation = await _organisationService.activateOrganisation(event.id);
|
||||
emit(OrganisationActivated(activatedOrganisation));
|
||||
|
||||
// Mettre à jour la liste si elle était déjà chargée
|
||||
final currentState = state;
|
||||
if (currentState is OrganisationsLoaded) {
|
||||
final updatedList = currentState.organisations.map((org) {
|
||||
return org.id == event.id ? activatedOrganisation : org;
|
||||
}).toList();
|
||||
|
||||
final filteredList = _applyCurrentFilters(updatedList, currentState);
|
||||
emit(currentState.copyWith(
|
||||
organisations: updatedList,
|
||||
filteredOrganisations: filteredList,
|
||||
));
|
||||
}
|
||||
} catch (e) {
|
||||
emit(OrganisationsError(
|
||||
'Erreur lors de l\'activation de l\'organisation',
|
||||
details: e.toString(),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/// Filtre par statut
|
||||
void _onFilterOrganisationsByStatus(
|
||||
FilterOrganisationsByStatus event,
|
||||
Emitter<OrganisationsState> emit,
|
||||
) {
|
||||
final currentState = state;
|
||||
if (currentState is! OrganisationsLoaded) return;
|
||||
|
||||
final filteredOrganisations = _applyCurrentFilters(
|
||||
currentState.organisations,
|
||||
currentState.copyWith(statusFilter: event.statut),
|
||||
);
|
||||
|
||||
emit(currentState.copyWith(
|
||||
filteredOrganisations: filteredOrganisations,
|
||||
statusFilter: event.statut,
|
||||
));
|
||||
}
|
||||
|
||||
/// Filtre par type
|
||||
void _onFilterOrganisationsByType(
|
||||
FilterOrganisationsByType event,
|
||||
Emitter<OrganisationsState> emit,
|
||||
) {
|
||||
final currentState = state;
|
||||
if (currentState is! OrganisationsLoaded) return;
|
||||
|
||||
final filteredOrganisations = _applyCurrentFilters(
|
||||
currentState.organisations,
|
||||
currentState.copyWith(typeFilter: event.type),
|
||||
);
|
||||
|
||||
emit(currentState.copyWith(
|
||||
filteredOrganisations: filteredOrganisations,
|
||||
typeFilter: event.type,
|
||||
));
|
||||
}
|
||||
|
||||
/// Trie les organisations
|
||||
void _onSortOrganisations(
|
||||
SortOrganisations event,
|
||||
Emitter<OrganisationsState> emit,
|
||||
) {
|
||||
final currentState = state;
|
||||
if (currentState is! OrganisationsLoaded) return;
|
||||
|
||||
List<OrganisationModel> sortedOrganisations;
|
||||
switch (event.sortType) {
|
||||
case OrganisationSortType.nom:
|
||||
sortedOrganisations = _organisationService.sortByName(
|
||||
currentState.filteredOrganisations,
|
||||
ascending: event.ascending,
|
||||
);
|
||||
break;
|
||||
case OrganisationSortType.dateCreation:
|
||||
sortedOrganisations = _organisationService.sortByCreationDate(
|
||||
currentState.filteredOrganisations,
|
||||
ascending: event.ascending,
|
||||
);
|
||||
break;
|
||||
case OrganisationSortType.nombreMembres:
|
||||
sortedOrganisations = _organisationService.sortByMemberCount(
|
||||
currentState.filteredOrganisations,
|
||||
ascending: event.ascending,
|
||||
);
|
||||
break;
|
||||
default:
|
||||
sortedOrganisations = currentState.filteredOrganisations;
|
||||
}
|
||||
|
||||
emit(currentState.copyWith(
|
||||
filteredOrganisations: sortedOrganisations,
|
||||
sortType: event.sortType,
|
||||
sortAscending: event.ascending,
|
||||
));
|
||||
}
|
||||
|
||||
/// Charge les statistiques
|
||||
Future<void> _onLoadOrganisationsStats(
|
||||
LoadOrganisationsStats event,
|
||||
Emitter<OrganisationsState> emit,
|
||||
) async {
|
||||
emit(const OrganisationsStatsLoading());
|
||||
|
||||
try {
|
||||
final stats = await _organisationService.getOrganisationsStats();
|
||||
emit(OrganisationsStatsLoaded(stats));
|
||||
} catch (e) {
|
||||
emit(const OrganisationsStatsError('Erreur lors du chargement des statistiques'));
|
||||
}
|
||||
}
|
||||
|
||||
/// Efface les filtres
|
||||
void _onClearOrganisationsFilters(
|
||||
ClearOrganisationsFilters event,
|
||||
Emitter<OrganisationsState> emit,
|
||||
) {
|
||||
final currentState = state;
|
||||
if (currentState is! OrganisationsLoaded) return;
|
||||
|
||||
emit(currentState.copyWith(
|
||||
filteredOrganisations: currentState.organisations,
|
||||
clearSearch: true,
|
||||
clearStatusFilter: true,
|
||||
clearTypeFilter: true,
|
||||
clearSort: true,
|
||||
));
|
||||
}
|
||||
|
||||
/// Rafraîchit les données
|
||||
void _onRefreshOrganisations(
|
||||
RefreshOrganisations event,
|
||||
Emitter<OrganisationsState> emit,
|
||||
) {
|
||||
add(const LoadOrganisations(refresh: true));
|
||||
}
|
||||
|
||||
/// Remet à zéro l'état
|
||||
void _onResetOrganisationsState(
|
||||
ResetOrganisationsState event,
|
||||
Emitter<OrganisationsState> emit,
|
||||
) {
|
||||
emit(const OrganisationsInitial());
|
||||
}
|
||||
|
||||
/// Applique les filtres actuels à une liste d'organisations
|
||||
List<OrganisationModel> _applyCurrentFilters(
|
||||
List<OrganisationModel> organisations,
|
||||
OrganisationsLoaded state,
|
||||
) {
|
||||
var filtered = organisations;
|
||||
|
||||
// Filtre par recherche
|
||||
if (state.currentSearch?.isNotEmpty == true) {
|
||||
filtered = _organisationService.searchLocal(filtered, state.currentSearch!);
|
||||
}
|
||||
|
||||
// Filtre par statut
|
||||
if (state.statusFilter != null) {
|
||||
filtered = _organisationService.filterByStatus(filtered, state.statusFilter!);
|
||||
}
|
||||
|
||||
// Filtre par type
|
||||
if (state.typeFilter != null) {
|
||||
filtered = _organisationService.filterByType(filtered, state.typeFilter!);
|
||||
}
|
||||
|
||||
return filtered;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,216 @@
|
||||
/// Événements pour le BLoC des organisations
|
||||
library organisations_event;
|
||||
|
||||
import 'package:equatable/equatable.dart';
|
||||
import '../data/models/organisation_model.dart';
|
||||
|
||||
/// Classe de base pour tous les événements des organisations
|
||||
abstract class OrganisationsEvent extends Equatable {
|
||||
const OrganisationsEvent();
|
||||
|
||||
@override
|
||||
List<Object?> get props => [];
|
||||
}
|
||||
|
||||
/// Événement pour charger la liste des organisations
|
||||
class LoadOrganisations extends OrganisationsEvent {
|
||||
final int page;
|
||||
final int size;
|
||||
final String? recherche;
|
||||
final bool refresh;
|
||||
|
||||
const LoadOrganisations({
|
||||
this.page = 0,
|
||||
this.size = 20,
|
||||
this.recherche,
|
||||
this.refresh = false,
|
||||
});
|
||||
|
||||
@override
|
||||
List<Object?> get props => [page, size, recherche, refresh];
|
||||
}
|
||||
|
||||
/// Événement pour charger plus d'organisations (pagination)
|
||||
class LoadMoreOrganisations extends OrganisationsEvent {
|
||||
const LoadMoreOrganisations();
|
||||
}
|
||||
|
||||
/// Événement pour rechercher des organisations
|
||||
class SearchOrganisations extends OrganisationsEvent {
|
||||
final String query;
|
||||
|
||||
const SearchOrganisations(this.query);
|
||||
|
||||
@override
|
||||
List<Object?> get props => [query];
|
||||
}
|
||||
|
||||
/// Événement pour recherche avancée
|
||||
class AdvancedSearchOrganisations extends OrganisationsEvent {
|
||||
final String? nom;
|
||||
final TypeOrganisation? type;
|
||||
final StatutOrganisation? statut;
|
||||
final String? ville;
|
||||
final String? region;
|
||||
final String? pays;
|
||||
final int page;
|
||||
final int size;
|
||||
|
||||
const AdvancedSearchOrganisations({
|
||||
this.nom,
|
||||
this.type,
|
||||
this.statut,
|
||||
this.ville,
|
||||
this.region,
|
||||
this.pays,
|
||||
this.page = 0,
|
||||
this.size = 20,
|
||||
});
|
||||
|
||||
@override
|
||||
List<Object?> get props => [nom, type, statut, ville, region, pays, page, size];
|
||||
}
|
||||
|
||||
/// Événement pour charger une organisation spécifique
|
||||
class LoadOrganisationById extends OrganisationsEvent {
|
||||
final String id;
|
||||
|
||||
const LoadOrganisationById(this.id);
|
||||
|
||||
@override
|
||||
List<Object?> get props => [id];
|
||||
}
|
||||
|
||||
/// Événement pour créer une nouvelle organisation
|
||||
class CreateOrganisation extends OrganisationsEvent {
|
||||
final OrganisationModel organisation;
|
||||
|
||||
const CreateOrganisation(this.organisation);
|
||||
|
||||
@override
|
||||
List<Object?> get props => [organisation];
|
||||
}
|
||||
|
||||
/// Événement pour mettre à jour une organisation
|
||||
class UpdateOrganisation extends OrganisationsEvent {
|
||||
final String id;
|
||||
final OrganisationModel organisation;
|
||||
|
||||
const UpdateOrganisation(this.id, this.organisation);
|
||||
|
||||
@override
|
||||
List<Object?> get props => [id, organisation];
|
||||
}
|
||||
|
||||
/// Événement pour supprimer une organisation
|
||||
class DeleteOrganisation extends OrganisationsEvent {
|
||||
final String id;
|
||||
|
||||
const DeleteOrganisation(this.id);
|
||||
|
||||
@override
|
||||
List<Object?> get props => [id];
|
||||
}
|
||||
|
||||
/// Événement pour activer une organisation
|
||||
class ActivateOrganisation extends OrganisationsEvent {
|
||||
final String id;
|
||||
|
||||
const ActivateOrganisation(this.id);
|
||||
|
||||
@override
|
||||
List<Object?> get props => [id];
|
||||
}
|
||||
|
||||
/// Événement pour filtrer les organisations par statut
|
||||
class FilterOrganisationsByStatus extends OrganisationsEvent {
|
||||
final StatutOrganisation? statut;
|
||||
|
||||
const FilterOrganisationsByStatus(this.statut);
|
||||
|
||||
@override
|
||||
List<Object?> get props => [statut];
|
||||
}
|
||||
|
||||
/// Événement pour filtrer les organisations par type
|
||||
class FilterOrganisationsByType extends OrganisationsEvent {
|
||||
final TypeOrganisation? type;
|
||||
|
||||
const FilterOrganisationsByType(this.type);
|
||||
|
||||
@override
|
||||
List<Object?> get props => [type];
|
||||
}
|
||||
|
||||
/// Événement pour trier les organisations
|
||||
class SortOrganisations extends OrganisationsEvent {
|
||||
final OrganisationSortType sortType;
|
||||
final bool ascending;
|
||||
|
||||
const SortOrganisations(this.sortType, {this.ascending = true});
|
||||
|
||||
@override
|
||||
List<Object?> get props => [sortType, ascending];
|
||||
}
|
||||
|
||||
/// Événement pour charger les statistiques des organisations
|
||||
class LoadOrganisationsStats extends OrganisationsEvent {
|
||||
const LoadOrganisationsStats();
|
||||
}
|
||||
|
||||
/// Événement pour effacer les filtres
|
||||
class ClearOrganisationsFilters extends OrganisationsEvent {
|
||||
const ClearOrganisationsFilters();
|
||||
}
|
||||
|
||||
/// Événement pour rafraîchir les données
|
||||
class RefreshOrganisations extends OrganisationsEvent {
|
||||
const RefreshOrganisations();
|
||||
}
|
||||
|
||||
/// Événement pour réinitialiser l'état
|
||||
class ResetOrganisationsState extends OrganisationsEvent {
|
||||
const ResetOrganisationsState();
|
||||
}
|
||||
|
||||
/// Types de tri pour les organisations
|
||||
enum OrganisationSortType {
|
||||
nom,
|
||||
dateCreation,
|
||||
nombreMembres,
|
||||
type,
|
||||
statut,
|
||||
}
|
||||
|
||||
/// Extension pour les types de tri
|
||||
extension OrganisationSortTypeExtension on OrganisationSortType {
|
||||
String get displayName {
|
||||
switch (this) {
|
||||
case OrganisationSortType.nom:
|
||||
return 'Nom';
|
||||
case OrganisationSortType.dateCreation:
|
||||
return 'Date de création';
|
||||
case OrganisationSortType.nombreMembres:
|
||||
return 'Nombre de membres';
|
||||
case OrganisationSortType.type:
|
||||
return 'Type';
|
||||
case OrganisationSortType.statut:
|
||||
return 'Statut';
|
||||
}
|
||||
}
|
||||
|
||||
String get icon {
|
||||
switch (this) {
|
||||
case OrganisationSortType.nom:
|
||||
return '📝';
|
||||
case OrganisationSortType.dateCreation:
|
||||
return '📅';
|
||||
case OrganisationSortType.nombreMembres:
|
||||
return '👥';
|
||||
case OrganisationSortType.type:
|
||||
return '🏷️';
|
||||
case OrganisationSortType.statut:
|
||||
return '📊';
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,282 @@
|
||||
/// États pour le BLoC des organisations
|
||||
library organisations_state;
|
||||
|
||||
import 'package:equatable/equatable.dart';
|
||||
import '../data/models/organisation_model.dart';
|
||||
import 'organisations_event.dart';
|
||||
|
||||
/// Classe de base pour tous les états des organisations
|
||||
abstract class OrganisationsState extends Equatable {
|
||||
const OrganisationsState();
|
||||
|
||||
@override
|
||||
List<Object?> get props => [];
|
||||
}
|
||||
|
||||
/// État initial
|
||||
class OrganisationsInitial extends OrganisationsState {
|
||||
const OrganisationsInitial();
|
||||
}
|
||||
|
||||
/// État de chargement
|
||||
class OrganisationsLoading extends OrganisationsState {
|
||||
const OrganisationsLoading();
|
||||
}
|
||||
|
||||
/// État de chargement de plus d'éléments (pagination)
|
||||
class OrganisationsLoadingMore extends OrganisationsState {
|
||||
final List<OrganisationModel> currentOrganisations;
|
||||
|
||||
const OrganisationsLoadingMore(this.currentOrganisations);
|
||||
|
||||
@override
|
||||
List<Object?> get props => [currentOrganisations];
|
||||
}
|
||||
|
||||
/// État de succès avec données
|
||||
class OrganisationsLoaded extends OrganisationsState {
|
||||
final List<OrganisationModel> organisations;
|
||||
final List<OrganisationModel> filteredOrganisations;
|
||||
final bool hasReachedMax;
|
||||
final int currentPage;
|
||||
final String? currentSearch;
|
||||
final StatutOrganisation? statusFilter;
|
||||
final TypeOrganisation? typeFilter;
|
||||
final OrganisationSortType? sortType;
|
||||
final bool sortAscending;
|
||||
final Map<String, dynamic>? stats;
|
||||
|
||||
const OrganisationsLoaded({
|
||||
required this.organisations,
|
||||
required this.filteredOrganisations,
|
||||
this.hasReachedMax = false,
|
||||
this.currentPage = 0,
|
||||
this.currentSearch,
|
||||
this.statusFilter,
|
||||
this.typeFilter,
|
||||
this.sortType,
|
||||
this.sortAscending = true,
|
||||
this.stats,
|
||||
});
|
||||
|
||||
/// Copie avec modifications
|
||||
OrganisationsLoaded copyWith({
|
||||
List<OrganisationModel>? organisations,
|
||||
List<OrganisationModel>? filteredOrganisations,
|
||||
bool? hasReachedMax,
|
||||
int? currentPage,
|
||||
String? currentSearch,
|
||||
StatutOrganisation? statusFilter,
|
||||
TypeOrganisation? typeFilter,
|
||||
OrganisationSortType? sortType,
|
||||
bool? sortAscending,
|
||||
Map<String, dynamic>? stats,
|
||||
bool clearSearch = false,
|
||||
bool clearStatusFilter = false,
|
||||
bool clearTypeFilter = false,
|
||||
bool clearSort = false,
|
||||
}) {
|
||||
return OrganisationsLoaded(
|
||||
organisations: organisations ?? this.organisations,
|
||||
filteredOrganisations: filteredOrganisations ?? this.filteredOrganisations,
|
||||
hasReachedMax: hasReachedMax ?? this.hasReachedMax,
|
||||
currentPage: currentPage ?? this.currentPage,
|
||||
currentSearch: clearSearch ? null : (currentSearch ?? this.currentSearch),
|
||||
statusFilter: clearStatusFilter ? null : (statusFilter ?? this.statusFilter),
|
||||
typeFilter: clearTypeFilter ? null : (typeFilter ?? this.typeFilter),
|
||||
sortType: clearSort ? null : (sortType ?? this.sortType),
|
||||
sortAscending: sortAscending ?? this.sortAscending,
|
||||
stats: stats ?? this.stats,
|
||||
);
|
||||
}
|
||||
|
||||
/// Nombre total d'organisations
|
||||
int get totalCount => organisations.length;
|
||||
|
||||
/// Nombre d'organisations filtrées
|
||||
int get filteredCount => filteredOrganisations.length;
|
||||
|
||||
/// Indique si des filtres sont appliqués
|
||||
bool get hasFilters =>
|
||||
currentSearch?.isNotEmpty == true ||
|
||||
statusFilter != null ||
|
||||
typeFilter != null;
|
||||
|
||||
/// Indique si un tri est appliqué
|
||||
bool get hasSorting => sortType != null;
|
||||
|
||||
/// Statistiques rapides
|
||||
Map<String, int> get quickStats {
|
||||
final actives = organisations.where((org) => org.statut == StatutOrganisation.active).length;
|
||||
final inactives = organisations.length - actives;
|
||||
final totalMembres = organisations.fold<int>(0, (sum, org) => sum + org.nombreMembres);
|
||||
|
||||
return {
|
||||
'total': organisations.length,
|
||||
'actives': actives,
|
||||
'inactives': inactives,
|
||||
'totalMembres': totalMembres,
|
||||
};
|
||||
}
|
||||
|
||||
@override
|
||||
List<Object?> get props => [
|
||||
organisations,
|
||||
filteredOrganisations,
|
||||
hasReachedMax,
|
||||
currentPage,
|
||||
currentSearch,
|
||||
statusFilter,
|
||||
typeFilter,
|
||||
sortType,
|
||||
sortAscending,
|
||||
stats,
|
||||
];
|
||||
}
|
||||
|
||||
/// État d'erreur
|
||||
class OrganisationsError extends OrganisationsState {
|
||||
final String message;
|
||||
final String? details;
|
||||
final List<OrganisationModel>? previousOrganisations;
|
||||
|
||||
const OrganisationsError(
|
||||
this.message, {
|
||||
this.details,
|
||||
this.previousOrganisations,
|
||||
});
|
||||
|
||||
@override
|
||||
List<Object?> get props => [message, details, previousOrganisations];
|
||||
}
|
||||
|
||||
/// État de chargement d'une organisation spécifique
|
||||
class OrganisationLoading extends OrganisationsState {
|
||||
final String id;
|
||||
|
||||
const OrganisationLoading(this.id);
|
||||
|
||||
@override
|
||||
List<Object?> get props => [id];
|
||||
}
|
||||
|
||||
/// État d'organisation chargée
|
||||
class OrganisationLoaded extends OrganisationsState {
|
||||
final OrganisationModel organisation;
|
||||
|
||||
const OrganisationLoaded(this.organisation);
|
||||
|
||||
@override
|
||||
List<Object?> get props => [organisation];
|
||||
}
|
||||
|
||||
/// État d'erreur pour une organisation spécifique
|
||||
class OrganisationError extends OrganisationsState {
|
||||
final String message;
|
||||
final String? organisationId;
|
||||
|
||||
const OrganisationError(this.message, {this.organisationId});
|
||||
|
||||
@override
|
||||
List<Object?> get props => [message, organisationId];
|
||||
}
|
||||
|
||||
/// État de création d'organisation
|
||||
class OrganisationCreating extends OrganisationsState {
|
||||
const OrganisationCreating();
|
||||
}
|
||||
|
||||
/// État de succès de création
|
||||
class OrganisationCreated extends OrganisationsState {
|
||||
final OrganisationModel organisation;
|
||||
|
||||
const OrganisationCreated(this.organisation);
|
||||
|
||||
@override
|
||||
List<Object?> get props => [organisation];
|
||||
}
|
||||
|
||||
/// État de mise à jour d'organisation
|
||||
class OrganisationUpdating extends OrganisationsState {
|
||||
final String id;
|
||||
|
||||
const OrganisationUpdating(this.id);
|
||||
|
||||
@override
|
||||
List<Object?> get props => [id];
|
||||
}
|
||||
|
||||
/// État de succès de mise à jour
|
||||
class OrganisationUpdated extends OrganisationsState {
|
||||
final OrganisationModel organisation;
|
||||
|
||||
const OrganisationUpdated(this.organisation);
|
||||
|
||||
@override
|
||||
List<Object?> get props => [organisation];
|
||||
}
|
||||
|
||||
/// État de suppression d'organisation
|
||||
class OrganisationDeleting extends OrganisationsState {
|
||||
final String id;
|
||||
|
||||
const OrganisationDeleting(this.id);
|
||||
|
||||
@override
|
||||
List<Object?> get props => [id];
|
||||
}
|
||||
|
||||
/// État de succès de suppression
|
||||
class OrganisationDeleted extends OrganisationsState {
|
||||
final String id;
|
||||
|
||||
const OrganisationDeleted(this.id);
|
||||
|
||||
@override
|
||||
List<Object?> get props => [id];
|
||||
}
|
||||
|
||||
/// État d'activation d'organisation
|
||||
class OrganisationActivating extends OrganisationsState {
|
||||
final String id;
|
||||
|
||||
const OrganisationActivating(this.id);
|
||||
|
||||
@override
|
||||
List<Object?> get props => [id];
|
||||
}
|
||||
|
||||
/// État de succès d'activation
|
||||
class OrganisationActivated extends OrganisationsState {
|
||||
final OrganisationModel organisation;
|
||||
|
||||
const OrganisationActivated(this.organisation);
|
||||
|
||||
@override
|
||||
List<Object?> get props => [organisation];
|
||||
}
|
||||
|
||||
/// État de chargement des statistiques
|
||||
class OrganisationsStatsLoading extends OrganisationsState {
|
||||
const OrganisationsStatsLoading();
|
||||
}
|
||||
|
||||
/// État des statistiques chargées
|
||||
class OrganisationsStatsLoaded extends OrganisationsState {
|
||||
final Map<String, dynamic> stats;
|
||||
|
||||
const OrganisationsStatsLoaded(this.stats);
|
||||
|
||||
@override
|
||||
List<Object?> get props => [stats];
|
||||
}
|
||||
|
||||
/// État d'erreur des statistiques
|
||||
class OrganisationsStatsError extends OrganisationsState {
|
||||
final String message;
|
||||
|
||||
const OrganisationsStatsError(this.message);
|
||||
|
||||
@override
|
||||
List<Object?> get props => [message];
|
||||
}
|
||||
Reference in New Issue
Block a user