// Rôle : fournit l'outil images avec import, collage, libellés et annotation rapide. import { useState } from "react"; import { Icon } from "../../../components/Icon.jsx"; import { usePointerReorder } from "../../../hooks/usePointerReorder.js"; export function ImagesModule({ toolboxId, moduleId, context, editing }) { const data = context.getModuleData(toolboxId, moduleId, { images: [] }); const textContent = context.moduleText?.images || {}; const [dragOver, setDragOver] = useState(false); const pastePlaceholder = textContent.pastePlaceholder || "Coller une image ici"; const { draggingId: draggingImageId, dropTarget, startDrag } = usePointerReorder({ targetSelector: "[data-image-id]", getTargetId: (target) => target.dataset.imageId, canDropOn: (target) => target.dataset.imageModuleId === moduleId, getPlacement: (event, target) => { const rect = target.getBoundingClientRect(); return event.clientX > rect.left + rect.width / 2 ? "after" : "before"; }, onMove: (draggingId, targetId, placement) => { const nextImages = data.images.filter((image) => image.id !== draggingId); const targetIndex = nextImages.findIndex((image) => image.id === targetId); if (targetIndex === -1) return; nextImages.splice(placement === "after" ? targetIndex + 1 : targetIndex, 0, data.images.find((image) => image.id === draggingId)); context.setModuleData(toolboxId, moduleId, { images: nextImages.filter(Boolean) }); } }); async function addFiles(files) { if (await context.addImageFiles(toolboxId, moduleId, files)) { setDragOver(false); } } function updateImage(imageId, patch) { context.setModuleData(toolboxId, moduleId, { images: data.images.map((image) => image.id === imageId ? { ...image, ...patch } : image) }); } return ( <> {editing && (