import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:intl/intl.dart'; import '../../core/constants/app_constants.dart'; import '../../core/theme/app_theme.dart'; import '../../data/models/session.dart'; import '../../data/models/target_type.dart'; import '../../data/repositories/session_repository.dart'; import 'session_detail_screen.dart'; import 'widgets/session_list_item.dart'; import 'widgets/history_chart.dart'; class HistoryScreen extends StatefulWidget { const HistoryScreen({super.key}); @override State createState() => _HistoryScreenState(); } class _HistoryScreenState extends State { List _sessions = []; bool _isLoading = true; TargetType? _filterType; @override void initState() { super.initState(); _loadSessions(); } Future _loadSessions() async { setState(() => _isLoading = true); try { final repository = context.read(); final sessions = await repository.getAllSessions( targetType: _filterType, ); if (mounted) { setState(() { _sessions = sessions; _isLoading = false; }); } } catch (e) { if (mounted) { setState(() => _isLoading = false); ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text('Erreur de chargement: $e'), backgroundColor: AppTheme.errorColor, ), ); } } } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('Historique'), actions: [ PopupMenuButton( icon: const Icon(Icons.filter_list), tooltip: 'Filtrer', onSelected: (type) { setState(() => _filterType = type); _loadSessions(); }, itemBuilder: (context) => [ const PopupMenuItem( value: null, child: Text('Tous'), ), ...TargetType.values.map((type) => PopupMenuItem( value: type, child: Text(type.displayName), )), ], ), ], ), body: _isLoading ? const Center(child: CircularProgressIndicator()) : _sessions.isEmpty ? _buildEmptyState() : _buildContent(), ); } Widget _buildEmptyState() { return Center( child: Padding( padding: const EdgeInsets.all(AppConstants.defaultPadding), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon(Icons.history, size: 64, color: Colors.grey[400]), const SizedBox(height: 16), Text( 'Aucune session', style: Theme.of(context).textTheme.titleLarge, ), const SizedBox(height: 8), Text( _filterType != null ? 'Aucune session de type ${_filterType!.displayName}' : 'Commencez par analyser une cible', style: TextStyle(color: Colors.grey[600]), textAlign: TextAlign.center, ), ], ), ), ); } Widget _buildContent() { return RefreshIndicator( onRefresh: _loadSessions, child: CustomScrollView( slivers: [ // Chart section if (_sessions.length >= 2) SliverToBoxAdapter( child: Padding( padding: const EdgeInsets.all(AppConstants.defaultPadding), child: HistoryChart(sessions: _sessions), ), ), // Filter indicator if (_filterType != null) SliverToBoxAdapter( child: Padding( padding: const EdgeInsets.symmetric(horizontal: AppConstants.defaultPadding), child: Chip( label: Text('Filtre: ${_filterType!.displayName}'), deleteIcon: const Icon(Icons.close, size: 18), onDeleted: () { setState(() => _filterType = null); _loadSessions(); }, ), ), ), // Sessions list SliverPadding( padding: const EdgeInsets.all(AppConstants.defaultPadding), sliver: SliverList( delegate: SliverChildBuilderDelegate( (context, index) { final session = _sessions[index]; return Padding( padding: const EdgeInsets.only(bottom: 12), child: SessionListItem( session: session, onTap: () => _openSessionDetail(session), onDelete: () => _deleteSession(session), ), ); }, childCount: _sessions.length, ), ), ), ], ), ); } void _openSessionDetail(Session session) async { await Navigator.push( context, MaterialPageRoute( builder: (_) => SessionDetailScreen(session: session), ), ); _loadSessions(); // Refresh in case session was deleted } Future _deleteSession(Session session) async { final confirmed = await showDialog( context: context, builder: (context) => AlertDialog( title: const Text('Supprimer'), content: Text( 'Supprimer la session du ${DateFormat('dd/MM/yyyy').format(session.createdAt)}?', ), actions: [ TextButton( onPressed: () => Navigator.pop(context, false), child: const Text('Annuler'), ), TextButton( onPressed: () => Navigator.pop(context, true), child: const Text('Supprimer', style: TextStyle(color: AppTheme.errorColor)), ), ], ), ); if (confirmed == true && mounted) { try { final repository = context.read(); await repository.deleteSession(session.id); _loadSessions(); if (mounted) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('Session supprimee')), ); } } catch (e) { if (mounted) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text('Erreur: $e'), backgroundColor: AppTheme.errorColor, ), ); } } } } }