Spaces:
Running
Running
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>SQL Query Agent</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> | |
| .chat-container { | |
| height: calc(100vh - 200px); | |
| } | |
| .file-dropzone { | |
| border: 2px dashed #cbd5e0; | |
| transition: all 0.3s ease; | |
| } | |
| .file-dropzone.active { | |
| border-color: #4f46e5; | |
| background-color: #eef2ff; | |
| } | |
| .result-table { | |
| max-height: 300px; | |
| overflow-y: auto; | |
| } | |
| .typing-indicator span { | |
| animation: bounce 1.5s infinite ease-in-out; | |
| } | |
| .typing-indicator span:nth-child(2) { | |
| animation-delay: 0.2s; | |
| } | |
| .typing-indicator span:nth-child(3) { | |
| animation-delay: 0.4s; | |
| } | |
| @keyframes bounce { | |
| 0%, 100% { transform: translateY(0); } | |
| 50% { transform: translateY(-5px); } | |
| } | |
| .sql-editor { | |
| font-family: 'Courier New', monospace; | |
| min-height: 100px; | |
| } | |
| </style> | |
| </head> | |
| <body class="bg-gray-50"> | |
| <div class="container mx-auto px-4 py-8 max-w-6xl"> | |
| <!-- Header --> | |
| <header class="mb-8"> | |
| <div class="flex items-center justify-between"> | |
| <div class="flex items-center space-x-3"> | |
| <i class="fas fa-database text-3xl text-indigo-600"></i> | |
| <h1 class="text-2xl font-bold text-gray-800">SQL Query Agent</h1> | |
| </div> | |
| <div class="flex space-x-4"> | |
| <button id="darkModeToggle" class="p-2 rounded-full hover:bg-gray-200 dark:hover:bg-gray-700"> | |
| <i class="fas fa-moon text-gray-600"></i> | |
| </button> | |
| <button class="px-4 py-2 bg-indigo-600 text-white rounded-lg hover:bg-indigo-700 transition"> | |
| <i class="fas fa-question-circle mr-2"></i>Help | |
| </button> | |
| </div> | |
| </div> | |
| <p class="text-gray-600 mt-2">Upload your Excel file or connect to a database to start querying</p> | |
| </header> | |
| <!-- Main Content --> | |
| <div class="grid grid-cols-1 lg:grid-cols-3 gap-6"> | |
| <!-- Left Panel - Data Source Selection --> | |
| <div class="lg:col-span-1 bg-white rounded-xl shadow-md p-6"> | |
| <h2 class="text-xl font-semibold mb-4 text-gray-800">Data Sources</h2> | |
| <!-- Tabs --> | |
| <div class="flex border-b mb-6"> | |
| <button id="excelTab" class="tab-btn active px-4 py-2 font-medium text-indigo-600 border-b-2 border-indigo-600"> | |
| <i class="fas fa-file-excel mr-2"></i>Excel File | |
| </button> | |
| <button id="sqlTab" class="tab-btn px-4 py-2 font-medium text-gray-500 hover:text-gray-700"> | |
| <i class="fas fa-database mr-2"></i>SQL Database | |
| </button> | |
| </div> | |
| <!-- Excel Upload Section --> | |
| <div id="excelSection" class="data-source-section"> | |
| <div id="fileDropzone" class="file-dropzone rounded-lg p-8 text-center mb-4 cursor-pointer"> | |
| <i class="fas fa-cloud-upload-alt text-4xl text-gray-400 mb-3"></i> | |
| <p class="text-gray-600">Drag & drop your Excel file here</p> | |
| <p class="text-sm text-gray-500 mt-1">or click to browse files</p> | |
| <input type="file" id="fileInput" class="hidden" accept=".xlsx, .xls, .csv"> | |
| </div> | |
| <div id="fileInfo" class="hidden p-4 bg-gray-50 rounded-lg mb-4"> | |
| <div class="flex justify-between items-center"> | |
| <div> | |
| <p class="font-medium text-gray-800" id="fileName">sample_data.xlsx</p> | |
| <p class="text-sm text-gray-500" id="fileSize">2.4 MB</p> | |
| </div> | |
| <button id="removeFile" class="text-red-500 hover:text-red-700"> | |
| <i class="fas fa-times"></i> | |
| </button> | |
| </div> | |
| </div> | |
| <div class="mb-4"> | |
| <label class="block text-sm font-medium text-gray-700 mb-1">Sheet Selection</label> | |
| <select id="sheetSelect" class="w-full p-2 border border-gray-300 rounded-lg" disabled> | |
| <option value="">Select a sheet</option> | |
| </select> | |
| </div> | |
| <div class="mb-4"> | |
| <label class="block text-sm font-medium text-gray-700 mb-1">Preview</label> | |
| <div class="bg-gray-50 p-2 rounded-lg border border-gray-200 overflow-x-auto"> | |
| <table class="min-w-full divide-y divide-gray-200"> | |
| <thead id="previewHeader" class="bg-gray-100"> | |
| <!-- Headers will be populated here --> | |
| </thead> | |
| <tbody id="previewBody" class="divide-y divide-gray-200"> | |
| <!-- Preview rows will be populated here --> | |
| </tbody> | |
| </table> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- SQL Connection Section --> | |
| <div id="sqlSection" class="data-source-section hidden"> | |
| <div class="space-y-4"> | |
| <div> | |
| <label class="block text-sm font-medium text-gray-700 mb-1">Database Type</label> | |
| <select class="w-full p-2 border border-gray-300 rounded-lg"> | |
| <option>MySQL</option> | |
| <option>PostgreSQL</option> | |
| <option>SQL Server</option> | |
| <option>SQLite</option> | |
| <option>Oracle</option> | |
| </select> | |
| </div> | |
| <div> | |
| <label class="block text-sm font-medium text-gray-700 mb-1">Host</label> | |
| <input type="text" class="w-full p-2 border border-gray-300 rounded-lg" placeholder="localhost"> | |
| </div> | |
| <div> | |
| <label class="block text-sm font-medium text-gray-700 mb-1">Port</label> | |
| <input type="text" class="w-full p-2 border border-gray-300 rounded-lg" placeholder="3306"> | |
| </div> | |
| <div> | |
| <label class="block text-sm font-medium text-gray-700 mb-1">Database Name</label> | |
| <input type="text" class="w-full p-2 border border-gray-300 rounded-lg" placeholder="my_database"> | |
| </div> | |
| <div> | |
| <label class="block text-sm font-medium text-gray-700 mb-1">Username</label> | |
| <input type="text" class="w-full p-2 border border-gray-300 rounded-lg" placeholder="username"> | |
| </div> | |
| <div> | |
| <label class="block text-sm font-medium text-gray-700 mb-1">Password</label> | |
| <input type="password" class="w-full p-2 border border-gray-300 rounded-lg" placeholder="••••••••"> | |
| </div> | |
| <button class="w-full py-2 bg-indigo-600 text-white rounded-lg hover:bg-indigo-700 transition"> | |
| <i class="fas fa-plug mr-2"></i>Connect | |
| </button> | |
| </div> | |
| </div> | |
| <div class="mt-6 pt-4 border-t border-gray-200"> | |
| <h3 class="text-sm font-medium text-gray-700 mb-2">Recent Connections</h3> | |
| <div class="space-y-2"> | |
| <div class="flex items-center p-2 hover:bg-gray-50 rounded-lg cursor-pointer"> | |
| <i class="fas fa-file-excel text-green-500 mr-3"></i> | |
| <div> | |
| <p class="text-sm font-medium">sales_data.xlsx</p> | |
| <p class="text-xs text-gray-500">Yesterday</p> | |
| </div> | |
| </div> | |
| <div class="flex items-center p-2 hover:bg-gray-50 rounded-lg cursor-pointer"> | |
| <i class="fas fa-database text-blue-500 mr-3"></i> | |
| <div> | |
| <p class="text-sm font-medium">Production DB</p> | |
| <p class="text-xs text-gray-500">2 days ago</p> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Right Panel - Chat Interface --> | |
| <div class="lg:col-span-2 bg-white rounded-xl shadow-md overflow-hidden"> | |
| <div class="p-6 border-b border-gray-200"> | |
| <h2 class="text-xl font-semibold text-gray-800">Query Assistant</h2> | |
| <p class="text-sm text-gray-600">Ask questions about your data in natural language or write SQL queries</p> | |
| </div> | |
| <!-- Chat Container --> | |
| <div class="chat-container overflow-y-auto p-4 space-y-4"> | |
| <!-- Welcome Message --> | |
| <div class="flex justify-start"> | |
| <div class="max-w-[80%] bg-indigo-50 rounded-lg p-4"> | |
| <div class="flex items-start"> | |
| <div class="flex-shrink-0 h-8 w-8 rounded-full bg-indigo-100 flex items-center justify-center"> | |
| <i class="fas fa-robot text-indigo-600"></i> | |
| </div> | |
| <div class="ml-3"> | |
| <h3 class="text-sm font-medium text-indigo-800">SQL Assistant</h3> | |
| <div class="mt-1 text-sm text-gray-700"> | |
| <p>Hello! I can help you analyze your data. Please upload an Excel file or connect to a database to get started.</p> | |
| <p class="mt-2">You can ask questions like:</p> | |
| <ul class="list-disc pl-5 mt-1 space-y-1"> | |
| <li>"Show me the top 5 customers by sales"</li> | |
| <li>"What's the average order value?"</li> | |
| <li>"Find all orders from last month"</li> | |
| </ul> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Sample User Message --> | |
| <div class="flex justify-end"> | |
| <div class="max-w-[80%] bg-indigo-600 rounded-lg p-4 text-white"> | |
| <p>Show me the top 5 products by revenue</p> | |
| </div> | |
| </div> | |
| <!-- Sample Assistant Response --> | |
| <div class="flex justify-start"> | |
| <div class="max-w-[80%] bg-gray-50 rounded-lg p-4"> | |
| <div class="flex items-start"> | |
| <div class="flex-shrink-0 h-8 w-8 rounded-full bg-gray-100 flex items-center justify-center"> | |
| <i class="fas fa-robot text-gray-600"></i> | |
| </div> | |
| <div class="ml-3"> | |
| <h3 class="text-sm font-medium text-gray-800">SQL Assistant</h3> | |
| <div class="mt-1 text-sm text-gray-700"> | |
| <p>Here are the top 5 products by revenue:</p> | |
| <div class="result-table mt-2 border border-gray-200 rounded-lg overflow-hidden"> | |
| <table class="min-w-full divide-y divide-gray-200"> | |
| <thead class="bg-gray-100"> | |
| <tr> | |
| <th class="px-4 py-2 text-left text-xs font-medium text-gray-500 uppercase">Product</th> | |
| <th class="px-4 py-2 text-left text-xs font-medium text-gray-500 uppercase">Revenue</th> | |
| </tr> | |
| </thead> | |
| <tbody class="divide-y divide-gray-200"> | |
| <tr> | |
| <td class="px-4 py-2">Premium Widget</td> | |
| <td class="px-4 py-2">$12,450</td> | |
| </tr> | |
| <tr> | |
| <td class="px-4 py-2">Basic Widget</td> | |
| <td class="px-4 py-2">$8,720</td> | |
| </tr> | |
| <tr> | |
| <td class="px-4 py-2">Deluxe Package</td> | |
| <td class="px-4 py-2">$7,890</td> | |
| </tr> | |
| <tr> | |
| <td class="px-4 py-2">Standard Package</td> | |
| <td class="px-4 py-2">$5,430</td> | |
| </tr> | |
| <tr> | |
| <td class="px-4 py-2">Add-on Service</td> | |
| <td class="px-4 py-2">$3,210</td> | |
| </tr> | |
| </tbody> | |
| </table> | |
| </div> | |
| <div class="mt-3 text-xs text-gray-500"> | |
| <p>Generated SQL: <code class="bg-gray-200 px-1 rounded">SELECT product_name, SUM(revenue) as revenue FROM sales GROUP BY product_name ORDER BY revenue DESC LIMIT 5</code></p> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Typing Indicator (hidden by default) --> | |
| <div id="typingIndicator" class="flex justify-start hidden"> | |
| <div class="max-w-[80%] bg-gray-50 rounded-lg p-4"> | |
| <div class="flex items-center"> | |
| <div class="flex-shrink-0 h-8 w-8 rounded-full bg-gray-100 flex items-center justify-center"> | |
| <i class="fas fa-robot text-gray-600"></i> | |
| </div> | |
| <div class="ml-3 typing-indicator"> | |
| <span class="inline-block h-2 w-2 rounded-full bg-gray-400 mx-1"></span> | |
| <span class="inline-block h-2 w-2 rounded-full bg-gray-400 mx-1"></span> | |
| <span class="inline-block h-2 w-2 rounded-full bg-gray-400 mx-1"></span> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Input Area --> | |
| <div class="border-t border-gray-200 p-4 bg-gray-50"> | |
| <div class="flex items-start space-x-2"> | |
| <div class="flex-grow"> | |
| <div class="relative"> | |
| <div id="sqlEditor" class="sql-editor w-full p-3 border border-gray-300 rounded-lg bg-white focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500" contenteditable="true" placeholder="Type your question or SQL query here..."></div> | |
| <div class="absolute right-2 bottom-2 flex space-x-1"> | |
| <button class="p-1 text-gray-500 hover:text-indigo-600"> | |
| <i class="fas fa-magic"></i> | |
| </button> | |
| <button class="p-1 text-gray-500 hover:text-indigo-600"> | |
| <i class="fas fa-history"></i> | |
| </button> | |
| </div> | |
| </div> | |
| <div class="flex items-center justify-between mt-2"> | |
| <div class="flex space-x-2"> | |
| <button class="p-1 text-gray-500 hover:text-indigo-600"> | |
| <i class="fas fa-paperclip"></i> | |
| </button> | |
| <button class="p-1 text-gray-500 hover:text-indigo-600"> | |
| <i class="fas fa-code"></i> | |
| </button> | |
| </div> | |
| <div class="text-xs text-gray-500"> | |
| <span id="charCount">0</span>/1000 | |
| </div> | |
| </div> | |
| </div> | |
| <button id="sendButton" class="flex-shrink-0 h-12 w-12 rounded-full bg-indigo-600 text-white flex items-center justify-center hover:bg-indigo-700 transition"> | |
| <i class="fas fa-paper-plane"></i> | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <script> | |
| // Tab switching functionality | |
| const excelTab = document.getElementById('excelTab'); | |
| const sqlTab = document.getElementById('sqlTab'); | |
| const excelSection = document.getElementById('excelSection'); | |
| const sqlSection = document.getElementById('sqlSection'); | |
| excelTab.addEventListener('click', () => { | |
| excelTab.classList.add('active', 'text-indigo-600', 'border-indigo-600'); | |
| excelTab.classList.remove('text-gray-500'); | |
| sqlTab.classList.remove('active', 'text-indigo-600', 'border-indigo-600'); | |
| sqlTab.classList.add('text-gray-500'); | |
| excelSection.classList.remove('hidden'); | |
| sqlSection.classList.add('hidden'); | |
| }); | |
| sqlTab.addEventListener('click', () => { | |
| sqlTab.classList.add('active', 'text-indigo-600', 'border-indigo-600'); | |
| sqlTab.classList.remove('text-gray-500'); | |
| excelTab.classList.remove('active', 'text-indigo-600', 'border-indigo-600'); | |
| excelTab.classList.add('text-gray-500'); | |
| sqlSection.classList.remove('hidden'); | |
| excelSection.classList.add('hidden'); | |
| }); | |
| // File upload functionality | |
| const fileDropzone = document.getElementById('fileDropzone'); | |
| const fileInput = document.getElementById('fileInput'); | |
| const fileInfo = document.getElementById('fileInfo'); | |
| const fileName = document.getElementById('fileName'); | |
| const fileSize = document.getElementById('fileSize'); | |
| const removeFile = document.getElementById('removeFile'); | |
| const sheetSelect = document.getElementById('sheetSelect'); | |
| fileDropzone.addEventListener('click', () => fileInput.click()); | |
| fileInput.addEventListener('change', (e) => { | |
| if (e.target.files.length > 0) { | |
| const file = e.target.files[0]; | |
| fileName.textContent = file.name; | |
| fileSize.textContent = `${(file.size / (1024 * 1024)).toFixed(1)} MB`; | |
| fileInfo.classList.remove('hidden'); | |
| fileDropzone.classList.add('hidden'); | |
| // Simulate sheet selection (in a real app, you'd parse the Excel file) | |
| sheetSelect.innerHTML = ` | |
| <option value="">Select a sheet</option> | |
| <option value="Sheet1">Sheet1</option> | |
| <option value="Sheet2">Sheet2</option> | |
| <option value="Orders">Orders</option> | |
| `; | |
| sheetSelect.disabled = false; | |
| } | |
| }); | |
| removeFile.addEventListener('click', () => { | |
| fileInput.value = ''; | |
| fileInfo.classList.add('hidden'); | |
| fileDropzone.classList.remove('hidden'); | |
| sheetSelect.innerHTML = '<option value="">Select a sheet</option>'; | |
| sheetSelect.disabled = true; | |
| // Clear preview | |
| document.getElementById('previewHeader').innerHTML = ''; | |
| document.getElementById('previewBody').innerHTML = ''; | |
| }); | |
| // Drag and drop functionality | |
| fileDropzone.addEventListener('dragover', (e) => { | |
| e.preventDefault(); | |
| fileDropzone.classList.add('active'); | |
| }); | |
| fileDropzone.addEventListener('dragleave', () => { | |
| fileDropzone.classList.remove('active'); | |
| }); | |
| fileDropzone.addEventListener('drop', (e) => { | |
| e.preventDefault(); | |
| fileDropzone.classList.remove('active'); | |
| if (e.dataTransfer.files.length > 0) { | |
| fileInput.files = e.dataTransfer.files; | |
| const event = new Event('change'); | |
| fileInput.dispatchEvent(event); | |
| } | |
| }); | |
| // Sheet selection change | |
| sheetSelect.addEventListener('change', (e) => { | |
| if (e.target.value) { | |
| // Simulate loading data for the selected sheet | |
| const headers = ['ID', 'Product', 'Category', 'Price', 'Quantity']; | |
| const data = [ | |
| [1, 'Premium Widget', 'Widgets', 49.99, 120], | |
| [2, 'Basic Widget', 'Widgets', 19.99, 350], | |
| [3, 'Deluxe Package', 'Packages', 199.99, 45], | |
| [4, 'Standard Package', 'Packages', 99.99, 80], | |
| [5, 'Add-on Service', 'Services', 29.99, 210] | |
| ]; | |
| const previewHeader = document.getElementById('previewHeader'); | |
| const previewBody = document.getElementById('previewBody'); | |
| // Build header | |
| previewHeader.innerHTML = ''; | |
| const headerRow = document.createElement('tr'); | |
| headers.forEach(header => { | |
| const th = document.createElement('th'); | |
| th.className = 'px-4 py-2 text-left text-xs font-medium text-gray-500 uppercase'; | |
| th.textContent = header; | |
| headerRow.appendChild(th); | |
| }); | |
| previewHeader.appendChild(headerRow); | |
| // Build body | |
| previewBody.innerHTML = ''; | |
| data.forEach(row => { | |
| const tr = document.createElement('tr'); | |
| row.forEach(cell => { | |
| const td = document.createElement('td'); | |
| td.className = 'px-4 py-2 text-sm text-gray-700'; | |
| td.textContent = cell; | |
| tr.appendChild(td); | |
| }); | |
| previewBody.appendChild(tr); | |
| }); | |
| } | |
| }); | |
| // Chat functionality | |
| const sqlEditor = document.getElementById('sqlEditor'); | |
| const sendButton = document.getElementById('sendButton'); | |
| const typingIndicator = document.getElementById('typingIndicator'); | |
| const charCount = document.getElementById('charCount'); | |
| // Character count | |
| sqlEditor.addEventListener('input', () => { | |
| charCount.textContent = sqlEditor.textContent.length; | |
| }); | |
| // Send message | |
| sendButton.addEventListener('click', () => { | |
| const message = sqlEditor.textContent.trim(); | |
| if (message) { | |
| // Add user message to chat | |
| const chatContainer = document.querySelector('.chat-container'); | |
| const userMessage = document.createElement('div'); | |
| userMessage.className = 'flex justify-end'; | |
| userMessage.innerHTML = ` | |
| <div class="max-w-[80%] bg-indigo-600 rounded-lg p-4 text-white"> | |
| <p>${message}</p> | |
| </div> | |
| `; | |
| chatContainer.appendChild(userMessage); | |
| // Clear input | |
| sqlEditor.textContent = ''; | |
| charCount.textContent = '0'; | |
| // Show typing indicator | |
| typingIndicator.classList.remove('hidden'); | |
| // Scroll to bottom | |
| chatContainer.scrollTop = chatContainer.scrollHeight; | |
| // Simulate assistant response after delay | |
| setTimeout(() => { | |
| typingIndicator.classList.add('hidden'); | |
| // Create assistant response | |
| const assistantResponse = document.createElement('div'); | |
| assistantResponse.className = 'flex justify-start'; | |
| assistantResponse.innerHTML = ` | |
| <div class="max-w-[80%] bg-gray-50 rounded-lg p-4"> | |
| <div class="flex items-start"> | |
| <div class="flex-shrink-0 h-8 w-8 rounded-full bg-gray-100 flex items-center justify-center"> | |
| <i class="fas fa-robot text-gray-600"></i> | |
| </div> | |
| <div class="ml-3"> | |
| <h3 class="text-sm font-medium text-gray-800">SQL Assistant</h3> | |
| <div class="mt-1 text-sm text-gray-700"> | |
| <p>Here are the results for your query:</p> | |
| <div class="result-table mt-2 border border-gray-200 rounded-lg overflow-hidden"> | |
| <table class="min-w-full divide-y divide-gray-200"> | |
| <thead class="bg-gray-100"> | |
| <tr> | |
| <th class="px-4 py-2 text-left text-xs font-medium text-gray-500 uppercase">Column 1</th> | |
| <th class="px-4 py-2 text-left text-xs font-medium text-gray-500 uppercase">Column 2</th> | |
| <th class="px-4 py-2 text-left text-xs font-medium text-gray-500 uppercase">Column 3</th> | |
| </tr> | |
| </thead> | |
| <tbody class="divide-y divide-gray-200"> | |
| <tr> | |
| <td class="px-4 py-2">Value 1</td> | |
| <td class="px-4 py-2">Value 2</td> | |
| <td class="px-4 py-2">Value 3</td> | |
| </tr> | |
| <tr> | |
| <td class="px-4 py-2">Value 4</td> | |
| <td class="px-4 py-2">Value 5</td> | |
| <td class="px-4 py-2">Value 6</td> | |
| </tr> | |
| </tbody> | |
| </table> | |
| </div> | |
| <div class="mt-3 text-xs text-gray-500"> | |
| <p>Generated SQL: <code class="bg-gray-200 px-1 rounded">SELECT * FROM ${sheetSelect.value || 'your_data'} WHERE condition</code></p> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| `; | |
| chatContainer.appendChild(assistantResponse); | |
| // Scroll to bottom | |
| chatContainer.scrollTop = chatContainer.scrollHeight; | |
| }, 1500); | |
| } | |
| }); | |
| // Dark mode toggle | |
| const darkModeToggle = document.getElementById('darkModeToggle'); | |
| darkModeToggle.addEventListener('click', () => { | |
| document.documentElement.classList.toggle('dark'); | |
| const icon = darkModeToggle.querySelector('i'); | |
| if (document.documentElement.classList.contains('dark')) { | |
| icon.classList.remove('fa-moon'); | |
| icon.classList.add('fa-sun'); | |
| icon.classList.remove('text-gray-600'); | |
| icon.classList.add('text-yellow-300'); | |
| } else { | |
| icon.classList.remove('fa-sun'); | |
| icon.classList.add('fa-moon'); | |
| icon.classList.remove('text-yellow-300'); | |
| icon.classList.add('text-gray-600'); | |
| } | |
| }); | |
| </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=SanyamV/sql-query-agent-project" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> | |
| </html> |