{[
- { label: 'Total Tasks', num: total, border: '#6366f1' },
- { label: 'Completed', num: completed, border: '#22c55e' },
- { label: 'Overdue', num: overdue, border: '#ef4444' },
- { label: 'Critical Open', num: critical, border: '#f97316' },
+ { label: 'Total Tasks', num: total, border: '#6366f1', icon: '📋' },
+ { label: 'Completed', num: completed, border: '#22c55e', icon: '✅' },
+ { label: 'In Progress', num: inProgress, border: '#818cf8', icon: '⏳' },
+ { label: 'In Review', num: inReview, border: '#f59e0b', icon: '👀' },
+ { label: 'Overdue', num: overdue, border: '#ef4444', icon: '🔴' },
+ { label: 'Critical', num: critical, border: '#f97316', icon: '🔥' },
+ { label: 'Subtask %', num: `${avgSubtaskCompletion}%`, border: '#a78bfa', icon: '📊' },
+ { label: 'Comments', num: totalComments, border: '#ec4899', icon: '💬' },
].map(s => (
))}
+ {/* 1 · Tasks per Member */}
Tasks per Member
-
-
-
-
+
+
+
+
-
+
-
+
+ {/* 2 · Priority Distribution */}
Priority Distribution
-
+
{/* eslint-disable-next-line @typescript-eslint/no-explicit-any */}
- `${entry.name} ${((entry.percent ?? 0) * 100).toFixed(0)}%`) as any}>
- {prioData.map(d => | )}
+ `${entry.name} ${((entry.percent ?? 0) * 100).toFixed(0)}%`) as any}
+ labelLine={{ stroke: '#334155' }}>
+ {prioData.map(d => | )}
- {total}
+
+ {/* 3 · Completion Trend (Area) */}
-
Completions This Week
-
-
-
-
-
-
-
+ Completion Trend vs target
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {/* 4 · Overdue by Member */}
-
Overdue by Member
-
-
-
-
+ Overdue by Member ⚠ needs attention
+
+
+
+
-
+
+ {overdueData.length === 0 && 🎉 No overdue tasks!
}
+
+
+ {/* 5 · Member Performance Radar */}
+
+
Member Performance
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {/* 6 · Tag Distribution */}
+
+
Top Tags
+ {tagData.length > 0 ? (
+
+
+
+
+
+
+ {tagData.map((_d, i) => | )}
+
+
+
+ ) :
No tags assigned yet
}
+
+ {/* INSIGHTS SECTION (CTO/Manager only) */}
+ {isCTO && (
+
+
💡 Key Insights
+
+ {(() => {
+ const insights: { icon: string; text: string; type: 'warning' | 'success' | 'info' }[] = [];
+ // Completion rate
+ const compRate = total ? Math.round((completed / total) * 100) : 0;
+ if (compRate >= 70) insights.push({ icon: '🎯', text: `Great completion rate: ${compRate}% of tasks are done.`, type: 'success' });
+ else if (compRate < 40) insights.push({ icon: '⚠️', text: `Low completion rate: only ${compRate}% of tasks are done.`, type: 'warning' });
+ else insights.push({ icon: '📈', text: `Completion rate is ${compRate}% — keep pushing!`, type: 'info' });
+
+ // Overdue
+ if (overdue > 0) insights.push({ icon: '🔴', text: `${overdue} task${overdue > 1 ? 's are' : ' is'} overdue and needs attention.`, type: 'warning' });
+ else insights.push({ icon: '✅', text: 'No overdue tasks — the team is on track!', type: 'success' });
+
+ // Busiest member
+ const busiest = USERS.map(u => ({ name: u.name, count: tasks.filter(t => t.assignee === u.id && t.status !== 'done').length }))
+ .sort((a, b) => b.count - a.count)[0];
+ if (busiest && busiest.count > 3) insights.push({ icon: '🏋️', text: `${busiest.name} has the heaviest load with ${busiest.count} active tasks.`, type: 'warning' });
+
+ // Critical items
+ if (critical > 0) insights.push({ icon: '🔥', text: `${critical} critical task${critical > 1 ? 's' : ''} still open — prioritize these.`, type: 'warning' });
+
+ // Comments activity
+ if (totalComments > 5) insights.push({ icon: '💬', text: `Good collaboration: ${totalComments} comments across all tasks.`, type: 'success' });
+ else insights.push({ icon: '🤫', text: `Only ${totalComments} comments total — encourage more team communication.`, type: 'info' });
+
+ return insights.map((ins, i) => (
+
+ {ins.icon}
+ {ins.text}
+
+ ));
+ })()}
+
+