import { Task, fetchAllTasks } from "./tasks"; import { fetchGanttSnapshot } from "@/lib/data/gantt-snapshot"; export interface Project { id: string; name: string; description?: string; color: string; createdAt: string; } export interface Sprint { id: string; name: string; status: "planning" | "active" | "completed" | "cancelled"; startDate: string; endDate: string; goal?: string; } export interface ProjectStats { project: Project; totalTasks: number; completedTasks: number; inProgressTasks: number; urgentTasks: number; highPriorityTasks: number; progress: number; recentTasks: Task[]; } export async function fetchAllProjects(): Promise { const snapshot = await fetchGanttSnapshot(); return snapshot.projects; } export async function countProjects(): Promise { const projects = await fetchAllProjects(); return projects.length; } export async function fetchAllSprints(): Promise { const snapshot = await fetchGanttSnapshot(); return snapshot.sprints; } export async function fetchActiveSprint(): Promise { const sprints = await fetchAllSprints(); const active = sprints.find((sprint) => sprint.status === "active"); return active || null; } export async function countSprintsByStatus(): Promise<{ planning: number; active: number; completed: number; total: number }> { const sprints = await fetchAllSprints(); const counts = { planning: 0, active: 0, completed: 0, total: sprints.length }; for (const sprint of sprints) { if (sprint.status === "planning") counts.planning++; else if (sprint.status === "active") counts.active++; else if (sprint.status === "completed") counts.completed++; } return counts; } export function calculateProjectStats(project: Project, tasks: Task[]): ProjectStats { const projectTasks = tasks.filter((task) => task.projectId === project.id); const completedTasks = projectTasks.filter((task) => task.status === "done"); const inProgressTasks = projectTasks.filter((task) => task.status === "in-progress"); const urgentTasks = projectTasks.filter((task) => task.priority === "urgent" && task.status !== "done"); const highPriorityTasks = projectTasks.filter((task) => task.priority === "high" && task.status !== "done"); const totalTasks = projectTasks.length; const progress = totalTasks > 0 ? Math.round((completedTasks.length / totalTasks) * 100) : 0; const recentTasks = [...projectTasks] .sort((a, b) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime()) .slice(0, 5); return { project, totalTasks, completedTasks: completedTasks.length, inProgressTasks: inProgressTasks.length, urgentTasks: urgentTasks.length, highPriorityTasks: highPriorityTasks.length, progress, recentTasks, }; } export async function fetchProjectsWithStats(): Promise { const [projects, tasks] = await Promise.all([fetchAllProjects(), fetchAllTasks()]); return projects.map((project) => calculateProjectStats(project, tasks)); } export function getProjectHealth(stats: ProjectStats): { status: "healthy" | "warning" | "critical"; label: string; color: string; } { const { progress, urgentTasks, highPriorityTasks, totalTasks } = stats; if (urgentTasks > 0 || (totalTasks > 5 && progress === 0)) { return { status: "critical", label: "Needs Attention", color: "text-red-500" }; } if (highPriorityTasks > 2 || (totalTasks > 10 && progress < 30)) { return { status: "warning", label: "At Risk", color: "text-yellow-500" }; } return { status: "healthy", label: "On Track", color: "text-green-500" }; } export function getSprintDaysRemaining(sprint: Sprint): number { const endDate = new Date(sprint.endDate); const today = new Date(); const diffTime = endDate.getTime() - today.getTime(); return Math.ceil(diffTime / (1000 * 60 * 60 * 24)); } export function formatSprintDateRange(sprint: Sprint): string { const start = new Date(sprint.startDate); const end = new Date(sprint.endDate); return `${start.toLocaleDateString("en-US", { month: "short", day: "numeric" })} - ${end.toLocaleDateString("en-US", { month: "short", day: "numeric", })}`; }