diff --git a/frontend/src/api/todos.ts b/frontend/src/api/todos.ts new file mode 100644 index 0000000..9720724 --- /dev/null +++ b/frontend/src/api/todos.ts @@ -0,0 +1,101 @@ +// frontend/src/api/todos.ts +export interface Todo { + id: string + title: string + body: string | null + url: string | null + domain: string | null + category: string | null + tags: string[] + status: 'pending' | 'done' | 'cancelled' + priority: 'low' | 'medium' | 'high' + due_date: string | null + postponed_count: number + created_at: string + updated_at: string | null + owner_id: string | null +} + +export interface TodoCreate { + title: string + body?: string + url?: string + domain?: string + category?: string + tags?: string[] + status?: string + priority?: string + due_date?: string +} + +export interface TodoUpdate { + title?: string + body?: string + url?: string + domain?: string + category?: string + tags?: string[] + status?: string + priority?: string + due_date?: string +} + +export interface TodoFilters { + domain?: string + status?: string + priority?: string + tag?: string + due_after?: string + due_before?: string +} + +const BASE = '/api/todos' + +async function handleResponse(res: Response): Promise { + if (!res.ok) throw new Error(`${res.status} ${res.statusText}`) + return res.json() as Promise +} + +export async function fetchTodos(filters?: TodoFilters): Promise { + const qs = new URLSearchParams() + if (filters?.domain) qs.set('domain', filters.domain) + if (filters?.status !== undefined) qs.set('status', filters.status) + if (filters?.priority) qs.set('priority', filters.priority) + if (filters?.tag) qs.set('tag', filters.tag) + if (filters?.due_after) qs.set('due_after', filters.due_after) + if (filters?.due_before) qs.set('due_before', filters.due_before) + const res = await fetch(`${BASE}/?${qs}`) + return handleResponse(res) +} + +export async function createTodo(data: TodoCreate): Promise { + const res = await fetch(`${BASE}/`, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(data), + }) + return handleResponse(res) +} + +export async function updateTodo(id: string, data: TodoUpdate): Promise { + const res = await fetch(`${BASE}/${id}`, { + method: 'PATCH', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(data), + }) + return handleResponse(res) +} + +export async function deleteTodo(id: string): Promise { + const res = await fetch(`${BASE}/${id}`, { method: 'DELETE' }) + if (!res.ok) throw new Error(`${res.status} ${res.statusText}`) +} + +export async function postponeTodo(id: string, days: 1 | 7): Promise { + const res = await fetch(`${BASE}/${id}/postpone`, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ days }), + }) + return handleResponse(res) +}