53 lines
1.5 KiB
TypeScript
53 lines
1.5 KiB
TypeScript
/**
|
|
* PatternsList — Sprint 3.6c.
|
|
*
|
|
* Liste les erreurs récurrentes détectées, groupées par critère et triées par
|
|
* fréquence DESC (déjà fait côté backend).
|
|
*
|
|
* Règle L : tokens Direction H exclusivement.
|
|
*/
|
|
|
|
import { Card } from '@/shared/ui/Card'
|
|
import { Badge } from '@/shared/ui/Badge'
|
|
import { CRITERE_LABELS } from '@/entities/report/lib'
|
|
import type { Pattern } from '@/entities/patterns/types'
|
|
|
|
interface Props {
|
|
patterns: Pattern[]
|
|
}
|
|
|
|
function humanizeCode(code: string): string {
|
|
return code.replace(/_/g, ' ')
|
|
}
|
|
|
|
export function PatternsList({ patterns }: Props) {
|
|
if (patterns.length === 0) {
|
|
return (
|
|
<Card variant="default" className="p-4">
|
|
<p className="text-sm text-ink-3">
|
|
Aucune erreur récurrente détectée sur vos 5 dernières productions. Continuez ainsi !
|
|
</p>
|
|
</Card>
|
|
)
|
|
}
|
|
|
|
return (
|
|
<ul className="space-y-2">
|
|
{patterns.map((p) => (
|
|
<li key={`${p.critere}-${p.code}-${p.description ?? ''}`}>
|
|
<Card variant="default" className="flex items-start justify-between gap-3 p-4">
|
|
<div className="min-w-0 space-y-1">
|
|
<p className="text-sm font-semibold text-ink-1">
|
|
{p.description ?? humanizeCode(p.code)}
|
|
</p>
|
|
<p className="text-xs text-ink-4">{CRITERE_LABELS[p.critere]}</p>
|
|
</div>
|
|
<Badge variant="nclc" className="shrink-0 tabular-nums">
|
|
{p.frequency}/5
|
|
</Badge>
|
|
</Card>
|
|
</li>
|
|
))}
|
|
</ul>
|
|
)
|
|
}
|