175 lines
14 KiB
PHP
175 lines
14 KiB
PHP
@extends('layouts.vitrine')
|
||
|
||
@section('titre', 'Espace élève')
|
||
|
||
@section('contenu')
|
||
<section class="relative overflow-hidden border-b border-[#e3e5e8] bg-white">
|
||
<div aria-hidden="true" class="pointer-events-none absolute inset-0"></div>
|
||
<div class="relative mx-auto flex max-w-7xl flex-wrap items-end gap-6 px-5 pb-12 pt-12 lg:px-10">
|
||
<div class="flex-1">
|
||
<p class="font-mono text-sm font-semibold">Espace élève · {{ $eleve->identifiant }}</p>
|
||
<div class="min-w-0 flex-1"><p data-public="E" class="mb-2 inline-flex items-center gap-2 rounded-full border border-[#b8c1cf] bg-white px-3 py-1 text-sm font-bold text-[#0b5e3c]">Pour les élèves</p>
|
||
<h1 class="mt-2 text-6xl font-extrabold leading-[1.05] tracking-tight sm:text-7xl">Salut {{ $eleve->prenom }}.</h1></div>
|
||
<p class="mt-4 text-xl font-semibold">{{ $eleve->classe->nom }}@if($eleve->classe->formation) · {{ $eleve->classe->formation }}@endif</p>
|
||
</div>
|
||
<a href="{{ route('labs.essai') }}" class="inline-flex items-center gap-4 border border-[#e3e5e8] rounded-2xl bg-black px-6 py-4 text-lg font-extrabold text-white transition-transform hover:bg-[#ec3013].5.5 active:shadow-none">Reprendre mon TP <span class="font-mono" aria-hidden="true">→</span></a>
|
||
</div>
|
||
</section>
|
||
{{-- Chantier « vrai cockpit », étape 2 : Quiz flash, réel, pas de démo.
|
||
Caché par défaut ; rempli et affiché par le sondage ci-dessous. --}}
|
||
<section id="quiz-flash" hidden class="mx-auto max-w-7xl px-5 pt-10 lg:px-10" aria-labelledby="t-quiz-flash">
|
||
<div class="rounded-2xl border border-[#e3e5e8] bg-[#eef0fd] p-6">
|
||
<h2 id="t-quiz-flash" class="text-2xl font-extrabold">Quiz flash</h2>
|
||
<div data-quiz-contenu class="mt-4"></div>
|
||
</div>
|
||
</section>
|
||
@php($seancesOuvertes = $eleve->classe->seances()->whereIn('statut', [\App\Models\Seance::SALLE_ATTENTE, \App\Models\Seance::EN_COURS])->with('lab')->get())
|
||
@if ($seancesOuvertes->isNotEmpty())
|
||
<section class="mx-auto max-w-7xl px-5 pt-10 lg:px-10" aria-labelledby="t-seance-ouverte">
|
||
<h2 id="t-seance-ouverte" class="text-2xl font-extrabold">Séance en cours</h2>
|
||
<ul class="mt-4 grid gap-3">
|
||
@foreach ($seancesOuvertes as $seance)
|
||
<li class="flex flex-wrap items-center justify-between gap-4 rounded-2xl border border-[#e3e5e8] bg-[#e6f4ea] p-5">
|
||
<span class="text-xl font-extrabold">{{ $seance->lab->titre }}</span>
|
||
<form action="{{ route('seances.rejoindre', $seance) }}" method="post">
|
||
@csrf
|
||
<button type="submit" class="inline-flex h-11 items-center rounded-full bg-black px-5 font-bold text-white">Rejoindre la séance</button>
|
||
</form>
|
||
@if ($seance->visioOuverte())
|
||
<a href="{{ route('seances.visio.eleve', $seance) }}" class="inline-flex h-11 items-center rounded-full bg-[#0b57d0] px-5 font-bold text-white">Rejoindre la visio</a>
|
||
@endif
|
||
</li>
|
||
@endforeach
|
||
</ul>
|
||
</section>
|
||
@endif
|
||
<div class="mx-auto grid max-w-7xl gap-12 px-5 py-14 lg:grid-cols-12 lg:px-10">
|
||
<section class="lg:col-span-7" aria-labelledby="t-afaire">
|
||
<h2 id="t-afaire" class="text-4xl font-extrabold tracking-tight">À faire</h2>
|
||
<ul class="mt-8 grid gap-6">
|
||
<li><a href="{{ route('ide') }}" class="relative flex flex-wrap items-center gap-4 border border-[#e3e5e8] rounded-2xl bg-white p-5"><span class="absolute -right-3 -top-4 border border-[#dadce0] rounded-lg bg-[#ec3013] px-2 py-0.5 text-sm font-extrabold text-white">Devoir maison</span><span class="border border-[#dadce0] rounded-lg bg-[#13233A] px-2 font-mono text-sm font-semibold text-white">IDE</span><span class="flex-1"><span class="block text-xl font-extrabold">Défi Python : somme d’une liste</span><span class="block font-semibold">À rendre mer. 8 oct. · 18:00</span></span><span class="font-mono font-semibold">Rendre →</span></a></li>
|
||
<li><a href="{{ route('labs.essai') }}" class="relative flex flex-wrap items-center gap-4 border border-[#e3e5e8] rounded-2xl bg-[#e6f4ea] p-5 transition-transform">
|
||
<span class="absolute -right-3 -top-4 border border-[#dadce0] rounded-lg bg-white px-2 py-0.5 text-sm font-extrabold">En cours</span>
|
||
<span class="border border-[#dadce0] rounded-lg bg-white px-2 font-mono text-sm font-semibold">TP</span>
|
||
<span class="flex-1"><span class="block text-xl font-extrabold">Routage inter-VLAN</span><span class="block font-semibold">Étape 3 sur 4 · VM prête</span></span>
|
||
<span class="font-mono font-semibold">Continuer →</span></a></li>
|
||
<li><a href="{{ route('cours.show') }}#qcm" class="flex flex-wrap items-center gap-4 border border-[#e3e5e8] rounded-2xl bg-[#fef7e0] p-5 transition-transform md:ml-8">
|
||
<span class="border border-[#dadce0] rounded-lg bg-white px-2 font-mono text-sm font-semibold">QCM</span>
|
||
<span class="flex-1"><span class="block text-xl font-extrabold">Adressage IPv4 · 2ᵉ essai</span><span class="block font-semibold">Pour vendredi · 5 questions</span></span>
|
||
<span class="font-mono font-semibold">Commencer →</span></a></li>
|
||
<li><a href="{{ route('cours.show') }}#td" class="flex flex-wrap items-center gap-4 border border-[#e3e5e8] rounded-2xl bg-[#eef0fd] p-5 transition-transform">
|
||
<span class="border border-[#dadce0] rounded-lg bg-white px-2 font-mono text-sm font-semibold">TD</span>
|
||
<span class="flex-1"><span class="block text-xl font-extrabold">Découpage en sous-réseaux</span><span class="block font-semibold">Assigné par Mme Roux · 3 exercices</span></span>
|
||
<span class="font-mono font-semibold">Ouvrir →</span></a></li>
|
||
<li><a href="{{ route('examen') }}" class="flex flex-wrap items-center gap-4 border border-[#e3e5e8] rounded-2xl bg-black p-5 text-white transition-transform md:ml-8">
|
||
<span class="border-2 border-white bg-[#ec3013] px-2 font-mono text-sm font-semibold">EXAMEN</span>
|
||
<span class="flex-1"><span class="block text-xl font-extrabold">E6 blanc SISR · Adressage et VLAN</span><span class="block font-semibold">Lundi 10:00 · 1 h</span></span>
|
||
<span class="font-mono font-semibold">Voir →</span></a></li>
|
||
</ul>
|
||
</section>
|
||
<aside class="grid content-start gap-10 lg:col-span-5">
|
||
<section class="border border-[#e3e5e8] rounded-2xl bg-white p-6" aria-labelledby="t-prog">
|
||
<h2 id="t-prog" class="text-2xl font-extrabold">Ma progression</h2>
|
||
<ul class="mt-5 grid gap-4">
|
||
<li><p class="flex justify-between font-bold"><span>Adressage IPv4</span><span class="font-mono">100 %</span></p><div class="mt-1 h-4 border border-[#dadce0] rounded-lg bg-white"><div class="h-full bg-[#e6f4ea] border-r border-[#e3e5e8]" style="width:100%"></div></div></li>
|
||
<li><p class="flex justify-between font-bold"><span>VLAN et commutation</span><span class="font-mono">100 %</span></p><div class="mt-1 h-4 border border-[#dadce0] rounded-lg bg-white"><div class="h-full bg-[#e6f4ea] border-r border-[#e3e5e8]" style="width:100%"></div></div></li>
|
||
<li><p class="flex justify-between font-bold"><span>Routage inter-VLAN</span><span class="font-mono">75 %</span></p><div class="mt-1 h-4 border border-[#dadce0] rounded-lg bg-white"><div class="h-full bg-[#fef7e0] border-r border-[#e3e5e8]" style="width:75%"></div></div></li>
|
||
<li><p class="flex justify-between font-bold"><span>Serveur DHCP</span><span class="font-mono">25 %</span></p><div class="mt-1 h-4 border border-[#dadce0] rounded-lg bg-white"><div class="h-full bg-[#fef7e0] border-r border-[#e3e5e8]" style="width:25%"></div></div></li>
|
||
<li><p class="flex justify-between font-bold"><span>Serveur DNS avec BIND 9</span><span class="font-mono">0 %</span></p><div class="mt-1 h-4 border border-[#dadce0] rounded-lg bg-white"><div class="h-full bg-white border-r border-[#e3e5e8]" style="width:0%"></div></div></li>
|
||
</ul>
|
||
</section>
|
||
<section class="border border-[#e3e5e8] rounded-2xl bg-[#fce8e6] p-6" aria-labelledby="t-notes">
|
||
<h2 id="t-notes" class="text-2xl font-extrabold">Mes QCM</h2>
|
||
<ul class="mt-4 divide-y divide-[#e3e5e8] border border-[#dadce0] rounded-lg bg-white font-semibold">
|
||
<li class="flex justify-between px-4 py-2"><span>VLAN et commutation</span><span class="font-mono">17/20</span></li>
|
||
<li class="flex justify-between px-4 py-2"><span>Adressage IPv4</span><span class="font-mono">14/20</span></li>
|
||
<li class="flex justify-between px-4 py-2"><span>Modèle OSI</span><span class="font-mono">18/20</span></li>
|
||
</ul>
|
||
<a href="{{ route('cours.index') }}" class="mt-5 inline-block border border-[#e3e5e8] rounded-2xl bg-white px-4 py-2 font-extrabold hover:bg-[#fef7e0]">Réviser dans les cours</a>
|
||
<a href="{{ route('maison') }}" class="mt-3 block font-extrabold underline underline-offset-4">Aller plus loin à la maison →</a>
|
||
</section>
|
||
</aside>
|
||
</div>
|
||
<script nonce="{{ Vite::cspNonce() }}">
|
||
(function () {
|
||
var URL_ETAT = @json(route('quiz.eleve.etat'));
|
||
var CSRF = @json(csrf_token());
|
||
var section = document.getElementById('quiz-flash');
|
||
var contenu = section.querySelector('[data-quiz-contenu]');
|
||
var questionAffichee = null, repondu = false;
|
||
|
||
function echapper(s) {
|
||
return s.replace(/[&<>"]/g, function (c) { return { '&': '&', '<': '<', '>': '>', '"': '"' }[c]; });
|
||
}
|
||
|
||
function rendreQuestion(q) {
|
||
var champs = q.type === 'vrai_faux'
|
||
? '<label class="flex items-center gap-2 font-semibold"><input type="radio" name="reponse" value="vrai"> Vrai</label>' +
|
||
'<label class="flex items-center gap-2 font-semibold"><input type="radio" name="reponse" value="faux"> Faux</label>'
|
||
: q.choix.map(function (c) {
|
||
return '<label class="flex items-center gap-2 font-semibold"><input type="radio" name="reponse" value="' + c.id + '"> ' + echapper(c.texte) + '</label>';
|
||
}).join('');
|
||
|
||
contenu.innerHTML =
|
||
'<p class="text-xl font-extrabold">' + echapper(q.enonce) + '</p>' +
|
||
'<form data-form-reponse class="mt-4 grid gap-2">' + champs +
|
||
'<button type="submit" class="mt-2 inline-flex h-11 w-fit items-center rounded-full bg-black px-5 font-bold text-white">Valider ma réponse</button></form>' +
|
||
'<p data-resultat class="mt-3 hidden font-extrabold"></p>';
|
||
|
||
contenu.querySelector('[data-form-reponse]').addEventListener('submit', function (e) {
|
||
e.preventDefault();
|
||
var choisi = contenu.querySelector('input[name="reponse"]:checked');
|
||
if (!choisi) return;
|
||
var corps = q.type === 'vrai_faux'
|
||
? { reponse_vrai_faux: choisi.value === 'vrai' }
|
||
: { choix_id: parseInt(choisi.value, 10) };
|
||
|
||
fetch('/sessions-quiz/' + sessionActuelle + '/repondre', {
|
||
method: 'POST',
|
||
headers: { 'X-CSRF-TOKEN': CSRF, 'Content-Type': 'application/json', 'Accept': 'application/json' },
|
||
body: JSON.stringify(corps),
|
||
}).then(function (r) { return r.json(); }).then(function (d) {
|
||
repondu = true;
|
||
var form = contenu.querySelector('[data-form-reponse]');
|
||
form.hidden = true;
|
||
var p = contenu.querySelector('[data-resultat]');
|
||
p.hidden = false;
|
||
p.textContent = d.correcte ? 'Bonne réponse !' : 'Réponse envoyée.';
|
||
p.className = 'mt-3 font-extrabold ' + (d.correcte ? 'text-[#3C8A5A]' : '');
|
||
}).catch(function () {});
|
||
});
|
||
}
|
||
|
||
var sessionActuelle = null;
|
||
|
||
function sonder() {
|
||
fetch(URL_ETAT, { headers: { Accept: 'application/json' } })
|
||
.then(function (r) { return r.json(); })
|
||
.then(function (d) {
|
||
var s = d.session;
|
||
if (!s) { section.hidden = true; questionAffichee = null; sessionActuelle = null; return; }
|
||
sessionActuelle = s.id;
|
||
section.hidden = false;
|
||
|
||
if (s.statut === 'en_attente' || !s.question) {
|
||
questionAffichee = null;
|
||
contenu.innerHTML = '<p class="font-semibold">Un quiz va commencer. Garde cette page ouverte.</p>';
|
||
return;
|
||
}
|
||
if (s.deja_repondu) {
|
||
questionAffichee = s.question.id;
|
||
contenu.innerHTML = '<p class="font-extrabold">' + echapper(s.question.enonce) + '</p><p class="mt-3 font-extrabold">Réponse envoyée. En attente de la suite…</p>';
|
||
return;
|
||
}
|
||
if (s.question.id !== questionAffichee) {
|
||
questionAffichee = s.question.id;
|
||
repondu = false;
|
||
rendreQuestion(s.question);
|
||
}
|
||
}).catch(function () {});
|
||
}
|
||
sonder();
|
||
setInterval(sonder, 2000);
|
||
})();
|
||
</script>
|
||
@endsection
|