# F-123 — Editor de producto: quitar gate, reorder y selector de peso en gramos

## Cambios

### `apps/admin/src/features/products/components/ProductEditor.tsx`
- **Eliminados** los dos bloques `⚠️ Guarda primero el producto para configurar …` (líneas 286 y 374 originales).
- **Renderizado siempre** `<PriceStockSection productId={productId} />` y `<ImagesSection productId={productId} />` (productId puede ser undefined).
- **Reordenado** el bloque Marca / Canal de venta / Fecha de caducidad para que aparezca **después** de `<PriceStockSection>` y **antes** de Descripción (estaba al revés).

### `apps/admin/src/features/products/components/sections/PriceStockSection.tsx`
- Prop `productId: string → productId?: string` con flag `pending = !productId`.
- `useEffect` de carga: si `!productId` no hace fetches.
- Early return cuando `!pending && !variant` para el caso "existe producto pero sin variante" (legacy).
- **Reemplazado** el input libre de peso unitario (kg) por un `<select>` con presets `[100, 150, 200, 250, 300, 350, 500, 740, Personalizado…]`. Al elegir "Personalizado…" aparece un input auxiliar en gramos.
- Estado interno en gramos (`unitWeightGr`, `customWeightGr`); se convierte a kg (÷1000) al persistir.
- **Disabled** los botones / inputs de guardado (`Guardar precio`, stock onBlur, EAN onBlur, peso onBlur, compra mínima onBlur) cuando `pending` es true.
- **Caption** "Se guardará al crear el producto" en la cabecera cuando pending.
- Guard TypeScript: añadido `const pending = !productId` y capturas locales (`pid`, `productId as string`) para que TS estreche bien dentro de `.then`/async.

### `apps/admin/src/features/products/components/sections/ImagesSection.tsx`
- Prop `productId: string → productId?: string`.
- Bloque pending: renderiza la UI de carga de imágenes deshabilitada (URL, "Añadir URL", "Subir imagen", área de drop) con caption "Se guardarán al crear el producto".
- `load()` captura `pid` para evitar warnings de TS.

## UX resultante

### Crear producto nuevo (`/products/new`)
- Pestaña General: Nombre + Slug + Precio/Stock (con caption "Se guardará al crear el producto", inputs deshabilitados) + Marca / Canal / Caducidad (siempre editables) + Descripción + Categorías + Atributos.
- Tras pulsar "Crear producto": `setProductId(saved.id)` desbloquea toda la sección de precio/stock, los inputs se hidratan desde API y la caption desaparece.

### Editar producto existente (`/products/[id]`)
- Comportamiento idéntico al previo (productId siempre truthy → no entra en modo pending).

## Evidencia

- `apps/admin npx tsc --noEmit` → exit 0.
- `apps/admin npm run build` → exit 0, BUILD_ID regenerado.
- `apps/admin npx eslint` sobre los tres archivos → 0 errors, 8 warnings preexistentes (no relacionados).
- `grep "Guarda primero" apps/admin/.next/static/chunks/` → 0 ocurrencias en el bundle compilado.
- Source: `grep "Guarda primero"` en los tres archivos modificados → 0 ocurrencias.

## Notas

- Sin cambios en backend ni en tipos del API client.
- La columna de peso en `/products` y `/inventory` se seguirá mostrando en kg (consistente con API), pero el input del editor ya está en gramos.
- El reinicio del monolith lo hace el operador; el bundle compilado ya está en `apps/admin/.next`.