feat(ui): écran Historique des séances
Ajoute l'écran d'historique des séances (presentation/history_screen.dart), avec les ajustements application/domaine/repositories nécessaires et la navigation depuis l'accueil. Complète le dernier écran du périmètre UI. flutter analyze propre, 18/18 tests verts, build APK debug validé. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@ -5,6 +5,7 @@ import 'package:flutter/material.dart';
|
||||
|
||||
import '../application/application.dart';
|
||||
import '../domain/domain.dart';
|
||||
import 'history_screen.dart';
|
||||
|
||||
enum WorkoutExecutionMode { active, rest, paused, finished }
|
||||
|
||||
@ -13,12 +14,16 @@ final class WorkoutExecutionScreen extends StatefulWidget {
|
||||
required this.initialSession,
|
||||
required this.activeUseCases,
|
||||
required this.closeUseCase,
|
||||
required this.historyUseCases,
|
||||
required this.workoutTemplateUseCases,
|
||||
super.key,
|
||||
});
|
||||
|
||||
final ActiveWorkoutSession initialSession;
|
||||
final ActiveWorkoutSessionUseCases activeUseCases;
|
||||
final CloseWorkoutSessionUseCase closeUseCase;
|
||||
final WorkoutHistoryUseCases historyUseCases;
|
||||
final WorkoutTemplateUseCases workoutTemplateUseCases;
|
||||
|
||||
@override
|
||||
State<WorkoutExecutionScreen> createState() => _WorkoutExecutionScreenState();
|
||||
@ -30,6 +35,7 @@ final class _WorkoutExecutionScreenState extends State<WorkoutExecutionScreen> {
|
||||
late WorkoutExecutionMode _mode;
|
||||
Timer? _ticker;
|
||||
Timer? _restTicker;
|
||||
WorkoutHistory? _completedHistory;
|
||||
var _reps = 0;
|
||||
final _scoreController = TextEditingController();
|
||||
var _remainingRestSeconds = 0;
|
||||
@ -232,9 +238,12 @@ final class _WorkoutExecutionScreenState extends State<WorkoutExecutionScreen> {
|
||||
const SizedBox(height: 12),
|
||||
Text('Temps total : ${_formatDuration(elapsed)}'),
|
||||
const SizedBox(height: 24),
|
||||
OutlinedButton(onPressed: () {}, child: const Text('Voir le détail')),
|
||||
OutlinedButton(
|
||||
onPressed: () {},
|
||||
onPressed: _completedHistory == null ? null : _openHistoryDetail,
|
||||
child: const Text('Voir le détail'),
|
||||
),
|
||||
OutlinedButton(
|
||||
onPressed: _completedHistory == null ? null : _restartCompleted,
|
||||
child: const Text('Relancer cette séance'),
|
||||
),
|
||||
FilledButton(
|
||||
@ -367,7 +376,7 @@ final class _WorkoutExecutionScreenState extends State<WorkoutExecutionScreen> {
|
||||
|
||||
Future<void> _complete() async {
|
||||
_session = await widget.activeUseCases.complete(_session.metadata.id);
|
||||
await widget.closeUseCase.close(
|
||||
_completedHistory = await widget.closeUseCase.close(
|
||||
sessionId: _session.metadata.id,
|
||||
nameSnapshot: _plan.name,
|
||||
completed: true,
|
||||
@ -375,6 +384,56 @@ final class _WorkoutExecutionScreenState extends State<WorkoutExecutionScreen> {
|
||||
if (!mounted) return;
|
||||
setState(() => _mode = WorkoutExecutionMode.finished);
|
||||
}
|
||||
|
||||
Future<void> _openHistoryDetail() async {
|
||||
final history = _completedHistory;
|
||||
if (history == null) return;
|
||||
await Navigator.of(context).push(
|
||||
MaterialPageRoute(
|
||||
builder: (context) => HistoryDetailScreen(
|
||||
history: history,
|
||||
historyUseCases: widget.historyUseCases,
|
||||
workoutTemplateUseCases: widget.workoutTemplateUseCases,
|
||||
activeUseCases: widget.activeUseCases,
|
||||
closeUseCase: widget.closeUseCase,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _restartCompleted() async {
|
||||
final history = _completedHistory;
|
||||
if (history == null) return;
|
||||
ActiveWorkoutSession session;
|
||||
final sourceId = history.sourceWorkoutTemplateId;
|
||||
if (sourceId != null &&
|
||||
await widget.workoutTemplateUseCases.findById(sourceId) != null) {
|
||||
session = await widget.activeUseCases.startFromTemplate(sourceId);
|
||||
} else {
|
||||
if (mounted) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(
|
||||
content: Text(
|
||||
"La séance originale n'existe plus. Une copie va être utilisée.",
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
session = await widget.activeUseCases.startFromHistory(history);
|
||||
}
|
||||
if (!mounted) return;
|
||||
await Navigator.of(context).pushReplacement(
|
||||
MaterialPageRoute(
|
||||
builder: (context) => WorkoutExecutionScreen(
|
||||
initialSession: session,
|
||||
activeUseCases: widget.activeUseCases,
|
||||
closeUseCase: widget.closeUseCase,
|
||||
historyUseCases: widget.historyUseCases,
|
||||
workoutTemplateUseCases: widget.workoutTemplateUseCases,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
final class SetMeasureInput extends StatelessWidget {
|
||||
|
||||
Reference in New Issue
Block a user