Spaces:
Runtime error
Runtime error
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Multiple Choice Quiz</title> | |
| <link rel="stylesheet" href="{{ url_for('static', filename='styles.css') }}"> | |
| <!-- Add Google Fonts --> | |
| <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet"> | |
| <!-- Add Font Awesome for icons --> | |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> | |
| </head> | |
| <body> | |
| <header class="header"> | |
| <a href="{{ url_for('index_page') }}" class="logo"> | |
| <i class="fas fa-brain"></i> | |
| Omniscient | |
| </a> | |
| <nav class="nav-links"> | |
| <a href="{{ url_for('index_page') }}" class="home-link"> | |
| <i class="fas fa-home"></i> | |
| Home | |
| </a> | |
| </nav> | |
| </header> | |
| <div class="container"> | |
| <!-- Quiz Selection Grid --> | |
| <div id="quiz-selection-container" class="quiz-selection-container"> | |
| <div class="selection-header"> | |
| <h2 style="font-size: 3.5em; font-weight: bold; color: #f4f4f4;"> <i class="fas fa-brain"></i> Omniscient</h2> | |
| </div> | |
| <!-- Quiz Generation Section --> | |
| <div class="quiz-generator"> | |
| <div class="generator-input"> | |
| <input type="text" id="topic-input" placeholder="What do you wanna learn?" maxlength="200"> | |
| <button id="generate-quiz-btn"> | |
| <i class="fas fa-magic"></i> Generate Quiz | |
| </button> | |
| </div> | |
| <div id="generation-status" class="generation-status" style="display: none;"> | |
| <i class="fas fa-spinner fa-spin"></i> Generating your custom quiz... | |
| </div> | |
| </div> | |
| <div id="quizzes-grid" class="quizzes-grid"> | |
| <!-- Quiz cards will be loaded here --> | |
| </div> | |
| </div> | |
| <!-- Quiz Content (initially hidden) --> | |
| <div id="quiz-content" class="quiz-content" style="display: none;"> | |
| <div class="left-side" id="quiz-info"> | |
| <!-- Quiz information will be loaded here --> | |
| </div> | |
| <div class="quiz-container"> | |
| <div class="quiz-header"> | |
| <button id="back-to-selection" class="back-btn"> | |
| <i class="fas fa-arrow-left"></i> Back to Quiz Selection | |
| </button> | |
| </div> | |
| <div class="quiz-title"> | |
| <h1 id="quiz-title"></h1> | |
| <p id="quiz-description"></p> | |
| </div> | |
| <div id="quiz"> | |
| <!-- Questions will be dynamically inserted here --> | |
| </div> | |
| <div class="progress-bars"> | |
| <div class="progress-label" style="font-size: 1.2em; font-weight: bold; margin-bottom: 15px;"> | |
| Score: <span id="score-percentage">0</span>% | | |
| Remaining: <span id="remaining-count"><span id="total-questions"></span></span> Questions | |
| </div> | |
| <div class="progress-label">Correct Answers: <span id="correct-count">0</span> of <span id="total-questions"></span></div> | |
| <div class="progress-bar"> | |
| <div id="correct-progress" class="progress-fill progress-correct" style="width: 0%"></div> | |
| </div> | |
| <div class="progress-label">Incorrect Answers: <span id="incorrect-count">0</span> of <span id="total-questions"></span></div> | |
| <div class="progress-bar"> | |
| <div id="incorrect-progress" class="progress-fill progress-incorrect" style="width: 0%"></div> | |
| </div> | |
| </div> | |
| <button id="submit-button">Submit Quiz</button> | |
| </div> | |
| </div> | |
| </div> | |
| <script> | |
| // Global variable to store quiz data | |
| let quizData = null; | |
| // Quiz selection and loading | |
| document.addEventListener('DOMContentLoaded', function() { | |
| const selectionContainer = document.getElementById('quiz-selection-container'); | |
| const quizContent = document.getElementById('quiz-content'); | |
| const backBtn = document.getElementById('back-to-selection'); | |
| const quizzesGrid = document.getElementById('quizzes-grid'); | |
| // Load available quizzes on page load | |
| loadQuizzesList(); | |
| // Quiz generation functionality | |
| const topicInput = document.getElementById('topic-input'); | |
| const generateBtn = document.getElementById('generate-quiz-btn'); | |
| const generationStatus = document.getElementById('generation-status'); | |
| generateBtn.addEventListener('click', generateCustomQuiz); | |
| topicInput.addEventListener('keypress', function(e) { | |
| if (e.key === 'Enter') { | |
| generateCustomQuiz(); | |
| } | |
| }); | |
| async function generateCustomQuiz() { | |
| const topic = topicInput.value.trim(); | |
| if (!topic) { | |
| alert('Please enter a topic to generate a quiz about!'); | |
| return; | |
| } | |
| // Show loading state | |
| generateBtn.disabled = true; | |
| generationStatus.style.display = 'block'; | |
| try { | |
| const response = await fetch('/api/generate-quiz', { | |
| method: 'POST', | |
| headers: { | |
| 'Content-Type': 'application/json', | |
| }, | |
| body: JSON.stringify({ topic: topic }) | |
| }); | |
| if (!response.ok) { | |
| throw new Error('Failed to generate quiz'); | |
| } | |
| const result = await response.json(); | |
| // Clear input and reload quizzes list | |
| topicInput.value = ''; | |
| loadQuizzesList(); | |
| // Auto-start the newly generated quiz | |
| setTimeout(() => { | |
| startQuiz(result.filename); | |
| }, 1000); | |
| } catch (error) { | |
| console.error('Error generating quiz:', error); | |
| alert('Error generating quiz. Please try again.'); | |
| } finally { | |
| // Hide loading state | |
| generateBtn.disabled = false; | |
| generationStatus.style.display = 'none'; | |
| } | |
| } | |
| // Back button functionality | |
| backBtn.addEventListener('click', function() { | |
| quizContent.style.display = 'none'; | |
| selectionContainer.style.display = 'block'; | |
| // Reset quiz content | |
| document.getElementById('quiz').innerHTML = ''; | |
| quizData = null; | |
| }); | |
| // Load all available quizzes | |
| async function loadQuizzesList() { | |
| try { | |
| const response = await fetch('/api/quizzes'); | |
| if (!response.ok) { | |
| throw new Error('Failed to load quizzes'); | |
| } | |
| const quizzes = await response.json(); | |
| displayQuizzesGrid(quizzes); | |
| } catch (error) { | |
| console.error('Error loading quizzes:', error); | |
| quizzesGrid.innerHTML = '<p>Error loading quizzes. Please try again.</p>'; | |
| } | |
| } | |
| // Display quizzes in a 3-column grid | |
| function displayQuizzesGrid(quizzes) { | |
| quizzesGrid.innerHTML = ''; | |
| quizzes.forEach(quiz => { | |
| const quizCard = document.createElement('div'); | |
| quizCard.className = 'quiz-card'; | |
| quizCard.innerHTML = ` | |
| <div class="quiz-card-header"> | |
| <h3>${quiz.title}</h3> | |
| <div class="quiz-card-meta"> | |
| <span class="difficulty difficulty-${quiz.difficulty.toLowerCase()}">${quiz.difficulty}</span> | |
| <span class="question-count">${quiz.question_count} Questions</span> | |
| </div> | |
| </div> | |
| <p class="quiz-card-description">${quiz.description}</p> | |
| <div class="quiz-card-tags"> | |
| ${quiz.tags.map(tag => `<span class="tag">${tag}</span>`).join('')} | |
| </div> | |
| <div class="quiz-card-footer"> | |
| <span class="created-date">Created: ${formatDate(quiz.created_date)}</span> | |
| <button class="start-quiz-btn" data-filename="${quiz.filename}"> | |
| Start Quiz <i class="fas fa-arrow-right"></i> | |
| </button> | |
| </div> | |
| `; | |
| // Add click event to start quiz | |
| const startBtn = quizCard.querySelector('.start-quiz-btn'); | |
| startBtn.addEventListener('click', () => startQuiz(quiz.filename)); | |
| quizzesGrid.appendChild(quizCard); | |
| }); | |
| } | |
| // Format date for display | |
| function formatDate(dateString) { | |
| const date = new Date(dateString); | |
| return date.toLocaleDateString('en-US', { | |
| year: 'numeric', | |
| month: 'short', | |
| day: 'numeric' | |
| }); | |
| } | |
| // Start a quiz | |
| async function startQuiz(filename) { | |
| try { | |
| const response = await fetch(`/api/quiz/${filename}`); | |
| if (!response.ok) { | |
| throw new Error('Failed to load quiz data'); | |
| } | |
| const data = await response.json(); | |
| quizData = data; | |
| // Hide selection and show quiz content | |
| selectionContainer.style.display = 'none'; | |
| quizContent.style.display = 'block'; | |
| // Initialize quiz | |
| initializeQuiz(data); | |
| } catch (error) { | |
| console.error('Error loading quiz:', error); | |
| alert('Error loading quiz data. Please try again.'); | |
| } | |
| } | |
| // Initialize quiz interface | |
| function initializeQuiz(data) { | |
| // Initialize quiz title and description | |
| document.getElementById('quiz-title').textContent = data.info.title; | |
| document.getElementById('quiz-description').textContent = data.info.description; | |
| // Initialize total questions count (excluding concept cards) | |
| const totalQuestionsCount = data.cards.filter(q => q.type !== 'concept').length; | |
| document.querySelectorAll('#total-questions').forEach(el => { | |
| el.textContent = totalQuestionsCount; | |
| }); | |
| // Display the quiz | |
| displayQuiz(data); | |
| } | |
| }); | |
| </script> | |
| <script src="{{ url_for('static', filename='funcs.js') }}"></script> | |
| </body> | |
| </html> |