79 lines
2.6 KiB
Markdown
79 lines
2.6 KiB
Markdown
# 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
|