|
@@ -3,9 +3,10 @@
|
|
|
import { useState } from "react";
|
|
|
import { Clock, Play, Pause, RotateCcw, X, Target } from "lucide-react";
|
|
|
|
|
|
-import { useI18n } from "locales/client";
|
|
|
+import { useCurrentLocale, useI18n } from "locales/client";
|
|
|
import { cn } from "@/shared/lib/utils";
|
|
|
import { useWorkoutSession } from "@/features/workout-session/model/use-workout-session";
|
|
|
+import { Timer } from "@/components/ui/timer";
|
|
|
import { Button } from "@/components/ui/button";
|
|
|
|
|
|
import { QuitWorkoutDialog } from "../../workout-builder/ui/quit-workout-dialog";
|
|
@@ -31,8 +32,9 @@ export function WorkoutSessionHeader({
|
|
|
}: WorkoutSessionHeaderProps) {
|
|
|
const t = useI18n();
|
|
|
const [showQuitDialog, setShowQuitDialog] = useState(false);
|
|
|
-
|
|
|
- const { getExercisesCompleted, getTotalExercises } = useWorkoutSession();
|
|
|
+ const [resetCount, setResetCount] = useState(0);
|
|
|
+ const locale = useCurrentLocale();
|
|
|
+ const { getExercisesCompleted, getTotalExercises, session } = useWorkoutSession();
|
|
|
const exercisesCompleted = getExercisesCompleted();
|
|
|
const totalExercises = getTotalExercises();
|
|
|
|
|
@@ -50,17 +52,21 @@ export function WorkoutSessionHeader({
|
|
|
setShowQuitDialog(false);
|
|
|
};
|
|
|
|
|
|
+ const handleReset = () => {
|
|
|
+ onResetTimer();
|
|
|
+ setResetCount((c) => c + 1);
|
|
|
+ };
|
|
|
+
|
|
|
return (
|
|
|
<>
|
|
|
<div className="w-full mb-8">
|
|
|
- {/* Minimal header, fond blanc en clair, dégradé en dark */}
|
|
|
<div className="rounded-xl p-3 bg-slate-50">
|
|
|
- {/* Top row - Status et Quit button */}
|
|
|
<div className="flex items-center justify-between mb-4">
|
|
|
<div className="flex items-center gap-2">
|
|
|
- <div className="w-2 h-2 rounded-full bg-emerald-400 animate-pulse"></div>
|
|
|
+ <div className="w-2 h-2 rounded-full bg-emerald-400 animate-ping"></div>
|
|
|
<span className="text-emerald-400 font-semibold text-xs uppercase tracking-wider">
|
|
|
- {t("workout_builder.session.workout_in_progress")}
|
|
|
+ {t("workout_builder.session.started_at")}{" "}
|
|
|
+ {new Date(session?.startedAt || "").toLocaleTimeString(locale, { hour: "2-digit", minute: "2-digit" })}
|
|
|
</span>
|
|
|
</div>
|
|
|
|
|
@@ -74,24 +80,23 @@ export function WorkoutSessionHeader({
|
|
|
</Button>
|
|
|
</div>
|
|
|
|
|
|
- {/* Main content - Cards */}
|
|
|
- <div className="grid grid-cols-1 lg:grid-cols-3 gap-3">
|
|
|
- {/* Card 1: Temps écoulé */}
|
|
|
+ <div className="grid grid-cols-1 sm:grid-cols-3 gap-3">
|
|
|
+ {/* Card 1: elapsed time */}
|
|
|
<div className="bg-white dark:bg-gradient-to-br dark:from-slate-800/80 dark:to-slate-700/80 rounded-lg p-3 border border-slate-100 dark:border-slate-600/30">
|
|
|
<div className="flex items-center gap-2 mb-2">
|
|
|
<div className="w-8 h-8 rounded-full bg-blue-500/20 flex items-center justify-center">
|
|
|
<Clock className="h-4 w-4 text-blue-400" />
|
|
|
</div>
|
|
|
<div>
|
|
|
- <h3 className="text-slate-700 dark:text-white font-semibold text-base">{t("workout_builder.session.elapsed_time")}</h3>
|
|
|
+ <h3 className="text-slate-700 dark:text-white font-semibold text-base">{t("workout_builder.session.chronometer")}</h3>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
- {/* Chrono display - Large et centré */}
|
|
|
<div className="text-center">
|
|
|
- <div className="text-2xl font-mono font-bold text-slate-900 dark:text-white mb-2 tracking-wider">{elapsedTime}</div>
|
|
|
+ <div className="text-2xl font-mono font-bold text-slate-900 dark:text-white mb-2 tracking-wider">
|
|
|
+ <Timer initialSeconds={typeof elapsedTime === "number" ? elapsedTime : 0} isRunning={isTimerRunning} key={resetCount} />
|
|
|
+ </div>
|
|
|
|
|
|
- {/* Timer controls */}
|
|
|
<div className="flex items-center justify-center gap-2">
|
|
|
<Button
|
|
|
className={cn(
|
|
@@ -105,7 +110,7 @@ export function WorkoutSessionHeader({
|
|
|
|
|
|
<Button
|
|
|
className="w-8 h-8 rounded-full p-0 border-slate-200 text-slate-400 hover:bg-slate-100 dark:border-slate-600 hover:dark:bg-slate-700"
|
|
|
- onClick={onResetTimer}
|
|
|
+ onClick={handleReset}
|
|
|
variant="outline"
|
|
|
>
|
|
|
<RotateCcw className="h-4 w-4" />
|
|
@@ -114,7 +119,7 @@ export function WorkoutSessionHeader({
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
- {/* Card 2: Progression */}
|
|
|
+ {/* Card 2: progress */}
|
|
|
<div className="bg-white dark:bg-gradient-to-br dark:from-slate-800/80 dark:to-slate-700/80 rounded-lg p-3 border border-slate-100 dark:border-slate-600/30">
|
|
|
<div className="flex items-center gap-2 mb-2">
|
|
|
<div className="w-8 h-8 rounded-full bg-purple-500/20 flex items-center justify-center">
|
|
@@ -128,13 +133,11 @@ export function WorkoutSessionHeader({
|
|
|
</div>
|
|
|
|
|
|
<div className="space-y-2">
|
|
|
- {/* Progress display */}
|
|
|
<div className="flex items-center justify-between">
|
|
|
<span className="text-lg font-bold text-slate-900 dark:text-white">{exercisesCompleted}</span>
|
|
|
<span className="text-slate-400">/ {totalExercises}</span>
|
|
|
</div>
|
|
|
|
|
|
- {/* Progress bar */}
|
|
|
<div className="w-full bg-slate-200 dark:bg-slate-700 rounded-full h-2 overflow-hidden">
|
|
|
<div
|
|
|
className="h-full bg-gradient-to-r from-purple-500 to-pink-500 transition-all duration-500 ease-out"
|
|
@@ -142,7 +145,6 @@ export function WorkoutSessionHeader({
|
|
|
/>
|
|
|
</div>
|
|
|
|
|
|
- {/* Percentage */}
|
|
|
<div className="text-center">
|
|
|
<span className="text-xs text-slate-400">
|
|
|
{Math.round((exercisesCompleted / totalExercises) * 100)}% {t("workout_builder.session.complete")}
|
|
@@ -154,7 +156,6 @@ export function WorkoutSessionHeader({
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
- {/* Dialog de confirmation pour quitter */}
|
|
|
<QuitWorkoutDialog
|
|
|
elapsedTime={elapsedTime}
|
|
|
exercisesCompleted={exercisesCompleted}
|