feat: passage du filtre date à une sélection de période (DateRange) dans l'historique
This commit is contained in:
@@ -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');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user