File size: 2,283 Bytes
7563aec
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
// 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<T>(path: string): Promise<T> {
  const res = await fetch(`${BASE}${path}`);
  if (!res.ok) throw new Error(`API error ${res.status}: ${await res.text()}`);
  return res.json() as Promise<T>;
}

export const api = {
  datasets: (): Promise<DatasetInfo[]> =>
    get('/datasets'),

  patients: (params: {
    dataset: string;
    page?: number;
    limit?: number;
    search?: string;
    cdr?: number | null;
  }): Promise<PatientsPage> => {
    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<PatientDetail> =>
    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`),
};