Test / index.html
Ramesh-vani's picture
Update index.html
6849482 verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Minimalistic MCQ Generator - Multiple Tests</title>
<script src="https://cdn.tailwindcss.com"></script>
<style>
.section-tab.active { background-color: #3B82F6; color: white; }
.section-content { display: none; }
.section-content.active { display: block; }
</style>
</head>
<body class="bg-gray-100 min-h-screen py-8">
<div class="container mx-auto max-w-2xl bg-white p-6 rounded-lg shadow-md">
<h1 class="text-3xl font-bold text-center mb-6 text-gray-800">MCQ Generator</h1>
<!-- Topics input area -->
<div id="topics-container" class="space-y-4 mb-6">
<div class="topic-row flex items-center space-x-2">
<input type="text" name="topic" placeholder="Topic Name" class="flex-grow p-2 border rounded" required>
<input type="number" name="num" placeholder="# of Questions" class="w-32 p-2 border rounded" required min="1">
<!-- Status indicator for this topic row -->
<span class="row-status w-6"></span>
<button class="remove-topic bg-red-500 text-white p-2 rounded hover:bg-red-600 transition">
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
<path fill-rule="evenodd" d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z" clip-rule="evenodd" />
</svg>
</button>
</div>
</div>
<!-- Controls: Add Topic, Number of Tests & Generate MCQs -->
<div class="flex justify-center items-center space-x-4 mb-8">
<button id="add-topic" class="bg-blue-500 text-white px-4 py-2 rounded hover:bg-blue-600 transition">Add Topic</button>
<input type="number" id="num-tests" placeholder="# of Tests" class="w-32 p-2 border rounded" required min="1">
<button id="submit-topics" class="bg-green-500 text-white px-4 py-2 rounded hover:bg-green-600 transition">Generate MCQs</button>
</div>
<!-- Results area for tests -->
<div id="tests-results" class="mt-8">
<h2 class="text-2xl font-semibold text-center mb-4 text-gray-700">Results:</h2>
<!-- Test containers will be appended here -->
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', () => {
const topicsContainer = document.getElementById('topics-container');
const addTopicBtn = document.getElementById('add-topic');
const submitTopicsBtn = document.getElementById('submit-topics');
const testsResults = document.getElementById('tests-results');
addTopicBtn.addEventListener('click', addTopicRow);
submitTopicsBtn.addEventListener('click', submitTopics);
topicsContainer.addEventListener('click', handleRemoveTopic);
// Add a new topic row
function addTopicRow() {
const newRow = document.createElement('div');
newRow.className = 'topic-row flex items-center space-x-2';
newRow.innerHTML = `
<input type="text" name="topic" placeholder="Topic Name" class="flex-grow p-2 border rounded" required>
<input type="number" name="num" placeholder="# of Questions" class="w-32 p-2 border rounded" required min="1">
<span class="row-status w-6"></span>
<button class="remove-topic bg-red-500 text-white p-2 rounded hover:bg-red-600 transition">
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
<path fill-rule="evenodd" d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z" clip-rule="evenodd" />
</svg>
</button>
`;
topicsContainer.appendChild(newRow);
}
// Remove a topic row
function handleRemoveTopic(event) {
if (event.target.closest('.remove-topic')) {
event.target.closest('.topic-row').remove();
}
}
// Generate tests and call backend for each test & topic
function submitTopics() {
// Clear previous test results
testsResults.innerHTML = `<h2 class="text-2xl font-semibold text-center mb-4 text-gray-700">Results:</h2>`;
const numTests = parseInt(document.getElementById('num-tests').value);
const rows = document.querySelectorAll('.topic-row');
// Reset dataset counter for each topic row (to track completions across tests)
rows.forEach(row => {
row.dataset.completed = "0";
});
// For each test (e.g. Test 1 to Test numTests)
for (let testIndex = 1; testIndex <= numTests; testIndex++) {
// Create a container for each test
const testContainer = document.createElement('div');
testContainer.className = 'test-container mb-8 border p-4 rounded';
testContainer.innerHTML = `<h2 class="text-2xl font-semibold text-center mb-4 text-gray-700">Test ${testIndex}</h2>`;
// Create containers for tab headers and tab contents for this test
const tabHeaders = document.createElement('div');
tabHeaders.className = 'tab-headers flex flex-wrap gap-2 mb-4';
const tabContents = document.createElement('div');
tabContents.className = 'tab-contents';
testContainer.appendChild(tabHeaders);
testContainer.appendChild(tabContents);
testsResults.appendChild(testContainer);
// For each topic row, create a tab for that topic in this test
rows.forEach((row, topicIndex) => {
const topic = row.querySelector('input[name="topic"]').value;
const num = parseInt(row.querySelector('input[name="num"]').value);
// Create tab header for current test & topic with spinner status
const tabHeader = document.createElement('button');
tabHeader.className = 'tab-header px-4 py-2 rounded-t-lg bg-gray-200 hover:bg-gray-300 transition';
tabHeader.id = `tab-header-${testIndex}-${topicIndex}`;
tabHeader.setAttribute('data-tab', `${testIndex}-${topicIndex}`);
tabHeader.innerHTML = `${topic} <span class="status ml-2" id="status-${testIndex}-${topicIndex}">
<div class="animate-spin rounded-full h-3 w-3 border-b-2 border-blue-500 inline-block"></div>
</span>`;
tabHeader.addEventListener('click', () => activateTab(testIndex, topicIndex));
tabHeaders.appendChild(tabHeader);
// Create tab content container for current test & topic
const tabContent = document.createElement('div');
tabContent.className = 'tab-content hidden p-4 bg-gray-100 rounded-b-lg';
tabContent.id = `tab-content-${testIndex}-${topicIndex}`;
tabContent.innerHTML = 'Loading...';
tabContents.appendChild(tabContent);
// Call the backend API for this test and topic
callBackend(topic, num, testIndex, (responseText) => {
updateTabContent(testIndex, topicIndex, responseText);
// Update the tab header status to tick (✓)
document.getElementById(`status-${testIndex}-${topicIndex}`).innerHTML = '✓';
// Update the topic row's status counter
let completed = parseInt(row.dataset.completed) || 0;
completed++;
row.dataset.completed = completed;
// When all tests for a topic are complete, update its row status with tick
if (completed === numTests) {
row.querySelector('.row-status').innerHTML = '✓';
}
});
});
// Activate the first tab for this test by default (if available)
if (rows.length > 0) {
activateTab(testIndex, 0);
}
}
}
// Update the tab content for given test & topic
function updateTabContent(testIndex, topicIndex, content) {
document.getElementById(`tab-content-${testIndex}-${topicIndex}`).innerHTML = `<pre class="whitespace-pre-wrap">${content}</pre>`;
}
// Activate a tab for a specific test
function activateTab(testIndex, topicIndex) {
// Find the test container by getting any element inside it
const testContainer = document.getElementById(`tab-header-${testIndex}-${topicIndex}`).closest('.test-container');
const tabHeaders = testContainer.querySelectorAll('.tab-header');
const tabContents = testContainer.querySelectorAll('.tab-content');
tabHeaders.forEach(header => header.classList.remove('bg-blue-500', 'text-white'));
tabContents.forEach(content => content.classList.add('hidden'));
document.getElementById(`tab-header-${testIndex}-${topicIndex}`).classList.add('bg-blue-500', 'text-white');
document.getElementById(`tab-content-${testIndex}-${topicIndex}`).classList.remove('hidden');
}
// Real backend API call for MCQ generation
function callBackend(topic, num, testNumber, callback) {
fetch('/generate_mcq', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ topic: topic, num: num, test: testNumber })
})
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
})
.then(data => {
callback(data.mcqs);
})
.catch(error => {
callback("Error: " + error.message);
});
}
});
</script>
</body>
</html>