chih.yikuan
Redesign ClassLens v2: 3-step exam analysis workflow
bc45e54
Raw
History Blame Contribute Delete
2.31 kB
import { API_BASE_URL } from "./config";
const TOKEN_KEY = "classlens_token";
export function getToken(): string | null {
return localStorage.getItem(TOKEN_KEY);
}
export function setToken(token: string) {
localStorage.setItem(TOKEN_KEY, token);
}
export function clearToken() {
localStorage.removeItem(TOKEN_KEY);
}
function authHeaders(): Record<string, string> {
const token = getToken();
return token ? { Authorization: `Bearer ${token}` } : {};
}
async function handleResponse<T>(res: Response): Promise<T> {
if (res.status === 401) {
clearToken();
window.location.reload();
throw new Error("Unauthorized");
}
if (!res.ok) {
const text = await res.text();
let msg = text;
try {
const j = JSON.parse(text);
msg = j.detail || j.message || text;
} catch {}
throw new Error(msg);
}
return res.json();
}
export async function apiGet<T>(path: string): Promise<T> {
const res = await fetch(`${API_BASE_URL}${path}`, {
headers: { ...authHeaders() },
});
return handleResponse<T>(res);
}
export async function apiPost<T>(path: string, body?: unknown): Promise<T> {
const res = await fetch(`${API_BASE_URL}${path}`, {
method: "POST",
headers: { "Content-Type": "application/json", ...authHeaders() },
body: body ? JSON.stringify(body) : undefined,
});
return handleResponse<T>(res);
}
export async function apiPut<T>(path: string, body: unknown): Promise<T> {
const res = await fetch(`${API_BASE_URL}${path}`, {
method: "PUT",
headers: { "Content-Type": "application/json", ...authHeaders() },
body: JSON.stringify(body),
});
return handleResponse<T>(res);
}
export async function apiDelete(path: string): Promise<void> {
const res = await fetch(`${API_BASE_URL}${path}`, {
method: "DELETE",
headers: { ...authHeaders() },
});
if (res.status === 401) {
clearToken();
window.location.reload();
throw new Error("Unauthorized");
}
if (!res.ok) {
const text = await res.text();
throw new Error(text);
}
}
export async function apiUpload<T>(path: string, formData: FormData): Promise<T> {
const res = await fetch(`${API_BASE_URL}${path}`, {
method: "POST",
headers: { ...authHeaders() },
body: formData,
});
return handleResponse<T>(res);
}