document.addEventListener('DOMContentLoaded', function() { // Initialize local storage for study tracking if (!localStorage.getItem('studySessions')) { localStorage.setItem('studySessions', '0'); } if (!localStorage.getItem('studyStreak')) { localStorage.setItem('studyStreak', '0'); } if (!localStorage.getItem('lastStudyDate')) { localStorage.setItem('lastStudyDate', new Date().toDateString()); } // Check if user studied today to update streak const lastStudyDate = localStorage.getItem('lastStudyDate'); const today = new Date().toDateString(); if (lastStudyDate !== today) { // Reset streak if more than one day has passed const lastDate = new Date(lastStudyDate); const todayDate = new Date(); const diffTime = Math.abs(todayDate - lastDate); const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24)); if (diffDays > 1) { localStorage.setItem('studyStreak', '0'); } } // Update UI with stored data updateStudyStats(); }); function updateStudyStats() { const sessions = localStorage.getItem('studySessions'); const streak = localStorage.getItem('studyStreak'); document.querySelectorAll('.session-count').forEach(el => { el.textContent = sessions; }); document.querySelectorAll('.streak-count').forEach(el => { el.textContent = streak; }); } function startStudySession(subject) { // Validate subject if (!subject) { showErrorToast("Please select a subject to study!"); return; } // In a real app, this would start tracking study time console.log(`Starting study session for ${subject}`); // Update session count const sessions = parseInt(localStorage.getItem('studySessions')) + 1; localStorage.setItem('studySessions', sessions.toString()); // Update streak if needed const lastStudyDate = localStorage.getItem('lastStudyDate'); const today = new Date().toDateString(); if (lastStudyDate !== today) { const streak = parseInt(localStorage.getItem('studyStreak')) + 1; localStorage.setItem('studyStreak', streak.toString()); localStorage.setItem('lastStudyDate', today); } updateStudyStats(); showSuccessToast(`Started studying ${subject}! Good luck!`); } function showErrorToast(message) { const toast = document.createElement('div'); toast.className = 'fixed bottom-4 left-1/2 transform -translate-x-1/2 bg-red-500 text-white px-6 py-3 rounded-lg shadow-xl flex items-center animate-fade-in z-50'; toast.innerHTML = `
${message}
`; document.body.appendChild(toast); feather.replace(); setTimeout(() => { toast.classList.add('opacity-0', 'transition-opacity', 'duration-300'); setTimeout(() => toast.remove(), 300); }, 3000); } function showSuccessToast(message) { const toast = document.createElement('div'); toast.className = 'fixed bottom-4 left-1/2 transform -translate-x-1/2 bg-green-500 text-white px-6 py-3 rounded-lg shadow-xl flex items-center animate-fade-in z-50'; toast.innerHTML = `
${message}
`; document.body.appendChild(toast); feather.replace(); setTimeout(() => { toast.classList.add('opacity-0', 'transition-opacity', 'duration-300'); setTimeout(() => toast.remove(), 300); }, 3000); } // Photo upload functionality function setupPhotoUpload() { const uploadElements = document.querySelectorAll('.photo-upload'); uploadElements.forEach(upload => { const input = upload.querySelector('input[type="file"]'); const preview = upload.querySelector('.photo-preview'); if (input && preview) { input.addEventListener('change', (e) => { const file = e.target.files[0]; if (file) { const reader = new FileReader(); reader.onload = (event) => { preview.src = event.target.result; preview.style.display = 'block'; }; reader.readAsDataURL(file); } }); } }); } // Helper functions for study assistance function provideHint(questionElement) { // This would be connected to your question system const hint = questionElement.dataset.hint || "Try breaking the problem down into smaller steps."; // Show hint showSuccessToast(`Hint: ${hint}`); // Speak the hint using Web Speech API speakText(hint); // Provide similar example const example = questionElement.dataset.example || "Here's a similar problem: " + questionElement.textContent.replace(/\d+/g, function(match) { return Math.floor(Math.random() * 10) + 1; }); setTimeout(() => { showSuccessToast(`Example: ${example}`); speakText(example); }, 2000); } // AI Quiz Generation Service using Open Trivia DB API async function generateQuizQuestions(subject, difficulty = 'medium', topic = '') { // Map our subject categories to Open Trivia categories const categoryMap = { 'math': 19, // Mathematics 'science': 17, // Science & Nature 'history': 23, // History 'languages': 20, // Mythology (as a placeholder) 'computer_science': 18 // Computers }; const categoryId = categoryMap[subject] || 9; // General Knowledge as fallback try { // Fetch questions from Open Trivia DB API const response = await fetch(`https://opentdb.com/api.php?amount=5&category=${categoryId}&difficulty=${difficulty}&type=multiple&encode=url3986`); const data = await response.json(); if (data.response_code !== 0 || !data.results) { throw new Error('Failed to fetch questions from API'); } // Process the API response into our question format return data.results.map(q => { // Decode URL-encoded strings and fix HTML entities const decodedQuestion = decodeURIComponent(q.question) .replace(/"/g, '"') .replace(/&/g, '&') .replace(/'/g, "'"); const decodedCorrect = decodeURIComponent(q.correct_answer) .replace(/"/g, '"') .replace(/&/g, '&') .replace(/'/g, "'"); const decodedIncorrect = q.incorrect_answers.map(ans => decodeURIComponent(ans) .replace(/"/g, '"') .replace(/&/g, '&') .replace(/'/g, "'") ); // Combine and shuffle options const allOptions = [...decodedIncorrect, decodedCorrect]; const shuffledOptions = shuffleArray(allOptions); return { question: decodedQuestion, options: shuffledOptions, correctIndex: shuffledOptions.indexOf(decodedCorrect), hint: `Think about ${q.category.toLowerCase()} concepts`, example: `This is a ${difficulty} level question about ${q.category.toLowerCase()}` }; }); } catch (error) { console.error('Error fetching quiz questions:', error); showErrorToast('Failed to fetch questions. Using sample questions instead.'); return generateFallbackQuestions(subject, difficulty, topic); } } function generateFallbackQuestions(subject, difficulty, topic) { // Fallback questions if API fails const fallbackQuestions = [ { question: `What is the capital of France? (Fallback for ${subject})`, options: ["London", "Paris", "Berlin", "Madrid"], correctIndex: 1, hint: "It's known as the City of Light", example: "Other European capitals include Rome and Berlin" }, { question: `What is 5 × 7? (Fallback for ${subject})`, options: ["25", "30", "35", "40"], correctIndex: 2, hint: "It's 5 less than 40", example: "Similar to 6 × 6 = 36" }, { question: `What is the chemical symbol for oxygen? (Fallback for ${subject})`, options: ["O", "Ox", "Og", "On"], correctIndex: 0, hint: "It's a single letter", example: "H is for Hydrogen" } ]; return fallbackQuestions; } // Helper function to shuffle array function shuffleArray(array) { for (let i = array.length - 1; i > 0; i--) { const j = Math.floor(Math.random() * (i + 1)); [array[i], array[j]] = [array[j], array[i]]; } return array; } function speakText(text) { if ('speechSynthesis' in window) { const utterance = new SpeechSynthesisUtterance(text); utterance.voice = speechSynthesis.getVoices().find(voice => voice.name.includes('Female') || voice.lang.includes('en-US') ); utterance.rate = 0.9; utterance.pitch = 1.2; speechSynthesis.speak(utterance); } } function setupHelpButtons() { // Add help button to question pages if (document.querySelector('.question-container')) { const helpBtn = document.createElement('button'); helpBtn.className = 'help-btn'; helpBtn.innerHTML = ''; helpBtn.onclick = () => { const currentQuestion = document.querySelector('.question-container:not([style*="display: none"])'); if (currentQuestion) { provideHint(currentQuestion); } }; document.body.appendChild(helpBtn); feather.replace(); } } // Initialize all helper features document.addEventListener('DOMContentLoaded', () => { setupPhotoUpload(); setupHelpButtons(); // Load voices for speech synthesis if ('speechSynthesis' in window) { speechSynthesis.onvoiceschanged = () => { // Voices are now loaded }; } });