chore: prettier everywhere
This commit is contained in:
@@ -19,8 +19,13 @@ interface ProductivityAnalyticsProps {
|
||||
hiddenSources?: string[];
|
||||
}
|
||||
|
||||
export function ProductivityAnalytics({ metrics, deadlineMetrics, tagMetrics, selectedSources, hiddenSources = [] }: ProductivityAnalyticsProps) {
|
||||
|
||||
export function ProductivityAnalytics({
|
||||
metrics,
|
||||
deadlineMetrics,
|
||||
tagMetrics,
|
||||
selectedSources,
|
||||
hiddenSources = [],
|
||||
}: ProductivityAnalyticsProps) {
|
||||
// Filtrer les métriques selon les sources sélectionnées
|
||||
const filteredMetrics = useMemo(() => {
|
||||
if (selectedSources.length === 0) {
|
||||
@@ -41,31 +46,31 @@ export function ProductivityAnalytics({ metrics, deadlineMetrics, tagMetrics, se
|
||||
|
||||
// Si on a des sources sélectionnées, ne garder que celles-ci
|
||||
if (selectedSources.length > 0) {
|
||||
filteredOverdue = filteredOverdue.filter(task =>
|
||||
filteredOverdue = filteredOverdue.filter((task) =>
|
||||
selectedSources.includes(task.source)
|
||||
);
|
||||
filteredCritical = filteredCritical.filter(task =>
|
||||
filteredCritical = filteredCritical.filter((task) =>
|
||||
selectedSources.includes(task.source)
|
||||
);
|
||||
filteredWarning = filteredWarning.filter(task =>
|
||||
filteredWarning = filteredWarning.filter((task) =>
|
||||
selectedSources.includes(task.source)
|
||||
);
|
||||
filteredUpcoming = filteredUpcoming.filter(task =>
|
||||
filteredUpcoming = filteredUpcoming.filter((task) =>
|
||||
selectedSources.includes(task.source)
|
||||
);
|
||||
} else if (hiddenSources.length > 0) {
|
||||
// Sinon, retirer les sources masquées
|
||||
filteredOverdue = filteredOverdue.filter(task =>
|
||||
!hiddenSources.includes(task.source)
|
||||
filteredOverdue = filteredOverdue.filter(
|
||||
(task) => !hiddenSources.includes(task.source)
|
||||
);
|
||||
filteredCritical = filteredCritical.filter(task =>
|
||||
!hiddenSources.includes(task.source)
|
||||
filteredCritical = filteredCritical.filter(
|
||||
(task) => !hiddenSources.includes(task.source)
|
||||
);
|
||||
filteredWarning = filteredWarning.filter(task =>
|
||||
!hiddenSources.includes(task.source)
|
||||
filteredWarning = filteredWarning.filter(
|
||||
(task) => !hiddenSources.includes(task.source)
|
||||
);
|
||||
filteredUpcoming = filteredUpcoming.filter(task =>
|
||||
!hiddenSources.includes(task.source)
|
||||
filteredUpcoming = filteredUpcoming.filter(
|
||||
(task) => !hiddenSources.includes(task.source)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -79,8 +84,12 @@ export function ProductivityAnalytics({ metrics, deadlineMetrics, tagMetrics, se
|
||||
criticalCount: filteredCritical.length,
|
||||
warningCount: filteredWarning.length,
|
||||
upcomingCount: filteredUpcoming.length,
|
||||
totalWithDeadlines: filteredOverdue.length + filteredCritical.length + filteredWarning.length + filteredUpcoming.length
|
||||
}
|
||||
totalWithDeadlines:
|
||||
filteredOverdue.length +
|
||||
filteredCritical.length +
|
||||
filteredWarning.length +
|
||||
filteredUpcoming.length,
|
||||
},
|
||||
};
|
||||
}, [deadlineMetrics, selectedSources, hiddenSources]);
|
||||
|
||||
@@ -91,7 +100,9 @@ export function ProductivityAnalytics({ metrics, deadlineMetrics, tagMetrics, se
|
||||
|
||||
{/* Titre de section Analytics */}
|
||||
<div className="flex items-center justify-between">
|
||||
<h2 className="text-2xl font-bold"><Emoji emoji="📊" /> Analytics & Métriques</h2>
|
||||
<h2 className="text-2xl font-bold">
|
||||
<Emoji emoji="📊" /> Analytics & Métriques
|
||||
</h2>
|
||||
<div className="text-sm text-[var(--muted-foreground)]">
|
||||
Derniers 30 jours
|
||||
</div>
|
||||
@@ -108,8 +119,10 @@ export function ProductivityAnalytics({ metrics, deadlineMetrics, tagMetrics, se
|
||||
|
||||
{/* Distributions */}
|
||||
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
|
||||
<PriorityDistributionChart data={filteredMetrics.priorityDistribution} />
|
||||
|
||||
<PriorityDistributionChart
|
||||
data={filteredMetrics.priorityDistribution}
|
||||
/>
|
||||
|
||||
{/* Status Flow - Graphique simple en barres horizontales */}
|
||||
<Card variant="glass" className="p-6">
|
||||
<h3 className="text-lg font-semibold mb-4">Répartition par Statut</h3>
|
||||
@@ -120,7 +133,7 @@ export function ProductivityAnalytics({ metrics, deadlineMetrics, tagMetrics, se
|
||||
{item.status}
|
||||
</div>
|
||||
<div className="flex-1 bg-[var(--border)] rounded-full h-2 relative">
|
||||
<div
|
||||
<div
|
||||
className="bg-gradient-to-r from-blue-500 to-cyan-500 h-2 rounded-full transition-all duration-300"
|
||||
style={{ width: `${item.percentage}%` }}
|
||||
></div>
|
||||
@@ -142,31 +155,46 @@ export function ProductivityAnalytics({ metrics, deadlineMetrics, tagMetrics, se
|
||||
|
||||
{/* Insights automatiques */}
|
||||
<Card variant="glass" className="p-6">
|
||||
<h3 className="text-lg font-semibold mb-4"><Emoji emoji="💡" /> Insights</h3>
|
||||
<h3 className="text-lg font-semibold mb-4">
|
||||
<Emoji emoji="💡" /> Insights
|
||||
</h3>
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
|
||||
<MetricCard
|
||||
title="Vélocité Moyenne"
|
||||
value={`${filteredMetrics.velocityData.length > 0
|
||||
? Math.round(filteredMetrics.velocityData.reduce((acc, item) => acc + item.completed, 0) / filteredMetrics.velocityData.length)
|
||||
: 0
|
||||
value={`${
|
||||
filteredMetrics.velocityData.length > 0
|
||||
? Math.round(
|
||||
filteredMetrics.velocityData.reduce(
|
||||
(acc, item) => acc + item.completed,
|
||||
0
|
||||
) / filteredMetrics.velocityData.length
|
||||
)
|
||||
: 0
|
||||
} tâches/sem`}
|
||||
color="primary"
|
||||
/>
|
||||
|
||||
|
||||
<MetricCard
|
||||
title="Priorité Principale"
|
||||
value={filteredMetrics.priorityDistribution.reduce((max, item) =>
|
||||
item.count > max.count ? item : max,
|
||||
filteredMetrics.priorityDistribution[0]
|
||||
)?.priority || 'N/A'}
|
||||
value={
|
||||
filteredMetrics.priorityDistribution.reduce(
|
||||
(max, item) => (item.count > max.count ? item : max),
|
||||
filteredMetrics.priorityDistribution[0]
|
||||
)?.priority || 'N/A'
|
||||
}
|
||||
color="success"
|
||||
/>
|
||||
|
||||
|
||||
<MetricCard
|
||||
title="Taux de Completion"
|
||||
value={`${(() => {
|
||||
const completed = filteredMetrics.statusFlow.find(s => s.status === 'Terminé')?.count || 0;
|
||||
const total = filteredMetrics.statusFlow.reduce((acc, s) => acc + s.count, 0);
|
||||
const completed =
|
||||
filteredMetrics.statusFlow.find((s) => s.status === 'Terminé')
|
||||
?.count || 0;
|
||||
const total = filteredMetrics.statusFlow.reduce(
|
||||
(acc, s) => acc + s.count,
|
||||
0
|
||||
);
|
||||
return total > 0 ? Math.round((completed / total) * 100) : 0;
|
||||
})()}%`}
|
||||
color="warning"
|
||||
|
||||
Reference in New Issue
Block a user