feat: Début des évolutions interfaces mobiles v3.2.4
- Préparation de la nouvelle branche pour les évolutions - Mise à jour de la version vers 3.2.4 - Intégration des modifications en cours 🤖 Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -40,15 +40,10 @@ class _UserHistoryPageState extends State<UserHistoryPage> {
|
||||
// État du tri actuel
|
||||
PassageSortType _currentSort = PassageSortType.dateDesc;
|
||||
|
||||
// État des filtres
|
||||
String selectedSector = 'Tous';
|
||||
String selectedPeriod = 'Tous';
|
||||
String selectedType = 'Tous';
|
||||
String selectedPaymentMethod = 'Tous';
|
||||
DateTimeRange? selectedDateRange;
|
||||
|
||||
// IDs pour les filtres
|
||||
// État des filtres (uniquement pour synchronisation)
|
||||
int? selectedSectorId;
|
||||
String selectedPeriod = 'Toutes';
|
||||
DateTimeRange? selectedDateRange;
|
||||
|
||||
// Repository pour les secteurs
|
||||
late SectorRepository _sectorRepository;
|
||||
@@ -130,20 +125,11 @@ class _UserHistoryPageState extends State<UserHistoryPage> {
|
||||
try {
|
||||
// Charger le secteur présélectionné
|
||||
final int? preselectedSectorId = _settingsBox.get('history_selectedSectorId');
|
||||
final String? preselectedSectorName = _settingsBox.get('history_selectedSectorName');
|
||||
final int? preselectedTypeId = _settingsBox.get('history_selectedTypeId');
|
||||
final String? preselectedPeriod = _settingsBox.get('history_selectedPeriod');
|
||||
final int? preselectedPaymentId = _settingsBox.get('history_selectedPaymentId');
|
||||
|
||||
if (preselectedSectorId != null && preselectedSectorName != null) {
|
||||
if (preselectedSectorId != null) {
|
||||
selectedSectorId = preselectedSectorId;
|
||||
selectedSector = preselectedSectorName;
|
||||
debugPrint('Secteur présélectionné: $preselectedSectorName (ID: $preselectedSectorId)');
|
||||
}
|
||||
|
||||
if (preselectedTypeId != null) {
|
||||
selectedType = preselectedTypeId.toString();
|
||||
debugPrint('Type de passage présélectionné: $preselectedTypeId');
|
||||
debugPrint('Secteur présélectionné: ID $preselectedSectorId');
|
||||
}
|
||||
|
||||
if (preselectedPeriod != null) {
|
||||
@@ -152,11 +138,6 @@ class _UserHistoryPageState extends State<UserHistoryPage> {
|
||||
debugPrint('Période présélectionnée: $preselectedPeriod');
|
||||
}
|
||||
|
||||
if (preselectedPaymentId != null) {
|
||||
selectedPaymentMethod = preselectedPaymentId.toString();
|
||||
debugPrint('Mode de règlement présélectionné: $preselectedPaymentId');
|
||||
}
|
||||
|
||||
// Nettoyer les valeurs après utilisation
|
||||
_settingsBox.delete('history_selectedSectorId');
|
||||
_settingsBox.delete('history_selectedSectorName');
|
||||
@@ -173,26 +154,11 @@ class _UserHistoryPageState extends State<UserHistoryPage> {
|
||||
try {
|
||||
if (selectedSectorId != null) {
|
||||
_settingsBox.put('history_selectedSectorId', selectedSectorId);
|
||||
_settingsBox.put('history_selectedSectorName', selectedSector);
|
||||
}
|
||||
|
||||
if (selectedType != 'Tous') {
|
||||
final typeId = int.tryParse(selectedType);
|
||||
if (typeId != null) {
|
||||
_settingsBox.put('history_selectedTypeId', typeId);
|
||||
}
|
||||
}
|
||||
|
||||
if (selectedPeriod != 'Tous') {
|
||||
if (selectedPeriod != 'Toutes') {
|
||||
_settingsBox.put('history_selectedPeriod', selectedPeriod);
|
||||
}
|
||||
|
||||
if (selectedPaymentMethod != 'Tous') {
|
||||
final paymentId = int.tryParse(selectedPaymentMethod);
|
||||
if (paymentId != null) {
|
||||
_settingsBox.put('history_selectedPaymentId', paymentId);
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
debugPrint('Erreur lors de la sauvegarde des préférences: $e');
|
||||
}
|
||||
@@ -201,7 +167,6 @@ class _UserHistoryPageState extends State<UserHistoryPage> {
|
||||
// Mettre à jour le filtre par secteur
|
||||
void _updateSectorFilter(String sectorName, int? sectorId) {
|
||||
setState(() {
|
||||
selectedSector = sectorName;
|
||||
selectedSectorId = sectorId;
|
||||
});
|
||||
_saveFilterPreferences();
|
||||
@@ -328,21 +293,6 @@ class _UserHistoryPageState extends State<UserHistoryPage> {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Filtrer par type
|
||||
if (selectedType != 'Tous') {
|
||||
final typeId = int.tryParse(selectedType);
|
||||
if (typeId != null && passage['type'] != typeId) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Filtrer par mode de règlement
|
||||
if (selectedPaymentMethod != 'Tous') {
|
||||
final paymentId = int.tryParse(selectedPaymentMethod);
|
||||
if (paymentId != null && passage['payment'] != paymentId) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Filtrer par période/date
|
||||
if (selectedDateRange != null && passage['date'] is DateTime) {
|
||||
@@ -654,210 +604,9 @@ class _UserHistoryPageState extends State<UserHistoryPage> {
|
||||
);
|
||||
}
|
||||
|
||||
// Construction des filtres
|
||||
Widget _buildFilters(BuildContext context) {
|
||||
final theme = Theme.of(context);
|
||||
final size = MediaQuery.of(context).size;
|
||||
final isDesktop = size.width > 900;
|
||||
|
||||
return Card(
|
||||
elevation: 2,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
color: Colors.white.withValues(alpha: 0.95),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'Filtres',
|
||||
style: theme.textTheme.titleMedium?.copyWith(
|
||||
fontWeight: FontWeight.bold,
|
||||
color: theme.colorScheme.primary,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
|
||||
if (isDesktop)
|
||||
Row(
|
||||
children: [
|
||||
// Filtre par secteur (si plusieurs secteurs)
|
||||
if (_userSectors.length > 1)
|
||||
Expanded(
|
||||
child: _buildSectorFilter(theme),
|
||||
),
|
||||
if (_userSectors.length > 1)
|
||||
const SizedBox(width: 16),
|
||||
|
||||
// Filtre par période
|
||||
Expanded(
|
||||
child: _buildPeriodFilter(theme),
|
||||
),
|
||||
],
|
||||
)
|
||||
else
|
||||
Column(
|
||||
children: [
|
||||
// Filtre par secteur (si plusieurs secteurs)
|
||||
if (_userSectors.length > 1) ...[
|
||||
_buildSectorFilter(theme),
|
||||
const SizedBox(height: 16),
|
||||
],
|
||||
|
||||
// Filtre par période
|
||||
_buildPeriodFilter(theme),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
// Les filtres sont maintenant gérés directement dans le PassagesListWidget
|
||||
|
||||
// Construction du filtre par secteur
|
||||
Widget _buildSectorFilter(ThemeData theme) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'Secteur',
|
||||
style: theme.textTheme.bodyMedium?.copyWith(
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Container(
|
||||
width: double.infinity,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12.0),
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(color: theme.colorScheme.outline),
|
||||
borderRadius: BorderRadius.circular(8.0),
|
||||
),
|
||||
child: DropdownButtonHideUnderline(
|
||||
child: DropdownButton<String>(
|
||||
value: selectedSector,
|
||||
isExpanded: true,
|
||||
icon: const Icon(Icons.arrow_drop_down),
|
||||
items: [
|
||||
const DropdownMenuItem<String>(
|
||||
value: 'Tous',
|
||||
child: Text('Tous les secteurs'),
|
||||
),
|
||||
..._userSectors.map((sector) {
|
||||
final String libelle = sector.libelle.isNotEmpty
|
||||
? sector.libelle
|
||||
: 'Secteur ${sector.id}';
|
||||
return DropdownMenuItem<String>(
|
||||
value: libelle,
|
||||
child: Text(
|
||||
libelle,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
);
|
||||
}),
|
||||
],
|
||||
onChanged: (String? value) {
|
||||
if (value != null) {
|
||||
if (value == 'Tous') {
|
||||
_updateSectorFilter('Tous', null);
|
||||
} else {
|
||||
try {
|
||||
final sector = _userSectors.firstWhere(
|
||||
(s) => s.libelle == value,
|
||||
);
|
||||
_updateSectorFilter(value, sector.id);
|
||||
} catch (e) {
|
||||
debugPrint('Erreur lors de la sélection du secteur: $e');
|
||||
_updateSectorFilter('Tous', null);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
// Construction du filtre par période
|
||||
Widget _buildPeriodFilter(ThemeData theme) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'Période',
|
||||
style: theme.textTheme.bodyMedium?.copyWith(
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Container(
|
||||
width: double.infinity,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12.0),
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(color: theme.colorScheme.outline),
|
||||
borderRadius: BorderRadius.circular(8.0),
|
||||
),
|
||||
child: DropdownButtonHideUnderline(
|
||||
child: DropdownButton<String>(
|
||||
value: selectedPeriod,
|
||||
isExpanded: true,
|
||||
icon: const Icon(Icons.arrow_drop_down),
|
||||
items: const [
|
||||
DropdownMenuItem<String>(
|
||||
value: 'Tous',
|
||||
child: Text('Toutes les périodes'),
|
||||
),
|
||||
DropdownMenuItem<String>(
|
||||
value: 'Derniers 15 jours',
|
||||
child: Text('Derniers 15 jours'),
|
||||
),
|
||||
DropdownMenuItem<String>(
|
||||
value: 'Dernière semaine',
|
||||
child: Text('Dernière semaine'),
|
||||
),
|
||||
DropdownMenuItem<String>(
|
||||
value: 'Dernier mois',
|
||||
child: Text('Dernier mois'),
|
||||
),
|
||||
],
|
||||
onChanged: (String? value) {
|
||||
if (value != null) {
|
||||
_updatePeriodFilter(value);
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
// Afficher la plage de dates sélectionnée si elle existe
|
||||
if (selectedDateRange != null && selectedPeriod != 'Tous')
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 8.0),
|
||||
child: Row(
|
||||
children: [
|
||||
Icon(
|
||||
Icons.date_range,
|
||||
size: 16,
|
||||
color: theme.colorScheme.primary,
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
Text(
|
||||
'Du ${selectedDateRange!.start.day}/${selectedDateRange!.start.month}/${selectedDateRange!.start.year} au ${selectedDateRange!.end.day}/${selectedDateRange!.end.month}/${selectedDateRange!.end.year}',
|
||||
style: theme.textTheme.bodySmall?.copyWith(
|
||||
color: theme.colorScheme.primary,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
// Méthodes de filtre retirées car maintenant gérées dans le widget
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@@ -869,18 +618,7 @@ class _UserHistoryPageState extends State<UserHistoryPage> {
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
// Filtres avec bouton de rafraîchissement
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
// Filtres (secteur et période) avec bouton rafraîchir
|
||||
if (!_isLoading && (_userSectors.length > 1 || selectedPeriod != 'Tous'))
|
||||
_buildFilters(context),
|
||||
],
|
||||
),
|
||||
),
|
||||
// Les filtres sont maintenant intégrés dans le PassagesListWidget
|
||||
|
||||
// Affichage du chargement ou des erreurs
|
||||
if (_isLoading)
|
||||
@@ -944,14 +682,31 @@ class _UserHistoryPageState extends State<UserHistoryPage> {
|
||||
}
|
||||
}
|
||||
|
||||
// Appliquer les filtres
|
||||
passagesMap = _getFilteredPassages(passagesMap);
|
||||
|
||||
// Appliquer le tri sélectionné
|
||||
passagesMap = _sortPassages(passagesMap);
|
||||
|
||||
return PassagesListWidget(
|
||||
showAddButton: true, // Activer le bouton de création
|
||||
// Données
|
||||
passages: passagesMap,
|
||||
// Activation des filtres
|
||||
showFilters: true,
|
||||
showSearch: true,
|
||||
showTypeFilter: true,
|
||||
showPaymentFilter: true,
|
||||
showSectorFilter: true,
|
||||
showUserFilter: false, // Pas de filtre membre pour la page user
|
||||
showPeriodFilter: true,
|
||||
// Données pour les filtres
|
||||
sectors: _userSectors,
|
||||
members: null, // Pas de filtre membre pour la page user
|
||||
// Valeurs initiales
|
||||
initialSectorId: selectedSectorId,
|
||||
initialPeriod: selectedPeriod,
|
||||
dateRange: selectedDateRange,
|
||||
// Filtre par utilisateur courant
|
||||
filterByUserId: currentUserId,
|
||||
// Bouton d'ajout
|
||||
showAddButton: true,
|
||||
onAddPassage: () async {
|
||||
// Ouvrir le dialogue de création de passage
|
||||
await showDialog(
|
||||
@@ -1041,17 +796,17 @@ class _UserHistoryPageState extends State<UserHistoryPage> {
|
||||
),
|
||||
],
|
||||
),
|
||||
passages: passagesMap,
|
||||
showFilters: true,
|
||||
showSearch: true,
|
||||
// Actions
|
||||
showActions: true,
|
||||
initialSearchQuery: '',
|
||||
initialTypeFilter: selectedType,
|
||||
initialPaymentFilter: selectedPaymentMethod,
|
||||
excludePassageTypes: const [],
|
||||
filterByUserId: null, // Déjà filtré en amont
|
||||
key: const ValueKey('user_passages_list'),
|
||||
onPassageSelected: null,
|
||||
// Callback pour synchroniser les filtres
|
||||
onFiltersChanged: (filters) {
|
||||
setState(() {
|
||||
selectedSectorId = filters['sectorId'];
|
||||
selectedPeriod = filters['period'] ?? 'Toutes';
|
||||
selectedDateRange = filters['dateRange'];
|
||||
});
|
||||
},
|
||||
onDetailsView: (passage) {
|
||||
debugPrint('Affichage des détails: ${passage['id']}');
|
||||
_showPassageDetails(passage);
|
||||
|
||||
Reference in New Issue
Block a user