Paillasse/portail/resources/views/labs/essai.blade.php
Adam Belkacemi e4a6aaebb1 ajoute les pages légales, la purge RGPD et sert polices et scripts depuis le portail
Pages /legal et /confidentialite réécrites d'après le système réel, purge
des classes archivées depuis 90 jours (prouvée par Pest), archivage côté
prof. Polices, xterm.js et CodeMirror ne sont plus chargés depuis Google
ni jsDelivr. Pages d'aperçu signalées, sans vrais établissements ni faux
chiffres. Journaux Laravel gardés 14 jours.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 21:07:25 +02:00

84 lines
6.7 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

@extends('layouts.vitrine')
@section('titre', 'Lab d’essai · Premiers pas dans le shell')
@push('head')
<link rel="stylesheet" href="{{ asset('vendor/xterm/xterm.css') }}">
<script defer src="{{ asset('vendor/xterm/xterm.js') }}"></script>
<script defer src="{{ asset('vendor/xterm/addon-fit.js') }}"></script>
<script defer src="{{ asset('js/paillasse-terminal.js') }}"></script>
@endpush
@section('contenu')
@include('partials.apercu')
<section class="border-b border-[#e3e5e8] bg-[#fef7e0]">
<div class="mx-auto flex max-w-7xl flex-wrap items-center gap-4 px-5 py-4 lg:px-10">
<a href="{{ route('labs.index') }}" class="border border-[#dadce0] rounded-lg bg-white px-3 py-1 font-extrabold hover:bg-[#0b57d0] hover:text-white">← Labs</a>
<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="flex-1 text-2xl font-extrabold tracking-tight">Premiers pas dans le shell</h1></div>
<span class="border border-[#dadce0] rounded-lg bg-white px-3 py-1 font-mono text-sm font-semibold">Lab d’essai</span>
</div>
</section>
<section class="mx-auto grid max-w-7xl gap-8 px-5 py-10 lg:grid-cols-12 lg:px-10" aria-label="Espace de lab">
<article class="border border-[#e3e5e8] rounded-2xl bg-white p-6 lg:col-span-3" aria-labelledby="t-consignes">
<h2 id="t-consignes" class="text-2xl font-extrabold">Consignes</h2>
<ol id="consignes" class="mt-5 space-y-2 font-medium">
<li class="flex gap-3 p-2"><span class="font-mono font-semibold">1</span><span>Affiche le dossier courant avec <code class="bg-[#fef7e0] px-1 font-mono">pwd</code>.</span></li>
<li class="flex gap-3 p-2"><span class="font-mono font-semibold">2</span><span>Liste son contenu avec <code class="bg-[#fef7e0] px-1 font-mono">ls -la</code>.</span></li>
<li class="flex gap-3 p-2"><span class="font-mono font-semibold">3</span><span>Crée un dossier <code class="bg-[#fef7e0] px-1 font-mono">projets</code> et entre dedans.</span></li>
<li class="flex gap-3 p-2"><span class="font-mono font-semibold">4</span><span>Crée un fichier <code class="bg-[#fef7e0] px-1 font-mono">notes.txt</code>.</span></li>
<li class="flex gap-3 p-2"><span class="font-mono font-semibold">5</span><span>Écris ton prénom dedans avec <code class="bg-[#fef7e0] px-1 font-mono">echo</code>.</span></li>
</ol>
</article>
<div class="border border-[#e3e5e8] rounded-2xl bg-[#13233A] font-mono text-white lg:col-span-6">
<div class="flex items-center gap-2 border-b border-[#e3e5e8] bg-[#0d192b] px-4 py-2">
<span class="h-3 w-3 bg-[#ec3013]"></span><span class="h-3 w-3 bg-[#fef7e0]"></span><span class="h-3 w-3 bg-[#e6f4ea]"></span>
<span class="ml-2 text-sm">debian-lab · console 1 · xterm.js</span>
</div>
<div id="xterm-lab" class="h-[440px] bg-[#13233A] p-3"></div>
</div>
<aside class="flex flex-col gap-6 lg:col-span-3" aria-label="Vérification">
<div class="border border-[#e3e5e8] rounded-2xl bg-[#e6f4ea] p-5">
<h2 class="text-xl font-extrabold">Vérification</h2>
<p id="etape-texte" class="mt-2 font-extrabold" aria-live="polite">Tape ta première commande</p>
<div id="etape-barre" class="mt-3 grid grid-cols-5 gap-1"><span class="h-3 border border-[#dadce0] rounded-lg bg-white"></span><span class="h-3 border border-[#dadce0] rounded-lg bg-white"></span><span class="h-3 border border-[#dadce0] rounded-lg bg-white"></span><span class="h-3 border border-[#dadce0] rounded-lg bg-white"></span><span class="h-3 border border-[#dadce0] rounded-lg bg-white"></span></div>
<p class="mt-4 text-sm font-semibold">Chaque étape se valide dès que la commande est juste.</p>
</div>
<details class="border border-[#e3e5e8] rounded-2xl bg-white p-5">
<summary class="cursor-pointer text-xl font-extrabold">Indice</summary>
<p class="mt-3 font-medium">La commande <code class="bg-[#fef7e0] px-1 font-mono">touch</code> crée un fichier vide.</p>
</details>
<button type="button" onclick="const on=this.getAttribute('aria-pressed')!=='true';this.setAttribute('aria-pressed',on);this.querySelector('span').textContent=on?'Main levée · le prof est prévenu':'Lever la main';" aria-pressed="false" class="border border-[#e3e5e8] rounded-2xl bg-[#fce8e6] px-5 py-4 text-left text-lg font-extrabold transition-transform active:shadow-none aria-pressed:bg-[#fef7e0]"><span>Lever la main</span></button>
</aside>
</section>
<script>
document.addEventListener('DOMContentLoaded', function () {
var etapes = document.querySelectorAll('#consignes > li');
var barre = document.querySelectorAll('#etape-barre > span');
var texte = document.getElementById('etape-texte');
var fait = [false, false, false, false, false], vus = { pwd: false, ls: false };
function maj(sh) {
var h = sh.home, p = h + '/projets', n = p + '/notes.txt';
fait[0] = vus.pwd;
fait[1] = fait[0] && vus.ls;
fait[2] = fait[1] && sh.dirs.has(p) && sh.cwd === p;
fait[3] = fait[2] && sh.files.has(n);
fait[4] = fait[3] && (sh.files.get(n) || '').trim().length > 0;
var k = fait.indexOf(false); if (k === -1) k = 5;
etapes.forEach(function (li, i) {
li.className = 'flex gap-3 p-2 ' + (i < k ? 'line-through decoration-2' : i === k ? 'border border-[#dadce0] rounded-lg bg-[#e6f4ea]' : '');
});
barre.forEach(function (b, i) { b.className = 'h-3 border border-[#dadce0] rounded-lg ' + (i < k ? 'bg-black' : 'bg-white'); });
texte.textContent = k === 5 ? 'Lab terminé : 5 / 5 ✓' : k === 0 ? 'Tape ta première commande' : 'Étape ' + k + ' / 5 validée';
}
SyllabusTerminal.mount(document.getElementById('xterm-lab'), {
user: 'eleve', host: 'debian-lab', focus: true,
welcome: '\x1b[2mDebian GNU/Linux 13 · VM prête en 3,2 s\x1b[0m\nTape \x1b[93mhelp\x1b[0m pour voir les commandes.\n',
onCommand: function (line, sh) {
line.split(/&&|;/).forEach(function (c) { c = c.trim().split(/\s+/)[0]; if (c === 'pwd') vus.pwd = true; if (c === 'ls' && vus.pwd) vus.ls = true; });
maj(sh);
}
});
});
</script>
@endsection