From a862c86bc896fb4c642e6f215d5f5df04cdee726 Mon Sep 17 00:00:00 2001 From: bigben-7 Date: Sat, 17 Oct 2026 11:01:45 +0100 Subject: [PATCH] Essther77-git: real profile/activity/report loaders + change-password call (#1504-#1507) --- frontend/src/lib/auth-api.ts | 27 +++++++++++++++ frontend/src/lib/profile-api.ts | 59 +++++++++++++++++++++++++++++++++ 2 files changed, 86 insertions(+) create mode 100644 frontend/src/lib/auth-api.ts create mode 100644 frontend/src/lib/profile-api.ts diff --git a/frontend/src/lib/auth-api.ts b/frontend/src/lib/auth-api.ts new file mode 100644 index 0000000..cbc89f7 --- /dev/null +++ b/frontend/src/lib/auth-api.ts @@ -0,0 +1,27 @@ +/** + * Auth API calls (#1507). + * + * The security settings "Change password" form reported success without calling + * any API. This provides the missing call so the UI reflects the real result. + */ +import { apiUrl } from "./api-version"; + +export interface ChangePasswordPayload { + currentPassword: string; + newPassword: string; +} + +export async function changePassword( + payload: ChangePasswordPayload, + fetchImpl: typeof fetch = fetch, +): Promise { + const response = await fetchImpl(apiUrl("/auth/change-password"), { + method: "POST", + headers: { "Content-Type": "application/json" }, + credentials: "include", + body: JSON.stringify(payload), + }); + if (!response.ok) { + throw new Error(`Failed to change password (${response.status})`); + } +} diff --git a/frontend/src/lib/profile-api.ts b/frontend/src/lib/profile-api.ts new file mode 100644 index 0000000..b350cc4 --- /dev/null +++ b/frontend/src/lib/profile-api.ts @@ -0,0 +1,59 @@ +/** + * Profile and admin activity loaders (#1506, #1505, #1504). + * + * The profile page showed a hard-coded "Jane Doe" and faked saving with a + * timeout; the admin activity page fell back to MOCK_ACTIVITY; the report page + * silently showed a fake "Sample Land Title". These loaders return the real API + * result and never substitute fake data — callers are expected to render an + * empty/error state instead. + */ +import { apiUrl } from "./api-version"; + +export interface UserProfile { + id: string; + name: string; + email: string; +} + +export async function loadProfile( + fetchImpl: typeof fetch = fetch, +): Promise { + const response = await fetchImpl(apiUrl("/users/me"), { + credentials: "include", + }); + if (response.status === 401) { + return null; + } + if (!response.ok) { + throw new Error(`Failed to load profile (${response.status})`); + } + return (await response.json()) as UserProfile; +} + +export async function loadAdminActivity( + fetchImpl: typeof fetch = fetch, +): Promise { + const response = await fetchImpl(apiUrl("/admin/activity"), { + credentials: "include", + }); + if (!response.ok) { + throw new Error(`Failed to load activity (${response.status})`); + } + return (await response.json()) as T[]; +} + +export async function loadReport( + reportId: string, + fetchImpl: typeof fetch = fetch, +): Promise { + const response = await fetchImpl(apiUrl(`/reports/${reportId}`), { + credentials: "include", + }); + if (response.status === 404) { + return null; + } + if (!response.ok) { + throw new Error(`Failed to load report (${response.status})`); + } + return (await response.json()) as T; +}