refactoring

This commit is contained in:
dahoud
2026-03-31 09:14:47 +00:00
parent 9bfffeeebe
commit 5383df6dcb
200 changed files with 11192 additions and 7063 deletions

View File

@@ -0,0 +1,95 @@
import 'package:dio/dio.dart';
import 'package:equatable/equatable.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:injectable/injectable.dart';
import '../domain/entities/type_reference_entity.dart';
import '../domain/usecases/get_org_types.dart';
import '../domain/usecases/create_org_type.dart';
import '../domain/usecases/update_org_type.dart';
import '../domain/usecases/delete_org_type.dart';
part 'org_types_event.dart';
part 'org_types_state.dart';
@injectable
class OrgTypesBloc extends Bloc<OrgTypesEvent, OrgTypesState> {
final GetOrgTypes _getOrgTypes;
final CreateOrgType _createOrgType;
final UpdateOrgType _updateOrgType;
final DeleteOrgType _deleteOrgType;
OrgTypesBloc(
this._getOrgTypes,
this._createOrgType,
this._updateOrgType,
this._deleteOrgType,
) : super(const OrgTypesInitial()) {
on<LoadOrgTypes>(_onLoad);
on<CreateOrgTypeEvent>(_onCreate);
on<UpdateOrgTypeEvent>(_onUpdate);
on<DeleteOrgTypeEvent>(_onDelete);
}
Future<void> _onLoad(LoadOrgTypes event, Emitter<OrgTypesState> emit) async {
emit(const OrgTypesLoading());
try {
final types = await _getOrgTypes();
emit(OrgTypesLoaded(types));
} catch (e) {
if (e is DioException && e.type == DioExceptionType.cancel) return;
emit(OrgTypesError(e.toString()));
}
}
Future<void> _onCreate(CreateOrgTypeEvent event, Emitter<OrgTypesState> emit) async {
final current = state is OrgTypesLoaded ? (state as OrgTypesLoaded).types : <TypeReferenceEntity>[];
emit(OrgTypeOperating(List.from(current)));
try {
await _createOrgType(
code: event.code,
libelle: event.libelle,
description: event.description,
couleur: event.couleur,
ordreAffichage: event.ordreAffichage,
);
final types = await _getOrgTypes();
emit(OrgTypeSuccess(types: types, message: 'Type créé avec succès'));
} catch (e) {
if (e is DioException && e.type == DioExceptionType.cancel) return;
emit(OrgTypeOperationError(types: List.from(current), message: e.toString()));
}
}
Future<void> _onUpdate(UpdateOrgTypeEvent event, Emitter<OrgTypesState> emit) async {
final current = state is OrgTypesLoaded ? (state as OrgTypesLoaded).types : <TypeReferenceEntity>[];
emit(OrgTypeOperating(List.from(current)));
try {
await _updateOrgType(
id: event.id,
code: event.code,
libelle: event.libelle,
description: event.description,
couleur: event.couleur,
ordreAffichage: event.ordreAffichage,
);
final types = await _getOrgTypes();
emit(OrgTypeSuccess(types: types, message: 'Type modifié avec succès'));
} catch (e) {
if (e is DioException && e.type == DioExceptionType.cancel) return;
emit(OrgTypeOperationError(types: List.from(current), message: e.toString()));
}
}
Future<void> _onDelete(DeleteOrgTypeEvent event, Emitter<OrgTypesState> emit) async {
final current = state is OrgTypesLoaded ? (state as OrgTypesLoaded).types : <TypeReferenceEntity>[];
emit(OrgTypeOperating(List.from(current)));
try {
await _deleteOrgType(event.id);
final types = await _getOrgTypes();
emit(OrgTypeSuccess(types: types, message: 'Type supprimé'));
} catch (e) {
if (e is DioException && e.type == DioExceptionType.cancel) return;
emit(OrgTypeOperationError(types: List.from(current), message: e.toString()));
}
}
}

View File

@@ -0,0 +1,58 @@
part of 'org_types_bloc.dart';
abstract class OrgTypesEvent extends Equatable {
const OrgTypesEvent();
@override
List<Object?> get props => [];
}
class LoadOrgTypes extends OrgTypesEvent {
const LoadOrgTypes();
}
class CreateOrgTypeEvent extends OrgTypesEvent {
final String code;
final String libelle;
final String? description;
final String? couleur;
final int ordreAffichage;
const CreateOrgTypeEvent({
required this.code,
required this.libelle,
this.description,
this.couleur,
this.ordreAffichage = 0,
});
@override
List<Object?> get props => [code, libelle, description, couleur, ordreAffichage];
}
class UpdateOrgTypeEvent extends OrgTypesEvent {
final String id;
final String code;
final String libelle;
final String? description;
final String? couleur;
final int ordreAffichage;
const UpdateOrgTypeEvent({
required this.id,
required this.code,
required this.libelle,
this.description,
this.couleur,
this.ordreAffichage = 0,
});
@override
List<Object?> get props => [id, code, libelle, description, couleur, ordreAffichage];
}
class DeleteOrgTypeEvent extends OrgTypesEvent {
final String id;
const DeleteOrgTypeEvent(this.id);
@override
List<Object?> get props => [id];
}

View File

@@ -0,0 +1,52 @@
part of 'org_types_bloc.dart';
abstract class OrgTypesState extends Equatable {
const OrgTypesState();
@override
List<Object?> get props => [];
}
class OrgTypesInitial extends OrgTypesState {
const OrgTypesInitial();
}
class OrgTypesLoading extends OrgTypesState {
const OrgTypesLoading();
}
class OrgTypesLoaded extends OrgTypesState {
final List<TypeReferenceEntity> types;
const OrgTypesLoaded(this.types);
@override
List<Object?> get props => [types];
}
class OrgTypesError extends OrgTypesState {
final String message;
const OrgTypesError(this.message);
@override
List<Object?> get props => [message];
}
class OrgTypeOperating extends OrgTypesState {
final List<TypeReferenceEntity> types;
const OrgTypeOperating(this.types);
@override
List<Object?> get props => [types];
}
class OrgTypeSuccess extends OrgTypesState {
final List<TypeReferenceEntity> types;
final String message;
const OrgTypeSuccess({required this.types, required this.message});
@override
List<Object?> get props => [types, message];
}
class OrgTypeOperationError extends OrgTypesState {
final List<TypeReferenceEntity> types;
final String message;
const OrgTypeOperationError({required this.types, required this.message});
@override
List<Object?> get props => [types, message];
}

View File

@@ -1,6 +1,7 @@
/// BLoC pour la gestion des organisations (Clean Architecture)
library organizations_bloc;
import 'package:dio/dio.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:injectable/injectable.dart';
import '../data/models/organization_model.dart';
@@ -99,6 +100,7 @@ class OrganizationsBloc extends Bloc<OrganizationsEvent, OrganizationsState> {
useMesOnly: event.useMesOnly,
));
} catch (e) {
if (e is DioException && e.type == DioExceptionType.cancel) return;
emit(OrganizationsError(
'Erreur lors du chargement des organisations',
details: e.toString(),
@@ -144,6 +146,7 @@ class OrganizationsBloc extends Bloc<OrganizationsEvent, OrganizationsState> {
currentPage: nextPage,
));
} catch (e) {
if (e is DioException && e.type == DioExceptionType.cancel) return;
emit(OrganizationsError(
'Erreur lors du chargement de plus d\'organisations',
details: e.toString(),
@@ -204,6 +207,7 @@ class OrganizationsBloc extends Bloc<OrganizationsEvent, OrganizationsState> {
));
}
} catch (e) {
if (e is DioException && e.type == DioExceptionType.cancel) return;
emit(OrganizationsError(
'Erreur lors de la recherche',
details: e.toString(),
@@ -240,6 +244,7 @@ class OrganizationsBloc extends Bloc<OrganizationsEvent, OrganizationsState> {
statusFilter: event.statut,
));
} catch (e) {
if (e is DioException && e.type == DioExceptionType.cancel) return;
emit(OrganizationsError(
'Erreur lors de la recherche avancée',
details: e.toString(),
@@ -262,6 +267,7 @@ class OrganizationsBloc extends Bloc<OrganizationsEvent, OrganizationsState> {
emit(OrganizationError('Organisation non trouvée', organizationId: event.id));
}
} catch (e) {
if (e is DioException && e.type == DioExceptionType.cancel) return;
emit(OrganizationError(
'Erreur lors du chargement de l\'organisation',
organizationId: event.id,
@@ -279,12 +285,10 @@ class OrganizationsBloc extends Bloc<OrganizationsEvent, OrganizationsState> {
try {
final createdOrganization = await _createOrganization(event.organization);
emit(OrganizationCreated(createdOrganization));
// Recharger la liste si elle était déjà chargée
if (state is OrganizationsLoaded) {
add(const RefreshOrganizations());
}
// Toujours recharger la liste après création
add(const RefreshOrganizations());
} catch (e) {
if (e is DioException && e.type == DioExceptionType.cancel) return;
emit(OrganizationsError(
'Erreur lors de la création de l\'organisation',
details: e.toString(),
@@ -299,6 +303,8 @@ class OrganizationsBloc extends Bloc<OrganizationsEvent, OrganizationsState> {
) async {
emit(OrganizationUpdating(event.id));
// Capturer l'état avant tout emit
final previousState = state;
try {
final updatedOrganization = await _updateOrganization(
event.id,
@@ -306,20 +312,20 @@ class OrganizationsBloc extends Bloc<OrganizationsEvent, OrganizationsState> {
);
emit(OrganizationUpdated(updatedOrganization));
// Mettre à jour la liste si elle était déjà chargée
final currentState = state;
if (currentState is OrganizationsLoaded) {
final updatedList = currentState.organizations.map((org) {
// Mettre à jour la liste en place
if (previousState is OrganizationsLoaded) {
final updatedList = previousState.organizations.map((org) {
return org.id == event.id ? updatedOrganization : org;
}).toList();
final filteredList = _applyCurrentFilters(updatedList, currentState);
emit(currentState.copyWith(
final filteredList = _applyCurrentFilters(updatedList, previousState);
emit(previousState.copyWith(
organizations: updatedList,
filteredOrganizations: filteredList,
));
}
} catch (e) {
if (e is DioException && e.type == DioExceptionType.cancel) return;
emit(OrganizationsError(
'Erreur lors de la mise à jour de l\'organisation',
details: e.toString(),
@@ -334,21 +340,23 @@ class OrganizationsBloc extends Bloc<OrganizationsEvent, OrganizationsState> {
) async {
emit(OrganizationDeleting(event.id));
// Capturer l'état avant tout emit
final previousState = state;
try {
await _deleteOrganization(event.id);
emit(OrganizationDeleted(event.id));
// Retirer de la liste si elle était déjà chargée
final currentState = state;
if (currentState is OrganizationsLoaded) {
final updatedList = currentState.organizations.where((org) => org.id != event.id).toList();
final filteredList = _applyCurrentFilters(updatedList, currentState);
emit(currentState.copyWith(
// Retirer de la liste en place
if (previousState is OrganizationsLoaded) {
final updatedList = previousState.organizations.where((org) => org.id != event.id).toList();
final filteredList = _applyCurrentFilters(updatedList, previousState);
emit(previousState.copyWith(
organizations: updatedList,
filteredOrganizations: filteredList,
));
}
} catch (e) {
if (e is DioException && e.type == DioExceptionType.cancel) return;
emit(OrganizationsError(
'Erreur lors de la suppression de l\'organisation',
details: e.toString(),
@@ -361,26 +369,26 @@ class OrganizationsBloc extends Bloc<OrganizationsEvent, OrganizationsState> {
ActivateOrganization event,
Emitter<OrganizationsState> emit,
) async {
final previousState = state;
emit(OrganizationActivating(event.id));
try {
final activatedOrganization = await _repository.activateOrganization(event.id);
emit(OrganizationActivated(activatedOrganization));
// Mettre à jour la liste si elle était déjà chargée
final currentState = state;
if (currentState is OrganizationsLoaded) {
final updatedList = currentState.organizations.map((org) {
if (previousState is OrganizationsLoaded) {
final updatedList = previousState.organizations.map((org) {
return org.id == event.id ? activatedOrganization : org;
}).toList();
final filteredList = _applyCurrentFilters(updatedList, currentState);
emit(currentState.copyWith(
final filteredList = _applyCurrentFilters(updatedList, previousState);
emit(previousState.copyWith(
organizations: updatedList,
filteredOrganizations: filteredList,
));
}
} catch (e) {
if (e is DioException && e.type == DioExceptionType.cancel) return;
emit(OrganizationsError(
'Erreur lors de l\'activation de l\'organisation',
details: e.toString(),
@@ -393,26 +401,26 @@ class OrganizationsBloc extends Bloc<OrganizationsEvent, OrganizationsState> {
SuspendOrganization event,
Emitter<OrganizationsState> emit,
) async {
final previousState = state;
emit(OrganizationSuspending(event.id));
try {
final suspendedOrganization = await _repository.suspendOrganization(event.id);
emit(OrganizationSuspended(suspendedOrganization));
// Mettre à jour la liste si elle était déjà chargée
final currentState = state;
if (currentState is OrganizationsLoaded) {
final updatedList = currentState.organizations.map((org) {
if (previousState is OrganizationsLoaded) {
final updatedList = previousState.organizations.map((org) {
return org.id == event.id ? suspendedOrganization : org;
}).toList();
final filteredList = _applyCurrentFilters(updatedList, currentState);
emit(currentState.copyWith(
final filteredList = _applyCurrentFilters(updatedList, previousState);
emit(previousState.copyWith(
organizations: updatedList,
filteredOrganizations: filteredList,
));
}
} catch (e) {
if (e is DioException && e.type == DioExceptionType.cancel) return;
emit(OrganizationsError(
'Erreur lors de la suspension de l\'organisation',
details: e.toString(),
@@ -508,6 +516,7 @@ class OrganizationsBloc extends Bloc<OrganizationsEvent, OrganizationsState> {
final stats = await _repository.getOrganizationsStats();
emit(OrganizationsStatsLoaded(stats));
} catch (e) {
if (e is DioException && e.type == DioExceptionType.cancel) return;
emit(const OrganizationsStatsError('Erreur lors du chargement des statistiques'));
}
}

View File

@@ -54,7 +54,7 @@ class SearchOrganizations extends OrganizationsEvent {
/// Événement pour recherche avancée
class AdvancedSearchOrganizations extends OrganizationsEvent {
final String? nom;
final TypeOrganization? type;
final String? type;
final StatutOrganization? statut;
final String? ville;
final String? region;
@@ -150,7 +150,7 @@ class FilterOrganizationsByStatus extends OrganizationsEvent {
/// Événement pour filtrer les organisations par type
class FilterOrganizationsByType extends OrganizationsEvent {
final TypeOrganization? type;
final String? type;
const FilterOrganizationsByType(this.type);

View File

@@ -40,7 +40,7 @@ class OrganizationsLoaded extends OrganizationsState {
final int currentPage;
final String? currentSearch;
final StatutOrganization? statusFilter;
final TypeOrganization? typeFilter;
final String? typeFilter;
final OrganizationSortType? sortType;
final bool sortAscending;
final Map<String, dynamic>? stats;
@@ -72,7 +72,7 @@ class OrganizationsLoaded extends OrganizationsState {
int? currentPage,
String? currentSearch,
StatutOrganization? statusFilter,
TypeOrganization? typeFilter,
String? typeFilter,
OrganizationSortType? sortType,
bool? sortAscending,
Map<String, dynamic>? stats,