first commit
This commit is contained in:
commit
0e854110d3
49 files changed
+2292
No files matched your search
@@ -0,0 +1,79 @@
|
||||
export interface AnatomicalSystem {
|
||||
id: string;
|
||||
slug: string;
|
||||
namePt: string;
|
||||
nameEn: string;
|
||||
colorHex: string;
|
||||
order: number;
|
||||
_count?: { structures: number };
|
||||
}
|
||||
|
||||
export interface Structure {
|
||||
id: string;
|
||||
fmaId: string | null;
|
||||
slug: string;
|
||||
namePt: string;
|
||||
nameEn: string;
|
||||
synonyms: string[];
|
||||
description: string | null;
|
||||
regionPath: string[];
|
||||
modelFile: string;
|
||||
meshName: string;
|
||||
systemId: string;
|
||||
system: AnatomicalSystem;
|
||||
}
|
||||
|
||||
export interface QuizCard {
|
||||
id: string;
|
||||
structureId: string;
|
||||
easeFactor: number;
|
||||
intervalDays: number;
|
||||
repetitions: number;
|
||||
dueAt: string;
|
||||
}
|
||||
|
||||
const BASE = "/api";
|
||||
|
||||
async function getJson<T>(url: string): Promise<T> {
|
||||
const res = await fetch(url);
|
||||
if (!res.ok) throw new Error(`GET ${url} failed: ${res.status}`);
|
||||
return res.json() as Promise<T>;
|
||||
}
|
||||
|
||||
export const api = {
|
||||
systems: () => getJson<AnatomicalSystem[]>(`${BASE}/systems`),
|
||||
|
||||
structures: (params: { system?: string; q?: string } = {}) => {
|
||||
const usp = new URLSearchParams();
|
||||
if (params.system) usp.set("system", params.system);
|
||||
if (params.q) usp.set("q", params.q);
|
||||
const qs = usp.toString();
|
||||
return getJson<Structure[]>(`${BASE}/structures${qs ? `?${qs}` : ""}`);
|
||||
},
|
||||
|
||||
structure: (id: string) => getJson<Structure>(`${BASE}/structures/${id}`),
|
||||
|
||||
quizNext: (params: { system?: string; limit?: number } = {}) => {
|
||||
const usp = new URLSearchParams();
|
||||
if (params.system) usp.set("system", params.system);
|
||||
if (params.limit) usp.set("limit", String(params.limit));
|
||||
const qs = usp.toString();
|
||||
return getJson<(Structure & { quizCard: QuizCard | null })[]>(
|
||||
`${BASE}/quiz/next${qs ? `?${qs}` : ""}`,
|
||||
);
|
||||
},
|
||||
|
||||
quizReview: async (structureId: string, quality: number): Promise<QuizCard> => {
|
||||
const res = await fetch(`${BASE}/quiz/${structureId}/review`, {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ quality }),
|
||||
});
|
||||
if (!res.ok) throw new Error(`quizReview failed: ${res.status}`);
|
||||
return res.json();
|
||||
},
|
||||
};
|
||||
|
||||
export function modelUrl(modelFile: string): string {
|
||||
return `/models/${modelFile}`;
|
||||
}
|
||||
Reference in new issue
Block a user