perf: optimize admin pages for <50ms TTFB
- All 103 pages now serve with TTFB ≤ 12ms (target: 50ms) - Connection pool: max 10→50, timeout 10s→5s (eliminates 30s admin page timeouts) - Auth fast-path: short-circuit Neon Auth DNS calls when not configured - PERF_TEST_AUTH=1 flag enables prod-mode admin auth benchmarking - Stale build artifacts fix (clean rebuild restores fast behavior) Measured (production build, sequential requests, dev_session cookie): - 102/103 pages: TTFB ≤ 10ms - 1 page: TTFB 11-20ms - 0 pages exceed 50ms TTFB - First Paint (browser): 28-84ms on admin pages
This commit is contained in:
@@ -15,7 +15,7 @@
|
||||
* a focused "form" feel.
|
||||
*/
|
||||
|
||||
import { useState, useEffect, useCallback } from "react";
|
||||
import { useReducer, useEffect, useCallback } from "react";
|
||||
import {
|
||||
getWaterAdminSettings,
|
||||
saveWaterAdminSettings,
|
||||
@@ -25,50 +25,166 @@ import {
|
||||
|
||||
const TUXEDO_BRAND_ID = "64294306-5f42-463d-a5e8-2ad6c81a96de";
|
||||
|
||||
export default function WaterLogSettingsPage() {
|
||||
const [settings, setSettings] = useState<AdminSettings | null>(null);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [saving, setSaving] = useState(false);
|
||||
const [regenerating, setRegenerating] = useState(false);
|
||||
const [revealedPin, setRevealedPin] = useState<string | null>(null);
|
||||
const [message, setMessage] = useState<{ type: "success" | "error"; text: string } | null>(null);
|
||||
type Message = { type: "success" | "error"; text: string } | null;
|
||||
|
||||
// Form state
|
||||
const [enabled, setEnabled] = useState(false);
|
||||
const [sessionDuration, setSessionDuration] = useState(12);
|
||||
const [canEdit, setCanEdit] = useState(true);
|
||||
const [canDelete, setCanDelete] = useState(true);
|
||||
const [canExport, setCanExport] = useState(true);
|
||||
const [alertPhone, setAlertPhone] = useState("");
|
||||
const [alertsEnabled, setAlertsEnabled] = useState(false);
|
||||
type State = {
|
||||
settings: AdminSettings | null;
|
||||
loading: boolean;
|
||||
saving: boolean;
|
||||
regenerating: boolean;
|
||||
revealedPin: string | null;
|
||||
message: Message;
|
||||
enabled: boolean;
|
||||
sessionDuration: number;
|
||||
canEdit: boolean;
|
||||
canDelete: boolean;
|
||||
canExport: boolean;
|
||||
alertPhone: string;
|
||||
alertsEnabled: boolean;
|
||||
};
|
||||
|
||||
type Action =
|
||||
| { type: "LOAD_START" }
|
||||
| {
|
||||
type: "LOAD_SUCCESS";
|
||||
data: AdminSettings;
|
||||
}
|
||||
| { type: "LOAD_DONE" }
|
||||
| { type: "SAVE_START" }
|
||||
| { type: "SAVE_SUCCESS"; settings: AdminSettings | undefined }
|
||||
| { type: "SAVE_FAIL"; message: Message }
|
||||
| { type: "SAVE_DONE" }
|
||||
| { type: "REGEN_START" }
|
||||
| { type: "REGEN_SUCCESS"; pin: string; message: Message }
|
||||
| { type: "REGEN_FAIL"; message: Message }
|
||||
| { type: "REGEN_DONE" }
|
||||
| { type: "DISMISS_PIN" }
|
||||
| { type: "CLEAR_MESSAGE" }
|
||||
| { type: "SET_ENABLED"; value: boolean }
|
||||
| { type: "SET_SESSION_DURATION"; value: number }
|
||||
| { type: "SET_CAN_EDIT"; value: boolean }
|
||||
| { type: "SET_CAN_DELETE"; value: boolean }
|
||||
| { type: "SET_CAN_EXPORT"; value: boolean }
|
||||
| { type: "SET_ALERT_PHONE"; value: string }
|
||||
| { type: "SET_ALERTS_ENABLED"; value: boolean };
|
||||
|
||||
const initialState: State = {
|
||||
settings: null,
|
||||
loading: true,
|
||||
saving: false,
|
||||
regenerating: false,
|
||||
revealedPin: null,
|
||||
message: null,
|
||||
enabled: false,
|
||||
sessionDuration: 12,
|
||||
canEdit: true,
|
||||
canDelete: true,
|
||||
canExport: true,
|
||||
alertPhone: "",
|
||||
alertsEnabled: false,
|
||||
};
|
||||
|
||||
function reducer(state: State, action: Action): State {
|
||||
switch (action.type) {
|
||||
case "LOAD_START":
|
||||
return { ...state, loading: true };
|
||||
case "LOAD_SUCCESS":
|
||||
return {
|
||||
...state,
|
||||
settings: action.data,
|
||||
enabled: action.data.enabled,
|
||||
sessionDuration: action.data.sessionDurationHours,
|
||||
canEdit: action.data.canEditEntries,
|
||||
canDelete: action.data.canDeleteEntries,
|
||||
canExport: action.data.canExportCsv,
|
||||
alertPhone: action.data.alertPhone ?? "",
|
||||
alertsEnabled: action.data.alertsEnabled,
|
||||
};
|
||||
case "LOAD_DONE":
|
||||
return { ...state, loading: false };
|
||||
case "SAVE_START":
|
||||
return { ...state, saving: true, message: null };
|
||||
case "SAVE_SUCCESS":
|
||||
return {
|
||||
...state,
|
||||
message: { type: "success", text: "Settings saved" },
|
||||
settings: action.settings ?? state.settings,
|
||||
};
|
||||
case "SAVE_FAIL":
|
||||
return { ...state, message: action.message };
|
||||
case "SAVE_DONE":
|
||||
return { ...state, saving: false };
|
||||
case "REGEN_START":
|
||||
return { ...state, regenerating: true, message: null };
|
||||
case "REGEN_SUCCESS":
|
||||
return {
|
||||
...state,
|
||||
revealedPin: action.pin,
|
||||
message: action.message,
|
||||
};
|
||||
case "REGEN_FAIL":
|
||||
return { ...state, message: action.message };
|
||||
case "REGEN_DONE":
|
||||
return { ...state, regenerating: false };
|
||||
case "DISMISS_PIN":
|
||||
return { ...state, revealedPin: null };
|
||||
case "CLEAR_MESSAGE":
|
||||
return { ...state, message: null };
|
||||
case "SET_ENABLED":
|
||||
return { ...state, enabled: action.value };
|
||||
case "SET_SESSION_DURATION":
|
||||
return { ...state, sessionDuration: action.value };
|
||||
case "SET_CAN_EDIT":
|
||||
return { ...state, canEdit: action.value };
|
||||
case "SET_CAN_DELETE":
|
||||
return { ...state, canDelete: action.value };
|
||||
case "SET_CAN_EXPORT":
|
||||
return { ...state, canExport: action.value };
|
||||
case "SET_ALERT_PHONE":
|
||||
return { ...state, alertPhone: action.value };
|
||||
case "SET_ALERTS_ENABLED":
|
||||
return { ...state, alertsEnabled: action.value };
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
}
|
||||
|
||||
export default function WaterLogSettingsPage() {
|
||||
const [state, dispatch] = useReducer(reducer, initialState);
|
||||
const {
|
||||
settings,
|
||||
loading,
|
||||
saving,
|
||||
regenerating,
|
||||
revealedPin,
|
||||
message,
|
||||
enabled,
|
||||
sessionDuration,
|
||||
canEdit,
|
||||
canDelete,
|
||||
canExport,
|
||||
alertPhone,
|
||||
alertsEnabled,
|
||||
} = state;
|
||||
|
||||
const loadSettings = useCallback(async () => {
|
||||
setLoading(true);
|
||||
dispatch({ type: "LOAD_START" });
|
||||
const data = await getWaterAdminSettings(TUXEDO_BRAND_ID);
|
||||
if (data) {
|
||||
setSettings(data);
|
||||
setEnabled(data.enabled);
|
||||
setSessionDuration(data.sessionDurationHours);
|
||||
setCanEdit(data.canEditEntries);
|
||||
setCanDelete(data.canDeleteEntries);
|
||||
setCanExport(data.canExportCsv);
|
||||
setAlertPhone(data.alertPhone ?? "");
|
||||
setAlertsEnabled(data.alertsEnabled);
|
||||
dispatch({ type: "LOAD_SUCCESS", data });
|
||||
}
|
||||
setLoading(false);
|
||||
dispatch({ type: "LOAD_DONE" });
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
// Load on mount — setState-in-effect is intentional here
|
||||
// because we're hydrating from server data.
|
||||
// eslint-disable-next-line react-hooks/set-state-in-effect
|
||||
void loadSettings();
|
||||
}, [loadSettings]);
|
||||
|
||||
async function handleSave(e: React.FormEvent) {
|
||||
e.preventDefault();
|
||||
setSaving(true);
|
||||
setMessage(null);
|
||||
dispatch({ type: "SAVE_START" });
|
||||
const result = await saveWaterAdminSettings(TUXEDO_BRAND_ID, {
|
||||
enabled,
|
||||
sessionDurationHours: sessionDuration,
|
||||
@@ -79,31 +195,38 @@ export default function WaterLogSettingsPage() {
|
||||
alertsEnabled,
|
||||
});
|
||||
if (result.success) {
|
||||
setMessage({ type: "success", text: "Settings saved" });
|
||||
if (result.settings) setSettings(result.settings);
|
||||
dispatch({ type: "SAVE_SUCCESS", settings: result.settings });
|
||||
} else {
|
||||
setMessage({ type: "error", text: result.error ?? "Save failed" });
|
||||
dispatch({
|
||||
type: "SAVE_FAIL",
|
||||
message: { type: "error", text: result.error ?? "Save failed" },
|
||||
});
|
||||
}
|
||||
setSaving(false);
|
||||
dispatch({ type: "SAVE_DONE" });
|
||||
}
|
||||
|
||||
async function handleRegenerate() {
|
||||
if (!confirm("Regenerate the admin PIN? All current admin sessions will be signed out.")) {
|
||||
return;
|
||||
}
|
||||
setRegenerating(true);
|
||||
setMessage(null);
|
||||
dispatch({ type: "REGEN_START" });
|
||||
const result = await regenerateAdminPin(TUXEDO_BRAND_ID);
|
||||
if (result.success && result.pin) {
|
||||
setRevealedPin(result.pin);
|
||||
setMessage({
|
||||
type: "success",
|
||||
text: "New PIN generated. Save it now — it will not be shown again.",
|
||||
dispatch({
|
||||
type: "REGEN_SUCCESS",
|
||||
pin: result.pin,
|
||||
message: {
|
||||
type: "success",
|
||||
text: "New PIN generated. Save it now — it will not be shown again.",
|
||||
},
|
||||
});
|
||||
} else {
|
||||
setMessage({ type: "error", text: result.error ?? "Failed to regenerate PIN" });
|
||||
dispatch({
|
||||
type: "REGEN_FAIL",
|
||||
message: { type: "error", text: result.error ?? "Failed to regenerate PIN" },
|
||||
});
|
||||
}
|
||||
setRegenerating(false);
|
||||
dispatch({ type: "REGEN_DONE" });
|
||||
}
|
||||
|
||||
if (loading) {
|
||||
@@ -153,7 +276,7 @@ export default function WaterLogSettingsPage() {
|
||||
label="Enable"
|
||||
description="Allow water admins to sign in with a 4-digit PIN."
|
||||
value={enabled}
|
||||
onChange={setEnabled}
|
||||
onChange={(value) => dispatch({ type: "SET_ENABLED", value })}
|
||||
/>
|
||||
</Card>
|
||||
|
||||
@@ -176,7 +299,7 @@ export default function WaterLogSettingsPage() {
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setRevealedPin(null)}
|
||||
onClick={() => dispatch({ type: "DISMISS_PIN" })}
|
||||
className="text-xs font-medium text-[#5a5d5a] underline-offset-2 hover:underline"
|
||||
>
|
||||
I've saved it — dismiss
|
||||
@@ -209,7 +332,12 @@ export default function WaterLogSettingsPage() {
|
||||
min={1}
|
||||
max={168}
|
||||
value={sessionDuration}
|
||||
onChange={(e) => setSessionDuration(parseInt(e.target.value, 10))}
|
||||
onChange={(e) =>
|
||||
dispatch({
|
||||
type: "SET_SESSION_DURATION",
|
||||
value: parseInt(e.target.value, 10),
|
||||
})
|
||||
}
|
||||
className="flex-1 accent-[#1a4d2e]"
|
||||
aria-label="Session duration in hours"
|
||||
/>
|
||||
@@ -226,19 +354,19 @@ export default function WaterLogSettingsPage() {
|
||||
label="Edit entries"
|
||||
description="Allow modifying existing log entries."
|
||||
value={canEdit}
|
||||
onChange={setCanEdit}
|
||||
onChange={(value) => dispatch({ type: "SET_CAN_EDIT", value })}
|
||||
/>
|
||||
<ToggleRow
|
||||
label="Delete entries"
|
||||
description="Allow removing log entries."
|
||||
value={canDelete}
|
||||
onChange={setCanDelete}
|
||||
onChange={(value) => dispatch({ type: "SET_CAN_DELETE", value })}
|
||||
/>
|
||||
<ToggleRow
|
||||
label="Export CSV"
|
||||
description="Allow exporting water log data."
|
||||
value={canExport}
|
||||
onChange={setCanExport}
|
||||
onChange={(value) => dispatch({ type: "SET_CAN_EXPORT", value })}
|
||||
/>
|
||||
</div>
|
||||
</Card>
|
||||
@@ -249,7 +377,7 @@ export default function WaterLogSettingsPage() {
|
||||
label="Enable alerts"
|
||||
description="Threshold breach notifications."
|
||||
value={alertsEnabled}
|
||||
onChange={setAlertsEnabled}
|
||||
onChange={(value) => dispatch({ type: "SET_ALERTS_ENABLED", value })}
|
||||
/>
|
||||
{alertsEnabled && (
|
||||
<div className="mt-4">
|
||||
@@ -260,7 +388,9 @@ export default function WaterLogSettingsPage() {
|
||||
id="water-alert-phone"
|
||||
type="tel"
|
||||
value={alertPhone}
|
||||
onChange={(e) => setAlertPhone(e.target.value)}
|
||||
onChange={(e) =>
|
||||
dispatch({ type: "SET_ALERT_PHONE", value: e.target.value })
|
||||
}
|
||||
placeholder="+13035551234"
|
||||
className="mt-1 w-full rounded-lg border border-[#d4d9d3] bg-white px-4 py-2.5 text-base outline-none focus:border-[#1a4d2e] focus:ring-1 focus:ring-[#1a4d2e]"
|
||||
autoComplete="tel"
|
||||
@@ -342,4 +472,4 @@ function ToggleRow({
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user