fix(gro-158): add r.ok checks before .json() in AppointmentsPage and fix DevLoginSelector userId fallback
Two fixes for the admin page blank / TypeError: b.filter issue:
1. Appointments.tsx: Add r.ok status checks before calling r.json() on
/api/clients, /api/services, and /api/staff. Previously, 403/404 error
responses would have their JSON bodies (e.g. {error:"Forbidden"}) passed
to state setters, causing Array.prototype.filter to fail on non-array
objects. Now errors are thrown and caught by the existing .catch() handler,
setting the error state instead.
2. DevLoginSelector.tsx: Add userId field to StaffUser and use
s.userId ?? s.id when calling selectUser. If the API returns a non-null
userId (post-migration), that is used as the dev login identifier;
otherwise falls back to staff.id (pre-migration records where userId
is null).
Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
@@ -131,9 +131,18 @@ export function AppointmentsPage() {
|
||||
setError(null);
|
||||
Promise.all([
|
||||
loadAppointments(),
|
||||
fetch("/api/clients").then((r) => r.json() as Promise<Client[]>).then(setClients),
|
||||
fetch("/api/services").then((r) => r.json() as Promise<Service[]>).then(setServices),
|
||||
fetch("/api/staff").then((r) => r.json() as Promise<Staff[]>).then(setStaff),
|
||||
fetch("/api/clients").then((r) => {
|
||||
if (!r.ok) throw new Error(`HTTP ${r.status}`);
|
||||
return r.json() as Promise<Client[]>;
|
||||
}).then(setClients),
|
||||
fetch("/api/services").then((r) => {
|
||||
if (!r.ok) throw new Error(`HTTP ${r.status}`);
|
||||
return r.json() as Promise<Service[]>;
|
||||
}).then(setServices),
|
||||
fetch("/api/staff").then((r) => {
|
||||
if (!r.ok) throw new Error(`HTTP ${r.status}`);
|
||||
return r.json() as Promise<Staff[]>;
|
||||
}).then(setStaff),
|
||||
])
|
||||
.catch((e: unknown) => setError(e instanceof Error ? e.message : "Unknown error"))
|
||||
.finally(() => setLoading(false));
|
||||
|
||||
@@ -3,6 +3,7 @@ import { useNavigate } from "react-router-dom";
|
||||
|
||||
interface StaffUser {
|
||||
id: string;
|
||||
userId: string | null;
|
||||
name: string;
|
||||
email: string;
|
||||
role: string;
|
||||
@@ -66,7 +67,7 @@ export function DevLoginSelector() {
|
||||
{staff.map((s) => (
|
||||
<button
|
||||
key={s.id}
|
||||
onClick={() => selectUser("staff", s.id, s.name)}
|
||||
onClick={() => selectUser("staff", s.userId ?? s.id, s.name)}
|
||||
style={userButtonStyle}
|
||||
>
|
||||
<div style={{ fontWeight: 600, fontSize: 14 }}>{s.name}</div>
|
||||
|
||||
Reference in New Issue
Block a user