Preuve de Test

body {
font-family: ‘Arial’, sans-serif;
line-height: 1.6;
max-width: 100%;
margin: 0 auto;
padding: 20px;
color: #333;
}

h1, h2 {
color: #0066cc;
text-align: center;
}

.intro {
background-color: #f0f8ff;
padding: 15px;
border-radius: 8px;
margin-bottom: 20px;
}

.question-container {
margin-bottom: 20px;
padding: 15px;
border: 1px solid #ddd;
border-radius: 8px;
background-color: #f9f9f9;
}

.options {
margin-top: 10px;
}

button {
background-color: #0066cc;
color: white;
border: none;
padding: 10px 15px;
border-radius: 5px;
cursor: pointer;
margin-top: 10px;
}

button:hover {
background-color: #004c99;
}

input[type=”text”], textarea {
width: 100%;
padding: 8px;
margin-top: 5px;
border: 1px solid #ddd;
border-radius: 4px;
}

textarea {
min-height: 100px;
}

.result-section {
display: none;
text-align: center;
margin-top: 20px;
}

.badge {
border: 2px solid #0066cc;
padding: 20px;
margin: 20px auto;
text-align: center;
background-color: #f0f8ff;
max-width: 500px;
box-shadow: 0 0 10px rgba(0,0,0,0.1);
border-radius: 10px;
}

.progress-container {
width: 100%;
background-color: #ddd;
margin-bottom: 20px;
border-radius: 5px;
}

.progress-bar {
height: 20px;
background-color: #0066cc;
border-radius: 5px;
width: 0%;
text-align: center;
line-height: 20px;
color: white;
}

.controls {
display: flex;
justify-content: center;
margin-top: 15px;
}

#email-form {
margin-top: 20px;
display: none;
}

.stamp {
width: 100px;
height: 100px;
border: 2px solid #0066cc;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
margin: 20px auto;
background-color: #e6f0ff;
font-weight: bold;
color: #0066cc;
transform: rotate(-15deg);
}

#badge {
border: 5px solid #0066cc;
border-radius: 10px;
padding: 20px;
max-width: 800px;
margin: 20px auto;
background-color: #f9f9f9;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
position: relative;
}

#grade-stamp {
position: absolute;
top: 20px;
right: 20px;
width: 60px;
height: 60px;
background-color: #e63946;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
color: white;
font-size: 24px;
font-weight: bold;
border: 3px solid #333;
transform: rotate(15deg);
}

#email-status {
padding: 10px;
background-color: #dff0d8;
border: 1px solid #d6e9c6;
border-radius: 4px;
color: #3c763d;
margin-top: 15px;
display: none;
}

.certificate-header {
text-align: center;
margin-bottom: 20px;
}

.certificate-header h2 {
color: #0066cc;
font-size: 28px;
margin-bottom: 5px;
}

.certificate-header p {
font-style: italic;
color: #666;
}

.certificate-body {
margin: 20px 0;
text-align: center;
}

.certificate-signature {
margin-top: 40px;
text-align: center;
}

.signature-line {
width: 200px;
height: 1px;
background-color: #333;
margin: 10px auto;
}

.timer {
position: fixed;
top: 20px;
right: 20px;
background-color: #0066cc;
color: white;
padding: 15px;
border-radius: 50%;
width: 100px;
height: 100px;
display: flex;
align-items: center;
justify-content: center;
font-size: 24px;
font-weight: bold;
box-shadow: 0 4px 8px rgba(0,0,0,0.2);
z-index: 1000;
}

.texte-comprehension {
background-color: #fff;
padding: 20px;
border-left: 5px solid #0066cc;
margin-bottom: 20px;
line-height: 1.8;
}

.aplenguas-login-form {
max-width: 100%;
margin: 0 auto;
padding: 20px;
background-color: #f9f9f9;
border-radius: 8px;
box-shadow: 0 2px 5px rgba(0,0,0,0.1);
}

.form-group {
margin-bottom: 15px;
}

.form-group label {
display: block;
margin-bottom: 5px;
font-weight: bold;
}

.form-group input {
width: 100%;
padding: 8px;
border: 1px solid #ddd;
border-radius: 4px;
}

.btn-submit {
background-color: #4285f4;
color: white;
border: none;
padding: 10px 15px;
border-radius: 4px;
cursor: pointer;
}

#continuar {
background-color: #34a853;
color: white;
border: none;
padding: 10px 15px;
border-radius: 4px;
cursor: pointer;
margin-top: 10px;
}

1:30:00

Examen de Français A2, ESIT Groupe 627 – L’Éducation

Cette évaluation porte sur le thème de l’éducation et les contenus du manuel Défi 2. L’examen est noté sur 100 points.

0%

Résultats de l’évaluation

Nom:

Prénom:

Score: /100

Commentaire:

Certificat de Réussite

ESIT – Évaluation de Français A2

Ce certificat atteste que

a complété avec succès l’évaluation de français avec un score de

sur un total de 100 points

Signature du professeur

Envoyer le certificat par email

// Script para el formulario de inicio de sesión
const SCRIPT_URL = ‘https://script.google.com/macros/s/AKfycbySKFDJZ7MwZUvEdMbMIJAvsamQHhmvJhrW3xW_mWbClvummp_jBSYu78IAyWv9QLWUGA/exec’;

document.getElementById(‘login-form’).addEventListener(‘submit’, function(e) {
e.preventDefault();

const email = document.getElementById(‘email’).value;
const nombre = document.getElementById(‘nombre’).value;
const curso = document.getElementById(‘curso’).value;

// Mostrar estado de procesamiento
document.getElementById(‘estado-envio’).style.display = ‘block’;
document.getElementById(‘mensaje-estado’).innerText = ‘Enviando datos…’;

// Guardar los datos localmente
sessionStorage.setItem(‘student_email’, email);
sessionStorage.setItem(‘student_name’, nombre);
sessionStorage.setItem(‘student_course’, curso);

// Enviar datos al servidor usando fetch
const formData = new FormData();
formData.append(‘email’, email);
formData.append(‘nombre’, nombre);
formData.append(‘curso’, curso);
formData.append(‘accion’, ‘iniciar’); // Indica que es inicio de sesión

fetch(SCRIPT_URL, {
method: ‘POST’,
body: formData,
mode: ‘no-cors’
})
.then(response => {
// No podemos acceder a la respuesta debido a no-cors,
// pero asumimos que funcionó si no hubo errores
document.getElementById(‘login-form’).style.display = ‘none’;
document.getElementById(‘mensaje-confirmacion’).style.display = ‘block’;
document.getElementById(‘estado-envio’).style.display = ‘none’;
})
.catch(error => {
console.error(‘Error:’, error);
document.getElementById(‘mensaje-estado’).innerText = ‘Error al enviar datos’;
document.getElementById(‘detalles-error’).innerText = error.message;
document.getElementById(‘detalles-error’).style.display = ‘block’;
});
});

document.getElementById(‘continuar’).addEventListener(‘click’, function() {
document.querySelector(‘.aplenguas-login-form’).style.display = ‘none’;
document.getElementById(‘contenido-ejercicio’).style.display = ‘block’;
});

// Variables globales para el examen
let currentQuestionIndex = 0;
let userAnswers = [];
let questionOrder = [];
let studentData = {};
let examTimer;
let timeLeft = 90 * 60; // 1h30 en segundos

// Función para actualizar el temporizador
function updateTimer() {
const hours = Math.floor(timeLeft / 3600);
const minutes = Math.floor((timeLeft % 3600) / 60);
const seconds = timeLeft % 60;

document.getElementById(‘exam-timer’).textContent =
(hours > 0 ? hours + ‘:’ : ”) +
(minutes < 10 ? '0' + minutes : minutes) + ':' +
(seconds < 10 ? '0' + seconds : seconds);

if (timeLeft <= 0) {
clearInterval(examTimer);
alert("Le temps est écoulé! L'examen va être terminé automatiquement.");
calculateResults();
} else {
timeLeft–;
}
}

// El texto de comprensión para la primera parte del examen (REDUCIDO)
const texteComprehension = `

L’éducation des filles dans le monde : défis et progrès

L’éducation des filles reste un défi majeur dans de nombreuses régions du monde. Selon l’UNESCO, plus de 130 millions de filles âgées de 6 à 17 ans ne sont pas scolarisées aujourd’hui.

Les obstacles incluent les traditions culturelles qui privilégient les garçons, les contraintes économiques, le manque d’infrastructures adaptées et les problèmes de sécurité sur le chemin de l’école. Les mariages précoces et les grossesses adolescentes interrompent également la scolarité des jeunes filles.

Pourtant, une fille éduquée a plus de chances d’être en bonne santé, d’avoir un revenu plus élevé et d’offrir de meilleures perspectives à ses enfants. Chaque année supplémentaire d’éducation secondaire réduit la probabilité de mariage précoce et augmente les futurs revenus de 10 à 20%.

Au niveau collectif, l’éducation des filles stimule la croissance économique. Si toutes les filles terminaient leur éducation secondaire, le nombre de mariages d’enfants pourrait diminuer de 64% et la mortalité infantile de près de 50%.

Des initiatives internationales, comme le programme “Éducation pour tous” de l’UNESCO, travaillent à éliminer ces obstacles. Certains pays ont adopté des politiques spécifiques, comme des bourses d’études pour les filles ou des campagnes de sensibilisation.

Si des progrès ont été réalisés ces dernières décennies, beaucoup reste à faire pour atteindre l’égalité d’accès à tous les niveaux d’éducation, particulièrement dans l’enseignement secondaire et supérieur.

`;

// Las preguntas de la evaluación
const questionsData = [
// Parte 1: Comprensión de lectura sobre la educación de las niñas
{
type: “text_intro”,
content: texteComprehension,
category: “Compréhension de lecture”
},
{
type: “qcm”,
question: “Selon le texte, combien de filles âgées de 6 à 17 ans ne sont pas scolarisées aujourd’hui?”,
options: [“Plus de 100 millions”, “Plus de 130 millions”, “Plus de 150 millions”, “Plus de 200 millions”],
correct: 1,
category: “Compréhension de lecture”,
points: 2.5
},
{
type: “qcm”,
question: “Parmi ces obstacles à l’éducation des filles, lequel n’est PAS mentionné dans le texte?”,
options: [“Les traditions culturelles”, “Le coût élevé des uniformes scolaires”, “Le manque d’infrastructures adaptées”, “Les mariages précoces”],
correct: 1,
category: “Compréhension de lecture”,
points: 2.5
},
{
type: “qcm”,
question: “Selon le texte, chaque année supplémentaire d’éducation secondaire augmente les futurs revenus de:”,
options: [“5 à 10%”, “10 à 20%”, “20 à 30%”, “30 à 40%”],
correct: 1,
category: “Compréhension de lecture”,
points: 2.5
},
{
type: “qcm”,
question: “Si toutes les filles terminaient leur éducation secondaire, de combien pourrait diminuer le nombre de mariages d’enfants?”,
options: [“44%”, “54%”, “64%”, “74%”],
correct: 2,
category: “Compréhension de lecture”,
points: 2.5
},
{
type: “choix_phrase”,
question: “Quelle affirmation est correcte selon le texte?”,
options: [
“L’éducation des filles est principalement importante pour leur développement personnel.”,
“Les pays qui investissent dans l’éducation des filles voient leur économie s’affaiblir.”,
“Les écarts entre les sexes sont plus importants dans l’enseignement primaire.”,
“L’éducation des filles stimule la croissance économique.”
],
correct: 3,
category: “Compréhension de lecture”,
points: 2.5
},
{
type: “text”,
question: “Citez un exemple de politique spécifique mentionnée dans le texte pour favoriser l’éducation des filles.”,
correct: “bourses d’études”,
acceptableAnswers: [“bourses d’études”, “campagnes de sensibilisation”],
category: “Compréhension de lecture”,
points: 2.5
},
{
type: “choix_phrase”,
question: “Selon le texte, dans quels niveaux d’éducation les écarts entre les sexes sont-ils les plus importants?”,
options: [
“Dans l’enseignement primaire”,
“Dans l’enseignement secondaire et supérieur”,
“Dans les programmes d’alphabétisation”,
“Dans l’enseignement préscolaire”
],
correct: 1,
category: “Compréhension de lecture”,
points: 2.5
},
{
type: “qcm”,
question: “Quel programme international est mentionné dans le texte pour lutter contre les obstacles à l’éducation des filles?”,
options: [“Éducation sans frontières”, “Éducation pour tous”, “Éducation des filles d’abord”, “Éducation mondiale”],
correct: 1,
category: “Compréhension de lecture”,
points: 2.5
},
{
type: “qcm”,
question: “Selon le texte, quel pourrait être l’impact de l’éducation des filles sur la mortalité infantile?”,
options: [“Une diminution de près de 25%”, “Une diminution de près de 50%”, “Une diminution de près de 75%”, “Une diminution de près de 100%”],
correct: 1,
category: “Compréhension de lecture”,
points: 2.5
},
{
type: “choix_phrase”,
question: “Selon le texte, quelles sont les conséquences d’une année supplémentaire d’éducation secondaire pour une fille?”,
options: [
“Elle aura plus d’enfants et sera en meilleure santé.”,
“Elle se mariera plus jeune et gagnera plus d’argent.”,
“Elle se mariera moins jeune et gagnera plus d’argent.”,
“Elle aura moins d’enfants mais gagnera moins d’argent.”
],
correct: 2,
category: “Compréhension de lecture”,
points: 2.5
},

// Parte 2: Expresión del deseo (reformulado sin subjonctif)
{
type: “text”,
question: “Complétez la phrase pour exprimer un souhait: “Je voudrais _____ accès à une meilleure éducation.””,
correct: “avoir”,
category: “Expression du souhait”,
points: 2.5
},
{
type: “text”,
question: “Complétez la phrase pour exprimer un souhait: “J’aimerais _____ dans une université à l’étranger.””,
correct: “étudier”,
category: “Expression du souhait”,
points: 2.5
},
{
type: “choix_phrase”,
question: “Choisissez la phrase qui exprime correctement un souhait:”,
options: [
“J’espère que tu réussis ton examen.”,
“J’espère que tu réussiras ton examen.”,
“J’espère que tu réussirais ton examen.”,
“J’espère réussir que ton examen.”
],
correct: 1,
category: “Expression du souhait”,
points: 2.5
},
{
type: “text”,
question: “Complétez la phrase pour exprimer un souhait: “Nous espérons _____ au programme d’échange l’année prochaine.””,
correct: “participer”,
category: “Expression du souhait”,
points: 2.5
},
{
type: “choix_phrase”,
question: “Choisissez la phrase qui exprime correctement un souhait:”,
options: [
“Elle voudra apprendre le français.”,
“Elle veut apprendre le français.”,
“Elle voudrait apprendre le français.”,
“Elle a voulu apprendre le français.”
],
correct: 2,
category: “Expression du souhait”,
points: 2.5
},

// Parte 3: Situar en el futuro (conjugación)
{
type: “text”,
question: “Conjuguez le verbe au futur simple: “L’année prochaine, nous _____ (aller) étudier à l’étranger.””,
correct: “irons”,
category: “Situer dans le futur”,
points: 2.5
},
{
type: “text”,
question: “Conjuguez le verbe au futur simple: “Dans dix ans, les technologies _____ (transformer) complètement l’éducation.””,
correct: “transformeront”,
category: “Situer dans le futur”,
points: 2.5
},
{
type: “choix_phrase”,
question: “Choisissez la phrase correctement conjuguée au futur simple:”,
options: [
“Je serais professeur après mes études.”,
“Je suis professeur après mes études.”,
“Je serai professeur après mes études.”,
“J’ai été professeur après mes études.”
],
correct: 2,
category: “Situer dans le futur”,
points: 2.5
},
{
type: “text”,
question: “Conjuguez le verbe au futur simple: “Tu _____ (avoir) plus d’opportunités avec un diplôme universitaire.””,
correct: “auras”,
category: “Situer dans le futur”,
points: 2.5
},
{
type: “choix_phrase”,
question: “Choisissez la phrase correctement conjuguée au futur simple:”,
options: [
“Ils font leurs examens la semaine prochaine.”,
“Ils feront leurs examens la semaine prochaine.”,
“Ils ont fait leurs examens la semaine prochaine.”,
“Ils faisaient leurs examens la semaine prochaine.”
],
correct: 1,
category: “Situer dans le futur”,
points: 2.5
},

// Parte 4: Condición con si+presente
{
type: “text”,
question: “Complétez avec le verbe au présent et au futur: “Si tu _____ (travailler) dur, tu _____ (réussir) tes examens.””,
correct: “travailles, réussiras”,
category: “Condition avec si+présent”,
points: 2.5
},
{
type: “text”,
question: “Complétez avec le verbe au présent et au présent: “Si vous _____ (vouloir) progresser, vous _____ (devoir) pratiquer tous les jours.””,
correct: “voulez, devez”,
category: “Condition avec si+présent”,
points: 2.5
},
{
type: “choix_phrase”,
question: “Choisissez la phrase correcte avec si+présent:”,
options: [
“Si j’aurai du temps, je lirai ce livre.”,
“Si j’ai du temps, je lirai ce livre.”,
“Si j’avais du temps, je lirai ce livre.”,
“Si j’ai du temps, je lis ce livre.”
],
correct: 1,
category: “Condition avec si+présent”,
points: 2.5
},
{
type: “text”,
question: “Complétez avec le verbe au présent et au futur simple: “Si les élèves _____ (être) attentifs, ils _____ (comprendre) mieux.””,
correct: “sont, comprendront”,
category: “Condition avec si+présent”,
points: 2.5
},
{
type: “choix_phrase”,
question: “Choisissez la phrase correcte avec si+présent:”,
options: [
“Si nous apprendrons le français, nous voyagerons en France.”,
“Si nous apprenons le français, nous voyagerons en France.”,
“Si nous apprenons le français, nous voyageons en France.”,
“Si nous avons appris le français, nous voyagerons en France.”
],
correct: 1,
category: “Condition avec si+présent”,
points: 2.5
},

// Parte 5: Vocabulario de la escuela y educación
{
type: “qcm”,
question: “Que signifie ‘redoubler’?”,
options: [“Obtenir deux fois la même note”, “Faire une année scolaire deux fois”, “Étudier deux fois plus”, “Être inscrit dans deux écoles différentes”],
correct: 1,
category: “Vocabulaire de l’école”,
points: 2.5
},
{
type: “qcm”,
question: “Complétez la phrase: ‘Pour réussir à l’école, il faut être _____ et travailler régulièrement.'”,
options: [“diplômé”, “assidu”, “redoublant”, “surveillant”],
correct: 1,
category: “Vocabulaire de l’école”,
points: 2.5
},
{
type: “qcm”,
question: “Qu’est-ce qu’un ‘emploi du temps’?”,
options: [“Un document qui indique les horaires des cours”, “Un travail à temps partiel”, “Une méthode pour gérer son temps”, “Un exercice chronométré”],
correct: 0,
category: “Vocabulaire de l’école”,
points: 2.5
},
{
type: “qcm”,
question: “Que signifie ‘être reçu à un examen’?”,
options: [“Être accueilli par l’examinateur”, “Recevoir ses notes”, “Avoir une bonne réception internet pendant l’examen”, “Réussir l’examen”],
correct: 3,
category: “Vocabulaire de l’école”,
points: 2.5
},
{
type: “qcm”,
question: “Qu’est-ce qu’une ‘matière’ dans le contexte scolaire?”,
options: [“Un sujet d’étude comme les mathématiques ou l’histoire”, “Le matériel scolaire”, “Une substance physique”, “La structure d’un établissement scolaire”],
correct: 0,
category: “Vocabulaire de l’école”,
points: 2.5
},

// Parte 6: Producción escrita
{
type: “essay”,
question: “Écrivez un texte de 80-100 mots sur le thème: ‘L’importance de l’éducation dans la vie’. Utilisez au moins 3 verbes au futur simple et 2 expressions de souhait.”,
category: “Production écrite”,
points: 20
}
];

// Función para iniciar el examen
document.getElementById(‘start-btn’).addEventListener(‘click’, function() {
this.style.display = ‘none’;
document.querySelector(‘.progress-container’).style.display = ‘block’;
document.querySelector(‘.controls’).style.display = ‘flex’;

// Iniciar temporizador
examTimer = setInterval(updateTimer, 1000);

// Recuperar datos del estudiante
studentData = {
email: sessionStorage.getItem(‘student_email’),
fullName: sessionStorage.getItem(‘student_name’),
course: sessionStorage.getItem(‘student_course’)
};

// Dividir nombre completo en nombre y apellido si es posible
const nameParts = studentData.fullName ? studentData.fullName.split(‘ ‘) : [‘Étudiant’, ”];
studentData.firstName = nameParts[0];
studentData.lastName = nameParts.slice(1).join(‘ ‘);

// Aleatorizar el orden de las preguntas excepto la introducción y el ensayo
const introQuestions = questionsData.filter(q => q.type === ‘text_intro’);
const essayQuestions = questionsData.filter(q => q.type === ‘essay’);
const regularQuestions = questionsData.filter(q => q.type !== ‘text_intro’ && q.type !== ‘essay’);

// Mezclar las preguntas regulares
for (let i = regularQuestions.length – 1; i > 0; i–) {
const j = Math.floor(Math.random() * (i + 1));
[regularQuestions[i], regularQuestions[j]] = [regularQuestions[j], regularQuestions[i]];
}

// Combinar todas las preguntas en el orden correcto
questionOrder = […introQuestions, …regularQuestions, …essayQuestions];

// Inicializar array de respuestas del usuario
userAnswers = new Array(questionOrder.length).fill(null);

// Mostrar la primera pregunta
showQuestion(0);
});

// Función para mostrar una pregunta
function showQuestion(index) {
if (index >= questionOrder.length) {
calculateResults();
return;
}

currentQuestionIndex = index;
const question = questionOrder[index];
const questionArea = document.getElementById(‘question-area’);
questionArea.innerHTML = ”;

// Actualizar la barra de progreso
const progressPercent = Math.round((index / questionOrder.length) * 100);
document.querySelector(‘.progress-bar’).style.width = progressPercent + ‘%’;
document.querySelector(‘.progress-bar’).textContent = progressPercent + ‘%’;

// Crear el contenedor de la pregunta
const questionContainer = document.createElement(‘div’);
questionContainer.className = ‘question-container’;

// Si es un texto introductorio
if (question.type === ‘text_intro’) {
const header = document.createElement(‘h2’);
header.textContent = ‘Partie 1: ‘ + question.category;
questionContainer.appendChild(header);

const content = document.createElement(‘div’);
content.innerHTML = question.content;
questionContainer.appendChild(content);
}
// Si es una pregunta de opción múltiple
else if (question.type === ‘qcm’ || question.type === ‘choix_phrase’) {
const header = document.createElement(‘h3’);
header.textContent = ‘Question ‘ + (index + 1) + ‘ – ‘ + question.category;
questionContainer.appendChild(header);

const questionText = document.createElement(‘p’);
questionText.textContent = question.question;
questionContainer.appendChild(questionText);

const optionsDiv = document.createElement(‘div’);
optionsDiv.className = ‘options’;

question.options.forEach((option, optionIndex) => {
const optionLabel = document.createElement(‘label’);
optionLabel.style.display = ‘block’;
optionLabel.style.margin = ’10px 0′;

const optionInput = document.createElement(‘input’);
optionInput.type = ‘radio’;
optionInput.name = ‘q’ + index;
optionInput.value = optionIndex;
optionInput.checked = userAnswers[index] === optionIndex;
optionInput.addEventListener(‘change’, () => {
userAnswers[index] = optionIndex;
});

optionLabel.appendChild(optionInput);
optionLabel.appendChild(document.createTextNode(‘ ‘ + option));
optionsDiv.appendChild(optionLabel);
});

questionContainer.appendChild(optionsDiv);
}
// Si es una pregunta de texto libre
else if (question.type === ‘text’) {
const header = document.createElement(‘h3’);
header.textContent = ‘Question ‘ + (index + 1) + ‘ – ‘ + question.category;
questionContainer.appendChild(header);

const questionText = document.createElement(‘p’);
questionText.textContent = question.question;
questionContainer.appendChild(questionText);

const answerInput = document.createElement(‘input’);
answerInput.type = ‘text’;
answerInput.value = userAnswers[index] || ”;
answerInput.addEventListener(‘input’, (e) => {
userAnswers[index] = e.target.value;
});

questionContainer.appendChild(answerInput);
}
// Si es un ensayo
else if (question.type === ‘essay’) {
const header = document.createElement(‘h3’);
header.textContent = ‘Question ‘ + (index + 1) + ‘ – ‘ + question.category + ‘ (‘ + question.points + ‘ points)’;
questionContainer.appendChild(header);

const questionText = document.createElement(‘p’);
questionText.textContent = question.question;
questionContainer.appendChild(questionText);

const answerTextarea = document.createElement(‘textarea’);
answerTextarea.value = userAnswers[index] || ”;
answerTextarea.addEventListener(‘input’, (e) => {
userAnswers[index] = e.target.value;
});

questionContainer.appendChild(answerTextarea);

// Contador de palabras
const wordCounter = document.createElement(‘div’);
wordCounter.textContent = ‘Mots: 0′;
wordCounter.style.marginTop = ’10px’;
questionContainer.appendChild(wordCounter);

answerTextarea.addEventListener(‘input’, (e) => {
const text = e.target.value;
const wordCount = text.trim() ? text.trim().split(/s+/).length : 0;
wordCounter.textContent = ‘Mots: ‘ + wordCount;
});
}

questionArea.appendChild(questionContainer);
}

// Función para pasar a la siguiente pregunta
document.getElementById(‘next-btn’).addEventListener(‘click’, function() {
showQuestion(currentQuestionIndex + 1);
});

// Función para calcular los resultados
function calculateResults() {
clearInterval(examTimer); // Detener el temporizador

// Ocultar áreas de preguntas y controles
document.getElementById(‘question-area’).style.display = ‘none’;
document.querySelector(‘.controls’).style.display = ‘none’;
document.querySelector(‘.progress-container’).style.display = ‘none’;
document.getElementById(‘exam-timer’).style.display = ‘none’;

// Mostrar sección de resultados
document.getElementById(‘result-section’).style.display = ‘block’;

// Calcular puntuación
let totalScore = 0;
let possibleScore = 0;

questionOrder.forEach((question, index) => {
if (question.type !== ‘text_intro’) {
possibleScore += question.points;

if (question.type === ‘qcm’ || question.type === ‘choix_phrase’) {
if (userAnswers[index] === question.correct) {
totalScore += question.points;
}
} else if (question.type === ‘text’) {
const userAnswer = (userAnswers[index] || ”).trim().toLowerCase();
if (question.acceptableAnswers) {
const isCorrect = question.acceptableAnswers.some(ans => userAnswer.includes(ans.toLowerCase()));
if (isCorrect) totalScore += question.points;
} else {
const correctAnswer = question.correct.toLowerCase();
if (userAnswer === correctAnswer) totalScore += question.points;
}
} else if (question.type === ‘essay’ && userAnswers[index]) {
// Asignar puntos basado en longitud (simplificado)
const wordCount = userAnswers[index].trim().split(/s+/).length;
if (wordCount >= 80) {
totalScore += question.points * 0.8; // 80% por longitud

// Buscar verbos en futuro simple
const futurVerbs = [
“serai”, “seras”, “sera”, “serons”, “serez”, “seront”,
“aurai”, “auras”, “aura”, “aurons”, “aurez”, “auront”,
“ferai”, “feras”, “fera”, “ferons”, “ferez”, “feront”,
“irai”, “iras”, “ira”, “irons”, “irez”, “iront”
];

let futurVerbCount = 0;
futurVerbs.forEach(verb => {
const regex = new RegExp(“\b” + verb + “\b”, “gi”);
const matches = userAnswers[index].match(regex);
if (matches) futurVerbCount += matches.length;
});

// Buscar expresiones de deseo
const wishExpressions = [
“j’aimerais”, “je voudrais”, “j’espère”, “nous aimerions”,
“nous voudrions”, “nous espérons”, “tu aimerais”, “tu voudrais”,
“il aimerait”, “elle aimerait”, “ils aimeraient”, “elles aimeraient”
];

let wishCount = 0;
wishExpressions.forEach(expr => {
const regex = new RegExp(“\b” + expr + “\b”, “gi”);
const matches = userAnswers[index].match(regex);
if (matches) wishCount += matches.length;
});

// Calcular puntos adicionales (simplificado)
if (futurVerbCount >= 3) totalScore += question.points * 0.1;
if (wishCount >= 2) totalScore += question.points * 0.1;
}
}
}
});

// Redondear a 2 decimales
totalScore = Math.round(totalScore * 100) / 100;

// Mostrar resultados
document.getElementById(‘result-nom’).textContent = studentData.lastName || ”;
document.getElementById(‘result-prenom’).textContent = studentData.firstName || ”;
document.getElementById(‘score’).textContent = totalScore;

// Generar comentario basado en la puntuación
let feedback;
if (totalScore >= 90) {
feedback = “Excellent ! Tu as très bien maîtrisé les concepts du cours.”;
} else if (totalScore >= 75) {
feedback = “Très bien ! Tu as une bonne compréhension des concepts du cours.”;
} else if (totalScore >= 60) {
feedback = “Bien ! Continue à travailler pour améliorer ta compréhension.”;
} else if (totalScore >= 50) {
feedback = “Passable. Il faut revoir certains concepts pour mieux les comprendre.”;
} else {
feedback = “Il faut retravailler les concepts du cours. N’hésite pas à demander de l’aide.”;
}
document.getElementById(‘feedback’).textContent = feedback;

// Actualizar certificado
document.getElementById(‘cert-prenom’).textContent = studentData.firstName || ”;
document.getElementById(‘cert-nom’).textContent = studentData.lastName || ”;
document.getElementById(‘cert-score’).textContent = totalScore + ‘/100’;

// Agregar fecha actual
const today = new Date();
const options = { year: ‘numeric’, month: ‘long’, day: ‘numeric’ };
document.getElementById(‘cert-date’).textContent = “Date: ” + today.toLocaleDateString(‘fr-FR’, options);

// Mostrar sello de calificación
const gradeStamp = document.getElementById(‘grade-stamp’);
let grade;
if (totalScore >= 90) grade = “A+”;
else if (totalScore >= 85) grade = “A”;
else if (totalScore >= 80) grade = “A-“;
else if (totalScore >= 75) grade = “B+”;
else if (totalScore >= 70) grade = “B”;
else if (totalScore >= 65) grade = “B-“;
else if (totalScore >= 60) grade = “C+”;
else if (totalScore >= 55) grade = “C”;
else if (totalScore >= 50) grade = “C-“;
else grade = “F”;

gradeStamp.textContent = grade;

// Enviar resultados al servidor
sendResults(totalScore);
}

// Función para enviar los resultados al servidor
function sendResults(score) {
const formData = new FormData();
formData.append(‘email’, studentData.email);
formData.append(‘nombre’, studentData.fullName);
formData.append(‘curso’, studentData.course);
formData.append(‘nota’, score);
formData.append(‘accion’, ‘finalizar’); // Indica que es fin del examen

fetch(SCRIPT_URL, {
method: ‘POST’,
body: formData,
mode: ‘no-cors’
});
}

// Función para descargar el certificado
document.getElementById(‘download-badge’).addEventListener(‘click’, function() {
const { jsPDF } = window.jspdf;

html2canvas(document.getElementById(‘badge’)).then(canvas => {
const imgData = canvas.toDataURL(‘image/png’);
const pdf = new jsPDF(‘l’, ‘mm’, ‘a4’);
const imgProps = pdf.getImageProperties(imgData);
const pdfWidth = pdf.internal.pageSize.getWidth();
const pdfHeight = (imgProps.height * pdfWidth) / imgProps.width;

pdf.addImage(imgData, ‘PNG’, 0, 0, pdfWidth, pdfHeight);
pdf.save(‘certificat-francais-a2.pdf’);
});
});

// Mostrar/ocultar formulario de correo electrónico
document.getElementById(‘show-email-form’).addEventListener(‘click’, function() {
const emailForm = document.getElementById(‘email-form’);
emailForm.style.display = emailForm.style.display === ‘none’ ? ‘block’ : ‘none’;
});

// Enviar certificado por correo electrónico
document.getElementById(‘send-email’).addEventListener(‘click’, function() {
const recipientEmail = document.getElementById(‘recipient-email’).value;
const emailStatus = document.getElementById(‘email-status’);

if (!recipientEmail) {
emailStatus.textContent = “Veuillez entrer une adresse email valide.”;
emailStatus.style.display = ‘block’;
emailStatus.style.backgroundColor = ‘#f8d7da’;
emailStatus.style.color = ‘#721c24’;
return;
}

// Capturar el certificado como imagen y enviar por correo electrónico
html2canvas(document.getElementById(‘badge’)).then(canvas => {
const imgData = canvas.toDataURL(‘image/png’);

const formData = new FormData();
formData.append(‘recipient’, recipientEmail);
formData.append(‘studentName’, studentData.fullName);
formData.append(‘course’, studentData.course);
formData.append(‘score’, document.getElementById(‘score’).textContent);
formData.append(‘certificate’, imgData);
formData.append(‘accion’, ‘enviar_certificado’);

emailStatus.textContent = “Envoi en cours…”;
emailStatus.style.display = ‘block’;
emailStatus.style.backgroundColor = ‘#fff3cd’;
emailStatus.style.color = ‘#856404’;

fetch(SCRIPT_URL, {
method: ‘POST’,
body: formData,
mode: ‘no-cors’
})
.then(() => {
emailStatus.textContent = “Certificat envoyé avec succès !”;
emailStatus.style.backgroundColor = ‘#d4edda’;
emailStatus.style.color = ‘#155724’;
})
.catch(error => {
emailStatus.textContent = “Erreur lors de l’envoi: ” + error.message;
emailStatus.style.backgroundColor = ‘#f8d7da’;
emailStatus.style.color = ‘#721c24’;
});
});
});