feat(simulations): exposer sujet dans useSimulation + composant SujetDisplay
This commit is contained in:
parent
e130d3792e
commit
b356bc7109
2 changed files with 68 additions and 0 deletions
67
src/features/simulations/components/SujetDisplay.tsx
Normal file
67
src/features/simulations/components/SujetDisplay.tsx
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
/**
|
||||
* Affichage du sujet d'examen (consigne + documents) au-dessus de la zone de saisie.
|
||||
*
|
||||
* Prop `sujet` vient du hook `useSimulation` (alimenté par `POST /simulations`).
|
||||
* Si `sujet === null` (aucun sujet actif pour la tâche, ou EO_T2_LIVE) → rien n'est rendu.
|
||||
*
|
||||
* Règle H : composant purement présentationnel, aucune logique métier.
|
||||
* Règle L : tokens Direction H exclusivement (canvas, surface, ink-*, line, expria).
|
||||
*
|
||||
* Rendu plain-text avec `whitespace-pre-wrap` pour préserver les sauts de ligne.
|
||||
* Les sujets étant du contenu admin-curé (pas du texte IA), pas de react-markdown.
|
||||
*/
|
||||
|
||||
import { Badge } from '@/shared/ui/Badge'
|
||||
import { Card } from '@/shared/ui/Card'
|
||||
import type { SujetData } from '@/entities/production/types'
|
||||
|
||||
interface Props {
|
||||
sujet: SujetData | null
|
||||
}
|
||||
|
||||
function DocumentBlock({ titre, texte }: { titre: string | null; texte: string | null }) {
|
||||
if (!titre && !texte) return null
|
||||
return (
|
||||
<article className="rounded-md border border-line bg-canvas-2 p-3">
|
||||
{titre && <h4 className="mb-2 text-sm font-semibold text-ink-1">{titre}</h4>}
|
||||
{texte && (
|
||||
<p className="whitespace-pre-wrap text-sm leading-relaxed text-ink-2">{texte}</p>
|
||||
)}
|
||||
</article>
|
||||
)
|
||||
}
|
||||
|
||||
export function SujetDisplay({ sujet }: Props) {
|
||||
if (!sujet) return null
|
||||
|
||||
return (
|
||||
<Card variant="default" className="p-5">
|
||||
<div className="space-y-4">
|
||||
{sujet.role && (
|
||||
<div className="flex items-center gap-2">
|
||||
<Badge variant="neutral">Rôle</Badge>
|
||||
<span className="text-sm text-ink-2">{sujet.role}</span>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{sujet.contexte && (
|
||||
<p className="whitespace-pre-wrap text-sm leading-relaxed text-ink-3">
|
||||
{sujet.contexte}
|
||||
</p>
|
||||
)}
|
||||
|
||||
<div>
|
||||
<h3 className="mb-1 text-xs font-semibold uppercase tracking-wide text-ink-4">
|
||||
Consigne
|
||||
</h3>
|
||||
<p className="whitespace-pre-wrap text-base leading-relaxed text-ink-1">
|
||||
{sujet.consigne}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<DocumentBlock titre={sujet.doc1_titre} texte={sujet.doc1_texte} />
|
||||
<DocumentBlock titre={sujet.doc2_titre} texte={sujet.doc2_texte} />
|
||||
</div>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
|
|
@ -62,6 +62,7 @@ export function useSimulation() {
|
|||
return {
|
||||
step,
|
||||
production,
|
||||
sujet: production?.sujet ?? null,
|
||||
report: (correctMutation.data ?? null) as Report | null,
|
||||
isCreating: createMutation.isPending,
|
||||
isCorrecting: correctMutation.isPending,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue