feat: Version 3.5.2 - Configuration Stripe et gestion des immeubles

- Configuration complète Stripe pour les 3 environnements (DEV/REC/PROD)
  * DEV: Clés TEST Pierre (mode test)
  * REC: Clés TEST Client (mode test)
  * PROD: Clés LIVE Client (mode live)
- Ajout de la gestion des bases de données immeubles/bâtiments
  * Configuration buildings_database pour DEV/REC/PROD
  * Service BuildingService pour enrichissement des adresses
- Optimisations pages et améliorations ergonomie
- Mises à jour des dépendances Composer
- Nettoyage des fichiers obsolètes

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
pierre
2025-11-09 18:26:27 +01:00
parent 21657a3820
commit 2f5946a184
812 changed files with 142105 additions and 25992 deletions

View File

@@ -13,6 +13,8 @@ import 'package:geosector_app/presentation/widgets/membre_table_widget.dart';
import 'package:geosector_app/core/utils/api_exception.dart';
import 'package:geosector_app/core/repositories/passage_repository.dart';
import 'package:geosector_app/core/repositories/operation_repository.dart';
import 'package:geosector_app/presentation/widgets/loading_spin_overlay.dart';
import 'package:geosector_app/presentation/widgets/result_dialog.dart';
/// Page d'administration de l'amicale et des membres
/// Cette page est intégrée dans le tableau de bord administrateur
@@ -123,6 +125,12 @@ class _AdminAmicalePageState extends State<AdminAmicalePage> {
),
],
onSubmit: (updatedUser, {String? password}) async {
// Afficher le loading
final overlay = LoadingSpinOverlayUtils.show(
context: context,
message: 'Mise à jour en cours...',
);
try {
// Convertir le UserModel mis à jour vers MembreModel
final updatedMembre =
@@ -134,19 +142,33 @@ class _AdminAmicalePageState extends State<AdminAmicalePage> {
password: password,
);
if (success) {
// Masquer le loading
LoadingSpinOverlayUtils.hideSpecific(overlay);
if (success && context.mounted) {
// Afficher le résultat de succès
await ResultDialog.show(
context: context,
success: true,
message: 'Membre ${updatedMembre.firstName} ${updatedMembre.name} mis à jour',
);
if (context.mounted) {
Navigator.of(context).pop();
}
if (context.mounted) {
ApiException.showSuccess(context,
'Membre ${updatedMembre.firstName} ${updatedMembre.name} mis à jour');
}
}
} catch (e) {
debugPrint('❌ Erreur mise à jour membre: $e');
// Masquer le loading
LoadingSpinOverlayUtils.hideSpecific(overlay);
if (context.mounted) {
ApiException.showError(context, e);
await ResultDialog.show(
context: context,
success: false,
message: ApiException.fromError(e).message,
);
}
}
},
@@ -230,10 +252,10 @@ class _AdminAmicalePageState extends State<AdminAmicalePage> {
debugPrint('🎯 Opération courante: $_currentOperationId');
// Filtrer les passages par opération courante ET par utilisateur
// Filtrer les passages par opération courante ET par utilisateur (utiliser opeUserId)
final allUserPassages =
widget.passageRepository.getPassagesByUser(membre.id);
debugPrint('📊 Total passages du membre: ${allUserPassages.length}');
widget.passageRepository.getPassagesByUser(membre.opeUserId ?? 0);
debugPrint('📊 Total passages du membre (opeUserId=${membre.opeUserId}): ${allUserPassages.length}');
final passagesRealises = allUserPassages
.where((passage) =>
@@ -348,9 +370,9 @@ class _AdminAmicalePageState extends State<AdminAmicalePage> {
Container(
padding: const EdgeInsets.all(12),
decoration: BoxDecoration(
color: Colors.blue.withValues(alpha: 0.1),
color: Colors.blue.withOpacity(0.1),
borderRadius: BorderRadius.circular(8),
border: Border.all(color: Colors.blue.withValues(alpha: 0.3)),
border: Border.all(color: Colors.blue.withOpacity(0.3)),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
@@ -373,7 +395,7 @@ class _AdminAmicalePageState extends State<AdminAmicalePage> {
),
const SizedBox(height: 8),
DropdownButtonFormField<int>(
initialValue: selectedMemberForTransfer,
value: selectedMemberForTransfer,
decoration: const InputDecoration(
labelText: 'Membre destinataire',
border: OutlineInputBorder(),
@@ -401,7 +423,7 @@ class _AdminAmicalePageState extends State<AdminAmicalePage> {
Container(
padding: const EdgeInsets.all(8),
decoration: BoxDecoration(
color: Colors.green.withValues(alpha: 0.1),
color: Colors.green.withOpacity(0.1),
borderRadius: BorderRadius.circular(4),
),
child: Row(
@@ -429,10 +451,10 @@ class _AdminAmicalePageState extends State<AdminAmicalePage> {
Container(
padding: const EdgeInsets.all(12),
decoration: BoxDecoration(
color: Colors.green.withValues(alpha: 0.1),
color: Colors.green.withOpacity(0.1),
borderRadius: BorderRadius.circular(8),
border:
Border.all(color: Colors.green.withValues(alpha: 0.3)),
Border.all(color: Colors.green.withOpacity(0.3)),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
@@ -619,6 +641,12 @@ class _AdminAmicalePageState extends State<AdminAmicalePage> {
),
],
onSubmit: (newUserData, {String? password}) async {
// Afficher le loading
final overlay = LoadingSpinOverlayUtils.show(
context: context,
message: 'Création en cours...',
);
try {
// Créer un nouveau MembreModel directement
final newMembre = MembreModel(
@@ -645,27 +673,41 @@ class _AdminAmicalePageState extends State<AdminAmicalePage> {
password: password,
);
if (createdMembre != null) {
// Fermer le dialog
// Masquer le loading
LoadingSpinOverlayUtils.hideSpecific(overlay);
if (createdMembre != null && context.mounted) {
// Afficher le résultat de succès
await ResultDialog.show(
context: context,
success: true,
message: 'Membre ${createdMembre.firstName} ${createdMembre.name} ajouté avec succès (ID: ${createdMembre.id})',
);
if (context.mounted) {
Navigator.of(context).pop();
}
// Afficher le message de succès avec les informations du membre créé
if (context.mounted) {
ApiException.showSuccess(context,
'Membre ${createdMembre.firstName} ${createdMembre.name} ajouté avec succès (ID: ${createdMembre.id})');
}
} else if (context.mounted) {
// En cas d'échec, ne pas fermer le dialog pour permettre la correction
ApiException.showError(
context, Exception('Erreur lors de la création du membre'));
await ResultDialog.show(
context: context,
success: false,
message: 'Erreur lors de la création du membre',
);
}
} catch (e) {
debugPrint('❌ Erreur création membre: $e');
// Masquer le loading
LoadingSpinOverlayUtils.hideSpecific(overlay);
if (context.mounted) {
// En cas d'exception, ne pas fermer le dialog
ApiException.showError(context, e);
await ResultDialog.show(
context: context,
success: false,
message: ApiException.fromError(e).message,
);
}
}
},
@@ -701,9 +743,9 @@ class _AdminAmicalePageState extends State<AdminAmicalePage> {
padding: const EdgeInsets.all(12),
margin: const EdgeInsets.only(bottom: 16),
decoration: BoxDecoration(
color: Colors.red.withValues(alpha: 0.1),
color: Colors.red.withOpacity(0.1),
borderRadius: BorderRadius.circular(8),
border: Border.all(color: Colors.red.withValues(alpha: 0.3)),
border: Border.all(color: Colors.red.withOpacity(0.3)),
),
child: Row(
children: [
@@ -752,7 +794,7 @@ class _AdminAmicalePageState extends State<AdminAmicalePage> {
Icon(
Icons.business_outlined,
size: 64,
color: theme.colorScheme.primary.withValues(alpha: 0.7),
color: theme.colorScheme.primary.withOpacity(0.7),
),
const SizedBox(height: 16),
Text(
@@ -801,7 +843,7 @@ class _AdminAmicalePageState extends State<AdminAmicalePage> {
borderRadius: BorderRadius.circular(8),
boxShadow: [
BoxShadow(
color: Colors.black.withValues(alpha: 0.05),
color: Colors.black.withOpacity(0.05),
blurRadius: 4,
offset: const Offset(0, 2),
),
@@ -852,7 +894,7 @@ class _AdminAmicalePageState extends State<AdminAmicalePage> {
borderRadius: BorderRadius.circular(8),
boxShadow: [
BoxShadow(
color: Colors.black.withValues(alpha: 0.05),
color: Colors.black.withOpacity(0.05),
blurRadius: 4,
offset: const Offset(0, 2),
),