feat: due dates, subtasks, and task detail page (HQ-{number} URLs)
- Schema: added due_date and subtasks JSONB columns to tasks
- API: CRUD endpoints for subtasks (/tasks/:id/subtasks)
- API: due date support in create/update task
- TaskDetailPanel: due date picker with overdue/soon badges
- TaskDetailPanel: subtask checklist with progress bar
- TaskPage: full-page task view at /task/HQ-{number}
- Dashboard: task cards link to detail page, show subtask progress & due date badges
- Migration: 0001_mighty_callisto.sql
This commit is contained in:
@@ -115,6 +115,38 @@ export async function deleteProject(id: string): Promise<void> {
|
||||
if (!res.ok) throw new Error("Failed to delete project");
|
||||
}
|
||||
|
||||
// Subtasks
|
||||
export async function addSubtask(taskId: string, title: string): Promise<Task> {
|
||||
const res = await fetch(`${BASE}/${taskId}/subtasks`, {
|
||||
method: "POST",
|
||||
credentials: "include",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ title }),
|
||||
});
|
||||
if (!res.ok) throw new Error("Failed to add subtask");
|
||||
return res.json();
|
||||
}
|
||||
|
||||
export async function toggleSubtask(taskId: string, subtaskId: string, completed: boolean): Promise<Task> {
|
||||
const res = await fetch(`${BASE}/${taskId}/subtasks/${subtaskId}`, {
|
||||
method: "PATCH",
|
||||
credentials: "include",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ completed }),
|
||||
});
|
||||
if (!res.ok) throw new Error("Failed to toggle subtask");
|
||||
return res.json();
|
||||
}
|
||||
|
||||
export async function deleteSubtask(taskId: string, subtaskId: string): Promise<Task> {
|
||||
const res = await fetch(`${BASE}/${taskId}/subtasks/${subtaskId}`, {
|
||||
method: "DELETE",
|
||||
credentials: "include",
|
||||
});
|
||||
if (!res.ok) throw new Error("Failed to delete subtask");
|
||||
return res.json();
|
||||
}
|
||||
|
||||
// Progress Notes
|
||||
export async function addProgressNote(taskId: string, note: string): Promise<Task> {
|
||||
const res = await fetch(`${BASE}/${taskId}/notes`, {
|
||||
|
||||
Reference in New Issue
Block a user