diff --git a/apps/web/src/lib/devFetch.ts b/apps/web/src/lib/devFetch.ts index 76798a7..42078ce 100644 --- a/apps/web/src/lib/devFetch.ts +++ b/apps/web/src/lib/devFetch.ts @@ -9,10 +9,6 @@ const originalFetch = window.fetch; * Intentionally mutates window.fetch — this is dev-only (AUTH_DISABLED=true). */ export function installDevFetchInterceptor() { - // Only install if a dev user is selected (localStorage check, not build-time flag). - // This ensures the interceptor runs in deployed dev builds, not just `vite dev`. - if (!getDevUser()) return; - window.fetch = function (input: RequestInfo | URL, init?: RequestInit) { const user = getDevUser(); if (!user) return originalFetch(input, init); diff --git a/apps/web/src/pages/Services.tsx b/apps/web/src/pages/Services.tsx index 65cf380..7398c9d 100644 --- a/apps/web/src/pages/Services.tsx +++ b/apps/web/src/pages/Services.tsx @@ -26,6 +26,7 @@ export function ServicesPage() { const [form, setForm] = useState(EMPTY_FORM); const [saving, setSaving] = useState(false); const [formError, setFormError] = useState(null); + const [togglingId, setTogglingId] = useState(null); async function load() { const r = await fetch("/api/services?includeInactive=true"); @@ -102,12 +103,17 @@ export function ServicesPage() { } async function toggleActive(s: Service) { - await fetch(`/api/services/${s.id}`, { - method: "PATCH", - headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ active: !s.active }), - }); - await load(); + setTogglingId(s.id); + try { + await fetch(`/api/services/${s.id}`, { + method: "PATCH", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ active: !s.active }), + }); + await load(); + } finally { + setTogglingId(null); + } } if (loading) return

Loading…

; @@ -147,26 +153,43 @@ export function ServicesPage() { ${(s.basePriceCents / 100).toFixed(2)} {s.durationMinutes} min - toggleActive(s)} + disabled={togglingId === s.id} + title={s.active ? "Deactivate" : "Activate"} style={{ - padding: "2px 8px", - borderRadius: 12, - fontSize: 11, - fontWeight: 600, - background: s.active ? "#d1fae5" : "#f3f4f6", - color: s.active ? "#065f46" : "#6b7280", + position: "relative", + width: 36, + height: 20, + borderRadius: 10, + border: "1px solid", + borderColor: s.active ? "#10b981" : "#d1d5db", + background: s.active ? "#d1fae5" : "#fff", + cursor: togglingId === s.id ? "not-allowed" : "pointer", + padding: 0, + display: "inline-flex", + alignItems: "center", + opacity: togglingId === s.id ? 0.6 : 1, }} > - {s.active ? "Active" : "Inactive"} - + + {togglingId === s.id && ( + + )} + - ))}