feat: Mise à jour des interfaces mobiles v3.2.3

- Amélioration des interfaces utilisateur sur mobile
- Optimisation de la responsivité des composants Flutter
- Mise à jour des widgets de chat et communication
- Amélioration des formulaires et tableaux
- Ajout de nouveaux composants pour l'administration
- Optimisation des thèmes et styles visuels

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

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-09-02 20:35:40 +02:00
parent 08f4bff358
commit 43d4cd66e1
2133 changed files with 237004 additions and 173303 deletions

View File

@@ -138,14 +138,14 @@ class _AdminAmicalePageState extends State<AdminAmicalePage> {
if (context.mounted) {
Navigator.of(context).pop();
}
if (mounted) {
if (context.mounted) {
ApiException.showSuccess(context,
'Membre ${updatedMembre.firstName} ${updatedMembre.name} mis à jour');
}
}
} catch (e) {
debugPrint('❌ Erreur mise à jour membre: $e');
if (mounted) {
if (context.mounted) {
ApiException.showError(context, e);
}
}
@@ -348,9 +348,9 @@ class _AdminAmicalePageState extends State<AdminAmicalePage> {
Container(
padding: const EdgeInsets.all(12),
decoration: BoxDecoration(
color: Colors.blue.withOpacity(0.1),
color: Colors.blue.withValues(alpha: 0.1),
borderRadius: BorderRadius.circular(8),
border: Border.all(color: Colors.blue.withOpacity(0.3)),
border: Border.all(color: Colors.blue.withValues(alpha: 0.3)),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
@@ -373,7 +373,7 @@ class _AdminAmicalePageState extends State<AdminAmicalePage> {
),
const SizedBox(height: 8),
DropdownButtonFormField<int>(
value: selectedMemberForTransfer,
initialValue: selectedMemberForTransfer,
decoration: const InputDecoration(
labelText: 'Membre destinataire',
border: OutlineInputBorder(),
@@ -401,7 +401,7 @@ class _AdminAmicalePageState extends State<AdminAmicalePage> {
Container(
padding: const EdgeInsets.all(8),
decoration: BoxDecoration(
color: Colors.green.withOpacity(0.1),
color: Colors.green.withValues(alpha: 0.1),
borderRadius: BorderRadius.circular(4),
),
child: Row(
@@ -429,10 +429,10 @@ class _AdminAmicalePageState extends State<AdminAmicalePage> {
Container(
padding: const EdgeInsets.all(12),
decoration: BoxDecoration(
color: Colors.green.withOpacity(0.1),
color: Colors.green.withValues(alpha: 0.1),
borderRadius: BorderRadius.circular(8),
border:
Border.all(color: Colors.green.withOpacity(0.3)),
Border.all(color: Colors.green.withValues(alpha: 0.3)),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
@@ -652,18 +652,18 @@ class _AdminAmicalePageState extends State<AdminAmicalePage> {
}
// Afficher le message de succès avec les informations du membre créé
if (mounted) {
if (context.mounted) {
ApiException.showSuccess(context,
'Membre ${createdMembre.firstName} ${createdMembre.name} ajouté avec succès (ID: ${createdMembre.id})');
}
} else if (mounted) {
} 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'));
}
} catch (e) {
debugPrint('❌ Erreur création membre: $e');
if (mounted) {
if (context.mounted) {
// En cas d'exception, ne pas fermer le dialog
ApiException.showError(context, e);
}
@@ -701,9 +701,9 @@ class _AdminAmicalePageState extends State<AdminAmicalePage> {
padding: const EdgeInsets.all(12),
margin: const EdgeInsets.only(bottom: 16),
decoration: BoxDecoration(
color: Colors.red.withOpacity(0.1),
color: Colors.red.withValues(alpha: 0.1),
borderRadius: BorderRadius.circular(8),
border: Border.all(color: Colors.red.withOpacity(0.3)),
border: Border.all(color: Colors.red.withValues(alpha: 0.3)),
),
child: Row(
children: [
@@ -752,7 +752,7 @@ class _AdminAmicalePageState extends State<AdminAmicalePage> {
Icon(
Icons.business_outlined,
size: 64,
color: theme.colorScheme.primary.withOpacity(0.7),
color: theme.colorScheme.primary.withValues(alpha: 0.7),
),
const SizedBox(height: 16),
Text(
@@ -801,7 +801,7 @@ class _AdminAmicalePageState extends State<AdminAmicalePage> {
borderRadius: BorderRadius.circular(8),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.05),
color: Colors.black.withValues(alpha: 0.05),
blurRadius: 4,
offset: const Offset(0, 2),
),
@@ -852,7 +852,7 @@ class _AdminAmicalePageState extends State<AdminAmicalePage> {
borderRadius: BorderRadius.circular(8),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.05),
color: Colors.black.withValues(alpha: 0.05),
blurRadius: 4,
offset: const Offset(0, 2),
),

View File

@@ -12,7 +12,7 @@ class DotsPainter extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
final paint = Paint()
..color = Colors.white.withOpacity(0.5)
..color = Colors.white.withValues(alpha: 0.5)
..style = PaintingStyle.fill;
final random = math.Random(42); // Seed fixe pour consistance
@@ -220,31 +220,12 @@ class _AdminDashboardHomePageState extends State<AdminDashboardHomePage> {
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Titre avec bouton de rafraîchissement sur la même ligne
Row(
children: [
Expanded(
child: Text(
title,
style: Theme.of(context).textTheme.headlineSmall?.copyWith(
fontWeight: FontWeight.bold,
),
// Titre
Text(
title,
style: Theme.of(context).textTheme.titleLarge?.copyWith(
fontWeight: FontWeight.bold,
),
),
// Bouton de rafraîchissement
if (!isLoading)
IconButton(
icon: const Icon(Icons.refresh),
tooltip: 'Rafraîchir les données',
onPressed: _loadDashboardData,
)
else
const SizedBox(
width: 24,
height: 24,
child: CircularProgressIndicator(strokeWidth: 2),
),
],
),
const SizedBox(height: AppTheme.spacingM),
// Afficher un indicateur de chargement si les données ne sont pas encore chargées

View File

@@ -21,7 +21,7 @@ class DotsPainter extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
final paint = Paint()
..color = Colors.white.withOpacity(0.5)
..color = Colors.white.withValues(alpha: 0.5)
..style = PaintingStyle.fill;
final random = math.Random(42); // Seed fixe pour consistance

View File

@@ -36,7 +36,7 @@ class AdminDebugInfoWidget extends StatelessWidget {
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8.0),
),
tileColor: Colors.grey.withOpacity(0.1),
tileColor: Colors.grey.withValues(alpha: 0.1),
),
// Autres options de débogage peuvent être ajoutées ici
],

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -445,7 +445,7 @@ class _AdminOperationsPageState extends State<AdminOperationsPage> {
bottomRight: Radius.circular(8),
),
border: Border.all(
color: theme.colorScheme.primary.withOpacity(0.1),
color: theme.colorScheme.primary.withValues(alpha: 0.1),
width: 1,
),
),
@@ -471,10 +471,10 @@ class _AdminOperationsPageState extends State<AdminOperationsPage> {
return Container(
decoration: BoxDecoration(
color: theme.colorScheme.primary.withOpacity(0.1),
color: theme.colorScheme.primary.withValues(alpha: 0.1),
border: Border(
bottom: BorderSide(
color: theme.dividerColor.withOpacity(0.3),
color: theme.dividerColor.withValues(alpha: 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.withOpacity(0.05) : null,
hoverColor: operation.isActive ? theme.colorScheme.primary.withValues(alpha: 0.05) : null,
child: Container(
decoration: BoxDecoration(
color: backgroundColor,
border: Border(
bottom: BorderSide(
color: theme.dividerColor.withOpacity(0.3),
color: theme.dividerColor.withValues(alpha: 0.3),
width: 1,
),
),
@@ -582,7 +582,7 @@ class _AdminOperationsPageState extends State<AdminOperationsPage> {
Icon(
Icons.edit_outlined,
size: 16,
color: theme.colorScheme.primary.withOpacity(0.6),
color: theme.colorScheme.primary.withValues(alpha: 0.6),
),
const SizedBox(width: 4),
],
@@ -768,7 +768,7 @@ class _AdminOperationsPageState extends State<AdminOperationsPage> {
borderRadius: BorderRadius.circular(8),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.05),
color: Colors.black.withValues(alpha: 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.withOpacity(0.5),
color: theme.colorScheme.primary.withValues(alpha: 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.withOpacity(0.6),
color: theme.colorScheme.onSurface.withValues(alpha: 0.6),
),
),
],

View File

@@ -13,7 +13,7 @@ class DotsPainter extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
final paint = Paint()
..color = Colors.white.withOpacity(0.5)
..color = Colors.white.withValues(alpha: 0.5)
..style = PaintingStyle.fill;
final random = math.Random(42); // Seed fixe pour consistance
@@ -178,22 +178,6 @@ class _AdminStatisticsPageState extends State<AdminStatisticsPage> {
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Titre et description
Text(
'Analyse des statistiques',
style: Theme.of(context).textTheme.headlineSmall?.copyWith(
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: AppTheme.spacingS),
Text(
'Visualisez les statistiques de passages et de collecte pour votre amicale.',
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
color: Colors.grey[600],
),
),
const SizedBox(height: AppTheme.spacingL),
// Filtres
Card(
elevation: 2,
@@ -598,31 +582,8 @@ class _AdminStatisticsPageState extends State<AdminStatisticsPage> {
}
// Méthode pour obtenir tous les IDs des membres d'un secteur
List<int> _getMemberIdsForSector(int sectorId) {
return _userSectors
.where((us) => us.fkSector == sectorId)
.map((us) => us.id)
.toList();
}
// Méthode pour déterminer quel userId utiliser pour les graphiques
int? _getUserIdForCharts() {
// Si un membre spécifique est sélectionné, utiliser son ID
if (_selectedMember != 'Tous') {
return _getMemberIdFromName(_selectedMember);
}
// Si un secteur est sélectionné mais pas de membre spécifique
// Les widgets actuels ne supportent pas plusieurs userIds
// Donc on ne peut pas filtrer par secteur pour le moment
// TODO: Implémenter le support multi-users ou sectorId dans les widgets
return null; // Afficher tous les passages
}
// Méthode pour déterminer si on doit afficher tous les passages
bool _shouldShowAllPassages() {
// Afficher tous les passages seulement si aucun filtre n'est appliqué
return _selectedMember == 'Tous' && _selectedSector == 'Tous';
}
}