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