Spaces:
Running
Running
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>AI Workflow Dashboard</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"> | |
| <script src="https://cdn.jsdelivr.net/npm/sortablejs@1.14.0/Sortable.min.js"></script> | |
| <style> | |
| .kanban-column { | |
| min-height: 300px; | |
| background-color: #f8fafc; | |
| border-radius: 0.5rem; | |
| } | |
| .kanban-card { | |
| transition: all 0.2s ease; | |
| cursor: grab; | |
| } | |
| .kanban-card:hover { | |
| transform: translateY(-2px); | |
| box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1); | |
| } | |
| .kanban-card:active { | |
| cursor: grabbing; | |
| } | |
| .tab-active { | |
| border-bottom: 3px solid #3b82f6; | |
| color: #3b82f6; | |
| } | |
| .workflow-btn { | |
| transition: all 0.2s ease; | |
| } | |
| .workflow-btn:hover { | |
| transform: translateY(-2px); | |
| } | |
| #loading-overlay { | |
| display: none; | |
| } | |
| .sortable-chosen { | |
| opacity: 0.8; | |
| background: #f0f9ff; | |
| } | |
| .sortable-ghost { | |
| opacity: 0.4; | |
| background: #dbeafe; | |
| } | |
| </style> | |
| </head> | |
| <body class="bg-gray-50 min-h-screen"> | |
| <div class="container mx-auto px-4 py-8"> | |
| <header class="mb-8"> | |
| <h1 class="text-3xl font-bold text-gray-800">AI Workflow Dashboard</h1> | |
| <p class="text-gray-600">Manage all your AI workflows in one place</p> | |
| </header> | |
| <!-- Tabs --> | |
| <div class="flex border-b mb-6"> | |
| <button id="workflows-tab" class="px-4 py-2 font-medium tab-active"> | |
| <i class="fas fa-bolt mr-2"></i>AI Workflows | |
| </button> | |
| <button id="chat-tab" class="px-4 py-2 font-medium text-gray-500"> | |
| <i class="fas fa-comment mr-2"></i>AI Chat | |
| </button> | |
| <button id="content-tab" class="px-4 py-2 font-medium text-gray-500"> | |
| <i class="fas fa-columns mr-2"></i>AI Content | |
| </button> | |
| </div> | |
| <!-- Workflows Tab --> | |
| <div id="workflows-content" class="bg-white rounded-lg shadow p-6"> | |
| <h2 class="text-xl font-semibold mb-4 text-gray-800">AI Workflows</h2> | |
| <p class="text-gray-600 mb-6">Select a workflow to execute</p> | |
| <div class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-5 gap-4"> | |
| <!-- Summarize --> | |
| <button onclick="triggerWorkflow('summarize')" class="bg-blue-100 hover:bg-blue-200 text-blue-800 workflow-btn rounded-lg p-4 flex flex-col items-center justify-center h-32 shadow-sm"> | |
| <i class="fas fa-file-lines text-2xl mb-2"></i> | |
| <span>Summarize</span> | |
| </button> | |
| <!-- Translate --> | |
| <button onclick="triggerWorkflow('translate')" class="bg-green-100 hover:bg-green-200 text-green-800 workflow-btn rounded-lg p-4 flex flex-col items-center justify-center h-32 shadow-sm"> | |
| <i class="fas fa-language text-2xl mb-2"></i> | |
| <span>Translate</span> | |
| </button> | |
| <!-- Generate Text --> | |
| <button onclick="triggerWorkflow('generate')" class="bg-purple-100 hover:bg-purple-200 text-purple-800 workflow-btn rounded-lg p-4 flex flex-col items-center justify-center h-32 shadow-sm"> | |
| <i class="fas fa-pen text-2xl mb-2"></i> | |
| <span>Generate Text</span> | |
| </button> | |
| <!-- Analyze --> | |
| <button onclick="triggerWorkflow('analyze')" class="bg-yellow-100 hover:bg-yellow-200 text-yellow-800 workflow-btn rounded-lg p-4 flex flex-col items-center justify-center h-32 shadow-sm"> | |
| <i class="fas fa-chart-bar text-2xl mb-2"></i> | |
| <span>Analyze</span> | |
| </button> | |
| <!-- Extract --> | |
| <button onclick="triggerWorkflow('extract')" class="bg-red-100 hover:bg-red-200 text-red-800 workflow-btn rounded-lg p-4 flex flex-col items-center justify-center h-32 shadow-sm"> | |
| <i class="fas fa-filter text-2xl mb-2"></i> | |
| <span>Extract</span> | |
| </button> | |
| <!-- Classify --> | |
| <button onclick="triggerWorkflow('classify')" class="bg-indigo-100 hover:bg-indigo-200 text-indigo-800 workflow-btn rounded-lg p-4 flex flex-col items-center justify-center h-32 shadow-sm"> | |
| <i class="fas fa-tags text-2xl mb-2"></i> | |
| <span>Classify</span> | |
| </button> | |
| <!-- Rewrite --> | |
| <button onclick="triggerWorkflow('rewrite')" class="bg-pink-100 hover:bg-pink-200 text-pink-800 workflow-btn rounded-lg p-4 flex flex-col items-center justify-center h-32 shadow-sm"> | |
| <i class="fas fa-pen-fancy text-2xl mb-2"></i> | |
| <span>Rewrite</span> | |
| </button> | |
| <!-- Generate Code --> | |
| <button onclick="triggerWorkflow('code')" class="bg-gray-100 hover:bg-gray-200 text-gray-800 workflow-btn rounded-lg p-4 flex flex-col items-center justify-center h-32 shadow-sm"> | |
| <i class="fas fa-code text-2xl mb-2"></i> | |
| <span>Generate Code</span> | |
| </button> | |
| <!-- Q&A --> | |
| <button onclick="triggerWorkflow('qa')" class="bg-teal-100 hover:bg-teal-200 text-teal-800 workflow-btn rounded-lg p-4 flex flex-col items-center justify-center h-32 shadow-sm"> | |
| <i class="fas fa-question text-2xl mb-2"></i> | |
| <span>Q&A</span> | |
| </button> | |
| <!-- Generate Image --> | |
| <button onclick="triggerWorkflow('image')" class="bg-orange-100 hover:bg-orange-200 text-orange-800 workflow-btn rounded-lg p-4 flex flex-col items-center justify-center h-32 shadow-sm"> | |
| <i class="fas fa-image text-2xl mb-2"></i> | |
| <span>Generate Image</span> | |
| </button> | |
| <!-- Generate Audio --> | |
| <button onclick="triggerWorkflow('audio')" class="bg-blue-100 hover:bg-blue-200 text-blue-800 workflow-btn rounded-lg p-4 flex flex-col items-center justify-center h-32 shadow-sm"> | |
| <i class="fas fa-music text-2xl mb-2"></i> | |
| <span>Generate Audio</span> | |
| </button> | |
| <!-- Generate Video --> | |
| <button onclick="triggerWorkflow('video')" class="bg-green-100 hover:bg-green-200 text-green-800 workflow-btn rounded-lg p-4 flex flex-col items-center justify-center h-32 shadow-sm"> | |
| <i class="fas fa-video text-2xl mb-2"></i> | |
| <span>Generate Video</span> | |
| </button> | |
| <!-- Process Data --> | |
| <button onclick="triggerWorkflow('data')" class="bg-purple-100 hover:bg-purple-200 text-purple-800 workflow-btn rounded-lg p-4 flex flex-col items-center justify-center h-32 shadow-sm"> | |
| <i class="fas fa-database text-2xl mb-2"></i> | |
| <span>Process Data</span> | |
| </button> | |
| <!-- Generate Report --> | |
| <button onclick="triggerWorkflow('report')" class="bg-yellow-100 hover:bg-yellow-200 text-yellow-800 workflow-btn rounded-lg p-4 flex flex-col items-center justify-center h-32 shadow-sm"> | |
| <i class="fas fa-file-alt text-2xl mb-2"></i> | |
| <span>Generate Report</span> | |
| </button> | |
| <!-- Automate --> | |
| <button onclick="triggerWorkflow('automate')" class="bg-red-100 hover:bg-red-200 text-red-800 workflow-btn rounded-lg p-4 flex flex-col items-center justify-center h-32 shadow-sm"> | |
| <i class="fas fa-robot text-2xl mb-2"></i> | |
| <span>Automate</span> | |
| </button> | |
| </div> | |
| <div id="response-container" class="mt-8 p-4 bg-gray-50 rounded-lg hidden"> | |
| <h3 class="font-medium text-gray-700 mb-2">Last Response:</h3> | |
| <pre id="webhook-response" class="bg-white p-3 rounded overflow-x-auto text-sm"></pre> | |
| </div> | |
| </div> | |
| <!-- Chat Tab --> | |
| <div id="chat-content" class="bg-white rounded-lg shadow p-6 hidden"> | |
| <h2 class="text-xl font-semibold mb-4 text-gray-800">AI Chat</h2> | |
| <div id="chat-history" class="mb-4 h-64 overflow-y-auto p-3 bg-gray-50 rounded-lg"> | |
| <!-- Chat messages will appear here --> | |
| </div> | |
| <div class="flex gap-2"> | |
| <input | |
| type="text" | |
| id="message-input" | |
| placeholder="Type your message..." | |
| class="flex-1 p-3 border rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500" | |
| onkeypress="if(event.key === 'Enter') sendMessage()" | |
| /> | |
| <button | |
| id="send-button" | |
| onclick="sendMessage()" | |
| class="bg-blue-600 hover:bg-blue-700 text-white px-4 py-2 rounded-lg flex items-center" | |
| > | |
| <i class="fas fa-paper-plane mr-2"></i> Send | |
| </button> | |
| </div> | |
| </div> | |
| <!-- AI Content Tab (Kanban) --> | |
| <div id="content-content" class="bg-white rounded-lg shadow p-6 hidden"> | |
| <h2 class="text-xl font-semibold mb-6 text-gray-800">AI Content Kanban</h2> | |
| <div class="grid grid-cols-1 md:grid-cols-3 gap-4"> | |
| <!-- To Do Column --> | |
| <div class="kanban-column p-4"> | |
| <h3 class="font-medium text-gray-700 mb-4 flex items-center"> | |
| <i class="fas fa-list-ul mr-2"></i> To Do | |
| </h3> | |
| <div id="todo-column" class="space-y-3 min-h-[300px]"> | |
| <!-- Cards will be added here --> | |
| </div> | |
| </div> | |
| <!-- In Progress Column --> | |
| <div class="kanban-column p-4"> | |
| <h3 class="font-medium text-gray-700 mb-4 flex items-center"> | |
| <i class="fas fa-spinner fa-spin mr-2"></i> In Progress | |
| </h3> | |
| <div id="inprogress-column" class="space-y-3 min-h-[300px]"> | |
| <!-- Cards will be added here --> | |
| </div> | |
| </div> | |
| <!-- Done Column --> | |
| <div class="kanban-column p-4"> | |
| <h3 class="font-medium text-gray-700 mb-4 flex items-center"> | |
| <i class="fas fa-check-circle mr-2"></i> Done | |
| </h3> | |
| <div id="done-column" class="space-y-3 min-h-[300px]"> | |
| <!-- Cards will be added here --> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Loading Overlay --> | |
| <div id="loading-overlay" class="fixed inset-0 bg-black bg-opacity-30 flex items-center justify-center z-50 hidden"> | |
| <div class="bg-white p-6 rounded-lg shadow-xl flex items-center"> | |
| <i class="fas fa-spinner fa-spin text-blue-500 text-2xl mr-3"></i> | |
| <span>Processing your request...</span> | |
| </div> | |
| </div> | |
| <script> | |
| // Tab switching functionality | |
| document.getElementById('workflows-tab').addEventListener('click', () => switchTab('workflows')); | |
| document.getElementById('chat-tab').addEventListener('click', () => switchTab('chat')); | |
| document.getElementById('content-tab').addEventListener('click', () => switchTab('content')); | |
| function switchTab(tabName) { | |
| // Hide all content | |
| document.getElementById('workflows-content').classList.add('hidden'); | |
| document.getElementById('chat-content').classList.add('hidden'); | |
| document.getElementById('content-content').classList.add('hidden'); | |
| // Remove active from all tabs | |
| document.getElementById('workflows-tab').classList.remove('tab-active'); | |
| document.getElementById('chat-tab').classList.remove('tab-active'); | |
| document.getElementById('content-tab').classList.remove('tab-active'); | |
| // Show selected content and mark tab as active | |
| document.getElementById(`${tabName}-content`).classList.remove('hidden'); | |
| document.getElementById(`${tabName}-tab`).classList.add('tab-active'); | |
| } | |
| // Kanban board state | |
| const kanbanColumns = { | |
| todo: [], | |
| inProgress: [], | |
| done: [] | |
| }; | |
| // Initialize SortableJS for drag and drop | |
| document.addEventListener('DOMContentLoaded', () => { | |
| new Sortable(document.getElementById('todo-column'), { | |
| group: 'shared', | |
| animation: 150, | |
| ghostClass: 'sortable-ghost', | |
| chosenClass: 'sortable-chosen', | |
| onEnd: (evt) => handleDrop(evt, 'todo') | |
| }); | |
| new Sortable(document.getElementById('inprogress-column'), { | |
| group: 'shared', | |
| animation: 150, | |
| ghostClass: 'sortable-ghost', | |
| chosenClass: 'sortable-chosen', | |
| onEnd: (evt) => handleDrop(evt, 'inProgress') | |
| }); | |
| new Sortable(document.getElementById('done-column'), { | |
| group: 'shared', | |
| animation: 150, | |
| ghostClass: 'sortable-ghost', | |
| chosenClass: 'sortable-chosen', | |
| onEnd: (evt) => handleDrop(evt, 'done') | |
| }); | |
| }); | |
| function handleDrop(evt, toColumn) { | |
| const itemId = evt.item.dataset.id; | |
| const fromColumn = evt.from.id.replace('-column', ''); | |
| if (fromColumn === toColumn) return; | |
| // Find the item in the source column | |
| const itemIndex = kanbanColumns[fromColumn].findIndex(item => item.id === itemId); | |
| if (itemIndex === -1) return; | |
| // Move the item | |
| const [movedItem] = kanbanColumns[fromColumn].splice(itemIndex, 1); | |
| kanbanColumns[toColumn].push(movedItem); | |
| // Update UI | |
| renderKanbanColumns(); | |
| } | |
| function addToKanban(content, title = 'AI Response') { | |
| const newItem = { | |
| id: Date.now().toString(), | |
| title, | |
| content, | |
| timestamp: new Date().toLocaleTimeString() | |
| }; | |
| kanbanColumns.todo.push(newItem); | |
| renderKanbanColumns(); | |
| } | |
| function renderKanbanColumns() { | |
| renderKanbanColumn('todo'); | |
| renderKanbanColumn('inProgress'); | |
| renderKanbanColumn('done'); | |
| } | |
| function renderKanbanColumn(columnName) { | |
| const columnElement = document.getElementById(`${columnName.toLowerCase()}-column`); | |
| columnElement.innerHTML = ''; | |
| kanbanColumns[columnName].forEach(item => { | |
| const card = document.createElement('div'); | |
| card.className = 'kanban-card bg-white p-3 rounded-lg shadow border cursor-move'; | |
| if (columnName === 'inProgress') card.classList.add('border-blue-200'); | |
| if (columnName === 'done') card.classList.add('border-green-200'); | |
| card.dataset.id = item.id; | |
| card.innerHTML = ` | |
| <div class="flex justify-between items-start mb-2"> | |
| <h4 class="font-medium text-gray-800">${item.title}</h4> | |
| <span class="text-xs text-gray-500">${item.timestamp}</span> | |
| </div> | |
| <pre class="text-xs bg-gray-50 p-2 rounded overflow-x-auto">${item.content}</pre> | |
| `; | |
| columnElement.appendChild(card); | |
| }); | |
| } | |
| // Workflow functions | |
| async function triggerWorkflow(workflowType) { | |
| showLoading(); | |
| try { | |
| // Simulate different API responses based on workflow type | |
| let response; | |
| switch(workflowType) { | |
| case 'summarize': | |
| response = { summary: "This is a generated summary of the content..." }; | |
| break; | |
| case 'translate': | |
| response = { translation: "Translated text goes here..." }; | |
| break; | |
| case 'generate': | |
| response = { generatedText: "This is AI-generated content based on your prompt..." }; | |
| break; | |
| case 'analyze': | |
| response = { analysis: "Sentiment analysis shows positive sentiment..." }; | |
| break; | |
| case 'extract': | |
| response = { entities: ["Person", "Location", "Organization"] }; | |
| break; | |
| case 'classify': | |
| response = { categories: ["Technology", "AI", "Machine Learning"] }; | |
| break; | |
| case 'rewrite': | |
| response = { rewrittenText: "This is a rewritten version of your text..." }; | |
| break; | |
| case 'code': | |
| response = { codeSnippet: "function example() {\n return 'Hello World';\n}" }; | |
| break; | |
| case 'qa': | |
| response = { answer: "The answer to your question is..." }; | |
| break; | |
| case 'image': | |
| response = { imageUrl: "https://via.placeholder.com/300" }; | |
| break; | |
| case 'audio': | |
| response = { audioUrl: "https://example.com/audio.mp3" }; | |
| break; | |
| case 'video': | |
| response = { videoUrl: "https://example.com/video.mp4" }; | |
| break; | |
| case 'data': | |
| response = { data: { key1: "value1", key2: "value2" } }; | |
| break; | |
| case 'report': | |
| response = { report: "Your detailed report is ready..." }; | |
| break; | |
| case 'automate': | |
| response = { status: "Workflow automation completed successfully" }; | |
| break; | |
| default: | |
| response = { message: "Workflow executed successfully" }; | |
| } | |
| // Show response | |
| document.getElementById('webhook-response').textContent = JSON.stringify(response, null, 2); | |
| document.getElementById('response-container').classList.remove('hidden'); | |
| // Add to kanban | |
| addToKanban(JSON.stringify(response, null, 2), `Workflow: ${workflowType}`); | |
| } catch (error) { | |
| document.getElementById('webhook-response').textContent = error.message; | |
| document.getElementById('response-container').classList.remove('hidden'); | |
| addToKanban(error.message, "Error"); | |
| } finally { | |
| hideLoading(); | |
| } | |
| } | |
| // Chat functions | |
| const chatHistory = []; | |
| async function sendMessage() { | |
| const messageInput = document.getElementById('message-input'); | |
| const message = messageInput.value.trim(); | |
| if (!message) return; | |
| showLoading(); | |
| document.getElementById('send-button').disabled = true; | |
| try { | |
| // Add user message | |
| const userMessage = { role: 'user', content: message, id: Date.now() }; | |
| chatHistory.push(userMessage); | |
| renderChatHistory(); | |
| messageInput.value = ''; | |
| // Simulate AI response after delay | |
| await new Promise(resolve => setTimeout(resolve, 1000)); | |
| // Add AI response | |
| const aiMessage = { | |
| role: 'assistant', | |
| content: `This is a simulated response to: "${userMessage.content}"`, | |
| id: Date.now() + 1 | |
| }; | |
| chatHistory.push(aiMessage); | |
| renderChatHistory(); | |
| // Add to kanban | |
| addToKanban(aiMessage.content, "Chat Response"); | |
| } catch (error) { | |
| const errorMessage = { role: 'assistant', content: `Error: ${error.message}`, id: Date.now() + 1 }; | |
| chatHistory.push(errorMessage); | |
| renderChatHistory(); | |
| addToKanban(error.message, "Error"); | |
| } finally { | |
| hideLoading(); | |
| document.getElementById('send-button').disabled = false; | |
| messageInput.focus(); | |
| } | |
| } | |
| function renderChatHistory() { | |
| const chatHistoryElement = document.getElementById('chat-history'); | |
| chatHistoryElement.innerHTML = ''; | |
| chatHistory.forEach(msg => { | |
| const messageElement = document.createElement('div'); | |
| messageElement.className = `mb-3 p-3 rounded-lg max-w-3xl ${msg.role === 'user' ? 'ml-auto bg-blue-100 text-blue-900' : 'mr-auto bg-gray-100 text-gray-900'}`; | |
| messageElement.innerHTML = ` | |
| <div class="font-medium">${msg.role === 'user' ? 'You' : 'AI Assistant'}</div> | |
| <div>${msg.content}</div> | |
| `; | |
| chatHistoryElement.appendChild(messageElement); | |
| }); | |
| // Scroll to bottom | |
| chatHistoryElement.scrollTop = chatHistoryElement.scrollHeight; | |
| } | |
| // Loading functions | |
| function showLoading() { | |
| document.getElementById('loading-overlay').classList.remove('hidden'); | |
| } | |
| function hideLoading() { | |
| document.getElementById('loading-overlay').classList.add('hidden'); | |
| } | |
| </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=a40login/dashboard-mvp" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> | |
| </html> |