body {
font-family: ‘Segoe UI’, Tahoma, Geneva, Verdana, sans-serif;
max-width: 100%;
margin: 0 auto;
padding: 20px;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
}
h1, h2, h3 {
color: #2c3e50;
}
.container {
background: rgba(255, 255, 255, 0.95);
padding: 30px;
border-radius: 15px;
box-shadow: 0 8px 32px rgba(0,0,0,0.1);
backdrop-filter: blur(10px);
max-width: 100%;
margin: 0 auto;
}
.subscription-form {
background: linear-gradient(135deg, #e8f5e9 0%, #c8e6c9 100%);
padding: 25px;
border-radius: 12px;
margin-bottom: 30px;
border: 1px solid rgba(76, 175, 80, 0.2);
}
.exercise-container {
display: none;
}
.form-group {
margin-bottom: 15px;
}
label {
display: block;
margin-bottom: 5px;
font-weight: bold;
color: #2c3e50;
}
input, select, textarea {
width: 100%;
padding: 12px;
border: 2px solid #e9ecef;
border-radius: 8px;
font-size: 16px;
transition: border-color 0.3s ease;
box-sizing: border-box;
}
input:focus, select:focus, textarea:focus {
outline: none;
border-color: #667eea;
box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1);
}
button {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
border: none;
padding: 15px 25px;
border-radius: 8px;
cursor: pointer;
font-size: 16px;
font-weight: bold;
transition: all 0.3s ease;
box-shadow: 0 4px 15px rgba(102, 126, 234, 0.3);
}
button:hover {
transform: translateY(-2px);
box-shadow: 0 6px 20px rgba(102, 126, 234, 0.4);
}
.question {
margin-bottom: 25px;
padding: 25px;
background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);
border-radius: 12px;
border-left: 5px solid #667eea;
box-shadow: 0 2px 10px rgba(0,0,0,0.05);
}
.question-number {
font-weight: bold;
color: #2c3e50;
margin-bottom: 12px;
font-size: 18px;
}
.question-text {
font-size: 16px;
margin-bottom: 15px;
line-height: 1.6;
color: #2c3e50;
}
.question-type {
background: #667eea;
color: white;
padding: 4px 12px;
border-radius: 20px;
font-size: 12px;
font-weight: bold;
display: inline-block;
margin-bottom: 10px;
}
.options {
display: grid;
gap: 12px;
}
.option {
display: flex;
align-items: center;
padding: 12px;
background: white;
border: 2px solid #e9ecef;
border-radius: 8px;
cursor: pointer;
transition: all 0.3s ease;
}
.option:hover {
border-color: #667eea;
background: linear-gradient(135deg, #e8f5e9 0%, #f3e5f5 100%);
transform: translateX(5px);
}
.option input[type=”radio”], .option input[type=”checkbox”] {
margin-right: 12px;
width: auto;
transform: scale(1.2);
}
.option.correct {
background: linear-gradient(135deg, #d4edda 0%, #c3e6cb 100%);
border-color: #28a745;
}
.option.incorrect {
background: linear-gradient(135deg, #f8d7da 0%, #f1b0b7 100%);
border-color: #dc3545;
}
.option.correct-answer {
background: linear-gradient(135deg, #d1ecf1 0%, #bee5eb 100%);
border-color: #17a2b8;
}
.result {
margin-top: 30px;
padding: 25px;
background: linear-gradient(135deg, #eafaf1 0%, #d4f1de 100%);
border-radius: 12px;
display: none;
border: 1px solid rgba(40, 167, 69, 0.2);
}
.certificate {
text-align: center;
margin-top: 30px;
padding: 25px;
border: 3px solid #2c3e50;
border-radius: 12px;
display: none;
background: white;
}
.error {
color: #dc3545;
font-size: 14px;
margin-top: 5px;
}
.progress-bar {
width: 100%;
height: 25px;
background: linear-gradient(135deg, #e9ecef 0%, #dee2e6 100%);
border-radius: 15px;
margin-bottom: 25px;
overflow: hidden;
box-shadow: inset 0 2px 4px rgba(0,0,0,0.1);
}
.progress-fill {
height: 100%;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
border-radius: 15px;
transition: width 0.5s ease;
width: 0%;
box-shadow: 0 2px 4px rgba(102, 126, 234, 0.3);
}
#certificatePreview {
position: relative;
width: 100%;
height: 500px;
background: linear-gradient(135deg, #fff 0%, #f8f9fa 100%);
border: 12px solid transparent;
border-image: linear-gradient(45deg, #667eea, #764ba2, #f093fb, #4facfe) 1;
box-sizing: border-box;
overflow: hidden;
margin-bottom: 25px;
box-shadow: 0 8px 32px rgba(0,0,0,0.1);
}
.certificate-content {
position: relative;
z-index: 1;
padding: 25px;
width: 100%;
height: 100%;
box-sizing: border-box;
display: flex;
flex-direction: column;
justify-content: space-between;
}
.certificate-header {
display: flex;
justify-content: space-between;
align-items: flex-start;
}
.certificate-title {
flex-grow: 1;
text-align: center;
}
.certificate-logo {
width: 140px;
height: 70px;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
border-radius: 8px;
display: flex;
align-items: center;
justify-content: center;
color: white;
font-weight: bold;
font-size: 18px;
}
.certificate-footer {
display: flex;
justify-content: space-between;
align-items: flex-end;
}
.certificate-qr {
width: 120px;
height: 120px;
display: flex;
justify-content: center;
align-items: center;
background: #f9f9f9;
border: 2px solid #dee2e6;
border-radius: 8px;
}
.certificate-signature {
flex-grow: 1;
text-align: center;
}
.loading {
display: none;
margin-top: 15px;
font-style: italic;
color: #6c757d;
text-align: center;
}
.instruction-box {
background: linear-gradient(135deg, #fff3cd 0%, #ffeaa7 100%);
border: 2px solid #ffeaa7;
border-radius: 12px;
padding: 20px;
margin-bottom: 25px;
}
.theme-section {
margin-bottom: 35px;
padding: 25px;
background: linear-gradient(135deg, #f1f3f4 0%, #e8eaed 100%);
border-radius: 12px;
border-left: 6px solid #764ba2;
box-shadow: 0 4px 15px rgba(0,0,0,0.05);
}
.theme-title {
color: #764ba2;
font-size: 20px;
font-weight: bold;
margin-bottom: 20px;
text-transform: uppercase;
letter-spacing: 1px;
}
.multiple-choice-container {
display: grid;
gap: 10px;
}
.score-display {
font-size: 24px;
font-weight: bold;
color: #27ae60;
text-align: center;
margin: 20px 0;
padding: 15px;
background: linear-gradient(135deg, #d4f1de 0%, #c3e6cb 100%);
border-radius: 10px;
}
.input-text {
width: 100%;
padding: 12px;
border: 2px solid #667eea;
border-radius: 8px;
font-size: 16px;
margin: 10px 0;
}
📚 Quiz B1 – Révision Complète Langues Vivantes
Testez vos connaissances sur les pronoms relatifs, verbes d’opinion, indéfinis et l’hypothèse ! Inscrivez-vous pour commencer.
📚 Quiz B1 – Révision Complète
📋 Instructions: Ce quiz comprend 50 questions réparties en 5 parties :
- ✅ Partie 1: Vrai ou Faux (10 questions)
- 🔘 Partie 2: Choix Multiples (10 questions)
- ✍️ Partie 3: Complétez les conjugaisons (10 questions)
- ☑️ Partie 4: Réponses Multiples (10 questions)
- 📖 Partie 5: Vocabulaire (10 questions)
📊 Résultats de votre Quiz
🎓 Certificat de Réussite
CERTIFICAT D’EXCELLENCE
Révision Langues Vivantes B1
Ce certificat est décerné à
pour avoir complété avec succès le quiz B1
de révision complète des langues vivantes:
Pronoms Relatifs • Verbes d’Opinion • Indéfinis • Hypoth” value=”a”> dit
// Variables globales
let userData = {};
let answers = {};
let isVerified = false;
// Validation du formulaire
document.getElementById(‘startButton’).addEventListener(‘click’, function() {
const prenom = document.getElementById(‘prenom’).value.trim();
const nom = document.getElementById(‘nom’).value.trim();
const email = document.getElementById(‘email’).value.trim();
const subscribe = document.getElementById(‘subscribe’).checked;
// Reset erreurs
document.querySelectorAll(‘.error’).forEach(el => el.textContent = ”);
let isValid = true;
if (!prenom) {
document.getElementById(‘prenomError’).textContent = ‘Le prénom est requis’;
isValid = false;
}
if (!nom) {
document.getElementById(‘nomError’).textContent = ‘Le nom est requis’;
isValid = false;
}
if (!email) {
document.getElementById(‘emailError’).textContent = ‘L’email est requis’;
isValid = false;
} else if (!email.match(/^[^s@]+@[^s@]+.[^s@]+$/)) {
document.getElementById(‘emailError’).textContent = ‘Email invalide’;
isValid = false;
}
if (!subscribe) {
document.getElementById(‘subscribeError’).textContent = ‘Vous devez accepter de vous abonner’;
isValid = false;
}
if (isValid) {
userData = { prenom, nom, email };
document.getElementById(‘subscriptionForm’).style.display = ‘none’;
document.getElementById(‘exerciseContainer’).style.display = ‘block’;
window.scrollTo(0, 0);
}
});
// Fonction pour normaliser les réponses textuelles
function normalizeText(text) {
return text.toLowerCase()
.trim()
.normalize(“NFD”)
.replace(/[u0300-u036f]/g, “”); // Enlève les accents
}
// Vérification des réponses
document.getElementById(‘verifyButton’).addEventListener(‘click’, function() {
if (isVerified) {
alert(‘Vous avez déjà vérifié vos réponses !’);
return;
}
const questions = document.querySelectorAll(‘.question’);
let score = 0;
let mistakes = [];
questions.forEach((question, index) => {
const questionNumber = index + 1;
const correctAnswer = question.dataset.answer;
const questionType = question.dataset.type;
const questionText = question.querySelector(‘.question-text’).textContent;
if (questionType === ‘single’) {
// Questions à choix unique (radio)
const selectedOption = question.querySelector(‘input[type=”radio”]:checked’);
if (selectedOption) {
const userAnswer = selectedOption.value;
if (userAnswer === correctAnswer) {
score++;
selectedOption.parentElement.classList.add(‘correct’);
} else {
selectedOption.parentElement.classList.add(‘incorrect’);
// Montrer la bonne réponse
const correctOption = question.querySelector(`input[value=”${correctAnswer}”]`);
if (correctOption) {
correctOption.parentElement.classList.add(‘correct-answer’);
}
mistakes.push({
question: questionNumber,
text: questionText,
userAnswer: selectedOption.parentElement.textContent.trim(),
correctAnswer: correctOption ? correctOption.parentElement.textContent.trim() : correctAnswer
});
}
} else {
// Aucune réponse sélectionnée
const correctOption = question.querySelector(`input[value=”${correctAnswer}”]`);
if (correctOption) {
correctOption.parentElement.classList.add(‘correct-answer’);
}
mistakes.push({
question: questionNumber,
text: questionText,
userAnswer: ‘Aucune réponse’,
correctAnswer: correctOption ? correctOption.parentElement.textContent.trim() : correctAnswer
});
}
} else if (questionType === ‘text’) {
// Questions à compléter
const input = question.querySelector(‘input[type=”text”]’);
const userAnswer = normalizeText(input.value);
const correctAnswerNormalized = normalizeText(correctAnswer);
if (userAnswer === correctAnswerNormalized) {
score++;
input.style.borderColor = ‘#28a745’;
input.style.backgroundColor = ‘#d4edda’;
} else {
input.style.borderColor = ‘#dc3545’;
input.style.backgroundColor = ‘#f8d7da’;
mistakes.push({
question: questionNumber,
text: questionText,
userAnswer: input.value || ‘Aucune réponse’,
correctAnswer: correctAnswer
});
}
} else if (questionType === ‘multiple’) {
// Questions à choix multiples (checkbox)
const selectedOptions = Array.from(question.querySelectorAll(‘input[type=”checkbox”]:checked’))
.map(cb => cb.value)
.sort()
.join(‘,’);
const correctAnswers = correctAnswer.split(‘,’).sort().join(‘,’);
if (selectedOptions === correctAnswers) {
score++;
question.querySelectorAll(‘input[type=”checkbox”]:checked’).forEach(cb => {
cb.parentElement.classList.add(‘correct’);
});
} else {
// Marquer les erreurs
question.querySelectorAll(‘input[type=”checkbox”]’).forEach(cb => {
const isSelected = cb.checked;
const shouldBeSelected = correctAnswer.split(‘,’).includes(cb.value);
if (isSelected && !shouldBeSelected) {
cb.parentElement.classList.add(‘incorrect’);
} else if (!isSelected && shouldBeSelected) {
cb.parentElement.classList.add(‘correct-answer’);
} else if (isSelected && shouldBeSelected) {
cb.parentElement.classList.add(‘correct’);
}
});
const correctLabels = correctAnswer.split(‘,’).map(val => {
const option = question.querySelector(`input[value=”${val}”]`);
return option ? option.parentElement.textContent.trim() : val;
}).join(‘, ‘);
mistakes.push({
question: questionNumber,
text: questionText,
userAnswer: selectedOptions ? selectedOptions : ‘Aucune réponse’,
correctAnswer: correctLabels
});
}
}
});
// Afficher les résultats
const percentage = (score / 50 * 100).toFixed(1);
document.getElementById(‘scoreDisplay’).textContent = `${score}/50 (${percentage}%)`;
let resultMessage = ”;
if (percentage >= 90) {
resultMessage = ‘🎉 Excellent ! Vous maîtrisez parfaitement le niveau B1 !’;
document.getElementById(‘showCertificateButton’).style.display = ‘inline-block’;
} else if (percentage >= 75) {
resultMessage = ‘👏 Très bien ! Vous avez un bon niveau B1 !’;
document.getElementById(‘showCertificateButton’).style.display = ‘inline-block’;
} else if (percentage >= 60) {
resultMessage = ‘👍 Bien ! Continuez à pratiquer pour améliorer votre niveau.’;
} else {
resultMessage = ‘📚 Continuez à étudier. Révisez les points faibles identifiés ci-dessous.’;
}
document.getElementById(‘resultText’).textContent = resultMessage;
// Afficher les erreurs
if (mistakes.length > 0) {
let mistakesHTML = ‘
❌ Questions à revoir:
‘;
mistakesHTML += ‘
mistakes.forEach(mistake => {
mistakesHTML += `
Votre réponse: ${mistake.userAnswer}
Réponse correcte: ${mistake.correctAnswer}
`;
});
mistakesHTML += ‘
‘;
document.getElementById(‘mistakesContainer’).innerHTML = mistakesHTML;
}
document.getElementById(‘resultContainer’).style.display = ‘block’;
document.getElementById(‘verifyButton’).style.display = ‘none’;
// Mise à jour de la barre de progression
document.getElementById(‘progressFill’).style.width = percentage + ‘%’;
isVerified = true;
// Scroll vers les résultats
document.getElementById(‘resultContainer’).scrollIntoView({ behavior: ‘smooth’, block: ‘center’ });
});
// Afficher le certificat
document.getElementById(‘showCertificateButton’).addEventListener(‘click’, function() {
const fullName = `${userData.prenom} ${userData.nom}`;
document.getElementById(‘certificateName’).textContent = fullName;
const score = document.getElementById(‘scoreDisplay’).textContent;
document.getElementById(‘certificateScore’).textContent = `Score: ${score}`;
const today = new Date();
const dateStr = today.toLocaleDateString(‘fr-FR’, {
year: ‘numeric’,
month: ‘long’,
day: ‘numeric’
});
document.getElementById(‘certificateDate’).textContent = `Délivré le ${dateStr}`;
document.getElementById(‘certificateContainer’).style.display = ‘block’;
document.getElementById(‘certificateContainer’).scrollIntoView({ behavior: ‘smooth’, block: ‘center’ });
});
// Télécharger le certificat en PDF
document.getElementById(‘downloadCertificate’).addEventListener(‘click’, async function() {
const loadingMessage = document.getElementById(‘loadingMessage’);
loadingMessage.style.display = ‘block’;
try {
const certificateElement = document.getElementById(‘certificatePreview’);
// Utiliser html2canvas pour capturer le certificat
const canvas = await html2canvas(certificateElement, {
scale: 2,
backgroundColor: ‘#ffffff’,
logging: false
});
// Créer le PDF avec jsPDF
const { jsPDF } = window.jspdf;
const pdf = new jsPDF({
orientation: ‘landscape’,
unit: ‘mm’,
format: ‘a4’
});
const imgData = canvas.toDataURL(‘image/png’);
const imgWidth = 297; // A4 landscape width in mm
const imgHeight = (canvas.height * imgWidth) / canvas.width;
pdf.addImage(imgData, ‘PNG’, 0, 0, imgWidth, imgHeight);
pdf.save(`Certificat_B1_${userData.prenom}_${userData.nom}.pdf`);
loadingMessage.style.display = ‘none’;
} catch (error) {
console.error(‘Erreur lors de la génération du PDF:’, error);
alert(‘Erreur lors de la génération du PDF. Veuillez réessayer.’);
loadingMessage.style.display = ‘none’;
}
});
// Mise à jour de la barre de progression en temps réel
document.querySelectorAll(‘input[type=”radio”], input[type=”checkbox”], input[type=”text”]’).forEach(input => {
input.addEventListener(‘change’, updateProgress);
if (input.type === ‘text’) {
input.addEventListener(‘input’, updateProgress);
}
});
function updateProgress() {
if (isVerified) return;
const totalQuestions = 50;
let answeredQuestions = 0;
// Compter les questions répondues
document.querySelectorAll(‘.question’).forEach(question => {
const questionType = question.dataset.type;
if (questionType === ‘single’) {
if (question.querySelector(‘input[type=”radio”]:checked’)) {
answeredQuestions++;
}
} else if (questionType === ‘text’) {
const input = question.querySelector(‘input[type=”text”]’);
if (input && input.value.trim() !== ”) {
answeredQuestions++;
}
} else if (questionType === ‘multiple’) {
if (question.querySelector(‘input[type=”checkbox”]:checked’)) {
answeredQuestions++;
}
}
});
const percentage = (answeredQuestions / totalQuestions * 100).toFixed(1);
document.getElementById(‘progressFill’).style.width = percentage + ‘%’;
}