feat(bibliothèque): badge Exemple, catégories et états vides bibliothèque (ticket #80)

Ajoute le badge "Exemple" (example_badge.dart) affiché sur les
exercices/programmes/séances-modèles seedés, le filtrage par catégorie
dans la bibliothèque d'exercices et les états vides dédiés. Préserve
isExample lors de l'édition d'un programme ou d'une séance-modèle
existants (ProgramUseCases/WorkoutTemplateUseCases).

Validé GO par Main : dart analyze propre, 173 tests (4 échecs
préexistants sans rapport avec ce lot).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-22 07:39:26 +02:00
parent 24e266c0e9
commit e05405157a
9 changed files with 357 additions and 16 deletions

View File

@ -4,6 +4,7 @@ import 'package:flutter/material.dart';
import '../application/application.dart';
import '../domain/domain.dart';
import 'example_badge.dart';
import 'share_screen.dart';
import 'workout_execution_screen.dart';
@ -66,8 +67,9 @@ final class _WorkoutTemplateListScreenState
final templates = snapshot.data ?? const <WorkoutTemplate>[];
if (templates.isEmpty) {
return _CenteredMessage(
title: 'Aucune séance pour le moment',
message: 'Compose une séance à partir de tes programmes.',
title: 'Aucune séance',
message:
'Crée une séance-modèle pour lancer ton entraînement plus vite.',
actionLabel: 'Créer une séance',
onAction: () => _openForm(),
);
@ -78,7 +80,15 @@ final class _WorkoutTemplateListScreenState
itemBuilder: (context, index) {
final template = templates[index];
return ListTile(
title: Text(template.name),
title: Wrap(
spacing: 8,
runSpacing: 4,
crossAxisAlignment: WrapCrossAlignment.center,
children: [
Text(template.name),
if (template.isExample) const ExampleBadge(),
],
),
subtitle: Text(_templateSummary(template)),
trailing: Wrap(
spacing: 8,