5m4ck3r commited on
Commit
ba758fd
·
verified ·
1 Parent(s): e03a184

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +1553 -18
index.html CHANGED
@@ -1,19 +1,1554 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
  </html>
 
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 Paper Creator</title>
7
+ <script src="https://cdn.tailwindcss.com"></script>
8
+ <link href="https://unpkg.com/aos@2.3.1/dist/aos.css" rel="stylesheet">
9
+ <script src="https://unpkg.com/aos@2.3.1/dist/aos.js"></script>
10
+ <script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script>
11
+ <script src="https://unpkg.com/feather-icons"></script>
12
+ <script>
13
+ tailwind.config = {
14
+ theme: {
15
+ extend: {
16
+ colors: {
17
+ primary: '#2563eb',
18
+ secondary: '#64748b',
19
+ accent: '#f59e0b',
20
+ }
21
+ }
22
+ }
23
+ }
24
+ </script>
25
+ <style>
26
+ .paper-container {
27
+ width: 210mm;
28
+ min-height: 297mm;
29
+ padding: 20mm;
30
+ margin: 10mm auto;
31
+ box-shadow: 0 0 10px rgba(0,0,0,0.1);
32
+ background: white;
33
+ }
34
+ .question-item {
35
+ position: relative;
36
+ margin-bottom: 20px;
37
+ padding: 15px;
38
+ border-radius: 8px;
39
+ border-left: 4px solid #2563eb;
40
+ }
41
+ .question-item:hover {
42
+ background-color: #f8fafc;
43
+ }
44
+ .option-grid {
45
+ display: grid;
46
+ grid-template-columns: 1fr 1fr;
47
+ gap: 15px;
48
+ margin-top: 10px;
49
+ }
50
+ .subquestions-container {
51
+ margin-left: 30px;
52
+ border-left: 2px dashed #cbd5e1;
53
+ padding-left: 15px;
54
+ }
55
+ .image-preview {
56
+ max-width: 100%;
57
+ max-height: 200px;
58
+ border-radius: 6px;
59
+ margin: 10px 0;
60
+ }
61
+ .popup-overlay {
62
+ position: fixed;
63
+ top: 0;
64
+ left: 0;
65
+ right: 0;
66
+ bottom: 0;
67
+ background-color: rgba(0,0,0,0.5);
68
+ display: flex;
69
+ align-items: center;
70
+ justify-content: center;
71
+ }
72
+ #questionModal.popup-overlay {
73
+ z-index: 3000;
74
+ }
75
+ #subquestionTypeModal.popup-overlay {
76
+ z-index: 5000;
77
+ }
78
+ .popup-content {
79
+ background: white;
80
+ border-radius: 12px;
81
+ padding: 24px;
82
+ max-width: 600px;
83
+ width: 90%;
84
+ max-height: 90vh;
85
+ overflow-y: auto;
86
+ }
87
+ .question-type-btn {
88
+ transition: all 0.2s ease;
89
+ }
90
+ .question-type-btn:hover {
91
+ transform: translateY(-2px);
92
+ box-shadow: 0 4px 6px -1px rgba(0,0,0,0.1);
93
+ }
94
+ .text-size-control {
95
+ position: fixed;
96
+ bottom: 20px;
97
+ right: 20px;
98
+ background: white;
99
+ border-radius: 50px;
100
+ padding: 10px;
101
+ box-shadow: 0 4px 12px rgba(0,0,0,0.15);
102
+ z-index: 100;
103
+ }
104
+ #questionsContainer .question-item {
105
+ position: relative;
106
+ z-index: 1;
107
+ }
108
+ .popup-overlay {
109
+ z-index: 9999;
110
+ }
111
+ .question-type-btn.selected {
112
+ background-color: #2563eb;
113
+ color: white;
114
+ border-color: #2563eb;
115
+ }
116
+ </style>
117
+ </head>
118
+ <body class="bg-gray-100 min-h-screen">
119
+ <!-- Initial Setup Modal -->
120
+ <div id="setupModal" class="popup-overlay">
121
+ <div class="popup-content" data-aos="zoom-in">
122
+ <h2 class="text-2xl font-bold text-center mb-6">Create Your Exam Paper</h2>
123
+ <div class="space-y-4">
124
+ <div>
125
+ <label class="block text-sm font-medium text-gray-700 mb-1">School Name</label>
126
+ <input type="text" id="schoolName" class="w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-primary focus:border-primary" placeholder="Enter school name">
127
+ </div>
128
+ <div>
129
+ <label class="block text-sm font-medium text-gray-700 mb-1">Exam Name</label>
130
+ <input type="text" id="examName" class="w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-primary focus:border-primary" placeholder="Enter exam name">
131
+ </div>
132
+ <div>
133
+ <label class="block text-sm font-medium text-gray-700 mb-1">Language</label>
134
+ <select id="language" class="w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-primary focus:border-primary">
135
+ <option value="english">English</option>
136
+ <option value="hindi">Hindi</option>
137
+ </select>
138
+ </div>
139
+ <div>
140
+ <label class="block text-sm font-medium text-gray-700 mb-1">Total Time (Hour)</label>
141
+ <input type="number" id="totalTime" class="w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-primary focus:border-primary" placeholder="Enter total time">
142
+ </div>
143
+ <div class="flex justify-end pt-4">
144
+ <button onclick="saveSetup()" class="bg-primary text-white px-6 py-2 rounded-md hover:bg-blue-700 transition">Create Paper</button>
145
+ </div>
146
+ </div>
147
+ </div>
148
+ </div>
149
+
150
+ <!-- Add Question Modal -->
151
+ <div id="addQuestionModal" class="popup-overlay hidden">
152
+ <div class="popup-content" data-aos="zoom-in">
153
+ <h2 class="text-2xl font-bold text-center mb-6">Add Question</h2>
154
+ <div class="mb-4">
155
+ <label class="block text-sm font-medium text-gray-700 mb-1">Marks for this question</label>
156
+ <input type="number" id="questionMarks" class="w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-primary focus:border-primary" placeholder="Enter marks">
157
+ </div>
158
+
159
+ <h3 class="text-lg font-semibold mb-4">Select Question Type</h3>
160
+ <div class="grid grid-cols-2 gap-4">
161
+ <button onclick="selectQuestionType('mcq', this)" class="question-type-btn p-4 border border-gray-200 rounded-md text-center hover:border-primary hover:bg-blue-50">
162
+ <i data-feather="check-square" class="mx-auto mb-2"></i>
163
+ <p>Multiple Choice</p>
164
+ </button>
165
+ <button onclick="selectQuestionType('normal', this)" class="question-type-btn p-4 border border-gray-200 rounded-md text-center hover:border-primary hover:bg-blue-50">
166
+ <i data-feather="edit" class="mx-auto mb-2"></i>
167
+ <p>Normal Question</p>
168
+ </button>
169
+ <button onclick="selectQuestionType('truefalse', this)" class="question-type-btn p-4 border border-gray-200 rounded-md text-center hover:border-primary hover:bg-blue-50">
170
+ <i data-feather="check-circle" class="mx-auto mb-2"></i>
171
+ <p>True/False</p>
172
+ </button>
173
+ <button onclick="selectQuestionType('imagefirst', this)" class="question-type-btn p-4 border border-gray-200 rounded-md text-center hover:border-primary hover:bg-blue-50">
174
+ <i data-feather="image" class="mx-auto mb-2"></i>
175
+ <p>Image with Question</p>
176
+ </button>
177
+ <button onclick="selectQuestionType('questionfirst', this)" class="question-type-btn p-4 border border-gray-200 rounded-md text-center hover:border-primary hover:bg-blue-50">
178
+ <i data-feather="type" class="mx-auto mb-2"></i>
179
+ <p>Question with Image</p>
180
+ </button>
181
+ <button onclick="selectQuestionType('subquestion', this)" class="question-type-btn p-4 border border-gray-200 rounded-md text-center hover:border-primary hover:bg-blue-50">
182
+ <i data-feather="layers" class="mx-auto mb-2"></i>
183
+ <p>Question with Subquestions</p>
184
+ </button>
185
+ <button onclick="selectQuestionType('questionspace', this)" class="question-type-btn p-4 border border-gray-200 rounded-md text-center hover:border-primary hover:bg-blue-50">
186
+ <i data-feather="align-left" class="mx-auto mb-2"></i>
187
+ <p>Question with Space</p>
188
+ </button>
189
+ <button onclick="selectQuestionType('spacequestion', this)" class="question-type-btn p-4 border border-gray-200 rounded-md text-center hover:border-primary hover:bg-blue-50">
190
+ <i data-feather="align-right" class="mx-auto mb-2"></i>
191
+ <p>Space with Question</p>
192
+ </button>
193
+ <button onclick="selectQuestionType('blank', this)" class="question-type-btn p-4 border border-gray-200 rounded-md text-center hover:border-primary hover:bg-blue-50">
194
+ <i data-feather="square" class="mx-auto mb-2"></i>
195
+ <p>Blank Space</p>
196
+ </button>
197
+ <button onclick="selectQuestionType('orquestion', this)" class="question-type-btn p-4 border border-gray-200 rounded-md text-center hover:border-primary hover:bg-blue-50">
198
+ <i data-feather="list" class="mx-auto mb-2"></i>
199
+ <p>Or Question</p>
200
+ </button>
201
+ </div>
202
+
203
+ <div class="flex justify-end space-x-3 mt-6 pt-4 border-t">
204
+ <button onclick="closeAddQuestionModal()" class="px-4 py-2 border border-gray-300 rounded-md hover:bg-gray-50">Cancel</button>
205
+ <button id="nextToDetailsBtn" onclick="showQuestionDetails()" class="bg-primary text-white px-4 py-2 rounded-md hover:bg-blue-700 hidden">Next</button>
206
+ </div>
207
+ </div>
208
+ </div>
209
+
210
+ <!-- Question Details Modal -->
211
+ <div id="questionDetailsModal" class="popup-overlay hidden">
212
+ <div class="popup-content" data-aos="zoom-in">
213
+ <h2 id="detailsModalTitle" class="text-2xl font-bold text-center mb-6">Question Details</h2>
214
+
215
+ <!-- Dynamic content based on question type -->
216
+ <div id="questionDetailsContent"></div>
217
+
218
+ <div class="flex justify-between mt-6 pt-4 border-t">
219
+ <button onclick="backToTypeSelection()" class="px-4 py-2 border border-gray-300 rounded-md hover:bg-gray-50">
220
+ <i data-feather="arrow-left" class="inline mr-2"></i> Back
221
+ </button>
222
+ <div class="space-x-3">
223
+ <button onclick="showUpcomingAlert('scan')" class="px-4 py-2 border border-gray-300 rounded-md hover:bg-gray-50">
224
+ <i data-feather="camera" class="inline mr-2"></i> Scan
225
+ </button>
226
+ <button onclick="showUpcomingAlert('ai')" class="px-4 py-2 border border-gray-300 rounded-md hover:bg-gray-50">
227
+ <i data-feather="cpu" class="inline mr-2"></i> AI Rewrite
228
+ </button>
229
+ <button onclick="addQuestionToPaper()" class="bg-primary text-white px-4 py-2 rounded-md hover:bg-blue-700">
230
+ Add Question
231
+ </button>
232
+ </div>
233
+ </div>
234
+ </div>
235
+ </div>
236
+
237
+ <!-- Subquestion Add Modal -->
238
+ <div id="subquestionModal" class="popup-overlay hidden">
239
+ <div class="popup-content" data-aos="zoom-in">
240
+ <h2 class="text-2xl font-bold text-center mb-6">Add Subquestion</h2>
241
+ <div id="subquestionContainer" class="space-y-4 mb-4"></div>
242
+
243
+ <div class="flex justify-between mt-6 pt-4 border-t">
244
+ <button onclick="addSubquestionType()" class="px-4 py-2 border border-primary text-primary rounded-md hover:bg-blue-50">
245
+ <i data-feather="plus" class="inline mr-2"></i> Add Another
246
+ </button>
247
+ <button onclick="finishSubquestions()" class="bg-primary text-white px-4 py-2 rounded-md hover:bg-blue-700">Done</button>
248
+ </div>
249
+ </div>
250
+ </div>
251
+
252
+ <!-- Main Content -->
253
+ <div class="container mx-auto py-8">
254
+ <!-- Header with controls -->
255
+ <div class="flex justify-between items-center mb-6 px-4">
256
+ <div>
257
+ <div class="flex items-center space-x-4 mt-2 text-sm text-gray-600">
258
+ <span id="timeDisplay">Time: --:--</span>
259
+ <span id="totalMarksDisplay">Total Marks: 0</span>
260
+ </div>
261
+ </div>
262
+ <div class="flex items-center space-x-3">
263
+ <button onclick="showAddQuestionModal()" class="bg-primary text-white px-4 py-2 rounded-md hover:bg-blue-700 flex items-center">
264
+ <i data-feather="plus" class="mr-2"></i> Add Question
265
+ </button>
266
+ <button id="downloadPdf" class="bg-green-600 text-white px-4 py-2 rounded-md hover:bg-green-700 flex items-center">
267
+ <i data-feather="download" class="mr-2"></i> Export PDF
268
+ </button>
269
+ </div>
270
+ </div>
271
+
272
+ <!-- Paper Container -->
273
+ <div class="paper-container" id="paperContent">
274
+ <!-- School and exam details -->
275
+ <div class="text-center mb-8">
276
+ <h2 id="schoolNameDisplay" class="text-xl font-bold uppercase"></h2>
277
+ <h3 id="examNameDisplay" class="text-lg font-semibold mt-2"></h3>
278
+ <div class="flex justify-between items-center mt-6 text-sm">
279
+ <div>Time: <span id="paperTimeDisplay"></span></div>
280
+ <div>Total Marks: <span id="paperTotalMarksDisplay">0</span></div>
281
+ </div>
282
+ <div class="border-b border-gray-300 mt-4"></div>
283
+ </div>
284
+
285
+ <!-- Questions will be added here -->
286
+ <div id="questionsContainer"></div>
287
+ </div>
288
+
289
+ <!-- Page counter -->
290
+ <div class="text-center mt-4 text-gray-600">
291
+ Page <span id="currentPage">1</span> of <span id="totalPages">1</span>
292
+ </div>
293
+ </div>
294
+
295
+ <!-- Text size controls -->
296
+ <div class="text-size-control flex items-center space-x-2">
297
+ <button onclick="decreaseTextSize()" class="w-8 h-8 rounded-full bg-gray-100 flex items-center justify-center hover:bg-gray-200">
298
+ <i data-feather="minus"></i>
299
+ </button>
300
+ <span class="text-sm">Text Size</span>
301
+ <button onclick="increaseTextSize()" class="w-8 h-8 rounded-full bg-gray-100 flex items-center justify-center hover:bg-gray-200">
302
+ <i data-feather="plus"></i>
303
+ </button>
304
+ </div>
305
+
306
+ <script>
307
+ let currentQuestionType = '';
308
+ let questions = [];
309
+ let textSize = 16;
310
+ let paperData = {
311
+ schoolName: '',
312
+ examName: '',
313
+ language: 'english',
314
+ totalTime: 0,
315
+ date: new Date()
316
+ };
317
+
318
+ document.addEventListener('DOMContentLoaded', function() {
319
+ AOS.init();
320
+ feather.replace();
321
+
322
+ // Check if we have saved data
323
+ const savedData = localStorage.getItem('examPaperData');
324
+ if (savedData) {
325
+ paperData = JSON.parse(savedData);
326
+ updatePaperHeader();
327
+ document.getElementById('setupModal').classList.add('hidden');
328
+ }
329
+
330
+ // Update date and time displays
331
+ updateDateTime();
332
+ setInterval(updateDateTime, 60000); // Update every minute
333
+ });
334
+
335
+ function getReadableQuestionTypeLabel(type) {
336
+ const map = {
337
+ 'mcq': 'Multiple Choice',
338
+ 'normal': 'Normal Question',
339
+ 'truefalse': 'True/False',
340
+ 'imagefirst': 'Image with Question',
341
+ 'questionfirst': 'Question with Image',
342
+ 'questionspace': 'Question with Space',
343
+ 'spacequestion': 'Space with Question',
344
+ 'blank': 'Blank Space',
345
+ 'orquestion': 'Or Question',
346
+ 'subquestion': 'Subquestion'
347
+ };
348
+ return map[type] || '';
349
+ }
350
+
351
+ function removeSubquestion(btn) {
352
+ const item = btn.closest('.subquestion-item');
353
+ if (!item) return;
354
+ const id = item.getAttribute('data-id');
355
+
356
+ // remove from editor container
357
+ const container = document.getElementById('subquestionContainer');
358
+ const modalItem = container ? container.querySelector(`.subquestion-item[data-id="${id}"]`) : null;
359
+ if (modalItem) modalItem.remove();
360
+
361
+ // remove from preview/details container
362
+ const detailsContainer = document.getElementById('subquestionsUI');
363
+ const detailsItem = detailsContainer ? detailsContainer.querySelector(`.subquestion-item[data-id="${id}"]`) : null;
364
+ if (detailsItem) detailsItem.remove();
365
+ }
366
+
367
+ function updateDateTime() {
368
+ const now = new Date();
369
+ const timeStr = now.toLocaleTimeString([], {hour: '2-digit', minute:'2-digit'});
370
+
371
+ document.getElementById('timeDisplay').textContent = `Time: ${timeStr}`;
372
+ }
373
+
374
+ function saveSetup() {
375
+ const schoolName = document.getElementById('schoolName').value;
376
+ const examName = document.getElementById('examName').value;
377
+ const language = document.getElementById('language').value;
378
+ const totalTime = document.getElementById('totalTime').value;
379
+
380
+ if (!schoolName || !examName || !totalTime) {
381
+ alert('Please fill all required fields');
382
+ return;
383
+ }
384
+
385
+ paperData = {
386
+ schoolName,
387
+ examName,
388
+ language,
389
+ totalTime: parseInt(totalTime),
390
+ date: new Date()
391
+ };
392
+
393
+ // Save to localStorage
394
+ localStorage.setItem('examPaperData', JSON.stringify(paperData));
395
+
396
+ // Update the display
397
+ updatePaperHeader();
398
+
399
+ // Hide the setup modal
400
+ document.getElementById('setupModal').classList.add('hidden');
401
+ }
402
+
403
+ function updatePaperHeader() {
404
+ document.getElementById('schoolNameDisplay').textContent = paperData.schoolName;
405
+ document.getElementById('examNameDisplay').textContent = paperData.examName;
406
+ document.getElementById('paperTimeDisplay').textContent = `${paperData.totalTime} Hours`;
407
+ updateTotalMarks();
408
+ }
409
+
410
+ function showAddQuestionModal() {
411
+ document.getElementById('addQuestionModal').classList.remove('hidden');
412
+ }
413
+
414
+ function closeAddQuestionModal() {
415
+ document.getElementById('addQuestionModal').classList.add('hidden');
416
+ document.getElementById('nextToDetailsBtn').classList.add('hidden');
417
+ currentQuestionType = '';
418
+ }
419
+
420
+ function selectQuestionType(type, button) {
421
+ currentQuestionType = type;
422
+ document.querySelectorAll('.question-type-btn').forEach(btn => {
423
+ btn.classList.remove('selected');
424
+ });
425
+ button.classList.add('selected');
426
+ document.getElementById('nextToDetailsBtn').classList.remove('hidden');
427
+ }
428
+
429
+ function showQuestionDetails() {
430
+ if (!currentQuestionType) {
431
+ alert('Please select a question type');
432
+ return;
433
+ }
434
+
435
+ const marks = document.getElementById('questionMarks').value;
436
+ if (!marks || marks <= 0) {
437
+ alert('Please enter valid marks for this question');
438
+ return;
439
+ }
440
+
441
+ document.getElementById('addQuestionModal').classList.add('hidden');
442
+
443
+ // Set modal title based on type
444
+ const typeTitles = {
445
+ 'mcq': 'Multiple Choice Question',
446
+ 'normal': 'Normal Question',
447
+ 'truefalse': 'True/False Question',
448
+ 'imagefirst': 'Image with Question',
449
+ 'questionfirst': 'Question with Image',
450
+ 'subquestion': 'Question with Subquestions',
451
+ 'questionspace': 'Question with Space',
452
+ 'spacequestion': 'Space with Question',
453
+ 'blank': 'Blank Space',
454
+ 'orquestion': 'Or Question'
455
+ };
456
+
457
+ document.getElementById('detailsModalTitle').textContent = typeTitles[currentQuestionType];
458
+
459
+ // Generate content based on question type
460
+ let contentHTML = '';
461
+
462
+ switch(currentQuestionType) {
463
+ case 'subquestion':
464
+ // Create parent object (only if not editing)
465
+ const newQuestion = {
466
+ type: 'subquestion',
467
+ marks: parseInt(document.getElementById('questionMarks').value),
468
+ id: Date.now(),
469
+ mainTitle: '',
470
+ subquestions: []
471
+ };
472
+ questions.push(newQuestion);
473
+
474
+ // store the parent id on the details modal so we can find it later
475
+ document.getElementById('questionDetailsModal').setAttribute('data-new-subquestion-id', newQuestion.id);
476
+
477
+ contentHTML = `
478
+ <div class="mb-4">
479
+ <label class="block text-sm font-medium text-gray-700 mb-1">Main Question Title</label>
480
+ <input type="text" id="mainQuestionTitle" class="w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-primary focus:border-primary" placeholder="Enter main question title">
481
+ </div>
482
+ <div id="subquestionsUI" class="space-y-3"></div>
483
+ <div class="text-center py-4">
484
+ <button onclick="openSubquestionModal()" class="bg-primary text-white px-4 py-2 rounded-md hover:bg-blue-700">
485
+ <i data-feather="plus" class="inline mr-2"></i> Add Subquestions
486
+ </button>
487
+ </div>
488
+ `;
489
+ break;
490
+
491
+ case 'mcq':
492
+ contentHTML = `
493
+ <div class="mb-4">
494
+ <label class="block text-sm font-medium text-gray-700 mb-1">Question</label>
495
+ <textarea id="mcqQuestion" class="w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-primary focus:border-primary" rows="3" placeholder="Enter your question"></textarea>
496
+ </div>
497
+ <div class="option-grid">
498
+ <div>
499
+ <label class="block text-sm font-medium text-gray-700 mb-1">Option i)</label>
500
+ <input type="text" id="option1" class="w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-primary focus:border-primary" placeholder="Option 1">
501
+ </div>
502
+ <div>
503
+ <label class="block text-sm font-medium text-gray-700 mb-1">Option ii)</label>
504
+ <input type="text" id="option2" class="w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-primary focus:border-primary" placeholder="Option 2">
505
+ </div>
506
+ <div>
507
+ <label class="block text-sm font-medium text-gray-700 mb-1">Option iii)</label>
508
+ <input type="text" id="option3" class="w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-primary focus:border-primary" placeholder="Option 3">
509
+ </div>
510
+ <div>
511
+ <label class="block text-sm font-medium text-gray-700 mb-1">Option iv)</label>
512
+ <input type="text" id="option4" class="w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-primary focus:border-primary" placeholder="Option 4">
513
+ </div>
514
+ </div>
515
+ <div class="mt-4 flex items-center">
516
+ <input type="checkbox" id="mcqAnswerOnPaper" class="mr-2">
517
+ <label for="mcqAnswerOnPaper" class="text-sm text-gray-700">Students answer on question paper</label>
518
+ </div>
519
+ `;
520
+ break;
521
+
522
+ case 'normal':
523
+ contentHTML = `
524
+ <div class="mb-4">
525
+ <label class="block text-sm font-medium text-gray-700 mb-1">Question</label>
526
+ <textarea id="normalQuestion" class="w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-primary focus:border-primary" rows="3" placeholder="Enter your question"></textarea>
527
+ </div>
528
+ <div class="flex items-center">
529
+ <input type="checkbox" id="normalAnswerOnPaper" class="mr-2">
530
+ <label for="normalAnswerOnPaper" class="text-sm text-gray-700">Students answer on question paper</label>
531
+ </div>
532
+ `;
533
+ break;
534
+
535
+ case 'truefalse':
536
+ contentHTML = `
537
+ <div class="mb-4">
538
+ <label class="block text-sm font-medium text-gray-700 mb-1">Question</label>
539
+ <textarea id="tfQuestion" class="w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-primary focus:border-primary" rows="3" placeholder="Enter your question"></textarea>
540
+ </div>
541
+ `;
542
+ break;
543
+
544
+ case 'imagefirst':
545
+ case 'questionfirst':
546
+ contentHTML = `
547
+ <div class="mb-4">
548
+ <label class="block text-sm font-medium text-gray-700 mb-1">${currentQuestionType === 'imagefirst' ? 'Upload Image' : 'Question'}</label>
549
+ ${currentQuestionType === 'imagefirst' ?
550
+ `<input type="file" id="imageUpload" accept="image/*" class="w-full px-4 py-2 border border-gray-300 rounded-md">` :
551
+ `<textarea id="questionText" class="w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-primary focus:border-primary" rows="3" placeholder="Enter your question"></textarea>`}
552
+ </div>
553
+ <div class="mb-4">
554
+ <label class="block text-sm font-medium text-gray-700 mb-1">${currentQuestionType === 'imagefirst' ? 'Question' : 'Upload Image'}</label>
555
+ ${currentQuestionType === 'imagefirst' ?
556
+ `<textarea id="questionText" class="w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-primary focus:border-primary" rows="3" placeholder="Enter your question"></textarea>` :
557
+ `<input type="file" id="imageUpload" accept="image/*" class="w-full px-4 py-2 border border-gray-300 rounded-md">`}
558
+ </div>
559
+ <div class="flex items-center">
560
+ <input type="checkbox" id="imageAnswerOnPaper" class="mr-2">
561
+ <label for="imageAnswerOnPaper" class="text-sm text-gray-700">Students answer on question paper</label>
562
+ </div>
563
+ `;
564
+ break;
565
+
566
+ case 'subquestion':
567
+ contentHTML = `
568
+ <div class="mb-4">
569
+ <label class="block text-sm font-medium text-gray-700 mb-1">Main Question Title</label>
570
+ <input type="text" id="mainQuestionTitle" class="w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-primary focus:border-primary" placeholder="Enter main question title">
571
+ </div>
572
+ <div class="text-center py-4">
573
+ <button onclick="openSubquestionModal()" class="bg-primary text-white px-4 py-2 rounded-md hover:bg-blue-700">
574
+ <i data-feather="plus" class="inline mr-2"></i> Add Subquestions
575
+ </button>
576
+ </div>
577
+ `;
578
+ break;
579
+
580
+ case 'questionspace':
581
+ case 'spacequestion':
582
+ contentHTML = `
583
+ <div class="mb-4">
584
+ <label class="block text-sm font-medium text-gray-700 mb-1">Question</label>
585
+ <textarea id="spaceQuestion" class="w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-primary focus:border-primary" rows="3" placeholder="Enter your question"></textarea>
586
+ </div>
587
+ <div class="mb-4">
588
+ <label class="block text-sm font-medium text-gray-700 mb-1">Space Height (lines)</label>
589
+ <input type="number" id="spaceHeight" class="w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-primary focus:border-primary" value="5" min="1">
590
+ </div>
591
+ <div class="flex items-center">
592
+ <input type="checkbox" id="spaceAnswerOnPaper" class="mr-2">
593
+ <label for="spaceAnswerOnPaper" class="text-sm text-gray-700">Students answer on question paper</label>
594
+ </div>
595
+ `;
596
+ break;
597
+
598
+ case 'blank':
599
+ contentHTML = `
600
+ <div class="mb-4">
601
+ <label class="block text-sm font-medium text-gray-700 mb-1">Space Height (lines)</label>
602
+ <input type="number" id="blankHeight" class="w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-primary focus:border-primary" value="5" min="1">
603
+ </div>
604
+ `;
605
+ break;
606
+
607
+ case 'orquestion':
608
+ contentHTML = `
609
+ <div id="orQuestionsContainer" class="space-y-4">
610
+ <div class="or-question-item">
611
+ <label class="block text-sm font-medium text-gray-700 mb-1">Option 1</label>
612
+ <textarea class="w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-primary focus:border-primary" rows="2" placeholder="Enter question option"></textarea>
613
+ </div>
614
+ <div class="or-question-item">
615
+ <label class="block text-sm font-medium text-gray-700 mb-1">Option 2</label>
616
+ <textarea class="w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-primary focus:border-primary" rows="2" placeholder="Enter question option"></textarea>
617
+ </div>
618
+ </div>
619
+ <div class="mt-4">
620
+ <button onclick="addOrOption()" class="text-primary hover:underline flex items-center">
621
+ <i data-feather="plus" class="inline mr-1 w-4 h-4"></i> Add another option
622
+ </button>
623
+ </div>
624
+ `;
625
+ break;
626
+ }
627
+
628
+ document.getElementById('questionDetailsContent').innerHTML = contentHTML;
629
+ feather.replace();
630
+ document.getElementById('questionDetailsModal').classList.remove('hidden');
631
+ }
632
+
633
+ function backToTypeSelection() {
634
+ document.getElementById('questionDetailsModal').classList.add('hidden');
635
+ document.getElementById('addQuestionModal').classList.remove('hidden');
636
+ }
637
+
638
+ function addQuestionToPaper() {
639
+ const marks = parseInt(document.getElementById('questionMarks').value);
640
+ const editId = document.getElementById('questionDetailsModal').getAttribute('data-edit-id');
641
+
642
+ let questionData = {
643
+ type: currentQuestionType,
644
+ marks: marks,
645
+ id: editId || Date.now()
646
+ };
647
+
648
+ // Collect data based on question type
649
+ switch(currentQuestionType) {
650
+ case 'mcq':
651
+ questionData.question = document.getElementById('mcqQuestion').value;
652
+ questionData.options = [
653
+ document.getElementById('option1').value,
654
+ document.getElementById('option2').value,
655
+ document.getElementById('option3').value,
656
+ document.getElementById('option4').value
657
+ ];
658
+ questionData.answerOnPaper = document.getElementById('mcqAnswerOnPaper').checked;
659
+ break;
660
+
661
+ case 'normal':
662
+ questionData.question = document.getElementById('normalQuestion').value;
663
+ questionData.answerOnPaper = document.getElementById('normalAnswerOnPaper').checked;
664
+ break;
665
+
666
+ case 'truefalse':
667
+ questionData.question = document.getElementById('tfQuestion').value;
668
+ break;
669
+
670
+ case 'imagefirst':
671
+ case 'questionfirst':
672
+ questionData.question = document.getElementById('questionText').value;
673
+ questionData.hasImage = true;
674
+ questionData.imagePlaceholder = true;
675
+ questionData.answerOnPaper = document.getElementById('imageAnswerOnPaper').checked;
676
+ break;
677
+
678
+ case 'subquestion':
679
+ const titleEl = document.getElementById('mainQuestionTitle');
680
+ // Prefer the id we stored earlier
681
+ const newId = document.getElementById('questionDetailsModal').getAttribute('data-new-subquestion-id');
682
+ let mainQuestion = null;
683
+ if (newId) mainQuestion = questions.find(q => q.id == newId);
684
+ if (!mainQuestion) {
685
+ // fallback
686
+ mainQuestion = questions.find(q => q.type === 'subquestion');
687
+ }
688
+ if (mainQuestion) {
689
+ mainQuestion.mainTitle = titleEl ? titleEl.value : '';
690
+ questionData = mainQuestion; // reuse existing object
691
+ }
692
+ break;
693
+
694
+ case 'questionspace':
695
+ case 'spacequestion':
696
+ questionData.question = document.getElementById('spaceQuestion').value;
697
+ questionData.spaceHeight = parseInt(document.getElementById('spaceHeight').value);
698
+ questionData.answerOnPaper = document.getElementById('spaceAnswerOnPaper').checked;
699
+ break;
700
+
701
+ case 'blank':
702
+ questionData.spaceHeight = parseInt(document.getElementById('blankHeight').value);
703
+ break;
704
+
705
+ case 'orquestion':
706
+ const orOptions = [];
707
+ document.querySelectorAll('.or-question-item textarea').forEach((ta, index) => {
708
+ orOptions.push({
709
+ id: index + 1,
710
+ text: ta.value
711
+ });
712
+ });
713
+ questionData.options = orOptions;
714
+ break;
715
+ }
716
+
717
+ if (editId) {
718
+ // Update existing question
719
+ const index = questions.findIndex(q => q.id === parseInt(editId));
720
+ if (index !== -1) {
721
+ questions[index] = { ...questions[index], ...questionData };
722
+ }
723
+ } else {
724
+ // Only push new questions if it's NOT subquestion
725
+ if (currentQuestionType !== 'subquestion') {
726
+ questions.push(questionData);
727
+ }
728
+ }
729
+
730
+ renderQuestions();
731
+ updateTotalMarks();
732
+
733
+ // Close the modal
734
+ document.getElementById('questionDetailsModal').classList.add('hidden');
735
+ document.getElementById('questionDetailsModal').removeAttribute('data-edit-id');
736
+
737
+ // Reset for next question
738
+ currentQuestionType = '';
739
+ document.getElementById('questionMarks').value = '';
740
+ }
741
+
742
+ function openSubquestionModal() {
743
+ // show the subquestion editor modal
744
+ document.getElementById('questionDetailsModal').classList.add('hidden');
745
+ document.getElementById('subquestionModal').classList.remove('hidden');
746
+
747
+ // populate subquestionContainer from preview (#subquestionsUI) so user can edit
748
+ const details = document.getElementById('subquestionsUI');
749
+ const container = document.getElementById('subquestionContainer');
750
+ container.innerHTML = '';
751
+
752
+ if (details && details.children.length) {
753
+ Array.from(details.children).forEach(child => {
754
+ container.appendChild(child.cloneNode(true));
755
+ });
756
+ } else {
757
+ container.innerHTML = `
758
+ <div class="text-center py-6 border-2 border-dashed border-gray-300 rounded-lg">
759
+ <p class="text-gray-500 mb-3">No subquestions added yet</p>
760
+ <button onclick="addSubquestionType()" class="bg-primary text-white px-4 py-2 rounded-md hover:bg-blue-700">
761
+ <i data-feather="plus" class="inline mr-2"></i> Add Subquestion
762
+ </button>
763
+ </div>
764
+ `;
765
+ }
766
+
767
+ feather.replace();
768
+ }
769
+
770
+ function addSubquestionType() {
771
+ // Create modal for selecting subquestion type
772
+ const modal = document.createElement('div');
773
+ modal.className = 'popup-overlay';
774
+ modal.id = 'subquestionTypeModal';
775
+ modal.innerHTML = `
776
+ <div class="popup-content">
777
+ <h2 class="text-2xl font-bold text-center mb-6">Select Subquestion Type</h2>
778
+ <div class="grid grid-cols-2 gap-4">
779
+ <button onclick="createSubquestion('mcq', true)" class="question-type-btn p-4 border border-gray-200 rounded-md text-center hover:border-primary hover:bg-blue-50">
780
+ <i data-feather="check-square" class="mx-auto mb-2"></i>
781
+ <p>Multiple Choice</p>
782
+ </button>
783
+ <button onclick="createSubquestion('normal', true)" class="question-type-btn p-4 border border-gray-200 rounded-md text-center hover:border-primary hover:bg-blue-50">
784
+ <i data-feather="edit" class="mx-auto mb-2"></i>
785
+ <p>Normal Question</p>
786
+ </button>
787
+ <button onclick="createSubquestion('truefalse', true)" class="question-type-btn p-4 border border-gray-200 rounded-md text-center hover:border-primary hover:bg-blue-50">
788
+ <i data-feather="check-circle" class="mx-auto mb-2"></i>
789
+ <p>True/False</p>
790
+ </button>
791
+ <button onclick="createSubquestion('imagefirst', true)" class="question-type-btn p-4 border border-gray-200 rounded-md text-center hover:border-primary hover:bg-blue-50">
792
+ <i data-feather="image" class="mx-auto mb-2"></i>
793
+ <p>Image with Question</p>
794
+ </button>
795
+ <button onclick="createSubquestion('questionfirst', true)" class="question-type-btn p-4 border border-gray-200 rounded-md text-center hover:border-primary hover:bg-blue-50">
796
+ <i data-feather="type" class="mx-auto mb-2"></i>
797
+ <p>Question with Image</p>
798
+ </button>
799
+ <button onclick="createSubquestion('questionspace', true)" class="question-type-btn p-4 border border-gray-200 rounded-md text-center hover:border-primary hover:bg-blue-50">
800
+ <i data-feather="align-left" class="mx-auto mb-2"></i>
801
+ <p>Question with Space</p>
802
+ </button>
803
+ <button onclick="createSubquestion('spacequestion', true)" class="question-type-btn p-4 border border-gray-200 rounded-md text-center hover:border-primary hover:bg-blue-50">
804
+ <i data-feather="align-right" class="mx-auto mb-2"></i>
805
+ <p>Space with Question</p>
806
+ </button>
807
+ <button onclick="createSubquestion('blank', true)" class="question-type-btn p-4 border border-gray-200 rounded-md text-center hover:border-primary hover:bg-blue-50">
808
+ <i data-feather="square" class="mx-auto mb-2"></i>
809
+ <p>Blank Space</p>
810
+ </button>
811
+ <button onclick="createSubquestion('orquestion', true)" class="question-type-btn p-4 border border-gray-200 rounded-md text-center hover:border-primary hover:bg-blue-50">
812
+ <i data-feather="list" class="mx-auto mb-2"></i>
813
+ <p>Or Question</p>
814
+ </button>
815
+ </div>
816
+ <div class="flex justify-end mt-6 pt-4 border-t">
817
+ <button onclick="document.getElementById('subquestionTypeModal').remove()" class="px-4 py-2 border border-gray-300 rounded-md hover:bg-gray-50">Cancel</button>
818
+ </div>
819
+ </div>
820
+ `;
821
+ document.body.appendChild(modal);
822
+ modal.classList.remove('hidden');
823
+ document.getElementById('subquestionModal').style.display = 'none';
824
+ feather.replace();
825
+ }
826
+
827
+ function createSubquestion(type, vie=false) {
828
+ // remove the type selection modal
829
+ if (vie) {
830
+ document.getElementById('subquestionModal').style.removeProperty("display");
831
+ }
832
+ const modal = document.getElementById('subquestionTypeModal');
833
+ if (modal) modal.remove();
834
+
835
+ const container = document.getElementById('subquestionContainer');
836
+ // Remove empty state if it exists
837
+ if (container && container.innerHTML.includes('No subquestions')) {
838
+ container.innerHTML = '';
839
+ }
840
+
841
+ const subquestionId = Date.now();
842
+ const newSubquestion = document.createElement('div');
843
+ newSubquestion.className = 'subquestion-item p-4 border border-gray-200 rounded-md mb-3';
844
+ newSubquestion.setAttribute('data-id', subquestionId);
845
+ newSubquestion.setAttribute('data-type', type);
846
+
847
+ // Header + delete button (delete calls removeSubquestion to sync preview + editor)
848
+ const readable = getReadableQuestionTypeLabel(type);
849
+ let contentHTML = `
850
+ <div class="flex justify-between items-start mb-3">
851
+ <h4 class="font-semibold">${readable}</h4>
852
+ <button onclick="removeSubquestion(this)" class="text-red-600 hover:text-red-800">
853
+ <i data-feather="trash-2" class="w-4 h-4"></i>
854
+ </button>
855
+ </div>
856
+ `;
857
+
858
+ // Fill based on type
859
+ switch(type) {
860
+ case 'mcq':
861
+ contentHTML += `
862
+ <div class="mb-3">
863
+ <label class="block text-sm font-medium text-gray-700 mb-1">Question</label>
864
+ <textarea class="w-full px-3 py-2 border border-gray-300 rounded-md" rows="2" placeholder="Enter question"></textarea>
865
+ </div>
866
+ <div class="grid grid-cols-2 gap-3 mb-3">
867
+ <div><label class="text-sm text-gray-600 block mb-1">i)</label><input type="text" class="w-full px-3 py-1 border border-gray-300 rounded-md" placeholder="Option 1"></div>
868
+ <div><label class="text-sm text-gray-600 block mb-1">ii)</label><input type="text" class="w-full px-3 py-1 border border-gray-300 rounded-md" placeholder="Option 2"></div>
869
+ <div><label class="text-sm text-gray-600 block mb-1">iii)</label><input type="text" class="w-full px-3 py-1 border border-gray-300 rounded-md" placeholder="Option 3"></div>
870
+ <div><label class="text-sm text-gray-600 block mb-1">iv)</label><input type="text" class="w-full px-3 py-1 border border-gray-300 rounded-md" placeholder="Option 4"></div>
871
+ </div>
872
+ `;
873
+ break;
874
+
875
+ case 'normal':
876
+ case 'truefalse':
877
+ contentHTML += `
878
+ <div class="mb-3">
879
+ <label class="block text-sm font-medium text-gray-700 mb-1">Question</label>
880
+ <textarea class="w-full px-3 py-2 border border-gray-300 rounded-md" rows="2" placeholder="Enter question"></textarea>
881
+ </div>
882
+ `;
883
+ break;
884
+
885
+ case 'imagefirst':
886
+ case 'questionfirst':
887
+ contentHTML += `
888
+ <div class="mb-3">
889
+ <label class="block text-sm font-medium text-gray-700 mb-1">Question</label>
890
+ <textarea class="w-full px-3 py-2 border border-gray-300 rounded-md" rows="2" placeholder="Enter question"></textarea>
891
+ </div>
892
+ <div class="mb-3">
893
+ <label class="block text-sm font-medium text-gray-700 mb-1">Image</label>
894
+ <input type="file" class="w-full px-3 py-1 border border-gray-300 rounded-md">
895
+ </div>
896
+ `;
897
+ break;
898
+
899
+ case 'questionspace':
900
+ case 'spacequestion':
901
+ // note: space height input comes BEFORE marks input so finishSubquestions can pick correctly
902
+ contentHTML += `
903
+ <div class="mb-3">
904
+ <label class="block text-sm font-medium text-gray-700 mb-1">Question</label>
905
+ <textarea class="w-full px-3 py-2 border border-gray-300 rounded-md" rows="2" placeholder="Enter question"></textarea>
906
+ </div>
907
+ <div class="mb-3">
908
+ <label class="block text-sm font-medium text-gray-700 mb-1">Space Height (lines)</label>
909
+ <input type="number" class="w-full px-3 py-1 border border-gray-300 rounded-md" value="5" min="1">
910
+ </div>
911
+ `;
912
+ break;
913
+
914
+ case 'blank':
915
+ contentHTML += `
916
+ <div class="mb-3">
917
+ <label class="block text-sm font-medium text-gray-700 mb-1">Space Height (lines)</label>
918
+ <input type="number" class="w-full px-3 py-1 border border-gray-300 rounded-md" value="5" min="1">
919
+ </div>
920
+ `;
921
+ break;
922
+
923
+ case 'orquestion':
924
+ contentHTML += `
925
+ <div class="space-y-3 mb-3">
926
+ <div>
927
+ <label class="block text-sm font-medium text-gray-700 mb-1">Option 1</label>
928
+ <textarea class="w-full px-3 py-1 border border-gray-300 rounded-md" rows="1" placeholder="Enter option"></textarea>
929
+ </div>
930
+ <div>
931
+ <label class="block text-sm font-medium text-gray-700 mb-1">Option 2</label>
932
+ <textarea class="w-full px-3 py-1 border border-gray-300 rounded-md" rows="1" placeholder="Enter option"></textarea>
933
+ </div>
934
+ </div>
935
+ <button onclick="addOrOptionToSubquestion(this)" class="text-primary text-sm hover:underline">+ Add another option</button>
936
+ `;
937
+ break;
938
+ }
939
+
940
+ // Marks field - note: this should be the LAST number input to identify marks reliably
941
+ contentHTML += `
942
+ <div class="mt-3">
943
+ <label class="block text-sm font-medium text-gray-700 mb-1">Marks</label>
944
+ <input type="number" class="w-20 px-3 py-1 border border-gray-300 rounded-md" value="1" min="1">
945
+ </div>
946
+ `;
947
+
948
+ newSubquestion.innerHTML = contentHTML;
949
+
950
+ // Append to modal subquestion container (editor)
951
+ container.appendChild(newSubquestion);
952
+
953
+ // Clone to preview area in details modal (so the user sees a live preview)
954
+ const detailsContainer = document.getElementById("subquestionsUI");
955
+ if (detailsContainer) {
956
+ detailsContainer.appendChild(newSubquestion.cloneNode(true));
957
+ }
958
+
959
+ feather.replace();
960
+ }
961
+
962
+ function addOrOptionToSubquestion(button) {
963
+ const container = button.parentElement.querySelector('.space-y-3');
964
+ const optionCount = container.children.length + 1;
965
+
966
+ const newOption = document.createElement('div');
967
+ newOption.innerHTML = `
968
+ <div>
969
+ <label class="block text-sm font-medium text-gray-700 mb-1">Option ${optionCount}</label>
970
+ <textarea class="w-full px-3 py-1 border border-gray-300 rounded-md" rows="1" placeholder="Enter option"></textarea>
971
+ <button onclick="this.parentElement.remove()" class="text-red-600 text-xs hover:underline mt-1">Remove</button>
972
+ </div>
973
+ `;
974
+ container.appendChild(newOption);
975
+ }
976
+
977
+ function finishSubquestions() {
978
+ const subquestions = [];
979
+
980
+ document.querySelectorAll('#subquestionContainer .subquestion-item').forEach((item) => {
981
+ const type = item.getAttribute('data-type');
982
+ const numberInputs = item.querySelectorAll('input[type="number"]');
983
+
984
+ // last numeric input = marks, the earlier numeric input (if any) is space height
985
+ let marks = 1;
986
+ let spaceHeight;
987
+ if (numberInputs.length) {
988
+ marks = parseInt(numberInputs[numberInputs.length - 1].value) || 1;
989
+ if (numberInputs.length > 1) {
990
+ spaceHeight = parseInt(numberInputs[0].value) || 5;
991
+ }
992
+ }
993
+
994
+ let questionData = {
995
+ type: type,
996
+ marks: marks
997
+ };
998
+
999
+ switch (type) {
1000
+ case 'mcq':
1001
+ questionData.question = item.querySelector('textarea') ? item.querySelector('textarea').value : '';
1002
+ questionData.options = Array.from(item.querySelectorAll('input[type="text"]')).map(opt => opt.value);
1003
+ break;
1004
+
1005
+ case 'normal':
1006
+ case 'truefalse':
1007
+ questionData.question = item.querySelector('textarea') ? item.querySelector('textarea').value : '';
1008
+ break;
1009
+
1010
+ case 'imagefirst':
1011
+ case 'questionfirst':
1012
+ questionData.question = item.querySelector('textarea') ? item.querySelector('textarea').value : '';
1013
+ const fileInput = item.querySelector('input[type="file"]');
1014
+ if (fileInput && fileInput.files && fileInput.files[0]) {
1015
+ const file = fileInput.files[0];
1016
+ const reader = new FileReader();
1017
+ reader.onload = (e) => {
1018
+ questionData.imageData = e.target.result; // store base64 data
1019
+ };
1020
+ reader.readAsDataURL(file);
1021
+ } else {
1022
+ questionData.imageData = null; // fallback if no file
1023
+ }
1024
+ break;
1025
+
1026
+ case 'questionspace':
1027
+ case 'spacequestion':
1028
+ questionData.question = item.querySelector('textarea') ? item.querySelector('textarea').value : '';
1029
+ questionData.spaceHeight = spaceHeight || 5;
1030
+ break;
1031
+
1032
+ case 'blank':
1033
+ questionData.type = 'blank';
1034
+ questionData.spaceHeight = spaceHeight || 5;
1035
+ break;
1036
+
1037
+ case 'orquestion':
1038
+ questionData.options = Array.from(item.querySelectorAll('.space-y-3 textarea')).map((ta, idx) => ({
1039
+ id: idx + 1,
1040
+ text: ta.value
1041
+ }));
1042
+ break;
1043
+ }
1044
+
1045
+ subquestions.push(questionData);
1046
+ });
1047
+
1048
+ // Attach to the parent question using the id we stored on the details modal
1049
+ const mainId = document.getElementById('questionDetailsModal').getAttribute('data-new-subquestion-id');
1050
+ let mainQuestion = null;
1051
+ if (mainId) {
1052
+ mainQuestion = questions.find(q => q.id == mainId);
1053
+ }
1054
+ // fallback: find the most recent subquestion parent
1055
+ if (!mainQuestion) {
1056
+ mainQuestion = [...questions].reverse().find(q => q.type === 'subquestion');
1057
+ }
1058
+
1059
+ if (mainQuestion) {
1060
+ mainQuestion.subquestions = subquestions;
1061
+ }
1062
+
1063
+ // close the subquestion editor and return to details
1064
+ document.getElementById('subquestionModal').classList.add('hidden');
1065
+ document.getElementById('questionDetailsModal').classList.remove('hidden');
1066
+
1067
+ // refresh preview in details (optional)
1068
+ const detailsContainer = document.getElementById('subquestionsUI');
1069
+ if (detailsContainer) {
1070
+ detailsContainer.innerHTML = '';
1071
+ subquestions.forEach((sq, idx) => {
1072
+ // make a simple preview node for each subquestion
1073
+ const preview = document.createElement('div');
1074
+ preview.className = 'subquestion-item p-3 border border-gray-100 rounded mb-2';
1075
+ preview.innerHTML = `<div class="font-medium">${getReadableQuestionTypeLabel(sq.type)}: ${sq.question || ''}</div>`;
1076
+ detailsContainer.appendChild(preview);
1077
+ });
1078
+ }
1079
+ }
1080
+
1081
+ function addOrOption() {
1082
+ const container = document.getElementById('orQuestionsContainer');
1083
+ const count = container.children.length + 1;
1084
+
1085
+ const newOption = document.createElement('div');
1086
+ newOption.className = 'or-question-item';
1087
+ newOption.innerHTML = `
1088
+ <label class="block text-sm font-medium text-gray-700 mb-1">Option ${count}</label>
1089
+ <textarea class="w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-primary focus:border-primary" rows="2" placeholder="Enter question option"></textarea>
1090
+ <button onclick="this.parentElement.remove()" class="mt-1 text-red-600 text-sm hover:underline flex items-center">
1091
+ <i data-feather="trash-2" class="inline mr-1 w-4 h-4"></i> Remove
1092
+ </button>
1093
+ `;
1094
+
1095
+ container.appendChild(newOption);
1096
+ feather.replace();
1097
+ }
1098
+
1099
+ function renderQuestions() {
1100
+ const container = document.getElementById('questionsContainer');
1101
+ container.innerHTML = '';
1102
+
1103
+ questions.forEach((q, index) => {
1104
+ const questionElement = document.createElement('div');
1105
+ questionElement.className = 'question-item';
1106
+ questionElement.setAttribute('data-id', q.id);
1107
+
1108
+ let questionHTML = `
1109
+ <div class="flex justify-between items-start mb-2">
1110
+ <div class="font-semibold">
1111
+ Q${index + 1}. ${
1112
+ q.type === 'subquestion'
1113
+ ? (q.mainTitle || '')
1114
+ : ['imagefirst','spacequestion','orquestion'].includes(q.type)
1115
+ ? ''
1116
+ : q.question
1117
+ }${q.type === 'truefalse' ? ' (True / False)' : ''}
1118
+ </div>
1119
+ <div class="flex space-x-2">
1120
+ <span class="text-sm text-blue-800 px-2 py-1 rounded">${q.marks || ''} marks</span>
1121
+ <button onclick="editQuestion(${q.id})" class="text-blue-600 hover:text-blue-800">
1122
+ <i data-feather="edit" class="w-4 h-4"></i>
1123
+ </button>
1124
+ <button onclick="deleteQuestion(${q.id})" class="text-red-600 hover:text-red-800">
1125
+ <i data-feather="trash-2" class="w-4 h-4"></i>
1126
+ </button>
1127
+ </div>
1128
+ </div>
1129
+ `;
1130
+
1131
+ switch(q.type) {
1132
+ case 'mcq':
1133
+ questionHTML += `
1134
+ <div class="option-grid mt-3">
1135
+ <div>i) ${q.options[0]}</div>
1136
+ <div>ii) ${q.options[1]}</div>
1137
+ <div>iii) ${q.options[2]}</div>
1138
+ <div>iv) ${q.options[3]}</div>
1139
+ </div>
1140
+ `;
1141
+ if (q.answerOnPaper) {
1142
+ questionHTML += `
1143
+ <div class="mt-3 flex space-x-6">
1144
+ <div>i) □</div>
1145
+ <div>ii) □</div>
1146
+ <div>iii) □</div>
1147
+ <div>iv) □</div>
1148
+ </div>
1149
+ `;
1150
+ }
1151
+ break;
1152
+
1153
+ case 'normal':
1154
+ if (q.answerOnPaper) {
1155
+ questionHTML += `<div class="mt-2 border-t border-gray-300 pt-2">Answer: _________________________</div>`;
1156
+ }
1157
+ break;
1158
+
1159
+ case 'truefalse':
1160
+ break;
1161
+
1162
+ case 'imagefirst':
1163
+ questionHTML += `
1164
+ <div class="mb-3">
1165
+ <img src="http://static.photos/education/640x360/${index + 10}" class="image-preview">
1166
+ </div>
1167
+ <div class="mb-2">${q.question}</div>
1168
+ `;
1169
+ if (q.answerOnPaper) {
1170
+ questionHTML += `<div class="mt-2 border-t border-gray-300 pt-2">Answer: _________________________</div>`;
1171
+ }
1172
+ break;
1173
+
1174
+ case 'questionfirst':
1175
+ questionHTML += `
1176
+ <div class="mb-3">
1177
+ <img src="http://static.photos/education/640x360/${index + 20}" class="image-preview">
1178
+ </div>
1179
+ `;
1180
+ if (q.answerOnPaper) {
1181
+ questionHTML += `<div class="mt-2 border-t border-gray-300 pt-2">Answer: _________________________</div>`;
1182
+ }
1183
+ break;
1184
+
1185
+ case 'subquestion':
1186
+ // Main title with spacing
1187
+ if (q.subquestions && q.subquestions.length) {
1188
+ questionHTML += `<div class="subquestions-container ml-6">`;
1189
+
1190
+ // Roman numerals for numbering
1191
+ const romanNumerals = ['i','ii','iii','iv','v','vi','vii','viii','ix','x'];
1192
+
1193
+ q.subquestions.forEach((sq, sqIndex) => {
1194
+ const label = romanNumerals[sqIndex] || (sqIndex + 1);
1195
+
1196
+ questionHTML += `<div class="mb-3">`;
1197
+ // layout: left = question content, right = marks
1198
+ questionHTML += `<div class="flex justify-between">`;
1199
+ questionHTML += `<div class="w-full">`;
1200
+
1201
+ // render by subquestion type (mirror top-level rendering)
1202
+ switch (sq.type) {
1203
+ case 'mcq':
1204
+ questionHTML += `<div class="font-medium">${label}) ${sq.question || ''}</div>`;
1205
+ questionHTML += `<div class="option-grid mt-2">`;
1206
+ questionHTML += `<div>i) ${sq.options && sq.options[0] ? sq.options[0] : ''}</div>`;
1207
+ questionHTML += `<div>ii) ${sq.options && sq.options[1] ? sq.options[1] : ''}</div>`;
1208
+ questionHTML += `<div>iii) ${sq.options && sq.options[2] ? sq.options[2] : ''}</div>`;
1209
+ questionHTML += `<div>iv) ${sq.options && sq.options[3] ? sq.options[3] : ''}</div>`;
1210
+ questionHTML += `</div>`;
1211
+ if (sq.answerOnPaper) {
1212
+ questionHTML += `<div class="mt-3 flex space-x-6"><div>i) □</div><div>ii) □</div><div>iii) □</div><div>iv) □</div></div>`;
1213
+ }
1214
+ break;
1215
+
1216
+ case 'normal':
1217
+ questionHTML += `<div class="font-medium">${label}) ${sq.question || ''}</div>`;
1218
+ if (sq.answerOnPaper) questionHTML += `<div class="mt-2 border-t border-gray-300 pt-2">Answer: _________________________</div>`;
1219
+ break;
1220
+
1221
+ case 'truefalse':
1222
+ questionHTML += `<div class="font-medium">${label}) ${sq.question || ''} (True / False)</div>`;
1223
+ break;
1224
+
1225
+ case 'imagefirst':
1226
+ // show image first then question (use stored imageData if available; else placeholder)
1227
+ questionHTML += `<div class="mb-3">`;
1228
+ questionHTML += `<img src="${sq.imageData || `http://static.photos/education/640x360/${index + 10}-${sqIndex}`}" class="image-preview">`;
1229
+ questionHTML += `</div>`;
1230
+ questionHTML += `<div class="font-medium">${label}) ${sq.question || ''}</div>`;
1231
+ if (sq.answerOnPaper) questionHTML += `<div class="mt-2 border-t border-gray-300 pt-2">Answer: _________________________</div>`;
1232
+ break;
1233
+
1234
+ case 'questionfirst':
1235
+ // question then image
1236
+ questionHTML += `<div class="font-medium">${label}) ${sq.question || ''}</div>`;
1237
+ questionHTML += `<div class="mb-3">`;
1238
+ questionHTML += `<img src="${sq.imageData || `http://static.photos/education/640x360/${index + 20}-${sqIndex}`}" class="image-preview">`;
1239
+ questionHTML += `</div>`;
1240
+ if (sq.answerOnPaper) questionHTML += `<div class="mt-2 border-t border-gray-300 pt-2">Answer: _________________________</div>`;
1241
+ break;
1242
+
1243
+ case 'questionspace':
1244
+ questionHTML += `<div class="font-medium">${label}) ${sq.question || ''}</div>`;
1245
+ questionHTML += `<div class="mt-2" style="height: ${(sq.spaceHeight || 5) * 24}px; border-bottom: 1px dashed #ccc;"></div>`;
1246
+ break;
1247
+
1248
+ case 'spacequestion':
1249
+ questionHTML += `<div class="mb-2" style="height: ${(sq.spaceHeight || 5) * 24}px; border-bottom: 1px dashed #ccc;"></div>`;
1250
+ questionHTML += `<div class="font-medium">${label}) ${sq.question || ''}</div>`;
1251
+ break;
1252
+
1253
+ case 'blank':
1254
+ questionHTML += `<div class="my-4" style="height: ${(sq.spaceHeight || 5) * 24}px; border-bottom: 1px dashed #ccc;"></div>`;
1255
+ break;
1256
+
1257
+ case 'orquestion':
1258
+ questionHTML += `<div class="font-medium">${label})</div>`;
1259
+ questionHTML += `<div class="space-y-3">`;
1260
+ (sq.options || []).forEach((opt, optIndex) => {
1261
+ questionHTML += `<div class="flex items-start"><div class="mr-2 font-medium">${optIndex + 1}.</div><div>${opt.text || ''}</div></div>`;
1262
+ if (optIndex < (sq.options || []).length - 1) questionHTML += `<div class="text-center font-bold">OR</div>`;
1263
+ });
1264
+ questionHTML += `</div>`;
1265
+ break;
1266
+
1267
+ default:
1268
+ questionHTML += `<div class="font-medium">${label}) ${sq.question || ''}</div>`;
1269
+ }
1270
+
1271
+ questionHTML += `</div>`; // close left side (w-full)
1272
+
1273
+ // marks on the right
1274
+ questionHTML += `<div class="ml-4"><span class="text-sm text-blue-800 px-2 py-1 rounded">${sq.marks || 1} marks</span></div>`;
1275
+
1276
+ questionHTML += `</div>`; // close flex justify-between
1277
+ questionHTML += `</div>`; // close mb-3
1278
+ });
1279
+
1280
+ questionHTML += `</div>`; // close subquestions-container
1281
+ }
1282
+ break;
1283
+
1284
+ case 'questionspace':
1285
+ questionHTML += `
1286
+ <div class="mt-4" style="height: ${q.spaceHeight * 24}px; border-bottom: 1px dashed #ccc;"></div>
1287
+ `;
1288
+ if (q.answerOnPaper) {
1289
+ questionHTML += `<div class="mt-2 border-t border-gray-300 pt-2">Answer: _________________________</div>`;
1290
+ }
1291
+ break;
1292
+
1293
+ case 'spacequestion':
1294
+ questionHTML += `
1295
+ <div class="mb-4" style="height: ${q.spaceHeight * 24}px; border-bottom: 1px dashed #ccc;"></div>
1296
+ <div class="mb-2">${q.question}</div>
1297
+ `;
1298
+ if (q.answerOnPaper) {
1299
+ questionHTML += `<div class="mt-2 border-t border-gray-300 pt-2">Answer: _________________________</div>`;
1300
+ }
1301
+ break;
1302
+
1303
+ case 'blank':
1304
+ questionHTML += `<div class="my-4" style="height: ${q.spaceHeight * 24}px; border-bottom: 1px dashed #ccc;"></div>`;
1305
+ break;
1306
+
1307
+ case 'orquestion':
1308
+ questionHTML += `<div class="space-y-3">`;
1309
+ q.options.forEach((opt, optIndex) => {
1310
+ questionHTML += `
1311
+ <div class="flex items-start">
1312
+ <div class="mr-2 font-medium">${optIndex + 1}.</div>
1313
+ <div>${opt.text}</div>
1314
+ </div>
1315
+ `;
1316
+ if (optIndex < q.options.length - 1) {
1317
+ questionHTML += `<div class="text-center font-bold">OR</div>`;
1318
+ }
1319
+ });
1320
+ questionHTML += `</div>`;
1321
+ break;
1322
+ }
1323
+
1324
+ questionElement.innerHTML = questionHTML;
1325
+ container.appendChild(questionElement);
1326
+ });
1327
+
1328
+ feather.replace();
1329
+ }
1330
+
1331
+ function getQuestionTypeLabel(type) {
1332
+ const labels = {
1333
+ 'mcq': '',
1334
+ 'normal': '',
1335
+ 'truefalse': '',
1336
+ 'imagefirst': '',
1337
+ 'questionfirst': '',
1338
+ 'subquestion': '',
1339
+ 'questionspace': '',
1340
+ 'spacequestion': '',
1341
+ 'blank': '',
1342
+ 'orquestion': ''
1343
+ };
1344
+ return labels[type] || '';
1345
+ }
1346
+
1347
+ function updateTotalMarks() {
1348
+ const total = questions.reduce((sum, q) => {
1349
+ if (q.type === 'subquestion' && q.subquestions) {
1350
+ return sum + q.subquestions.reduce((subSum, sq) => subSum + sq.marks, 0);
1351
+ }
1352
+ return sum + (q.marks || 0);
1353
+ }, 0);
1354
+
1355
+ document.getElementById('paperTotalMarksDisplay').textContent = total;
1356
+ }
1357
+
1358
+ function editQuestion(id) {
1359
+ const question = questions.find(q => q.id === id);
1360
+ if (!question) return;
1361
+
1362
+ currentQuestionType = question.type;
1363
+ document.getElementById('questionMarks').value = question.marks;
1364
+
1365
+ // Set modal title
1366
+ const typeTitles = {
1367
+ 'mcq': 'Multiple Choice Question',
1368
+ 'normal': 'Normal Question',
1369
+ 'truefalse': 'True/False Question',
1370
+ 'imagefirst': 'Image with Question',
1371
+ 'questionfirst': 'Question with Image',
1372
+ 'subquestion': 'Question with Subquestions',
1373
+ 'questionspace': 'Question with Space',
1374
+ 'spacequestion': 'Space with Question',
1375
+ 'blank': 'Blank Space',
1376
+ 'orquestion': 'Or Question'
1377
+ };
1378
+
1379
+ document.getElementById('detailsModalTitle').textContent = `Edit ${typeTitles[currentQuestionType]}`;
1380
+
1381
+ // Generate content with pre-filled data
1382
+ let contentHTML = '';
1383
+
1384
+ switch(currentQuestionType) {
1385
+ case 'mcq':
1386
+ contentHTML = `
1387
+ <div class="mb-4">
1388
+ <label class="block text-sm font-medium text-gray-700 mb-1">Question</label>
1389
+ <textarea id="mcqQuestion" class="w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-primary focus:border-primary" rows="3">${question.question || ''}</textarea>
1390
+ </div>
1391
+ <div class="option-grid">
1392
+ <div><label class="block text-sm font-medium text-gray-700 mb-1">Option i)</label><input type="text" id="option1" class="w-full px-4 py-2 border border-gray-300 rounded-md" value="${question.options[0] || ''}"></div>
1393
+ <div><label class="block text-sm font-medium text-gray-700 mb-1">Option ii)</label><input type="text" id="option2" class="w-full px-4 py-2 border border-gray-300 rounded-md" value="${question.options[1] || ''}"></div>
1394
+ <div><label class="block text-sm font-medium text-gray-700 mb-1">Option iii)</label><input type="text" id="option3" class="w-full px-4 py-2 border border-gray-300 rounded-md" value="${question.options[2] || ''}"></div>
1395
+ <div><label class="block text-sm font-medium text-gray-700 mb-1">Option iv)</label><input type="text" id="option4" class="w-full px-4 py-2 border border-gray-300 rounded-md" value="${question.options[3] || ''}"></div>
1396
+ </div>
1397
+ <div class="mt-4 flex items-center"><input type="checkbox" id="mcqAnswerOnPaper" ${question.answerOnPaper ? 'checked' : ''} class="mr-2"><label class="text-sm text-gray-700">Students answer on question paper</label></div>
1398
+ `;
1399
+ break;
1400
+
1401
+ case 'normal':
1402
+ contentHTML = `
1403
+ <div class="mb-4">
1404
+ <label class="block text-sm font-medium text-gray-700 mb-1">Question</label>
1405
+ <textarea id="normalQuestion" class="w-full px-4 py-2 border border-gray-300 rounded-md" rows="3">${question.question || ''}</textarea>
1406
+ </div>
1407
+ <div class="flex items-center"><input type="checkbox" id="normalAnswerOnPaper" ${question.answerOnPaper ? 'checked' : ''} class="mr-2"><label class="text-sm text-gray-700">Students answer on question paper</label></div>
1408
+ `;
1409
+ break;
1410
+
1411
+ case 'truefalse':
1412
+ contentHTML = `
1413
+ <div class="mb-4">
1414
+ <label class="block text-sm font-medium text-gray-700 mb-1">Question</label>
1415
+ <textarea id="tfQuestion" class="w-full px-4 py-2 border border-gray-300 rounded-md" rows="3">${question.question || ''}</textarea>
1416
+ </div>
1417
+ `;
1418
+ break;
1419
+
1420
+ case 'imagefirst':
1421
+ case 'questionfirst':
1422
+ contentHTML = `
1423
+ <div class="mb-4">
1424
+ <label class="block text-sm font-medium text-gray-700 mb-1">${currentQuestionType === 'imagefirst' ? 'Upload Image' : 'Question'}</label>
1425
+ ${currentQuestionType === 'imagefirst' ?
1426
+ `<input type="file" id="imageUpload" accept="image/*" class="w-full px-4 py-2 border border-gray-300 rounded-md">` :
1427
+ `<textarea id="questionText" class="w-full px-4 py-2 border border-gray-300 rounded-md" rows="3">${question.question || ''}</textarea>`}
1428
+ </div>
1429
+ <div class="mb-4">
1430
+ <label class="block text-sm font-medium text-gray-700 mb-1">${currentQuestionType === 'imagefirst' ? 'Question' : 'Upload Image'}</label>
1431
+ ${currentQuestionType === 'imagefirst' ?
1432
+ `<textarea id="questionText" class="w-full px-4 py-2 border border-gray-300 rounded-md" rows="3">${question.question || ''}</textarea>` :
1433
+ `<input type="file" id="imageUpload" accept="image/*" class="w-full px-4 py-2 border border-gray-300 rounded-md">`}
1434
+ </div>
1435
+ <div class="flex items-center"><input type="checkbox" id="imageAnswerOnPaper" ${question.answerOnPaper ? 'checked' : ''} class="mr-2"><label class="text-sm text-gray-700">Students answer on question paper</label></div>
1436
+ `;
1437
+ break;
1438
+
1439
+ case 'subquestion':
1440
+ contentHTML = `
1441
+ <div class="mb-4">
1442
+ <label class="block text-sm font-medium text-gray-700 mb-1">Main Question Title</label>
1443
+ <input type="text" id="mainQuestionTitle" class="w-full px-4 py-2 border border-gray-300 rounded-md" value="${question.mainTitle || ''}">
1444
+ </div>
1445
+ <div class="text-center py-4">
1446
+ <button onclick="openSubquestionModal()" class="bg-primary text-white px-4 py-2 rounded-md">
1447
+ <i data-feather="edit" class="inline mr-2"></i> Edit Subquestions
1448
+ </button>
1449
+ </div>
1450
+ `;
1451
+ break;
1452
+
1453
+ case 'questionspace':
1454
+ case 'spacequestion':
1455
+ contentHTML = `
1456
+ <div class="mb-4">
1457
+ <label class="block text-sm font-medium text-gray-700 mb-1">Question</label>
1458
+ <textarea id="spaceQuestion" class="w-full px-4 py-2 border border-gray-300 rounded-md" rows="3">${question.question || ''}</textarea>
1459
+ </div>
1460
+ <div class="mb-4">
1461
+ <label class="block text-sm font-medium text-gray-700 mb-1">Space Height (lines)</label>
1462
+ <input type="number" id="spaceHeight" class="w-full px-4 py-2 border border-gray-300 rounded-md" value="${question.spaceHeight || 5}">
1463
+ </div>
1464
+ <div class="flex items-center"><input type="checkbox" id="spaceAnswerOnPaper" ${question.answerOnPaper ? 'checked' : ''} class="mr-2"><label class="text-sm text-gray-700">Students answer on question paper</label></div>
1465
+ `;
1466
+ break;
1467
+
1468
+ case 'blank':
1469
+ contentHTML = `
1470
+ <div class="mb-4">
1471
+ <label class="block text-sm font-medium text-gray-700 mb-1">Space Height (lines)</label>
1472
+ <input type="number" id="blankHeight" class="w-full px-4 py-2 border border-gray-300 rounded-md" value="${question.spaceHeight || 5}">
1473
+ </div>
1474
+ `;
1475
+ break;
1476
+
1477
+ case 'orquestion':
1478
+ contentHTML = `
1479
+ <div id="orQuestionsContainer" class="space-y-4">
1480
+ ${question.options.map((opt, index) => `
1481
+ <div class="or-question-item">
1482
+ <label class="block text-sm font-medium text-gray-700 mb-1">Option ${index + 1}</label>
1483
+ <textarea class="w-full px-4 py-2 border border-gray-300 rounded-md" rows="2">${opt.text || ''}</textarea>
1484
+ </div>
1485
+ `).join('')}
1486
+ </div>
1487
+ <div class="mt-4">
1488
+ <button onclick="addOrOption()" class="text-primary hover:underline flex items-center">
1489
+ <i data-feather="plus" class="inline mr-1 w-4 h-4"></i> Add another option
1490
+ </button>
1491
+ </div>
1492
+ `;
1493
+ break;
1494
+ }
1495
+
1496
+ document.getElementById('questionDetailsContent').innerHTML = contentHTML;
1497
+ feather.replace();
1498
+
1499
+ // Store the question ID for updating
1500
+ document.getElementById('questionDetailsModal').setAttribute('data-edit-id', id);
1501
+ document.getElementById('questionDetailsModal').classList.remove('hidden');
1502
+ }
1503
+
1504
+ function deleteQuestion(id) {
1505
+ if (confirm('Are you sure you want to delete this question?')) {
1506
+ questions = questions.filter(q => q.id !== id);
1507
+ renderQuestions();
1508
+ updateTotalMarks();
1509
+ }
1510
+ }
1511
+
1512
+ function increaseTextSize() {
1513
+ textSize = Math.min(24, textSize + 1);
1514
+ document.getElementById('paperContent').style.fontSize = `${textSize}px`;
1515
+ }
1516
+
1517
+ function decreaseTextSize() {
1518
+ textSize = Math.max(12, textSize - 1);
1519
+ document.getElementById('paperContent').style.fontSize = `${textSize}px`;
1520
+ }
1521
+
1522
+ function showUpcomingAlert(feature) {
1523
+ alert(`Feature "${feature}" is upcoming and will be available soon!`);
1524
+ }
1525
+
1526
+ </script>
1527
+ <script>feather.replace();</script>
1528
+ <script>AOS.init();</script>
1529
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js"></script>
1530
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js"></script>
1531
+ <script>
1532
+ document.getElementById("downloadPdf").addEventListener("click", async () => {
1533
+ document.querySelectorAll('#paperContent svg').forEach(el => el.style.display = 'none');
1534
+ feather.replace();
1535
+ const { jsPDF } = window.jspdf;
1536
+
1537
+ const pdf = new jsPDF('p', 'pt', 'a4'); // Use mm units for easier calculations
1538
+
1539
+ const element = document.getElementById("paperContent");
1540
+
1541
+ await pdf.html(element, {
1542
+ callback: function (pdf) {
1543
+ pdf.save("section.pdf");
1544
+ },
1545
+ x: 5,
1546
+ y: 5,
1547
+ html2canvas: { scale: 0.7 }
1548
+ });
1549
+
1550
+ document.querySelectorAll('#paperContent svg').forEach(el => el.style.display = '');
1551
+ });
1552
+ </script>
1553
+ </body>
1554
  </html>