@extends('layouts.vitrine') @section('titre', $classe->nom) {{-- Tableau de bord prof (chantier « vrai cockpit », étape 1 — 2026-10-12) : même mise en page que la démonstration /cockpit (sélecteur de classe, cartes d'indicateurs, tableau des élèves), mais chaque chiffre vient d'une vraie table ou d'un vrai cache. Rien n'est inventé (CLAUDE.md) : les cartes des fonctions pas encore construites (quiz, DM, observations, examen) n'existent pas ici tant qu'elles n'existent pas vraiment — elles arriveront une par une. --}} @section('contenu') @php $etats = \App\Models\LabSession::class; @endphp

Tableau de bord

{{ $classe->nom }}

@if ($classe->formation)

{{ $classe->formation }}

@endif

Code de classe : {{ $classe->code_classe }}

@if (session('classe_creee'))

Classe créée. Ajoute maintenant tes élèves ci-dessous.

@endif {{-- Indicateurs réels : rien ici qui ne vienne d'une vraie table ou d'un vrai cache. --}} @if ($seance && $avancement->isNotEmpty()) {{-- Équivalent réel de la « répartition par étape » de la démo : une barre par vérification du lab, comptée sur les vraies dernières corrections (pas de fausse étape numérotée). --}}

Avancement du lab « {{ $seance->lab->titre }} »

{{ $avancement->count() }} vérifications · {{ $avancement->first()['total'] }} élève(s) corrigé(s)

    @foreach ($avancement as $v)
  • {{ $v['titre'] }} {{ $v['reussi'] }}/{{ $v['total'] }}
  • @endforeach
@endif @if ($seance && $seance->visioOuverte()) {{-- Équivalent réel du panneau « Mains levées » de la démo : la même file que la page de visio, avec la même action (donner la parole), juste accessible sans quitter le tableau de bord. --}}

Mains levées

ordre d'arrivée
@if (empty($mains))

Aucune main levée pour l'instant.

@else
    @foreach ($mains as $i => $main)
  1. {{ $i + 1 }} {{ $main['nom'] }} @php($attente = max(0, time() - $main['depuis'])) · depuis {{ intdiv($attente, 60) }} min {{ str_pad((string) ($attente % 60), 2, '0', STR_PAD_LEFT) }} s
    @csrf
  2. @endforeach
@endif
@endif @if ($seance) {{-- Vraies données de la séance en cours : un élève, son état, sa dernière vérification. --}}

{{ $seance->lab->titre }} — {{ $seance->statut === \App\Models\Seance::EN_COURS ? 'en cours' : 'salle d\'attente' }}

Salle d'attente {{ $seance->visioOuverte() ? 'Rejoindre la visio' : 'Lancer la visio' }}
@if ($seance->labSessions->isEmpty())

Personne n'a encore rejoint.

@else
@foreach ($seance->labSessions as $labSession) @endforeach
ÉlèveÉtatDernière vérification
{{ $labSession->eleve->nomAffiche() }} @switch($labSession->etat) @case($etats::EN_ATTENTE)
@csrf
@break @case($etats::ADMIS) Préparation des VM… @break @case($etats::ACTIF) Admis @break @case($etats::ECHEC) Échec (3 essais) @break @default Terminé @endswitch
@if ($labSession->derniereCorrection) {{ $labSession->derniereCorrection->reussi ? 'Réussi' : 'En cours' }} · {{ $labSession->derniereCorrection->note }}/{{ $labSession->derniereCorrection->note_max }} @else — @endif @if ($labSession->etat === $etats::ACTIF) Voir sa console @endif
@endif
@endif @unless ($classe->estArchivee())

Faire rejoindre tes élèves

Projette ce code ou ce QR. Chaque élève va sur {{ preg_replace('#^https?://#', '', route('rejoindre')) }}, tape le code et son prénom ; tu acceptes sa demande ici, et il reçoit à l'écran son identifiant et son code secret. Aucun e-mail.

{{ $classe->code_classe }}

Demandes en attente ({{ $demandes->count() }})

@if ($demandes->isEmpty())

Aucune pour l'instant. Cette liste se met à jour toute seule.

@else
    @foreach ($demandes as $demande)
  • {{ $demande->prenom }}@if ($demande->nom) {{ $demande->nom }}@endif · {{ $demande->created_at->diffForHumans() }}
    @csrf
    @csrf
  • @endforeach
@endif
{!! \App\Support\QrCode::svg(route('rejoindre', ['code' => $classe->code_classe])) !!}
@endunless @if (session('fiches'))

Fiches à imprimer @if (session('nombre_importes')) ({{ session('nombre_importes') }} élève(s) importé(s)) @endif

Le code secret ne sera plus jamais affiché après cette page : imprime ou note-le maintenant.

@foreach (session('fiches') as $fiche)
{!! \App\Support\QrCode::svg(route('connexion.qr', $fiche['jeton_qr'])) !!}

{{ $fiche['prenom'] }}@if($fiche['nom']) {{ $fiche['nom'] }}@endif

Identifiant
{{ $fiche['identifiant'] }}

Code secret
{{ $fiche['code_secret'] }}

@endforeach
@endif

Ajouter un élève

@error('prenom')

{{ $message }}

@enderror
@csrf

Importer une liste (CSV)

Une ligne par élève : prenom,nom (le nom peut être vide).

@error('fichier')

{{ $message }}

@enderror
@csrf

Élèves ({{ $classe->eleves->count() }})

@if ($classe->eleves->isNotEmpty())
@csrf
@endif
@error('eleves')

Coche au moins un élève.

@enderror @if ($classe->eleves->isEmpty())

Aucun élève pour l'instant.

@else
@foreach ($classe->eleves as $eleve) @endforeach
ÉlèveIdentifiantDernière connexion
{{ $eleve->nomAffiche() }} {{ $eleve->identifiant }} {{ $eleve->derniere_connexion_a?->diffForHumans() ?? 'jamais' }}
@csrf
@endif
@if ($classe->estArchivee())

Classe archivée

Archivée le {{ $classe->archivee_a->timezone(config('app.fuseau_utilisateurs'))->format('d/m/Y') }}. La classe et toutes les données de ses élèves (comptes, séances, résultats) seront supprimées définitivement le {{ $classe->supprimeeLe()->timezone(config('app.fuseau_utilisateurs'))->format('d/m/Y') }}.

@csrf
@else

Lancer ou planifier une séance

Les élèves qui rejoignent patientent dans la salle d'attente jusqu'à ce que tu les admettes. Si tu planifies la séance, les machines de toute la classe sont préparées 10 minutes avant : elles s'ouvrent alors en quelques secondes.

@if (session('seance_planifiee'))

Séance planifiée.

@endif
@csrf
@error('prevue_a')

{{ $message }}

@enderror @php($planifiees = $classe->seances()->where('statut', \App\Models\Seance::PLANIFIEE)->with('lab')->orderBy('prevue_a')->get()) @if ($planifiees->isNotEmpty())

Séances planifiées

    @foreach ($planifiees as $planifiee)
  • {{ $planifiee->prevue_a->timezone(config('app.fuseau_utilisateurs'))->translatedFormat('d/m/Y H:i') }} · {{ $planifiee->lab->titre }}
    @csrf
  • @endforeach
@endif

Fin d'année

Archiver la classe ferme ses séances. {{ \App\Models\Classe::DELAI_PURGE_JOURS }} jours plus tard, la classe et toutes les données de ses élèves sont supprimées automatiquement (RGPD). Tu peux la désarchiver d'ici là.

@error('archivage')

{{ $message }}

@enderror
@csrf
@endif
@endsection