AutoExamGen / templates /step2_config.html
Omnamdev02's picture
Add templates
a0ae5a7
{% extends 'base.html' %}
{% block title %}Step 2: Configure Questions - AutoExamGen{% endblock %}
{% block head %}
<style>
body {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}
.container {
padding-top: 2rem;
}
.card {
border: none;
border-radius: 15px;
box-shadow: 0 10px 30px rgba(0,0,0,0.1);
backdrop-filter: blur(10px);
background: rgba(255, 255, 255, 0.95);
}
.btn-primary {
background: linear-gradient(45deg, #667eea, #764ba2);
border: none;
border-radius: 25px;
padding: 12px 30px;
font-weight: 600;
transition: all 0.3s ease;
}
.btn-primary:hover {
transform: translateY(-2px);
box-shadow: 0 5px 15px rgba(0,0,0,0.2);
}
.btn-secondary {
border-radius: 25px;
padding: 12px 30px;
font-weight: 600;
}
.form-control, .form-select {
border-radius: 10px;
border: 2px solid #e9ecef;
transition: all 0.3s ease;
}
.form-control:focus, .form-select:focus {
border-color: #667eea;
box-shadow: 0 0 0 0.2rem rgba(102, 126, 234, 0.25);
}
.step-indicator {
display: flex;
justify-content: center;
margin-bottom: 2rem;
}
.step {
width: 40px;
height: 40px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
margin: 0 10px;
font-weight: bold;
color: white;
}
.step.active {
background: linear-gradient(45deg, #667eea, #764ba2);
}
.step.completed {
background: #28a745;
}
.step.inactive {
background: #ccc;
}
.question-type-card {
border: 2px solid #e9ecef;
border-radius: 15px;
padding: 1.5rem;
margin-bottom: 1rem;
transition: all 0.3s ease;
}
.question-type-card:hover {
border-color: #667eea;
box-shadow: 0 5px 15px rgba(0,0,0,0.1);
}
.question-type-card.active {
border-color: #667eea;
background-color: #f8f9ff;
}
.marks-preview {
background: linear-gradient(45deg, #667eea, #764ba2);
color: white;
border-radius: 10px;
padding: 1rem;
text-align: center;
}
.alert {
border-radius: 10px;
}
.input-group-text {
border-radius: 10px 0 0 10px;
}
.form-control.rounded-end {
border-radius: 0 10px 10px 0;
}
</style>
{% endblock %}
{% block content %}
<div class="container">
<div class="row justify-content-center">
<div class="col-md-10">
<!-- Progress Indicator -->
<div class="step-indicator">
<div class="step completed">1</div>
<div class="step active">2</div>
<div class="step inactive">3</div>
</div>
<div class="card">
<div class="card-header bg-transparent text-center py-4">
<h2 class="mb-0">
<i class="fas fa-cogs text-primary me-2"></i>
Step 2: Configure Your Question Paper
</h2>
<p class="text-muted mt-2">Choose the types and number of questions for your exam paper</p>
<div class="badge bg-info">
<i class="fas fa-file-text me-1"></i>
Syllabus loaded: {{ word_count }} words
</div>
</div>
<div class="card-body p-4">
{% if error %}
<div class="alert alert-danger" role="alert">
<i class="fas fa-exclamation-triangle me-2"></i>{{ error }}
</div>
{% endif %}
<form action="{{ url_for('step3_generate') }}" method="POST" id="configForm">
<!-- Exam Details -->
<div class="row mb-4">
<div class="col-md-12">
<div class="question-type-card">
<div class="row g-3">
<div class="col-md-4">
<label class="form-label">Exam Name (optional)</label>
<input type="text" class="form-control" name="exam_name" id="exam_name" placeholder="e.g., Midterm Examination">
</div>
<div class="col-md-4">
<label class="form-label">Subject Name (optional)</label>
<input type="text" class="form-control" name="subject_name" id="subject_name" placeholder="e.g., Computer Science">
</div>
<div class="col-md-4">
<label class="form-label">Exam Duration (optional)</label>
<input type="text" class="form-control" name="exam_duration" id="exam_duration" placeholder="e.g., 180, 3h, 3 hours, 2h 30m">
</div>
</div>
</div>
</div>
</div>
<div class="row">
<!-- Multiple Choice Questions -->
<div class="col-md-4">
<div class="question-type-card" id="mcqCard">
<div class="text-center mb-3">
<i class="fas fa-list-ul fa-3x text-warning"></i>
<h5 class="mt-2">Multiple Choice Questions</h5>
<p class="text-muted small">Questions with multiple options to choose from</p>
</div>
<div class="mb-3">
<label class="form-label">Number of Questions</label>
<input type="number" class="form-control" name="mcq_questions" id="mcq_questions"
value="0" min="0" max="30" onchange="updatePreview()">
</div>
<div class="mb-3">
<label class="form-label">Marks per Question</label>
<div class="input-group">
<input type="number" class="form-control rounded-end" value="1" readonly>
<span class="input-group-text">mark</span>
</div>
<div class="form-text">MCQ questions are typically 1 mark each</div>
</div>
<div class="text-center">
<span class="badge bg-warning" id="mcqTotal">0 marks total</span>
</div>
</div>
</div>
<!-- Short Answer Questions -->
<div class="col-md-4">
<div class="question-type-card" id="shortCard">
<div class="text-center mb-3">
<i class="fas fa-edit fa-3x text-primary"></i>
<h5 class="mt-2">Short Answer Questions</h5>
<p class="text-muted small">Brief, focused questions requiring concise answers</p>
</div>
<div class="mb-3">
<label class="form-label">Number of Questions</label>
<input type="number" class="form-control" name="short_questions" id="short_questions"
value="0" min="0" max="20" onchange="updatePreview()">
</div>
<div class="mb-3">
<label class="form-label">Marks per Question</label>
<div class="input-group">
<input type="number" class="form-control rounded-end" name="short_marks" id="short_marks"
value="3" min="1" max="10" onchange="updatePreview()">
<span class="input-group-text">marks</span>
</div>
</div>
<div class="form-check mb-3">
<input class="form-check-input" type="checkbox" value="1" id="short_or" name="short_or" onchange="updatePreview()">
<label class="form-check-label" for="short_or">
Provide an 'OR' alternative for each short question
</label>
</div>
<div class="text-center">
<span class="badge bg-primary" id="shortTotal">0 marks total</span>
</div>
</div>
</div>
<!-- Long Answer Questions -->
<div class="col-md-4">
<div class="question-type-card" id="longCard">
<div class="text-center mb-3">
<i class="fas fa-file-alt fa-3x text-success"></i>
<h5 class="mt-2">Long Answer Questions</h5>
<p class="text-muted small">Detailed questions requiring comprehensive answers</p>
</div>
<div class="mb-3">
<label class="form-label">Number of Questions</label>
<input type="number" class="form-control" name="long_questions" id="long_questions"
value="0" min="0" max="10" onchange="updatePreview()">
</div>
<div class="mb-3">
<label class="form-label">Marks per Question</label>
<div class="input-group">
<input type="number" class="form-control rounded-end" name="long_marks" id="long_marks"
value="10" min="5" max="25" onchange="updatePreview()">
<span class="input-group-text">marks</span>
</div>
</div>
<div class="mb-3">
<label class="form-label">Attempt any (optional)</label>
<div class="input-group">
<input type="number" class="form-control rounded-end" name="long_attempt" id="long_attempt"
value="" min="0" max="10" placeholder="e.g., 3" onchange="updatePreview()">
<span class="input-group-text">questions</span>
</div>
<div class="form-text">If set, students will be instructed to attempt only this many long questions.</div>
</div>
<div class="text-center">
<span class="badge bg-success" id="longTotal">0 marks total</span>
</div>
</div>
</div>
</div>
<!-- Summary Card -->
<div class="row mt-4">
<div class="col-md-12">
<div class="marks-preview">
<h4 class="mb-3">
<i class="fas fa-calculator me-2"></i>
Question Paper Summary
</h4>
<div class="row">
<div class="col-md-3 text-center">
<h5 id="totalQuestions">0</h5>
<small>Total Questions</small>
</div>
<div class="col-md-3 text-center">
<h5 id="totalMarks">0</h5>
<small>Total Marks</small>
</div>
<div class="col-md-3 text-center">
<h5 id="estimatedTime">0</h5>
<small>Estimated Time (min)</small>
</div>
<div class="col-md-3 text-center">
<h5 id="difficulty">Easy</h5>
<small>Difficulty Level</small>
</div>
</div>
</div>
</div>
</div>
<!-- Action Buttons -->
<div class="row mt-4">
<div class="col-md-6">
<a href="/" class="btn btn-secondary btn-lg w-100">
<i class="fas fa-arrow-left me-2"></i>
Back to Input
</a>
</div>
<div class="col-md-6">
<button type="submit" class="btn btn-primary btn-lg w-100" id="generateBtn">
<i class="fas fa-magic me-2"></i>
Generate Question Paper
</button>
</div>
</div>
</form>
</div>
</div>
<!-- Tips Card -->
<div class="card mt-4">
<div class="card-body">
<h5 class="card-title">
<i class="fas fa-lightbulb text-warning me-2"></i>
Configuration Tips
</h5>
<div class="row">
<div class="col-md-4">
<h6><i class="fas fa-list-ul text-warning me-2"></i>MCQ Questions</h6>
<small class="text-muted">Great for testing factual knowledge and quick assessment. Usually 1 mark each.</small>
</div>
<div class="col-md-4">
<h6><i class="fas fa-edit text-primary me-2"></i>Short Questions</h6>
<small class="text-muted">Best for definitions, concepts, and quick explanations. Usually 2-5 marks.</small>
</div>
<div class="col-md-4">
<h6><i class="fas fa-file-alt text-success me-2"></i>Long Questions</h6>
<small class="text-muted">Perfect for detailed explanations, analysis, and comprehensive answers. Usually 8-15 marks.</small>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
{% block scripts %}
<script>
function updatePreview() {
const shortQuestions = parseInt(document.getElementById('short_questions').value) || 0;
const longQuestions = parseInt(document.getElementById('long_questions').value) || 0;
const mcqQuestions = parseInt(document.getElementById('mcq_questions').value) || 0;
const shortMarks = parseInt(document.getElementById('short_marks').value) || 3;
const longMarks = parseInt(document.getElementById('long_marks').value) || 10;
// Calculate totals
const shortTotal = shortQuestions * shortMarks;
const longTotal = longQuestions * longMarks;
const mcqTotal = mcqQuestions * 1; // MCQ is always 1 mark
const totalQuestions = shortQuestions + longQuestions + mcqQuestions;
const totalMarks = shortTotal + longTotal + mcqTotal;
// Update individual totals
document.getElementById('shortTotal').textContent = shortTotal + ' marks total';
document.getElementById('longTotal').textContent = longTotal + ' marks total';
document.getElementById('mcqTotal').textContent = mcqTotal + ' marks total';
// Update summary
document.getElementById('totalQuestions').textContent = totalQuestions;
document.getElementById('totalMarks').textContent = totalMarks;
// Estimate time unless custom duration provided (supports formats like '3 hours', '2h 30m')
const customDurationRaw = document.getElementById('exam_duration').value.trim();
let customDuration = parseInt(customDurationRaw);
if (customDurationRaw && isNaN(customDuration)) {
const lower = customDurationRaw.toLowerCase();
// crude parse: extract h and m
let minutesParsed = 0;
const hMatch = lower.match(/(\d+)\s*h/);
const mMatch = lower.match(/(\d+)\s*m/);
if (hMatch) minutesParsed += parseInt(hMatch[1], 10) * 60;
if (mMatch) minutesParsed += parseInt(mMatch[1], 10);
if (minutesParsed > 0) customDuration = minutesParsed;
}
const estimatedTime = Math.round(totalMarks * 1.5);
const timeToShow = (!isNaN(customDuration) && customDuration > 0) ? customDuration : estimatedTime;
document.getElementById('estimatedTime').textContent = timeToShow;
// Determine difficulty
let difficulty = 'Easy';
if (totalMarks > 50) difficulty = 'Medium';
if (totalMarks > 100) difficulty = 'Hard';
document.getElementById('difficulty').textContent = difficulty;
// Update card styles
updateCardStyles(shortQuestions, longQuestions, mcqQuestions);
// Enable/disable generate button
const generateBtn = document.getElementById('generateBtn');
if (totalQuestions > 0) {
generateBtn.disabled = false;
generateBtn.innerHTML = '<i class="fas fa-magic me-2"></i>Generate Question Paper';
} else {
generateBtn.disabled = true;
generateBtn.innerHTML = '<i class="fas fa-exclamation-triangle me-2"></i>Select at least one question type';
}
}
function updateCardStyles(short, long, mcq) {
const shortCard = document.getElementById('shortCard');
const longCard = document.getElementById('longCard');
const mcqCard = document.getElementById('mcqCard');
// Remove active class from all cards
[shortCard, longCard, mcqCard].forEach(card => card.classList.remove('active'));
// Add active class to cards with questions
if (short > 0) shortCard.classList.add('active');
if (long > 0) longCard.classList.add('active');
if (mcq > 0) mcqCard.classList.add('active');
}
// Form validation and loading state
document.getElementById('configForm').addEventListener('submit', function(e) {
const totalQuestions = parseInt(document.getElementById('totalQuestions').textContent);
if (totalQuestions === 0) {
e.preventDefault();
alert('Please select at least one question type before generating the paper.');
return;
}
// Show loading state
const generateBtn = document.getElementById('generateBtn');
const originalText = generateBtn.innerHTML;
generateBtn.disabled = true;
generateBtn.innerHTML = '<i class="fas fa-spinner fa-spin me-2"></i>Generating Questions... Please wait';
// Show loading message
const loadingDiv = document.createElement('div');
loadingDiv.id = 'loadingMessage';
loadingDiv.className = 'alert alert-info mt-3';
loadingDiv.innerHTML = `
<div class="d-flex align-items-center">
<div class="spinner-border spinner-border-sm me-3" role="status">
<span class="visually-hidden">Loading...</span>
</div>
<div>
<strong>Generating your question paper...</strong><br>
<small>This may take 30-60 seconds. Please don't refresh the page.</small>
</div>
</div>
`;
// Insert loading message after the form
const form = document.getElementById('configForm');
form.parentNode.insertBefore(loadingDiv, form.nextSibling);
// Timeout fallback - if it takes too long, show error message
setTimeout(function() {
if (document.getElementById('loadingMessage')) {
const errorDiv = document.createElement('div');
errorDiv.className = 'alert alert-warning mt-2';
errorDiv.innerHTML = `
<strong>Taking longer than expected...</strong><br>
The system might be initializing. Please wait a bit more or try refreshing the page if it doesn't respond.
`;
loadingDiv.appendChild(errorDiv);
}
}, 30000); // 30 seconds
});
// Initialize preview
updatePreview();
</script>
{% endblock %}