Phase 1 Complete by Claude Code
This commit is contained in:
@@ -1 +1,63 @@
|
||||
// TODO: Axios/fetch wrapper with JWT
|
||||
const API_BASE = "/api";
|
||||
|
||||
class ApiClient {
|
||||
getToken() {
|
||||
return localStorage.getItem("access_token");
|
||||
}
|
||||
|
||||
async request(endpoint, options = {}) {
|
||||
const url = `${API_BASE}${endpoint}`;
|
||||
const token = this.getToken();
|
||||
|
||||
const headers = {
|
||||
"Content-Type": "application/json",
|
||||
...options.headers,
|
||||
};
|
||||
|
||||
if (token) {
|
||||
headers["Authorization"] = `Bearer ${token}`;
|
||||
}
|
||||
|
||||
const response = await fetch(url, { ...options, headers });
|
||||
|
||||
if (response.status === 401) {
|
||||
localStorage.removeItem("access_token");
|
||||
localStorage.removeItem("user");
|
||||
window.location.href = "/login";
|
||||
throw new Error("Session expired");
|
||||
}
|
||||
|
||||
if (!response.ok) {
|
||||
const error = await response.json().catch(() => ({}));
|
||||
throw new Error(error.detail || `Request failed: ${response.status}`);
|
||||
}
|
||||
|
||||
if (response.status === 204) return null;
|
||||
return response.json();
|
||||
}
|
||||
|
||||
get(endpoint) {
|
||||
return this.request(endpoint, { method: "GET" });
|
||||
}
|
||||
|
||||
post(endpoint, data) {
|
||||
return this.request(endpoint, {
|
||||
method: "POST",
|
||||
body: JSON.stringify(data),
|
||||
});
|
||||
}
|
||||
|
||||
put(endpoint, data) {
|
||||
return this.request(endpoint, {
|
||||
method: "PUT",
|
||||
body: JSON.stringify(data),
|
||||
});
|
||||
}
|
||||
|
||||
delete(endpoint) {
|
||||
return this.request(endpoint, { method: "DELETE" });
|
||||
}
|
||||
}
|
||||
|
||||
const api = new ApiClient();
|
||||
export default api;
|
||||
|
||||
Reference in New Issue
Block a user