feat: Version 3.3.5 - Optimisations pages, améliorations ergonomie et affichages dynamiques stats
🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -140,12 +140,14 @@ class _HistoryContentState extends State<HistoryContent> {
|
||||
|
||||
// Sauvegarder aussi dans Hive pour la persistance
|
||||
_saveMemberFilter(widget.memberId!);
|
||||
} else if (!isAdmin) {
|
||||
// Pour un user standard, toujours filtrer sur son propre ID
|
||||
selectedMemberId = currentUserId;
|
||||
} else {
|
||||
// Admin sans memberId spécifique, charger les filtres depuis Hive
|
||||
// Pour tous les autres cas (admin et user), charger les filtres depuis Hive
|
||||
_loadPreselectedFilters();
|
||||
|
||||
// Pour un user standard, toujours filtrer sur son propre ID
|
||||
if (!isAdmin) {
|
||||
selectedMemberId = currentUserId;
|
||||
}
|
||||
}
|
||||
|
||||
_initializeNewFilters();
|
||||
@@ -385,7 +387,7 @@ class _HistoryContentState extends State<HistoryContent> {
|
||||
// Filtre Type de passage
|
||||
Expanded(
|
||||
child: DropdownButtonFormField<String>(
|
||||
initialValue: _selectedTypeFilter,
|
||||
value: _selectedTypeFilter,
|
||||
decoration: const InputDecoration(
|
||||
border: OutlineInputBorder(),
|
||||
contentPadding: EdgeInsets.symmetric(horizontal: 12, vertical: 8),
|
||||
@@ -418,7 +420,7 @@ class _HistoryContentState extends State<HistoryContent> {
|
||||
// Filtre Mode de règlement
|
||||
Expanded(
|
||||
child: DropdownButtonFormField<String>(
|
||||
initialValue: _selectedPaymentFilter,
|
||||
value: _selectedPaymentFilter,
|
||||
decoration: const InputDecoration(
|
||||
border: OutlineInputBorder(),
|
||||
contentPadding: EdgeInsets.symmetric(horizontal: 12, vertical: 8),
|
||||
@@ -473,7 +475,7 @@ class _HistoryContentState extends State<HistoryContent> {
|
||||
final sectors = sectorsBox.values.toList();
|
||||
|
||||
return DropdownButtonFormField<int?>(
|
||||
initialValue: _selectedSectorId,
|
||||
value: _selectedSectorId,
|
||||
decoration: const InputDecoration(
|
||||
border: OutlineInputBorder(),
|
||||
contentPadding: EdgeInsets.symmetric(horizontal: 12, vertical: 8),
|
||||
@@ -520,37 +522,30 @@ class _HistoryContentState extends State<HistoryContent> {
|
||||
const SizedBox(width: 12),
|
||||
if (isAdmin)
|
||||
Expanded(
|
||||
child: ValueListenableBuilder<Box<UserModel>>(
|
||||
valueListenable: Hive.box<UserModel>(AppKeys.userBoxName).listenable(),
|
||||
builder: (context, usersBox, child) {
|
||||
final users = usersBox.values.where((user) => user.role == 1).toList();
|
||||
|
||||
return DropdownButtonFormField<int?>(
|
||||
initialValue: _selectedUserId,
|
||||
decoration: const InputDecoration(
|
||||
border: OutlineInputBorder(),
|
||||
contentPadding: EdgeInsets.symmetric(horizontal: 12, vertical: 8),
|
||||
isDense: true,
|
||||
),
|
||||
items: [
|
||||
const DropdownMenuItem<int?>(
|
||||
value: null,
|
||||
child: Text('Membres'),
|
||||
),
|
||||
...users.map((UserModel user) {
|
||||
return DropdownMenuItem<int?>(
|
||||
value: user.id,
|
||||
child: Text('${user.firstName ?? ''} ${user.name ?? ''}'),
|
||||
);
|
||||
}),
|
||||
],
|
||||
onChanged: (int? newValue) {
|
||||
setState(() {
|
||||
_selectedUserId = newValue;
|
||||
});
|
||||
_notifyFiltersChanged();
|
||||
},
|
||||
);
|
||||
child: DropdownButtonFormField<int?>(
|
||||
value: _selectedUserId,
|
||||
decoration: const InputDecoration(
|
||||
border: OutlineInputBorder(),
|
||||
contentPadding: EdgeInsets.symmetric(horizontal: 12, vertical: 8),
|
||||
isDense: true,
|
||||
),
|
||||
items: [
|
||||
const DropdownMenuItem<int?>(
|
||||
value: null,
|
||||
child: Text('Membres'),
|
||||
),
|
||||
..._users.map((UserModel user) {
|
||||
return DropdownMenuItem<int?>(
|
||||
value: user.id,
|
||||
child: Text('${user.firstName ?? ''} ${user.name ?? ''}'),
|
||||
);
|
||||
}),
|
||||
],
|
||||
onChanged: (int? newValue) {
|
||||
setState(() {
|
||||
_selectedUserId = newValue;
|
||||
});
|
||||
_notifyFiltersChanged();
|
||||
},
|
||||
),
|
||||
)
|
||||
@@ -896,6 +891,7 @@ class _HistoryContentState extends State<HistoryContent> {
|
||||
if (memberId != null && memberId is int) {
|
||||
setState(() {
|
||||
selectedMemberId = memberId;
|
||||
_selectedUserId = memberId; // Synchroniser avec le nouveau filtre
|
||||
});
|
||||
debugPrint('HistoryPage: Membre présélectionné chargé: $memberId');
|
||||
}
|
||||
@@ -906,6 +902,7 @@ class _HistoryContentState extends State<HistoryContent> {
|
||||
if (sectorId != null && sectorId is int) {
|
||||
setState(() {
|
||||
selectedSectorId = sectorId;
|
||||
_selectedSectorId = sectorId; // Synchroniser avec le nouveau filtre
|
||||
});
|
||||
debugPrint('HistoryPage: Secteur présélectionné chargé: $sectorId');
|
||||
}
|
||||
@@ -917,6 +914,10 @@ class _HistoryContentState extends State<HistoryContent> {
|
||||
selectedTypeId = typeId;
|
||||
final typeInfo = AppKeys.typesPassages[typeId];
|
||||
selectedType = typeInfo != null ? typeInfo['titre'] as String : 'Inconnu';
|
||||
// Synchroniser avec le nouveau filtre
|
||||
if (typeInfo != null) {
|
||||
_selectedTypeFilter = typeInfo['titre'] as String;
|
||||
}
|
||||
});
|
||||
debugPrint('HistoryPage: Type de passage présélectionné: $typeId');
|
||||
}
|
||||
@@ -926,6 +927,12 @@ class _HistoryContentState extends State<HistoryContent> {
|
||||
if (paymentTypeId != null && paymentTypeId is int) {
|
||||
setState(() {
|
||||
selectedPaymentTypeId = paymentTypeId;
|
||||
_selectedPaymentTypeId = paymentTypeId; // Synchroniser avec le nouveau filtre
|
||||
// Mettre à jour aussi le label du filtre
|
||||
final paymentInfo = AppKeys.typesReglements[paymentTypeId];
|
||||
if (paymentInfo != null) {
|
||||
_selectedPaymentFilter = paymentInfo['titre'] as String;
|
||||
}
|
||||
});
|
||||
debugPrint('HistoryPage: Type de règlement présélectionné: $paymentTypeId');
|
||||
}
|
||||
@@ -1592,8 +1599,11 @@ class _HistoryContentState extends State<HistoryContent> {
|
||||
orElse: () => PassageModel.fromJson(passageMap),
|
||||
);
|
||||
|
||||
// Vérifier les permissions : admin peut tout éditer, user seulement ses propres passages
|
||||
if (isAdmin || passage.fkUser == currentUserId) {
|
||||
// Vérifier les permissions :
|
||||
// - Admin peut tout éditer
|
||||
// - User peut éditer ses propres passages
|
||||
// - Type 2 (À finaliser) : éditable par tous les utilisateurs
|
||||
if (isAdmin || passage.fkUser == currentUserId || passage.fkType == 2) {
|
||||
_handlePassageEdit(passage);
|
||||
} else {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
|
||||
@@ -93,13 +93,11 @@ class _HomeContentState extends State<HomeContent> {
|
||||
|
||||
// Tableau détaillé des membres - uniquement pour admin sur Web
|
||||
if (isAdmin && kIsWeb) ...[
|
||||
const MembersBoardPassages(
|
||||
height: 700,
|
||||
),
|
||||
const MembersBoardPassages(),
|
||||
const SizedBox(height: AppTheme.spacingL),
|
||||
],
|
||||
|
||||
// LIGNE 2 : Carte de répartition par secteur
|
||||
// LIGNE 2 : Carte de répartition par secteur (uniquement si > 1 secteur)
|
||||
// Le widget filtre automatiquement selon le rôle de l'utilisateur
|
||||
ValueListenableBuilder<Box<SectorModel>>(
|
||||
valueListenable: Hive.box<SectorModel>(AppKeys.sectorsBoxName).listenable(),
|
||||
@@ -113,9 +111,13 @@ class _HomeContentState extends State<HomeContent> {
|
||||
sectorCount = userSectors.length;
|
||||
}
|
||||
|
||||
// N'afficher que s'il y a plus d'un secteur
|
||||
if (sectorCount <= 1) {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
|
||||
return SectorDistributionCard(
|
||||
title: '$sectorCount secteur${sectorCount > 1 ? 's' : ''}',
|
||||
height: 500,
|
||||
title: '$sectorCount secteurs',
|
||||
);
|
||||
},
|
||||
),
|
||||
@@ -132,10 +134,9 @@ class _HomeContentState extends State<HomeContent> {
|
||||
child: ActivityChart(
|
||||
height: 350,
|
||||
showAllPassages: isAdmin, // Admin voit tout, user voit tous les passages de ses secteurs
|
||||
title: isAdmin
|
||||
? 'Passages réalisés par jour (15 derniers jours)'
|
||||
: 'Passages de mes secteurs par jour (15 derniers jours)',
|
||||
daysToShow: 15,
|
||||
title: isAdmin ? 'Passages' : 'Mes passages',
|
||||
daysToShow: 7,
|
||||
showPeriodButtons: true,
|
||||
),
|
||||
),
|
||||
|
||||
|
||||
Reference in New Issue
Block a user