feat(F-073): completed feature

This commit is contained in:
chattie
2026-08-19 19:23:44 +02:00
parent 352033e3fc
commit 1fe9b8babd
12 changed files with 255 additions and 49 deletions

View File

@@ -0,0 +1,78 @@
# F-073 — Architect: Activate/deactivate VAT types in admin tax rates page
## Current state
`/tax-rates/page.tsx` has inline edit for the `active` field:
1. Click "RowActions" (✏️) → enters edit mode
2. Change dropdown "Activo"/"Inactivo"
3. Click "Guardar"
This is cumbersome for a simple toggle. The `active` field should be a direct **toggle switch** in the "Estado" column, with immediate feedback.
## Goal
Add a prominent toggle switch (pill/checkbox style) in the "Estado" column that directly calls `taxApi.update(id, { active: !current })` without entering edit mode.
## Scope IN
- `project/apps/admin/src/app/(dashboard)/tax-rates/page.tsx`:
- Add `toggling` state (`Record<string, boolean>`) to track in-flight toggle requests
- Replace badge-only display in "Estado" column with a toggle switch
- Toggle switch calls `taxApi.update(r.id, { active: !r.active })` directly
- Shows spinner while toggling
- Shows error message on failure and reverts optimistically
- Maintains the existing inline edit functionality for name/rate changes
## Scope OUT
- Backend API — already supports `active` field toggle via `PATCH /admin/tax-rates/:id`
- No migration needed
- No other pages
## Design
Toggle switch (pill style):
```tsx
<button
onClick={() => toggleActive(r.id, !r.active)}
disabled={toggling[r.id]}
className={`relative inline-flex h-6 w-11 items-center rounded-full transition-colors focus:outline-none focus:ring-2 focus:ring-[#2D6A4F] ${
r.active ? 'bg-green-500' : 'bg-gray-300'
}`}
>
{toggling[r.id] ? (
<span className="text-white text-xs">...</span>
) : (
<span className={`inline-block h-4 w-4 transform rounded-full bg-white shadow transition-transform ${
r.active ? 'translate-x-6' : 'translate-x-1'
}`} />
)}
</button>
```
`toggleActive` function:
```ts
const toggleActive = async (id: string, newActive: boolean) => {
setToggling(prev => ({ ...prev, [id]: true }));
try {
await taxApi.update(id, { active: newActive });
setRates(prev => prev.map(r => r.id === id ? { ...r, active: newActive } : r));
} catch (er) {
alert(er instanceof Error ? er.message : 'Error al cambiar estado');
} finally {
setToggling(prev => ({ ...prev, [id]: false }));
}
};
```
## Risk
- **Low risk**: purely frontend UX change, no backend or DB changes
- Fallback: existing inline edit still works if toggle fails
## Verification
- `npx tsc --noEmit` admin
- `npx eslint` on changed file
- `./scripts/verify.sh` green
- Manual: toggle a tax rate active/inactive in /tax-rates page → pricing tab updates dropdown