Onboarding guidé systématique + tableau de bord simplifié
Build and deploy / test-python (push) Failing after 1m48s
Build and deploy / test-js (push) Successful in 53s
Build and deploy / build-and-push (push) Skipped
Build and deploy / deploy (push) Skipped

Comportement SYSTÉMATIQUE à chaque création de jeu (admin compris), pas
une formalité réservée à l'inscription : /onboarding (routes/onboarding/)
devient le point d'entrée unique — 4 cartes retournables (survol =
explication au dos), défilement horizontal animé vers le nom du jeu. Un
admin y repasse à volonté (pas de project_slug dédié, jamais bloqué/
redirigé vers un projet précédent) ; un compte "user" n'en a plus qu'un
créé d'office (routes/auth/register_2fa.py), guidé ici à la place.

- db/games/game_type_catalog.py : catalogue des 4 types (Quiz/
  Embranchement-escape game/RPG/Créer mon jeu de A à Z), _meta['onboarding_type']
  décide du "kind" du premier écran créé et si le tableau de bord complet
  reste accessible.
- routes/games/game_dashboard.py, templates/game_dashboard_simple.html :
  un type restreint (quiz/embranchement/rpg) voit désormais SON tableau
  de bord (même route que "custom"), rendu en version simplifiée — juste
  ses écrans en cartes avec un aperçu RÉEL du contenu (scène mise à
  l'échelle par container query CSS, adaptée à la largeur réelle de la
  carte). "+ Ajouter un écran" n'y propose pas de choix de type : imposé
  par le projet (routes/screens/screens_new.py), verrouillé aussi côté
  serveur.
- core/auth_guard.py : plus de blocage de game_dashboard par type — la
  restriction se fait au rendu, pas à l'accès à la route.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
william
2026-09-02 06:22:45 +02:00
co-authored by Claude Sonnet 5
parent 0f23024882
commit 76a50fa87a
23 changed files with 876 additions and 52 deletions
+65
View File
@@ -0,0 +1,65 @@
// Onboarding guidé (templates/onboarding/onboarding_new.html) — interactions
// pures DOM, aucune logique métier ici (voir routes/onboarding/
// onboarding_new.py pour la validation réelle, côté serveur). Deux
// "pages" (choix du type / nom du jeu) posées côte à côte dans
// #onboardingTrack, révélées par un défilement horizontal animé en CSS
// (voir .onboardingTrack--step2 dans static/style.css) plutôt qu'un vrai
// changement de page — pas de rechargement, pas d'aller-retour serveur
// tant que le formulaire n'est pas soumis pour de vrai.
function forgeOnboardingGoToStep(step) {
var track = document.getElementById("onboardingTrack");
if (track) track.classList.toggle("onboardingTrack--step2", step === 2);
if (step === 2) {
var nameField = document.getElementById("onboardingNameInput");
// Après la fin de l'animation de défilement (voir la durée de
// transition posée sur .onboardingTrack) — focus immédiat plus tôt
// ferait sauter le scroll du champ à moitié visible.
if (nameField) setTimeout(function () { nameField.focus(); }, 500);
}
}
function forgeOnboardingChooseType(card) {
document.querySelectorAll(".onboardingCard").forEach(function (c) {
c.classList.toggle("is-selected", c === card);
});
var hiddenType = document.getElementById("onboardingTypeHidden");
if (hiddenType) hiddenType.value = card.dataset.type || "";
forgeOnboardingUpdateSubmitState();
forgeOnboardingGoToStep(2);
}
function forgeOnboardingUpdateSubmitState() {
var nameField = document.getElementById("onboardingNameInput");
var hiddenType = document.getElementById("onboardingTypeHidden");
var submitBtn = document.getElementById("onboardingSubmitBtn");
if (!nameField || !hiddenType || !submitBtn) return;
submitBtn.disabled = !(hiddenType.value && nameField.value.trim());
}
function forgeOnboardingInit() {
// Appelé directement (pas de DOMContentLoaded) : ce fichier est chargé
// par un <script src> posé à la fin du contenu de la page — les
// éléments dont on a besoin existent déjà à ce stade. Nécessaire aussi
// pour la navigation pjax (voir static/pjax.js — runScriptsIn
// ré-exécute ce script à chaque page swappée, mais DOMContentLoaded,
// lui, ne se redéclenche jamais après le tout premier chargement réel).
// Entrée en cascade des cartes — délai posé en JS plutôt qu'en CSS pur
// (nth-child) pour rester correct quel que soit le nombre de types
// affichés (voir db.ONBOARDING_TYPES, appelé à générer la liste).
document.querySelectorAll(".onboardingCard").forEach(function (card, i) {
card.style.animationDelay = (i * 70) + "ms";
card.addEventListener("click", function () { forgeOnboardingChooseType(card); });
});
var backBtn = document.getElementById("onboardingBackBtn");
if (backBtn) backBtn.addEventListener("click", function () { forgeOnboardingGoToStep(1); });
var nameField = document.getElementById("onboardingNameInput");
if (nameField) nameField.addEventListener("input", forgeOnboardingUpdateSubmitState);
forgeOnboardingUpdateSubmitState();
}
forgeOnboardingInit();