Files
infrapuzzle/projects/mila/src/api.ts
T

85 lines
2.4 KiB
TypeScript

import type { MilaDashboardData, DayDetailData } from './types'
const API_BASE = '/duckdb-api/v1'
export function getLocalDateString(): string {
const d = new Date()
const year = d.getFullYear()
const month = String(d.getMonth() + 1).padStart(2, '0')
const day = String(d.getDate()).padStart(2, '0')
return `${year}-${month}-${day}`
}
export async function fetchMilaDashboard(asOf?: string): Promise<MilaDashboardData> {
const url = asOf ? `${API_BASE}/mila/dashboard?as_of=${encodeURIComponent(asOf)}` : `${API_BASE}/mila/dashboard`
const res = await fetch(url)
if (!res.ok) {
throw new Error(`Failed to fetch dashboard: ${res.status} ${res.statusText}`)
}
return res.json()
}
export async function fetchMilaDayDetail(date: string): Promise<DayDetailData> {
const res = await fetch(`${API_BASE}/mila/day/${encodeURIComponent(date)}`)
if (!res.ok) {
throw new Error(`Failed to fetch day detail for ${date}: ${res.statusText}`)
}
return res.json()
}
export async function logEvent(payload: {
kind: string
subject: string
payload: Record<string, any>
start?: string
end?: string
date?: string
since?: string
note?: string
actor?: string
}): Promise<any> {
const res = await fetch(`${API_BASE}/events`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload),
})
if (!res.ok) {
const err = await res.json().catch(() => ({ detail: res.statusText }))
throw new Error(err.detail || 'Failed to log event')
}
return res.json()
}
export async function stopSleepEvent(payload: {
subject: string
end_time?: string
since?: string
event_id?: string
}): Promise<any> {
const res = await fetch(`${API_BASE}/events/stop`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
kind: 'sleep.session',
...payload,
}),
})
if (!res.ok) {
const err = await res.json().catch(() => ({ detail: res.statusText }))
throw new Error(err.detail || 'Failed to stop sleep event')
}
return res.json()
}
export async function deleteEvent(eventId: string): Promise<any> {
const res = await fetch(`${API_BASE}/events/${encodeURIComponent(eventId)}`, {
method: 'DELETE',
})
if (!res.ok) {
const err = await res.json().catch(() => ({ detail: res.statusText }))
throw new Error(err.detail || 'Failed to delete event')
}
return res.json()
}