fix(mobile): URL changement mdp corrigée + v3.0 — multi-org, AppAuth, sécurité prod

Auth:
- profile_repository.dart: /api/auth/change-password → /api/membres/auth/change-password

Multi-org (Phase 3):
- OrgSelectorPage, OrgSwitcherBloc, OrgSwitcherEntry
- org_context_service.dart: headers X-Active-Organisation-Id + X-Active-Role

Navigation:
- MorePage: navigation conditionnelle par typeOrganisation
- Suppression adaptive_navigation (remplacé par main_navigation_layout)

Auth AppAuth:
- keycloak_webview_auth_service: fixes AppAuth Android
- AuthBloc: gestion REAUTH_REQUIS + premierLoginComplet

Onboarding:
- Nouveaux états: payment_method_page, onboarding_shared_widgets
- SouscriptionStatusModel mis à jour StatutValidationSouscription

Android:
- build.gradle: ProGuard/R8, network_security_config
- Gradle wrapper mis à jour
This commit is contained in:
dahoud
2026-04-07 20:56:03 +00:00
parent 22f9c7e9a1
commit 70cbd1c873
63 changed files with 9316 additions and 6122 deletions

View File

@@ -0,0 +1,73 @@
/// Modèle pour un item du sélecteur d'organisation.
/// Mappé depuis GET /api/membres/mes-organisations.
library org_switcher_entry;
import 'package:equatable/equatable.dart';
class OrgSwitcherEntry extends Equatable {
final String organisationId;
final String nom;
final String? nomCourt;
final String typeOrganisation;
final String? categorieType;
final String? modulesActifs;
final String? statut;
final String? statutMembre;
final String? roleOrg;
final String? dateAdhesion;
const OrgSwitcherEntry({
required this.organisationId,
required this.nom,
this.nomCourt,
required this.typeOrganisation,
this.categorieType,
this.modulesActifs,
this.statut,
this.statutMembre,
this.roleOrg,
this.dateAdhesion,
});
/// Libellé court pour le switcher (nomCourt ou nom tronqué).
String get libelleCourt {
if (nomCourt != null && nomCourt!.isNotEmpty) return nomCourt!;
if (nom.length > 25) return '${nom.substring(0, 22)}';
return nom;
}
/// Modules actifs parsés en Set<String>.
Set<String> get modulesActifsSet {
if (modulesActifs == null || modulesActifs!.isEmpty) return {};
return modulesActifs!.split(',').map((m) => m.trim()).toSet();
}
factory OrgSwitcherEntry.fromJson(Map<String, dynamic> json) {
return OrgSwitcherEntry(
organisationId: json['organisationId']?.toString() ?? '',
nom: json['nom']?.toString() ?? '',
nomCourt: json['nomCourt']?.toString(),
typeOrganisation: json['typeOrganisation']?.toString() ?? '',
categorieType: json['categorieType']?.toString(),
modulesActifs: json['modulesActifs']?.toString(),
statut: json['statut']?.toString(),
statutMembre: json['statutMembre']?.toString(),
roleOrg: json['roleOrg']?.toString(),
dateAdhesion: json['dateAdhesion']?.toString(),
);
}
@override
List<Object?> get props => [
organisationId,
nom,
nomCourt,
typeOrganisation,
categorieType,
modulesActifs,
statut,
statutMembre,
roleOrg,
dateAdhesion,
];
}