// Typed API client for the MRI viewer backend export interface ChannelInfo { id: string; label: string; colormap: string; } export interface DatasetInfo { id: string; name: string; patient_count: number; } export interface PatientSummary { id: string; dataset: string; age: number | null; sex: string | null; cdr: number | null; cdr_label: string | null; } export interface PatientDetail { id: string; dataset: string; age: number | null; sex: string | null; handedness: string | null; education: number | null; ses: number | null; mmse: number | null; cdr: number | null; cdr_label: string | null; etiv: number | null; nwbv: number | null; asf: number | null; channels: ChannelInfo[]; } export interface PatientsPage { total: number; page: number; limit: number; patients: PatientSummary[]; } const BASE = '/api'; async function get(path: string): Promise { const res = await fetch(`${BASE}${path}`); if (!res.ok) throw new Error(`API error ${res.status}: ${await res.text()}`); return res.json() as Promise; } export const api = { datasets: (): Promise => get('/datasets'), patients: (params: { dataset: string; page?: number; limit?: number; search?: string; cdr?: number | null; }): Promise => { const q = new URLSearchParams({ dataset: params.dataset }); if (params.page) q.set('page', String(params.page)); if (params.limit) q.set('limit', String(params.limit)); if (params.search) q.set('search', params.search); if (params.cdr != null) q.set('cdr', String(params.cdr)); return get(`/patients?${q}`); }, patient: (id: string): Promise => get(`/patients/${encodeURIComponent(id)}`), volumeUrl: (patientId: string, channel: string): string => `${BASE}/patients/${encodeURIComponent(patientId)}/volume/${channel}`, sliceUrl: (patientId: string, channel: string, axis: string, index: number): string => `${BASE}/patients/${encodeURIComponent(patientId)}/slice/${channel}/${axis}/${index}`, volumeShape: (patientId: string, channel: string): Promise<{ shape: number[]; axes: string[] }> => get(`/patients/${encodeURIComponent(patientId)}/volume/${channel}/shape`), };