"use client"; import { useEffect, useState } from "react"; import { DAY_NAMES } from "@/lib/types"; import type { GeneratedWeeklyPlan, WorkoutDetail, WeeklyPreview, PreviewDay, } from "@/lib/types"; import { DayCard } from "@/components/plans/DayCard"; import { api } from "@/lib/api"; interface WeeklyPlanGridProps { plan?: GeneratedWeeklyPlan; preview?: WeeklyPreview; onUpdate?: () => void; onPreviewChange?: (preview: WeeklyPreview) => void; } export function WeeklyPlanGrid({ plan, preview, onUpdate, onPreviewChange, }: WeeklyPlanGridProps) { const [workoutDetails, setWorkoutDetails] = useState< Record >({}); const [refreshKey, setRefreshKey] = useState(0); // Saved mode: fetch workout details const workoutIds = plan?.generated_workouts .filter((w) => w.workout && !w.is_rest_day) .map((w) => w.workout!) ?? []; useEffect(() => { if (!plan || workoutIds.length === 0) return; let cancelled = false; async function fetchDetails() { const results = await Promise.allSettled( workoutIds.map((id) => api.getWorkoutDetail(id)) ); if (cancelled) return; const details: Record = {}; results.forEach((result, i) => { if (result.status === "fulfilled") { details[workoutIds[i]] = result.value; } }); setWorkoutDetails(details); } fetchDetails(); return () => { cancelled = true; }; // eslint-disable-next-line react-hooks/exhaustive-deps }, [plan?.id, refreshKey]); const handleSavedUpdate = () => { setRefreshKey((k) => k + 1); onUpdate?.(); }; const handlePreviewDayChange = (dayIndex: number, newDay: PreviewDay) => { if (!preview || !onPreviewChange) return; const newDays = [...preview.days]; newDays[dayIndex] = newDay; onPreviewChange({ ...preview, days: newDays }); }; // Determine items to render if (preview) { const trainingDays = preview.days .map((day, idx) => ({ day, idx })) .filter((d) => !d.day.is_rest_day); const pairs: (typeof trainingDays)[] = []; for (let i = 0; i < trainingDays.length; i += 2) { pairs.push(trainingDays.slice(i, i + 2)); } return (
{/* Desktop: two per row */}
{pairs.map((pair, rowIdx) => (
{pair.map(({ day, idx }) => (
{DAY_NAMES[day.day_of_week]}
))}
))}
{/* Mobile stack */}
{trainingDays.map(({ day, idx }) => (
{DAY_NAMES[day.day_of_week]}
))}
); } // Saved plan mode if (!plan) return null; const sortedWorkouts = [...plan.generated_workouts].sort( (a, b) => a.day_of_week - b.day_of_week ); const nonRestWorkouts = sortedWorkouts.filter((w) => !w.is_rest_day); const pairs: (typeof nonRestWorkouts)[] = []; for (let i = 0; i < nonRestWorkouts.length; i += 2) { pairs.push(nonRestWorkouts.slice(i, i + 2)); } return (
{/* Desktop: two per row */}
{pairs.map((pair, rowIdx) => (
{pair.map((workout) => (
{DAY_NAMES[workout.day_of_week]}
))}
))}
{/* Mobile stack */}
{nonRestWorkouts.map((workout) => (
{DAY_NAMES[workout.day_of_week]}
))}
); }