Lorsqu'on termine la session et qu'on a l'écran d'accueil > exécuter un refresh automatique pour prendre en compte cette dernière sessions dans les star de l'écran d'accueil. Actuellement il faut refresh manuellement pour que ce soit pris en compte -Dans Armurerie > Mon arme > le nb de session n'est pas remonté Ajouter un date picker pour y inscrire une date de l'entretien et qu'elle apparaisse dans la liste en bas (dans la modale ajouter un entretien)

This commit is contained in:
qguillaume
2026-06-19 13:09:52 +02:00
parent 0564bdbb48
commit f7fecf0ef2
4 changed files with 74 additions and 2 deletions

View File

@@ -509,6 +509,16 @@ class DatabaseHelper {
return Sqflite.firstIntValue(result) ?? 0; return Sqflite.firstIntValue(result) ?? 0;
} }
Future<int> getSessionCountForWeapon(String weaponId) async {
final db = await database;
final result = await db.rawQuery('''
SELECT COUNT(id) as count
FROM ${AppConstants.sessionsTable}
WHERE weapon_id = ?
''', [weaponId]);
return Sqflite.firstIntValue(result) ?? 0;
}
Future<int> insertMaintenance(MaintenanceEntry entry) async { Future<int> insertMaintenance(MaintenanceEntry entry) async {
final db = await database; final db = await database;
return await db.insert( return await db.insert(

View File

@@ -182,18 +182,23 @@ class SessionRepository {
return await _databaseHelper.getRoundsFiredForWeapon(weaponId); return await _databaseHelper.getRoundsFiredForWeapon(weaponId);
} }
Future<int> getSessionCountForWeapon(String weaponId) async {
return await _databaseHelper.getSessionCountForWeapon(weaponId);
}
Future<void> addMaintenanceEntry({ Future<void> addMaintenanceEntry({
required String weaponId, required String weaponId,
required MaintenanceType type, required MaintenanceType type,
required String description, required String description,
int? roundsSinceLast, int? roundsSinceLast,
DateTime? date,
}) async { }) async {
final entry = MaintenanceEntry( final entry = MaintenanceEntry(
id: _uuid.v4(), id: _uuid.v4(),
weaponId: weaponId, weaponId: weaponId,
type: type, type: type,
description: description, description: description,
date: DateTime.now(), date: date ?? DateTime.now(),
roundsSinceLastMaintenance: roundsSinceLast, roundsSinceLastMaintenance: roundsSinceLast,
); );
await _databaseHelper.insertMaintenance(entry); await _databaseHelper.insertMaintenance(entry);

View File

@@ -19,6 +19,7 @@ class _WeaponDetailScreenState extends State<WeaponDetailScreen> {
late Weapon _weapon; late Weapon _weapon;
List<MaintenanceEntry> _maintenance = []; List<MaintenanceEntry> _maintenance = [];
int _totalRounds = 0; int _totalRounds = 0;
int _sessionCount = 0;
bool _isLoading = true; bool _isLoading = true;
@override @override
@@ -32,10 +33,12 @@ class _WeaponDetailScreenState extends State<WeaponDetailScreen> {
final repository = context.read<SessionRepository>(); final repository = context.read<SessionRepository>();
final history = await repository.getMaintenanceHistory(_weapon.id); final history = await repository.getMaintenanceHistory(_weapon.id);
final rounds = await repository.getRoundsFiredForWeapon(_weapon.id); final rounds = await repository.getRoundsFiredForWeapon(_weapon.id);
final sessions = await repository.getSessionCountForWeapon(_weapon.id);
if (mounted) { if (mounted) {
setState(() { setState(() {
_maintenance = history; _maintenance = history;
_totalRounds = rounds; _totalRounds = rounds;
_sessionCount = sessions;
_isLoading = false; _isLoading = false;
}); });
} }
@@ -93,7 +96,7 @@ class _WeaponDetailScreenState extends State<WeaponDetailScreen> {
Expanded( Expanded(
child: _buildStatCard( child: _buildStatCard(
'Sessions', 'Sessions',
'N/A', _sessionCount.toString(),
Icons.history, Icons.history,
Colors.orange, Colors.orange,
), ),
@@ -347,6 +350,7 @@ class _WeaponDetailScreenState extends State<WeaponDetailScreen> {
void _showAddMaintenanceDialog(BuildContext context) async { void _showAddMaintenanceDialog(BuildContext context) async {
final descController = TextEditingController(); final descController = TextEditingController();
MaintenanceType selectedType = MaintenanceType.cleaning; MaintenanceType selectedType = MaintenanceType.cleaning;
DateTime selectedDate = DateTime.now();
final result = await showDialog<bool>( final result = await showDialog<bool>(
context: context, context: context,
@@ -367,6 +371,27 @@ class _WeaponDetailScreenState extends State<WeaponDetailScreen> {
decoration: const InputDecoration(labelText: 'Description', hintText: 'ex: Nettoyage complet après séance'), decoration: const InputDecoration(labelText: 'Description', hintText: 'ex: Nettoyage complet après séance'),
maxLines: 2, maxLines: 2,
), ),
const SizedBox(height: 8),
InkWell(
onTap: () async {
final picked = await showDatePicker(
context: context,
initialDate: selectedDate,
firstDate: DateTime(2000),
lastDate: DateTime.now(),
);
if (picked != null) {
setState(() => selectedDate = picked);
}
},
child: InputDecorator(
decoration: const InputDecoration(
labelText: 'Date',
suffixIcon: Icon(Icons.calendar_today, size: 18),
),
child: Text(DateFormat('dd/MM/yyyy').format(selectedDate)),
),
),
], ],
), ),
actions: [ actions: [
@@ -384,6 +409,7 @@ class _WeaponDetailScreenState extends State<WeaponDetailScreen> {
type: selectedType, type: selectedType,
description: descController.text, description: descController.text,
roundsSinceLast: _totalRounds, roundsSinceLast: _totalRounds,
date: selectedDate,
); );
_loadData(); _loadData();
} }

View File

@@ -25,12 +25,43 @@ class _HomeScreenState extends State<HomeScreen> {
List<Session> _recentSessions = []; List<Session> _recentSessions = [];
bool _isLoading = true; bool _isLoading = true;
SessionProvider? _sessionProvider;
bool _wasSessionActive = false;
@override @override
void initState() { void initState() {
super.initState(); super.initState();
_loadStats(); _loadStats();
} }
@override
void didChangeDependencies() {
super.didChangeDependencies();
final provider = context.read<SessionProvider>();
if (provider != _sessionProvider) {
_sessionProvider?.removeListener(_onSessionChanged);
_sessionProvider = provider;
_sessionProvider!.addListener(_onSessionChanged);
_wasSessionActive = provider.isSessionActive;
}
}
void _onSessionChanged() {
final isActive = _sessionProvider?.isSessionActive ?? false;
// Quand une session vient de se terminer, on rafraîchit les stats
// automatiquement pour prendre en compte la dernière session.
if (_wasSessionActive && !isActive) {
_loadStats();
}
_wasSessionActive = isActive;
}
@override
void dispose() {
_sessionProvider?.removeListener(_onSessionChanged);
super.dispose();
}
Future<void> _loadStats() async { Future<void> _loadStats() async {
final repository = context.read<SessionRepository>(); final repository = context.read<SessionRepository>();
final stats = await repository.getStatistics(); final stats = await repository.getStatistics();