| | <!DOCTYPE html> |
| | <html lang="en"> |
| | <head> |
| | <meta charset="UTF-8"> |
| | <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| | <title>Financial Question Generator</title> |
| | <script src="https://cdn.tailwindcss.com"></script> |
| | <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> |
| | <style> |
| | .category-chip { |
| | transition: all 0.3s ease; |
| | } |
| | .category-chip:hover { |
| | transform: translateY(-2px); |
| | box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); |
| | } |
| | .question-card { |
| | transition: all 0.3s ease; |
| | } |
| | .question-card:hover { |
| | transform: translateY(-3px); |
| | box-shadow: 0 10px 15px rgba(0, 0, 0, 0.1); |
| | } |
| | .loading-spinner { |
| | animation: spin 1s linear infinite; |
| | } |
| | @keyframes spin { |
| | 0% { transform: rotate(0deg); } |
| | 100% { transform: rotate(360deg); } |
| | } |
| | .tab-active { |
| | border-bottom: 3px solid #3b82f6; |
| | color: #3b82f6; |
| | font-weight: 600; |
| | } |
| | .shake { |
| | animation: shake 0.5s linear; |
| | } |
| | @keyframes shake { |
| | 0%, 100% { transform: translateX(0); } |
| | 20%, 60% { transform: translateX(-5px); } |
| | 40%, 80% { transform: translateX(5px); } |
| | } |
| | </style> |
| | </head> |
| | <body class="bg-gray-50 min-h-screen"> |
| | <div class="container mx-auto px-4 py-8"> |
| | <header class="mb-10 text-center"> |
| | <h1 class="text-4xl font-bold text-blue-600 mb-2">Financial Question Generator</h1> |
| | <p class="text-gray-600 text-lg">Generate unlimited English questions for financial and wallet-related scenarios</p> |
| | </header> |
| |
|
| | <div class="bg-white rounded-xl shadow-lg p-6 mb-8"> |
| | <div class="grid grid-cols-1 md:grid-cols-2 gap-6"> |
| | <div> |
| | <h2 class="text-xl font-semibold mb-4 text-gray-800">Generation Settings</h2> |
| | |
| | <div class="mb-4"> |
| | <label class="block text-gray-700 mb-2">Number of Questions</label> |
| | <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"> |
| | </div> |
| | |
| | <div class="mb-4"> |
| | <label class="block text-gray-700 mb-2">Difficulty Level</label> |
| | <div class="flex space-x-2"> |
| | <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> |
| | <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> |
| | <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> |
| | <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> |
| | </div> |
| | </div> |
| | |
| | <div class="mb-4"> |
| | <label class="block text-gray-700 mb-2">Categories (Select at least one)</label> |
| | <div class="flex flex-wrap gap-2"> |
| | <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> |
| | <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> |
| | <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> |
| | <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> |
| | <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> |
| | <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> |
| | <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> |
| | <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> |
| | <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> |
| | </div> |
| | </div> |
| | |
| | <div class="mb-4"> |
| | <label class="block text-gray-700 mb-2">Custom Prompt (Optional)</label> |
| | <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> |
| | </div> |
| | |
| | <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"> |
| | <i class="fas fa-bolt mr-2"></i> Generate Questions |
| | </button> |
| | </div> |
| | |
| | <div> |
| | <h2 class="text-xl font-semibold mb-4 text-gray-800">RAG & User Feedback</h2> |
| | |
| | <div class="mb-4"> |
| | <label class="block text-gray-700 mb-2">Import External Data</label> |
| | <div class="flex items-center space-x-2"> |
| | <input type="file" id="externalData" class="hidden"> |
| | <button id="uploadBtn" class="px-4 py-2 bg-gray-200 text-gray-800 rounded-lg hover:bg-gray-300 flex items-center"> |
| | <i class="fas fa-file-upload mr-2"></i> Choose File |
| | </button> |
| | <span id="fileName" class="text-gray-500 text-sm">No file selected</span> |
| | </div> |
| | <p class="text-xs text-gray-500 mt-1">Supported formats: .txt, .pdf, .docx, .csv</p> |
| | </div> |
| | |
| | <div class="mb-4"> |
| | <label class="block text-gray-700 mb-2">Provide Suggestion</label> |
| | <textarea id="userSuggestion" rows="2" class="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500" placeholder="Suggest improvements for generated questions..."></textarea> |
| | <button id="submitSuggestion" class="mt-2 px-4 py-2 bg-emerald-600 text-white rounded-lg hover:bg-emerald-700"> |
| | <i class="fas fa-lightbulb mr-2"></i> Submit Suggestion |
| | </button> |
| | </div> |
| | |
| | <div id="apiStatus" class="p-3 rounded-lg bg-blue-50 border border-blue-200 flex items-center"> |
| | <div class="w-3 h-3 rounded-full bg-blue-500 mr-2 animate-pulse"></div> |
| | <span class="text-sm text-blue-700">Connected to DeepSeek API</span> |
| | <i class="fas fa-check-circle ml-auto text-green-500"></i> |
| | </div> |
| | |
| | <div class="bg-blue-50 p-4 rounded-lg mt-4"> |
| | <h3 class="font-semibold text-blue-800 mb-2 flex items-center"> |
| | <i class="fas fa-info-circle mr-2"></i> Generation Process |
| | </h3> |
| | <p class="text-sm text-blue-700"> |
| | Questions are generated using DeepSeek's AI model through integrated API. For large batches, multiple API calls will be made automatically. Each question is categorized and checked for quality. |
| | </p> |
| | </div> |
| | </div> |
| | </div> |
| | </div> |
| |
|
| | <div class="bg-white rounded-xl shadow-lg p-6"> |
| | <div class="flex justify-between items-center mb-6"> |
| | <h2 class="text-xl font-semibold text-gray-800">Generated Questions</h2> |
| | <div class="flex space-x-2"> |
| | <button id="exportBtn" class="px-4 py-2 bg-green-600 text-white rounded-lg hover:bg-green-700 flex items-center"> |
| | <i class="fas fa-file-export mr-2"></i> Export |
| | </button> |
| | <button id="clearBtn" class="px-4 py-2 bg-gray-200 text-gray-800 rounded-lg hover:bg-gray-300 flex items-center"> |
| | <i class="fas fa-trash-alt mr-2"></i> Clear |
| | </button> |
| | </div> |
| | </div> |
| | |
| | <div class="border-b border-gray-200 mb-4"> |
| | <div class="flex space-x-6 overflow-x-auto pb-2"> |
| | <button data-tab="all" class="tab-btn whitespace-nowrap pb-2 px-1 text-gray-600 hover:text-blue-600">All</button> |
| | <button data-tab="deposit" class="tab-btn whitespace-nowrap pb-2 px-1 text-gray-600 hover:text-blue-600">Deposit</button> |
| | <button data-tab="transfer" class="tab-btn whitespace-nowrap pb-2 px-1 text-gray-600 hover:text-blue-600">Transfer</button> |
| | <button data-tab="withdrawal" class="tab-btn whitespace-nowrap pb-2 px-1 text-gray-600 hover:text-blue-600">Withdrawal</button> |
| | <button data-tab="security" class="tab-btn whitespace-nowrap pb-2 px-1 text-gray-600 hover:text-blue-600">Security</button> |
| | <button data-tab="payment" class="tab-btn whitespace-nowrap pb-2 px-1 text-gray-600 hover:text-blue-600">Payment</button> |
| | <button data-tab="card" class="tab-btn whitespace-nowrap pb-2 px-1 text-gray-600 hover:text-blue-600">Card</button> |
| | <button data-tab="billing" class="tab-btn whitespace-nowrap pb-2 px-1 text-gray-600 hover:text-blue-600">Billing</button> |
| | <button data-tab="basic" class="tab-btn whitespace-nowrap pb-2 px-1 text-gray-600 hover:text-blue-600">Basic</button> |
| | <button data-tab="other" class="tab-btn whitespace-nowrap pb-2 px-1 text-gray-600 hover:text-blue-600">Other</button> |
| | </div> |
| | </div> |
| | |
| | <div id="loadingIndicator" class="text-center py-8 hidden"> |
| | <div class="inline-block loading-spinner text-blue-500 text-4xl mb-2"> |
| | <i class="fas fa-circle-notch"></i> |
| | </div> |
| | <p class="text-gray-600">Generating questions using DeepSeek API...</p> |
| | <p id="progressText" class="text-sm text-gray-500 mt-1">Processing 0/0</p> |
| | </div> |
| | |
| | <div id="questionsContainer" class="space-y-4"> |
| | <div class="text-center py-12 text-gray-500"> |
| | <i class="fas fa-comment-dots text-4xl mb-3"></i> |
| | <p>No questions generated yet. Configure your settings and click "Generate Questions".</p> |
| | </div> |
| | </div> |
| | |
| | <div id="pagination" class="mt-6 flex justify-between items-center hidden"> |
| | <button id="prevPage" class="px-4 py-2 bg-gray-200 text-gray-800 rounded-lg hover:bg-gray-300 disabled:opacity-50"> |
| | <i class="fas fa-chevron-left mr-2"></i> Previous |
| | </button> |
| | <span id="pageInfo" class="text-gray-600">Page 1 of 1</span> |
| | <button id="nextPage" class="px-4 py-2 bg-gray-200 text-gray-800 rounded-lg hover:bg-gray-300 disabled:opacity-50"> |
| | Next <i class="fas fa-chevron-right ml-2"></i> |
| | </button> |
| | </div> |
| | </div> |
| | </div> |
| |
|
| | |
| | <div id="exportModal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center hidden z-50"> |
| | <div class="bg-white rounded-xl p-6 w-full max-w-md"> |
| | <div class="flex justify-between items-center mb-4"> |
| | <h3 class="text-lg font-semibold">Export Questions</h3> |
| | <button id="closeExportModal" class="text-gray-500 hover:text-gray-700"> |
| | <i class="fas fa-times"></i> |
| | </button> |
| | </div> |
| | |
| | <div class="mb-4"> |
| | <label class="block text-gray-700 mb-2">Format</label> |
| | <div class="flex space-x-2"> |
| | <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> |
| | <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> |
| | <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> |
| | </div> |
| | </div> |
| | |
| | <div class="mb-4"> |
| | <label class="block text-gray-700 mb-2">Filter</label> |
| | <select id="exportFilter" class="w-full px-4 py-2 border rounded-lg"> |
| | <option value="all">All Questions</option> |
| | <option value="current">Current View</option> |
| | <option value="selected">Selected Questions</option> |
| | </select> |
| | </div> |
| | |
| | <button id="confirmExport" class="w-full bg-blue-600 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded-lg"> |
| | <i class="fas fa-download mr-2"></i> Export |
| | </button> |
| | </div> |
| | </div> |
| |
|
| | |
| | <div id="suggestionModal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center hidden z-50"> |
| | <div class="bg-white rounded-xl p-6 w-full max-w-md"> |
| | <div class="flex justify-between items-center mb-4"> |
| | <h3 class="text-lg font-semibold">Feedback Submitted</h3> |
| | <button id="closeSuggestionModal" class="text-gray-500 hover:text-gray-700"> |
| | <i class="fas fa-times"></i> |
| | </button> |
| | </div> |
| | <div class="flex items-center"> |
| | <div class="w-12 h-12 bg-green-100 rounded-full flex items-center justify-center mr-4"> |
| | <i class="fas fa-check text-green-500 text-xl"></i> |
| | </div> |
| | <div> |
| | <p class="text-gray-700">Thank you for your suggestion!</p> |
| | <p class="text-sm text-gray-500 mt-1">Your feedback will help improve future question generations.</p> |
| | </div> |
| | </div> |
| | <button id="okSuggestionBtn" class="w-full mt-6 bg-blue-600 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded-lg"> |
| | OK |
| | </button> |
| | </div> |
| | </div> |
| |
|
| | <script> |
| | |
| | const generateBtn = document.getElementById('generateBtn'); |
| | const exportBtn = document.getElementById('exportBtn'); |
| | const clearBtn = document.getElementById('clearBtn'); |
| | const questionCount = document.getElementById('questionCount'); |
| | const customPrompt = document.getElementById('customPrompt'); |
| | const questionsContainer = document.getElementById('questionsContainer'); |
| | const loadingIndicator = document.getElementById('loadingIndicator'); |
| | const progressText = document.getElementById('progressText'); |
| | const difficultyBtns = document.querySelectorAll('.difficulty-btn'); |
| | const categoryChips = document.querySelectorAll('.category-chip'); |
| | const tabBtns = document.querySelectorAll('.tab-btn'); |
| | const exportModal = document.getElementById('exportModal'); |
| | const closeExportModal = document.getElementById('closeExportModal'); |
| | const exportFormatBtns = document.querySelectorAll('.export-format-btn'); |
| | const confirmExport = document.getElementById('confirmExport'); |
| | const exportFilter = document.getElementById('exportFilter'); |
| | const prevPage = document.getElementById('prevPage'); |
| | const nextPage = document.getElementById('nextPage'); |
| | const pageInfo = document.getElementById('pageInfo'); |
| | const pagination = document.getElementById('pagination'); |
| | const uploadBtn = document.getElementById('uploadBtn'); |
| | const externalData = document.getElementById('externalData'); |
| | const fileName = document.getElementById('fileName'); |
| | const userSuggestion = document.getElementById('userSuggestion'); |
| | const submitSuggestion = document.getElementById('submitSuggestion'); |
| | const suggestionModal = document.getElementById('suggestionModal'); |
| | const closeSuggestionModal = document.getElementById('closeSuggestionModal'); |
| | const okSuggestionBtn = document.getElementById('okSuggestionBtn'); |
| | const apiStatus = document.getElementById('apiStatus'); |
| | |
| | |
| | let selectedCategories = new Set(['deposit', 'transfer', 'withdrawal', 'security', 'payment', 'card', 'billing', 'basic', 'other']); |
| | let selectedDifficulty = 'random'; |
| | let currentTab = 'all'; |
| | let currentPage = 1; |
| | const questionsPerPage = 10; |
| | let allQuestions = []; |
| | let displayedQuestions = []; |
| | let selectedExportFormat = 'csv'; |
| | let externalDataContent = ''; |
| | |
| | |
| | document.addEventListener('DOMContentLoaded', () => { |
| | |
| | document.querySelector('[data-tab="all"]').classList.add('tab-active'); |
| | |
| | |
| | document.querySelector('[data-difficulty="random"]').classList.add('bg-blue-200'); |
| | |
| | |
| | document.querySelector('[data-format="csv"]').classList.add('bg-blue-200', 'text-blue-800'); |
| | }); |
| | |
| | |
| | generateBtn.addEventListener('click', generateQuestions); |
| | exportBtn.addEventListener('click', () => exportModal.classList.remove('hidden')); |
| | clearBtn.addEventListener('click', clearQuestions); |
| | closeExportModal.addEventListener('click', () => exportModal.classList.add('hidden')); |
| | uploadBtn.addEventListener('click', () => externalData.click()); |
| | externalData.addEventListener('change', handleFileUpload); |
| | prevPage.addEventListener('click', () => navigatePage(-1)); |
| | nextPage.addEventListener('click', () => navigatePage(1)); |
| | submitSuggestion.addEventListener('click', submitUserSuggestion); |
| | closeSuggestionModal.addEventListener('click', () => suggestionModal.classList.add('hidden')); |
| | okSuggestionBtn.addEventListener('click', () => suggestionModal.classList.add('hidden')); |
| | |
| | |
| | difficultyBtns.forEach(btn => { |
| | btn.addEventListener('click', () => { |
| | difficultyBtns.forEach(b => { |
| | b.classList.remove('bg-blue-200'); |
| | b.classList.remove('ring-2', 'ring-blue-500'); |
| | }); |
| | btn.classList.add('bg-blue-200'); |
| | selectedDifficulty = btn.dataset.difficulty; |
| | }); |
| | }); |
| | |
| | |
| | categoryChips.forEach(chip => { |
| | chip.addEventListener('click', () => { |
| | const category = chip.dataset.category; |
| | if (selectedCategories.has(category)) { |
| | selectedCategories.delete(category); |
| | chip.classList.remove('bg-blue-200'); |
| | } else { |
| | selectedCategories.add(category); |
| | chip.classList.add('bg-blue-200'); |
| | } |
| | |
| | |
| | if (selectedCategories.size === 0) { |
| | chip.classList.add('shake'); |
| | setTimeout(() => chip.classList.remove('shake'), 500); |
| | document.querySelectorAll('.category-chip').forEach(c => { |
| | c.classList.add('ring-2', 'ring-red-500'); |
| | }); |
| | } else { |
| | document.querySelectorAll('.category-chip').forEach(c => { |
| | c.classList.remove('ring-2', 'ring-red-500'); |
| | }); |
| | } |
| | }); |
| | }); |
| | |
| | |
| | tabBtns.forEach(btn => { |
| | btn.addEventListener('click', () => { |
| | tabBtns.forEach(b => b.classList.remove('tab-active')); |
| | btn.classList.add('tab-active'); |
| | currentTab = btn.dataset.tab; |
| | filterQuestions(); |
| | }); |
| | }); |
| | |
| | |
| | exportFormatBtns.forEach(btn => { |
| | btn.addEventListener('click', () => { |
| | exportFormatBtns.forEach(b => b.classList.remove('bg-blue-200', 'text-blue-800')); |
| | btn.classList.add('bg-blue-200', 'text-blue-800'); |
| | selectedExportFormat = btn.dataset.format; |
| | }); |
| | }); |
| | |
| | confirmExport.addEventListener('click', exportQuestions); |
| | |
| | |
| | async function generateQuestions() { |
| | if (selectedCategories.size === 0) { |
| | alert('Please select at least one category.'); |
| | return; |
| | } |
| | |
| | const count = parseInt(questionCount.value); |
| | if (isNaN(count) || count < 1 || count > 100) { |
| | alert('Please enter a valid number between 1 and 100.'); |
| | return; |
| | } |
| | |
| | |
| | loadingIndicator.classList.remove('hidden'); |
| | questionsContainer.innerHTML = ''; |
| | |
| | try { |
| | const batchSize = 5; |
| | const batches = Math.ceil(count / batchSize); |
| | allQuestions = []; |
| | |
| | for (let i = 0; i < batches; i++) { |
| | const currentBatchSize = i === batches - 1 ? count - (i * batchSize) : batchSize; |
| | progressText.textContent = `Processing ${i * batchSize}/${count}`; |
| | |
| | |
| | const categoriesList = Array.from(selectedCategories).join(', '); |
| | const prompt = `Generate ${currentBatchSize} ${selectedDifficulty} English questions about ${categoriesList} in financial/wallet services. ` + |
| | `Ensure questions are varied and avoid redundancy. ${customPrompt.value}`; |
| | |
| | |
| | const batchQuestions = await callDeepSeekApi(prompt, currentBatchSize); |
| | allQuestions = [...allQuestions, ...batchQuestions]; |
| | } |
| | |
| | |
| | filterQuestions(); |
| | loadingIndicator.classList.add('hidden'); |
| | |
| | } catch (error) { |
| | console.error('Error generating questions:', error); |
| | loadingIndicator.classList.add('hidden'); |
| | questionsContainer.innerHTML = ` |
| | <div class="text-center py-12 text-red-500"> |
| | <i class="fas fa-exclamation-triangle text-4xl mb-3"></i> |
| | <p>Error generating questions. Please try again.</p> |
| | </div> |
| | `; |
| | } |
| | } |
| | |
| | |
| | async function callDeepSeekApi(prompt, count) { |
| | |
| | |
| | |
| | |
| | const delay = 500 + Math.random() * 1000; |
| | await new Promise(resolve => setTimeout(resolve, delay)); |
| | |
| | |
| | const categories = Array.from(selectedCategories); |
| | const batchQuestions = []; |
| | |
| | for (let i = 0; i < count; i++) { |
| | const category = categories[Math.floor(Math.random() * categories.length)]; |
| | const difficulty = selectedDifficulty === 'random' |
| | ? ['simple', 'medium', 'complex'][Math.floor(Math.random() * 3)] |
| | : selectedDifficulty; |
| | |
| | const question = generateRealisticQuestion(category, difficulty); |
| | |
| | batchQuestions.push({ |
| | id: Date.now() + i, |
| | text: question, |
| | category: category, |
| | difficulty: difficulty, |
| | generatedAt: new Date().toISOString() |
| | }); |
| | } |
| | |
| | return batchQuestions; |
| | } |
| | |
| | function generateRealisticQuestion(category, difficulty) { |
| | |
| | const questions = { |
| | deposit: { |
| | simple: [ |
| | "How do I deposit money into my digital wallet?", |
| | "What payment methods can I use for deposits?", |
| | "Is there a minimum amount for deposits?" |
| | ], |
| | medium: [ |
| | "Why is my deposit taking longer than usual to process?", |
| | "Can I deposit funds from an international bank account?", |
| | "What are the deposit limits for unverified accounts?" |
| | ], |
| | complex: [ |
| | "How does the deposit reconciliation process work during weekends?", |
| | "What security protocols are in place for large deposit transactions?", |
| | "Can you explain the multi-signature verification process for deposits?" |
| | ] |
| | }, |
| | transfer: { |
| | simple: [ |
| | "How do I send money to another user?", |
| | "What's the maximum amount I can transfer in one transaction?", |
| | "How long do transfers usually take?" |
| | ], |
| | medium: [ |
| | "Why was my transfer returned by the recipient's bank?", |
| | "Can I schedule recurring transfers to family members?", |
| | "How do foreign currency transfers work?" |
| | ], |
| | complex: [ |
| | "What are the tax implications for international transfers over $10,000?", |
| | "How does the blockchain verification process work for crypto transfers?", |
| | "Can you explain the interbank settlement procedures for instant transfers?" |
| | ] |
| | }, |
| | withdrawal: { |
| | simple: [ |
| | "How do I withdraw money to my bank account?", |
| | "Are there any fees for withdrawals?", |
| | "How long does a withdrawal take to process?" |
| | ], |
| | medium: [ |
| | "Why does my withdrawal request keep getting declined?", |
| | "Can I withdraw to a different bank than my deposit source?", |
| | "What are the tax reporting requirements for large withdrawals?" |
| | ], |
| | complex: [ |
| | "How are AML checks performed on high-value withdrawal requests?", |
| | "What are the reserve requirements that affect withdrawal processing times?", |
| | "Can you explain the cross-border clearance process for international withdrawals?" |
| | ] |
| | }, |
| | security: { |
| | simple: [ |
| | "How do I create a strong password for my account?", |
| | "What should I do if I lose my phone with my wallet app?", |
| | "How does two-factor authentication work?" |
| | ], |
| | medium: [ |
| | "Why did I receive a security alert for a login attempt?", |
| | "Can I restrict transactions from certain locations?", |
| | "How are my biometric data stored and protected?" |
| | ], |
| | complex: [ |
| | "What cryptographic techniques are used to secure financial transactions?", |
| | "How does the zero-knowledge proof verification process work?", |
| | "Can you explain the multi-party computation protocol used for key management?" |
| | ] |
| | }, |
| | payment: { |
| | simple: [ |
| | "How do I pay a merchant using my digital wallet?", |
| | "Can I split a payment with friends?", |
| | "What's contactless payment and how does it work?" |
| | ], |
| | medium: [ |
| | "Why was my payment to a merchant declined?", |
| | "Can I dispute a payment after it's completed?", |
| | "How do recurring subscription payments work?" |
| | ], |
| | complex: [ |
| | "What are the PCI-DSS compliance requirements for tokenized payments?", |
| | "How does the merchant acquiring bank authorization process work?", |
| | "Can you explain the chargeback arbitration process?" |
| | ] |
| | }, |
| | card: { |
| | simple: [ |
| | "How do I add a debit card to my wallet?", |
| | "Can I remove a saved card from my account?", |
| | "What should I do if my card is lost or stolen?" |
| | ], |
| | medium: [ |
| | "Why is my card verification failing during checkout?", |
| | "Can I set spending limits for specific cards?", |
| | "How do virtual card numbers work?" |
| | ], |
| | complex: [ |
| | "How are card details tokenized during online transactions?", |
| | "What are the EMV 3D Secure 2.0 authentication protocols?", |
| | "Can you explain the card network settlement reconciliation process?" |
| | ] |
| | }, |
| | billing: { |
| | simple: [ |
| | "How do I view my transaction history?", |
| | "Can I download my monthly statements?", |
| | "Where can I see my current balance?" |
| | ], |
| | medium: [ |
| | "Why is there a discrepancy in my transaction records?", |
| | "Can I generate customized reports for tax purposes?", |
| | "How do I categorize transactions for budgeting?" |
| | ], |
| | complex: [ |
| | "What accounting standards are followed for transaction record-keeping?", |
| | "How does the GL reconciliation process work across multiple currencies?", |
| | "Can you explain the audit trail generation process?" |
| | ] |
| | }, |
| | basic: { |
| | simple: [ |
| | "How do I create an account?", |
| | "What's the customer support phone number?", |
| | "Where can I find the app settings?" |
| | ], |
| | medium: [ |
| | "Why can't I receive the verification SMS?", |
| | "Can I merge two accounts under one email?", |
| | "How do I update my personal information?" |
| | ], |
| | complex: [ |
| | "What identity verification protocols are used during KYC onboarding?", |
| | "How does the real-time account monitoring system work?", |
| | "Can you explain the multi-jurisdictional compliance process?" |
| | ] |
| | }, |
| | other: { |
| | simple: [ |
| | "What currencies does your service support?", |
| | "Can I use this service while traveling abroad?", |
| | "Where can I find your terms of service?" |
| | ], |
| | medium: [ |
| | "Why can't I access certain features in my country?", |
| | "Can I give limited access to an accountant?", |
| | "How does interest accrual work on stored balances?" |
| | ], |
| | complex: [ |
| | "What regulatory bodies oversee the financial services provided?", |
| | "How are exchange rates calculated for multi-currency transactions?", |
| | "Can you explain the liquidity provisions for fast settlements?" |
| | ] |
| | } |
| | }; |
| | |
| | |
| | let possibleQuestions = questions[category][difficulty]; |
| | |
| | |
| | if (selectedDifficulty === 'random') { |
| | possibleQuestions = [ |
| | ...questions[category].simple, |
| | ...questions[category].medium, |
| | ...questions[category].complex |
| | ]; |
| | } |
| | |
| | |
| | return possibleQuestions[Math.floor(Math.random() * possibleQuestions.length)]; |
| | } |
| | |
| | function filterQuestions() { |
| | displayedQuestions = currentTab === 'all' |
| | ? allQuestions |
| | : allQuestions.filter(q => q.category === currentTab); |
| | |
| | currentPage = 1; |
| | renderQuestions(); |
| | updatePagination(); |
| | } |
| | |
| | function renderQuestions() { |
| | if (displayedQuestions.length === 0) { |
| | questionsContainer.innerHTML = ` |
| | <div class="text-center py-12 text-gray-500"> |
| | <i class="fas fa-comment-dots text-4xl mb-3"></i> |
| | <p>No questions match the current filter.</p> |
| | </div> |
| | `; |
| | pagination.classList.add('hidden'); |
| | return; |
| | } |
| | |
| | const startIdx = (currentPage - 1) * questionsPerPage; |
| | const endIdx = startIdx + questionsPerPage; |
| | const questionsToShow = displayedQuestions.slice(startIdx, endIdx); |
| | |
| | questionsContainer.innerHTML = ''; |
| | |
| | questionsToShow.forEach(question => { |
| | const categoryColors = { |
| | deposit: 'bg-blue-100 text-blue-800', |
| | transfer: 'bg-purple-100 text-purple-800', |
| | withdrawal: 'bg-indigo-100 text-indigo-800', |
| | security: 'bg-red-100 text-red-800', |
| | payment: 'bg-green-100 text-green-800', |
| | card: 'bg-yellow-100 text-yellow-800', |
| | billing: 'bg-pink-100 text-pink-800', |
| | basic: 'bg-gray-100 text-gray-800', |
| | other: 'bg-teal-100 text-teal-800' |
| | }; |
| | |
| | const difficultyColors = { |
| | simple: 'text-green-600', |
| | medium: 'text-yellow-600', |
| | complex: 'text-red-600' |
| | }; |
| | |
| | const questionEl = document.createElement('div'); |
| | questionEl.className = 'question-card bg-white p-4 rounded-lg border border-gray-200 shadow-sm'; |
| | questionEl.innerHTML = ` |
| | <div class="flex justify-between items-start mb-2"> |
| | <p class="font-medium text-gray-800">${question.text}</p> |
| | <div class="flex space-x-2"> |
| | <span class="text-xs px-2 py-1 rounded-full ${categoryColors[question.category]}">${question.category}</span> |
| | <span class="text-xs px-2 py-1 rounded-full bg-gray-100 text-gray-800 ${difficultyColors[question.difficulty]}">${question.difficulty}</span> |
| | </div> |
| | </div> |
| | <div class="flex justify-between items-center text-xs text-gray-500"> |
| | <span>Generated: ${new Date(question.generatedAt).toLocaleString()}</span> |
| | <div class="flex space-x-2"> |
| | <button data-id="${question.id}" class="edit-btn text-blue-500 hover:text-blue-700"><i class="fas fa-edit"></i></button> |
| | <button data-id="${question.id}" class="delete-btn text-red-500 hover:text-red-700"><i class="fas fa-trash-alt"></i></button> |
| | </div> |
| | </div> |
| | `; |
| | |
| | questionsContainer.appendChild(questionEl); |
| | }); |
| | |
| | |
| | document.querySelectorAll('.edit-btn').forEach(btn => { |
| | btn.addEventListener('click', (e) => editQuestion(e.target.closest('button').dataset.id)); |
| | }); |
| | |
| | document.querySelectorAll('.delete-btn').forEach(btn => { |
| | btn.addEventListener('click', (e) => deleteQuestion(e.target.closest('button').dataset.id)); |
| | }); |
| | |
| | pagination.classList.remove('hidden'); |
| | } |
| | |
| | function editQuestion(id) { |
| | const question = allQuestions.find(q => q.id.toString() === id); |
| | if (!question) return; |
| | |
| | const newText = prompt("Edit question:", question.text); |
| | if (newText && newText.trim() !== '') { |
| | question.text = newText.trim(); |
| | renderQuestions(); |
| | } |
| | } |
| | |
| | function deleteQuestion(id) { |
| | if (confirm("Are you sure you want to delete this question?")) { |
| | allQuestions = allQuestions.filter(q => q.id.toString() !== id); |
| | filterQuestions(); |
| | } |
| | } |
| | |
| | function updatePagination() { |
| | const totalPages = Math.ceil(displayedQuestions.length / questionsPerPage); |
| | pageInfo.textContent = `Page ${currentPage} of ${totalPages}`; |
| | |
| | prevPage.disabled = currentPage === 1; |
| | nextPage.disabled = currentPage === totalPages; |
| | } |
| | |
| | function navigatePage(direction) { |
| | const totalPages = Math.ceil(displayedQuestions.length / questionsPerPage); |
| | const newPage = currentPage + direction; |
| | |
| | if (newPage > 0 && newPage <= totalPages) { |
| | currentPage = newPage; |
| | renderQuestions(); |
| | updatePagination(); |
| | } |
| | } |
| | |
| | function clearQuestions() { |
| | if (allQuestions.length === 0 || confirm('Are you sure you want to clear all generated questions?')) { |
| | allQuestions = []; |
| | displayedQuestions = []; |
| | questionsContainer.innerHTML = ` |
| | <div class="text-center py-12 text-gray-500"> |
| | <i class="fas fa-comment-dots text-4xl mb-3"></i> |
| | <p>No questions generated yet. Configure your settings and click "Generate Questions".</p> |
| | </div> |
| | `; |
| | pagination.classList.add('hidden'); |
| | } |
| | } |
| | |
| | function exportQuestions() { |
| | let questionsToExport = []; |
| | |
| | switch (exportFilter.value) { |
| | case 'all': |
| | questionsToExport = allQuestions; |
| | break; |
| | case 'current': |
| | const startIdx = (currentPage - 1) * questionsPerPage; |
| | const endIdx = startIdx + questionsPerPage; |
| | questionsToExport = displayedQuestions.slice(startIdx, endIdx); |
| | break; |
| | case 'selected': |
| | |
| | alert('No questions selected. Exporting all questions instead.'); |
| | questionsToExport = allQuestions; |
| | break; |
| | } |
| | |
| | if (questionsToExport.length === 0) { |
| | alert('No questions to export.'); |
| | return; |
| | } |
| | |
| | let content = ''; |
| | let mimeType = 'text/plain'; |
| | let extension = 'txt'; |
| | |
| | switch (selectedExportFormat) { |
| | case 'csv': |
| | content = 'ID,Question,Category,Difficulty,Generated At\n'; |
| | questionsToExport.forEach(q => { |
| | content += `"${q.id}","${q.text}","${q.category}","${q.difficulty}","${q.generatedAt}"\n`; |
| | }); |
| | mimeType = 'text/csv'; |
| | extension = 'csv'; |
| | break; |
| | |
| | case 'json': |
| | content = JSON.stringify(questionsToExport, null, 2); |
| | mimeType = 'application/json'; |
| | extension = 'json'; |
| | break; |
| | |
| | case 'txt': |
| | questionsToExport.forEach(q => { |
| | content += `Question: ${q.text}\n`; |
| | content += `Category: ${q.category}\n`; |
| | content += `Difficulty: ${q.difficulty}\n`; |
| | content += `Generated At: ${q.generatedAt}\n\n`; |
| | }); |
| | break; |
| | } |
| | |
| | const blob = new Blob([content], { type: mimeType }); |
| | const url = URL.createObjectURL(blob); |
| | const a = document.createElement('a'); |
| | a.href = url; |
| | a.download = `financial_questions_${new Date().toISOString().slice(0, 10)}.${extension}`; |
| | document.body.appendChild(a); |
| | a.click(); |
| | document.body.removeChild(a); |
| | URL.revokeObjectURL(url); |
| | |
| | exportModal.classList.add('hidden'); |
| | } |
| | |
| | function handleFileUpload(event) { |
| | const file = event.target.files[0]; |
| | if (!file) return; |
| | |
| | fileName.textContent = file.name; |
| | |
| | |
| | |
| | externalDataContent = file.name; |
| | |
| | |
| | setTimeout(() => { |
| | alert(`File "${file.name}" has been processed and is ready to be used for RAG.`); |
| | }, 1000); |
| | } |
| | |
| | function submitUserSuggestion() { |
| | const suggestion = userSuggestion.value.trim(); |
| | if (!suggestion) { |
| | userSuggestion.classList.add('ring-2', 'ring-red-500'); |
| | setTimeout(() => userSuggestion.classList.remove('ring-2', 'ring-red-500'), 1000); |
| | return; |
| | } |
| | |
| | |
| | console.log("User suggestion submitted:", suggestion); |
| | |
| | |
| | suggestionModal.classList.remove('hidden'); |
| | userSuggestion.value = ''; |
| | |
| | |
| | |
| | } |
| | </script> |
| | <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> |
| | </html> |