fix(simulations): TaskSelector EE — retirer cartes EO
This commit is contained in:
parent
a6f95c2093
commit
43f3ce2c6c
1 changed files with 9 additions and 21 deletions
|
|
@ -1,16 +1,14 @@
|
|||
/**
|
||||
* Sélecteur de tâche pour lancer une simulation.
|
||||
* Sélecteur de tâche pour lancer une simulation Expression Écrite.
|
||||
*
|
||||
* Affiche les 6 tâches TCF :
|
||||
* - EE T1/T2/T3 → sélectionnables si quota OK
|
||||
* - EO T1/T3 → verrouillées (audio — Sprint 4)
|
||||
* - EO T2 Live → verrouillée (Exclusivité Premium — Sprint 6)
|
||||
* Affiche les 3 tâches EE : T1, T2, T3 (sélectionnables si quota OK).
|
||||
* Les tâches Expression Orale seront sur /simulation/eo (Sprint EO).
|
||||
*
|
||||
* Règle D : le quota est vérifié via canSimulate(), jamais if (plan === 'free').
|
||||
* Règle H : aucune logique métier — uniquement appel de canSimulate() et affichage.
|
||||
*/
|
||||
|
||||
import { Lock, Loader2 } from 'lucide-react'
|
||||
import { Loader2 } from 'lucide-react'
|
||||
import { canSimulate } from '@/entities/user/lib'
|
||||
import { cn } from '@/shared/lib/utils'
|
||||
import { Card } from '@/shared/ui/Card'
|
||||
|
|
@ -26,20 +24,15 @@ interface Props {
|
|||
}
|
||||
|
||||
interface TaskCard {
|
||||
tache: Tache | null // null = EO T2 Live (hors Tache type)
|
||||
tache: Tache
|
||||
label: string
|
||||
sublabel: string
|
||||
sprintLocked?: boolean // audio ou premium non encore implémenté
|
||||
lockLabel?: string
|
||||
}
|
||||
|
||||
const TASK_CARDS: readonly TaskCard[] = [
|
||||
{ tache: 'EE_T1', label: 'Expression Écrite', sublabel: 'Tâche 1' },
|
||||
{ tache: 'EE_T2', label: 'Expression Écrite', sublabel: 'Tâche 2' },
|
||||
{ tache: 'EE_T3', label: 'Expression Écrite', sublabel: 'Tâche 3' },
|
||||
{ tache: 'EO_T1', label: 'Expression Orale', sublabel: 'Tâche 1', sprintLocked: true, lockLabel: 'Bientôt disponible' },
|
||||
{ tache: 'EO_T3', label: 'Expression Orale', sublabel: 'Tâche 3', sprintLocked: true, lockLabel: 'Bientôt disponible' },
|
||||
{ tache: null, label: 'Expression Orale', sublabel: 'Tâche 2 — Live', sprintLocked: true, lockLabel: 'Exclusivité Premium' },
|
||||
]
|
||||
|
||||
export function TaskSelector({ plan, simulationsUsed, isLoading, onSelect }: Props) {
|
||||
|
|
@ -70,24 +63,19 @@ export function TaskSelector({ plan, simulationsUsed, isLoading, onSelect }: Pro
|
|||
|
||||
<div className="grid grid-cols-2 gap-3 sm:grid-cols-3">
|
||||
{TASK_CARDS.map((card) => {
|
||||
const locked = card.sprintLocked || quotaBlocked
|
||||
const abbrev = (card.tache?.split('_')[0]) ?? 'EO'
|
||||
const abbrev = card.tache.split('_')[0]
|
||||
|
||||
if (locked || card.tache === null) {
|
||||
if (quotaBlocked) {
|
||||
return (
|
||||
<Card
|
||||
key={card.tache ?? 'eo-t2'}
|
||||
key={card.tache}
|
||||
variant="default"
|
||||
className="flex flex-col p-4 opacity-60"
|
||||
>
|
||||
<Lock className="mb-2 size-4 text-ink-4" aria-hidden="true" />
|
||||
<span className="text-[11px] font-semibold uppercase tracking-widest text-ink-5">
|
||||
{card.label}
|
||||
</span>
|
||||
<span className="mt-1 text-sm font-semibold text-ink-1">{card.sublabel}</span>
|
||||
{card.lockLabel && (
|
||||
<span className="mt-1.5 text-xs text-ink-4">{card.lockLabel}</span>
|
||||
)}
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
|
|
@ -98,7 +86,7 @@ export function TaskSelector({ plan, simulationsUsed, isLoading, onSelect }: Pro
|
|||
variant="interactive"
|
||||
className={cn('relative flex flex-col p-4', isLoading && 'cursor-wait')}
|
||||
onClick={() => {
|
||||
if (!isLoading) onSelect({ tache: card.tache as Tache, mode: 'entrainement' })
|
||||
if (!isLoading) onSelect({ tache: card.tache, mode: 'entrainement' })
|
||||
}}
|
||||
>
|
||||
<div className="mb-2 flex items-center justify-between">
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue