style: prettier format
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
79bbbdc4e8
commit
99617f117c
45 changed files with 229 additions and 302 deletions
|
|
@ -79,7 +79,10 @@ export function IdeesSuggestions({ idees, isLoading, error, isOpen, onClose }: P
|
|||
<ul className="space-y-2 text-sm text-ink-2">
|
||||
{idees.map((idee, i) => (
|
||||
<li key={i} className="flex gap-2">
|
||||
<span className="mt-[0.4em] size-1.5 shrink-0 rounded-full bg-expria" aria-hidden="true" />
|
||||
<span
|
||||
className="mt-[0.4em] size-1.5 shrink-0 rounded-full bg-expria"
|
||||
aria-hidden="true"
|
||||
/>
|
||||
<span>{idee}</span>
|
||||
</li>
|
||||
))}
|
||||
|
|
|
|||
|
|
@ -61,9 +61,7 @@ export function NclcCibleSelector({ value, onChange, disabled = false }: Props)
|
|||
)
|
||||
})}
|
||||
</div>
|
||||
<p className="text-xs text-ink-4">
|
||||
{OPTIONS.find((o) => o.value === value)?.hint}
|
||||
</p>
|
||||
<p className="text-xs text-ink-4">{OPTIONS.find((o) => o.value === value)?.hint}</p>
|
||||
</fieldset>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -117,11 +117,7 @@ export function SimulationForm({
|
|||
|
||||
const tipsAllowed = hasAccess(plan, 'tips')
|
||||
const ideesDisabled =
|
||||
isSubmitting ||
|
||||
idees.isLoading ||
|
||||
!sujet ||
|
||||
!tipsAllowed ||
|
||||
wordCount < MIN_WORDS_IDEES
|
||||
isSubmitting || idees.isLoading || !sujet || !tipsAllowed || wordCount < MIN_WORDS_IDEES
|
||||
const ideesTitle = !tipsAllowed
|
||||
? 'Disponible en Standard'
|
||||
: wordCount < MIN_WORDS_IDEES
|
||||
|
|
@ -311,11 +307,7 @@ export function SimulationForm({
|
|||
className="w-full resize-none overflow-y-hidden rounded-md border border-line bg-surface p-3 text-sm text-ink-1 placeholder:text-ink-5 focus:border-expria focus:outline-none focus:shadow-focus disabled:cursor-not-allowed disabled:opacity-50"
|
||||
/>
|
||||
<WordCountBar count={wordCount} config={config} />
|
||||
<NclcCibleSelector
|
||||
value={nclcCible}
|
||||
onChange={setNclcCible}
|
||||
disabled={isSubmitting}
|
||||
/>
|
||||
<NclcCibleSelector value={nclcCible} onChange={setNclcCible} disabled={isSubmitting} />
|
||||
|
||||
{autosave.savedAt && !fieldError && (
|
||||
<p className="text-xs text-ink-4" aria-live="polite">
|
||||
|
|
|
|||
|
|
@ -13,8 +13,36 @@
|
|||
*/
|
||||
|
||||
const SPECIAL_CHARS = [
|
||||
'à', 'â', 'é', 'è', 'ê', 'ë', 'î', 'ï', 'ô', 'ù', 'û', 'ü', 'ç', 'œ', 'æ',
|
||||
'À', 'Â', 'É', 'È', 'Ê', 'Ë', 'Î', 'Ï', 'Ô', 'Ù', 'Û', 'Ü', 'Ç', 'Œ', 'Æ',
|
||||
'à',
|
||||
'â',
|
||||
'é',
|
||||
'è',
|
||||
'ê',
|
||||
'ë',
|
||||
'î',
|
||||
'ï',
|
||||
'ô',
|
||||
'ù',
|
||||
'û',
|
||||
'ü',
|
||||
'ç',
|
||||
'œ',
|
||||
'æ',
|
||||
'À',
|
||||
'Â',
|
||||
'É',
|
||||
'È',
|
||||
'Ê',
|
||||
'Ë',
|
||||
'Î',
|
||||
'Ï',
|
||||
'Ô',
|
||||
'Ù',
|
||||
'Û',
|
||||
'Ü',
|
||||
'Ç',
|
||||
'Œ',
|
||||
'Æ',
|
||||
] as const
|
||||
|
||||
interface Props {
|
||||
|
|
|
|||
|
|
@ -24,9 +24,7 @@ function DocumentBlock({ titre, texte }: { titre: string | null; texte: string |
|
|||
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>
|
||||
)}
|
||||
{texte && <p className="whitespace-pre-wrap text-sm leading-relaxed text-ink-2">{texte}</p>}
|
||||
</article>
|
||||
)
|
||||
}
|
||||
|
|
@ -45,9 +43,7 @@ export function SujetDisplay({ sujet }: Props) {
|
|||
)}
|
||||
|
||||
{sujet.contexte && (
|
||||
<p className="whitespace-pre-wrap text-sm leading-relaxed text-ink-3">
|
||||
{sujet.contexte}
|
||||
</p>
|
||||
<p className="whitespace-pre-wrap text-sm leading-relaxed text-ink-3">{sujet.contexte}</p>
|
||||
)}
|
||||
|
||||
<div>
|
||||
|
|
|
|||
|
|
@ -44,7 +44,13 @@ const EE_CARDS: readonly TaskCard[] = [
|
|||
const EO_CARDS: readonly TaskCard[] = [
|
||||
{ key: 'EO_T1', tache: 'EO_T1', label: 'Expression Orale', sublabel: 'Entretien' },
|
||||
{ key: 'EO_T3', tache: 'EO_T3', label: 'Expression Orale', sublabel: 'Point de vue' },
|
||||
{ key: 'EO_T2_LIVE', tache: null, label: 'Expression Orale', sublabel: 'Tâche 2 — Live', lockLabel: 'Exclusivité Premium' },
|
||||
{
|
||||
key: 'EO_T2_LIVE',
|
||||
tache: null,
|
||||
label: 'Expression Orale',
|
||||
sublabel: 'Tâche 2 — Live',
|
||||
lockLabel: 'Exclusivité Premium',
|
||||
},
|
||||
]
|
||||
|
||||
export function TaskSelector({ type, plan, simulationsUsed, isLoading, onSelect }: Props) {
|
||||
|
|
@ -56,9 +62,7 @@ export function TaskSelector({ type, plan, simulationsUsed, isLoading, onSelect
|
|||
<div className="space-y-4">
|
||||
<div>
|
||||
<h2 className="text-lg font-semibold text-ink-1">Choisir une tâche</h2>
|
||||
<p className="mt-1 text-sm text-ink-3">
|
||||
Sélectionnez la tâche que vous souhaitez simuler.
|
||||
</p>
|
||||
<p className="mt-1 text-sm text-ink-3">Sélectionnez la tâche que vous souhaitez simuler.</p>
|
||||
</div>
|
||||
|
||||
{quotaBlocked && (
|
||||
|
|
@ -81,11 +85,7 @@ export function TaskSelector({ type, plan, simulationsUsed, isLoading, onSelect
|
|||
|
||||
if (locked) {
|
||||
return (
|
||||
<Card
|
||||
key={card.key}
|
||||
variant="default"
|
||||
className="flex flex-col p-4 opacity-60"
|
||||
>
|
||||
<Card key={card.key} variant="default" className="flex flex-col p-4 opacity-60">
|
||||
{card.tache === null && (
|
||||
<Lock className="mb-2 size-4 text-ink-4" aria-hidden="true" />
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -21,13 +21,9 @@ export function ConseilNclcCallout({ conseil }: Props) {
|
|||
<h2 className="mb-3 text-base font-semibold text-ink-1">Plan d'action NCLC</h2>
|
||||
<Card variant="raised" className="space-y-3 p-4">
|
||||
<div className="flex flex-wrap items-baseline gap-x-4 gap-y-1">
|
||||
<p className="text-[11px] font-semibold uppercase tracking-widest text-ink-5">
|
||||
Objectif
|
||||
</p>
|
||||
<p className="text-[11px] font-semibold uppercase tracking-widest text-ink-5">Objectif</p>
|
||||
<p className="text-sm font-semibold text-ink-1">{conseil.nclc_cible}</p>
|
||||
<p className="text-[11px] font-semibold uppercase tracking-widest text-ink-5">
|
||||
Écart
|
||||
</p>
|
||||
<p className="text-[11px] font-semibold uppercase tracking-widest text-ink-5">Écart</p>
|
||||
<p className="text-sm text-ink-2">{conseil.ecart}</p>
|
||||
</div>
|
||||
<div className="space-y-1.5 rounded-md border border-expria/30 bg-expria-50 p-3">
|
||||
|
|
|
|||
|
|
@ -44,9 +44,7 @@ export function CritereCard({ critere, erreursCodes }: Props) {
|
|||
<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>
|
||||
<p className="italic text-sm leading-relaxed text-ink-2">« {critere.exemple} »</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
|
|
@ -61,7 +59,9 @@ export function CritereCard({ critere, erreursCodes }: Props) {
|
|||
|
||||
{critere.astuce && (
|
||||
<div className="flex gap-2 text-sm text-ink-3">
|
||||
<span className="shrink-0 text-expria" aria-hidden="true">💡</span>
|
||||
<span className="shrink-0 text-expria" aria-hidden="true">
|
||||
💡
|
||||
</span>
|
||||
<span>{critere.astuce}</span>
|
||||
</div>
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -17,14 +17,10 @@ interface Props {
|
|||
export function DiagnosticCallout({ diagnostic }: Props) {
|
||||
return (
|
||||
<section aria-label="Frein principal">
|
||||
<h2 className="mb-3 text-base font-semibold text-ink-1">
|
||||
Ce qui freine votre progression
|
||||
</h2>
|
||||
<h2 className="mb-3 text-base font-semibold text-ink-1">Ce qui freine votre progression</h2>
|
||||
<Card variant="default" className="border-l-4 border-l-expria p-4">
|
||||
<div className="text-sm leading-relaxed text-ink-1">
|
||||
<ReactMarkdown disallowedElements={['script', 'iframe']}>
|
||||
{diagnostic}
|
||||
</ReactMarkdown>
|
||||
<ReactMarkdown disallowedElements={['script', 'iframe']}>{diagnostic}</ReactMarkdown>
|
||||
</div>
|
||||
</Card>
|
||||
</section>
|
||||
|
|
|
|||
|
|
@ -52,9 +52,7 @@ export function ExerciceInteractive({ exercice }: Props) {
|
|||
|
||||
{exercice.consigne && (
|
||||
<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">
|
||||
Consigne
|
||||
</p>
|
||||
<p className="text-[11px] font-semibold uppercase tracking-widest text-ink-5">Consigne</p>
|
||||
<p className="text-sm leading-relaxed text-ink-1">{exercice.consigne}</p>
|
||||
</div>
|
||||
)}
|
||||
|
|
@ -95,7 +93,7 @@ export function ExerciceInteractive({ exercice }: Props) {
|
|||
size="sm"
|
||||
disabled={!canRevealCorrection || correctionRevealed}
|
||||
onClick={() => setCorrectionRevealed(true)}
|
||||
title={!canRevealCorrection ? 'Écrivez d\'abord votre tentative' : undefined}
|
||||
title={!canRevealCorrection ? "Écrivez d'abord votre tentative" : undefined}
|
||||
>
|
||||
Voir la correction
|
||||
</Button>
|
||||
|
|
@ -106,9 +104,7 @@ export function ExerciceInteractive({ exercice }: Props) {
|
|||
className="space-y-1 rounded-md border border-warning/30 bg-warning-bg p-3"
|
||||
aria-live="polite"
|
||||
>
|
||||
<p className="text-[11px] font-semibold uppercase tracking-widest text-warning">
|
||||
Indice
|
||||
</p>
|
||||
<p className="text-[11px] font-semibold uppercase tracking-widest text-warning">Indice</p>
|
||||
<p className="text-sm leading-relaxed text-ink-1">{exercice.indice}</p>
|
||||
</div>
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -30,9 +30,7 @@ export function ProductionModeleSection({ modele }: Props) {
|
|||
<p className="text-[11px] font-semibold uppercase tracking-widest text-ink-5">
|
||||
Version restructurée NCLC 9+
|
||||
</p>
|
||||
<Badge variant="nclc">
|
||||
{modele.tcf_word_count ?? ''} mots
|
||||
</Badge>
|
||||
<Badge variant="nclc">{modele.tcf_word_count ?? ''} mots</Badge>
|
||||
</div>
|
||||
<p className="whitespace-pre-wrap text-sm leading-relaxed text-ink-1">
|
||||
{modele.production_modele_propre}
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ interface Props {
|
|||
|
||||
const SECTIONS: { key: keyof Revelation; titre: string; ton: 'ink' | 'warning' | 'danger' }[] = [
|
||||
{ key: 'croyance', titre: 'Ce que vous croyez', ton: 'ink' },
|
||||
{ key: 'realite', titre: 'Ce qu\'observe le correcteur', ton: 'warning' },
|
||||
{ key: 'realite', titre: "Ce qu'observe le correcteur", ton: 'warning' },
|
||||
{ key: 'consequence', titre: 'Conséquence sur la note', ton: 'danger' },
|
||||
]
|
||||
|
||||
|
|
@ -35,7 +35,9 @@ export function RevelationCards({ revelation }: Props) {
|
|||
<div className="grid gap-3 sm:grid-cols-3">
|
||||
{SECTIONS.map(({ key, titre, ton }) => (
|
||||
<Card key={key} variant="default" className="p-4">
|
||||
<p className={`mb-2 text-[11px] font-semibold uppercase tracking-widest ${TON_CLASS[ton]}`}>
|
||||
<p
|
||||
className={`mb-2 text-[11px] font-semibold uppercase tracking-widest ${TON_CLASS[ton]}`}
|
||||
>
|
||||
{titre}
|
||||
</p>
|
||||
<div className="text-sm leading-relaxed text-ink-2">
|
||||
|
|
|
|||
|
|
@ -13,8 +13,8 @@ import { ecartVsCible } from '@/entities/report/lib'
|
|||
import type { NclcCible } from '@/entities/report/types'
|
||||
|
||||
interface Props {
|
||||
score: number // /20
|
||||
nclc: number // NCLC atteint
|
||||
score: number // /20
|
||||
nclc: number // NCLC atteint
|
||||
nclcCible: NclcCible
|
||||
}
|
||||
|
||||
|
|
@ -30,9 +30,7 @@ export function ScoreHero({ score, nclc, nclcCible }: Props) {
|
|||
<Card variant="raised" className="space-y-4 p-6">
|
||||
<div className="flex flex-wrap items-end gap-8">
|
||||
<div>
|
||||
<p className="text-[11px] font-semibold uppercase tracking-widest text-ink-5">
|
||||
Score
|
||||
</p>
|
||||
<p className="text-[11px] font-semibold uppercase tracking-widest text-ink-5">Score</p>
|
||||
<p className="mt-1 tabular-nums text-ink-1">
|
||||
<span className="text-5xl font-bold">{score}</span>
|
||||
<span className="text-2xl font-medium text-ink-4">/20</span>
|
||||
|
|
@ -47,9 +45,7 @@ export function ScoreHero({ score, nclc, nclcCible }: Props) {
|
|||
</Badge>
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-[11px] font-semibold uppercase tracking-widest text-ink-5">
|
||||
Objectif
|
||||
</p>
|
||||
<p className="text-[11px] font-semibold uppercase tracking-widest text-ink-5">Objectif</p>
|
||||
<Badge variant="neutral" className="mt-2">
|
||||
NCLC {nclcCible}
|
||||
</Badge>
|
||||
|
|
@ -67,9 +63,7 @@ export function ScoreHero({ score, nclc, nclcCible }: Props) {
|
|||
aria-label={`Score ${score} sur 20`}
|
||||
>
|
||||
<div
|
||||
className={`h-full transition-all duration-300 ${
|
||||
atteint ? 'bg-success' : 'bg-expria'
|
||||
}`}
|
||||
className={`h-full transition-all duration-300 ${atteint ? 'bg-success' : 'bg-expria'}`}
|
||||
style={{ width: `${percent}%` }}
|
||||
/>
|
||||
{/* Marqueur du seuil NCLC cible */}
|
||||
|
|
@ -82,7 +76,9 @@ export function ScoreHero({ score, nclc, nclcCible }: Props) {
|
|||
</div>
|
||||
<div className="flex justify-between text-xs text-ink-4 tabular-nums">
|
||||
<span>0</span>
|
||||
<span className="font-medium">Seuil NCLC {nclcCible} : {seuilCible}/20</span>
|
||||
<span className="font-medium">
|
||||
Seuil NCLC {nclcCible} : {seuilCible}/20
|
||||
</span>
|
||||
<span>20</span>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -94,9 +90,7 @@ export function ScoreHero({ score, nclc, nclcCible }: Props) {
|
|||
</p>
|
||||
) : (
|
||||
<p className="rounded-md border border-warning/30 bg-warning-bg px-3 py-2 text-sm text-warning">
|
||||
{points === 1
|
||||
? '1 point avant NCLC '
|
||||
: `${points} points avant NCLC `}
|
||||
{points === 1 ? '1 point avant NCLC ' : `${points} points avant NCLC `}
|
||||
{nclcCible}+
|
||||
</p>
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ const EXERCICE: Exercice = {
|
|||
extrait: 'les enfants joue',
|
||||
indice: 'Pluriel du sujet ?',
|
||||
correction: 'les enfants jouent',
|
||||
explication: 'Le verbe s\'accorde en nombre avec le sujet.',
|
||||
explication: "Le verbe s'accorde en nombre avec le sujet.",
|
||||
}
|
||||
|
||||
describe('ExerciceInteractive', () => {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue