feat(F-082): completed feature
This commit is contained in:
74
work/artifacts/F-082/architect.md
Normal file
74
work/artifacts/F-082/architect.md
Normal file
@@ -0,0 +1,74 @@
|
||||
# F-082 — Architect: /inventory editable fields cannot be saved; Stock UX needs click-to-edit
|
||||
|
||||
## Root cause
|
||||
|
||||
Two views both have inline-edit affordances with subtle UX gaps:
|
||||
|
||||
### A) Standalone `/inventory` page (`apps/admin/src/app/(dashboard)/inventory/page.tsx`)
|
||||
- **SKU** and **EAN** are already click-to-edit and save on blur/Enter via `handleSaveSku`/`handleSaveEan`. ✅
|
||||
- **Stock** opens edit mode on click but the operator still has to click an **OK** button to persist. Cancel is via ✕. This violates the desired "save on blur or Enter" UX.
|
||||
|
||||
### B) `InventorySection.tsx` (inventory tab inside the product editor)
|
||||
- **Precio neto**: opens via ✏️ pencil, saves via OK button (no Enter/blur save).
|
||||
- **Stock**: opens via ✏️ pencil, saves via OK button.
|
||||
- **SKU** and **EAN**: not editable at all (plain text in the table) — silent loss if anyone tries.
|
||||
|
||||
## Design
|
||||
|
||||
Standardise on **click-to-edit + save on blur/Enter** for every editable cell. Remove pencil icons and OK buttons where they exist. Pattern:
|
||||
|
||||
```
|
||||
<button onClick={() => enterEdit(id)}>{value}</button>
|
||||
↳ swaps to
|
||||
<input autoFocus
|
||||
value={editValue}
|
||||
onChange={...}
|
||||
onBlur={() => save(id)}
|
||||
onKeyDown={e => { if (e.key === 'Enter') save(id); if (e.key === 'Escape') cancel(id); }}
|
||||
disabled={saving}
|
||||
/>
|
||||
```
|
||||
|
||||
### Files / changes
|
||||
|
||||
1. `apps/admin/src/app/(dashboard)/inventory/page.tsx`
|
||||
- Stock cell: drop the OK button and ✕ button. Save fires on blur and Enter; cancel on Escape restores the original stock value.
|
||||
- Existing `msg` indicator shows the save state.
|
||||
- SKU and EAN unchanged (they already work).
|
||||
|
||||
3. `apps/admin/src/features/products/components/sections/InventorySection.tsx`
|
||||
- **Stock**: replace ✏️ + OK + ✕ pattern with the same click-to-edit + save on blur/Enter pattern.
|
||||
- **Precio neto**: same — drop OK and ✕, save on Enter/blur.
|
||||
- **SKU**: add inline editing (was plain text). Click cell → input → save on blur/Enter → `productsApi.updateVariant(productId, variantId, { sku })`.
|
||||
- **EAN**: add inline editing (was plain text). Same mechanism; `null` when empty.
|
||||
- **IVA select**: stays as-is (already click-to-edit without explicit pencil).
|
||||
|
||||
### Persistence
|
||||
|
||||
All edits call existing PATCH endpoints:
|
||||
- `productsApi.updateVariant(productId, variantId, { sku | ean })`
|
||||
- `pricingApi.setVariantPrice(variantId, cents, vatRate)`
|
||||
- `inventoryApi.setStock(variantId, qty)`
|
||||
|
||||
No new endpoints, no schema changes.
|
||||
|
||||
### Failure handling
|
||||
|
||||
- On API failure the existing inline `saveMsg` shows `Error`; cell reverts via `cancelEdit*` which restores the value from the row state.
|
||||
- The previous value is held in state until the API response arrives so the cell can revert cleanly.
|
||||
|
||||
### Concurrency
|
||||
|
||||
A simple `saving` flag per cell disables the input and prevents double-submit. Last-write-wins on the backend (existing behaviour).
|
||||
|
||||
## Risk
|
||||
|
||||
Low. Pure UX refactor, no API contract change.
|
||||
|
||||
## Acceptance mapping
|
||||
- "Every editable cell in /inventory saves on blur or Enter via PATCH /variants/:id" → all cells adopt the click-to-edit + onBlur/onKeyDown pattern.
|
||||
- "Stock cell enters edit mode on a single click; the pencil icon is removed" → button value is the cell value; no pencil.
|
||||
- "Successful save shows visual confirmation" → `msg` chip shows ✓.
|
||||
- "Failed save shows inline error and restores the previous value" → saveMsg + cancelEdit path.
|
||||
- "No regressions in the existing Prices tab or product editor" → changes scoped to InventorySection + /inventory page.
|
||||
- "verify.sh is green" → typecheck + lint clean.
|
||||
Reference in New Issue
Block a user