Reprend le fonctionnement du TP Nuisibles (« Corriger » à partir du PDF généré avec les réponses du groupe) pour les deux exercices. - BioCID et FDS : carte « Identification du groupe » (groupe, date, formateur) sur l'écran d'intro, reprise dans l'en-tête du PDF exporté. - FDS : ajout d'un export PDF (inexistant) récapitulant réponse du groupe et réponse attendue, partie par partie, avec le score global. - Bouton « Corriger un rendu » sur l'écran final des deux exercices. - Nouvelle page correction-biocid.html : lecture du PDF, réponses regroupées par exercice avec badge renseigné / sans réponse. - Nouvelle page correction-fds.html : notation automatique du QCM (anneau de réussite, score par partie, ✓/✗/? par question).
889 lines
34 KiB
HTML
889 lines
34 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="fr">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>FDS, FT & Étiquettes — Gauthier Chombart & Nathan Chauwin</title>
|
|
<link href="https://fonts.googleapis.com/css2?family=Syne:wght@400;600;700;800&family=DM+Sans:ital,wght@0,300;0,400;0,500;1,300&display=swap" rel="stylesheet">
|
|
<link rel="stylesheet" href="../header-style.css"/>
|
|
<style>
|
|
/* SLIDES */
|
|
.slide {
|
|
position: absolute;
|
|
inset: 0;
|
|
display: none;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
justify-content: center;
|
|
padding: 2rem;
|
|
padding-top: calc(70px + 2rem);
|
|
padding-bottom: calc(52px + 2rem);
|
|
opacity: 0;
|
|
transition: opacity 0.4s ease;
|
|
overflow-y: auto;
|
|
min-height: calc(100vh - 70px);
|
|
}
|
|
.slide.active { display: flex; opacity: 1; }
|
|
.slide.fade-in { animation: fadeIn 0.5s ease forwards; }
|
|
@keyframes fadeIn {
|
|
from { opacity: 0; transform: translateY(16px); }
|
|
to { opacity: 1; transform: translateY(0); }
|
|
}
|
|
|
|
.progress-fill { background: var(--amber); transition: width 0.4s ease; }
|
|
|
|
/* PHASE INDICATOR */
|
|
.phase-badge {
|
|
position: fixed;
|
|
top: 80px; right: 16px;
|
|
font-family: 'Syne', sans-serif;
|
|
font-size: 11px;
|
|
font-weight: 700;
|
|
letter-spacing: 0.08em;
|
|
text-transform: uppercase;
|
|
padding: 4px 12px;
|
|
border-radius: 20px;
|
|
z-index: 100;
|
|
}
|
|
|
|
/* BOTTOM BAR */
|
|
.bottom-bar {
|
|
position: fixed;
|
|
bottom: 0; left: 0; right: 0;
|
|
height: 52px;
|
|
background: rgba(250, 238, 218, 0.98);
|
|
border-top: 2px solid var(--amber);
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
padding: 0 20px;
|
|
z-index: 100;
|
|
backdrop-filter: blur(10px);
|
|
}
|
|
.slide-counter { font-size: 12px; font-family: 'Syne', sans-serif; font-weight: 600; color: var(--amber-dark); }
|
|
.back-btn {
|
|
background: none;
|
|
border: 0.5px solid var(--amber);
|
|
border-radius: 20px;
|
|
padding: 6px 16px;
|
|
font-size: 12px;
|
|
color: var(--amber-dark);
|
|
cursor: pointer;
|
|
transition: all 0.2s;
|
|
font-family: 'DM Sans', sans-serif;
|
|
}
|
|
.back-btn:hover { background: rgba(186,117,23,0.08); }
|
|
|
|
/* BUTTONS */
|
|
.btn {
|
|
font-family: 'Syne', sans-serif;
|
|
font-size: 14px;
|
|
font-weight: 600;
|
|
padding: 12px 28px;
|
|
border-radius: 40px;
|
|
border: none;
|
|
cursor: pointer;
|
|
transition: all 0.2s;
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
text-decoration: none;
|
|
}
|
|
.btn:hover { transform: translateY(-1px); }
|
|
.btn:active { transform: scale(0.98); }
|
|
.btn-amber { background: var(--amber); color: white; }
|
|
.btn-coral { background: var(--coral-mid); color: white; }
|
|
.btn-teal { background: var(--teal-mid); color: white; }
|
|
.btn-outline { background: transparent; border: 1.5px solid var(--amber); color: var(--amber-dark); }
|
|
|
|
/* HERO / TITLES */
|
|
.hero-label {
|
|
font-family: 'Syne', sans-serif;
|
|
font-size: 11px;
|
|
font-weight: 700;
|
|
letter-spacing: 0.1em;
|
|
text-transform: uppercase;
|
|
color: var(--amber);
|
|
margin-bottom: 8px;
|
|
}
|
|
.hero-title {
|
|
font-family: 'Syne', sans-serif;
|
|
font-size: clamp(32px, 5.5vw, 58px);
|
|
font-weight: 800;
|
|
line-height: 1.02;
|
|
color: var(--text);
|
|
margin-bottom: 12px;
|
|
}
|
|
.hero-sub {
|
|
font-size: 16px;
|
|
color: var(--text-muted);
|
|
max-width: 480px;
|
|
text-align: center;
|
|
line-height: 1.6;
|
|
margin-bottom: 2rem;
|
|
}
|
|
.section-tag {
|
|
font-family: 'Syne', sans-serif;
|
|
font-size: 11px;
|
|
font-weight: 700;
|
|
letter-spacing: 0.08em;
|
|
text-transform: uppercase;
|
|
padding: 4px 12px;
|
|
border-radius: 20px;
|
|
margin-bottom: 10px;
|
|
display: inline-block;
|
|
background: var(--amber-light);
|
|
color: var(--amber-dark);
|
|
}
|
|
.slide-title {
|
|
font-family: 'Syne', sans-serif;
|
|
font-size: clamp(22px, 3.5vw, 34px);
|
|
font-weight: 800;
|
|
line-height: 1.15;
|
|
margin-bottom: 0.5rem;
|
|
text-align: center;
|
|
}
|
|
.slide-intro {
|
|
font-size: 14px;
|
|
color: var(--text-muted);
|
|
text-align: center;
|
|
max-width: 580px;
|
|
line-height: 1.6;
|
|
margin-bottom: 1.5rem;
|
|
}
|
|
.actions-row {
|
|
display: flex;
|
|
gap: 12px;
|
|
align-items: center;
|
|
margin-top: 1.5rem;
|
|
flex-wrap: wrap;
|
|
justify-content: center;
|
|
}
|
|
|
|
/* OVERVIEW CARDS */
|
|
.overview-grid {
|
|
display: grid;
|
|
grid-template-columns: repeat(3, 1fr);
|
|
gap: 14px;
|
|
max-width: 680px;
|
|
width: 100%;
|
|
margin: 1.5rem 0;
|
|
}
|
|
.overview-card {
|
|
background: white;
|
|
border: 0.5px solid var(--border);
|
|
border-radius: 14px;
|
|
padding: 1.25rem;
|
|
text-align: center;
|
|
}
|
|
.overview-icon { font-size: 30px; margin-bottom: 8px; }
|
|
.overview-title { font-family: 'Syne', sans-serif; font-size: 13px; font-weight: 700; margin-bottom: 4px; }
|
|
.overview-sub { font-size: 12px; color: var(--text-muted); line-height: 1.4; }
|
|
|
|
.info-card {
|
|
border-radius: 12px;
|
|
padding: 16px 20px;
|
|
max-width: 620px;
|
|
width: 100%;
|
|
font-size: 14px;
|
|
line-height: 1.6;
|
|
display: flex;
|
|
gap: 10px;
|
|
align-items: flex-start;
|
|
background: var(--amber-light);
|
|
color: var(--amber-dark);
|
|
}
|
|
|
|
/* QUIZ ROWS */
|
|
.quiz-list { width: 100%; max-width: 720px; display: flex; flex-direction: column; gap: 12px; }
|
|
.answer-row {
|
|
background: white;
|
|
border: 1px solid var(--border);
|
|
border-radius: 12px;
|
|
padding: 14px 16px;
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 16px;
|
|
transition: all 0.25s ease;
|
|
}
|
|
.answer-row:hover { border-color: var(--amber); box-shadow: 0 6px 16px rgba(186,117,23,0.08); }
|
|
.question-num {
|
|
font-family: 'Syne', sans-serif;
|
|
font-size: 12px;
|
|
font-weight: 800;
|
|
min-width: 30px;
|
|
height: 30px;
|
|
border-radius: 50%;
|
|
display: flex; align-items: center; justify-content: center;
|
|
background: var(--amber-light);
|
|
color: var(--amber-dark);
|
|
flex-shrink: 0;
|
|
}
|
|
.question-text { flex-grow: 1; font-size: 14px; color: var(--text); font-weight: 500; line-height: 1.4; }
|
|
.answer-label {
|
|
font-size: 11px;
|
|
font-weight: 700;
|
|
color: var(--amber-dark);
|
|
white-space: nowrap;
|
|
padding: 4px 10px;
|
|
background: var(--amber-light);
|
|
border: 1px solid var(--amber);
|
|
border-radius: 6px;
|
|
flex-shrink: 0;
|
|
}
|
|
.answer-icon { font-size: 1.2em; flex-shrink: 0; }
|
|
select {
|
|
font-family: 'DM Sans', sans-serif;
|
|
padding: 9px 12px;
|
|
border: 1px solid var(--border);
|
|
border-radius: 8px;
|
|
background: var(--bg);
|
|
color: var(--text);
|
|
font-size: 13px;
|
|
cursor: pointer;
|
|
transition: all 0.2s ease;
|
|
min-width: 175px;
|
|
flex-shrink: 0;
|
|
}
|
|
select:focus { outline: none; border-color: var(--amber); box-shadow: 0 0 0 3px rgba(186,117,23,0.1); }
|
|
|
|
.verify-btn {
|
|
font-family: 'Syne', sans-serif;
|
|
color: white;
|
|
border: none;
|
|
padding: 12px 30px;
|
|
border-radius: 40px;
|
|
cursor: pointer;
|
|
font-size: 14px;
|
|
font-weight: 600;
|
|
transition: all 0.2s ease;
|
|
}
|
|
.verify-btn:hover { transform: translateY(-1px); }
|
|
|
|
.result-message {
|
|
margin-top: 4px;
|
|
padding: 16px 20px;
|
|
border-radius: 10px;
|
|
font-weight: 600;
|
|
font-size: 14px;
|
|
display: none;
|
|
max-width: 720px;
|
|
width: 100%;
|
|
text-align: center;
|
|
}
|
|
.result-message.show { display: block; }
|
|
.result-message.success { background: var(--teal-light); border: 1.5px solid var(--teal-mid); color: var(--teal-dark); }
|
|
.result-message.error { background: var(--coral-light); border: 1.5px solid var(--coral-mid); color: var(--coral); }
|
|
|
|
/* COMPARISON TABLE */
|
|
.comparison-table {
|
|
width: 100%;
|
|
max-width: 760px;
|
|
border-collapse: collapse;
|
|
background: white;
|
|
border: 0.5px solid var(--border);
|
|
border-radius: 12px;
|
|
overflow: hidden;
|
|
font-size: 13px;
|
|
margin-bottom: 1.25rem;
|
|
}
|
|
.comparison-table th {
|
|
background: var(--amber-light);
|
|
color: var(--amber-dark);
|
|
padding: 12px 16px;
|
|
text-align: left;
|
|
font-family: 'Syne', sans-serif;
|
|
font-size: 11px;
|
|
font-weight: 700;
|
|
letter-spacing: 0.04em;
|
|
text-transform: uppercase;
|
|
border-bottom: 2px solid var(--amber);
|
|
}
|
|
.comparison-table td {
|
|
padding: 12px 16px;
|
|
border-bottom: 0.5px solid var(--border);
|
|
color: var(--text-muted);
|
|
}
|
|
.comparison-table tr:last-child td { border-bottom: none; }
|
|
.comparison-table strong { color: var(--text); }
|
|
|
|
/* TIPS LIST */
|
|
.tips-list { list-style: none; padding: 0; max-width: 680px; width: 100%; display: flex; flex-direction: column; gap: 8px; }
|
|
.tips-list li {
|
|
background: white;
|
|
border: 0.5px solid var(--border);
|
|
border-radius: 10px;
|
|
padding: 12px 16px 12px 40px;
|
|
position: relative;
|
|
font-size: 13.5px;
|
|
line-height: 1.5;
|
|
color: var(--text-muted);
|
|
}
|
|
.tips-list li::before { content: '💡'; position: absolute; left: 14px; }
|
|
.tips-list strong { color: var(--text); }
|
|
|
|
/* SCROLL AREA */
|
|
.scroll-area {
|
|
overflow-y: auto;
|
|
max-height: calc(100vh - 200px);
|
|
width: 100%;
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
gap: 1rem;
|
|
padding: 0.5rem 0 4rem;
|
|
}
|
|
.scroll-area::-webkit-scrollbar { width: 4px; }
|
|
.scroll-area::-webkit-scrollbar-thumb { background: var(--border); border-radius: 2px; }
|
|
|
|
/* IDENTITY CARD */
|
|
.identity-card {
|
|
background: white;
|
|
border: 0.5px solid var(--border);
|
|
border-radius: 14px;
|
|
padding: 16px 18px;
|
|
max-width: 560px;
|
|
width: 100%;
|
|
margin: 0.5rem 0;
|
|
}
|
|
.identity-card .identity-title {
|
|
font-family: 'Syne', sans-serif;
|
|
font-size: 12px;
|
|
font-weight: 700;
|
|
letter-spacing: 0.05em;
|
|
text-transform: uppercase;
|
|
color: var(--amber-dark);
|
|
margin-bottom: 10px;
|
|
display: flex; align-items: center; gap: 6px;
|
|
}
|
|
.identity-fields { display: flex; flex-direction: column; gap: 8px; }
|
|
.identity-fields input {
|
|
font-family: 'DM Sans', sans-serif;
|
|
font-size: 13.5px;
|
|
color: var(--text);
|
|
background: var(--bg);
|
|
border: 1px solid var(--border);
|
|
border-radius: 10px;
|
|
padding: 9px 13px;
|
|
width: 100%;
|
|
box-sizing: border-box;
|
|
}
|
|
.identity-fields input:focus { outline: none; border-color: var(--amber); background: white; }
|
|
|
|
/* DECO */
|
|
.deco-circle { position: fixed; border-radius: 50%; pointer-events: none; z-index: 0; }
|
|
.slide > * { position: relative; z-index: 1; }
|
|
|
|
@media (max-width: 700px) {
|
|
.overview-grid { grid-template-columns: 1fr; }
|
|
.answer-row { flex-wrap: wrap; }
|
|
select { width: 100%; min-width: 0; }
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
|
|
<!-- HEADER -->
|
|
<header>
|
|
<div class="logo">Gauthier Chombart & Nathan Chauwin</div>
|
|
<nav>
|
|
<a href="../index.html">Accueil</a>
|
|
<a href="../index.html#formations">Exercices</a>
|
|
<a href="../index.html#documentation">Documentation</a>
|
|
<a href="../index.html#rapports">Rapports</a>
|
|
<a href="../index.html#about">À propos</a>
|
|
<a href="../index.html#contact">Contact</a>
|
|
</nav>
|
|
</header>
|
|
|
|
<!-- Progress bar -->
|
|
<div class="progress-bar"><div class="progress-fill" id="progressFill"></div></div>
|
|
|
|
<!-- Phase badge -->
|
|
<div class="phase-badge" id="phaseBadge" style="display:none"></div>
|
|
|
|
<!-- Bottom bar -->
|
|
<div class="bottom-bar" id="bottomBar" style="display:none;">
|
|
<button class="back-btn" id="backBtn" onclick="goBack()" style="display:none;">← Retour</button>
|
|
<div class="slide-counter" id="slideCounter"></div>
|
|
</div>
|
|
|
|
<!-- ============ SLIDE 0 — ACCUEIL ============ -->
|
|
<div class="slide active fade-in" id="slide-0">
|
|
<div class="deco-circle" style="width:400px;height:400px;background:var(--amber-light);top:-100px;right:-80px;opacity:0.6;"></div>
|
|
<div class="deco-circle" style="width:200px;height:200px;background:var(--coral-light);bottom:60px;left:-60px;opacity:0.5;"></div>
|
|
<div style="text-align:center;">
|
|
<div class="hero-label">Certibiocide — Travaux dirigés</div>
|
|
<div class="hero-title">FDS, FT<br>& Étiquettes</div>
|
|
<p class="hero-sub">Maîtrisez les trois documents essentiels des produits biocides : fiche de sécurité, fiche technique et étiquetage réglementaire.</p>
|
|
<button class="btn btn-amber" onclick="goTo(1)">Démarrer le TD →</button>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- ============ SLIDE 1 — DÉROULÉ ============ -->
|
|
<div class="slide" id="slide-1">
|
|
<div class="deco-circle" style="width:300px;height:300px;background:var(--amber-light);top:-60px;left:-60px;opacity:0.4;"></div>
|
|
<div class="section-tag">Déroulé du TD</div>
|
|
<div class="slide-title">Trois documents, trois usages</div>
|
|
<p class="slide-intro">Vous allez apprendre à localiser une information dans chacun des documents de référence d'un produit biocide.</p>
|
|
<div class="overview-grid">
|
|
<div class="overview-card">
|
|
<div class="overview-icon">📄</div>
|
|
<div class="overview-title">Partie 1 — FDS</div>
|
|
<div class="overview-sub">Fiche de Données de Sécurité — 16 rubriques</div>
|
|
</div>
|
|
<div class="overview-card">
|
|
<div class="overview-icon">📋</div>
|
|
<div class="overview-title">Partie 2 — FT</div>
|
|
<div class="overview-sub">Fiche Technique — mode d'emploi produit</div>
|
|
</div>
|
|
<div class="overview-card">
|
|
<div class="overview-icon">🏷️</div>
|
|
<div class="overview-title">Partie 3 — Étiquette</div>
|
|
<div class="overview-sub">Interface directe avec l'utilisateur</div>
|
|
</div>
|
|
</div>
|
|
<div class="info-card">
|
|
<span>⏱️</span>
|
|
<div>Durée ≈ 30 min. Pour chaque question, sélectionnez la <strong>zone du document</strong> où trouver l'information, puis vérifiez votre score.</div>
|
|
</div>
|
|
<div class="identity-card">
|
|
<div class="identity-title">👥 Identification du groupe</div>
|
|
<div class="identity-fields">
|
|
<input type="text" id="idGroupe" placeholder="Nom du groupe / stagiaires (ex : Groupe 3 — Dupont / Martin)" autocomplete="off">
|
|
<input type="date" id="idDate">
|
|
<input type="text" id="idFormateur" placeholder="Formateur (facultatif)" autocomplete="off">
|
|
</div>
|
|
</div>
|
|
<button class="btn btn-amber" onclick="goTo(2)" style="margin-top:1.5rem;">Commencer la partie 1 →</button>
|
|
</div>
|
|
|
|
<!-- ============ SLIDE 2 — FDS INTRO ============ -->
|
|
<div class="slide" id="slide-2">
|
|
<div class="deco-circle" style="width:280px;height:280px;background:var(--amber-light);top:-40px;right:-40px;opacity:0.5;"></div>
|
|
<div class="section-tag">Partie 1 / 3 — 10 min</div>
|
|
<div class="slide-title">📄 Fiche de Données de Sécurité</div>
|
|
<p class="slide-intro">La FDS est le document de référence pour connaître les <strong>dangers</strong>, les <strong>EPI</strong>, les <strong>premiers secours</strong> et l'<strong>élimination</strong> d'un produit biocide. Elle contient 16 rubriques standardisées (règlement REACH).</p>
|
|
<div class="info-card">
|
|
<span>🎯</span>
|
|
<div>Pour chaque question, indiquez dans quelle <strong>rubrique (1 à 16)</strong> trouver la réponse — ou « Absent » si l'information n'y figure pas. Les questions sont mélangées à chaque chargement.</div>
|
|
</div>
|
|
<button class="btn btn-amber" onclick="goTo(3)" style="margin-top:1.5rem;">Répondre aux questions →</button>
|
|
</div>
|
|
|
|
<!-- ============ SLIDE 3 — FDS QUIZ ============ -->
|
|
<div class="slide" id="slide-3">
|
|
<div class="scroll-area">
|
|
<div class="section-tag">Partie 1 / 3 — FDS</div>
|
|
<div class="slide-title">Où trouver l'information ?</div>
|
|
<div class="quiz-list" id="fds-questions"></div>
|
|
<button class="verify-btn btn-amber" onclick="verifyFDS()">✓ Vérifier mes réponses</button>
|
|
<div id="fds-result" class="result-message"></div>
|
|
<div class="actions-row">
|
|
<button class="btn btn-coral" onclick="goTo(4)">Passer à la partie 2 →</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- ============ SLIDE 4 — FT INTRO ============ -->
|
|
<div class="slide" id="slide-4">
|
|
<div class="deco-circle" style="width:280px;height:280px;background:var(--coral-light);top:-40px;left:-40px;opacity:0.5;"></div>
|
|
<div class="section-tag" style="background:var(--coral-light);color:var(--coral);">Partie 2 / 3 — 10 min</div>
|
|
<div class="slide-title">📋 Fiche Technique</div>
|
|
<p class="slide-intro">La FT complète la FDS : elle fournit le <strong>mode d'emploi</strong>, les <strong>utilisations</strong>, les <strong>conditionnements</strong> et les <strong>compatibilités matières</strong>. C'est le document pratique de l'utilisateur.</p>
|
|
<div class="info-card" style="background:var(--coral-light);color:var(--coral);">
|
|
<span>🎯</span>
|
|
<div>Indiquez la <strong>section</strong> de la FT où trouver chaque information : Description, Propriétés biocides, Conditionnements, Utilisations — ou « Absent ».</div>
|
|
</div>
|
|
<button class="btn btn-coral" onclick="goTo(5)" style="margin-top:1.5rem;">Répondre aux questions →</button>
|
|
</div>
|
|
|
|
<!-- ============ SLIDE 5 — FT QUIZ ============ -->
|
|
<div class="slide" id="slide-5">
|
|
<div class="scroll-area">
|
|
<div class="section-tag" style="background:var(--coral-light);color:var(--coral);">Partie 2 / 3 — FT</div>
|
|
<div class="slide-title">Sections de la fiche technique</div>
|
|
<div class="quiz-list" id="ft-questions"></div>
|
|
<button class="verify-btn btn-coral" onclick="verifyFT()">✓ Vérifier mes réponses</button>
|
|
<div id="ft-result" class="result-message"></div>
|
|
<div class="actions-row">
|
|
<button class="btn btn-teal" onclick="goTo(6)">Passer à la partie 3 →</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- ============ SLIDE 6 — ÉTIQUETTE INTRO ============ -->
|
|
<div class="slide" id="slide-6">
|
|
<div class="deco-circle" style="width:280px;height:280px;background:var(--teal-light);bottom:-40px;right:-40px;opacity:0.6;"></div>
|
|
<div class="section-tag" style="background:var(--teal-light);color:var(--teal-dark);">Partie 3 / 3 — 10 min</div>
|
|
<div class="slide-title">🏷️ Étiquetage</div>
|
|
<p class="slide-intro">L'étiquette est l'interface directe entre le produit et l'utilisateur. Elle communique rapidement les <strong>dangers essentiels</strong>, les <strong>EPI</strong> et les <strong>consignes d'utilisation</strong>.</p>
|
|
<div class="info-card" style="background:var(--teal-light);color:var(--teal-dark);">
|
|
<span>🎯</span>
|
|
<div>Indiquez la <strong>zone de l'étiquette</strong> où trouver l'information : Identité, Pictogrammes, Mots d'avertissement, Mentions de danger, Conseils de prudence, Contenu net, Numéro d'urgence — ou « Absent ».</div>
|
|
</div>
|
|
<button class="btn btn-teal" onclick="goTo(7)" style="margin-top:1.5rem;">Répondre aux questions →</button>
|
|
</div>
|
|
|
|
<!-- ============ SLIDE 7 — ÉTIQUETTE QUIZ ============ -->
|
|
<div class="slide" id="slide-7">
|
|
<div class="scroll-area">
|
|
<div class="section-tag" style="background:var(--teal-light);color:var(--teal-dark);">Partie 3 / 3 — Étiquette</div>
|
|
<div class="slide-title">Zones de l'étiquette</div>
|
|
<div class="quiz-list" id="etiquette-questions"></div>
|
|
<button class="verify-btn btn-teal" onclick="verifyEtiquette()">✓ Vérifier mes réponses</button>
|
|
<div id="etiquette-result" class="result-message"></div>
|
|
<div class="actions-row">
|
|
<button class="btn btn-amber" onclick="goTo(8)">Voir la synthèse →</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- ============ SLIDE 8 — SYNTHÈSE / FIN ============ -->
|
|
<div class="slide" id="slide-8">
|
|
<div class="scroll-area">
|
|
<div class="deco-circle" style="width:320px;height:320px;background:var(--amber-light);bottom:-80px;right:-60px;opacity:0.5;"></div>
|
|
<div style="text-align:center;">
|
|
<div style="font-size:44px;margin-bottom:0.5rem;">🎉</div>
|
|
<div class="section-tag">TD terminé</div>
|
|
<div class="slide-title" style="margin-top:0.4rem;">Synthèse comparative</div>
|
|
</div>
|
|
<table class="comparison-table">
|
|
<thead>
|
|
<tr><th>Document</th><th>Utilité principale</th><th>Consultation</th><th>Public</th></tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr><td><strong>FDS</strong></td><td>Sécurité, dangers, EPI, premiers secours</td><td>AVANT manipulation</td><td>Professionnels</td></tr>
|
|
<tr><td><strong>FT</strong></td><td>Mode d'emploi, applications, conditionnements</td><td>Pour l'utilisation</td><td>Utilisateurs finaux</td></tr>
|
|
<tr><td><strong>Étiquette</strong></td><td>Dangers essentiels, interface rapide</td><td>À chaque prise du produit</td><td>Tous les utilisateurs</td></tr>
|
|
</tbody>
|
|
</table>
|
|
<ul class="tips-list">
|
|
<li><strong>FDS = Sécurité et dangers</strong> → à consulter AVANT manipulation.</li>
|
|
<li><strong>FT = Mode d'emploi et applications</strong> → à consulter pour l'utilisation.</li>
|
|
<li><strong>Étiquette = Interface rapide</strong> → lecture obligatoire avant ouverture du produit.</li>
|
|
<li>Les trois documents sont <strong>complémentaires</strong>, jamais redondants — chacun cible un besoin et un public différents.</li>
|
|
</ul>
|
|
<div class="actions-row">
|
|
<button class="btn btn-amber" onclick="exporterPDF()">⬇ Télécharger mes réponses (PDF)</button>
|
|
<a href="correction-fds.html" class="btn btn-outline">✔ Corriger un rendu</a>
|
|
</div>
|
|
<div class="actions-row" style="margin-top:0.5rem;">
|
|
<button class="btn btn-outline" onclick="restartAll()">↺ Recommencer</button>
|
|
<a href="../index.html#formations" class="btn btn-outline">Retour aux exercices</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
let currentSlide = 0;
|
|
let history = [];
|
|
const totalSlides = 8;
|
|
|
|
/* ======================== QUESTIONS ======================== */
|
|
const fdsQuestions = [
|
|
{ id: 1, text: "Quel est le nom du produit et qui est le fabricant ?", answer: "1" },
|
|
{ id: 2, text: "Quels sont les dangers du produit ?", answer: "2" },
|
|
{ id: 3, text: "Quelles sont les molécules actives et leurs concentrations ?", answer: "3" },
|
|
{ id: 4, text: "Quels gestes adopter en premiers secours ?", answer: "4" },
|
|
{ id: 5, text: "En cas d'incendie, quels sont les moyens d'extinction conseillés ?", answer: "5" },
|
|
{ id: 6, text: "Que faire en cas de dispersion accidentelle ?", answer: "6" },
|
|
{ id: 7, text: "Dans quelles conditions stocker mon produit ?", answer: "7" },
|
|
{ id: 8, text: "Quels équipements de protection individuelle (EPI) dois-je porter ?", answer: "8" },
|
|
{ id: 9, text: "Quel est le pH de ce produit ?", answer: "9" },
|
|
{ id: 10, text: "Le produit est-il stable dans des conditions normales ?", answer: "10" },
|
|
{ id: 11, text: "Quels sont les effets potentiels sur la santé ?", answer: "11" },
|
|
{ id: 12, text: "Quel est le degré de toxicité pour les poissons ? Potentiel de bioaccumulation ?", answer: "12" },
|
|
{ id: 13, text: "Comment éliminer le produit ?", answer: "13" },
|
|
{ id: 14, text: "Est-ce que mon produit est classé dangereux pour le transport ?", answer: "14" },
|
|
{ id: 15, text: "En cas d'ingestion du produit, que faire ?", answer: "4,11" },
|
|
{ id: 16, text: "Où trouver le mode d'emploi du produit ?", answer: "absent" }
|
|
];
|
|
|
|
const ftQuestions = [
|
|
{ id: 1, text: "Quel est le nom du produit et qui est le fabricant ?", answer: "Description" },
|
|
{ id: 2, text: "Sur quelles matières ce produit est-il compatible ?", answer: "Description" },
|
|
{ id: 3, text: "Quel est (sont) le(s) type(s) de ce produit ?", answer: "Propriétés biocides" },
|
|
{ id: 4, text: "Quels sont les types de conditionnements disponibles ?", answer: "Conditionnements" },
|
|
{ id: 5, text: "Où retrouver les différents modes d'utilisation de ce produit ?", answer: "Utilisations" }
|
|
];
|
|
const ftOptions = ["Description", "Propriétés biocides", "Conditionnements", "Utilisations"];
|
|
|
|
const etiquetteQuestions = [
|
|
{ id: 1, text: "Quel est le nom du produit et le nom de l'entreprise ?", answer: "Identité" },
|
|
{ id: 2, text: "Quels pictogrammes de danger sont affichés ?", answer: "Pictogrammes" },
|
|
{ id: 3, text: "Quels sont les mots d'avertissement (« Attention » ou « Danger ») ?", answer: "Mots d'avertissement" },
|
|
{ id: 4, text: "Quelles sont les mentions de danger (H-statements) identifiées ?", answer: "Mentions de danger" },
|
|
{ id: 5, text: "Quels équipements de protection individuelle (EPI) sont recommandés ?", answer: "Conseils de prudence" },
|
|
{ id: 6, text: "Quels premiers secours sont indiqués ?", answer: "Conseils de prudence" },
|
|
{ id: 7, text: "Comment éliminer l'emballage après utilisation ?", answer: "Conseils de prudence" },
|
|
{ id: 8, text: "Quel est le contenu net du produit ?", answer: "Contenu net" },
|
|
{ id: 9, text: "Y a-t-il un numéro d'appel d'urgence mentionné ?", answer: "Numéro d'urgence" },
|
|
{ id: 10, text: "Quelles consignes de stockage sont affichées ?", answer: "Conseils de prudence" }
|
|
];
|
|
const etiquetteOptions = ["Identité", "Pictogrammes", "Mots d'avertissement", "Mentions de danger", "Conseils de prudence", "Contenu net", "Numéro d'urgence"];
|
|
|
|
function shuffleArray(array) {
|
|
const a = [...array];
|
|
for (let i = a.length - 1; i > 0; i--) {
|
|
const j = Math.floor(Math.random() * (i + 1));
|
|
[a[i], a[j]] = [a[j], a[i]];
|
|
}
|
|
return a;
|
|
}
|
|
|
|
function buildRow(qNum, selectId, answerAttr, text, options, badgeStyle) {
|
|
let opts = '<option value="">-- Sélectionner --</option>';
|
|
options.forEach(o => { opts += `<option value="${o.value}">${o.label}</option>`; });
|
|
return `
|
|
<div class="answer-row">
|
|
<div class="question-num" style="${badgeStyle}">Q${qNum}</div>
|
|
<div class="question-text">${text}</div>
|
|
<select id="${selectId}" data-answer="${answerAttr}">${opts}</select>
|
|
</div>`;
|
|
}
|
|
|
|
function generateQuizzes() {
|
|
// FDS — shuffled, 16 rubriques
|
|
const rubriqueOpts = Array.from({ length: 16 }, (_, i) => ({ value: String(i + 1), label: 'Rubrique ' + (i + 1) }));
|
|
rubriqueOpts.push({ value: 'absent', label: 'Absent' });
|
|
const fdsC = document.getElementById('fds-questions');
|
|
fdsC.innerHTML = '';
|
|
shuffleArray(fdsQuestions).forEach((q, i) => {
|
|
fdsC.innerHTML += buildRow(i + 1, 'fds' + q.id, q.answer, q.text, rubriqueOpts, 'background:var(--amber-light);color:var(--amber-dark);');
|
|
});
|
|
|
|
// FT
|
|
const ftOpts = ftOptions.map(o => ({ value: o, label: o }));
|
|
ftOpts.push({ value: 'absent', label: 'Absent' });
|
|
const ftC = document.getElementById('ft-questions');
|
|
ftC.innerHTML = '';
|
|
ftQuestions.forEach((q, i) => {
|
|
ftC.innerHTML += buildRow(i + 1, 'ft' + q.id, q.answer, q.text, ftOpts, 'background:var(--coral-light);color:var(--coral);');
|
|
});
|
|
|
|
// Étiquette
|
|
const etiOpts = etiquetteOptions.map(o => ({ value: o, label: o }));
|
|
etiOpts.push({ value: 'absent', label: 'Absent' });
|
|
const etiC = document.getElementById('etiquette-questions');
|
|
etiC.innerHTML = '';
|
|
etiquetteQuestions.forEach((q, i) => {
|
|
etiC.innerHTML += buildRow(i + 1, 'eti' + q.id, q.answer, q.text, etiOpts, 'background:var(--teal-light);color:var(--teal-dark);');
|
|
});
|
|
}
|
|
|
|
/* ======================== VÉRIFICATION ======================== */
|
|
function showInlineResult(selectEl, isCorrect, isUnanswered, correctAnswerText) {
|
|
const row = selectEl.closest('.answer-row');
|
|
row.querySelector('.answer-label')?.remove();
|
|
row.querySelector('.answer-icon')?.remove();
|
|
|
|
const label = document.createElement('div');
|
|
label.className = 'answer-label';
|
|
label.textContent = correctAnswerText;
|
|
selectEl.before(label);
|
|
|
|
const icon = document.createElement('div');
|
|
icon.className = 'answer-icon';
|
|
icon.textContent = isUnanswered ? '❓' : (isCorrect ? '✅' : '❌');
|
|
selectEl.after(icon);
|
|
}
|
|
|
|
function showScore(resultDiv, correct, total) {
|
|
const p = Math.round((correct / total) * 100);
|
|
if (p === 100) {
|
|
resultDiv.className = 'result-message success show';
|
|
resultDiv.innerHTML = `<strong>🎉 Excellent !</strong> ${correct}/${total} bonnes réponses (${p}%)`;
|
|
} else if (p >= 80) {
|
|
resultDiv.className = 'result-message success show';
|
|
resultDiv.innerHTML = `<strong>✓ Très bien !</strong> ${correct}/${total} bonnes réponses (${p}%)`;
|
|
} else if (p >= 60) {
|
|
resultDiv.className = 'result-message error show';
|
|
resultDiv.innerHTML = `<strong>⚠️ À revoir</strong> — ${correct}/${total} bonnes réponses (${p}%)`;
|
|
} else {
|
|
resultDiv.className = 'result-message error show';
|
|
resultDiv.innerHTML = `<strong>❌ Insuffisant</strong> — ${correct}/${total} bonnes réponses (${p}%)`;
|
|
}
|
|
}
|
|
|
|
function verifyFDS() {
|
|
let correct = 0;
|
|
fdsQuestions.forEach(q => {
|
|
const select = document.getElementById('fds' + q.id);
|
|
const userAnswer = select.value;
|
|
const expected = q.answer.split(',');
|
|
const isCorrect = expected.includes(userAnswer);
|
|
const labelText = expected.length > 1
|
|
? 'Rubriques ' + expected.join(' et ')
|
|
: (expected[0] === 'absent' ? 'Absent' : 'Rubrique ' + expected[0]);
|
|
if (isCorrect) correct++;
|
|
showInlineResult(select, isCorrect, userAnswer === '', labelText);
|
|
});
|
|
showScore(document.getElementById('fds-result'), correct, fdsQuestions.length);
|
|
}
|
|
|
|
function verifyFT() {
|
|
let correct = 0;
|
|
ftQuestions.forEach(q => {
|
|
const select = document.getElementById('ft' + q.id);
|
|
const userAnswer = select.value;
|
|
const isCorrect = userAnswer === q.answer;
|
|
if (isCorrect) correct++;
|
|
showInlineResult(select, isCorrect, userAnswer === '', q.answer);
|
|
});
|
|
showScore(document.getElementById('ft-result'), correct, ftQuestions.length);
|
|
}
|
|
|
|
function verifyEtiquette() {
|
|
let correct = 0;
|
|
etiquetteQuestions.forEach(q => {
|
|
const select = document.getElementById('eti' + q.id);
|
|
const userAnswer = select.value;
|
|
const isCorrect = userAnswer === q.answer;
|
|
if (isCorrect) correct++;
|
|
showInlineResult(select, isCorrect, userAnswer === '', q.answer);
|
|
});
|
|
showScore(document.getElementById('etiquette-result'), correct, etiquetteQuestions.length);
|
|
}
|
|
|
|
/* ======================== EXPORT PDF ======================== */
|
|
function escapeHtml(str) {
|
|
if (!str) return '';
|
|
return String(str).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
|
|
}
|
|
function idVal(id) {
|
|
const el = document.getElementById(id);
|
|
return el ? el.value.trim() : '';
|
|
}
|
|
|
|
// Libellé lisible d'une réponse FDS (numéro de rubrique) et de l'attendu
|
|
function fdsAnswerLabel(v) {
|
|
if (!v) return '(non répondu)';
|
|
if (v === 'absent') return 'Absent';
|
|
return 'Rubrique ' + v;
|
|
}
|
|
function fdsExpectedLabel(answer) {
|
|
const parts = answer.split(',');
|
|
if (parts.length > 1) return 'Rubrique ' + parts.join(' ou ');
|
|
return parts[0] === 'absent' ? 'Absent' : 'Rubrique ' + parts[0];
|
|
}
|
|
function textAnswerLabel(v) {
|
|
if (!v) return '(non répondu)';
|
|
return v === 'absent' ? 'Absent' : v;
|
|
}
|
|
|
|
function isFdsCorrect(q, v) { return v !== '' && q.answer.split(',').includes(v); }
|
|
function isTextCorrect(q, v) { return v !== '' && v === q.answer; }
|
|
|
|
function exporterPDF() {
|
|
const groupe = idVal('idGroupe');
|
|
const date = idVal('idDate') || new Date().toISOString().slice(0, 10);
|
|
const formateur = idVal('idFormateur');
|
|
|
|
let scoreTotal = 0, nbTotal = 0;
|
|
|
|
function partHtml(prefix, title, questions, selPrefix, answerLabelFn, expectedLabelFn, correctFn) {
|
|
const rows = questions.map((q, i) => {
|
|
const sel = document.getElementById(selPrefix + q.id);
|
|
const v = sel ? sel.value : '';
|
|
const ok = correctFn(q, v);
|
|
nbTotal++; if (ok) scoreTotal++;
|
|
const mark = v === '' ? '❓' : (ok ? '✓' : '✗');
|
|
return `<div style="margin-bottom:10px;">
|
|
<div><strong>[${prefix}-Q${i + 1}]</strong> ${escapeHtml(q.text)}</div>
|
|
<div style="margin-top:2px;">Réponse du groupe : <strong>${escapeHtml(answerLabelFn(v))}</strong> — Attendu : ${escapeHtml(expectedLabelFn(q.answer))} — ${mark}</div>
|
|
</div>`;
|
|
}).join('');
|
|
return `<h2>${title}</h2>${rows}`;
|
|
}
|
|
|
|
const p1 = partHtml('P1', 'Partie 1 — FDS (Fiche de Données de Sécurité)', fdsQuestions, 'fds', fdsAnswerLabel, fdsExpectedLabel, isFdsCorrect);
|
|
const p2 = partHtml('P2', 'Partie 2 — FT (Fiche Technique)', ftQuestions, 'ft', textAnswerLabel, a => a, isTextCorrect);
|
|
const p3 = partHtml('P3', 'Partie 3 — Étiquette', etiquetteQuestions, 'eti', textAnswerLabel, a => a, isTextCorrect);
|
|
|
|
const w = window.open('', '_blank');
|
|
w.document.write(`
|
|
<html><head><meta charset="utf-8"><title>FDS, FT & Étiquettes — Réponses (${escapeHtml(groupe) || 'sans nom'})</title>
|
|
<style>
|
|
body { font-family: Arial, sans-serif; padding: 30px; color: #1a1a18; }
|
|
h1 { font-size: 20px; border-bottom: 2px solid #BA7517; padding-bottom: 8px; }
|
|
h2 { font-size: 15px; margin-top: 26px; color: #633806; }
|
|
.meta { font-size: 13px; color: #555; margin: 2px 0; }
|
|
</style></head>
|
|
<body>
|
|
<h1>TD — FDS, FT & Étiquettes</h1>
|
|
<p class="meta"><strong>Groupe / Stagiaire :</strong> ${escapeHtml(groupe) || '—'}</p>
|
|
<p class="meta"><strong>Date de session :</strong> ${escapeHtml(date)}</p>
|
|
<p class="meta"><strong>Formateur :</strong> ${escapeHtml(formateur) || '—'}</p>
|
|
<p class="meta"><strong>Score global :</strong> ${scoreTotal} / ${nbTotal}</p>
|
|
${p1}${p2}${p3}
|
|
</body></html>`);
|
|
w.document.close();
|
|
setTimeout(() => w.print(), 300);
|
|
}
|
|
|
|
/* ======================== NAVIGATION ======================== */
|
|
function goTo(n) {
|
|
const cur = document.getElementById('slide-' + currentSlide);
|
|
const next = document.getElementById('slide-' + n);
|
|
if (!next) return;
|
|
history.push(currentSlide);
|
|
cur.classList.remove('active', 'fade-in');
|
|
cur.style.display = 'none';
|
|
currentSlide = n;
|
|
next.style.display = 'flex';
|
|
setTimeout(() => next.classList.add('active', 'fade-in'), 10);
|
|
const sa = next.querySelector('.scroll-area');
|
|
if (sa) sa.scrollTop = 0;
|
|
updateUI();
|
|
}
|
|
|
|
function goBack() {
|
|
if (history.length === 0) return;
|
|
const prev = history.pop();
|
|
const cur = document.getElementById('slide-' + currentSlide);
|
|
const target = document.getElementById('slide-' + prev);
|
|
cur.classList.remove('active', 'fade-in');
|
|
cur.style.display = 'none';
|
|
currentSlide = prev;
|
|
target.style.display = 'flex';
|
|
setTimeout(() => target.classList.add('active', 'fade-in'), 10);
|
|
updateUI();
|
|
}
|
|
|
|
function updateUI() {
|
|
document.getElementById('progressFill').style.width =
|
|
currentSlide === 0 ? '0%' : ((currentSlide / totalSlides) * 100) + '%';
|
|
document.getElementById('slideCounter').textContent =
|
|
currentSlide === 0 ? '' : currentSlide + ' / ' + totalSlides;
|
|
document.getElementById('bottomBar').style.display = currentSlide === 0 ? 'none' : 'flex';
|
|
document.getElementById('backBtn').style.display = history.length > 0 ? 'block' : 'none';
|
|
|
|
const badge = document.getElementById('phaseBadge');
|
|
const set = (bg, col, txt) => { badge.style.display = 'block'; badge.style.background = bg; badge.style.color = col; badge.textContent = txt; };
|
|
if (currentSlide === 2 || currentSlide === 3) set('var(--amber-light)', 'var(--amber-dark)', 'Partie 1 — FDS');
|
|
else if (currentSlide === 4 || currentSlide === 5) set('var(--coral-light)', 'var(--coral)', 'Partie 2 — FT');
|
|
else if (currentSlide === 6 || currentSlide === 7) set('var(--teal-light)', 'var(--teal-dark)', 'Partie 3 — Étiquette');
|
|
else badge.style.display = 'none';
|
|
}
|
|
|
|
function restartAll() {
|
|
history = [];
|
|
document.querySelectorAll('.slide').forEach(s => { s.classList.remove('active', 'fade-in'); s.style.display = 'none'; });
|
|
document.querySelectorAll('.result-message').forEach(r => { r.className = 'result-message'; });
|
|
generateQuizzes();
|
|
currentSlide = 0;
|
|
const first = document.getElementById('slide-0');
|
|
first.style.display = 'flex';
|
|
setTimeout(() => first.classList.add('active', 'fade-in'), 10);
|
|
updateUI();
|
|
}
|
|
|
|
document.addEventListener('DOMContentLoaded', () => {
|
|
generateQuizzes();
|
|
updateUI();
|
|
});
|
|
</script>
|
|
</body>
|
|
</html>
|