Files
edu/lekcja.js
2026-05-26 21:19:14 +02:00

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();
});