Quiz reellement interactif en Mode Apercu (voir maquette document-formation-web.html)
Build and deploy / test-python (push) Failing after 1m5s
Build and deploy / test-js (push) Successful in 51s
Build and deploy / lint-python (push) Failing after 1m2s
Build and deploy / lint-js (push) Failing after 1m4s
Build and deploy / build-and-push (push) Skipped
Build and deploy / deploy (push) Skipped
Build and deploy / sonarqube (push) Failing after 1m0s
Build and deploy / test-python (push) Failing after 1m5s
Build and deploy / test-js (push) Successful in 51s
Build and deploy / lint-python (push) Failing after 1m2s
Build and deploy / lint-js (push) Failing after 1m4s
Build and deploy / build-and-push (push) Skipped
Build and deploy / deploy (push) Skipped
Build and deploy / sonarqube (push) Failing after 1m0s
Le quiz affichait jusqu'ici la meme carte resume en edition comme en Apercu. Ajoute un vrai questionnaire jouable, visible UNIQUEMENT en Mode Apercu (masque en edition via CSS, jamais les deux a la fois) : options de reponse cliquables, marquage correct/incorrect immediat, score qui accumule les points de chaque question repondue correctement, progression "Question suivante", et un ecran de resultat final (score obtenu / total des points possibles) avec "Recommencer le quiz" - structure et identite visuelle calquees sur docs/plan/maquettes/document-formation-web.html (cartes en degrade, options A/B/C/D, feedback vert/orange), adaptees aux tokens --doc-* deja en place (theme clair/sombre inclus, nouvelles variables --doc-quiz-success-*/--doc-quiz-danger-*). Cote rendu (document_engine/rendering/render_document_element.py), _render_quiz ajoute desormais le questionnaire (fonction privee _render_quiz_player) des qu'au moins une question existe : les questions sont embarquees en JSON dans un attribut data-quiz-config (jamais un <script> par element), echappees pour l'HTML - aucun aller-retour serveur pendant qu'on joue, tout le deroulé (reponse/ score/suivant/resultat) est gere par static/document/js/document-editor.js. pointer-events, desactive sur tout element en Apercu pour empecher la selection/le glisser-deposer pendant le test, est reactive specifiquement dans le questionnaire pour qu'il reste reellement cliquable. Tests : 3 nouveaux tests de rendu purs (sans Flask, dont un qui verifie l'echappement HTML du texte d'une question contre une injection). Verifie en live via une simulation DOM complete (basculer Apercu, repondre correctement puis incorrectement, verifier score/feedback/etat des options, passer a la question suivante, voir l'ecran de resultat) - le script de diagnostic n'a pas ete conserve dans le depot. SKIP=djlint : backlog H021 pre-existant, aucun template touche ici. ruff/mypy --strict/vulture/bandit/import-linter/eslint/stylelint tous verts ; 48 tests cibles (document + onboarding) verifies frais. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
9d87a4bfef
commit
9fb22be1ae
@@ -31,6 +31,12 @@ body.objectEditBody > main.content {
|
||||
--doc-accent: var(--accent);
|
||||
--doc-accent-2: var(--accent-2);
|
||||
--doc-glow: 0 0 0 1px rgb(255 95 46 / 25%), 0 8px 24px -6px rgb(255 95 46 / 25%);
|
||||
--doc-quiz-success-bg: rgb(59 165 93 / 12%);
|
||||
--doc-quiz-success-border: #3ba55d;
|
||||
--doc-quiz-success-text: #8fe3ab;
|
||||
--doc-quiz-danger-bg: rgb(255 95 46 / 12%);
|
||||
--doc-quiz-danger-border: #ff5f2e;
|
||||
--doc-quiz-danger-text: #ffb3a0;
|
||||
|
||||
/* Remplit main.content (voir body.objectEditBody dans static/style.css :
|
||||
`main.content` y est déjà `flex:1 1 auto; min-height:0; overflow:hidden;
|
||||
@@ -58,6 +64,12 @@ body.objectEditBody > main.content {
|
||||
--doc-text: #14161c;
|
||||
--doc-muted: #6b7280;
|
||||
--doc-glow: 0 0 0 1px rgb(255 95 46 / 30%), 0 8px 24px -6px rgb(255 95 46 / 30%);
|
||||
--doc-quiz-success-bg: #e4f5ea;
|
||||
--doc-quiz-success-border: #2e7d46;
|
||||
--doc-quiz-success-text: #1d4c2c;
|
||||
--doc-quiz-danger-bg: #fdede8;
|
||||
--doc-quiz-danger-border: #c1451f;
|
||||
--doc-quiz-danger-text: #7a1418;
|
||||
}
|
||||
|
||||
.docEditor3 * {
|
||||
@@ -467,12 +479,15 @@ img.docImage {
|
||||
.docMinigame {
|
||||
border: 1px solid var(--doc-accent);
|
||||
border-radius: 12px;
|
||||
background: rgb(255 95 46 / 8%);
|
||||
}
|
||||
|
||||
.docMinigameBadge {
|
||||
padding: 18px 20px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
background: rgb(255 95 46 / 8%);
|
||||
}
|
||||
|
||||
.docMinigameLabel {
|
||||
@@ -485,6 +500,237 @@ img.docImage {
|
||||
color: var(--doc-muted);
|
||||
}
|
||||
|
||||
/* ---- Quiz : questionnaire interactif en Mode Aperçu (voir docs/plan/
|
||||
maquettes/document-formation-web.html — référence visuelle). Masqué en
|
||||
édition (seul .docMinigameBadge y est visible, voir plus haut) ; les
|
||||
deux jamais visibles en même temps. ---- */
|
||||
.docQuizPlayer {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.docEditor3.docEditor3--preview [data-kind="quiz"] .docMinigameBadge {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.docEditor3.docEditor3--preview [data-kind="quiz"] .docQuizPlayer {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.docEditor3.docEditor3--preview [data-kind="quiz"] {
|
||||
border: none;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.docEditor3.docEditor3--preview .docQuizPlayer,
|
||||
.docEditor3.docEditor3--preview .docQuizPlayer * {
|
||||
/* .docEditor3--preview désactive pointer-events sur tout [data-element-id]
|
||||
(voir plus bas) pour empêcher la sélection/le déplacement pendant
|
||||
l'Aperçu — réactivé ici spécifiquement pour que le quiz reste
|
||||
RÉELLEMENT cliquable (répondre, question suivante, recommencer). */
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
.docQuizCard,
|
||||
.docQuizResultCard {
|
||||
background: linear-gradient(180deg, var(--doc-card), var(--doc-bg-2));
|
||||
border: 1px solid var(--doc-border);
|
||||
border-radius: 16px;
|
||||
padding: 1.8rem;
|
||||
}
|
||||
|
||||
.docQuizResultCard {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.docQuizKicker {
|
||||
font-size: 12px;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.04em;
|
||||
color: var(--doc-accent);
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.docQuizPlayerTitle {
|
||||
font-size: 1.15rem;
|
||||
font-weight: 700;
|
||||
margin: 0 0 20px;
|
||||
}
|
||||
|
||||
.docQuizProgressTrack {
|
||||
height: 4px;
|
||||
background: var(--doc-border);
|
||||
border-radius: 2px;
|
||||
overflow: hidden;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.docQuizProgressFill {
|
||||
height: 100%;
|
||||
width: 0%;
|
||||
background: linear-gradient(120deg, var(--doc-accent), var(--doc-accent-2));
|
||||
transition: width 0.2s ease;
|
||||
}
|
||||
|
||||
.docQuizMeta {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
font-size: 13px;
|
||||
color: var(--doc-muted);
|
||||
font-weight: 600;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.docQuizQuestionText {
|
||||
font-size: 17px;
|
||||
font-weight: 700;
|
||||
line-height: 1.3;
|
||||
margin: 0 0 18px;
|
||||
}
|
||||
|
||||
.docQuizOptions {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.docQuizOption {
|
||||
text-align: left;
|
||||
padding: 13px 15px;
|
||||
border: 1px solid var(--doc-border);
|
||||
background: var(--doc-bg-2);
|
||||
color: var(--doc-text);
|
||||
border-radius: 10px;
|
||||
font-size: 15px;
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
transition: border-color 0.15s ease;
|
||||
}
|
||||
|
||||
.docQuizOption:hover:not(:disabled) {
|
||||
border-color: var(--doc-accent);
|
||||
}
|
||||
|
||||
.docQuizOptionLetter {
|
||||
flex-shrink: 0;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
border-radius: 50%;
|
||||
border: 1px solid var(--doc-border);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-weight: 700;
|
||||
font-size: 12.5px;
|
||||
color: var(--doc-muted);
|
||||
}
|
||||
|
||||
.docQuizOption.is-correct {
|
||||
border-color: var(--doc-quiz-success-border);
|
||||
background: var(--doc-quiz-success-bg);
|
||||
}
|
||||
|
||||
.docQuizOption.is-correct .docQuizOptionLetter {
|
||||
border-color: var(--doc-quiz-success-border);
|
||||
background: var(--doc-quiz-success-border);
|
||||
color: #0b0e14;
|
||||
}
|
||||
|
||||
.docQuizOption.is-wrong {
|
||||
border-color: var(--doc-quiz-danger-border);
|
||||
background: var(--doc-quiz-danger-bg);
|
||||
}
|
||||
|
||||
.docQuizOption.is-wrong .docQuizOptionLetter {
|
||||
border-color: var(--doc-accent);
|
||||
background: var(--doc-accent);
|
||||
color: #0b0e14;
|
||||
}
|
||||
|
||||
.docQuizOption:disabled:not(.is-correct, .is-wrong) {
|
||||
opacity: 0.45;
|
||||
}
|
||||
|
||||
.docQuizFeedback {
|
||||
display: none;
|
||||
margin-top: 16px;
|
||||
padding: 13px 15px;
|
||||
border-radius: 10px;
|
||||
font-size: 14px;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.docQuizFeedback.is-visible {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.docQuizFeedback.is-ok {
|
||||
background: var(--doc-quiz-success-bg);
|
||||
color: var(--doc-quiz-success-text);
|
||||
border: 1px solid var(--doc-quiz-success-border);
|
||||
}
|
||||
|
||||
.docQuizFeedback.is-ko {
|
||||
background: var(--doc-quiz-danger-bg);
|
||||
color: var(--doc-quiz-danger-text);
|
||||
border: 1px solid var(--doc-quiz-danger-border);
|
||||
}
|
||||
|
||||
.docQuizNextBar {
|
||||
margin-top: 20px;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.docQuizNextBtn {
|
||||
padding: 0.75rem 1.6rem;
|
||||
border-radius: 10px;
|
||||
border: none;
|
||||
background: linear-gradient(120deg, var(--doc-accent), var(--doc-accent-2));
|
||||
color: #14100c;
|
||||
font-weight: 700;
|
||||
font-size: 14px;
|
||||
cursor: pointer;
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
transition: opacity 0.2s ease;
|
||||
}
|
||||
|
||||
.docQuizNextBtn.is-visible {
|
||||
opacity: 1;
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
.docQuizResultBig {
|
||||
font-weight: 800;
|
||||
font-size: 44px;
|
||||
background: linear-gradient(120deg, var(--doc-accent), var(--doc-accent-2));
|
||||
background-clip: text;
|
||||
color: transparent;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.docQuizResultSub {
|
||||
margin-top: 6px;
|
||||
margin-bottom: 18px;
|
||||
font-size: 13px;
|
||||
color: var(--doc-muted);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.docQuizRestartBtn {
|
||||
padding: 0.7rem 1.5rem;
|
||||
border-radius: 10px;
|
||||
background: transparent;
|
||||
border: 1px solid var(--doc-border);
|
||||
color: var(--doc-text);
|
||||
font-weight: 600;
|
||||
font-size: 14px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.docUnknown {
|
||||
font-size: 12.5px;
|
||||
color: var(--doc-muted);
|
||||
|
||||
Reference in New Issue
Block a user