Initial commit: unionflow-mobile-apps

Application Flutter complète (sans build artifacts).

Signed-off-by: lions dev Team
This commit is contained in:
dahoud
2026-03-15 16:30:08 +00:00
commit d094d6db9c
1790 changed files with 507435 additions and 0 deletions

View File

@@ -0,0 +1,51 @@
/// Interface du repository des membres (Clean Architecture)
library membre_repository_interface;
import '../../data/models/membre_complete_model.dart';
import '../../../../shared/models/membre_search_result.dart';
import '../../../../shared/models/membre_search_criteria.dart';
/// Interface définissant le contrat du repository des membres
/// Implémentée par MembreRepositoryImpl dans la couche data
abstract class IMembreRepository {
/// Récupère la liste des membres avec pagination
Future<MembreSearchResult> getMembres({
int page = 0,
int size = 20,
String? recherche,
});
/// Récupère un membre par son ID
Future<MembreCompletModel?> getMembreById(String id);
/// Crée un nouveau membre
Future<MembreCompletModel> createMembre(MembreCompletModel membre);
/// Met à jour un membre
Future<MembreCompletModel> updateMembre(String id, MembreCompletModel membre);
/// Supprime un membre
Future<void> deleteMembre(String id);
/// Active un membre
Future<MembreCompletModel> activateMembre(String id);
/// Désactive un membre
Future<MembreCompletModel> deactivateMembre(String id);
/// Recherche avancée de membres
Future<MembreSearchResult> searchMembres({
required MembreSearchCriteria criteria,
int page = 0,
int size = 20,
});
/// Récupère les membres actifs
Future<MembreSearchResult> getActiveMembers({int page = 0, int size = 20});
/// Récupère les membres du bureau
Future<MembreSearchResult> getBureauMembers({int page = 0, int size = 20});
/// Récupère les statistiques des membres
Future<Map<String, dynamic>> getMembresStats();
}

View File

@@ -0,0 +1,25 @@
/// Use case: Créer un nouveau membre
library create_member;
import 'package:injectable/injectable.dart';
import '../../data/models/membre_complete_model.dart';
import '../repositories/membre_repository.dart';
/// Use case pour créer un membre
/// Réservé aux utilisateurs avec le rôle HR_MANAGER
@injectable
class CreateMember {
final IMembreRepository _repository;
CreateMember(this._repository);
/// Exécute le use case
///
/// [membre] - Modèle complet du membre à créer
///
/// Retourne le membre créé avec son ID généré
/// Lève une exception en cas d'erreur de validation ou de création
Future<MembreCompletModel> call(MembreCompletModel membre) async {
return _repository.createMembre(membre);
}
}

View File

@@ -0,0 +1,25 @@
/// Use case: Supprimer un membre
library delete_member;
import 'package:injectable/injectable.dart';
import '../repositories/membre_repository.dart';
/// Use case pour supprimer un membre
/// Réservé aux utilisateurs avec le rôle HR_MANAGER ou ADMIN_ORGANISATION
@injectable
class DeleteMember {
final IMembreRepository _repository;
DeleteMember(this._repository);
/// Exécute le use case
///
/// [id] - UUID du membre à supprimer
///
/// Supprime le membre de manière définitive ou le marque comme inactif
/// selon la configuration de l'organisation
/// Lève une exception si le membre n'existe pas ou ne peut être supprimé
Future<void> call(String id) async {
return _repository.deleteMembre(id);
}
}

View File

@@ -0,0 +1,49 @@
/// Use case: Exporter la liste des membres
library export_members;
import 'package:injectable/injectable.dart';
import '../../../../shared/models/membre_search_criteria.dart';
import '../repositories/membre_repository.dart';
/// Use case pour exporter la liste des membres au format CSV ou PDF
/// Réservé aux utilisateurs avec le rôle ADMIN_ORGANISATION
@injectable
class ExportMembers {
final IMembreRepository _repository;
ExportMembers(this._repository);
/// Exécute le use case
///
/// [criteria] - Critères de filtre pour l'export (optionnel)
/// [format] - Format d'export ('csv' ou 'pdf')
///
/// Retourne les données exportées (liste complète des membres selon critères)
/// TODO: Ajouter endpoint backend GET /api/membres/export?format=csv|pdf
/// Le use case actuel récupère toutes les données, l'export final se fait côté UI
Future<List<Map<String, dynamic>>> call({
MembreSearchCriteria? criteria,
String format = 'csv',
}) async {
// Récupérer tous les membres (pagination large)
final result = await _repository.searchMembres(
criteria: criteria ?? const MembreSearchCriteria(),
page: 0,
size: 10000, // Grande pagination pour export complet
);
// Convertir en liste de maps pour l'export
return result.membres.map((membre) => {
'id': membre.id,
'nom': membre.nom,
'prenom': membre.prenom,
'email': membre.email,
'telephone': membre.telephone,
'adresse': membre.adresse,
'dateNaissance': membre.dateNaissance?.toIso8601String(),
'dateAdhesion': membre.dateAdhesion?.toIso8601String(),
'statut': membre.statut,
'actif': membre.actif,
}).toList();
}
}

View File

@@ -0,0 +1,24 @@
/// Use case: Récupérer un membre par son ID
library get_member_by_id;
import 'package:injectable/injectable.dart';
import '../../data/models/membre_complete_model.dart';
import '../repositories/membre_repository.dart';
/// Use case pour récupérer le détail complet d'un membre
@injectable
class GetMemberById {
final IMembreRepository _repository;
GetMemberById(this._repository);
/// Exécute le use case
///
/// [id] - UUID du membre
///
/// Retourne le détail complet du membre avec toutes ses informations
/// Retourne null si le membre n'existe pas
Future<MembreCompletModel?> call(String id) async {
return _repository.getMembreById(id);
}
}

View File

@@ -0,0 +1,29 @@
/// Use case: Récupérer les statistiques des membres
library get_member_stats;
import 'package:injectable/injectable.dart';
import '../repositories/membre_repository.dart';
/// Use case pour récupérer les statistiques globales des membres
/// Réservé aux utilisateurs avec le rôle ADMIN_ORGANISATION
@injectable
class GetMemberStats {
final IMembreRepository _repository;
GetMemberStats(this._repository);
/// Exécute le use case
///
/// Retourne un Map contenant les statistiques:
/// - totalMembres: Nombre total de membres
/// - membresActifs: Nombre de membres actifs
/// - membresInactifs: Nombre de membres inactifs
/// - nouveauxMembres30j: Nouveaux membres sur les 30 derniers jours
/// - membresBureau: Nombre de membres du bureau
/// - tauxActivite: Taux d'activité en pourcentage
///
/// Lève une exception en cas d'erreur d'accès
Future<Map<String, dynamic>> call() async {
return _repository.getMembresStats();
}
}

View File

@@ -0,0 +1,33 @@
/// Use case: Récupérer la liste des membres
library get_members;
import 'package:injectable/injectable.dart';
import '../../../../shared/models/membre_search_result.dart';
import '../repositories/membre_repository.dart';
/// Use case pour récupérer la liste des membres avec pagination
@injectable
class GetMembers {
final IMembreRepository _repository;
GetMembers(this._repository);
/// Exécute le use case
///
/// [page] - Numéro de page (pagination)
/// [size] - Taille de la page
/// [recherche] - Terme de recherche simple (optionnel)
///
/// Retourne la liste paginée des membres
Future<MembreSearchResult> call({
int page = 0,
int size = 20,
String? recherche,
}) async {
return _repository.getMembres(
page: page,
size: size,
recherche: recherche,
);
}
}

View File

@@ -0,0 +1,35 @@
/// Use case: Recherche avancée de membres
library search_members;
import 'package:injectable/injectable.dart';
import '../../../../shared/models/membre_search_result.dart';
import '../../../../shared/models/membre_search_criteria.dart';
import '../repositories/membre_repository.dart';
/// Use case pour effectuer une recherche avancée de membres
/// avec critères multiples (nom, email, téléphone, statut, rôle, organisation, etc.)
@injectable
class SearchMembers {
final IMembreRepository _repository;
SearchMembers(this._repository);
/// Exécute le use case
///
/// [criteria] - Critères de recherche avancée
/// [page] - Numéro de page (pagination)
/// [size] - Taille de la page
///
/// Retourne la liste paginée des membres correspondant aux critères
Future<MembreSearchResult> call({
required MembreSearchCriteria criteria,
int page = 0,
int size = 20,
}) async {
return _repository.searchMembres(
criteria: criteria,
page: page,
size: size,
);
}
}

View File

@@ -0,0 +1,26 @@
/// Use case: Mettre à jour un membre existant
library update_member;
import 'package:injectable/injectable.dart';
import '../../data/models/membre_complete_model.dart';
import '../repositories/membre_repository.dart';
/// Use case pour modifier un membre
/// Réservé aux utilisateurs avec le rôle HR_MANAGER
@injectable
class UpdateMember {
final IMembreRepository _repository;
UpdateMember(this._repository);
/// Exécute le use case
///
/// [id] - UUID du membre à modifier
/// [membre] - Données mises à jour
///
/// Retourne le membre modifié
/// Lève une exception si le membre n'existe pas ou erreur de validation
Future<MembreCompletModel> call(String id, MembreCompletModel membre) async {
return _repository.updateMembre(id, membre);
}
}