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:
@@ -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),
|
||||
),
|
||||
|
||||
@@ -445,7 +445,7 @@ class _AdminOperationsPageState extends State<AdminOperationsPage> {
|
||||
bottomRight: Radius.circular(8),
|
||||
),
|
||||
border: Border.all(
|
||||
color: theme.colorScheme.primary.withValues(alpha: 0.1),
|
||||
color: theme.colorScheme.primary.withOpacity(0.1),
|
||||
width: 1,
|
||||
),
|
||||
),
|
||||
@@ -471,10 +471,10 @@ class _AdminOperationsPageState extends State<AdminOperationsPage> {
|
||||
|
||||
return Container(
|
||||
decoration: BoxDecoration(
|
||||
color: theme.colorScheme.primary.withValues(alpha: 0.1),
|
||||
color: theme.colorScheme.primary.withOpacity(0.1),
|
||||
border: Border(
|
||||
bottom: BorderSide(
|
||||
color: theme.dividerColor.withValues(alpha: 0.3),
|
||||
color: theme.dividerColor.withOpacity(0.3),
|
||||
width: 1,
|
||||
),
|
||||
),
|
||||
@@ -544,13 +544,13 @@ class _AdminOperationsPageState extends State<AdminOperationsPage> {
|
||||
|
||||
return InkWell(
|
||||
onTap: operation.isActive ? () => _showEditOperationDialog(operation) : null,
|
||||
hoverColor: operation.isActive ? theme.colorScheme.primary.withValues(alpha: 0.05) : null,
|
||||
hoverColor: operation.isActive ? theme.colorScheme.primary.withOpacity(0.05) : null,
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: backgroundColor,
|
||||
border: Border(
|
||||
bottom: BorderSide(
|
||||
color: theme.dividerColor.withValues(alpha: 0.3),
|
||||
color: theme.dividerColor.withOpacity(0.3),
|
||||
width: 1,
|
||||
),
|
||||
),
|
||||
@@ -582,7 +582,7 @@ class _AdminOperationsPageState extends State<AdminOperationsPage> {
|
||||
Icon(
|
||||
Icons.edit_outlined,
|
||||
size: 16,
|
||||
color: theme.colorScheme.primary.withValues(alpha: 0.6),
|
||||
color: theme.colorScheme.primary.withOpacity(0.6),
|
||||
),
|
||||
const SizedBox(width: 4),
|
||||
],
|
||||
@@ -768,7 +768,7 @@ class _AdminOperationsPageState extends State<AdminOperationsPage> {
|
||||
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),
|
||||
),
|
||||
@@ -783,7 +783,7 @@ class _AdminOperationsPageState extends State<AdminOperationsPage> {
|
||||
Icon(
|
||||
Icons.calendar_today_outlined,
|
||||
size: 64,
|
||||
color: theme.colorScheme.primary.withValues(alpha: 0.5),
|
||||
color: theme.colorScheme.primary.withOpacity(0.5),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
Text(
|
||||
@@ -796,7 +796,7 @@ class _AdminOperationsPageState extends State<AdminOperationsPage> {
|
||||
Text(
|
||||
"Cliquez sur 'Nouvelle opération' pour commencer",
|
||||
style: theme.textTheme.bodyLarge?.copyWith(
|
||||
color: theme.colorScheme.onSurface.withValues(alpha: 0.6),
|
||||
color: theme.colorScheme.onSurface.withOpacity(0.6),
|
||||
),
|
||||
),
|
||||
],
|
||||
|
||||
Reference in New Issue
Block a user