|
@@ -0,0 +1,114 @@
|
|
|
+import { syncWorkoutSessionAction } from "@/features/workout-session/actions/sync-workout-sessions.action";
|
|
|
+import { getWorkoutSessionsAction } from "@/features/workout-session/actions/get-workout-sessions.action";
|
|
|
+import { useSession } from "@/features/auth/lib/auth-client";
|
|
|
+
|
|
|
+import { workoutSessionLocal } from "./workout-session.local";
|
|
|
+
|
|
|
+import type { WorkoutSession } from "./types/workout-session";
|
|
|
+
|
|
|
+// This is an abstraction layer to handle the local storage and/or the API calls.
|
|
|
+// He's the orchestrator.
|
|
|
+
|
|
|
+// TODO: replace with auth context
|
|
|
+function isUserLoggedIn(): boolean {
|
|
|
+ return !!localStorage.getItem("userToken");
|
|
|
+}
|
|
|
+
|
|
|
+export const useWorkoutSessionService = () => {
|
|
|
+ const { data: session } = useSession();
|
|
|
+ const userId = session?.user?.id;
|
|
|
+
|
|
|
+ const getAll = async (): Promise<WorkoutSession[]> => {
|
|
|
+ if (userId) {
|
|
|
+ const result = await getWorkoutSessionsAction({ userId });
|
|
|
+ if (result?.serverError) throw new Error(result.serverError);
|
|
|
+
|
|
|
+ const serverSessions = (result?.data?.sessions || []).map((session) => ({
|
|
|
+ ...session,
|
|
|
+ startedAt: session.startedAt instanceof Date ? session.startedAt.toISOString() : session.startedAt,
|
|
|
+ endedAt:
|
|
|
+ session.endedAt instanceof Date
|
|
|
+ ? session.endedAt.toISOString()
|
|
|
+ : typeof session.endedAt === "string"
|
|
|
+ ? session.endedAt
|
|
|
+ : undefined,
|
|
|
+ duration: session.duration === null ? undefined : session.duration,
|
|
|
+ exercises: session.exercises.map(({ exercise, order, sets }) => ({
|
|
|
+ ...exercise,
|
|
|
+ order,
|
|
|
+ sets: sets.map((set) => ({
|
|
|
+ ...set,
|
|
|
+ valueInt: set.valueInt === null ? undefined : set.valueInt,
|
|
|
+ valueSec: set.valueSec === null ? undefined : set.valueSec,
|
|
|
+ unit: set.unit === null ? undefined : set.unit,
|
|
|
+ units: set.units === null ? undefined : set.units,
|
|
|
+ })),
|
|
|
+ })),
|
|
|
+ }));
|
|
|
+ const localSessions = workoutSessionLocal.getAll().filter((s) => s.status !== "synced");
|
|
|
+
|
|
|
+ return [...localSessions, ...serverSessions].sort((a, b) => new Date(b.startedAt).getTime() - new Date(a.startedAt).getTime());
|
|
|
+ }
|
|
|
+
|
|
|
+ return workoutSessionLocal.getAll().sort((a, b) => {
|
|
|
+ const dateA = typeof a.startedAt === "string" ? new Date(a.startedAt) : a.startedAt;
|
|
|
+ const dateB = typeof b.startedAt === "string" ? new Date(b.startedAt) : b.startedAt;
|
|
|
+ return dateB.getTime() - dateA.getTime();
|
|
|
+ });
|
|
|
+ };
|
|
|
+
|
|
|
+ const add = async (session: WorkoutSession) => {
|
|
|
+ if (userId) {
|
|
|
+ // Utiliser l'action de synchronisation
|
|
|
+ const result = await syncWorkoutSessionAction({
|
|
|
+ session: {
|
|
|
+ ...session,
|
|
|
+ userId: "current-user-id", // TODO: passer le vrai userId
|
|
|
+ status: "synced",
|
|
|
+ },
|
|
|
+ });
|
|
|
+
|
|
|
+ if (result?.serverError) throw new Error(result.serverError);
|
|
|
+
|
|
|
+ if (result?.data?.data) {
|
|
|
+ workoutSessionLocal.markSynced(session.id, result.data.data.id);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return workoutSessionLocal.add(session);
|
|
|
+ };
|
|
|
+
|
|
|
+ const update = async (id: string, data: Partial<WorkoutSession>) => {
|
|
|
+ if (userId) {
|
|
|
+ // TODO: Créer une action updateWorkoutSessionAction
|
|
|
+ const result = await updateWorkoutSessionAction({ id, data });
|
|
|
+ if (result.serverError) throw new Error(result.serverError);
|
|
|
+ }
|
|
|
+ return workoutSessionLocal.update(id, data);
|
|
|
+ };
|
|
|
+
|
|
|
+ const complete = async (id: string) => {
|
|
|
+ const data = {
|
|
|
+ status: "completed" as const,
|
|
|
+ endedAt: new Date().toISOString(),
|
|
|
+ };
|
|
|
+
|
|
|
+ if (isUserLoggedIn()) {
|
|
|
+ const result = await completeWorkoutSessionAction({ id });
|
|
|
+ if (result.serverError) throw new Error(result.serverError);
|
|
|
+ }
|
|
|
+
|
|
|
+ return workoutSessionLocal.update(id, data);
|
|
|
+ };
|
|
|
+
|
|
|
+ const remove = async (id: string) => {
|
|
|
+ if (isUserLoggedIn()) {
|
|
|
+ // TODO: Créer une action deleteWorkoutSessionAction
|
|
|
+ const result = await deleteWorkoutSessionAction({ id });
|
|
|
+ if (result.serverError) throw new Error(result.serverError);
|
|
|
+ }
|
|
|
+ workoutSessionLocal.remove(id);
|
|
|
+ };
|
|
|
+
|
|
|
+ return { getAll, add, update, complete, remove };
|
|
|
+};
|