expria-frontend/src/features/simulations/components/rapport/CritereCard.tsx
Hermann_Kitio 99617f117c style: prettier format
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 03:17:16 +03:00

80 lines
2.7 KiB
TypeScript

/**
* CritereCard — Sprint 3.6b.
*
* Carte critère enrichie : nom, score /5, commentaire, exemple, suggestion,
* astuce + badges des codes d'erreurs taxonomie correspondants.
*
* Visible pour Standard et Premium (gate `detailed_report`). Le floutage est
* géré par le parent via BlurredSection — CritereCard ne connaît pas le plan.
*
* Règle L : tokens Direction H exclusivement.
* Règle H : purement présentationnel — aucune logique plan ici.
*/
import ReactMarkdown from 'react-markdown'
import { Card } from '@/shared/ui/Card'
import { Badge } from '@/shared/ui/Badge'
import type { Critere, ErreurCode } from '@/entities/report/types'
interface Props {
critere: Critere
erreursCodes: ErreurCode[]
}
export function CritereCard({ critere, erreursCodes }: Props) {
return (
<Card variant="default" className="space-y-3 p-4">
<div className="flex items-start justify-between gap-3">
<h3 className="text-sm font-semibold text-ink-1">{critere.nom}</h3>
<Badge variant="nclc" className="shrink-0 tabular-nums">
{critere.score}/5
</Badge>
</div>
{critere.commentaire && (
<div className="text-sm leading-relaxed text-ink-2">
<ReactMarkdown disallowedElements={['script', 'iframe']}>
{critere.commentaire}
</ReactMarkdown>
</div>
)}
{critere.exemple && (
<div className="space-y-1.5 rounded-md border border-line bg-canvas-2 p-3">
<p className="text-[11px] font-semibold uppercase tracking-widest text-ink-5">
Exemple tiré de votre texte
</p>
<p className="italic text-sm leading-relaxed text-ink-2">« {critere.exemple} »</p>
</div>
)}
{critere.suggestion && (
<div className="space-y-1.5 rounded-md border border-expria/30 bg-expria-50 p-3">
<p className="text-[11px] font-semibold uppercase tracking-widest text-expria">
Reformulation suggérée
</p>
<p className="text-sm leading-relaxed text-ink-1">{critere.suggestion}</p>
</div>
)}
{critere.astuce && (
<div className="flex gap-2 text-sm text-ink-3">
<span className="shrink-0 text-expria" aria-hidden="true">
💡
</span>
<span>{critere.astuce}</span>
</div>
)}
{erreursCodes.length > 0 && (
<div className="flex flex-wrap gap-1.5 border-t border-line pt-3">
{erreursCodes.map((e) => (
<Badge key={`${e.code}-${e.description ?? ''}`} variant="neutral">
{e.description ?? e.code.replace(/_/g, ' ')}
</Badge>
))}
</div>
)}
</Card>
)
}