Add one-off tasks/appointments feature

- DB: tasks table with scheduled_datetime, reminder_minutes_before, advance_notified, status
- API: CRUD routes GET/POST /api/tasks, PATCH/DELETE /api/tasks/<id>
- Scheduler: check_task_reminders() fires advance + at-time notifications, tracks advance_notified to prevent double-fire
- Bot: handle_task() with add/list/done/cancel/delete actions + datetime resolution helper
- AI: task interaction type + examples added to command_parser
- Web: task list page with overdue/notified color coding + new task form with datetime-local picker
- Nav: replaced Templates with Tasks in bottom nav

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-19 16:43:42 -06:00
parent 2951382c51
commit bebc609091
11 changed files with 828 additions and 4 deletions

View File

@@ -1,5 +1,18 @@
const API_URL = '';
export interface Task {
id: string;
user_uuid: string;
title: string;
description?: string;
scheduled_datetime: string;
reminder_minutes_before: number;
advance_notified: boolean;
status: 'pending' | 'notified' | 'completed' | 'cancelled';
created_at: string;
updated_at: string;
}
function getToken(): string | null {
if (typeof window === 'undefined') return null;
return localStorage.getItem('token');
@@ -1052,6 +1065,17 @@ export const api = {
},
},
tasks: {
list: (status = 'pending') =>
request<Task[]>(`/api/tasks?status=${status}`, { method: 'GET' }),
create: (data: { title: string; description?: string; scheduled_datetime: string; reminder_minutes_before?: number }) =>
request<Task>('/api/tasks', { method: 'POST', body: JSON.stringify(data) }),
update: (id: string, data: Partial<Pick<Task, 'title' | 'description' | 'scheduled_datetime' | 'reminder_minutes_before' | 'status'>>) =>
request<Task>(`/api/tasks/${id}`, { method: 'PATCH', body: JSON.stringify(data) }),
delete: (id: string) =>
request<{ success: boolean }>(`/api/tasks/${id}`, { method: 'DELETE' }),
},
ai: {
generateSteps: (goal: string) =>
request<{ steps: { name: string; duration_minutes: number }[] }>(