Files
impact/lib/features/home/home_screen.dart

229 lines
6.4 KiB
Dart

/// Écran d'accueil - Dashboard principal de l'application.
///
/// Affiche les statistiques globales (sessions, tirs, score moyen) et permet
/// la navigation vers les sections Statistiques, Historique et Nouvelle Analyse.
library;
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import '../../core/constants/app_constants.dart';
import '../../core/theme/app_theme.dart';
import '../../data/repositories/session_repository.dart';
import '../capture/capture_screen.dart';
import '../history/history_screen.dart';
import '../statistics/statistics_screen.dart';
import 'widgets/stats_card.dart';
class HomeScreen extends StatefulWidget {
const HomeScreen({super.key});
@override
State<HomeScreen> createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
Map<String, dynamic>? _stats;
bool _isLoading = true;
@override
void initState() {
super.initState();
_loadStats();
}
Future<void> _loadStats() async {
final repository = context.read<SessionRepository>();
final stats = await repository.getStatistics();
if (mounted) {
setState(() {
_stats = stats;
_isLoading = false;
});
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Bully'),
actions: [
IconButton(
icon: const Icon(Icons.analytics),
onPressed: () => _navigateToStatistics(context),
tooltip: 'Statistiques',
),
IconButton(
icon: const Icon(Icons.history),
onPressed: () => _navigateToHistory(context),
tooltip: 'Historique',
),
],
),
body: RefreshIndicator(
onRefresh: _loadStats,
child: SingleChildScrollView(
physics: const AlwaysScrollableScrollPhysics(),
padding: const EdgeInsets.all(AppConstants.defaultPadding),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
// App logo/header
_buildHeader(),
const SizedBox(height: AppConstants.largePadding),
// Main action button
_buildMainActionButton(context),
const SizedBox(height: AppConstants.largePadding),
// Statistics section
if (_isLoading)
const Center(child: CircularProgressIndicator())
else if (_stats != null)
_buildStatsSection(),
],
),
),
),
);
}
Widget _buildHeader() {
return Column(
children: [
Container(
padding: const EdgeInsets.all(24),
decoration: BoxDecoration(
color: AppTheme.primaryColor.withValues(alpha: 0.1),
shape: BoxShape.circle,
),
child: const Icon(
Icons.track_changes,
size: 64,
color: AppTheme.primaryColor,
),
),
const SizedBox(height: 16),
Text(
'Analyse de Cibles',
style: Theme.of(context).textTheme.headlineMedium?.copyWith(
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 8),
Text(
'Scannez vos cibles et analysez vos performances',
style: Theme.of(context).textTheme.bodyLarge?.copyWith(
color: AppTheme.textSecondary,
),
textAlign: TextAlign.center,
),
],
);
}
Widget _buildMainActionButton(BuildContext context) {
return ElevatedButton.icon(
onPressed: () => _navigateToCapture(context),
style: ElevatedButton.styleFrom(
backgroundColor: AppTheme.primaryColor,
foregroundColor: Colors.white,
padding: const EdgeInsets.symmetric(vertical: 20),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(AppConstants.borderRadius),
),
),
icon: const Icon(Icons.add_a_photo, size: 28),
label: const Text(
'Nouvelle Analyse',
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
),
);
}
Widget _buildStatsSection() {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Statistiques',
style: Theme.of(context).textTheme.titleLarge?.copyWith(
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 12),
Row(
children: [
Expanded(
child: StatsCard(
icon: Icons.assessment,
title: 'Sessions',
value: '${_stats!['totalSessions']}',
color: AppTheme.primaryColor,
),
),
const SizedBox(width: 12),
Expanded(
child: StatsCard(
icon: Icons.gps_fixed,
title: 'Tirs',
value: '${_stats!['totalShots']}',
color: AppTheme.secondaryColor,
),
),
],
),
const SizedBox(height: 12),
Row(
children: [
Expanded(
child: StatsCard(
icon: Icons.trending_up,
title: 'Score Moyen',
value: (_stats!['averageScore'] as double).toStringAsFixed(1),
color: AppTheme.warningColor,
),
),
const SizedBox(width: 12),
Expanded(
child: StatsCard(
icon: Icons.emoji_events,
title: 'Meilleur',
value: '${_stats!['bestScore']}',
color: AppTheme.successColor,
),
),
],
),
],
);
}
void _navigateToCapture(BuildContext context) async {
await Navigator.push(
context,
MaterialPageRoute(builder: (_) => const CaptureScreen()),
);
// Refresh stats when returning
_loadStats();
}
void _navigateToHistory(BuildContext context) async {
await Navigator.push(
context,
MaterialPageRoute(builder: (_) => const HistoryScreen()),
);
// Refresh stats when returning
_loadStats();
}
void _navigateToStatistics(BuildContext context) async {
await Navigator.push(
context,
MaterialPageRoute(builder: (_) => const StatisticsScreen()),
);
// Refresh stats when returning
_loadStats();
}
}