feat: SAC 0.6.0 user edit UI, login to dashboard, daily report timer sync
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+56
-1
@@ -51,7 +51,7 @@ export async function apiFetch<T>(path: string, init: RequestInit = {}): Promise
|
||||
}
|
||||
if (!res.ok) {
|
||||
const text = await res.text();
|
||||
throw new Error(text || res.statusText);
|
||||
throw new Error(parseApiError(text) || res.statusText);
|
||||
}
|
||||
return res.json() as Promise<T>;
|
||||
}
|
||||
@@ -72,6 +72,61 @@ export function fetchMe(): Promise<MeResponse> {
|
||||
return apiFetch<MeResponse>("/api/v1/auth/me");
|
||||
}
|
||||
|
||||
export function parseApiError(text: string): string {
|
||||
if (!text) return "";
|
||||
try {
|
||||
const data = JSON.parse(text) as { detail?: string | Array<{ msg?: string }> };
|
||||
if (typeof data.detail === "string") return data.detail;
|
||||
if (Array.isArray(data.detail)) {
|
||||
return data.detail.map((item) => item.msg ?? String(item)).join("; ");
|
||||
}
|
||||
} catch {
|
||||
/* plain text */
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
export interface UserSummary {
|
||||
id: number;
|
||||
username: string;
|
||||
role: string;
|
||||
is_active: boolean;
|
||||
created_at: string;
|
||||
}
|
||||
|
||||
export interface UserListResponse {
|
||||
items: UserSummary[];
|
||||
}
|
||||
|
||||
export interface UpdateUserPayload {
|
||||
username?: string;
|
||||
role?: string;
|
||||
password?: string;
|
||||
is_active?: boolean;
|
||||
}
|
||||
|
||||
export function fetchUsers(): Promise<UserListResponse> {
|
||||
return apiFetch<UserListResponse>("/api/v1/users");
|
||||
}
|
||||
|
||||
export function createUser(payload: {
|
||||
username: string;
|
||||
password: string;
|
||||
role: string;
|
||||
}): Promise<UserSummary> {
|
||||
return apiFetch<UserSummary>("/api/v1/users", {
|
||||
method: "POST",
|
||||
body: JSON.stringify(payload),
|
||||
});
|
||||
}
|
||||
|
||||
export function updateUser(userId: number, payload: UpdateUserPayload): Promise<UserSummary> {
|
||||
return apiFetch<UserSummary>(`/api/v1/users/${userId}`, {
|
||||
method: "PATCH",
|
||||
body: JSON.stringify(payload),
|
||||
});
|
||||
}
|
||||
|
||||
export interface EventSummary {
|
||||
id: number;
|
||||
event_id: string;
|
||||
|
||||
Reference in New Issue
Block a user