permet aux élèves de rejoindre leur classe avec son code, et les fiches en lot

L'élève saisit le code de classe et son prénom, le prof accepte, l'élève
voit une seule fois son identifiant et son code. Aucun e-mail. Le prof
peut aussi régénérer les fiches de plusieurs élèves d'un coup. Procédure
pour prouver la copie de la clé des sauvegardes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Adam Belkacemi 2026-10-09 22:18:53 +02:00
parent 1ac8d4773a
commit dd4f9c3c55
21 changed files with 573 additions and 26 deletions

View file

@ -3,9 +3,11 @@
namespace App\Http\Controllers;
use App\Models\Classe;
use App\Models\DemandeInscription;
use App\Models\Eleve;
use App\Models\Seance;
use App\Services\GenerateurCompteEleve;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
@ -30,6 +32,7 @@ class ClasseController extends Controller
return view('mes-classes.show', [
'classe' => $classe->load('eleves'),
'demandes' => $classe->demandesInscription()->where('statut', DemandeInscription::EN_ATTENTE)->oldest()->get(),
]);
}
@ -104,25 +107,64 @@ class ClasseController extends Controller
*/
private function creerEleve(Classe $classe, string $prenom, ?string $nom): array
{
$identifiant = $this->generateur->genererIdentifiant($prenom, $nom);
$codeSecret = $this->generateur->genererCodeSecret();
$jetonQr = Str::random(32);
$fiche = $this->generateur->creerDans($classe, $prenom, $nom);
unset($fiche['eleve']);
$classe->eleves()->create([
'prenom' => $prenom,
'nom' => $nom,
'identifiant' => $identifiant,
'code_secret' => Hash::make($codeSecret),
'jeton_qr' => $jetonQr,
]);
return $fiche;
}
return [
'identifiant' => $identifiant,
'prenom' => $prenom,
'nom' => $nom,
'code_secret' => $codeSecret,
'jeton_qr' => $jetonQr,
];
public function accepterDemande(Classe $classe, DemandeInscription $demande): RedirectResponse
{
$this->verifierProprietaire($classe);
abort_if($demande->classe_id !== $classe->id, 404);
if ($demande->statut === DemandeInscription::EN_ATTENTE && ! $classe->estArchivee()) {
$fiche = $this->generateur->creerDans($classe, $demande->prenom, $demande->nom);
$demande->forceFill([
'statut' => DemandeInscription::ACCEPTEE,
'eleve_id' => $fiche['eleve']->id,
'code_secret_chiffre' => $fiche['code_secret'],
])->save();
}
return redirect()->route('mes-classes.show', $classe);
}
public function refuserDemande(Classe $classe, DemandeInscription $demande): RedirectResponse
{
$this->verifierProprietaire($classe);
abort_if($demande->classe_id !== $classe->id, 404);
$demande->forceFill(['statut' => DemandeInscription::REFUSEE])->save();
return redirect()->route('mes-classes.show', $classe);
}
public function nombreDemandes(Classe $classe): JsonResponse
{
$this->verifierProprietaire($classe);
return response()->json(['en_attente' => $classe->demandesInscription()->where('statut', DemandeInscription::EN_ATTENTE)->count()]);
}
/**
* Nouvelles fiches (nouveau code, nouveau QR) pour les élèves cochés :
* la fiche n'est visible qu'une fois, ceci permet de la refaire en lot.
*/
public function nouvellesFiches(Request $request, Classe $classe): RedirectResponse
{
$this->verifierProprietaire($classe);
$ids = $request->validate(['eleves' => ['required', 'array'], 'eleves.*' => ['integer']])['eleves'];
$fiches = [];
foreach ($classe->eleves()->whereIn('id', $ids)->orderBy('prenom')->get() as $eleve) {
$codeSecret = $this->generateur->genererCodeSecret();
$jetonQr = Str::random(32);
$eleve->forceFill(['code_secret' => Hash::make($codeSecret), 'jeton_qr' => $jetonQr])->save();
$fiches[] = ['identifiant' => $eleve->identifiant, 'prenom' => $eleve->prenom, 'nom' => $eleve->nom, 'code_secret' => $codeSecret, 'jeton_qr' => $jetonQr];
}
return redirect()->route('mes-classes.show', $classe)->with('fiches', $fiches);
}
/**