Bio-Du commited on
Commit
68639d0
·
verified ·
1 Parent(s): 7bbfc4a

Add 2 files

Browse files
Files changed (2) hide show
  1. README.md +7 -5
  2. index.html +682 -19
README.md CHANGED
@@ -1,10 +1,12 @@
1
  ---
2
- title: Financial Question Generator
3
- emoji:
4
- colorFrom: indigo
5
- colorTo: red
6
  sdk: static
7
  pinned: false
 
 
8
  ---
9
 
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
1
  ---
2
+ title: financial-question-generator
3
+ emoji: 🐳
4
+ colorFrom: purple
5
+ colorTo: gray
6
  sdk: static
7
  pinned: false
8
+ tags:
9
+ - deepsite
10
  ---
11
 
12
+ Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
index.html CHANGED
@@ -1,19 +1,682 @@
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>Financial Question Generator</title>
7
+ <script src="https://cdn.tailwindcss.com"></script>
8
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
9
+ <style>
10
+ .category-chip {
11
+ transition: all 0.3s ease;
12
+ }
13
+ .category-chip:hover {
14
+ transform: translateY(-2px);
15
+ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
16
+ }
17
+ .question-card {
18
+ transition: all 0.3s ease;
19
+ }
20
+ .question-card:hover {
21
+ transform: translateY(-3px);
22
+ box-shadow: 0 10px 15px rgba(0, 0, 0, 0.1);
23
+ }
24
+ .loading-spinner {
25
+ animation: spin 1s linear infinite;
26
+ }
27
+ @keyframes spin {
28
+ 0% { transform: rotate(0deg); }
29
+ 100% { transform: rotate(360deg); }
30
+ }
31
+ .tab-active {
32
+ border-bottom: 3px solid #3b82f6;
33
+ color: #3b82f6;
34
+ font-weight: 600;
35
+ }
36
+ </style>
37
+ </head>
38
+ <body class="bg-gray-50 min-h-screen">
39
+ <div class="container mx-auto px-4 py-8">
40
+ <header class="mb-10 text-center">
41
+ <h1 class="text-4xl font-bold text-blue-600 mb-2">Financial Question Generator</h1>
42
+ <p class="text-gray-600 text-lg">Generate unlimited English questions for financial and wallet-related scenarios</p>
43
+ </header>
44
+
45
+ <div class="bg-white rounded-xl shadow-lg p-6 mb-8">
46
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-6">
47
+ <div>
48
+ <h2 class="text-xl font-semibold mb-4 text-gray-800">Generation Settings</h2>
49
+
50
+ <div class="mb-4">
51
+ <label class="block text-gray-700 mb-2">Number of Questions</label>
52
+ <input type="number" id="questionCount" min="1" max="100" value="10" class="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500">
53
+ </div>
54
+
55
+ <div class="mb-4">
56
+ <label class="block text-gray-700 mb-2">Difficulty Level</label>
57
+ <div class="flex space-x-2">
58
+ <button data-difficulty="simple" class="difficulty-btn px-4 py-2 bg-green-100 text-green-800 rounded-lg hover:bg-green-200">Simple</button>
59
+ <button data-difficulty="medium" class="difficulty-btn px-4 py-2 bg-yellow-100 text-yellow-800 rounded-lg hover:bg-yellow-200">Medium</button>
60
+ <button data-difficulty="complex" class="difficulty-btn px-4 py-2 bg-red-100 text-red-800 rounded-lg hover:bg-red-200">Complex</button>
61
+ <button data-difficulty="random" class="difficulty-btn px-4 py-2 bg-gray-100 text-gray-800 rounded-lg hover:bg-gray-200">Random</button>
62
+ </div>
63
+ </div>
64
+
65
+ <div class="mb-4">
66
+ <label class="block text-gray-700 mb-2">Categories (Select at least one)</label>
67
+ <div class="flex flex-wrap gap-2">
68
+ <button data-category="deposit" class="category-chip px-3 py-1 bg-blue-100 text-blue-800 rounded-full hover:bg-blue-200">Deposit</button>
69
+ <button data-category="transfer" class="category-chip px-3 py-1 bg-purple-100 text-purple-800 rounded-full hover:bg-purple-200">Transfer</button>
70
+ <button data-category="withdrawal" class="category-chip px-3 py-1 bg-indigo-100 text-indigo-800 rounded-full hover:bg-indigo-200">Withdrawal</button>
71
+ <button data-category="security" class="category-chip px-3 py-1 bg-red-100 text-red-800 rounded-full hover:bg-red-200">Account Security</button>
72
+ <button data-category="payment" class="category-chip px-3 py-1 bg-green-100 text-green-800 rounded-full hover:bg-green-200">Payment</button>
73
+ <button data-category="card" class="category-chip px-3 py-1 bg-yellow-100 text-yellow-800 rounded-full hover:bg-yellow-200">Card Management</button>
74
+ <button data-category="billing" class="category-chip px-3 py-1 bg-pink-100 text-pink-800 rounded-full hover:bg-pink-200">Billing & Records</button>
75
+ <button data-category="basic" class="category-chip px-3 py-1 bg-gray-100 text-gray-800 rounded-full hover:bg-gray-200">Basic Features</button>
76
+ <button data-category="other" class="category-chip px-3 py-1 bg-teal-100 text-teal-800 rounded-full hover:bg-teal-200">Other</button>
77
+ </div>
78
+ </div>
79
+
80
+ <div class="mb-4">
81
+ <label class="block text-gray-700 mb-2">Custom Prompt (Optional)</label>
82
+ <textarea id="customPrompt" rows="3" class="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500" placeholder="Add any specific instructions for question generation..."></textarea>
83
+ </div>
84
+
85
+ <button id="generateBtn" class="w-full bg-blue-600 hover:bg-blue-700 text-white font-bold py-3 px-4 rounded-lg transition duration-300 flex items-center justify-center">
86
+ <i class="fas fa-bolt mr-2"></i> Generate Questions
87
+ </button>
88
+ </div>
89
+
90
+ <div>
91
+ <h2 class="text-xl font-semibold mb-4 text-gray-800">RAG & External Data</h2>
92
+
93
+ <div class="mb-4">
94
+ <label class="block text-gray-700 mb-2">Import External Data</label>
95
+ <div class="flex items-center space-x-2">
96
+ <input type="file" id="externalData" class="hidden">
97
+ <button id="uploadBtn" class="px-4 py-2 bg-gray-200 text-gray-800 rounded-lg hover:bg-gray-300 flex items-center">
98
+ <i class="fas fa-file-upload mr-2"></i> Choose File
99
+ </button>
100
+ <span id="fileName" class="text-gray-500 text-sm">No file selected</span>
101
+ </div>
102
+ <p class="text-xs text-gray-500 mt-1">Supported formats: .txt, .pdf, .docx, .csv</p>
103
+ </div>
104
+
105
+ <div class="mb-4">
106
+ <label class="block text-gray-700 mb-2">API Connection</label>
107
+ <div class="flex items-center space-x-2">
108
+ <div class="relative flex-grow">
109
+ <input type="text" id="apiKey" placeholder="Enter DeepSeek API Key" class="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500">
110
+ <button id="toggleKey" class="absolute right-3 top-2 text-gray-500">
111
+ <i class="fas fa-eye"></i>
112
+ </button>
113
+ </div>
114
+ <button id="testApiBtn" class="px-4 py-2 bg-green-600 text-white rounded-lg hover:bg-green-700">
115
+ Test
116
+ </button>
117
+ </div>
118
+ <div id="apiStatus" class="mt-2 text-sm flex items-center hidden">
119
+ <span class="w-3 h-3 rounded-full mr-2"></span>
120
+ <span>API Status</span>
121
+ </div>
122
+ </div>
123
+
124
+ <div class="bg-blue-50 p-4 rounded-lg">
125
+ <h3 class="font-semibold text-blue-800 mb-2 flex items-center">
126
+ <i class="fas fa-info-circle mr-2"></i> Generation Process
127
+ </h3>
128
+ <p class="text-sm text-blue-700">
129
+ Questions are generated using DeepSeek's AI model. For large batches, multiple API calls will be made automatically. Each question is categorized and checked for quality.
130
+ </p>
131
+ </div>
132
+ </div>
133
+ </div>
134
+ </div>
135
+
136
+ <div class="bg-white rounded-xl shadow-lg p-6">
137
+ <div class="flex justify-between items-center mb-6">
138
+ <h2 class="text-xl font-semibold text-gray-800">Generated Questions</h2>
139
+ <div class="flex space-x-2">
140
+ <button id="exportBtn" class="px-4 py-2 bg-green-600 text-white rounded-lg hover:bg-green-700 flex items-center">
141
+ <i class="fas fa-file-export mr-2"></i> Export
142
+ </button>
143
+ <button id="clearBtn" class="px-4 py-2 bg-gray-200 text-gray-800 rounded-lg hover:bg-gray-300 flex items-center">
144
+ <i class="fas fa-trash-alt mr-2"></i> Clear
145
+ </button>
146
+ </div>
147
+ </div>
148
+
149
+ <div class="border-b border-gray-200 mb-4">
150
+ <div class="flex space-x-6">
151
+ <button data-tab="all" class="tab-btn pb-2 px-1 text-gray-600 hover:text-blue-600">All</button>
152
+ <button data-tab="deposit" class="tab-btn pb-2 px-1 text-gray-600 hover:text-blue-600">Deposit</button>
153
+ <button data-tab="transfer" class="tab-btn pb-2 px-1 text-gray-600 hover:text-blue-600">Transfer</button>
154
+ <button data-tab="withdrawal" class="tab-btn pb-2 px-1 text-gray-600 hover:text-blue-600">Withdrawal</button>
155
+ <button data-tab="security" class="tab-btn pb-2 px-1 text-gray-600 hover:text-blue-600">Security</button>
156
+ <button data-tab="payment" class="tab-btn pb-2 px-1 text-gray-600 hover:text-blue-600">Payment</button>
157
+ <button data-tab="card" class="tab-btn pb-2 px-1 text-gray-600 hover:text-blue-600">Card</button>
158
+ <button data-tab="billing" class="tab-btn pb-2 px-1 text-gray-600 hover:text-blue-600">Billing</button>
159
+ <button data-tab="basic" class="tab-btn pb-2 px-1 text-gray-600 hover:text-blue-600">Basic</button>
160
+ <button data-tab="other" class="tab-btn pb-2 px-1 text-gray-600 hover:text-blue-600">Other</button>
161
+ </div>
162
+ </div>
163
+
164
+ <div id="loadingIndicator" class="text-center py-8 hidden">
165
+ <div class="inline-block loading-spinner text-blue-500 text-4xl mb-2">
166
+ <i class="fas fa-circle-notch"></i>
167
+ </div>
168
+ <p class="text-gray-600">Generating questions using DeepSeek API...</p>
169
+ <p id="progressText" class="text-sm text-gray-500 mt-1">Processing 0/0</p>
170
+ </div>
171
+
172
+ <div id="questionsContainer" class="space-y-4">
173
+ <div class="text-center py-12 text-gray-500">
174
+ <i class="fas fa-comment-dots text-4xl mb-3"></i>
175
+ <p>No questions generated yet. Configure your settings and click "Generate Questions".</p>
176
+ </div>
177
+ </div>
178
+
179
+ <div id="pagination" class="mt-6 flex justify-between items-center hidden">
180
+ <button id="prevPage" class="px-4 py-2 bg-gray-200 text-gray-800 rounded-lg hover:bg-gray-300 disabled:opacity-50">
181
+ <i class="fas fa-chevron-left mr-2"></i> Previous
182
+ </button>
183
+ <span id="pageInfo" class="text-gray-600">Page 1 of 1</span>
184
+ <button id="nextPage" class="px-4 py-2 bg-gray-200 text-gray-800 rounded-lg hover:bg-gray-300 disabled:opacity-50">
185
+ Next <i class="fas fa-chevron-right ml-2"></i>
186
+ </button>
187
+ </div>
188
+ </div>
189
+ </div>
190
+
191
+ <!-- Export Modal -->
192
+ <div id="exportModal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center hidden z-50">
193
+ <div class="bg-white rounded-xl p-6 w-full max-w-md">
194
+ <div class="flex justify-between items-center mb-4">
195
+ <h3 class="text-lg font-semibold">Export Questions</h3>
196
+ <button id="closeExportModal" class="text-gray-500 hover:text-gray-700">
197
+ <i class="fas fa-times"></i>
198
+ </button>
199
+ </div>
200
+
201
+ <div class="mb-4">
202
+ <label class="block text-gray-700 mb-2">Format</label>
203
+ <div class="flex space-x-2">
204
+ <button data-format="csv" class="export-format-btn px-4 py-2 bg-blue-100 text-blue-800 rounded-lg hover:bg-blue-200">CSV</button>
205
+ <button data-format="json" class="export-format-btn px-4 py-2 bg-green-100 text-green-800 rounded-lg hover:bg-green-200">JSON</button>
206
+ <button data-format="txt" class="export-format-btn px-4 py-2 bg-purple-100 text-purple-800 rounded-lg hover:bg-purple-200">Text</button>
207
+ </div>
208
+ </div>
209
+
210
+ <div class="mb-4">
211
+ <label class="block text-gray-700 mb-2">Filter</label>
212
+ <select id="exportFilter" class="w-full px-4 py-2 border rounded-lg">
213
+ <option value="all">All Questions</option>
214
+ <option value="current">Current View</option>
215
+ <option value="selected">Selected Questions</option>
216
+ </select>
217
+ </div>
218
+
219
+ <button id="confirmExport" class="w-full bg-blue-600 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded-lg">
220
+ <i class="fas fa-download mr-2"></i> Export
221
+ </button>
222
+ </div>
223
+ </div>
224
+
225
+ <script>
226
+ // DOM Elements
227
+ const generateBtn = document.getElementById('generateBtn');
228
+ const exportBtn = document.getElementById('exportBtn');
229
+ const clearBtn = document.getElementById('clearBtn');
230
+ const questionCount = document.getElementById('questionCount');
231
+ const customPrompt = document.getElementById('customPrompt');
232
+ const apiKey = document.getElementById('apiKey');
233
+ const testApiBtn = document.getElementById('testApiBtn');
234
+ const apiStatus = document.getElementById('apiStatus');
235
+ const toggleKey = document.getElementById('toggleKey');
236
+ const uploadBtn = document.getElementById('uploadBtn');
237
+ const externalData = document.getElementById('externalData');
238
+ const fileName = document.getElementById('fileName');
239
+ const questionsContainer = document.getElementById('questionsContainer');
240
+ const loadingIndicator = document.getElementById('loadingIndicator');
241
+ const progressText = document.getElementById('progressText');
242
+ const difficultyBtns = document.querySelectorAll('.difficulty-btn');
243
+ const categoryChips = document.querySelectorAll('.category-chip');
244
+ const tabBtns = document.querySelectorAll('.tab-btn');
245
+ const exportModal = document.getElementById('exportModal');
246
+ const closeExportModal = document.getElementById('closeExportModal');
247
+ const exportFormatBtns = document.querySelectorAll('.export-format-btn');
248
+ const confirmExport = document.getElementById('confirmExport');
249
+ const exportFilter = document.getElementById('exportFilter');
250
+ const prevPage = document.getElementById('prevPage');
251
+ const nextPage = document.getElementById('nextPage');
252
+ const pageInfo = document.getElementById('pageInfo');
253
+ const pagination = document.getElementById('pagination');
254
+
255
+ // State variables
256
+ let selectedCategories = new Set(['deposit', 'transfer', 'withdrawal', 'security', 'payment', 'card', 'billing', 'basic', 'other']);
257
+ let selectedDifficulty = 'random';
258
+ let currentTab = 'all';
259
+ let currentPage = 1;
260
+ const questionsPerPage = 10;
261
+ let allQuestions = [];
262
+ let displayedQuestions = [];
263
+ let selectedExportFormat = 'csv';
264
+ let apiConnected = false;
265
+ let externalDataContent = '';
266
+
267
+ // Initialize
268
+ document.addEventListener('DOMContentLoaded', () => {
269
+ // Set default active tab
270
+ document.querySelector('[data-tab="all"]').classList.add('tab-active');
271
+
272
+ // Set default active difficulty
273
+ document.querySelector('[data-difficulty="random"]').classList.add('bg-blue-200');
274
+
275
+ // Set default active export format
276
+ document.querySelector('[data-format="csv"]').classList.add('bg-blue-200', 'text-blue-800');
277
+ });
278
+
279
+ // Event Listeners
280
+ generateBtn.addEventListener('click', generateQuestions);
281
+ exportBtn.addEventListener('click', () => exportModal.classList.remove('hidden'));
282
+ clearBtn.addEventListener('click', clearQuestions);
283
+ closeExportModal.addEventListener('click', () => exportModal.classList.add('hidden'));
284
+ testApiBtn.addEventListener('click', testApiConnection);
285
+ toggleKey.addEventListener('click', toggleApiKeyVisibility);
286
+ uploadBtn.addEventListener('click', () => externalData.click());
287
+ externalData.addEventListener('change', handleFileUpload);
288
+ prevPage.addEventListener('click', () => navigatePage(-1));
289
+ nextPage.addEventListener('click', () => navigatePage(1));
290
+
291
+ // Difficulty buttons
292
+ difficultyBtns.forEach(btn => {
293
+ btn.addEventListener('click', () => {
294
+ difficultyBtns.forEach(b => b.classList.remove('bg-blue-200'));
295
+ btn.classList.add('bg-blue-200');
296
+ selectedDifficulty = btn.dataset.difficulty;
297
+ });
298
+ });
299
+
300
+ // Category chips
301
+ categoryChips.forEach(chip => {
302
+ chip.addEventListener('click', () => {
303
+ const category = chip.dataset.category;
304
+ if (selectedCategories.has(category)) {
305
+ selectedCategories.delete(category);
306
+ chip.classList.remove('bg-blue-200');
307
+ } else {
308
+ selectedCategories.add(category);
309
+ chip.classList.add('bg-blue-200');
310
+ }
311
+ });
312
+ });
313
+
314
+ // Tab buttons
315
+ tabBtns.forEach(btn => {
316
+ btn.addEventListener('click', () => {
317
+ tabBtns.forEach(b => b.classList.remove('tab-active'));
318
+ btn.classList.add('tab-active');
319
+ currentTab = btn.dataset.tab;
320
+ filterQuestions();
321
+ });
322
+ });
323
+
324
+ // Export format buttons
325
+ exportFormatBtns.forEach(btn => {
326
+ btn.addEventListener('click', () => {
327
+ exportFormatBtns.forEach(b => b.classList.remove('bg-blue-200', 'text-blue-800'));
328
+ btn.classList.add('bg-blue-200', 'text-blue-800');
329
+ selectedExportFormat = btn.dataset.format;
330
+ });
331
+ });
332
+
333
+ confirmExport.addEventListener('click', exportQuestions);
334
+
335
+ // Functions
336
+ async function generateQuestions() {
337
+ if (selectedCategories.size === 0) {
338
+ alert('Please select at least one category.');
339
+ return;
340
+ }
341
+
342
+ const count = parseInt(questionCount.value);
343
+ if (isNaN(count) || count < 1 || count > 100) {
344
+ alert('Please enter a valid number between 1 and 100.');
345
+ return;
346
+ }
347
+
348
+ if (!apiConnected) {
349
+ alert('Please connect to the DeepSeek API first.');
350
+ return;
351
+ }
352
+
353
+ // Show loading indicator
354
+ loadingIndicator.classList.remove('hidden');
355
+ questionsContainer.innerHTML = '';
356
+
357
+ try {
358
+ // Simulate API calls (in a real app, you would call the actual DeepSeek API)
359
+ const batchSize = 5; // Simulate batch processing
360
+ const batches = Math.ceil(count / batchSize);
361
+ allQuestions = [];
362
+
363
+ for (let i = 0; i < batches; i++) {
364
+ const currentBatchSize = i === batches - 1 ? count - (i * batchSize) : batchSize;
365
+ progressText.textContent = `Processing ${i * batchSize}/${count}`;
366
+
367
+ // Simulate API delay
368
+ await new Promise(resolve => setTimeout(resolve, 1000));
369
+
370
+ // Generate mock questions (replace with actual API call)
371
+ const batchQuestions = generateMockQuestions(currentBatchSize);
372
+ allQuestions = [...allQuestions, ...batchQuestions];
373
+ }
374
+
375
+ // Display questions
376
+ filterQuestions();
377
+ loadingIndicator.classList.add('hidden');
378
+
379
+ } catch (error) {
380
+ console.error('Error generating questions:', error);
381
+ loadingIndicator.classList.add('hidden');
382
+ questionsContainer.innerHTML = `
383
+ <div class="text-center py-12 text-red-500">
384
+ <i class="fas fa-exclamation-triangle text-4xl mb-3"></i>
385
+ <p>Error generating questions. Please try again.</p>
386
+ </div>
387
+ `;
388
+ }
389
+ }
390
+
391
+ function generateMockQuestions(count) {
392
+ const categories = Array.from(selectedCategories);
393
+ const difficulties = selectedDifficulty === 'random' ? ['simple', 'medium', 'complex'] : [selectedDifficulty];
394
+
395
+ const mockQuestions = [];
396
+ const questionTypes = [
397
+ "How do I {action} with my {account}?",
398
+ "What are the steps to {action}?",
399
+ "Why is my {action} not working?",
400
+ "How long does {action} take to process?",
401
+ "What fees are associated with {action}?",
402
+ "Can I {action} from multiple devices?",
403
+ "Is there a limit to how much I can {action}?",
404
+ "What security measures are in place for {action}?",
405
+ "How can I track my {action} history?",
406
+ "What should I do if my {action} fails?"
407
+ ];
408
+
409
+ const actionsByCategory = {
410
+ deposit: ['deposit money', 'add funds', 'top up my account', 'make a deposit'],
411
+ transfer: ['transfer money', 'send funds', 'move money between accounts', 'make a transfer'],
412
+ withdrawal: ['withdraw money', 'take out funds', 'cash out', 'make a withdrawal'],
413
+ security: ['secure my account', 'change my password', 'enable 2FA', 'report suspicious activity'],
414
+ payment: ['make a payment', 'pay a bill', 'send money to a merchant', 'complete a transaction'],
415
+ card: ['add a card', 'remove a card', 'update card details', 'report a lost card'],
416
+ billing: ['view my transaction history', 'download a statement', 'check my balance', 'review past payments'],
417
+ basic: ['log in', 'sign up', 'update my profile', 'contact support'],
418
+ other: ['use advanced features', 'access premium services', 'get help', 'resolve issues']
419
+ };
420
+
421
+ for (let i = 0; i < count; i++) {
422
+ const category = categories[Math.floor(Math.random() * categories.length)];
423
+ const difficulty = difficulties[Math.floor(Math.random() * difficulties.length)];
424
+ const action = actionsByCategory[category][Math.floor(Math.random() * actionsByCategory[category].length)];
425
+
426
+ const questionTemplate = questionTypes[Math.floor(Math.random() * questionTypes.length)];
427
+ const questionText = questionTemplate
428
+ .replace('{action}', action)
429
+ .replace('{account}', 'bank account/wallet');
430
+
431
+ mockQuestions.push({
432
+ id: Date.now() + i,
433
+ text: questionText,
434
+ category: category,
435
+ difficulty: difficulty,
436
+ generatedAt: new Date().toISOString()
437
+ });
438
+ }
439
+
440
+ return mockQuestions;
441
+ }
442
+
443
+ function filterQuestions() {
444
+ displayedQuestions = currentTab === 'all'
445
+ ? allQuestions
446
+ : allQuestions.filter(q => q.category === currentTab);
447
+
448
+ currentPage = 1;
449
+ renderQuestions();
450
+ updatePagination();
451
+ }
452
+
453
+ function renderQuestions() {
454
+ if (displayedQuestions.length === 0) {
455
+ questionsContainer.innerHTML = `
456
+ <div class="text-center py-12 text-gray-500">
457
+ <i class="fas fa-comment-dots text-4xl mb-3"></i>
458
+ <p>No questions match the current filter.</p>
459
+ </div>
460
+ `;
461
+ pagination.classList.add('hidden');
462
+ return;
463
+ }
464
+
465
+ const startIdx = (currentPage - 1) * questionsPerPage;
466
+ const endIdx = startIdx + questionsPerPage;
467
+ const questionsToShow = displayedQuestions.slice(startIdx, endIdx);
468
+
469
+ questionsContainer.innerHTML = '';
470
+
471
+ questionsToShow.forEach(question => {
472
+ const categoryColors = {
473
+ deposit: 'bg-blue-100 text-blue-800',
474
+ transfer: 'bg-purple-100 text-purple-800',
475
+ withdrawal: 'bg-indigo-100 text-indigo-800',
476
+ security: 'bg-red-100 text-red-800',
477
+ payment: 'bg-green-100 text-green-800',
478
+ card: 'bg-yellow-100 text-yellow-800',
479
+ billing: 'bg-pink-100 text-pink-800',
480
+ basic: 'bg-gray-100 text-gray-800',
481
+ other: 'bg-teal-100 text-teal-800'
482
+ };
483
+
484
+ const difficultyColors = {
485
+ simple: 'text-green-600',
486
+ medium: 'text-yellow-600',
487
+ complex: 'text-red-600'
488
+ };
489
+
490
+ const questionEl = document.createElement('div');
491
+ questionEl.className = 'question-card bg-white p-4 rounded-lg border border-gray-200 shadow-sm';
492
+ questionEl.innerHTML = `
493
+ <div class="flex justify-between items-start mb-2">
494
+ <p class="font-medium text-gray-800">${question.text}</p>
495
+ <div class="flex space-x-2">
496
+ <span class="text-xs px-2 py-1 rounded-full ${categoryColors[question.category]}">${question.category}</span>
497
+ <span class="text-xs px-2 py-1 rounded-full bg-gray-100 text-gray-800 ${difficultyColors[question.difficulty]}">${question.difficulty}</span>
498
+ </div>
499
+ </div>
500
+ <div class="flex justify-between items-center text-xs text-gray-500">
501
+ <span>Generated: ${new Date(question.generatedAt).toLocaleString()}</span>
502
+ <div class="flex space-x-2">
503
+ <button class="text-blue-500 hover:text-blue-700"><i class="fas fa-edit"></i></button>
504
+ <button class="text-red-500 hover:text-red-700"><i class="fas fa-trash-alt"></i></button>
505
+ </div>
506
+ </div>
507
+ `;
508
+
509
+ questionsContainer.appendChild(questionEl);
510
+ });
511
+
512
+ pagination.classList.remove('hidden');
513
+ }
514
+
515
+ function updatePagination() {
516
+ const totalPages = Math.ceil(displayedQuestions.length / questionsPerPage);
517
+ pageInfo.textContent = `Page ${currentPage} of ${totalPages}`;
518
+
519
+ prevPage.disabled = currentPage === 1;
520
+ nextPage.disabled = currentPage === totalPages;
521
+ }
522
+
523
+ function navigatePage(direction) {
524
+ const totalPages = Math.ceil(displayedQuestions.length / questionsPerPage);
525
+ const newPage = currentPage + direction;
526
+
527
+ if (newPage > 0 && newPage <= totalPages) {
528
+ currentPage = newPage;
529
+ renderQuestions();
530
+ updatePagination();
531
+ }
532
+ }
533
+
534
+ function clearQuestions() {
535
+ if (allQuestions.length === 0 || confirm('Are you sure you want to clear all generated questions?')) {
536
+ allQuestions = [];
537
+ displayedQuestions = [];
538
+ questionsContainer.innerHTML = `
539
+ <div class="text-center py-12 text-gray-500">
540
+ <i class="fas fa-comment-dots text-4xl mb-3"></i>
541
+ <p>No questions generated yet. Configure your settings and click "Generate Questions".</p>
542
+ </div>
543
+ `;
544
+ pagination.classList.add('hidden');
545
+ }
546
+ }
547
+
548
+ function exportQuestions() {
549
+ let questionsToExport = [];
550
+
551
+ switch (exportFilter.value) {
552
+ case 'all':
553
+ questionsToExport = allQuestions;
554
+ break;
555
+ case 'current':
556
+ const startIdx = (currentPage - 1) * questionsPerPage;
557
+ const endIdx = startIdx + questionsPerPage;
558
+ questionsToExport = displayedQuestions.slice(startIdx, endIdx);
559
+ break;
560
+ case 'selected':
561
+ // In a real app, you would track selected questions
562
+ alert('No questions selected. Exporting all questions instead.');
563
+ questionsToExport = allQuestions;
564
+ break;
565
+ }
566
+
567
+ if (questionsToExport.length === 0) {
568
+ alert('No questions to export.');
569
+ return;
570
+ }
571
+
572
+ let content = '';
573
+ let mimeType = 'text/plain';
574
+ let extension = 'txt';
575
+
576
+ switch (selectedExportFormat) {
577
+ case 'csv':
578
+ content = 'ID,Question,Category,Difficulty,Generated At\n';
579
+ questionsToExport.forEach(q => {
580
+ content += `"${q.id}","${q.text}","${q.category}","${q.difficulty}","${q.generatedAt}"\n`;
581
+ });
582
+ mimeType = 'text/csv';
583
+ extension = 'csv';
584
+ break;
585
+
586
+ case 'json':
587
+ content = JSON.stringify(questionsToExport, null, 2);
588
+ mimeType = 'application/json';
589
+ extension = 'json';
590
+ break;
591
+
592
+ case 'txt':
593
+ questionsToExport.forEach(q => {
594
+ content += `Question: ${q.text}\n`;
595
+ content += `Category: ${q.category}\n`;
596
+ content += `Difficulty: ${q.difficulty}\n`;
597
+ content += `Generated At: ${q.generatedAt}\n\n`;
598
+ });
599
+ break;
600
+ }
601
+
602
+ const blob = new Blob([content], { type: mimeType });
603
+ const url = URL.createObjectURL(blob);
604
+ const a = document.createElement('a');
605
+ a.href = url;
606
+ a.download = `financial_questions_${new Date().toISOString().slice(0, 10)}.${extension}`;
607
+ document.body.appendChild(a);
608
+ a.click();
609
+ document.body.removeChild(a);
610
+ URL.revokeObjectURL(url);
611
+
612
+ exportModal.classList.add('hidden');
613
+ }
614
+
615
+ async function testApiConnection() {
616
+ if (!apiKey.value.trim()) {
617
+ alert('Please enter your DeepSeek API key.');
618
+ return;
619
+ }
620
+
621
+ testApiBtn.disabled = true;
622
+ testApiBtn.innerHTML = '<i class="fas fa-spinner loading-spinner mr-2"></i> Testing';
623
+
624
+ // Simulate API test (replace with actual API call)
625
+ await new Promise(resolve => setTimeout(resolve, 1500));
626
+
627
+ // Mock response
628
+ const success = Math.random() > 0.2; // 80% chance of success for demo
629
+
630
+ if (success) {
631
+ apiStatus.classList.remove('hidden');
632
+ apiStatus.classList.add('text-green-600');
633
+ apiStatus.classList.remove('text-red-600');
634
+ apiStatus.querySelector('span').textContent = 'Connected to DeepSeek API';
635
+ apiStatus.querySelector('.rounded-full').classList.add('bg-green-500');
636
+ apiStatus.querySelector('.rounded-full').classList.remove('bg-red-500');
637
+ apiConnected = true;
638
+ } else {
639
+ apiStatus.classList.remove('hidden');
640
+ apiStatus.classList.add('text-red-600');
641
+ apiStatus.classList.remove('text-green-600');
642
+ apiStatus.querySelector('span').textContent = 'Connection failed';
643
+ apiStatus.querySelector('.rounded-full').classList.add('bg-red-500');
644
+ apiStatus.querySelector('.rounded-full').classList.remove('bg-green-500');
645
+ apiConnected = false;
646
+ }
647
+
648
+ testApiBtn.disabled = false;
649
+ testApiBtn.innerHTML = 'Test';
650
+ }
651
+
652
+ function toggleApiKeyVisibility() {
653
+ const icon = toggleKey.querySelector('i');
654
+ if (apiKey.type === 'password') {
655
+ apiKey.type = 'text';
656
+ icon.classList.remove('fa-eye');
657
+ icon.classList.add('fa-eye-slash');
658
+ } else {
659
+ apiKey.type = 'password';
660
+ icon.classList.remove('fa-eye-slash');
661
+ icon.classList.add('fa-eye');
662
+ }
663
+ }
664
+
665
+ function handleFileUpload(event) {
666
+ const file = event.target.files[0];
667
+ if (!file) return;
668
+
669
+ fileName.textContent = file.name;
670
+
671
+ // In a real app, you would process the file content
672
+ // For demo purposes, we'll just store the filename
673
+ externalDataContent = file.name;
674
+
675
+ // Simulate processing
676
+ setTimeout(() => {
677
+ alert(`File "${file.name}" has been processed and is ready to be used for RAG.`);
678
+ }, 1000);
679
+ }
680
+ </script>
681
+ <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - <a href="https://enzostvs-deepsite.hf.space?remix=Bio-Du/financial-question-generator" style="color: #fff;text-decoration: underline;" target="_blank" >🧬 Remix</a></p></body>
682
+ </html>