feat: initial project scaffold with Watch companion app

This commit is contained in:
2026-08-04 17:28:06 +02:00
parent adbb4f01c5
commit 43b6467efb
65 changed files with 6361 additions and 166 deletions
@@ -0,0 +1,83 @@
import { useState, useCallback } from "react";
import type { WorkoutSet, StrokeType, RestType } from "@types/workout";
import { saveWorkout, saveTemplate } from "@db/operations";
const DEFAULT_SET: WorkoutSet = {
stroke: "Freestyle",
distancePerRep: 200,
repCount: 1,
restType: "fixed_rest",
restDuration: 30,
};
export function useWorkoutBuilder(initialSets?: WorkoutSet[]) {
const [sets, setSets] = useState<WorkoutSet[]>(initialSets ?? [{ ...DEFAULT_SET }]);
const [workoutName, setWorkoutName] = useState("");
const [isSaving, setIsSaving] = useState(false);
const addSet = useCallback(() => {
setSets((prev) => [...prev, { ...DEFAULT_SET }]);
}, []);
const updateSet = useCallback((index: number, updates: Partial<WorkoutSet>) => {
setSets((prev) => prev.map((s, i) => (i === index ? { ...s, ...updates } : s)));
}, []);
const removeSet = useCallback((index: number) => {
setSets((prev) => prev.filter((_, i) => i !== index));
}, []);
const totalDistance = sets.reduce((acc, s) => acc + s.distancePerRep * s.repCount, 0);
const save = useCallback(
async (poolLength: number, templateId?: string) => {
setIsSaving(true);
try {
const name = workoutName.trim() || `Workout ${new Date().toLocaleDateString()}`;
const id = await saveWorkout(name, poolLength, sets, templateId);
return id;
} finally {
setIsSaving(false);
}
},
[workoutName, sets]
);
const saveAsTemplate = useCallback(
async (templateName: string, poolLength: number) => {
setIsSaving(true);
try {
const id = await saveTemplate(templateName, poolLength, sets);
return id;
} finally {
setIsSaving(false);
}
},
[sets]
);
const loadTemplate = useCallback((templateSets: WorkoutSet[], name?: string) => {
setSets(templateSets);
if (name) setWorkoutName(name);
}, []);
const reset = useCallback(() => {
setSets([{ ...DEFAULT_SET }]);
setWorkoutName("");
}, []);
return {
sets,
workoutName,
setWorkoutName,
totalDistance,
isSaving,
addSet,
updateSet,
removeSet,
save,
saveAsTemplate,
loadTemplate,
reset,
};
}