feat(onboarding): UI/UX polish + mapping typeOrg + gestion erreur paiement Wave
Plan selection :
- Grille 2×2 compacte pour les plages (au lieu de liste verticale)
- Badge ⭐ POPULAIRE sur STANDARD
- Remise annuelle affichée (−X%/an)
- AnimatedSwitcher + auto-scroll vers formules quand plage sélectionnée
- Dark mode adaptatif complet
Récapitulatif :
- Dark mode complet (AppColors pairs)
- Bloc Total gradient gold adaptatif
- NoteBox avec backgrounds accent.withOpacity()
- Utilise OnboardingBottomBar (consistence)
Payment method :
- Dark mode + couleurs de marque Wave/Orange hardcodées (intentionnel)
- Logo container reste blanc (brand)
- Mapping typeOrganisation détaillé → enum backend ASSOCIATION/MUTUELLE/
COOPERATIVE/FEDERATION (fix HTTP 400 'Valeur invalide pour typeOrganisation')
Wave payment :
- Dark mode adaptatif
- Message dev clair (simulation automatique)
- Gestion OnboardingPaiementEchoue : SnackBar rouge + reset flags + reste sur page
(plus de faux succès quand confirmerPaiement() return false ou lève exception)
Bloc : nouvel état OnboardingPaiementEchoue, _onRetourDepuisWave vérifie le return
de confirmerPaiement() (plus de catch silencieux qui émettait OnboardingPaiementConfirme)
Shared widgets : OnboardingSectionTitle + OnboardingBottomBar dark mode + hint optionnel
This commit is contained in:
@@ -53,6 +53,43 @@ class SouscriptionDatasource {
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Mappe le type d'organisation détaillé (ex: MUTUELLE_EPARGNE, CLUB_SPORTIF)
|
||||
/// vers l'une des 4 catégories acceptées par le backend souscription :
|
||||
/// ASSOCIATION, MUTUELLE, COOPERATIVE, FEDERATION.
|
||||
static String? _mapTypeOrganisationBilling(String? detailedType) {
|
||||
if (detailedType == null || detailedType.isEmpty) return null;
|
||||
switch (detailedType.toUpperCase()) {
|
||||
// Catégorie ASSOCIATIF + RELIGIEUX
|
||||
case 'ASSOCIATION':
|
||||
case 'CLUB_SERVICE':
|
||||
case 'CLUB_SPORTIF':
|
||||
case 'CLUB_CULTUREL':
|
||||
case 'EGLISE':
|
||||
case 'GROUPE_PRIERE':
|
||||
return 'ASSOCIATION';
|
||||
// Catégorie FINANCIER_SOLIDAIRE (épargne/crédit)
|
||||
case 'TONTINE':
|
||||
case 'MUTUELLE_EPARGNE':
|
||||
case 'MUTUELLE_CREDIT':
|
||||
case 'MUTUELLE':
|
||||
return 'MUTUELLE';
|
||||
// Catégorie COOPERATIVE
|
||||
case 'COOPERATIVE':
|
||||
case 'GIE':
|
||||
return 'COOPERATIVE';
|
||||
// Catégorie PROFESSIONNEL + RESEAU_FEDERATION
|
||||
case 'ONG':
|
||||
case 'FONDATION':
|
||||
case 'SYNDICAT':
|
||||
case 'ORDRE_PROFESSIONNEL':
|
||||
case 'FEDERATION':
|
||||
case 'RESEAU':
|
||||
return 'FEDERATION';
|
||||
default:
|
||||
return 'ASSOCIATION'; // fallback sûr
|
||||
}
|
||||
}
|
||||
|
||||
/// Crée une demande de souscription
|
||||
Future<SouscriptionStatusModel?> creerDemande({
|
||||
required String typeFormule,
|
||||
@@ -63,14 +100,15 @@ class SouscriptionDatasource {
|
||||
}) async {
|
||||
try {
|
||||
final opts = await _authOptions();
|
||||
final mappedType = _mapTypeOrganisationBilling(typeOrganisation);
|
||||
final body = <String, dynamic>{
|
||||
'typeFormule': typeFormule,
|
||||
'plageMembres': plageMembres,
|
||||
'typePeriode': typePeriode,
|
||||
'organisationId': organisationId,
|
||||
};
|
||||
if (typeOrganisation != null && typeOrganisation.isNotEmpty) {
|
||||
body['typeOrganisation'] = typeOrganisation;
|
||||
if (mappedType != null && mappedType.isNotEmpty) {
|
||||
body['typeOrganisation'] = mappedType;
|
||||
}
|
||||
final response = await _dio.post(
|
||||
'$_base/api/souscriptions/demande',
|
||||
|
||||
Reference in New Issue
Block a user