init
This commit is contained in:
75
web/src/api.ts
Normal file
75
web/src/api.ts
Normal file
@@ -0,0 +1,75 @@
|
||||
export interface Staff {
|
||||
id: string;
|
||||
name: string;
|
||||
active: boolean;
|
||||
}
|
||||
|
||||
export type BusinessStatus = 'ACTIVE' | 'SOLD' | 'INACTIVE';
|
||||
|
||||
export interface BusinessListItem {
|
||||
id: string;
|
||||
name: string;
|
||||
status: BusinessStatus;
|
||||
}
|
||||
|
||||
export interface BusinessList {
|
||||
businesses: BusinessListItem[];
|
||||
counts: Record<BusinessStatus, number>;
|
||||
}
|
||||
|
||||
export interface Business {
|
||||
id: string;
|
||||
name: string;
|
||||
nas_path: string;
|
||||
status: BusinessStatus;
|
||||
}
|
||||
|
||||
export interface BusinessFile {
|
||||
name: string;
|
||||
size: number;
|
||||
mtime: string;
|
||||
}
|
||||
|
||||
export interface ScanResult {
|
||||
scanned: number;
|
||||
inserted: number;
|
||||
updated: number;
|
||||
missing: number;
|
||||
}
|
||||
|
||||
export class ApiError extends Error {
|
||||
constructor(readonly status: number, message: string) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
|
||||
async function request<T>(path: string, init?: RequestInit): Promise<T> {
|
||||
const res = await fetch(path, { credentials: 'same-origin', ...init });
|
||||
if (!res.ok) {
|
||||
const body = (await res.json().catch(() => null)) as { error?: string } | null;
|
||||
throw new ApiError(res.status, body?.error ?? `Request failed (${res.status})`);
|
||||
}
|
||||
return (await res.json()) as T;
|
||||
}
|
||||
|
||||
function post<T>(path: string, body?: unknown): Promise<T> {
|
||||
return request<T>(path, {
|
||||
method: 'POST',
|
||||
headers: { 'content-type': 'application/json' },
|
||||
body: JSON.stringify(body ?? {}),
|
||||
});
|
||||
}
|
||||
|
||||
export const api = {
|
||||
me: () => request<Staff>('/api/me'),
|
||||
staff: () => request<Staff[]>('/api/staff'),
|
||||
login: (staffId: string) => post<{ ok: boolean; staff: Staff }>('/api/login', { staff_id: staffId }),
|
||||
logout: () => post<{ ok: boolean }>('/api/logout'),
|
||||
businesses: (status: BusinessStatus, search: string) =>
|
||||
request<BusinessList>(
|
||||
`/api/businesses?status=${encodeURIComponent(status)}&search=${encodeURIComponent(search)}`,
|
||||
),
|
||||
business: (id: string) => request<Business>(`/api/businesses/${id}`),
|
||||
businessFiles: (id: string) => request<BusinessFile[]>(`/api/businesses/${id}/files`),
|
||||
scan: () => post<ScanResult>('/api/businesses/scan'),
|
||||
};
|
||||
Reference in New Issue
Block a user