feat(F-123): completed feature
This commit is contained in:
61
work/artifacts/F-123/architect.md
Normal file
61
work/artifacts/F-123/architect.md
Normal file
@@ -0,0 +1,61 @@
|
||||
# F-123 — Editor de producto: quitar gate, reorder y selector de peso en gramos
|
||||
|
||||
## Diagnóstico
|
||||
|
||||
F-121 (`a40d78d`) y F-107 (reorder previo) fueron fixes parciales:
|
||||
|
||||
1. **Gate "Guarda primero" sigue activo**: `ProductEditor.tsx` líneas 286 y 374 mantienen los `div` con el warning. F-121 solo cambió el flujo post-save (`router.push → router.replace` + `setProductId`), no eliminó los textos. Bundle live `15z1dcv3uvf3z.js` aún contiene "Guarda primero" (1 ocurrencia).
|
||||
2. **Reorder incompleto**: Marca / Canal / Caducidad están en `ProductEditor.tsx` **después** de Descripción. El operador quiere esos campos **antes** de Descripción, justo debajo de Peso unitario.
|
||||
3. **Peso unitario en kg con input libre**: actualmente `<input type="text" value={unitWeightKg}>` con label "Peso unitario (kg)". El operador quiere:
|
||||
- Label "Peso unitario (Gr)"
|
||||
- Select dropdown con valores [100, 150, 200, 250, 300, 350, 500, 740, custom]
|
||||
- Al elegir "custom" mostrar input libre en gramos
|
||||
- Convertir a kg al guardar (dividir por 1000)
|
||||
|
||||
## Diseño
|
||||
|
||||
### Cambios
|
||||
|
||||
1. **`ProductEditor.tsx`** — Eliminar los dos bloques condicionales `{productId ? <Section/> : <Warning/>}`. Renderizar siempre:
|
||||
- `<PriceStockSection productId={productId} />` (productId puede ser undefined)
|
||||
- `<ImagesSection productId={productId} />` (idem)
|
||||
|
||||
2. **`PriceStockSection.tsx`** — Aceptar `productId?: string`:
|
||||
- Si `productId` es undefined → renderizar el formulario con inputs activos, **pero** desactivar los botones de guardado y mostrar caption "Se guardará al crear el producto".
|
||||
- Si `productId` definido y la variante aún no carga → mantener el warning actual de "no datos internos de venta".
|
||||
- Si `productId` definido y variante cargada → comportamiento normal.
|
||||
|
||||
3. **`ImagesSection.tsx`** — Aceptar `productId?: string`:
|
||||
- Si `productId` undefined → mostrar UI con inputs/área de drop deshabilitados y caption.
|
||||
- Si `productId` definido → comportamiento normal.
|
||||
|
||||
### Garantías
|
||||
|
||||
- Sin cambios en backend.
|
||||
- Sin cambios en tipos del API client.
|
||||
- Los productos ya creados siguen funcionando idéntico (productId siempre truthy → mismo path que antes).
|
||||
- Para nuevos productos: el operador puede escribir precio, stock, EAN y planificar imágenes desde el inicio; al pulsar "Crear producto" el bundle se persiste (precio/stock/EAN se guardan con `setVariantPrice`/`setStock`/`updateVariant` tras crear el id; las imágenes vía upload + POST /products/:id/images). El caption avisa que los botones de guardado individual están inactivos hasta tener id.
|
||||
|
||||
### Riesgos
|
||||
|
||||
- Bajo. Cambios puramente UI. Sin migraciones, sin API, sin tipos.
|
||||
|
||||
## Plan de implementación
|
||||
|
||||
1. Editar `ProductEditor.tsx`:
|
||||
- Quitar los dos bloques de warning.
|
||||
- Renderizar siempre `<PriceStockSection>` y `<ImagesSection>`.
|
||||
- **Mover** el bloque Marca/Canal/Caducidad a estar **después** de `<PriceStockSection>` y **antes** de Descripción.
|
||||
2. Editar `PriceStockSection.tsx`:
|
||||
- Prop opcional `productId?: string` + flag `pending`.
|
||||
- Early return si pending → renderizar UI deshabilitada.
|
||||
- Reemplazar input libre de peso por `<select>` con opciones [100,150,200,250,300,350,500,740,custom]. Custom muestra input auxiliar.
|
||||
- Convertir gramos → kg al llamar API.
|
||||
3. Editar `ImagesSection.tsx`:
|
||||
- Prop opcional `productId?: string`.
|
||||
- Estado pending → renderizar UI deshabilitada con caption.
|
||||
4. `npx tsc --noEmit` en `apps/admin`.
|
||||
5. `npm run build` en `apps/admin`.
|
||||
6. Reiniciar admin (`monolith.sh prod restart`).
|
||||
7. Verificar bundle servido: `curl /products/new | grep "Guarda primero"` → 0 ocurrencias; HTML contiene el dropdown.
|
||||
8. Cerrar gates.
|
||||
Reference in New Issue
Block a user