Files
mercadodevida/work/artifacts/F-135/implementer.md
2026-08-21 18:48:24 +02:00

2.8 KiB

F-135 — Drop zone funcional en estado pending + cola de subida

Cambios

apps/admin/src/features/products/components/sections/ImagesSection.tsx

Estado nuevo

const [pendingFiles, setPendingFiles] = useState<File[]>([]);
const prevProductIdRef = useRef<string | undefined>(productId);

handleFileInput actualizado

  • Si hay productId → llama uploadFile(file) directamente
  • Si no hay productId → encola con queueFile(file)

handleDrop actualizado

  • Acepta múltiples archivos: Array.from(e.dataTransfer.files).filter(f => f.type.startsWith('image/'))
  • Si hay productId → sube en serie (para evitar carreras)
  • Si no hay productId → encola todos en pendingFiles

Nuevo queueFile

const queueFile = (file: File) => {
  setPendingFiles(prev => [...prev, file]);
};

Nuevo efecto de drenaje

useEffect(() => {
  const prev = prevProductIdRef.current;
  prevProductIdRef.current = productId;
  if (!productId || prev === productId) return;
  if (pendingFiles.length === 0) return;
  const queue = pendingFiles;
  setPendingFiles([]);
  void (async () => {
    for (const f of queue) {
      await uploadFile(f);
    }
  })();
}, [productId]);

Cuando productId pasa de undefined a un UUID (es decir, el padre creó el producto y llamó setProductId(saved.id)), el efecto dispara la subida automática de todos los archivos encolados. Se ejecuta una sola vez por transición (gracias al ref que guarda el valor anterior).

Bloque pending rediseñado

La zona de drop ahora tiene los handlers onDragOver / onDragLeave / onDrop (antes no los tenía). Visualmente:

  • Cambia color al hacer drag-over (verde marca)
  • Si hay archivos encolados, muestra caption: N imagen(es) en cola — se subirán al crear el producto

Comportamiento resultante

/products/new (sin productId)

  1. Operador arrastra imágenes → se encolan localmente
  2. Operador rellena nombre y pulsa "Crear producto"
  3. Backend responde con saved.id, ProductEditor llama setProductId(saved.id)
  4. El efecto dispara: sube todos los archivos encolados → backend los adjunta al producto
  5. La lista de imágenes aparece populated

/products/[id] (con productId)

  • Drag-drop y file picker funcionan igual que antes (subida inmediata)

Verificación

  • cd apps/admin && npx tsc --noEmit → exit 0.
  • cd apps/admin && NEXT_PUBLIC_API_URL=http://192.168.18.93:3000 npm run build → exit 0.

Notas

  • El caption del header cambió de "Se guardarán al crear el producto" a "Se subirán al crear el producto" (más preciso ahora que las imágenes sí se suben).
  • Sin cambios en backend ni en uploadFile/addImageByUrl — reusan la lógica existente.
  • Operador reinicia admin (./scripts/monolith.sh prod restart) para desplegar.