526 lines
24 KiB
JavaScript
526 lines
24 KiB
JavaScript
|
|
document.addEventListener('DOMContentLoaded', () => {
|
|
const app = document.getElementById('app');
|
|
const screens = {
|
|
start: document.getElementById('start-screen'),
|
|
question: document.getElementById('question-screen'),
|
|
result: document.getElementById('result-screen'),
|
|
};
|
|
|
|
const buttons = {
|
|
sex: document.querySelectorAll('.sex-card'),
|
|
back: document.getElementById('btn-back'),
|
|
reset: document.getElementById('btn-reset'),
|
|
next: document.getElementById('btn-next'),
|
|
print: document.getElementById('btn-print'),
|
|
};
|
|
|
|
const questionElements = {
|
|
container: document.getElementById('question-container'),
|
|
form: document.getElementById('question-form'),
|
|
progressText: document.getElementById('progress-text'),
|
|
progressFill: document.getElementById('progress-fill'),
|
|
validation: document.getElementById('validation-message'),
|
|
};
|
|
|
|
const resultElements = {
|
|
title: document.getElementById('result-title'),
|
|
content: document.getElementById('result-content'),
|
|
printSummary: document.getElementById('print-summary-content'),
|
|
};
|
|
|
|
let state = {
|
|
sex: null, // 'male' or 'female'
|
|
currentQuestionIndex: 0,
|
|
answers: [], // { questionId, answerValue }
|
|
history: [], // previous question indices
|
|
height: { value: null, unit: 'cm' },
|
|
weight: { value: null, unit: 'kg' },
|
|
};
|
|
|
|
const data = {
|
|
female: [
|
|
{ id: 'F1', text: 'Cum este menstruația ta?', help: 'Alege o singură variantă.', type: 'radio', options: [
|
|
{ text: 'Regulată, fără dureri sau disconfort', value: 0 },
|
|
{ text: 'Neregulată, dar fără alte simptome', value: 1 },
|
|
{ text: 'Dureri, crampe, cheaguri, sângerări abundente', value: 2 },
|
|
{ text: 'Am intrat la menopauză', value: 3, next: 'F2' },
|
|
]},
|
|
{ id: 'F1.1', text: 'Ai sindrom premenstrual (dureri de sâni, iritabilitate, balonare)?', type: 'radio', options: [
|
|
{ text: 'Nu, niciodată', value: 0 },
|
|
{ text: 'Uneori, dar ușor', value: 1 },
|
|
{ text: 'Da, intens și frecvent', value: 2 },
|
|
]},
|
|
{ id: 'F2', text: 'Ai simptome specifice menopauzei (bufeuri, transpirații nocturne, uscăciune vaginală)?', type: 'radio', options: [
|
|
{ text: 'Nu / Nu este cazul', value: 0 },
|
|
{ text: 'Da, moderate', value: 1 },
|
|
{ text: 'Da, severe și frecvente', value: 2 },
|
|
]},
|
|
// Common questions start here, but can be specific if needed
|
|
...getCommonQuestions('female'),
|
|
],
|
|
male: [
|
|
{ id: 'M1', text: 'Ai probleme cu urinarea (jet slab, urinări frecvente/nocturne)?', type: 'radio', options: [
|
|
{ text: 'Nu, deloc', value: 0 },
|
|
{ text: 'Uneori sau moderat', value: 1 },
|
|
{ text: 'Da, frecvent și deranjant', value: 2 },
|
|
]},
|
|
{ id: 'M2', text: 'Ai observat o scădere a libidoului sau a performanței sexuale?', type: 'radio', options: [
|
|
{ text: 'Nu, totul este normal', value: 0 },
|
|
{ text: 'O scădere ușoară', value: 1 },
|
|
{ text: 'O scădere semnificativă', value: 2 },
|
|
]},
|
|
...getCommonQuestions('male'),
|
|
],
|
|
};
|
|
|
|
function getCommonQuestions(sex) {
|
|
return [
|
|
{ id: 'C1', text: 'Cum este nivelul tău de energie pe parcursul zilei?', type: 'radio', options: [
|
|
{ text: 'Constant și ridicat', value: 0 },
|
|
{ text: 'Scade după-amiaza, dar îmi revin', value: 1 },
|
|
{ text: 'Scăzut, oboseală cronică', value: 2 },
|
|
]},
|
|
{ id: 'C2', text: 'Cum dormi?', help: 'Poți alege mai multe variante.', type: 'checkbox', options: [
|
|
{ text: 'Adorm greu sau mă trezesc des', value: 1 },
|
|
{ text: 'Nu mă simt odihnit dimineața', value: 1 },
|
|
{ text: 'Sforăi sau am apnee în somn', value: 1 },
|
|
{ text: 'Dorm bine și mă simt odihnit (bifează doar aceasta)', value: 0, exclusive: true },
|
|
]},
|
|
{ id: 'C3', text: 'Cum este digestia ta?', help: 'Poți alege mai multe variante.', type: 'checkbox', options: [
|
|
{ text: 'Balonare, gaze, disconfort abdominal', value: 1 },
|
|
{ text: 'Constipație sau diaree frecventă', value: 1 },
|
|
{ text: 'Arsuri la stomac, reflux acid', value: 1 },
|
|
{ text: 'Digestie normală, fără probleme (bifează doar aceasta)', value: 0, exclusive: true },
|
|
]},
|
|
{ id: 'C4', text: 'Cum reacționezi la stres?', type: 'radio', options: [
|
|
{ text: 'Calm, gestionez bine situațiile', value: 0 },
|
|
{ text: 'Anxios, iritabil, copleșit', value: 1 },
|
|
{ text: 'Apatie, lipsă de motivație', value: 2 },
|
|
]},
|
|
{ id: 'C5', text: 'Ai pofte alimentare necontrolate (dulciuri, carbohidrați, sărat)?', type: 'radio', options: [
|
|
{ text: 'Rareori sau deloc', value: 0 },
|
|
{ text: 'Uneori, mai ales la stres', value: 1 },
|
|
{ text: 'Frecvent și intens', value: 2 },
|
|
]},
|
|
{ id: 'C6', text: 'Cum este pielea, părul și unghiile tale?', help: 'Poți alege mai multe variante.', type: 'checkbox', options: [
|
|
{ text: 'Piele uscată, păr fragil, unghii casante', value: 1 },
|
|
{ text: 'Acnee, ten gras, mătreață', value: 1 },
|
|
{ text: 'Căderea excesivă a părului', value: 1 },
|
|
{ text: 'Aspect sănătos, fără probleme (bifează doar aceasta)', value: 0, exclusive: true },
|
|
]},
|
|
{ id: 'C7', text: 'Ai dureri articulare sau musculare inexplicabile?', type: 'radio', options: [
|
|
{ text: 'Nu', value: 0 },
|
|
{ text: 'Da, ocazional', value: 1 },
|
|
{ text: 'Da, cronice și răspândite', value: 2 },
|
|
]},
|
|
{ id: 'C8', text: 'Cum este starea ta de spirit generală?', type: 'radio', options: [
|
|
{ text: 'Bună, optimistă', value: 0 },
|
|
{ text: 'Variabilă, cu episoade de tristețe', value: 1 },
|
|
{ text: 'Predominant tristă, apatică', value: 2 },
|
|
]},
|
|
{ id: 'HW', text: 'Introdu înălțimea și greutatea ta.', type: 'hw' },
|
|
];
|
|
}
|
|
|
|
const results = {
|
|
A: {
|
|
title: "HealthType A: Vitalitate Optimă",
|
|
description: "Profilul tău indică un echilibru hormonal și metabolic excelent. Ai o bază solidă pe care poți construi și optimiza.",
|
|
recommendations: [
|
|
"Continuă cu stilul de viață sănătos: alimentație curată, mișcare regulată și management eficient al stresului.",
|
|
"Explorează practici de longevitate: post intermitent, exerciții de respirație (Wim Hof, Buteyko), expunere la frig.",
|
|
"Concentrează-te pe personalizarea dietei în funcție de obiectivele tale (performanță sportivă, claritate mentală).",
|
|
],
|
|
},
|
|
B: {
|
|
title: "HealthType B: Stres Adrenal și Oboseală",
|
|
description: "Sistemul tău adrenal pare a fi suprasolicitat. Acest lucru duce la oboseală, anxietate și dificultăți de concentrare.",
|
|
recommendations: [
|
|
"Prioritizează somnul: 7-9 ore pe noapte, într-un mediu întunecat și răcoros.",
|
|
"Redu consumul de cofeină și zahăr, care epuizează glandele suprarenale.",
|
|
"Introdu tehnici de relaxare: meditație, yoga, plimbări în natură. Chiar și 10 minute pe zi fac o diferență.",
|
|
"Consideră suplimente adaptogene precum Ashwagandha sau Rhodiola, după consultarea unui specialist.",
|
|
],
|
|
},
|
|
C: {
|
|
title: "HealthType C: Dezechilibru Glicemic și Inflamație",
|
|
description: "Răspunsurile tale sugerează o posibilă rezistență la insulină și un nivel crescut de inflamație în corp.",
|
|
recommendations: [
|
|
"Adoptă o dietă low-carb, bogată în grăsimi sănătoase (avocado, nuci, ulei de măsline) și proteine de calitate.",
|
|
"Include antrenamente de forță (greutăți, benzi elastice) pentru a îmbunătăți sensibilitatea la insulină.",
|
|
"Consumă alimente antiinflamatorii: pește gras (somon, sardine), turmeric, ghimbir, fructe de pădure.",
|
|
"Evită carbohidrații rafinați (pâine albă, paste, patiserie) și uleiurile vegetale procesate (floarea-soarelui, soia).",
|
|
],
|
|
},
|
|
D: {
|
|
title: "HealthType D: Digestie Compromisă și Sănătate Intestinală Scăzută",
|
|
description: "Simptomele tale indică probleme la nivelul sistemului digestiv, care pot afecta absorbția nutrienților și starea generală de bine.",
|
|
recommendations: [
|
|
"Încearcă o dietă de eliminare (ex: fără gluten și lactate timp de 30 de zile) pentru a identifica posibile intoleranțe.",
|
|
"Introdu în dietă alimente fermentate (chefir, varză murată) și o sursă de probiotice de calitate.",
|
|
"Asigură-te că mesteci bine mâncarea și mănânci într-un mediu relaxat, fără grabă.",
|
|
"Consideră enzime digestive sau oțet de mere diluat în apă înainte de mese pentru a sprijini digestia.",
|
|
],
|
|
},
|
|
E: {
|
|
title: "HealthType E: Dezechilibru Hormonal (Estrogen/Testosteron)",
|
|
description: "Datele sugerează un dezechilibru al hormonilor sexuali, care poate cauza o varietate de simptome fizice și emoționale.",
|
|
recommendations: [
|
|
"Sprijină detoxifierea ficatului prin consumul de legume crucifere (broccoli, conopidă, varză).",
|
|
"Asigură un aport adecvat de zinc (semințe de dovleac, carne roșie) și vitamina B6.",
|
|
"Redu expunerea la xenoestrogeni din plastic, cosmetice și pesticide (alege produse organice și recipiente de sticlă).",
|
|
"Pentru femei: monitorizează ciclul menstrual și ajustează dieta și antrenamentele în funcție de fazele acestuia.",
|
|
"Pentru bărbați: optimizează nivelul de testosteron prin antrenamente de forță, somn adecvat și managementul stresului.",
|
|
],
|
|
},
|
|
};
|
|
|
|
function switchScreen(screenId) {
|
|
Object.values(screens).forEach(screen => screen.setAttribute('aria-hidden', 'true'));
|
|
screens[screenId].setAttribute('aria-hidden', 'false');
|
|
window.scrollTo(0, 0);
|
|
}
|
|
|
|
function startTest(sex) {
|
|
resetState();
|
|
state.sex = sex;
|
|
state.currentQuestionIndex = 0;
|
|
renderQuestion();
|
|
switchScreen('question');
|
|
}
|
|
|
|
function renderQuestion() {
|
|
const questions = data[state.sex];
|
|
const question = questions[state.currentQuestionIndex];
|
|
|
|
if (!question) {
|
|
calculateResult();
|
|
return;
|
|
}
|
|
|
|
let html = `<h2 class="question-title">${question.text}</h2>`;
|
|
if (question.help) {
|
|
html += `<p class="question-help">${question.help}</p>`;
|
|
}
|
|
|
|
if (question.type === 'hw') {
|
|
html += renderHWInputs();
|
|
} else {
|
|
html += '<ul class="option-list">';
|
|
question.options.forEach((opt, index) => {
|
|
const inputId = `q${state.currentQuestionIndex}-opt${index}`;
|
|
html += `
|
|
<li>
|
|
<label for="${inputId}" class="option-label">
|
|
<input type="${question.type}" id="${inputId}" name="answer" value="${opt.value}" data-exclusive="${opt.exclusive || false}">
|
|
<span>${opt.text}</span>
|
|
</label>
|
|
</li>
|
|
`;
|
|
});
|
|
html += '</ul>';
|
|
}
|
|
|
|
questionElements.container.innerHTML = html;
|
|
updateProgress();
|
|
restoreAnswer();
|
|
addOptionListeners();
|
|
buttons.back.disabled = state.history.length === 0;
|
|
}
|
|
|
|
function renderHWInputs() {
|
|
return `
|
|
<div class="input-group">
|
|
<label for="height">Înălțime</label>
|
|
<div style="display: flex; align-items: center;">
|
|
<input type="number" id="height" class="input-field" value="${state.height.value || ''}">
|
|
<span id="height-unit" class="unit-toggle">${state.height.unit}</span>
|
|
</div>
|
|
</div>
|
|
<div class="input-group">
|
|
<label for="weight">Greutate</label>
|
|
<div style="display: flex; align-items: center;">
|
|
<input type="number" id="weight" class="input-field" value="${state.weight.value || ''}">
|
|
<span id="weight-unit" class="unit-toggle">${state.weight.unit}</span>
|
|
</div>
|
|
</div>
|
|
`;
|
|
}
|
|
|
|
function addOptionListeners() {
|
|
const question = data[state.sex][state.currentQuestionIndex];
|
|
if (question.type === 'hw') {
|
|
document.getElementById('height').addEventListener('input', e => state.height.value = e.target.value);
|
|
document.getElementById('weight').addEventListener('input', e => state.weight.value = e.target.value);
|
|
document.getElementById('height-unit').addEventListener('click', () => toggleUnit('height'));
|
|
document.getElementById('weight-unit').addEventListener('click', () => toggleUnit('weight'));
|
|
return;
|
|
}
|
|
|
|
const labels = questionElements.container.querySelectorAll('.option-label');
|
|
labels.forEach(label => {
|
|
label.addEventListener('click', (e) => {
|
|
const input = label.querySelector('input');
|
|
if (input.type === 'radio') {
|
|
labels.forEach(l => l.classList.remove('selected'));
|
|
label.classList.add('selected');
|
|
} else { // checkbox
|
|
label.classList.toggle('selected');
|
|
if (input.dataset.exclusive === 'true' && input.checked) {
|
|
// Uncheck others and remove selected class
|
|
labels.forEach(l => {
|
|
const i = l.querySelector('input');
|
|
if (i !== input) {
|
|
i.checked = false;
|
|
l.classList.remove('selected');
|
|
}
|
|
});
|
|
} else {
|
|
// Uncheck the exclusive option if another is selected
|
|
const exclusiveOpt = questionElements.container.querySelector('input[data-exclusive="true"]');
|
|
if (exclusiveOpt) exclusiveOpt.checked = false;
|
|
questionElements.container.querySelector('input[data-exclusive="true"]').parentElement.classList.remove('selected');
|
|
}
|
|
}
|
|
});
|
|
});
|
|
}
|
|
|
|
function toggleUnit(type) {
|
|
if (type === 'height') {
|
|
const currentUnit = state.height.unit;
|
|
const currentValue = parseFloat(document.getElementById('height').value);
|
|
if (currentUnit === 'cm') {
|
|
state.height.unit = 'ft';
|
|
if (!isNaN(currentValue)) {
|
|
document.getElementById('height').value = (currentValue * 0.0328084).toFixed(1);
|
|
}
|
|
} else {
|
|
state.height.unit = 'cm';
|
|
if (!isNaN(currentValue)) {
|
|
document.getElementById('height').value = (currentValue * 30.48).toFixed(0);
|
|
}
|
|
}
|
|
document.getElementById('height-unit').textContent = state.height.unit;
|
|
} else { // weight
|
|
const currentUnit = state.weight.unit;
|
|
const currentValue = parseFloat(document.getElementById('weight').value);
|
|
if (currentUnit === 'kg') {
|
|
state.weight.unit = 'lbs';
|
|
if (!isNaN(currentValue)) {
|
|
document.getElementById('weight').value = (currentValue * 2.20462).toFixed(1);
|
|
}
|
|
} else {
|
|
state.weight.unit = 'lbs';
|
|
if (!isNaN(currentValue)) {
|
|
document.getElementById('weight').value = (currentValue / 2.20462).toFixed(1);
|
|
}
|
|
}
|
|
document.getElementById('weight-unit').textContent = state.weight.unit;
|
|
}
|
|
}
|
|
|
|
function updateProgress() {
|
|
const questions = data[state.sex];
|
|
const progress = (state.currentQuestionIndex / (questions.length -1)) * 100;
|
|
questionElements.progressText.textContent = `Întrebarea ${state.currentQuestionIndex + 1}/${questions.length}`;
|
|
questionElements.progressFill.style.width = `${progress}%`;
|
|
}
|
|
|
|
function saveAnswer() {
|
|
const question = data[state.sex][state.currentQuestionIndex];
|
|
let answerValue;
|
|
|
|
if (question.type === 'hw') {
|
|
const h = parseFloat(document.getElementById('height').value);
|
|
const w = parseFloat(document.getElementById('weight').value);
|
|
state.height.value = h;
|
|
state.weight.value = w;
|
|
answerValue = { height: h, weight: w };
|
|
} else {
|
|
const inputs = questionElements.form.querySelectorAll('input:checked');
|
|
if (inputs.length === 0) return null; // Validation failed
|
|
|
|
if (question.type === 'radio') {
|
|
answerValue = parseFloat(inputs[0].value);
|
|
} else { // checkbox
|
|
answerValue = Array.from(inputs).reduce((sum, input) => sum + parseFloat(input.value), 0);
|
|
}
|
|
}
|
|
|
|
const existingAnswerIndex = state.answers.findIndex(a => a.questionId === question.id);
|
|
if (existingAnswerIndex > -1) {
|
|
state.answers[existingAnswerIndex].answerValue = answerValue;
|
|
} else {
|
|
state.answers.push({ questionId: question.id, answerValue });
|
|
}
|
|
return answerValue;
|
|
}
|
|
|
|
function restoreAnswer() {
|
|
const question = data[state.sex][state.currentQuestionIndex];
|
|
const savedAnswer = state.answers.find(a => a.questionId === question.id);
|
|
if (!savedAnswer) return;
|
|
|
|
const inputs = questionElements.form.querySelectorAll('input');
|
|
inputs.forEach(input => {
|
|
if (question.type === 'radio') {
|
|
if (parseFloat(input.value) === savedAnswer.answerValue) {
|
|
input.checked = true;
|
|
input.parentElement.classList.add('selected');
|
|
}
|
|
} else { // checkbox
|
|
// This is tricky for checkboxes as value is a sum.
|
|
// A simple restore isn't possible without storing individual selections.
|
|
// For now, we skip checkbox restore to avoid complexity.
|
|
}
|
|
});
|
|
}
|
|
|
|
function validateAndGoNext() {
|
|
const question = data[state.sex][state.currentQuestionIndex];
|
|
let answerValue = saveAnswer();
|
|
let validationPassed = true;
|
|
|
|
if (question.type === 'hw') {
|
|
const h = state.height.value;
|
|
const w = state.weight.value;
|
|
if (!h || !w || h <= 0 || w <= 0) {
|
|
questionElements.validation.textContent = 'Te rugăm să introduci valori valide.';
|
|
validationPassed = false;
|
|
} else {
|
|
questionElements.validation.textContent = '';
|
|
}
|
|
} else {
|
|
if (answerValue === null) {
|
|
questionElements.validation.textContent = 'Te rugăm să selectezi o opțiune.';
|
|
validationPassed = false;
|
|
} else {
|
|
questionElements.validation.textContent = '';
|
|
}
|
|
}
|
|
|
|
if (!validationPassed) return;
|
|
|
|
state.history.push(state.currentQuestionIndex);
|
|
|
|
// Branching logic
|
|
let nextIndex = state.currentQuestionIndex + 1;
|
|
if (question.type === 'radio') {
|
|
const selectedOption = question.options.find(o => o.value === answerValue);
|
|
if (selectedOption && selectedOption.next) {
|
|
const nextQuestion = data[state.sex].find(q => q.id === selectedOption.next);
|
|
if (nextQuestion) {
|
|
nextIndex = data[state.sex].indexOf(nextQuestion);
|
|
}
|
|
}
|
|
}
|
|
|
|
state.currentQuestionIndex = nextIndex;
|
|
renderQuestion();
|
|
}
|
|
|
|
function goBack() {
|
|
if (state.history.length > 0) {
|
|
state.currentQuestionIndex = state.history.pop();
|
|
renderQuestion();
|
|
}
|
|
}
|
|
|
|
function resetState() {
|
|
state = {
|
|
sex: null,
|
|
currentQuestionIndex: 0,
|
|
answers: [],
|
|
history: [],
|
|
height: { value: null, unit: 'cm' },
|
|
weight: { value: null, unit: 'kg' },
|
|
};
|
|
}
|
|
|
|
function resetTest() {
|
|
resetState();
|
|
switchScreen('start');
|
|
}
|
|
|
|
function calculateResult() {
|
|
let scores = { B: 0, C: 0, D: 0, E: 0 };
|
|
state.answers.forEach(answer => {
|
|
const qId = answer.questionId;
|
|
const val = answer.answerValue;
|
|
|
|
if (qId.startsWith('F') || qId.startsWith('M')) scores.E += val;
|
|
if (['C1', 'C4'].includes(qId)) scores.B += val;
|
|
if (['C5'].includes(qId)) scores.C += val;
|
|
if (['C3'].includes(qId)) scores.D += val;
|
|
if (['C2', 'C6', 'C7', 'C8'].includes(qId)) {
|
|
scores.B += val * 0.5;
|
|
scores.C += val * 0.5;
|
|
scores.D += val * 0.5;
|
|
}
|
|
});
|
|
|
|
// BMI calculation
|
|
let h = state.height.value;
|
|
if (state.height.unit === 'ft') h = h * 30.48; // to cm
|
|
let w = state.weight.value;
|
|
if (state.weight.unit === 'lbs') w = w / 2.20462; // to kg
|
|
const bmi = w / ((h / 100) ** 2);
|
|
if (bmi > 25) scores.C += 2;
|
|
if (bmi < 18.5) scores.D += 1;
|
|
|
|
const maxScore = Object.entries(scores).reduce((max, entry) => entry[1] > max[1] ? entry : max, [null, -1]);
|
|
const finalType = maxScore[1] > 2 ? maxScore[0] : 'A';
|
|
|
|
displayResult(finalType);
|
|
}
|
|
|
|
function displayResult(type) {
|
|
const result = results[type];
|
|
resultElements.title.textContent = result.title;
|
|
let html = `<div class="result-section"><h3>Descriere</h3><p>${result.description}</p></div>`;
|
|
html += `<div class="result-section"><h3>Recomandări</h3><ul>`;
|
|
result.recommendations.forEach(rec => {
|
|
html += `<li>${rec}</li>`;
|
|
});
|
|
html += `</ul></div>`;
|
|
resultElements.content.innerHTML = html;
|
|
|
|
// Prepare print summary
|
|
let summaryHtml = '<h3>Rezumatul Răspunsurilor</h3><ul>';
|
|
data[state.sex].forEach(q => {
|
|
const answer = state.answers.find(a => a.questionId === q.id);
|
|
if (answer) {
|
|
summaryHtml += `<li><strong>${q.text}</strong>: `;
|
|
if (q.type === 'hw') {
|
|
summaryHtml += `Înălțime: ${state.height.value} ${state.height.unit}, Greutate: ${state.weight.value} ${state.weight.unit}`;
|
|
} else {
|
|
// This part is complex to get right without storing more data
|
|
// For now, just show the score value
|
|
summaryHtml += `Răspuns (valoare: ${answer.answerValue})`;
|
|
}
|
|
summaryHtml += `</li>`;
|
|
}
|
|
});
|
|
summaryHtml += '</ul>';
|
|
summaryHtml += `<p>Data testului: ${new Date().toLocaleString('ro-RO')}</p>`;
|
|
resultElements.printSummary.innerHTML = summaryHtml;
|
|
|
|
switchScreen('result');
|
|
}
|
|
|
|
// Event Listeners
|
|
buttons.sex.forEach(button => {
|
|
button.addEventListener('click', () => startTest(button.dataset.sex));
|
|
});
|
|
|
|
buttons.next.addEventListener('click', validateAndGoNext);
|
|
buttons.back.addEventListener('click', goBack);
|
|
buttons.reset.addEventListener('click', resetTest);
|
|
buttons.print.addEventListener('click', () => window.print());
|
|
|
|
// Initial setup
|
|
switchScreen('start');
|
|
});
|