95 lines
3.8 KiB
TypeScript
95 lines
3.8 KiB
TypeScript
import type { Project, Tool, Settings } from '../types';
|
|
|
|
const BASE = '/api';
|
|
const TOKEN_KEY = 'codedump_token';
|
|
|
|
function getToken(): string | null {
|
|
return localStorage.getItem(TOKEN_KEY);
|
|
}
|
|
|
|
async function req<T>(path: string, options: RequestInit = {}): Promise<T> {
|
|
const token = getToken();
|
|
const headers: Record<string, string> = {
|
|
...(options.headers as Record<string, string> || {}),
|
|
};
|
|
if (token) headers['Authorization'] = `Bearer ${token}`;
|
|
if (options.body && typeof options.body === 'string') headers['Content-Type'] = 'application/json';
|
|
|
|
const res = await fetch(`${BASE}${path}`, { ...options, headers });
|
|
|
|
if (res.status === 401) {
|
|
// Token expired — clear storage and reload to login
|
|
localStorage.removeItem(TOKEN_KEY);
|
|
localStorage.removeItem('codedump_user');
|
|
window.location.href = '/login';
|
|
throw new Error('Session expired');
|
|
}
|
|
|
|
if (!res.ok) {
|
|
const err = await res.json().catch(() => ({ error: res.statusText }));
|
|
throw new Error(err.error || res.statusText);
|
|
}
|
|
if (res.status === 204) return undefined as T;
|
|
return res.json();
|
|
}
|
|
|
|
// Auth
|
|
export const pinLogin = (pin: string) =>
|
|
req<{ token: string; user: any }>('/auth/pin', { method: 'POST', body: JSON.stringify({ pin }) });
|
|
export const adminLogin = (username: string, password: string) =>
|
|
req<{ token: string; user: any }>('/auth/login', { method: 'POST', body: JSON.stringify({ username, password }) });
|
|
|
|
// Users (admin only)
|
|
export const getUsers = () => req<any[]>('/users');
|
|
export const createUser = (data: any) =>
|
|
req<any>('/users', { method: 'POST', body: JSON.stringify(data) });
|
|
export const updateUser = (id: string, data: any) =>
|
|
req<any>(`/users/${id}`, { method: 'PUT', body: JSON.stringify(data) });
|
|
export const deleteUser = (id: string) => req<void>(`/users/${id}`, { method: 'DELETE' });
|
|
|
|
// Projects
|
|
export const getProjects = () => req<Project[]>('/projects');
|
|
export const getProject = (id: string) => req<Project>(`/projects/${id}`);
|
|
export const createProject = (data: Partial<Project>) =>
|
|
req<Project>('/projects', { method: 'POST', body: JSON.stringify(data) });
|
|
export const updateProject = (id: string, data: Partial<Project>) =>
|
|
req<Project>(`/projects/${id}`, { method: 'PUT', body: JSON.stringify(data) });
|
|
export const deleteProject = (id: string) => req<void>(`/projects/${id}`, { method: 'DELETE' });
|
|
|
|
// Tools
|
|
export const getTools = () => req<Tool[]>('/tools');
|
|
export const createTool = (data: Partial<Tool>) =>
|
|
req<Tool>('/tools', { method: 'POST', body: JSON.stringify(data) });
|
|
export const updateTool = (id: string, data: Partial<Tool>) =>
|
|
req<Tool>(`/tools/${id}`, { method: 'PUT', body: JSON.stringify(data) });
|
|
export const deleteTool = (id: string) => req<void>(`/tools/${id}`, { method: 'DELETE' });
|
|
|
|
// Uploads
|
|
export const uploadDocument = (projectId: string, file: File) => {
|
|
const form = new FormData();
|
|
form.append('file', file);
|
|
const token = getToken();
|
|
return fetch(`${BASE}/uploads/projects/${projectId}`, {
|
|
method: 'POST',
|
|
headers: token ? { Authorization: `Bearer ${token}` } : {},
|
|
body: form,
|
|
}).then((r) => r.json());
|
|
};
|
|
export const deleteDocument = (id: string) => req<void>(`/uploads/documents/${id}`, { method: 'DELETE' });
|
|
export const getFileUrl = (filename: string) => `${BASE}/uploads/${filename}`;
|
|
|
|
// Settings
|
|
export const getSettings = () => req<Settings>('/settings');
|
|
export const updateSettings = (data: Partial<Settings>) =>
|
|
req<Settings>('/settings', { method: 'PUT', body: JSON.stringify(data) });
|
|
export const uploadLogo = (file: File) => {
|
|
const form = new FormData();
|
|
form.append('logo', file);
|
|
const token = getToken();
|
|
return fetch(`${BASE}/settings/logo`, {
|
|
method: 'POST',
|
|
headers: token ? { Authorization: `Bearer ${token}` } : {},
|
|
body: form,
|
|
}).then((r) => r.json());
|
|
};
|