import { useState, useEffect, useCallback, useMemo } from "react"; import { Loader2, Plus } from "lucide-react"; import { arrayMove, SortableContext, verticalListSortingStrategy } from "@dnd-kit/sortable"; import { restrictToVerticalAxis } from "@dnd-kit/modifiers"; import { DndContext, closestCenter, TouchSensor, MouseSensor, useSensor, useSensors, DragEndEvent } from "@dnd-kit/core"; import { useI18n } from "locales/client"; import { useWorkoutStepper } from "../model/use-workout-stepper"; import { ExerciseListItem } from "./exercise-list-item"; import type { ExerciseWithAttributes } from "../types"; interface ExercisesSelectionProps { isLoading: boolean; exercisesByMuscle: { muscle: string; exercises: ExerciseWithAttributes[] }[]; error: any; onShuffle: (exerciseId: string, muscle: string) => void; onPick: (exerciseId: string) => void; onDelete: (exerciseId: string, muscle: string) => void; onAdd: () => void; shufflingExerciseId?: string | null; } export const ExercisesSelection = ({ isLoading, exercisesByMuscle, error, onShuffle, onPick, onDelete, onAdd, shufflingExerciseId, }: ExercisesSelectionProps) => { const t = useI18n(); const [flatExercises, setFlatExercises] = useState<{ id: string; muscle: string; exercise: ExerciseWithAttributes }[]>([]); const { setExercisesOrder, exercisesOrder } = useWorkoutStepper(); const sensors = useSensors( useSensor(MouseSensor, { activationConstraint: { distance: 5, }, }), useSensor(TouchSensor, { activationConstraint: { delay: 100, tolerance: 5, }, }), ); const sortableItems = useMemo(() => flatExercises.map((item) => item.id), [flatExercises]); const flatExercisesComputed = useMemo(() => { if (exercisesByMuscle.length === 0) return []; const flat = exercisesByMuscle.flatMap((group) => group.exercises.map((exercise) => ({ id: exercise.id, muscle: group.muscle, exercise, })), ); if (exercisesOrder.length === 0) return flat; const exerciseMap = new Map(flat.map((item) => [item.id, item])); const orderedFlat = exercisesOrder.map((id) => exerciseMap.get(id)).filter(Boolean) as typeof flat; const newExercises = flat.filter((item) => !exercisesOrder.includes(item.id)); return [...orderedFlat, ...newExercises]; }, [exercisesByMuscle, exercisesOrder]); useEffect(() => { setFlatExercises(flatExercisesComputed); }, [flatExercisesComputed]); const handleDragEnd = useCallback( (event: DragEndEvent) => { const { active, over } = event; if (active.id !== over?.id) { setFlatExercises((items) => { const oldIndex = items.findIndex((item) => item.id === active.id); const newIndex = items.findIndex((item) => item.id === over?.id); const newOrder = arrayMove(items, oldIndex, newIndex); setExercisesOrder(newOrder.map((item) => item.id)); return newOrder; }); } }, [setExercisesOrder], ); if (isLoading) { return (

{t("workout_builder.loading.exercises")}

); } return (
{flatExercises.length > 0 ? (
{/* Liste des exercices drag and drop */}
{flatExercises.map((item) => ( ))}
) : error ? (

{t("workout_builder.error.loading_exercises")}

) : (

{t("workout_builder.no_exercises_found")}

)}
); };