/** * Thin wrappers over the server's REST API. * * Pattern: one async function per endpoint. Each one builds the request, * awaits the response, throws on non-2xx, and parses the JSON body. The UI * imports these by name, so changing a URL or shape only ever touches one * file. * * The `request` helper centralises the fetch + JSON + error-handling * boilerplate so the individual functions stay one-liners. Add a header * (auth tokens, etc.) here and every endpoint picks it up. * * Errors are surfaced as `Error` instances with the status code and body in * the message — the App component catches them and shows the message in the * UI. If you need structured error objects (with codes the UI can branch * on), augment `request` to JSON-parse non-2xx bodies and throw a typed * subclass. */ import type { Category, Todo } from './types'; async function request(path: string, init?: RequestInit): Promise { const res = await fetch(path, { ...init, headers: { 'Content-Type': 'application/json', ...init?.headers, }, }); if (!res.ok) { throw new Error(`Request failed: ${res.status} ${await res.text()}`); } return res.json() as Promise; } export function getCategories(): Promise { return request('/categories'); } export function createCategory(name: string, color: string): Promise { return request('/categories', { method: 'POST', body: JSON.stringify({ name, color }), }); } export function updateCategory(id: number, data: Partial>): Promise { return request(`/categories/${id}`, { method: 'PATCH', body: JSON.stringify(data), }); } export function deleteCategory(id: number): Promise<{ ok: true }> { return request<{ ok: true }>(`/categories/${id}`, { method: 'DELETE' }); } export function getTodos(categoryId: number | null): Promise { const query = categoryId ? `?category_id=${categoryId}` : ''; return request(`/todos${query}`); } export function createTodo(title: string, categoryId: number | null): Promise { return request('/todos', { method: 'POST', body: JSON.stringify({ title, category_id: categoryId }), }); } export function updateTodo(id: number, data: Partial>): Promise { return request(`/todos/${id}`, { method: 'PATCH', body: JSON.stringify(data), }); } export function deleteTodo(id: number): Promise<{ ok: true }> { return request<{ ok: true }>(`/todos/${id}`, { method: 'DELETE' }); }