feat: passage du filtre date à une sélection de période (DateRange) dans l'historique

This commit is contained in:
qguillaume
2026-05-06 23:17:22 +02:00
parent be62669d56
commit 8946955f76

View File

@@ -21,7 +21,9 @@ class _HistoryScreenState extends State<HistoryScreen> {
List<Session> _sessions = [];
bool _isLoading = true;
TargetType? _filterType;
DateTime? _selectedDate; // --- AJOUT : Variable pour le filtre date ---
// --- MODIFICATION : Remplacement de DateTime par DateTimeRange ---
DateTimeRange? _selectedDateRange;
@override
void initState() {
@@ -30,25 +32,42 @@ class _HistoryScreenState extends State<HistoryScreen> {
}
Future<void> _loadSessions() async {
if (!mounted) return;
setState(() => _isLoading = true);
try {
final repository = context.read<SessionRepository>();
// On récupère toutes les sessions. Le filtrage visuel se fera dans la liste
// ou tu peux adapter ton repository pour accepter un DateTime.
final sessions = await repository.getAllSessions(targetType: _filterType);
if (mounted) {
setState(() {
_sessions = sessions;
if (_selectedDate != null) {
_sessions = _sessions
.where(
(s) =>
s.createdAt.year == _selectedDate!.year &&
s.createdAt.month == _selectedDate!.month &&
s.createdAt.day == _selectedDate!.day,
)
.toList();
// --- LOGIQUE DE FILTRAGE PAR PÉRIODE ---
if (_selectedDateRange != null) {
_sessions = _sessions.where((s) {
// On compare uniquement les dates (sans les heures) pour éviter les bugs
final sessionDate = DateTime(
s.createdAt.year,
s.createdAt.month,
s.createdAt.day,
);
final startDate = DateTime(
_selectedDateRange!.start.year,
_selectedDateRange!.start.month,
_selectedDateRange!.start.day,
);
final endDate = DateTime(
_selectedDateRange!.end.year,
_selectedDateRange!.end.month,
_selectedDateRange!.end.day,
);
return sessionDate.isAtSameMomentAs(startDate) ||
sessionDate.isAtSameMomentAs(endDate) ||
(sessionDate.isAfter(startDate) &&
sessionDate.isBefore(endDate));
}).toList();
}
_isLoading = false;
});
@@ -66,17 +85,31 @@ class _HistoryScreenState extends State<HistoryScreen> {
}
}
// --- AJOUT : Fonction DatePicker ---
Future<void> _pickDate() async {
final DateTime? picked = await showDatePicker(
// --- MODIFICATION : Fonction DateRangePicker ---
Future<void> _pickDateRange() async {
final DateTimeRange? picked = await showDateRangePicker(
context: context,
initialDate: _selectedDate ?? DateTime.now(),
initialDateRange: _selectedDateRange,
firstDate: DateTime(2020),
lastDate: DateTime.now(),
lastDate: DateTime.now().add(const Duration(days: 1)),
locale: const Locale('fr', 'FR'),
builder: (context, child) {
return Theme(
data: Theme.of(context).copyWith(
colorScheme: ColorScheme.dark(
primary: AppTheme.primaryColor,
onPrimary: Colors.white,
surface: Theme.of(context).cardColor,
onSurface: Colors.white,
),
),
child: child!,
);
},
);
if (picked != null) {
setState(() => _selectedDate = picked);
setState(() => _selectedDateRange = picked);
_loadSessions();
}
}
@@ -103,7 +136,6 @@ class _HistoryScreenState extends State<HistoryScreen> {
),
],
),
// --- MODIFICATION : Utilisation d'une Column pour fixer le bas ---
body: Column(
children: [
Expanded(
@@ -113,23 +145,22 @@ class _HistoryScreenState extends State<HistoryScreen> {
? _buildEmptyState()
: _buildContent(),
),
_buildBottomFilterBar(), // --- AJOUT : La barre de filtre en bas ---
_buildBottomFilterBar(),
],
),
);
}
// --- AJOUT : Widget de la barre du bas ---
Widget _buildBottomFilterBar() {
return Container(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
decoration: BoxDecoration(
color: Theme.of(context).cardColor,
boxShadow: [
boxShadow: const [
BoxShadow(
color: Colors.black12,
color: Colors.black26,
blurRadius: 4,
offset: const Offset(0, -2),
offset: Offset(0, -2),
),
],
),
@@ -139,23 +170,20 @@ class _HistoryScreenState extends State<HistoryScreen> {
children: [
Expanded(
child: OutlinedButton.icon(
onPressed: _pickDate,
icon: const Icon(Icons.calendar_today, size: 18),
onPressed: _pickDateRange,
icon: const Icon(Icons.date_range, size: 18),
label: Text(
_selectedDate == null
? 'Choisir une date'
: DateFormat(
'dd MMMM yyyy',
'fr_FR',
).format(_selectedDate!),
_selectedDateRange == null
? 'Choisir une période'
: '${DateFormat('dd/MM/yy').format(_selectedDateRange!.start)} - ${DateFormat('dd/MM/yy').format(_selectedDateRange!.end)}',
),
),
),
if (_selectedDate != null)
if (_selectedDateRange != null)
IconButton(
icon: const Icon(Icons.close, color: AppTheme.errorColor),
onPressed: () {
setState(() => _selectedDate = null);
setState(() => _selectedDateRange = null);
_loadSessions();
},
),
@@ -172,7 +200,7 @@ class _HistoryScreenState extends State<HistoryScreen> {
children: [
Icon(Icons.history, size: 64, color: Colors.grey[400]),
const SizedBox(height: 16),
const Text('Aucune session trouvée'),
const Text('Aucune session sur cette période'),
],
),
);
@@ -183,7 +211,7 @@ class _HistoryScreenState extends State<HistoryScreen> {
onRefresh: _loadSessions,
child: CustomScrollView(
slivers: [
if (_sessions.length >= 2 && _selectedDate == null)
if (_sessions.length >= 2 && _selectedDateRange == null)
SliverToBoxAdapter(
child: Padding(
padding: const EdgeInsets.all(AppConstants.defaultPadding),
@@ -211,7 +239,6 @@ class _HistoryScreenState extends State<HistoryScreen> {
);
}
// Les fonctions _openSessionDetail et _deleteSession restent identiques à ton code original
void _openSessionDetail(Session session) async {
await Navigator.push(
context,
@@ -250,7 +277,7 @@ class _HistoryScreenState extends State<HistoryScreen> {
await repository.deleteSession(session.id);
_loadSessions();
} catch (e) {
// ... snackbar d'erreur
debugPrint('Erreur suppression: $e');
}
}
}