Un gabarit Heat généré depuis chaque lab.yaml, une stack par session de lab (création à l'admission, suppression à l'expiration via des jobs Redis et un worker systemd dédié). Passage du compte de service à une authentification par mot de passe : Heat refuse de créer un trust à partir d'un jeton d'application credential (voir ADR 0002). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
63 lines
3.8 KiB
PHP
63 lines
3.8 KiB
PHP
@extends('layouts.vitrine')
|
|
|
|
@section('titre', "Salle d'attente")
|
|
|
|
@section('contenu')
|
|
@if ($labSession->etat === \App\Models\LabSession::EN_ATTENTE)
|
|
<meta http-equiv="refresh" content="5">
|
|
@endif
|
|
<div class="mx-auto max-w-5xl px-5 py-14 lg:px-10">
|
|
<p class="font-mono text-sm font-semibold">{{ $seance->lab->titre }}</p>
|
|
@if ($labSession->etat === \App\Models\LabSession::EN_ATTENTE)
|
|
<div class="py-20 text-center">
|
|
<h1 class="text-4xl font-extrabold tracking-tight">En attente que le prof t'admette…</h1>
|
|
<p class="mt-4 font-semibold">Cette page se rafraîchit toute seule.</p>
|
|
</div>
|
|
@elseif ($labSession->etat === \App\Models\LabSession::ADMIS)
|
|
<meta http-equiv="refresh" content="4">
|
|
<div class="py-20 text-center">
|
|
<h1 class="text-4xl font-extrabold tracking-tight">Préparation de tes VM…</h1>
|
|
<p class="mt-4 font-semibold">Ça prend généralement moins d'une minute.</p>
|
|
</div>
|
|
@elseif ($labSession->machines->isNotEmpty())
|
|
<h1 class="mt-2 text-3xl font-extrabold tracking-tight">Tes machines</h1>
|
|
<div class="mt-4 flex gap-2" role="tablist">
|
|
@foreach ($labSession->machines as $i => $machine)
|
|
<button type="button" data-onglet="{{ $machine->id }}" class="onglet-machine rounded-lg border border-[#dadce0] px-4 py-2 font-mono font-bold {{ $i === 0 ? 'bg-[#0b57d0] text-white' : 'bg-white' }}">{{ $machine->nom }}</button>
|
|
@endforeach
|
|
</div>
|
|
@foreach ($labSession->machines as $i => $machine)
|
|
<div data-panneau="{{ $machine->id }}" @if ($i !== 0) hidden @endif class="mt-2 h-[480px] overflow-hidden rounded-2xl border border-[#e3e5e8]" style="background:#13233A">
|
|
<div id="terminal-{{ $machine->id }}" class="h-full"></div>
|
|
</div>
|
|
@endforeach
|
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@xterm/xterm@5.5.0/css/xterm.css">
|
|
<script src="https://cdn.jsdelivr.net/npm/@xterm/xterm@5.5.0/lib/xterm.min.js"></script>
|
|
<script src="https://cdn.jsdelivr.net/npm/@xterm/addon-fit@0.10.0/lib/addon-fit.min.js"></script>
|
|
<script src="{{ asset('js/console-reelle.js') }}"></script>
|
|
<script>
|
|
var monte = {};
|
|
document.querySelectorAll('.onglet-machine').forEach(function (bouton) {
|
|
bouton.addEventListener('click', function () {
|
|
var id = bouton.dataset.onglet;
|
|
document.querySelectorAll('.onglet-machine').forEach(function (b) { b.classList.toggle('bg-[#0b57d0]', b === bouton); b.classList.toggle('text-white', b === bouton); b.classList.toggle('bg-white', b !== bouton); });
|
|
document.querySelectorAll('[data-panneau]').forEach(function (p) { p.hidden = p.dataset.panneau !== id; });
|
|
});
|
|
});
|
|
@foreach ($labSession->machines as $machine)
|
|
fetch('{{ route('console.eleve', [$labSession, $machine]) }}', {
|
|
method: 'POST',
|
|
headers: { 'X-CSRF-TOKEN': '{{ csrf_token() }}' },
|
|
}).then(function (r) { return r.json(); }).then(function (d) {
|
|
window.SyllabusConsoleReelle.mount(document.getElementById('terminal-{{ $machine->id }}'), { jeton: d.jeton, lectureSeule: false });
|
|
});
|
|
@endforeach
|
|
</script>
|
|
@else
|
|
<div class="py-20 text-center">
|
|
<h1 class="text-4xl font-extrabold tracking-tight">La préparation a échoué</h1>
|
|
<p class="mt-4 font-semibold">Préviens ton prof.</p>
|
|
</div>
|
|
@endif
|
|
</div>
|
|
@endsection
|