MCPcopy Create free account
hub / github.com/GreatStackDev/project-management / ProjectAnalytics

Function ProjectAnalytics

src/components/ProjectAnalytics.jsx:13–178  ·  view source on GitHub ↗
({ project, tasks })

Source from the content-addressed store, hash-verified

11};
12
13const ProjectAnalytics = ({ project, tasks }) => {
14 const { stats, statusData, typeData, priorityData } = useMemo(() => {
15 const now = new Date();
16 const total = tasks.length;
17
18 const stats = {
19 total,
20 completed: 0,
21 inProgress: 0,
22 todo: 0,
23 overdue: 0,
24 };
25
26 const statusMap = { TODO: 0, IN_PROGRESS: 0, DONE: 0 };
27 const typeMap = { TASK: 0, BUG: 0, FEATURE: 0, IMPROVEMENT: 0, OTHER: 0 };
28 const priorityMap = { LOW: 0, MEDIUM: 0, HIGH: 0 };
29
30 tasks.forEach((t) => {
31 if (t.status === "DONE") stats.completed++;
32 if (t.status === "IN_PROGRESS") stats.inProgress++;
33 if (t.status === "TODO") stats.todo++;
34 if (new Date(t.due_date) < now && t.status !== "DONE") stats.overdue++;
35
36 if (statusMap[t.status] !== undefined) statusMap[t.status]++;
37 if (typeMap[t.type] !== undefined) typeMap[t.type]++;
38 if (priorityMap[t.priority] !== undefined) priorityMap[t.priority]++;
39 });
40
41 return {
42 stats,
43 statusData: Object.entries(statusMap).map(([k, v]) => ({ name: k.replace("_", " "), value: v })),
44 typeData: Object.entries(typeMap).filter(([_, v]) => v > 0).map(([k, v]) => ({ name: k, value: v })),
45 priorityData: Object.entries(priorityMap).map(([k, v]) => ({
46 name: k,
47 value: v,
48 percentage: total > 0 ? Math.round((v / total) * 100) : 0,
49 })),
50 };
51 }, [tasks]);
52
53 const completionRate = stats.total ? Math.round((stats.completed / stats.total) * 100) : 0;
54
55 const metrics = [
56 {
57 label: "Completion Rate",
58 value: `${completionRate}%`,
59 color: "text-emerald-600 dark:text-emerald-400",
60 icon: <CheckCircle className="size-5 text-emerald-600 dark:text-emerald-400" />,
61 bg: "bg-emerald-200 dark:bg-emerald-500/10",
62 },
63 {
64 label: "Active Tasks",
65 value: stats.inProgress,
66 color: "text-blue-600 dark:text-blue-400",
67 icon: <Clock className="size-5 text-blue-600 dark:text-blue-400" />,
68 bg: "bg-blue-200 dark:bg-blue-500/10",
69 },
70 {

Callers

nothing calls this directly

Calls

no outgoing calls

Tested by

no test coverage detected