|
@@ -1,9 +1,10 @@
|
|
|
"use client";
|
|
|
|
|
|
-import { useState } from "react";
|
|
|
-import { Clock, Play, Pause, RotateCcw, X, Target } from "lucide-react";
|
|
|
+import { useState, useEffect } from "react";
|
|
|
+import { Clock, Play, Pause, RotateCcw, X, Target, Weight } from "lucide-react";
|
|
|
|
|
|
import { useCurrentLocale, useI18n } from "locales/client";
|
|
|
+import { type WeightUnit } from "@/shared/lib/weight-conversion";
|
|
|
import { cn } from "@/shared/lib/utils";
|
|
|
import { useWorkoutSession } from "@/features/workout-session/model/use-workout-session";
|
|
|
import { Timer } from "@/components/ui/timer";
|
|
@@ -17,7 +18,6 @@ interface WorkoutSessionHeaderProps {
|
|
|
onToggleTimer: VoidFunction;
|
|
|
onResetTimer: VoidFunction;
|
|
|
onQuitWorkout: VoidFunction;
|
|
|
- currentExerciseIndex: number;
|
|
|
}
|
|
|
|
|
|
export function WorkoutSessionHeader({
|
|
@@ -26,15 +26,30 @@ export function WorkoutSessionHeader({
|
|
|
onToggleTimer,
|
|
|
onResetTimer,
|
|
|
onQuitWorkout,
|
|
|
- currentExerciseIndex,
|
|
|
}: WorkoutSessionHeaderProps) {
|
|
|
const t = useI18n();
|
|
|
const [showQuitDialog, setShowQuitDialog] = useState(false);
|
|
|
const [resetCount, setResetCount] = useState(0);
|
|
|
+ const [volumeUnit, setVolumeUnit] = useState<WeightUnit>("kg");
|
|
|
const locale = useCurrentLocale();
|
|
|
- const { getExercisesCompleted, getTotalExercises, session } = useWorkoutSession();
|
|
|
+ const { getExercisesCompleted, getTotalExercises, session, getTotalVolumeInUnit } = useWorkoutSession();
|
|
|
const exercisesCompleted = getExercisesCompleted();
|
|
|
const totalExercises = getTotalExercises();
|
|
|
+ const totalVolume = getTotalVolumeInUnit(volumeUnit);
|
|
|
+
|
|
|
+ // Load volume unit preference from localStorage
|
|
|
+ useEffect(() => {
|
|
|
+ const savedUnit = localStorage.getItem("volumeUnit") as WeightUnit;
|
|
|
+ if (savedUnit === "kg" || savedUnit === "lbs") {
|
|
|
+ setVolumeUnit(savedUnit);
|
|
|
+ }
|
|
|
+ }, []);
|
|
|
+
|
|
|
+ // Save volume unit preference to localStorage
|
|
|
+ const handleVolumeUnitChange = (unit: WeightUnit) => {
|
|
|
+ setVolumeUnit(unit);
|
|
|
+ localStorage.setItem("volumeUnit", unit);
|
|
|
+ };
|
|
|
|
|
|
const handleQuitClick = () => {
|
|
|
setShowQuitDialog(true);
|
|
@@ -56,7 +71,6 @@ export function WorkoutSessionHeader({
|
|
|
<div className="rounded-xl p-3 bg-slate-50 dark:bg-slate-900/80 border border-slate-200 dark:border-slate-700">
|
|
|
<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-ping"></div>
|
|
|
<span className="text-emerald-400 font-semibold text-xs uppercase tracking-wider">
|
|
|
{t("workout_builder.session.started_at")}{" "}
|
|
|
{new Date(session?.startedAt || "").toLocaleTimeString(locale, { hour: "2-digit", minute: "2-digit" })}
|
|
@@ -145,6 +159,49 @@ export function WorkoutSessionHeader({
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
+
|
|
|
+ {/* Card 3: Volume Total */}
|
|
|
+ <div className="bg-white dark:bg-slate-800 rounded-lg p-3 border border-slate-200 dark:border-slate-700 transition-colors duration-200 dark:text-white dark:hover:bg-slate-700">
|
|
|
+ <div className="flex items-center gap-2 mb-2">
|
|
|
+ <div className="w-8 h-8 rounded-full bg-orange-500/20 flex items-center justify-center">
|
|
|
+ <Weight className="h-4 w-4 text-orange-400" />
|
|
|
+ </div>
|
|
|
+ <div>
|
|
|
+ <h3 className="text-slate-700 dark:text-white font-semibold text-base">{t("workout_builder.session.total_volume")}</h3>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div className="text-center">
|
|
|
+ <div className="text-2xl font-bold text-slate-900 dark:text-white mb-1">
|
|
|
+ {totalVolume.toFixed(volumeUnit === "lbs" ? 1 : 0)}
|
|
|
+ </div>
|
|
|
+ <div className="flex items-center justify-center gap-1">
|
|
|
+ <button
|
|
|
+ className={cn(
|
|
|
+ "text-xs px-2 py-1 rounded transition-colors",
|
|
|
+ volumeUnit === "kg"
|
|
|
+ ? "bg-orange-100 text-orange-700 dark:bg-orange-900 dark:text-orange-100"
|
|
|
+ : "text-slate-400 hover:text-slate-600 dark:hover:text-slate-300",
|
|
|
+ )}
|
|
|
+ onClick={() => handleVolumeUnitChange("kg")}
|
|
|
+ >
|
|
|
+ kg
|
|
|
+ </button>
|
|
|
+ <span className="text-slate-300 dark:text-slate-600">|</span>
|
|
|
+ <button
|
|
|
+ className={cn(
|
|
|
+ "text-xs px-2 py-1 rounded transition-colors",
|
|
|
+ volumeUnit === "lbs"
|
|
|
+ ? "bg-orange-100 text-orange-700 dark:bg-orange-900 dark:text-orange-100"
|
|
|
+ : "text-slate-400 hover:text-slate-600 dark:hover:text-slate-300",
|
|
|
+ )}
|
|
|
+ onClick={() => handleVolumeUnitChange("lbs")}
|
|
|
+ >
|
|
|
+ lbs
|
|
|
+ </button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|