feat: initial project scaffold with Watch companion app
This commit is contained in:
@@ -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,
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user