235 lines
9.3 KiB
JavaScript
235 lines
9.3 KiB
JavaScript
document.addEventListener('DOMContentLoaded', async () => {
|
|
const body = document.body;
|
|
const topic = body.dataset.topic;
|
|
const currentLessonId = parseInt(body.dataset.lessonId, 10);
|
|
|
|
if (!topic) return;
|
|
|
|
// --- Pobieranie danych o lekcjach ---
|
|
const response = await fetch('lekcje.json');
|
|
const allTopics = await response.json();
|
|
const topicData = allTopics[topic];
|
|
const lessons = topicData.lessons;
|
|
const totalLessons = lessons.length;
|
|
|
|
// --- Inicjalizacja Dropdown Menu ---
|
|
const dropdownContent = document.querySelector('.dropdown-content');
|
|
const dropdownButton = document.querySelector('.dropdown-button');
|
|
|
|
lessons.forEach(lesson => {
|
|
const a = document.createElement('a');
|
|
a.href = lesson.url;
|
|
a.textContent = `Lekcja ${lesson.id}: ${lesson.title}`;
|
|
if (lesson.id === currentLessonId) {
|
|
a.classList.add('active');
|
|
}
|
|
dropdownContent.appendChild(a);
|
|
});
|
|
|
|
dropdownButton.addEventListener('click', (e) => {
|
|
e.stopPropagation();
|
|
dropdownContent.classList.toggle('show');
|
|
});
|
|
|
|
document.addEventListener('click', (e) => {
|
|
if (!e.target.matches('.dropdown-button')) {
|
|
if (dropdownContent.classList.contains('show')) {
|
|
dropdownContent.classList.remove('show');
|
|
}
|
|
}
|
|
});
|
|
|
|
// --- Zarządzanie postępem ---
|
|
const progressKey = `progress_${topic}`;
|
|
let progress = JSON.parse(localStorage.getItem(progressKey)) || [];
|
|
|
|
const progressBar = document.querySelector('.progress');
|
|
const progressLabel = document.querySelector('.progress-label');
|
|
|
|
function updateProgress() {
|
|
const completedCount = progress.length;
|
|
const progressPercentage = (completedCount / totalLessons) * 100;
|
|
|
|
if (progressBar) progressBar.style.width = `${progressPercentage}%`;
|
|
if (progressLabel) progressLabel.textContent = `Postęp: ${completedCount}/${totalLessons}`;
|
|
}
|
|
|
|
// --- Interaktywne zadania ---
|
|
const interactiveInputs = document.querySelectorAll('.interactive-input');
|
|
interactiveInputs.forEach(input => {
|
|
input.addEventListener('change', () => {
|
|
const correctAnswer = input.dataset.answer;
|
|
const feedbackSpan = input.nextElementSibling;
|
|
if (input.value === correctAnswer) {
|
|
feedbackSpan.textContent = '✅ Dobrze!';
|
|
feedbackSpan.style.color = 'green';
|
|
input.style.borderColor = 'green';
|
|
|
|
// Sprawdź, czy wszystkie zadania na stronie są rozwiązane
|
|
const allCorrect = Array.from(document.querySelectorAll('.interactive-input')).every(i => i.style.borderColor === 'green');
|
|
|
|
// Zapisz postęp, jeśli wszystkie zadania są poprawne
|
|
if (allCorrect && !progress.includes(currentLessonId)) {
|
|
progress.push(currentLessonId);
|
|
localStorage.setItem(progressKey, JSON.stringify(progress));
|
|
updateProgress();
|
|
}
|
|
} else {
|
|
feedbackSpan.textContent = '❌ Spróbuj jeszcze raz.';
|
|
feedbackSpan.style.color = 'red';
|
|
input.style.borderColor = 'red';
|
|
}
|
|
});
|
|
});
|
|
|
|
// --- Ćwiczenie "Start i doskocz" ---
|
|
const jumpExercise = document.querySelector('#exercise2');
|
|
if (jumpExercise) {
|
|
const jumpButtons = jumpExercise.querySelectorAll('.jump-btn');
|
|
const jumpFeedback = jumpExercise.querySelector('.jump-feedback');
|
|
let jumpCounter = 5;
|
|
let jumpsMade = 0;
|
|
|
|
jumpButtons.forEach(button => {
|
|
button.addEventListener('click', () => {
|
|
if (button.classList.contains('activated')) return;
|
|
|
|
jumpsMade++;
|
|
jumpCounter++;
|
|
button.classList.add('activated');
|
|
button.textContent = jumpCounter;
|
|
|
|
let feedbackText = "Start: 5";
|
|
for (let i = 1; i <= jumpsMade; i++) {
|
|
feedbackText += ` ↷ ${5 + i}`;
|
|
}
|
|
jumpFeedback.textContent = feedbackText;
|
|
|
|
// Po ostatnim skoku, wypełnij pole odpowiedzi
|
|
if (jumpsMade === jumpButtons.length) {
|
|
const targetInput = jumpExercise.querySelector('.interactive-input');
|
|
targetInput.value = jumpCounter;
|
|
// Wywołaj zdarzenie 'change', aby sprawdzić odpowiedź i zapisać postęp
|
|
targetInput.dispatchEvent(new Event('change'));
|
|
}
|
|
});
|
|
});
|
|
}
|
|
|
|
// --- Losowe ćwiczenie "Start i doskocz" ---
|
|
const randomExerciseContainer = document.getElementById('random-exercise-container');
|
|
const retryButton = document.getElementById('retry-random-exercise');
|
|
|
|
function generateRandomExercise() {
|
|
const num1 = Math.floor(Math.random() * 8) + 2; // 2-9
|
|
const num2 = Math.floor(Math.random() * 8) + 2; // 2-9
|
|
const startNum = Math.max(num1, num2);
|
|
const jumpCount = Math.min(num1, num2);
|
|
const answer = startNum + jumpCount;
|
|
|
|
let jumpsHTML = '';
|
|
for (let i = 0; i < jumpCount; i++) {
|
|
jumpsHTML += `<button class="jump-btn" data-value="${startNum + i + 1}">+1</button>`;
|
|
}
|
|
|
|
randomExerciseContainer.innerHTML = `
|
|
<div class="interactive-exercise" id="random-exercise">
|
|
<h4>Ćwiczenie losowe</h4>
|
|
<p>Mamy <strong>${startNum}</strong>. Chcemy dołożyć <strong>${jumpCount}</strong>.</p>
|
|
<div class="start-and-jump">
|
|
<div class="start-number">${startNum}</div>
|
|
<div class="jumps">${jumpsHTML}</div>
|
|
</div>
|
|
<p>Klikaj przyciski "+1", żeby "doskoczyć" do wyniku. Jaki będzie wynik?</p>
|
|
<div class="interactive-example">
|
|
<span>${startNum} + ${jumpCount} = </span>
|
|
<input type="number" class="interactive-input" data-answer="${answer}">
|
|
<span class="feedback"></span>
|
|
</div>
|
|
<div class="jump-feedback">
|
|
Start: ${startNum}...
|
|
</div>
|
|
</div>
|
|
`;
|
|
setupRandomExerciseListeners();
|
|
setupInteractiveInputs(); // Ponownie podłączamy listenery do nowo dodanych inputów
|
|
}
|
|
|
|
function setupRandomExerciseListeners() {
|
|
const exercise = document.getElementById('random-exercise');
|
|
if (!exercise) return;
|
|
|
|
const jumpButtons = exercise.querySelectorAll('.jump-btn');
|
|
const jumpFeedback = exercise.querySelector('.jump-feedback');
|
|
const startNum = parseInt(exercise.querySelector('.start-number').textContent, 10);
|
|
let jumpCounter = startNum;
|
|
let jumpsMade = 0;
|
|
|
|
jumpButtons.forEach(button => {
|
|
button.addEventListener('click', () => {
|
|
if (button.classList.contains('activated')) return;
|
|
|
|
jumpsMade++;
|
|
jumpCounter++;
|
|
button.classList.add('activated');
|
|
button.textContent = jumpCounter;
|
|
|
|
let feedbackText = `Start: ${startNum}`;
|
|
for (let i = 1; i <= jumpsMade; i++) {
|
|
feedbackText += ` ↷ ${startNum + i}`;
|
|
}
|
|
jumpFeedback.textContent = feedbackText;
|
|
|
|
if (jumpsMade === jumpButtons.length) {
|
|
const targetInput = exercise.querySelector('.interactive-input');
|
|
targetInput.value = jumpCounter;
|
|
targetInput.dispatchEvent(new Event('change'));
|
|
}
|
|
});
|
|
});
|
|
}
|
|
|
|
function setupInteractiveInputs() {
|
|
const allInputs = document.querySelectorAll('.interactive-input');
|
|
allInputs.forEach(input => {
|
|
// Usuń stare listenery, aby uniknąć duplikacji
|
|
const newInput = input.cloneNode(true);
|
|
input.parentNode.replaceChild(newInput, input);
|
|
|
|
newInput.addEventListener('change', () => {
|
|
const correctAnswer = newInput.dataset.answer;
|
|
const feedbackSpan = newInput.nextElementSibling;
|
|
if (newInput.value === correctAnswer) {
|
|
feedbackSpan.textContent = '✅ Dobrze!';
|
|
feedbackSpan.style.color = 'green';
|
|
newInput.style.borderColor = 'green';
|
|
|
|
const allCorrect = Array.from(document.querySelectorAll('.interactive-input')).every(i => i.style.borderColor === 'green');
|
|
|
|
if (allCorrect && !progress.includes(currentLessonId)) {
|
|
progress.push(currentLessonId);
|
|
localStorage.setItem(progressKey, JSON.stringify(progress));
|
|
updateProgress();
|
|
}
|
|
} else {
|
|
feedbackSpan.textContent = '❌ Spróbuj jeszcze raz.';
|
|
feedbackSpan.style.color = 'red';
|
|
newInput.style.borderColor = 'red';
|
|
}
|
|
});
|
|
});
|
|
}
|
|
|
|
|
|
if (randomExerciseContainer) {
|
|
generateRandomExercise();
|
|
retryButton.addEventListener('click', generateRandomExercise);
|
|
} else {
|
|
setupInteractiveInputs();
|
|
}
|
|
|
|
|
|
// Inicjalizacja paska postępu przy ładowaniu strony
|
|
updateProgress();
|
|
});
|