Report-Generator / templates /neetprep.html
Jaimodiji's picture
Upload folder using huggingface_hub
c001f24
Raw
History Blame
12 kB
{% extends "base.html" %}
{% block title %}NeetPrep Incorrect Questions{% endblock %}
{% block head %}
<style>
.name-column {
word-wrap: break-word;
white-space: normal;
max-width: 250px;
}
@media (max-width: 768px) {
.name-column {
max-width: 25%;
}
}
.table-responsive {
overflow-x: auto;
}
th:first-child, td:first-child {
position: sticky;
left: 0;
z-index: 2;
background-color: #212529;
}
th:nth-child(2), td:nth-child(2) {
position: sticky;
left: 40px;
z-index: 2;
background-color: #212529;
}
</style>
{% endblock %}
{% block content %}
<div class="container-fluid mt-5" style="width: 90%; margin: auto;">
<div class="card bg-dark text-white">
<div class="card-header">
<h2>NeetPrep Incorrect Question Manager</h2>
</div>
<div class="card-body">
{% if neetprep_enabled %}
<div class="d-flex flex-wrap gap-2 align-items-center mb-3">
<button id="sync-btn" class="btn btn-primary">Sync/Fetch Latest Incorrect Questions</button>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="force-sync-checkbox">
<label class="form-check-label" for="force-sync-checkbox">
Force full re-sync
</label>
</div>
</div>
<div class="d-flex flex-wrap gap-2 align-items-center">
<button id="classify-btn" class="btn btn-warning">Classify Unclassified Questions</button>
<span class="ms-3">({{ unclassified_count }} unclassified)</span>
</div>
{% else %}
<div class="alert alert-info" role="alert">
NeetPrep Sync is currently disabled. You can enable it in <a href="{{ url_for('settings.settings') }}" class="alert-link">Settings</a>.
</div>
{% endif %}
<div id="sync-status" class="mt-3"></div>
<div id="pdf-link-container" class="mt-3"></div>
<hr class="my-4">
<h4>Filter by Subject</h4>
<form id="subject-filter-form" method="get" action="{{ url_for('neetprep_bp.index') }}" class="mb-3">
<div class="row">
<div class="col-md-4">
<select name="subject" id="subject" class="form-select" onchange="this.form.submit()">
{% for subject in available_subjects %}
<option value="{{ subject }}" {% if subject == selected_subject %}selected{% endif %}>{{ subject }}</option>
{% endfor %}
</select>
</div>
</div>
</form>
<h4>Generate PDF</h4>
<form id="generate-pdf-form">
<div class="d-flex flex-wrap gap-2 mb-3">
{% if neetprep_enabled %}
<button type="submit" name="pdf_type" value="all" class="btn btn-success">Generate PDF of All Incorrect Questions</button>
<a href="/neetprep/edit" class="btn btn-secondary">Edit Synced Questions</a>
{% endif %}
<button type="submit" name="pdf_type" value="quiz" class="btn btn-primary">Start Quiz</button>
<a href="/classified/edit" class="btn btn-secondary">Edit Classified Questions</a>
</div>
<h5>Or, Generate by Topic:</h5>
<div class="table-responsive" style="max-height: 400px;">
<table class="table table-sm table-hover table-striped">
<thead>
<tr>
<th scope="col" style="width: 3%;">S.No.</th>
<th scope="col" style="width: 3%;"></th>
<th scope="col" class="name-column">Topic</th>
{% if neetprep_enabled %}<th>NeetPrep Questions</th>{% endif %}
<th>My Questions</th>
</tr>
</thead>
<tbody id="topic-list">
{% if topics %}
{% for item in topics %}
<tr>
<td>{{ loop.index }}</td>
<td><input class="form-check-input" type="checkbox" value="{{ item.topic }}"></td>
<td class="name-column">{{ item.topic }}</td>
{% if neetprep_enabled %}<td><span class="badge bg-secondary">{{ item.neetprep_count }}</span></td>{% endif %}
<td><span class="badge bg-info">{{ item.my_questions_count }}</span></td>
</tr>
{% endfor %}
{% else %}
<tr>
<td colspan="{% if neetprep_enabled %}5{% else %}4{% endif %}"><i>No topics found. {% if neetprep_enabled %}Sync with NeetPrep to fetch questions and topics.{% else %}No classified topics found.{% endif %}</i></td>
</tr>
{% endif %}
</tbody>
</table>
</div>
<button type="submit" name="pdf_type" value="selected" class="btn btn-info mt-2" {% if not topics %}disabled{% endif %}>Generate PDF for Selected Topics</button>
</form>
</div>
</div>
</div>
{% endblock %}
{% block scripts %}
<script>
function loadSettings() {
const settings = JSON.parse(localStorage.getItem('pdfGeneratorSettings'));
console.log("Loaded settings from localStorage:", settings);
if (settings) {
return settings;
} else {
console.log("No settings found in localStorage, using default.");
return {
images_per_page: 4,
orientation: 'portrait',
grid_rows: 4,
grid_cols: 1,
practice_mode: 'none'
};
}
}
// Only attach event listeners if NeetPrep is enabled
{% if neetprep_enabled %}
document.getElementById('sync-btn').addEventListener('click', async () => {
const syncStatus = document.getElementById('sync-status');
const forceSync = document.getElementById('force-sync-checkbox').checked;
syncStatus.innerHTML = '<div class="alert alert-info">Syncing... This may take a while.</div>';
try {
const response = await fetch('/neetprep/sync', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ force: forceSync })
});
const result = await response.json();
if (response.ok) {
syncStatus.innerHTML = `<div class="alert alert-success">${result.status}</div>`;
// Reload the page to show updated topics
setTimeout(() => window.location.reload(), 2000);
} else {
syncStatus.innerHTML = `<div class="alert alert-danger">Error: ${result.error || 'Unknown error'}</div>`;
}
} catch (error) {
syncStatus.innerHTML = `<div class="alert alert-danger">Request failed: ${error}</div>`;
}
});
document.getElementById('classify-btn').addEventListener('click', async () => {
const syncStatus = document.getElementById('sync-status');
syncStatus.innerHTML = '<div class="alert alert-info">Classification started... This will take time due to rate limits.</div>';
try {
const response = await fetch('/neetprep/classify', { method: 'POST' });
const result = await response.json();
if (response.ok) {
syncStatus.innerHTML = `<div class="alert alert-success">${result.status}</div>`;
setTimeout(() => window.location.reload(), 2000);
} else {
syncStatus.innerHTML = `<div class="alert alert-danger">Error: ${result.error || 'Unknown error'}</div>`;
}
} catch (error) {
syncStatus.innerHTML = `<div class="alert alert-danger">Request failed: ${error}</div>`;
}
});
{% endif %}
document.getElementById('generate-pdf-form').addEventListener('submit', async (e) => {
e.preventDefault();
const pdfType = e.submitter.value;
const statusDiv = document.getElementById('sync-status');
const settings = loadSettings();
if (pdfType === 'quiz') {
const selectedTopics = Array.from(document.querySelectorAll('#topic-list input[type="checkbox"]:checked')).map(cb => cb.value);
if (selectedTopics.length === 0) {
statusDiv.innerHTML = '<div class="alert alert-warning">Please select at least one topic for the quiz.</div>';
return;
}
// For quiz, we do a full page navigation, so we create a form and submit it.
const form = document.createElement('form');
form.method = 'POST';
form.action = '/neetprep/generate';
const typeInput = document.createElement('input');
typeInput.type = 'hidden';
typeInput.name = 'type';
typeInput.value = 'quiz';
form.appendChild(typeInput);
const topicsInput = document.createElement('input');
topicsInput.type = 'hidden';
topicsInput.name = 'topics';
topicsInput.value = JSON.stringify(selectedTopics);
form.appendChild(topicsInput);
document.body.appendChild(form);
form.submit();
return; // Stop the rest of the function
}
// Existing logic for PDF generation
let payload = {
type: pdfType,
layout: {
images_per_page: settings.images_per_page,
orientation: settings.orientation,
grid_rows: settings.grid_rows,
grid_cols: settings.grid_cols,
practice_mode: settings.practice_mode
}
};
if (pdfType === 'selected') {
const selectedTopics = Array.from(document.querySelectorAll('#topic-list input[type="checkbox"]:checked')).map(cb => cb.value);
if (selectedTopics.length === 0) {
statusDiv.innerHTML = '<div class="alert alert-warning">Please select at least one topic.</div>';
return;
}
payload.topics = selectedTopics;
}
console.log("Payload sent to server:", payload);
statusDiv.innerHTML = '<div class="alert alert-info">Generating PDF...</div>';
try {
const response = await fetch('/neetprep/generate', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
});
const result = await response.json();
if (response.ok && result.success) {
statusDiv.innerHTML = '<div class="alert alert-success">PDF generated!</div>';
if(result.pdf_url) {
const pdfLinkContainer = document.getElementById('pdf-link-container');
const link = document.createElement('a');
link.href = result.pdf_url;
link.textContent = 'View Generated PDF';
link.className = 'btn btn-outline-light';
link.target = '_blank';
pdfLinkContainer.innerHTML = ''; // Clear previous links
pdfLinkContainer.appendChild(link);
window.open(result.pdf_url, '_blank');
}
} else {
statusDiv.innerHTML = `<div class="alert alert-danger">Error: ${result.error || 'PDF generation failed.'}</div>`;
}
} catch (error) {
statusDiv.innerHTML = `<div class="alert alert-danger">Request failed: ${error}</div>`;
}
});
</script>
{% endblock %}