Spaces:
Sleeping
Sleeping
Commit ·
a0ae5a7
1
Parent(s): 43de021
Add templates
Browse files- templates/base.html +33 -0
- templates/index.html +258 -0
- templates/navbar.html +16 -0
- templates/printable_paper.html +232 -0
- templates/step1_input.html +297 -0
- templates/step2_config.html +471 -0
- templates/step3_result.html +392 -0
- templates/welcome.html +115 -0
templates/base.html
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<!DOCTYPE html>
|
| 2 |
+
<html lang="en">
|
| 3 |
+
<head>
|
| 4 |
+
<meta charset="UTF-8">
|
| 5 |
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
| 6 |
+
<title>{% block title %}AutoExamGen{% endblock %}</title>
|
| 7 |
+
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
|
| 8 |
+
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet">
|
| 9 |
+
{% block head %}{% endblock %}
|
| 10 |
+
</head>
|
| 11 |
+
<body>
|
| 12 |
+
{% include 'navbar.html' %}
|
| 13 |
+
<main>
|
| 14 |
+
{% with messages = get_flashed_messages(with_categories=true) %}
|
| 15 |
+
{% if messages %}
|
| 16 |
+
<div class="container mt-3">
|
| 17 |
+
{% for category, message in messages %}
|
| 18 |
+
<div class="alert alert-{{ 'danger' if category == 'error' else category }} alert-dismissible fade show" role="alert">
|
| 19 |
+
<i class="fas fa-{{ 'exclamation-triangle' if category == 'error' else 'info-circle' }} me-2"></i>
|
| 20 |
+
{{ message }}
|
| 21 |
+
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
| 22 |
+
</div>
|
| 23 |
+
{% endfor %}
|
| 24 |
+
</div>
|
| 25 |
+
{% endif %}
|
| 26 |
+
{% endwith %}
|
| 27 |
+
{% block content %}{% endblock %}
|
| 28 |
+
</main>
|
| 29 |
+
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
|
| 30 |
+
{% block scripts %}{% endblock %}
|
| 31 |
+
</body>
|
| 32 |
+
</html>
|
| 33 |
+
|
templates/index.html
ADDED
|
@@ -0,0 +1,258 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<!DOCTYPE html>
|
| 2 |
+
<html lang="en">
|
| 3 |
+
<head>
|
| 4 |
+
<meta charset="UTF-8">
|
| 5 |
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
| 6 |
+
<title>Exam Question Generator</title>
|
| 7 |
+
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
|
| 8 |
+
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet">
|
| 9 |
+
<style>
|
| 10 |
+
body {
|
| 11 |
+
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
| 12 |
+
min-height: 100vh;
|
| 13 |
+
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
| 14 |
+
}
|
| 15 |
+
.container {
|
| 16 |
+
padding-top: 2rem;
|
| 17 |
+
}
|
| 18 |
+
.card {
|
| 19 |
+
border: none;
|
| 20 |
+
border-radius: 15px;
|
| 21 |
+
box-shadow: 0 10px 30px rgba(0,0,0,0.1);
|
| 22 |
+
}
|
| 23 |
+
.btn-primary {
|
| 24 |
+
background: linear-gradient(45deg, #667eea, #764ba2);
|
| 25 |
+
border: none;
|
| 26 |
+
border-radius: 25px;
|
| 27 |
+
padding: 12px 30px;
|
| 28 |
+
}
|
| 29 |
+
.btn-primary:hover {
|
| 30 |
+
transform: translateY(-2px);
|
| 31 |
+
box-shadow: 0 5px 15px rgba(0,0,0,0.2);
|
| 32 |
+
}
|
| 33 |
+
.form-control, .form-select {
|
| 34 |
+
border-radius: 10px;
|
| 35 |
+
border: 2px solid #e9ecef;
|
| 36 |
+
}
|
| 37 |
+
.form-control:focus, .form-select:focus {
|
| 38 |
+
border-color: #667eea;
|
| 39 |
+
box-shadow: 0 0 0 0.2rem rgba(102, 126, 234, 0.25);
|
| 40 |
+
}
|
| 41 |
+
.question-card {
|
| 42 |
+
margin-bottom: 1.5rem;
|
| 43 |
+
border-left: 4px solid #667eea;
|
| 44 |
+
}
|
| 45 |
+
.option {
|
| 46 |
+
padding: 8px 15px;
|
| 47 |
+
margin: 5px 0;
|
| 48 |
+
border-radius: 8px;
|
| 49 |
+
background-color: #f8f9fa;
|
| 50 |
+
}
|
| 51 |
+
.correct-option {
|
| 52 |
+
background-color: #d4edda;
|
| 53 |
+
border: 1px solid #c3e6cb;
|
| 54 |
+
}
|
| 55 |
+
.loading {
|
| 56 |
+
display: none;
|
| 57 |
+
}
|
| 58 |
+
.spinner-border {
|
| 59 |
+
width: 1.5rem;
|
| 60 |
+
height: 1.5rem;
|
| 61 |
+
}
|
| 62 |
+
</style>
|
| 63 |
+
</head>
|
| 64 |
+
<body>
|
| 65 |
+
<div class="container">
|
| 66 |
+
<div class="row justify-content-center">
|
| 67 |
+
<div class="col-md-10">
|
| 68 |
+
<div class="text-center mb-4">
|
| 69 |
+
<h1 class="text-white mb-3">
|
| 70 |
+
<i class="fas fa-brain"></i> Exam Question Generator
|
| 71 |
+
</h1>
|
| 72 |
+
<p class="text-white-50">Generate intelligent exam questions from any text using AI</p>
|
| 73 |
+
</div>
|
| 74 |
+
|
| 75 |
+
<div class="card">
|
| 76 |
+
<div class="card-body p-4">
|
| 77 |
+
<form id="questionForm">
|
| 78 |
+
<div class="row">
|
| 79 |
+
<div class="col-md-8">
|
| 80 |
+
<div class="mb-3">
|
| 81 |
+
<label for="textInput" class="form-label">
|
| 82 |
+
<i class="fas fa-edit"></i> Enter Text or Upload File
|
| 83 |
+
</label>
|
| 84 |
+
<textarea class="form-control" id="textInput" name="text_input" rows="8"
|
| 85 |
+
placeholder="Paste your text here or upload a file below..."></textarea>
|
| 86 |
+
</div>
|
| 87 |
+
|
| 88 |
+
<div class="mb-3">
|
| 89 |
+
<label for="fileInput" class="form-label">
|
| 90 |
+
<i class="fas fa-upload"></i> Or Upload Text File
|
| 91 |
+
</label>
|
| 92 |
+
<input class="form-control" type="file" id="fileInput" name="file" accept=".txt,.md">
|
| 93 |
+
</div>
|
| 94 |
+
</div>
|
| 95 |
+
|
| 96 |
+
<div class="col-md-4">
|
| 97 |
+
<div class="mb-3">
|
| 98 |
+
<label for="maxQuestions" class="form-label">
|
| 99 |
+
<i class="fas fa-hashtag"></i> Number of Questions
|
| 100 |
+
</label>
|
| 101 |
+
<select class="form-select" id="maxQuestions" name="max_questions">
|
| 102 |
+
<option value="3">3 Questions</option>
|
| 103 |
+
<option value="5" selected>5 Questions</option>
|
| 104 |
+
<option value="8">8 Questions</option>
|
| 105 |
+
<option value="10">10 Questions</option>
|
| 106 |
+
</select>
|
| 107 |
+
</div>
|
| 108 |
+
|
| 109 |
+
<div class="mb-3">
|
| 110 |
+
<div class="form-check">
|
| 111 |
+
<input class="form-check-input" type="checkbox" id="includeMCQ" name="include_mcq" checked>
|
| 112 |
+
<label class="form-check-label" for="includeMCQ">
|
| 113 |
+
<i class="fas fa-list"></i> Generate Multiple Choice Options
|
| 114 |
+
</label>
|
| 115 |
+
</div>
|
| 116 |
+
</div>
|
| 117 |
+
|
| 118 |
+
<button type="submit" class="btn btn-primary w-100">
|
| 119 |
+
<span class="btn-text">
|
| 120 |
+
<i class="fas fa-magic"></i> Generate Questions
|
| 121 |
+
</span>
|
| 122 |
+
<span class="loading">
|
| 123 |
+
<span class="spinner-border spinner-border-sm me-2"></span>
|
| 124 |
+
Generating...
|
| 125 |
+
</span>
|
| 126 |
+
</button>
|
| 127 |
+
</div>
|
| 128 |
+
</div>
|
| 129 |
+
</form>
|
| 130 |
+
</div>
|
| 131 |
+
</div>
|
| 132 |
+
|
| 133 |
+
<div id="results" class="mt-4" style="display: none;">
|
| 134 |
+
<div class="card">
|
| 135 |
+
<div class="card-header bg-primary text-white">
|
| 136 |
+
<h5 class="mb-0"><i class="fas fa-question-circle"></i> Generated Questions</h5>
|
| 137 |
+
</div>
|
| 138 |
+
<div class="card-body" id="questionsContainer">
|
| 139 |
+
<!-- Questions will be populated here -->
|
| 140 |
+
</div>
|
| 141 |
+
</div>
|
| 142 |
+
</div>
|
| 143 |
+
</div>
|
| 144 |
+
</div>
|
| 145 |
+
</div>
|
| 146 |
+
|
| 147 |
+
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
|
| 148 |
+
<script>
|
| 149 |
+
document.getElementById('questionForm').addEventListener('submit', async function(e) {
|
| 150 |
+
e.preventDefault();
|
| 151 |
+
|
| 152 |
+
const btn = document.querySelector('button[type="submit"]');
|
| 153 |
+
const btnText = btn.querySelector('.btn-text');
|
| 154 |
+
const loading = btn.querySelector('.loading');
|
| 155 |
+
const results = document.getElementById('results');
|
| 156 |
+
|
| 157 |
+
// Show loading state
|
| 158 |
+
btnText.style.display = 'none';
|
| 159 |
+
loading.style.display = 'inline';
|
| 160 |
+
btn.disabled = true;
|
| 161 |
+
|
| 162 |
+
try {
|
| 163 |
+
const formData = new FormData(this);
|
| 164 |
+
const response = await fetch('/generate', {
|
| 165 |
+
method: 'POST',
|
| 166 |
+
body: formData
|
| 167 |
+
});
|
| 168 |
+
|
| 169 |
+
const data = await response.json();
|
| 170 |
+
|
| 171 |
+
if (data.success) {
|
| 172 |
+
displayQuestions(data.data);
|
| 173 |
+
results.style.display = 'block';
|
| 174 |
+
results.scrollIntoView({ behavior: 'smooth' });
|
| 175 |
+
} else {
|
| 176 |
+
alert('Error: ' + (data.error || 'Unknown error occurred'));
|
| 177 |
+
}
|
| 178 |
+
} catch (error) {
|
| 179 |
+
alert('Error: ' + error.message);
|
| 180 |
+
} finally {
|
| 181 |
+
// Hide loading state
|
| 182 |
+
btnText.style.display = 'inline';
|
| 183 |
+
loading.style.display = 'none';
|
| 184 |
+
btn.disabled = false;
|
| 185 |
+
}
|
| 186 |
+
});
|
| 187 |
+
|
| 188 |
+
function displayQuestions(data) {
|
| 189 |
+
const container = document.getElementById('questionsContainer');
|
| 190 |
+
let html = '';
|
| 191 |
+
|
| 192 |
+
// Display statistics
|
| 193 |
+
html += `
|
| 194 |
+
<div class="row mb-4">
|
| 195 |
+
<div class="col-md-3 text-center">
|
| 196 |
+
<div class="bg-light p-3 rounded">
|
| 197 |
+
<h4 class="text-primary">${data.metadata.questions_generated}</h4>
|
| 198 |
+
<small>Questions</small>
|
| 199 |
+
</div>
|
| 200 |
+
</div>
|
| 201 |
+
<div class="col-md-3 text-center">
|
| 202 |
+
<div class="bg-light p-3 rounded">
|
| 203 |
+
<h4 class="text-success">${data.metadata.keywords_extracted}</h4>
|
| 204 |
+
<small>Keywords</small>
|
| 205 |
+
</div>
|
| 206 |
+
</div>
|
| 207 |
+
<div class="col-md-3 text-center">
|
| 208 |
+
<div class="bg-light p-3 rounded">
|
| 209 |
+
<h4 class="text-info">${data.metadata.input_word_count}</h4>
|
| 210 |
+
<small>Words</small>
|
| 211 |
+
</div>
|
| 212 |
+
</div>
|
| 213 |
+
<div class="col-md-3 text-center">
|
| 214 |
+
<div class="bg-light p-3 rounded">
|
| 215 |
+
<h4 class="text-warning">${data.metadata.named_entities}</h4>
|
| 216 |
+
<small>Entities</small>
|
| 217 |
+
</div>
|
| 218 |
+
</div>
|
| 219 |
+
</div>
|
| 220 |
+
`;
|
| 221 |
+
|
| 222 |
+
// Display questions
|
| 223 |
+
data.questions.forEach((q, index) => {
|
| 224 |
+
html += `
|
| 225 |
+
<div class="question-card card mb-3">
|
| 226 |
+
<div class="card-body">
|
| 227 |
+
<h6 class="card-title">Question ${index + 1}</h6>
|
| 228 |
+
<p class="card-text fw-bold">${q.question}</p>
|
| 229 |
+
`;
|
| 230 |
+
|
| 231 |
+
if (q.options) {
|
| 232 |
+
html += '<div class="options mt-3">';
|
| 233 |
+
q.options.forEach((option, optIndex) => {
|
| 234 |
+
const isCorrect = optIndex === q.correct_index;
|
| 235 |
+
html += `
|
| 236 |
+
<div class="option ${isCorrect ? 'correct-option' : ''}">
|
| 237 |
+
${String.fromCharCode(65 + optIndex)}. ${option}
|
| 238 |
+
${isCorrect ? '<i class="fas fa-check text-success float-end"></i>' : ''}
|
| 239 |
+
</div>
|
| 240 |
+
`;
|
| 241 |
+
});
|
| 242 |
+
html += '</div>';
|
| 243 |
+
}
|
| 244 |
+
|
| 245 |
+
html += `
|
| 246 |
+
<small class="text-muted">
|
| 247 |
+
<strong>Context:</strong> ${q.context.substring(0, 100)}...
|
| 248 |
+
</small>
|
| 249 |
+
</div>
|
| 250 |
+
</div>
|
| 251 |
+
`;
|
| 252 |
+
});
|
| 253 |
+
|
| 254 |
+
container.innerHTML = html;
|
| 255 |
+
}
|
| 256 |
+
</script>
|
| 257 |
+
</body>
|
| 258 |
+
</html>
|
templates/navbar.html
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<nav class="navbar navbar-expand-lg navbar-dark" style="background: linear-gradient(45deg, #667eea, #764ba2);">
|
| 2 |
+
<div class="container">
|
| 3 |
+
<a class="navbar-brand fw-bold" href="/">
|
| 4 |
+
<i class="fas fa-bolt me-2"></i>AutoExamGen
|
| 5 |
+
</a>
|
| 6 |
+
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#mainNav" aria-controls="mainNav" aria-expanded="false" aria-label="Toggle navigation">
|
| 7 |
+
<span class="navbar-toggler-icon"></span>
|
| 8 |
+
</button>
|
| 9 |
+
<div class="collapse navbar-collapse" id="mainNav">
|
| 10 |
+
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
|
| 11 |
+
<li class="nav-item"><a class="nav-link" href="/">Home</a></li>
|
| 12 |
+
<li class="nav-item"><a class="nav-link" href="/step1">Start</a></li>
|
| 13 |
+
</ul>
|
| 14 |
+
</div>
|
| 15 |
+
</div>
|
| 16 |
+
</nav>
|
templates/printable_paper.html
ADDED
|
@@ -0,0 +1,232 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{% extends 'base.html' %}
|
| 2 |
+
{% block title %}Printable Paper - AutoExamGen{% endblock %}
|
| 3 |
+
{% block head %}
|
| 4 |
+
<style>
|
| 5 |
+
body {
|
| 6 |
+
font-family: 'Times New Roman', serif;
|
| 7 |
+
line-height: 1.6;
|
| 8 |
+
margin: 0;
|
| 9 |
+
padding: 20px;
|
| 10 |
+
background: white;
|
| 11 |
+
color: #000;
|
| 12 |
+
}
|
| 13 |
+
.paper-header {
|
| 14 |
+
text-align: center;
|
| 15 |
+
border-bottom: 2px solid #000;
|
| 16 |
+
padding-bottom: 20px;
|
| 17 |
+
margin-bottom: 30px;
|
| 18 |
+
}
|
| 19 |
+
.paper-header h1 {
|
| 20 |
+
font-size: 24px;
|
| 21 |
+
font-weight: bold;
|
| 22 |
+
margin: 10px 0;
|
| 23 |
+
text-transform: uppercase;
|
| 24 |
+
}
|
| 25 |
+
.paper-header h3 {
|
| 26 |
+
font-size: 18px;
|
| 27 |
+
margin: 10px 0;
|
| 28 |
+
}
|
| 29 |
+
.paper-header p {
|
| 30 |
+
margin: 5px 0;
|
| 31 |
+
font-size: 14px;
|
| 32 |
+
}
|
| 33 |
+
.instructions {
|
| 34 |
+
text-align: left;
|
| 35 |
+
display: inline-block;
|
| 36 |
+
margin: 10px 0;
|
| 37 |
+
}
|
| 38 |
+
.instructions li {
|
| 39 |
+
margin: 5px 0;
|
| 40 |
+
}
|
| 41 |
+
.section-header {
|
| 42 |
+
background: #f0f0f0;
|
| 43 |
+
border: 1px solid #000;
|
| 44 |
+
padding: 10px;
|
| 45 |
+
margin: 25px 0 15px 0;
|
| 46 |
+
font-weight: bold;
|
| 47 |
+
font-size: 16px;
|
| 48 |
+
text-transform: uppercase;
|
| 49 |
+
}
|
| 50 |
+
.question {
|
| 51 |
+
margin-bottom: 25px;
|
| 52 |
+
padding: 15px 0;
|
| 53 |
+
border-bottom: 1px solid #ddd;
|
| 54 |
+
page-break-inside: avoid;
|
| 55 |
+
}
|
| 56 |
+
.question:last-child {
|
| 57 |
+
border-bottom: none;
|
| 58 |
+
}
|
| 59 |
+
.question-number {
|
| 60 |
+
font-weight: bold;
|
| 61 |
+
font-size: 16px;
|
| 62 |
+
}
|
| 63 |
+
.question-marks {
|
| 64 |
+
float: right;
|
| 65 |
+
font-weight: bold;
|
| 66 |
+
border: 1px solid #000;
|
| 67 |
+
padding: 3px 8px;
|
| 68 |
+
font-size: 12px;
|
| 69 |
+
}
|
| 70 |
+
.question-text {
|
| 71 |
+
margin-top: 5px;
|
| 72 |
+
font-size: 14px;
|
| 73 |
+
clear: both;
|
| 74 |
+
}
|
| 75 |
+
.mcq-options {
|
| 76 |
+
margin-top: 10px;
|
| 77 |
+
padding-left: 20px;
|
| 78 |
+
}
|
| 79 |
+
.mcq-option {
|
| 80 |
+
margin: 8px 0;
|
| 81 |
+
font-size: 14px;
|
| 82 |
+
}
|
| 83 |
+
.answer-space {
|
| 84 |
+
margin-top: 15px;
|
| 85 |
+
border-bottom: 1px dotted #999;
|
| 86 |
+
height: 60px;
|
| 87 |
+
}
|
| 88 |
+
.long-answer-space {
|
| 89 |
+
margin-top: 15px;
|
| 90 |
+
border-bottom: 1px dotted #999;
|
| 91 |
+
height: 120px;
|
| 92 |
+
}
|
| 93 |
+
.footer {
|
| 94 |
+
text-align: center;
|
| 95 |
+
margin-top: 40px;
|
| 96 |
+
padding-top: 20px;
|
| 97 |
+
border-top: 1px solid #000;
|
| 98 |
+
font-size: 12px;
|
| 99 |
+
}
|
| 100 |
+
@media print {
|
| 101 |
+
body {
|
| 102 |
+
margin: 0;
|
| 103 |
+
padding: 15px;
|
| 104 |
+
}
|
| 105 |
+
.question {
|
| 106 |
+
page-break-inside: avoid;
|
| 107 |
+
}
|
| 108 |
+
.section-header {
|
| 109 |
+
page-break-after: avoid;
|
| 110 |
+
}
|
| 111 |
+
}
|
| 112 |
+
@page {
|
| 113 |
+
margin: 1in;
|
| 114 |
+
size: A4;
|
| 115 |
+
}
|
| 116 |
+
</style>
|
| 117 |
+
{% endblock %}
|
| 118 |
+
{% block content %}
|
| 119 |
+
<div class="paper-header">
|
| 120 |
+
<h1>{{ config.exam_name if config.exam_name else 'EXAMINATION QUESTION PAPER' }}</h1>
|
| 121 |
+
<h3>Subject: {{ config.subject_name if config.subject_name else '[Subject Name]' }}</h3>
|
| 122 |
+
<p><strong>Date:</strong> {{ exam_date }} <strong>Time:</strong> {{ display_duration }} minutes <strong>Total Marks:</strong> {{ total_marks }}</p>
|
| 123 |
+
<hr style="border: 1px solid #000; margin: 15px 0;">
|
| 124 |
+
<p><strong>INSTRUCTIONS:</strong></p>
|
| 125 |
+
<ul class="instructions">
|
| 126 |
+
<li>Answer all questions.</li>
|
| 127 |
+
<li>Write clearly and legibly.</li>
|
| 128 |
+
<li>Manage your time effectively.</li>
|
| 129 |
+
{% if config.mcq_questions > 0 %}
|
| 130 |
+
<li>For multiple choice questions, choose the best answer.</li>
|
| 131 |
+
{% endif %}
|
| 132 |
+
<li>Use additional answer sheets if necessary.</li>
|
| 133 |
+
</ul>
|
| 134 |
+
</div>
|
| 135 |
+
|
| 136 |
+
<!-- Multiple Choice Questions -->
|
| 137 |
+
{% if config.mcq_questions > 0 and question_paper.mcq_questions %}
|
| 138 |
+
<div class="section-header">
|
| 139 |
+
SECTION A: MULTIPLE CHOICE QUESTIONS (1 mark each)
|
| 140 |
+
</div>
|
| 141 |
+
<p><strong>Choose the best answer for each question. Circle the letter of your choice.</strong></p>
|
| 142 |
+
{% for question in question_paper.mcq_questions %}
|
| 143 |
+
<div class="question">
|
| 144 |
+
<span class="question-marks">[1 mark]</span>
|
| 145 |
+
<span class="question-number">{{ loop.index }}.</span>
|
| 146 |
+
<div class="question-text">
|
| 147 |
+
{{ question.question if question.question else question }}
|
| 148 |
+
</div>
|
| 149 |
+
|
| 150 |
+
<div class="mcq-options">
|
| 151 |
+
{% if question.options %}
|
| 152 |
+
{% for option in question.options %}
|
| 153 |
+
<div class="mcq-option">
|
| 154 |
+
<strong>{{ ['A', 'B', 'C', 'D'][loop.index0] }})</strong> {{ option }}
|
| 155 |
+
</div>
|
| 156 |
+
{% endfor %}
|
| 157 |
+
{% else %}
|
| 158 |
+
<div class="mcq-option"><strong>A)</strong> [Option A]</div>
|
| 159 |
+
<div class="mcq-option"><strong>B)</strong> [Option B]</div>
|
| 160 |
+
<div class="mcq-option"><strong>C)</strong> [Option C]</div>
|
| 161 |
+
<div class="mcq-option"><strong>D)</strong> [Option D]</div>
|
| 162 |
+
{% endif %}
|
| 163 |
+
</div>
|
| 164 |
+
</div>
|
| 165 |
+
{% endfor %}
|
| 166 |
+
{% endif %}
|
| 167 |
+
|
| 168 |
+
<!-- Short Answer Questions -->
|
| 169 |
+
{% if config.short_questions > 0 and question_paper.short_questions %}
|
| 170 |
+
<div class="section-header">
|
| 171 |
+
SECTION B: SHORT ANSWER QUESTIONS ({{ config.short_marks }} marks each)
|
| 172 |
+
</div>
|
| 173 |
+
{% if config.short_or %}
|
| 174 |
+
<p><strong>Answer ALL questions in this section. For each question, answer either Question A or Question B.</strong></p>
|
| 175 |
+
{% else %}
|
| 176 |
+
<p><strong>Answer ALL questions in this section.</strong></p>
|
| 177 |
+
{% endif %}
|
| 178 |
+
{% for item in question_paper.short_questions %}
|
| 179 |
+
{% if config.short_or and (item.a or item.b) %}
|
| 180 |
+
<div class="question">
|
| 181 |
+
<span class="question-marks">[{{ config.short_marks }} marks]</span>
|
| 182 |
+
<span class="question-number">{{ loop.index }}.</span>
|
| 183 |
+
<div class="question-text">
|
| 184 |
+
<div><strong>A)</strong> {{ (item.a.question if item.a.question else item.a) if item.a else '' }}</div>
|
| 185 |
+
{% if item.b %}
|
| 186 |
+
<div class="text-center" style="margin: 8px 0;"><em>OR</em></div>
|
| 187 |
+
<div><strong>B)</strong> {{ (item.b.question if item.b.question else item.b) if item.b else '' }}</div>
|
| 188 |
+
{% endif %}
|
| 189 |
+
</div>
|
| 190 |
+
<div class="answer-space"></div>
|
| 191 |
+
</div>
|
| 192 |
+
{% else %}
|
| 193 |
+
<div class="question">
|
| 194 |
+
<span class="question-marks">[{{ config.short_marks }} marks]</span>
|
| 195 |
+
<span class="question-number">{{ loop.index }}.</span>
|
| 196 |
+
<div class="question-text">
|
| 197 |
+
{{ item.question if item.question else item }}
|
| 198 |
+
</div>
|
| 199 |
+
<div class="answer-space"></div>
|
| 200 |
+
</div>
|
| 201 |
+
{% endif %}
|
| 202 |
+
{% endfor %}
|
| 203 |
+
{% endif %}
|
| 204 |
+
|
| 205 |
+
<!-- Long Answer Questions -->
|
| 206 |
+
{% if config.long_questions > 0 and question_paper.long_questions %}
|
| 207 |
+
<div class="section-header">
|
| 208 |
+
SECTION C: LONG ANSWER QUESTIONS ({{ config.long_marks }} marks each)
|
| 209 |
+
</div>
|
| 210 |
+
{% if config.long_attempt %}
|
| 211 |
+
<p><strong>Attempt any {{ config.long_attempt }} out of {{ config.long_questions }} questions.</strong></p>
|
| 212 |
+
{% else %}
|
| 213 |
+
<p><strong>Answer ALL questions in this section.</strong></p>
|
| 214 |
+
{% endif %}
|
| 215 |
+
{% for question in question_paper.long_questions %}
|
| 216 |
+
<div class="question">
|
| 217 |
+
<span class="question-marks">[{{ config.long_marks }} marks]</span>
|
| 218 |
+
<span class="question-number">{{ loop.index }}.</span>
|
| 219 |
+
<div class="question-text">
|
| 220 |
+
{{ question.question if question.question else question }}
|
| 221 |
+
</div>
|
| 222 |
+
<div class="long-answer-space"></div>
|
| 223 |
+
<div class="long-answer-space"></div>
|
| 224 |
+
</div>
|
| 225 |
+
{% endfor %}
|
| 226 |
+
{% endif %}
|
| 227 |
+
|
| 228 |
+
<div class="footer">
|
| 229 |
+
<p><strong>*** END OF QUESTION PAPER ***</strong></p>
|
| 230 |
+
<p>Generated on {{ exam_date }} | Total Questions: {{ config.short_questions + config.long_questions + config.mcq_questions }} | Total Marks: {{ total_marks }}</p>
|
| 231 |
+
</div>
|
| 232 |
+
{% endblock %}
|
templates/step1_input.html
ADDED
|
@@ -0,0 +1,297 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{% extends 'base.html' %}
|
| 2 |
+
{% block title %}Step 1: Input Syllabus - AutoExamGen{% endblock %}
|
| 3 |
+
{% block head %}
|
| 4 |
+
<style>
|
| 5 |
+
body {
|
| 6 |
+
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
| 7 |
+
min-height: 100vh;
|
| 8 |
+
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
| 9 |
+
}
|
| 10 |
+
.hero-title {
|
| 11 |
+
color: #4f46e5; /* Fallback color for visibility */
|
| 12 |
+
background: linear-gradient(45deg, #4f46e5, #9333ea);
|
| 13 |
+
background-clip: text;
|
| 14 |
+
-webkit-background-clip: text;
|
| 15 |
+
-webkit-text-fill-color: transparent;
|
| 16 |
+
text-shadow: 0 1px 0 rgba(0,0,0,0.05);
|
| 17 |
+
}
|
| 18 |
+
.glow {
|
| 19 |
+
text-shadow: 0 0 12px rgba(255,255,255,0.25);
|
| 20 |
+
}
|
| 21 |
+
.floating {
|
| 22 |
+
animation: float 6s ease-in-out infinite;
|
| 23 |
+
}
|
| 24 |
+
@keyframes float {
|
| 25 |
+
0% { transform: translateY(0px) }
|
| 26 |
+
50% { transform: translateY(-6px) }
|
| 27 |
+
100% { transform: translateY(0px) }
|
| 28 |
+
}
|
| 29 |
+
.container {
|
| 30 |
+
padding-top: 2rem;
|
| 31 |
+
}
|
| 32 |
+
.card {
|
| 33 |
+
border: none;
|
| 34 |
+
border-radius: 15px;
|
| 35 |
+
box-shadow: 0 10px 30px rgba(0,0,0,0.1);
|
| 36 |
+
backdrop-filter: blur(10px);
|
| 37 |
+
background: rgba(255, 255, 255, 0.95);
|
| 38 |
+
}
|
| 39 |
+
.btn-primary {
|
| 40 |
+
background: linear-gradient(45deg, #667eea, #764ba2);
|
| 41 |
+
border: none;
|
| 42 |
+
border-radius: 25px;
|
| 43 |
+
padding: 12px 30px;
|
| 44 |
+
font-weight: 600;
|
| 45 |
+
transition: all 0.3s ease;
|
| 46 |
+
}
|
| 47 |
+
.btn-primary:hover {
|
| 48 |
+
transform: translateY(-2px);
|
| 49 |
+
box-shadow: 0 5px 15px rgba(0,0,0,0.2);
|
| 50 |
+
}
|
| 51 |
+
.form-control, .form-select {
|
| 52 |
+
border-radius: 10px;
|
| 53 |
+
border: 2px solid #e9ecef;
|
| 54 |
+
transition: all 0.3s ease;
|
| 55 |
+
}
|
| 56 |
+
.form-control:focus, .form-select:focus {
|
| 57 |
+
border-color: #667eea;
|
| 58 |
+
box-shadow: 0 0 0 0.2rem rgba(102, 126, 234, 0.25);
|
| 59 |
+
}
|
| 60 |
+
.progress-bar {
|
| 61 |
+
background: linear-gradient(45deg, #667eea, #764ba2);
|
| 62 |
+
}
|
| 63 |
+
.step-indicator {
|
| 64 |
+
display: flex;
|
| 65 |
+
justify-content: center;
|
| 66 |
+
margin-bottom: 2rem;
|
| 67 |
+
}
|
| 68 |
+
.step {
|
| 69 |
+
width: 40px;
|
| 70 |
+
height: 40px;
|
| 71 |
+
border-radius: 50%;
|
| 72 |
+
display: flex;
|
| 73 |
+
align-items: center;
|
| 74 |
+
justify-content: center;
|
| 75 |
+
margin: 0 10px;
|
| 76 |
+
font-weight: bold;
|
| 77 |
+
color: white;
|
| 78 |
+
}
|
| 79 |
+
.step.active {
|
| 80 |
+
background: linear-gradient(45deg, #667eea, #764ba2);
|
| 81 |
+
}
|
| 82 |
+
.step.inactive {
|
| 83 |
+
background: #ccc;
|
| 84 |
+
}
|
| 85 |
+
.file-upload-area {
|
| 86 |
+
border: 2px dashed #667eea;
|
| 87 |
+
border-radius: 15px;
|
| 88 |
+
padding: 2rem;
|
| 89 |
+
text-align: center;
|
| 90 |
+
transition: all 0.3s ease;
|
| 91 |
+
cursor: pointer;
|
| 92 |
+
}
|
| 93 |
+
.file-upload-area:hover {
|
| 94 |
+
background-color: #f8f9ff;
|
| 95 |
+
border-color: #764ba2;
|
| 96 |
+
}
|
| 97 |
+
.alert {
|
| 98 |
+
border-radius: 10px;
|
| 99 |
+
}
|
| 100 |
+
/* Enhancements */
|
| 101 |
+
.accent-text {
|
| 102 |
+
color: #4f46e5; /* Fallback color */
|
| 103 |
+
background: linear-gradient(45deg, #4f46e5, #9333ea);
|
| 104 |
+
background-clip: text;
|
| 105 |
+
-webkit-background-clip: text;
|
| 106 |
+
-webkit-text-fill-color: transparent;
|
| 107 |
+
}
|
| 108 |
+
.shimmer {
|
| 109 |
+
position: relative;
|
| 110 |
+
overflow: hidden;
|
| 111 |
+
}
|
| 112 |
+
.shimmer::after {
|
| 113 |
+
content: "";
|
| 114 |
+
position: absolute;
|
| 115 |
+
top: 0; left: -150%;
|
| 116 |
+
width: 50%; height: 100%;
|
| 117 |
+
background: linear-gradient(120deg, rgba(255,255,255,0) 0%, rgba(255,255,255,0.25) 50%, rgba(255,255,255,0) 100%);
|
| 118 |
+
animation: shimmer 2.5s infinite;
|
| 119 |
+
}
|
| 120 |
+
@keyframes shimmer {
|
| 121 |
+
0% { left: -150%; }
|
| 122 |
+
60% { left: 150%; }
|
| 123 |
+
100% { left: 150%; }
|
| 124 |
+
}
|
| 125 |
+
.file-upload-area.dragover {
|
| 126 |
+
border-color: #00c2ff;
|
| 127 |
+
box-shadow: 0 10px 25px rgba(0, 194, 255, 0.25);
|
| 128 |
+
background: linear-gradient(0deg, rgba(0,194,255,0.06), transparent 60%);
|
| 129 |
+
}
|
| 130 |
+
.stat-pill {
|
| 131 |
+
border-radius: 999px;
|
| 132 |
+
background: #f3f6ff;
|
| 133 |
+
padding: 6px 12px;
|
| 134 |
+
border: 1px solid #e6ebff;
|
| 135 |
+
}
|
| 136 |
+
</style>
|
| 137 |
+
{% endblock %}
|
| 138 |
+
{% block content %}
|
| 139 |
+
<div class="container">
|
| 140 |
+
<div class="row justify-content-center">
|
| 141 |
+
<div class="col-md-8">
|
| 142 |
+
<!-- Progress Indicator -->
|
| 143 |
+
<div class="step-indicator">
|
| 144 |
+
<div class="step active">1</div>
|
| 145 |
+
<div class="step inactive">2</div>
|
| 146 |
+
<div class="step inactive">3</div>
|
| 147 |
+
</div>
|
| 148 |
+
|
| 149 |
+
<div class="card">
|
| 150 |
+
<div class="card-header bg-transparent text-center py-4">
|
| 151 |
+
<div class="shimmer">
|
| 152 |
+
<h2 class="mb-0 hero-title floating">
|
| 153 |
+
<i class="fas fa-file-text text-primary me-2 glow"></i>
|
| 154 |
+
Step 1: <span class="accent-text">Input Your Syllabus</span>
|
| 155 |
+
</h2>
|
| 156 |
+
</div>
|
| 157 |
+
<p class="text-muted mt-2">Enter your syllabus content by typing, pasting, or uploading a file</p>
|
| 158 |
+
</div>
|
| 159 |
+
<div class="card-body p-4">
|
| 160 |
+
<form action="/step2" method="POST" enctype="multipart/form-data" id="inputForm">
|
| 161 |
+
<!-- Text Input Option -->
|
| 162 |
+
<div class="mb-4">
|
| 163 |
+
<label for="text_input" class="form-label">
|
| 164 |
+
<i class="fas fa-keyboard me-2"></i>Type or Paste Your Syllabus
|
| 165 |
+
</label>
|
| 166 |
+
<textarea
|
| 167 |
+
class="form-control"
|
| 168 |
+
id="text_input"
|
| 169 |
+
name="text_input"
|
| 170 |
+
rows="10"
|
| 171 |
+
placeholder="Enter your syllabus content here... You can type or paste text directly into this area."
|
| 172 |
+
></textarea>
|
| 173 |
+
<div class="d-flex gap-2 mt-2 flex-wrap">
|
| 174 |
+
<span class="stat-pill"><i class="fas fa-font me-2 text-primary"></i>Paste text</span>
|
| 175 |
+
<span class="stat-pill"><i class="fas fa-file-word me-2 text-primary"></i>Supports .docx</span>
|
| 176 |
+
<span class="stat-pill"><i class="fas fa-bolt me-2 text-primary"></i>Fast processing</span>
|
| 177 |
+
</div>
|
| 178 |
+
<div class="form-text">
|
| 179 |
+
<i class="fas fa-info-circle me-1"></i>
|
| 180 |
+
You can type or paste your syllabus content directly here.
|
| 181 |
+
</div>
|
| 182 |
+
</div>
|
| 183 |
+
|
| 184 |
+
<div class="text-center my-3">
|
| 185 |
+
<span class="badge bg-secondary px-3 py-2">OR</span>
|
| 186 |
+
</div>
|
| 187 |
+
|
| 188 |
+
<!-- File Upload Option -->
|
| 189 |
+
<div class="mb-4">
|
| 190 |
+
<label class="form-label">
|
| 191 |
+
<i class="fas fa-upload me-2"></i>Upload a File
|
| 192 |
+
</label>
|
| 193 |
+
<div class="file-upload-area" id="dropArea" onclick="document.getElementById('file').click()">
|
| 194 |
+
<i class="fas fa-cloud-upload-alt fa-3x text-primary mb-3 floating"></i>
|
| 195 |
+
<h5 class="glow">Click to Upload File</h5>
|
| 196 |
+
<p class="text-muted mb-0">Supports .txt and .docx files</p>
|
| 197 |
+
<input type="file" id="file" name="file" class="d-none" accept=".txt,.docx" onchange="updateFileName(this)">
|
| 198 |
+
</div>
|
| 199 |
+
<div id="fileName" class="mt-2 text-center text-muted"></div>
|
| 200 |
+
</div>
|
| 201 |
+
|
| 202 |
+
<!-- Submit Button -->
|
| 203 |
+
<div class="text-center">
|
| 204 |
+
<button type="submit" class="btn btn-primary btn-lg">
|
| 205 |
+
<i class="fas fa-arrow-right me-2"></i>
|
| 206 |
+
Continue to Question Configuration
|
| 207 |
+
</button>
|
| 208 |
+
</div>
|
| 209 |
+
</form>
|
| 210 |
+
</div>
|
| 211 |
+
</div>
|
| 212 |
+
|
| 213 |
+
<!-- Info Card -->
|
| 214 |
+
<div class="card mt-4">
|
| 215 |
+
<div class="card-body">
|
| 216 |
+
<h5 class="card-title">
|
| 217 |
+
<i class="fas fa-lightbulb text-warning me-2"></i>
|
| 218 |
+
How it works
|
| 219 |
+
</h5>
|
| 220 |
+
<div class="row">
|
| 221 |
+
<div class="col-md-4 text-center mb-3">
|
| 222 |
+
<i class="fas fa-file-text fa-2x text-primary mb-2"></i>
|
| 223 |
+
<h6>1. Input Content</h6>
|
| 224 |
+
<small class="text-muted">Provide your syllabus content</small>
|
| 225 |
+
</div>
|
| 226 |
+
<div class="col-md-4 text-center mb-3">
|
| 227 |
+
<i class="fas fa-cogs fa-2x text-primary mb-2"></i>
|
| 228 |
+
<h6>2. Configure Questions</h6>
|
| 229 |
+
<small class="text-muted">Choose question types and marks</small>
|
| 230 |
+
</div>
|
| 231 |
+
<div class="col-md-4 text-center mb-3">
|
| 232 |
+
<i class="fas fa-download fa-2x text-primary mb-2"></i>
|
| 233 |
+
<h6>3. Generate & Download</h6>
|
| 234 |
+
<small class="text-muted">Get your formatted question paper</small>
|
| 235 |
+
</div>
|
| 236 |
+
</div>
|
| 237 |
+
</div>
|
| 238 |
+
</div>
|
| 239 |
+
</div>
|
| 240 |
+
</div>
|
| 241 |
+
</div>
|
| 242 |
+
|
| 243 |
+
{% endblock %}
|
| 244 |
+
{% block scripts %}
|
| 245 |
+
<script>
|
| 246 |
+
function updateFileName(input) {
|
| 247 |
+
const fileName = document.getElementById('fileName');
|
| 248 |
+
if (input.files && input.files[0]) {
|
| 249 |
+
fileName.innerHTML = `<i class="fas fa-file me-2"></i>Selected: ${input.files[0].name}`;
|
| 250 |
+
fileName.className = 'mt-2 text-center text-success';
|
| 251 |
+
|
| 252 |
+
// Clear text input when file is selected
|
| 253 |
+
document.getElementById('text_input').value = '';
|
| 254 |
+
}
|
| 255 |
+
}
|
| 256 |
+
|
| 257 |
+
// Clear file input when text is entered
|
| 258 |
+
document.getElementById('text_input').addEventListener('input', function() {
|
| 259 |
+
if (this.value.trim()) {
|
| 260 |
+
document.getElementById('file').value = '';
|
| 261 |
+
document.getElementById('fileName').innerHTML = '';
|
| 262 |
+
}
|
| 263 |
+
});
|
| 264 |
+
|
| 265 |
+
// Drag and drop handlers
|
| 266 |
+
const dropArea = document.getElementById('dropArea');
|
| 267 |
+
;['dragenter','dragover','dragleave','drop'].forEach(eventName => {
|
| 268 |
+
dropArea.addEventListener(eventName, (e) => { e.preventDefault(); e.stopPropagation(); }, false);
|
| 269 |
+
});
|
| 270 |
+
;['dragenter','dragover'].forEach(eventName => {
|
| 271 |
+
dropArea.addEventListener(eventName, () => dropArea.classList.add('dragover'), false);
|
| 272 |
+
});
|
| 273 |
+
;['dragleave','drop'].forEach(eventName => {
|
| 274 |
+
dropArea.addEventListener(eventName, () => dropArea.classList.remove('dragover'), false);
|
| 275 |
+
});
|
| 276 |
+
dropArea.addEventListener('drop', (e) => {
|
| 277 |
+
const dt = e.dataTransfer;
|
| 278 |
+
const files = dt.files;
|
| 279 |
+
if (files && files[0]) {
|
| 280 |
+
const fileInput = document.getElementById('file');
|
| 281 |
+
fileInput.files = files;
|
| 282 |
+
updateFileName(fileInput);
|
| 283 |
+
}
|
| 284 |
+
});
|
| 285 |
+
|
| 286 |
+
// Form validation
|
| 287 |
+
document.getElementById('inputForm').addEventListener('submit', function(e) {
|
| 288 |
+
const textInput = document.getElementById('text_input').value.trim();
|
| 289 |
+
const fileInput = document.getElementById('file').files.length;
|
| 290 |
+
|
| 291 |
+
if (!textInput && !fileInput) {
|
| 292 |
+
e.preventDefault();
|
| 293 |
+
alert('Please provide some text or upload a file before continuing.');
|
| 294 |
+
}
|
| 295 |
+
});
|
| 296 |
+
</script>
|
| 297 |
+
{% endblock %}
|
templates/step2_config.html
ADDED
|
@@ -0,0 +1,471 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{% extends 'base.html' %}
|
| 2 |
+
{% block title %}Step 2: Configure Questions - AutoExamGen{% endblock %}
|
| 3 |
+
{% block head %}
|
| 4 |
+
<style>
|
| 5 |
+
body {
|
| 6 |
+
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
| 7 |
+
min-height: 100vh;
|
| 8 |
+
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
| 9 |
+
}
|
| 10 |
+
.container {
|
| 11 |
+
padding-top: 2rem;
|
| 12 |
+
}
|
| 13 |
+
.card {
|
| 14 |
+
border: none;
|
| 15 |
+
border-radius: 15px;
|
| 16 |
+
box-shadow: 0 10px 30px rgba(0,0,0,0.1);
|
| 17 |
+
backdrop-filter: blur(10px);
|
| 18 |
+
background: rgba(255, 255, 255, 0.95);
|
| 19 |
+
}
|
| 20 |
+
.btn-primary {
|
| 21 |
+
background: linear-gradient(45deg, #667eea, #764ba2);
|
| 22 |
+
border: none;
|
| 23 |
+
border-radius: 25px;
|
| 24 |
+
padding: 12px 30px;
|
| 25 |
+
font-weight: 600;
|
| 26 |
+
transition: all 0.3s ease;
|
| 27 |
+
}
|
| 28 |
+
.btn-primary:hover {
|
| 29 |
+
transform: translateY(-2px);
|
| 30 |
+
box-shadow: 0 5px 15px rgba(0,0,0,0.2);
|
| 31 |
+
}
|
| 32 |
+
.btn-secondary {
|
| 33 |
+
border-radius: 25px;
|
| 34 |
+
padding: 12px 30px;
|
| 35 |
+
font-weight: 600;
|
| 36 |
+
}
|
| 37 |
+
.form-control, .form-select {
|
| 38 |
+
border-radius: 10px;
|
| 39 |
+
border: 2px solid #e9ecef;
|
| 40 |
+
transition: all 0.3s ease;
|
| 41 |
+
}
|
| 42 |
+
.form-control:focus, .form-select:focus {
|
| 43 |
+
border-color: #667eea;
|
| 44 |
+
box-shadow: 0 0 0 0.2rem rgba(102, 126, 234, 0.25);
|
| 45 |
+
}
|
| 46 |
+
.step-indicator {
|
| 47 |
+
display: flex;
|
| 48 |
+
justify-content: center;
|
| 49 |
+
margin-bottom: 2rem;
|
| 50 |
+
}
|
| 51 |
+
.step {
|
| 52 |
+
width: 40px;
|
| 53 |
+
height: 40px;
|
| 54 |
+
border-radius: 50%;
|
| 55 |
+
display: flex;
|
| 56 |
+
align-items: center;
|
| 57 |
+
justify-content: center;
|
| 58 |
+
margin: 0 10px;
|
| 59 |
+
font-weight: bold;
|
| 60 |
+
color: white;
|
| 61 |
+
}
|
| 62 |
+
.step.active {
|
| 63 |
+
background: linear-gradient(45deg, #667eea, #764ba2);
|
| 64 |
+
}
|
| 65 |
+
.step.completed {
|
| 66 |
+
background: #28a745;
|
| 67 |
+
}
|
| 68 |
+
.step.inactive {
|
| 69 |
+
background: #ccc;
|
| 70 |
+
}
|
| 71 |
+
.question-type-card {
|
| 72 |
+
border: 2px solid #e9ecef;
|
| 73 |
+
border-radius: 15px;
|
| 74 |
+
padding: 1.5rem;
|
| 75 |
+
margin-bottom: 1rem;
|
| 76 |
+
transition: all 0.3s ease;
|
| 77 |
+
}
|
| 78 |
+
.question-type-card:hover {
|
| 79 |
+
border-color: #667eea;
|
| 80 |
+
box-shadow: 0 5px 15px rgba(0,0,0,0.1);
|
| 81 |
+
}
|
| 82 |
+
.question-type-card.active {
|
| 83 |
+
border-color: #667eea;
|
| 84 |
+
background-color: #f8f9ff;
|
| 85 |
+
}
|
| 86 |
+
.marks-preview {
|
| 87 |
+
background: linear-gradient(45deg, #667eea, #764ba2);
|
| 88 |
+
color: white;
|
| 89 |
+
border-radius: 10px;
|
| 90 |
+
padding: 1rem;
|
| 91 |
+
text-align: center;
|
| 92 |
+
}
|
| 93 |
+
.alert {
|
| 94 |
+
border-radius: 10px;
|
| 95 |
+
}
|
| 96 |
+
.input-group-text {
|
| 97 |
+
border-radius: 10px 0 0 10px;
|
| 98 |
+
}
|
| 99 |
+
.form-control.rounded-end {
|
| 100 |
+
border-radius: 0 10px 10px 0;
|
| 101 |
+
}
|
| 102 |
+
</style>
|
| 103 |
+
{% endblock %}
|
| 104 |
+
{% block content %}
|
| 105 |
+
<div class="container">
|
| 106 |
+
<div class="row justify-content-center">
|
| 107 |
+
<div class="col-md-10">
|
| 108 |
+
<!-- Progress Indicator -->
|
| 109 |
+
<div class="step-indicator">
|
| 110 |
+
<div class="step completed">1</div>
|
| 111 |
+
<div class="step active">2</div>
|
| 112 |
+
<div class="step inactive">3</div>
|
| 113 |
+
</div>
|
| 114 |
+
|
| 115 |
+
<div class="card">
|
| 116 |
+
<div class="card-header bg-transparent text-center py-4">
|
| 117 |
+
<h2 class="mb-0">
|
| 118 |
+
<i class="fas fa-cogs text-primary me-2"></i>
|
| 119 |
+
Step 2: Configure Your Question Paper
|
| 120 |
+
</h2>
|
| 121 |
+
<p class="text-muted mt-2">Choose the types and number of questions for your exam paper</p>
|
| 122 |
+
<div class="badge bg-info">
|
| 123 |
+
<i class="fas fa-file-text me-1"></i>
|
| 124 |
+
Syllabus loaded: {{ word_count }} words
|
| 125 |
+
</div>
|
| 126 |
+
</div>
|
| 127 |
+
<div class="card-body p-4">
|
| 128 |
+
{% if error %}
|
| 129 |
+
<div class="alert alert-danger" role="alert">
|
| 130 |
+
<i class="fas fa-exclamation-triangle me-2"></i>{{ error }}
|
| 131 |
+
</div>
|
| 132 |
+
{% endif %}
|
| 133 |
+
|
| 134 |
+
<form action="{{ url_for('step3_generate') }}" method="POST" id="configForm">
|
| 135 |
+
<!-- Exam Details -->
|
| 136 |
+
<div class="row mb-4">
|
| 137 |
+
<div class="col-md-12">
|
| 138 |
+
<div class="question-type-card">
|
| 139 |
+
<div class="row g-3">
|
| 140 |
+
<div class="col-md-4">
|
| 141 |
+
<label class="form-label">Exam Name (optional)</label>
|
| 142 |
+
<input type="text" class="form-control" name="exam_name" id="exam_name" placeholder="e.g., Midterm Examination">
|
| 143 |
+
</div>
|
| 144 |
+
<div class="col-md-4">
|
| 145 |
+
<label class="form-label">Subject Name (optional)</label>
|
| 146 |
+
<input type="text" class="form-control" name="subject_name" id="subject_name" placeholder="e.g., Computer Science">
|
| 147 |
+
</div>
|
| 148 |
+
<div class="col-md-4">
|
| 149 |
+
<label class="form-label">Exam Duration (optional)</label>
|
| 150 |
+
<input type="text" class="form-control" name="exam_duration" id="exam_duration" placeholder="e.g., 180, 3h, 3 hours, 2h 30m">
|
| 151 |
+
</div>
|
| 152 |
+
</div>
|
| 153 |
+
</div>
|
| 154 |
+
</div>
|
| 155 |
+
</div>
|
| 156 |
+
<div class="row">
|
| 157 |
+
<!-- Multiple Choice Questions -->
|
| 158 |
+
<div class="col-md-4">
|
| 159 |
+
<div class="question-type-card" id="mcqCard">
|
| 160 |
+
<div class="text-center mb-3">
|
| 161 |
+
<i class="fas fa-list-ul fa-3x text-warning"></i>
|
| 162 |
+
<h5 class="mt-2">Multiple Choice Questions</h5>
|
| 163 |
+
<p class="text-muted small">Questions with multiple options to choose from</p>
|
| 164 |
+
</div>
|
| 165 |
+
|
| 166 |
+
<div class="mb-3">
|
| 167 |
+
<label class="form-label">Number of Questions</label>
|
| 168 |
+
<input type="number" class="form-control" name="mcq_questions" id="mcq_questions"
|
| 169 |
+
value="0" min="0" max="30" onchange="updatePreview()">
|
| 170 |
+
</div>
|
| 171 |
+
|
| 172 |
+
<div class="mb-3">
|
| 173 |
+
<label class="form-label">Marks per Question</label>
|
| 174 |
+
<div class="input-group">
|
| 175 |
+
<input type="number" class="form-control rounded-end" value="1" readonly>
|
| 176 |
+
<span class="input-group-text">mark</span>
|
| 177 |
+
</div>
|
| 178 |
+
<div class="form-text">MCQ questions are typically 1 mark each</div>
|
| 179 |
+
</div>
|
| 180 |
+
|
| 181 |
+
<div class="text-center">
|
| 182 |
+
<span class="badge bg-warning" id="mcqTotal">0 marks total</span>
|
| 183 |
+
</div>
|
| 184 |
+
</div>
|
| 185 |
+
</div>
|
| 186 |
+
|
| 187 |
+
<!-- Short Answer Questions -->
|
| 188 |
+
<div class="col-md-4">
|
| 189 |
+
<div class="question-type-card" id="shortCard">
|
| 190 |
+
<div class="text-center mb-3">
|
| 191 |
+
<i class="fas fa-edit fa-3x text-primary"></i>
|
| 192 |
+
<h5 class="mt-2">Short Answer Questions</h5>
|
| 193 |
+
<p class="text-muted small">Brief, focused questions requiring concise answers</p>
|
| 194 |
+
</div>
|
| 195 |
+
|
| 196 |
+
<div class="mb-3">
|
| 197 |
+
<label class="form-label">Number of Questions</label>
|
| 198 |
+
<input type="number" class="form-control" name="short_questions" id="short_questions"
|
| 199 |
+
value="0" min="0" max="20" onchange="updatePreview()">
|
| 200 |
+
</div>
|
| 201 |
+
|
| 202 |
+
<div class="mb-3">
|
| 203 |
+
<label class="form-label">Marks per Question</label>
|
| 204 |
+
<div class="input-group">
|
| 205 |
+
<input type="number" class="form-control rounded-end" name="short_marks" id="short_marks"
|
| 206 |
+
value="3" min="1" max="10" onchange="updatePreview()">
|
| 207 |
+
<span class="input-group-text">marks</span>
|
| 208 |
+
</div>
|
| 209 |
+
</div>
|
| 210 |
+
|
| 211 |
+
<div class="form-check mb-3">
|
| 212 |
+
<input class="form-check-input" type="checkbox" value="1" id="short_or" name="short_or" onchange="updatePreview()">
|
| 213 |
+
<label class="form-check-label" for="short_or">
|
| 214 |
+
Provide an 'OR' alternative for each short question
|
| 215 |
+
</label>
|
| 216 |
+
</div>
|
| 217 |
+
|
| 218 |
+
<div class="text-center">
|
| 219 |
+
<span class="badge bg-primary" id="shortTotal">0 marks total</span>
|
| 220 |
+
</div>
|
| 221 |
+
</div>
|
| 222 |
+
</div>
|
| 223 |
+
|
| 224 |
+
<!-- Long Answer Questions -->
|
| 225 |
+
<div class="col-md-4">
|
| 226 |
+
<div class="question-type-card" id="longCard">
|
| 227 |
+
<div class="text-center mb-3">
|
| 228 |
+
<i class="fas fa-file-alt fa-3x text-success"></i>
|
| 229 |
+
<h5 class="mt-2">Long Answer Questions</h5>
|
| 230 |
+
<p class="text-muted small">Detailed questions requiring comprehensive answers</p>
|
| 231 |
+
</div>
|
| 232 |
+
|
| 233 |
+
<div class="mb-3">
|
| 234 |
+
<label class="form-label">Number of Questions</label>
|
| 235 |
+
<input type="number" class="form-control" name="long_questions" id="long_questions"
|
| 236 |
+
value="0" min="0" max="10" onchange="updatePreview()">
|
| 237 |
+
</div>
|
| 238 |
+
|
| 239 |
+
<div class="mb-3">
|
| 240 |
+
<label class="form-label">Marks per Question</label>
|
| 241 |
+
<div class="input-group">
|
| 242 |
+
<input type="number" class="form-control rounded-end" name="long_marks" id="long_marks"
|
| 243 |
+
value="10" min="5" max="25" onchange="updatePreview()">
|
| 244 |
+
<span class="input-group-text">marks</span>
|
| 245 |
+
</div>
|
| 246 |
+
</div>
|
| 247 |
+
|
| 248 |
+
<div class="mb-3">
|
| 249 |
+
<label class="form-label">Attempt any (optional)</label>
|
| 250 |
+
<div class="input-group">
|
| 251 |
+
<input type="number" class="form-control rounded-end" name="long_attempt" id="long_attempt"
|
| 252 |
+
value="" min="0" max="10" placeholder="e.g., 3" onchange="updatePreview()">
|
| 253 |
+
<span class="input-group-text">questions</span>
|
| 254 |
+
</div>
|
| 255 |
+
<div class="form-text">If set, students will be instructed to attempt only this many long questions.</div>
|
| 256 |
+
</div>
|
| 257 |
+
|
| 258 |
+
<div class="text-center">
|
| 259 |
+
<span class="badge bg-success" id="longTotal">0 marks total</span>
|
| 260 |
+
</div>
|
| 261 |
+
</div>
|
| 262 |
+
</div>
|
| 263 |
+
</div>
|
| 264 |
+
|
| 265 |
+
<!-- Summary Card -->
|
| 266 |
+
<div class="row mt-4">
|
| 267 |
+
<div class="col-md-12">
|
| 268 |
+
<div class="marks-preview">
|
| 269 |
+
<h4 class="mb-3">
|
| 270 |
+
<i class="fas fa-calculator me-2"></i>
|
| 271 |
+
Question Paper Summary
|
| 272 |
+
</h4>
|
| 273 |
+
<div class="row">
|
| 274 |
+
<div class="col-md-3 text-center">
|
| 275 |
+
<h5 id="totalQuestions">0</h5>
|
| 276 |
+
<small>Total Questions</small>
|
| 277 |
+
</div>
|
| 278 |
+
<div class="col-md-3 text-center">
|
| 279 |
+
<h5 id="totalMarks">0</h5>
|
| 280 |
+
<small>Total Marks</small>
|
| 281 |
+
</div>
|
| 282 |
+
<div class="col-md-3 text-center">
|
| 283 |
+
<h5 id="estimatedTime">0</h5>
|
| 284 |
+
<small>Estimated Time (min)</small>
|
| 285 |
+
</div>
|
| 286 |
+
<div class="col-md-3 text-center">
|
| 287 |
+
<h5 id="difficulty">Easy</h5>
|
| 288 |
+
<small>Difficulty Level</small>
|
| 289 |
+
</div>
|
| 290 |
+
</div>
|
| 291 |
+
</div>
|
| 292 |
+
</div>
|
| 293 |
+
</div>
|
| 294 |
+
|
| 295 |
+
<!-- Action Buttons -->
|
| 296 |
+
<div class="row mt-4">
|
| 297 |
+
<div class="col-md-6">
|
| 298 |
+
<a href="/" class="btn btn-secondary btn-lg w-100">
|
| 299 |
+
<i class="fas fa-arrow-left me-2"></i>
|
| 300 |
+
Back to Input
|
| 301 |
+
</a>
|
| 302 |
+
</div>
|
| 303 |
+
<div class="col-md-6">
|
| 304 |
+
<button type="submit" class="btn btn-primary btn-lg w-100" id="generateBtn">
|
| 305 |
+
<i class="fas fa-magic me-2"></i>
|
| 306 |
+
Generate Question Paper
|
| 307 |
+
</button>
|
| 308 |
+
</div>
|
| 309 |
+
</div>
|
| 310 |
+
</form>
|
| 311 |
+
</div>
|
| 312 |
+
</div>
|
| 313 |
+
|
| 314 |
+
<!-- Tips Card -->
|
| 315 |
+
<div class="card mt-4">
|
| 316 |
+
<div class="card-body">
|
| 317 |
+
<h5 class="card-title">
|
| 318 |
+
<i class="fas fa-lightbulb text-warning me-2"></i>
|
| 319 |
+
Configuration Tips
|
| 320 |
+
</h5>
|
| 321 |
+
<div class="row">
|
| 322 |
+
<div class="col-md-4">
|
| 323 |
+
<h6><i class="fas fa-list-ul text-warning me-2"></i>MCQ Questions</h6>
|
| 324 |
+
<small class="text-muted">Great for testing factual knowledge and quick assessment. Usually 1 mark each.</small>
|
| 325 |
+
</div>
|
| 326 |
+
<div class="col-md-4">
|
| 327 |
+
<h6><i class="fas fa-edit text-primary me-2"></i>Short Questions</h6>
|
| 328 |
+
<small class="text-muted">Best for definitions, concepts, and quick explanations. Usually 2-5 marks.</small>
|
| 329 |
+
</div>
|
| 330 |
+
<div class="col-md-4">
|
| 331 |
+
<h6><i class="fas fa-file-alt text-success me-2"></i>Long Questions</h6>
|
| 332 |
+
<small class="text-muted">Perfect for detailed explanations, analysis, and comprehensive answers. Usually 8-15 marks.</small>
|
| 333 |
+
</div>
|
| 334 |
+
</div>
|
| 335 |
+
</div>
|
| 336 |
+
</div>
|
| 337 |
+
</div>
|
| 338 |
+
</div>
|
| 339 |
+
</div>
|
| 340 |
+
|
| 341 |
+
{% endblock %}
|
| 342 |
+
{% block scripts %}
|
| 343 |
+
<script>
|
| 344 |
+
function updatePreview() {
|
| 345 |
+
const shortQuestions = parseInt(document.getElementById('short_questions').value) || 0;
|
| 346 |
+
const longQuestions = parseInt(document.getElementById('long_questions').value) || 0;
|
| 347 |
+
const mcqQuestions = parseInt(document.getElementById('mcq_questions').value) || 0;
|
| 348 |
+
const shortMarks = parseInt(document.getElementById('short_marks').value) || 3;
|
| 349 |
+
const longMarks = parseInt(document.getElementById('long_marks').value) || 10;
|
| 350 |
+
|
| 351 |
+
// Calculate totals
|
| 352 |
+
const shortTotal = shortQuestions * shortMarks;
|
| 353 |
+
const longTotal = longQuestions * longMarks;
|
| 354 |
+
const mcqTotal = mcqQuestions * 1; // MCQ is always 1 mark
|
| 355 |
+
|
| 356 |
+
const totalQuestions = shortQuestions + longQuestions + mcqQuestions;
|
| 357 |
+
const totalMarks = shortTotal + longTotal + mcqTotal;
|
| 358 |
+
|
| 359 |
+
// Update individual totals
|
| 360 |
+
document.getElementById('shortTotal').textContent = shortTotal + ' marks total';
|
| 361 |
+
document.getElementById('longTotal').textContent = longTotal + ' marks total';
|
| 362 |
+
document.getElementById('mcqTotal').textContent = mcqTotal + ' marks total';
|
| 363 |
+
|
| 364 |
+
// Update summary
|
| 365 |
+
document.getElementById('totalQuestions').textContent = totalQuestions;
|
| 366 |
+
document.getElementById('totalMarks').textContent = totalMarks;
|
| 367 |
+
|
| 368 |
+
// Estimate time unless custom duration provided (supports formats like '3 hours', '2h 30m')
|
| 369 |
+
const customDurationRaw = document.getElementById('exam_duration').value.trim();
|
| 370 |
+
let customDuration = parseInt(customDurationRaw);
|
| 371 |
+
if (customDurationRaw && isNaN(customDuration)) {
|
| 372 |
+
const lower = customDurationRaw.toLowerCase();
|
| 373 |
+
// crude parse: extract h and m
|
| 374 |
+
let minutesParsed = 0;
|
| 375 |
+
const hMatch = lower.match(/(\d+)\s*h/);
|
| 376 |
+
const mMatch = lower.match(/(\d+)\s*m/);
|
| 377 |
+
if (hMatch) minutesParsed += parseInt(hMatch[1], 10) * 60;
|
| 378 |
+
if (mMatch) minutesParsed += parseInt(mMatch[1], 10);
|
| 379 |
+
if (minutesParsed > 0) customDuration = minutesParsed;
|
| 380 |
+
}
|
| 381 |
+
const estimatedTime = Math.round(totalMarks * 1.5);
|
| 382 |
+
const timeToShow = (!isNaN(customDuration) && customDuration > 0) ? customDuration : estimatedTime;
|
| 383 |
+
document.getElementById('estimatedTime').textContent = timeToShow;
|
| 384 |
+
|
| 385 |
+
// Determine difficulty
|
| 386 |
+
let difficulty = 'Easy';
|
| 387 |
+
if (totalMarks > 50) difficulty = 'Medium';
|
| 388 |
+
if (totalMarks > 100) difficulty = 'Hard';
|
| 389 |
+
document.getElementById('difficulty').textContent = difficulty;
|
| 390 |
+
|
| 391 |
+
// Update card styles
|
| 392 |
+
updateCardStyles(shortQuestions, longQuestions, mcqQuestions);
|
| 393 |
+
|
| 394 |
+
// Enable/disable generate button
|
| 395 |
+
const generateBtn = document.getElementById('generateBtn');
|
| 396 |
+
if (totalQuestions > 0) {
|
| 397 |
+
generateBtn.disabled = false;
|
| 398 |
+
generateBtn.innerHTML = '<i class="fas fa-magic me-2"></i>Generate Question Paper';
|
| 399 |
+
} else {
|
| 400 |
+
generateBtn.disabled = true;
|
| 401 |
+
generateBtn.innerHTML = '<i class="fas fa-exclamation-triangle me-2"></i>Select at least one question type';
|
| 402 |
+
}
|
| 403 |
+
}
|
| 404 |
+
|
| 405 |
+
function updateCardStyles(short, long, mcq) {
|
| 406 |
+
const shortCard = document.getElementById('shortCard');
|
| 407 |
+
const longCard = document.getElementById('longCard');
|
| 408 |
+
const mcqCard = document.getElementById('mcqCard');
|
| 409 |
+
|
| 410 |
+
// Remove active class from all cards
|
| 411 |
+
[shortCard, longCard, mcqCard].forEach(card => card.classList.remove('active'));
|
| 412 |
+
|
| 413 |
+
// Add active class to cards with questions
|
| 414 |
+
if (short > 0) shortCard.classList.add('active');
|
| 415 |
+
if (long > 0) longCard.classList.add('active');
|
| 416 |
+
if (mcq > 0) mcqCard.classList.add('active');
|
| 417 |
+
}
|
| 418 |
+
|
| 419 |
+
// Form validation and loading state
|
| 420 |
+
document.getElementById('configForm').addEventListener('submit', function(e) {
|
| 421 |
+
const totalQuestions = parseInt(document.getElementById('totalQuestions').textContent);
|
| 422 |
+
if (totalQuestions === 0) {
|
| 423 |
+
e.preventDefault();
|
| 424 |
+
alert('Please select at least one question type before generating the paper.');
|
| 425 |
+
return;
|
| 426 |
+
}
|
| 427 |
+
|
| 428 |
+
// Show loading state
|
| 429 |
+
const generateBtn = document.getElementById('generateBtn');
|
| 430 |
+
const originalText = generateBtn.innerHTML;
|
| 431 |
+
generateBtn.disabled = true;
|
| 432 |
+
generateBtn.innerHTML = '<i class="fas fa-spinner fa-spin me-2"></i>Generating Questions... Please wait';
|
| 433 |
+
|
| 434 |
+
// Show loading message
|
| 435 |
+
const loadingDiv = document.createElement('div');
|
| 436 |
+
loadingDiv.id = 'loadingMessage';
|
| 437 |
+
loadingDiv.className = 'alert alert-info mt-3';
|
| 438 |
+
loadingDiv.innerHTML = `
|
| 439 |
+
<div class="d-flex align-items-center">
|
| 440 |
+
<div class="spinner-border spinner-border-sm me-3" role="status">
|
| 441 |
+
<span class="visually-hidden">Loading...</span>
|
| 442 |
+
</div>
|
| 443 |
+
<div>
|
| 444 |
+
<strong>Generating your question paper...</strong><br>
|
| 445 |
+
<small>This may take 30-60 seconds. Please don't refresh the page.</small>
|
| 446 |
+
</div>
|
| 447 |
+
</div>
|
| 448 |
+
`;
|
| 449 |
+
|
| 450 |
+
// Insert loading message after the form
|
| 451 |
+
const form = document.getElementById('configForm');
|
| 452 |
+
form.parentNode.insertBefore(loadingDiv, form.nextSibling);
|
| 453 |
+
|
| 454 |
+
// Timeout fallback - if it takes too long, show error message
|
| 455 |
+
setTimeout(function() {
|
| 456 |
+
if (document.getElementById('loadingMessage')) {
|
| 457 |
+
const errorDiv = document.createElement('div');
|
| 458 |
+
errorDiv.className = 'alert alert-warning mt-2';
|
| 459 |
+
errorDiv.innerHTML = `
|
| 460 |
+
<strong>Taking longer than expected...</strong><br>
|
| 461 |
+
The system might be initializing. Please wait a bit more or try refreshing the page if it doesn't respond.
|
| 462 |
+
`;
|
| 463 |
+
loadingDiv.appendChild(errorDiv);
|
| 464 |
+
}
|
| 465 |
+
}, 30000); // 30 seconds
|
| 466 |
+
});
|
| 467 |
+
|
| 468 |
+
// Initialize preview
|
| 469 |
+
updatePreview();
|
| 470 |
+
</script>
|
| 471 |
+
{% endblock %}
|
templates/step3_result.html
ADDED
|
@@ -0,0 +1,392 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{% extends 'base.html' %}
|
| 2 |
+
{% block title %}Step 3: Your Question Paper - AutoExamGen{% endblock %}
|
| 3 |
+
{% block head %}
|
| 4 |
+
<style>
|
| 5 |
+
body {
|
| 6 |
+
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
| 7 |
+
min-height: 100vh;
|
| 8 |
+
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
| 9 |
+
}
|
| 10 |
+
.container {
|
| 11 |
+
padding-top: 2rem;
|
| 12 |
+
}
|
| 13 |
+
.card {
|
| 14 |
+
border: none;
|
| 15 |
+
border-radius: 15px;
|
| 16 |
+
box-shadow: 0 10px 30px rgba(0,0,0,0.1);
|
| 17 |
+
backdrop-filter: blur(10px);
|
| 18 |
+
background: rgba(255, 255, 255, 0.95);
|
| 19 |
+
}
|
| 20 |
+
.btn-primary {
|
| 21 |
+
background: linear-gradient(45deg, #667eea, #764ba2);
|
| 22 |
+
border: none;
|
| 23 |
+
border-radius: 25px;
|
| 24 |
+
padding: 12px 30px;
|
| 25 |
+
font-weight: 600;
|
| 26 |
+
transition: all 0.3s ease;
|
| 27 |
+
}
|
| 28 |
+
.btn-primary:hover {
|
| 29 |
+
transform: translateY(-2px);
|
| 30 |
+
box-shadow: 0 5px 15px rgba(0,0,0,0.2);
|
| 31 |
+
}
|
| 32 |
+
.btn-success {
|
| 33 |
+
border-radius: 25px;
|
| 34 |
+
padding: 12px 30px;
|
| 35 |
+
font-weight: 600;
|
| 36 |
+
}
|
| 37 |
+
.btn-secondary {
|
| 38 |
+
border-radius: 25px;
|
| 39 |
+
padding: 12px 30px;
|
| 40 |
+
font-weight: 600;
|
| 41 |
+
}
|
| 42 |
+
.step-indicator {
|
| 43 |
+
display: flex;
|
| 44 |
+
justify-content: center;
|
| 45 |
+
margin-bottom: 2rem;
|
| 46 |
+
}
|
| 47 |
+
.step {
|
| 48 |
+
width: 40px;
|
| 49 |
+
height: 40px;
|
| 50 |
+
border-radius: 50%;
|
| 51 |
+
display: flex;
|
| 52 |
+
align-items: center;
|
| 53 |
+
justify-content: center;
|
| 54 |
+
margin: 0 10px;
|
| 55 |
+
font-weight: bold;
|
| 56 |
+
color: white;
|
| 57 |
+
}
|
| 58 |
+
.step.completed {
|
| 59 |
+
background: #28a745;
|
| 60 |
+
}
|
| 61 |
+
.step.active {
|
| 62 |
+
background: linear-gradient(45deg, #667eea, #764ba2);
|
| 63 |
+
}
|
| 64 |
+
.question-paper {
|
| 65 |
+
background: white;
|
| 66 |
+
border-radius: 15px;
|
| 67 |
+
padding: 2rem;
|
| 68 |
+
box-shadow: 0 5px 15px rgba(0,0,0,0.1);
|
| 69 |
+
margin: 1rem 0;
|
| 70 |
+
}
|
| 71 |
+
.paper-header {
|
| 72 |
+
text-align: center;
|
| 73 |
+
border-bottom: 2px solid #333;
|
| 74 |
+
padding-bottom: 1rem;
|
| 75 |
+
margin-bottom: 2rem;
|
| 76 |
+
}
|
| 77 |
+
.section-header {
|
| 78 |
+
background: linear-gradient(45deg, #667eea, #764ba2);
|
| 79 |
+
color: white;
|
| 80 |
+
padding: 0.5rem 1rem;
|
| 81 |
+
border-radius: 8px;
|
| 82 |
+
margin: 1.5rem 0 1rem 0;
|
| 83 |
+
font-weight: bold;
|
| 84 |
+
}
|
| 85 |
+
.question {
|
| 86 |
+
margin-bottom: 1.5rem;
|
| 87 |
+
padding: 1rem;
|
| 88 |
+
border-left: 4px solid #667eea;
|
| 89 |
+
background-color: #f8f9ff;
|
| 90 |
+
border-radius: 0 8px 8px 0;
|
| 91 |
+
}
|
| 92 |
+
.question-number {
|
| 93 |
+
font-weight: bold;
|
| 94 |
+
color: #667eea;
|
| 95 |
+
}
|
| 96 |
+
.question-marks {
|
| 97 |
+
float: right;
|
| 98 |
+
background: #667eea;
|
| 99 |
+
color: white;
|
| 100 |
+
padding: 2px 8px;
|
| 101 |
+
border-radius: 12px;
|
| 102 |
+
font-size: 0.8rem;
|
| 103 |
+
font-weight: bold;
|
| 104 |
+
}
|
| 105 |
+
.mcq-options {
|
| 106 |
+
margin-top: 0.5rem;
|
| 107 |
+
padding-left: 1rem;
|
| 108 |
+
}
|
| 109 |
+
.mcq-option {
|
| 110 |
+
margin: 0.3rem 0;
|
| 111 |
+
padding: 0.3rem 0;
|
| 112 |
+
}
|
| 113 |
+
.summary-stats {
|
| 114 |
+
background: linear-gradient(45deg, #667eea, #764ba2);
|
| 115 |
+
color: white;
|
| 116 |
+
border-radius: 15px;
|
| 117 |
+
padding: 1.5rem;
|
| 118 |
+
margin-bottom: 2rem;
|
| 119 |
+
}
|
| 120 |
+
.stat-item {
|
| 121 |
+
text-align: center;
|
| 122 |
+
}
|
| 123 |
+
.stat-number {
|
| 124 |
+
font-size: 2rem;
|
| 125 |
+
font-weight: bold;
|
| 126 |
+
display: block;
|
| 127 |
+
}
|
| 128 |
+
.stat-label {
|
| 129 |
+
font-size: 0.9rem;
|
| 130 |
+
opacity: 0.9;
|
| 131 |
+
}
|
| 132 |
+
.preview-mode {
|
| 133 |
+
max-height: 600px;
|
| 134 |
+
overflow-y: auto;
|
| 135 |
+
border: 2px solid #e9ecef;
|
| 136 |
+
border-radius: 15px;
|
| 137 |
+
}
|
| 138 |
+
@media print {
|
| 139 |
+
body {
|
| 140 |
+
background: white !important;
|
| 141 |
+
}
|
| 142 |
+
.no-print {
|
| 143 |
+
display: none !important;
|
| 144 |
+
}
|
| 145 |
+
.question-paper {
|
| 146 |
+
box-shadow: none;
|
| 147 |
+
margin: 0;
|
| 148 |
+
padding: 1rem;
|
| 149 |
+
}
|
| 150 |
+
}
|
| 151 |
+
</style>
|
| 152 |
+
{% endblock %}
|
| 153 |
+
{% block content %}
|
| 154 |
+
<div class="container">
|
| 155 |
+
<div class="row justify-content-center">
|
| 156 |
+
<div class="col-md-12">
|
| 157 |
+
<!-- Progress Indicator -->
|
| 158 |
+
<div class="step-indicator no-print">
|
| 159 |
+
<div class="step completed">1</div>
|
| 160 |
+
<div class="step completed">2</div>
|
| 161 |
+
<div class="step active">3</div>
|
| 162 |
+
</div>
|
| 163 |
+
|
| 164 |
+
<!-- Header Card -->
|
| 165 |
+
<div class="card no-print">
|
| 166 |
+
<div class="card-header bg-transparent text-center py-4">
|
| 167 |
+
<h2 class="mb-0">
|
| 168 |
+
<i class="fas fa-check-circle text-success me-2"></i>
|
| 169 |
+
Your Question Paper is Ready!
|
| 170 |
+
</h2>
|
| 171 |
+
<p class="text-muted mt-2">Review your generated question paper below</p>
|
| 172 |
+
</div>
|
| 173 |
+
</div>
|
| 174 |
+
|
| 175 |
+
<!-- Summary Stats -->
|
| 176 |
+
<div class="summary-stats no-print">
|
| 177 |
+
<div class="row">
|
| 178 |
+
<div class="col-md-2 stat-item">
|
| 179 |
+
<span class="stat-number">{{ config.short_questions + config.long_questions + config.mcq_questions }}</span>
|
| 180 |
+
<span class="stat-label">Total Questions</span>
|
| 181 |
+
</div>
|
| 182 |
+
<div class="col-md-2 stat-item">
|
| 183 |
+
<span class="stat-number">{{ total_marks }}</span>
|
| 184 |
+
<span class="stat-label">Total Marks</span>
|
| 185 |
+
</div>
|
| 186 |
+
<div class="col-md-2 stat-item">
|
| 187 |
+
<span class="stat-number">{{ config.short_questions }}</span>
|
| 188 |
+
<span class="stat-label">Short Questions</span>
|
| 189 |
+
</div>
|
| 190 |
+
<div class="col-md-2 stat-item">
|
| 191 |
+
<span class="stat-number">{{ config.long_questions }}</span>
|
| 192 |
+
<span class="stat-label">Long Questions</span>
|
| 193 |
+
</div>
|
| 194 |
+
<div class="col-md-2 stat-item">
|
| 195 |
+
<span class="stat-number">{{ config.mcq_questions }}</span>
|
| 196 |
+
<span class="stat-label">MCQ Questions</span>
|
| 197 |
+
</div>
|
| 198 |
+
<div class="col-md-2 stat-item">
|
| 199 |
+
<span class="stat-number">{{ display_duration }}</span>
|
| 200 |
+
<span class="stat-label">Time (min)</span>
|
| 201 |
+
</div>
|
| 202 |
+
</div>
|
| 203 |
+
</div>
|
| 204 |
+
|
| 205 |
+
<!-- Action Buttons -->
|
| 206 |
+
<div class="row mb-4 no-print">
|
| 207 |
+
<div class="col-md-3">
|
| 208 |
+
<a href="/" class="btn btn-secondary btn-lg w-100">
|
| 209 |
+
<i class="fas fa-home me-2"></i>
|
| 210 |
+
Start Over
|
| 211 |
+
</a>
|
| 212 |
+
</div>
|
| 213 |
+
<div class="col-md-3">
|
| 214 |
+
<button onclick="window.print()" class="btn btn-primary btn-lg w-100">
|
| 215 |
+
<i class="fas fa-print me-2"></i>
|
| 216 |
+
Print Paper
|
| 217 |
+
</button>
|
| 218 |
+
</div>
|
| 219 |
+
<div class="col-md-3">
|
| 220 |
+
<a href="/download" class="btn btn-success btn-lg w-100">
|
| 221 |
+
<i class="fas fa-download me-2"></i>
|
| 222 |
+
Download HTML
|
| 223 |
+
</a>
|
| 224 |
+
</div>
|
| 225 |
+
<div class="col-md-3">
|
| 226 |
+
<button onclick="togglePreview()" class="btn btn-primary btn-lg w-100" id="previewBtn">
|
| 227 |
+
<i class="fas fa-eye me-2"></i>
|
| 228 |
+
Preview Mode
|
| 229 |
+
</button>
|
| 230 |
+
</div>
|
| 231 |
+
</div>
|
| 232 |
+
|
| 233 |
+
<!-- Question Paper -->
|
| 234 |
+
<div class="question-paper" id="questionPaper">
|
| 235 |
+
<div class="paper-header">
|
| 236 |
+
<h1>{{ config.exam_name if config.exam_name else 'EXAMINATION QUESTION PAPER' }}</h1>
|
| 237 |
+
<h3>Subject: {{ config.subject_name if config.subject_name else '[Subject Name]' }}</h3>
|
| 238 |
+
<p><strong>Date:</strong> {{ exam_date }} <strong>Time:</strong> {{ display_duration }} minutes <strong>Total Marks:</strong> {{ total_marks }}</p>
|
| 239 |
+
<hr>
|
| 240 |
+
<p><strong>Instructions:</strong></p>
|
| 241 |
+
<ul style="text-align: left; display: inline-block;">
|
| 242 |
+
<li>Answer all questions</li>
|
| 243 |
+
<li>Write clearly and legibly</li>
|
| 244 |
+
<li>Manage your time effectively</li>
|
| 245 |
+
{% if config.mcq_questions > 0 %}
|
| 246 |
+
<li>For MCQ questions, choose the best answer</li>
|
| 247 |
+
{% endif %}
|
| 248 |
+
</ul>
|
| 249 |
+
</div>
|
| 250 |
+
|
| 251 |
+
<!-- Multiple Choice Questions -->
|
| 252 |
+
{% if config.mcq_questions > 0 and question_paper.mcq_questions %}
|
| 253 |
+
<div class="section-header">
|
| 254 |
+
<i class="fas fa-list-ul me-2"></i>
|
| 255 |
+
SECTION A: MULTIPLE CHOICE QUESTIONS (1 mark each)
|
| 256 |
+
</div>
|
| 257 |
+
{% for question in question_paper.mcq_questions %}
|
| 258 |
+
<div class="question">
|
| 259 |
+
<span class="question-marks">1 mark</span>
|
| 260 |
+
<span class="question-number">{{ loop.index }}.</span>
|
| 261 |
+
{{ question.question if question.question else question }}
|
| 262 |
+
|
| 263 |
+
{% if question.options %}
|
| 264 |
+
<div class="mcq-options">
|
| 265 |
+
{% for option in question.options %}
|
| 266 |
+
<div class="mcq-option">
|
| 267 |
+
<strong>{{ ['A', 'B', 'C', 'D'][loop.index0] }})</strong> {{ option }}
|
| 268 |
+
</div>
|
| 269 |
+
{% endfor %}
|
| 270 |
+
</div>
|
| 271 |
+
{% else %}
|
| 272 |
+
<div class="mcq-options">
|
| 273 |
+
<div class="mcq-option"><strong>A)</strong> [Option A]</div>
|
| 274 |
+
<div class="mcq-option"><strong>B)</strong> [Option B]</div>
|
| 275 |
+
<div class="mcq-option"><strong>C)</strong> [Option C]</div>
|
| 276 |
+
<div class="mcq-option"><strong>D)</strong> [Option D]</div>
|
| 277 |
+
</div>
|
| 278 |
+
{% endif %}
|
| 279 |
+
</div>
|
| 280 |
+
{% endfor %}
|
| 281 |
+
{% endif %}
|
| 282 |
+
|
| 283 |
+
<!-- Short Answer Questions -->
|
| 284 |
+
{% if config.short_questions > 0 and question_paper.short_questions %}
|
| 285 |
+
<div class="section-header">
|
| 286 |
+
<i class="fas fa-edit me-2"></i>
|
| 287 |
+
SECTION B: SHORT ANSWER QUESTIONS ({{ config.short_marks }} marks each)
|
| 288 |
+
</div>
|
| 289 |
+
{% for item in question_paper.short_questions %}
|
| 290 |
+
{% if config.short_or and (item.a or item.b) %}
|
| 291 |
+
<div class="question">
|
| 292 |
+
<span class="question-marks">{{ config.short_marks }} marks</span>
|
| 293 |
+
<span class="question-number">{{ loop.index }}.</span>
|
| 294 |
+
<div>
|
| 295 |
+
{{ (item.a.question if item.a.question else item.a) if item.a else '' }}
|
| 296 |
+
</div>
|
| 297 |
+
{% if item.b %}
|
| 298 |
+
<div class="text-center my-2"><em>OR</em></div>
|
| 299 |
+
<div>
|
| 300 |
+
{{ (item.b.question if item.b.question else item.b) if item.b else '' }}
|
| 301 |
+
</div>
|
| 302 |
+
{% endif %}
|
| 303 |
+
</div>
|
| 304 |
+
{% else %}
|
| 305 |
+
<div class="question">
|
| 306 |
+
<span class="question-marks">{{ config.short_marks }} marks</span>
|
| 307 |
+
<span class="question-number">{{ loop.index }}.</span>
|
| 308 |
+
{{ item.question if item.question else item }}
|
| 309 |
+
</div>
|
| 310 |
+
{% endif %}
|
| 311 |
+
{% endfor %}
|
| 312 |
+
{% endif %}
|
| 313 |
+
|
| 314 |
+
<!-- Long Answer Questions -->
|
| 315 |
+
{% if config.long_questions > 0 and question_paper.long_questions %}
|
| 316 |
+
<div class="section-header">
|
| 317 |
+
<i class="fas fa-file-alt me-2"></i>
|
| 318 |
+
SECTION C: LONG ANSWER QUESTIONS ({{ config.long_marks }} marks each)
|
| 319 |
+
</div>
|
| 320 |
+
{% if config.long_attempt %}
|
| 321 |
+
<div class="alert alert-info">Attempt any {{ config.long_attempt }} out of {{ config.long_questions }} questions.</div>
|
| 322 |
+
{% endif %}
|
| 323 |
+
{% for question in question_paper.long_questions %}
|
| 324 |
+
<div class="question">
|
| 325 |
+
<span class="question-marks">{{ config.long_marks }} marks</span>
|
| 326 |
+
<span class="question-number">{{ loop.index }}.</span>
|
| 327 |
+
{{ question.question if question.question else question }}
|
| 328 |
+
</div>
|
| 329 |
+
{% endfor %}
|
| 330 |
+
{% endif %}
|
| 331 |
+
|
| 332 |
+
<!-- Footer -->
|
| 333 |
+
<div style="text-align: center; margin-top: 3rem; padding-top: 1rem; border-top: 1px solid #ccc;">
|
| 334 |
+
<p><strong>*** END OF QUESTION PAPER ***</strong></p>
|
| 335 |
+
<p style="font-size: 0.9rem; color: #666;">
|
| 336 |
+
Generated on {{ exam_date }} using AI Question Generator
|
| 337 |
+
</p>
|
| 338 |
+
</div>
|
| 339 |
+
</div>
|
| 340 |
+
|
| 341 |
+
<!-- Tips Card -->
|
| 342 |
+
<div class="card mt-4 no-print">
|
| 343 |
+
<div class="card-body">
|
| 344 |
+
<h5 class="card-title">
|
| 345 |
+
<i class="fas fa-lightbulb text-warning me-2"></i>
|
| 346 |
+
Next Steps
|
| 347 |
+
</h5>
|
| 348 |
+
<div class="row">
|
| 349 |
+
<div class="col-md-4">
|
| 350 |
+
<h6><i class="fas fa-print text-primary me-2"></i>Print</h6>
|
| 351 |
+
<small class="text-muted">Use the Print button to get a clean, formatted printout of your question paper.</small>
|
| 352 |
+
</div>
|
| 353 |
+
<div class="col-md-4">
|
| 354 |
+
<h6><i class="fas fa-download text-success me-2"></i>Download</h6>
|
| 355 |
+
<small class="text-muted">Download as HTML file to save or share your question paper digitally.</small>
|
| 356 |
+
</div>
|
| 357 |
+
<div class="col-md-4">
|
| 358 |
+
<h6><i class="fas fa-edit text-info me-2"></i>Customize</h6>
|
| 359 |
+
<small class="text-muted">Edit the subject name, instructions, or questions as needed before printing.</small>
|
| 360 |
+
</div>
|
| 361 |
+
</div>
|
| 362 |
+
</div>
|
| 363 |
+
</div>
|
| 364 |
+
</div>
|
| 365 |
+
</div>
|
| 366 |
+
</div>
|
| 367 |
+
|
| 368 |
+
{% endblock %}
|
| 369 |
+
{% block scripts %}
|
| 370 |
+
<script>
|
| 371 |
+
function togglePreview() {
|
| 372 |
+
const paper = document.getElementById('questionPaper');
|
| 373 |
+
const btn = document.getElementById('previewBtn');
|
| 374 |
+
|
| 375 |
+
if (paper.classList.contains('preview-mode')) {
|
| 376 |
+
paper.classList.remove('preview-mode');
|
| 377 |
+
btn.innerHTML = '<i class="fas fa-eye me-2"></i>Preview Mode';
|
| 378 |
+
} else {
|
| 379 |
+
paper.classList.add('preview-mode');
|
| 380 |
+
btn.innerHTML = '<i class="fas fa-expand me-2"></i>Full View';
|
| 381 |
+
}
|
| 382 |
+
}
|
| 383 |
+
|
| 384 |
+
// Auto-scroll to paper on load
|
| 385 |
+
window.addEventListener('load', function() {
|
| 386 |
+
document.getElementById('questionPaper').scrollIntoView({
|
| 387 |
+
behavior: 'smooth',
|
| 388 |
+
block: 'start'
|
| 389 |
+
});
|
| 390 |
+
});
|
| 391 |
+
</script>
|
| 392 |
+
{% endblock %}
|
templates/welcome.html
ADDED
|
@@ -0,0 +1,115 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{% extends 'base.html' %}
|
| 2 |
+
{% block title %}Welcome - {{ project_name }}{% endblock %}
|
| 3 |
+
{% block head %}
|
| 4 |
+
<style>
|
| 5 |
+
body {
|
| 6 |
+
min-height: 100vh;
|
| 7 |
+
margin: 0;
|
| 8 |
+
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
| 9 |
+
background: radial-gradient(1200px 500px at 10% 10%, rgba(118, 75, 162, 0.25), transparent 70%),
|
| 10 |
+
radial-gradient(1000px 600px at 90% 20%, rgba(102, 126, 234, 0.25), transparent 70%),
|
| 11 |
+
linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
| 12 |
+
color: white;
|
| 13 |
+
}
|
| 14 |
+
.glass {
|
| 15 |
+
background: rgba(255, 255, 255, 0.12);
|
| 16 |
+
border: 1px solid rgba(255, 255, 255, 0.2);
|
| 17 |
+
box-shadow: 0 10px 30px rgba(0,0,0,0.2);
|
| 18 |
+
backdrop-filter: blur(10px);
|
| 19 |
+
-webkit-backdrop-filter: blur(10px);
|
| 20 |
+
border-radius: 20px;
|
| 21 |
+
}
|
| 22 |
+
.brand {
|
| 23 |
+
letter-spacing: 1px;
|
| 24 |
+
}
|
| 25 |
+
.pulse {
|
| 26 |
+
animation: pulse 2s infinite;
|
| 27 |
+
}
|
| 28 |
+
@keyframes pulse {
|
| 29 |
+
0% { transform: scale(1); opacity: 1; }
|
| 30 |
+
50% { transform: scale(1.03); opacity: 0.95; }
|
| 31 |
+
100% { transform: scale(1); opacity: 1; }
|
| 32 |
+
}
|
| 33 |
+
.btn-start {
|
| 34 |
+
background: linear-gradient(45deg, #00d2ff, #3a7bd5);
|
| 35 |
+
border: none;
|
| 36 |
+
border-radius: 30px;
|
| 37 |
+
padding: 12px 28px;
|
| 38 |
+
font-weight: 600;
|
| 39 |
+
transition: transform .2s ease, box-shadow .2s ease;
|
| 40 |
+
}
|
| 41 |
+
.btn-start:hover {
|
| 42 |
+
transform: translateY(-2px);
|
| 43 |
+
box-shadow: 0 10px 20px rgba(0,0,0,0.2);
|
| 44 |
+
}
|
| 45 |
+
.feature-icon {
|
| 46 |
+
width: 44px;
|
| 47 |
+
height: 44px;
|
| 48 |
+
border-radius: 12px;
|
| 49 |
+
display: inline-flex;
|
| 50 |
+
align-items: center;
|
| 51 |
+
justify-content: center;
|
| 52 |
+
background: rgba(255,255,255,0.15);
|
| 53 |
+
border: 1px solid rgba(255,255,255,0.2);
|
| 54 |
+
}
|
| 55 |
+
</style>
|
| 56 |
+
<script>
|
| 57 |
+
// Auto-redirect to step1 after a brief delay (optional)
|
| 58 |
+
// setTimeout(() => window.location.href = '/step1', 4000);
|
| 59 |
+
</script>
|
| 60 |
+
{% endblock %}
|
| 61 |
+
{% block content %}
|
| 62 |
+
<div class="container py-5">
|
| 63 |
+
<div class="row justify-content-center">
|
| 64 |
+
<div class="col-12 col-lg-10">
|
| 65 |
+
<div class="glass p-5 text-center">
|
| 66 |
+
<div class="mb-3">
|
| 67 |
+
<span class="feature-icon me-2"><i class="fas fa-bolt text-warning"></i></span>
|
| 68 |
+
<span class="feature-icon"><i class="fas fa-brain text-info"></i></span>
|
| 69 |
+
</div>
|
| 70 |
+
<h1 class="display-5 fw-bold brand pulse">Welcome to {{ project_name }}</h1>
|
| 71 |
+
<p class="lead mt-3 mb-4">AI-powered Exam Paper Generator. Create high-quality question papers in minutes with MCQ, Short, and Long sections.</p>
|
| 72 |
+
<div class="d-flex justify-content-center gap-3 flex-wrap mb-4">
|
| 73 |
+
<div class="feature-icon"><i class="fas fa-list-ul"></i></div>
|
| 74 |
+
<small>MCQ, Short OR, Long Attempt-any</small>
|
| 75 |
+
<div class="feature-icon"><i class="fas fa-sliders-h"></i></div>
|
| 76 |
+
<small>Custom marks and duration</small>
|
| 77 |
+
<div class="feature-icon"><i class="fas fa-file-export"></i></div>
|
| 78 |
+
<small>Printable and downloadable</small>
|
| 79 |
+
</div>
|
| 80 |
+
<a href="/step1" class="btn btn-start btn-lg">
|
| 81 |
+
<i class="fas fa-arrow-right me-2"></i>Get Started
|
| 82 |
+
</a>
|
| 83 |
+
</div>
|
| 84 |
+
</div>
|
| 85 |
+
</div>
|
| 86 |
+
</div>
|
| 87 |
+
|
| 88 |
+
<div class="container mt-4">
|
| 89 |
+
<div class="row g-4">
|
| 90 |
+
<div class="col-md-4">
|
| 91 |
+
<div class="glass p-4 h-100">
|
| 92 |
+
<div class="mb-2"><i class="fas fa-magic"></i></div>
|
| 93 |
+
<h5>Smart Generation</h5>
|
| 94 |
+
<small>Transforms your syllabus into structured questions with contextual MCQ options.</small>
|
| 95 |
+
</div>
|
| 96 |
+
</div>
|
| 97 |
+
<div class="col-md-4">
|
| 98 |
+
<div class="glass p-4 h-100">
|
| 99 |
+
<div class="mb-2"><i class="fas fa-paint-brush"></i></div>
|
| 100 |
+
<h5>Beautiful Output</h5>
|
| 101 |
+
<small>Clean, printable layouts with clear sections and instructions.</small>
|
| 102 |
+
</div>
|
| 103 |
+
</div>
|
| 104 |
+
<div class="col-md-4">
|
| 105 |
+
<div class="glass p-4 h-100">
|
| 106 |
+
<div class="mb-2"><i class="fas fa-lock"></i></div>
|
| 107 |
+
<h5>Privacy First</h5>
|
| 108 |
+
<small>Your content is processed on demand; no database storage by default.</small>
|
| 109 |
+
</div>
|
| 110 |
+
</div>
|
| 111 |
+
</div>
|
| 112 |
+
</div>
|
| 113 |
+
|
| 114 |
+
{% endblock %}
|
| 115 |
+
|