feat: task time estimates and velocity chart on dashboard
- Added estimatedHours column to tasks schema - Backend: create/update support for estimatedHours - New /api/tasks/stats/velocity endpoint: daily completions, weekly velocity, estimate totals - Dashboard: velocity chart with 7-day bar chart, this week count, avg/week, estimate summary - TaskDetailPanel: estimated hours input field - CreateTaskModal: estimated hours in advanced options - TaskCard, KanbanBoard, TaskPage: estimate badge display
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import type { Task, Project, ProjectWithTasks } from "./types";
|
||||
import type { Task, Project, ProjectWithTasks, VelocityStats } from "./types";
|
||||
|
||||
const BASE = "/api/tasks";
|
||||
|
||||
@@ -38,7 +38,7 @@ export async function reorderTasks(ids: string[], token?: string): Promise<void>
|
||||
}
|
||||
|
||||
export async function createTask(
|
||||
task: { title: string; description?: string; source?: string; priority?: string; status?: string; projectId?: string; dueDate?: string },
|
||||
task: { title: string; description?: string; source?: string; priority?: string; status?: string; projectId?: string; dueDate?: string; estimatedHours?: number },
|
||||
token?: string
|
||||
): Promise<Task> {
|
||||
const headers: Record<string, string> = { "Content-Type": "application/json" };
|
||||
@@ -64,6 +64,14 @@ export async function deleteTask(id: string, token?: string): Promise<void> {
|
||||
if (!res.ok) throw new Error("Failed to delete task");
|
||||
}
|
||||
|
||||
// ─── Velocity Stats ───
|
||||
|
||||
export async function fetchVelocityStats(): Promise<VelocityStats> {
|
||||
const res = await fetch(`${BASE}/stats/velocity`, { credentials: "include" });
|
||||
if (!res.ok) throw new Error("Failed to fetch velocity stats");
|
||||
return res.json();
|
||||
}
|
||||
|
||||
// ─── Projects API ───
|
||||
|
||||
const PROJECTS_BASE = "/api/projects";
|
||||
|
||||
Reference in New Issue
Block a user