feat(todos): client API TypeScript — Todo interface + 5 fonctions fetch
This commit is contained in:
@@ -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<T>(res: Response): Promise<T> {
|
||||||
|
if (!res.ok) throw new Error(`${res.status} ${res.statusText}`)
|
||||||
|
return res.json() as Promise<T>
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function fetchTodos(filters?: TodoFilters): Promise<Todo[]> {
|
||||||
|
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<Todo[]>(res)
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function createTodo(data: TodoCreate): Promise<Todo> {
|
||||||
|
const res = await fetch(`${BASE}/`, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify(data),
|
||||||
|
})
|
||||||
|
return handleResponse<Todo>(res)
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function updateTodo(id: string, data: TodoUpdate): Promise<Todo> {
|
||||||
|
const res = await fetch(`${BASE}/${id}`, {
|
||||||
|
method: 'PATCH',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify(data),
|
||||||
|
})
|
||||||
|
return handleResponse<Todo>(res)
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function deleteTodo(id: string): Promise<void> {
|
||||||
|
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<Todo> {
|
||||||
|
const res = await fetch(`${BASE}/${id}/postpone`, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify({ days }),
|
||||||
|
})
|
||||||
|
return handleResponse<Todo>(res)
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user