source: frontend/src/lib/admin-api.ts

Last change on this file was b8093a0, checked in by imbrsk <boris696boris@…>, 3 days ago

Merge iknow-remaster into frontend/

Bring the Next.js frontend into this repository as a monorepo subdirectory,
preserving its full commit history via a subtree merge.

  • Property mode set to 100644
File size: 2.4 KB
Line 
1import { apiUrl } from "@/lib/api";
2import { getAccessToken } from "@/lib/auth";
3
4export type AdminResult = { ok: boolean; message?: string; id?: number | null };
5
6export type SubjectRef = { id: number; name?: string; code?: string | null };
7
8export type SubjectMajor = {
9 majorId: number;
10 majorName?: string;
11 mandatorySemester: number;
12};
13
14export type AdminSubject = {
15 id: number;
16 name?: string;
17 code?: string;
18 awardedCredits: number;
19 dependencyCredit?: number | null;
20 majors: SubjectMajor[];
21 prerequisites: SubjectRef[];
22 enrolledCount: number;
23};
24
25export type AdminSemester = {
26 id: number;
27 year: number;
28 type?: string;
29 name?: string;
30 enrolmentCount: number;
31 uncoveredSubjects: SubjectRef[];
32};
33
34export type ScheduleRow = {
35 subjectId: number;
36 subjectName?: string;
37 subjectCode?: string;
38 professorId: number;
39 professorName?: string;
40};
41
42export type ProfessorLoad = {
43 professorId: number;
44 professorName?: string;
45 subjects: number;
46};
47
48export type Schedule = {
49 semesterId: number;
50 semesterName?: string;
51 assignments: ScheduleRow[];
52 load: ProfessorLoad[];
53 uncoveredSubjects: SubjectRef[];
54 allSubjects: SubjectRef[];
55 professors: { id: number; name?: string }[];
56};
57
58function authHeaders(): Record<string, string> {
59 const token = getAccessToken();
60 if (!token) throw new Error("You are not signed in.");
61 return { Authorization: `Bearer ${token}`, "Content-Type": "application/json" };
62}
63
64/** GET that throws with the server message rather than a bare status code. */
65export async function adminGet<T>(path: string): Promise<T> {
66 const res = await fetch(apiUrl(path), { cache: "no-store", headers: authHeaders() });
67 if (!res.ok) {
68 const body = await res.json().catch(() => null);
69 throw new Error(body?.message || `Request failed (${res.status})`);
70 }
71 return (await res.json()) as T;
72}
73
74/** POST/PUT/DELETE returning the standard {ok, message} envelope. */
75export async function adminSend(
76 path: string,
77 method: "POST" | "PUT" | "DELETE",
78 body?: unknown,
79): Promise<AdminResult> {
80 const res = await fetch(apiUrl(path), {
81 method,
82 headers: authHeaders(),
83 body: body === undefined ? undefined : JSON.stringify(body),
84 });
85 const result = (await res.json().catch(() => null)) as AdminResult | null;
86 if (!res.ok || !result?.ok) {
87 throw new Error(result?.message || `Request failed (${res.status})`);
88 }
89 return result;
90}
Note: See TracBrowser for help on using the repository browser.