Spaces:
Running
Running
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Ask Devin - DevinAI Clone</title> | |
| <link rel="stylesheet" href="style.css"> | |
| <script src="https://cdn.tailwindcss.com"></script> | |
| <script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script> | |
| <script src="https://unpkg.com/feather-icons"></script> | |
| <link rel="preconnect" href="https://fonts.googleapis.com"> | |
| <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> | |
| <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet"> | |
| <style> | |
| * { | |
| font-family: 'Inter', sans-serif; | |
| } | |
| .code-font { | |
| font-family: 'JetBrains Mono', monospace; | |
| } | |
| .message-user { | |
| background: linear-gradient(135deg, #3b82f6, #6366f1); | |
| color: white; | |
| border-radius: 1rem 1rem 0.25rem 1rem; | |
| } | |
| .message-ai { | |
| background: #f3f4f6; | |
| color: #1f2937; | |
| border-radius: 1rem 1rem 1rem 0.25rem; | |
| } | |
| .thinking-dots span { | |
| animation: bounce 1.5s infinite; | |
| } | |
| .thinking-dots span:nth-child(2) { | |
| animation-delay: 0.2s; | |
| } | |
| .thinking-dots span:nth-child(3) { | |
| animation-delay: 0.4s; | |
| } | |
| @keyframes bounce { | |
| 0%, 80%, 100% { transform: translateY(0); } | |
| 40% { transform: translateY(-10px); } | |
| } | |
| </style> | |
| </head> | |
| <body class="bg-gray-50 min-h-screen"> | |
| <custom-navbar></custom-navbar> | |
| <custom-sidebar></custom-sidebar> | |
| <main class="ml-0 md:ml-64 pt-16 px-4 md:px-8 pb-8"> | |
| <div class="max-w-6xl mx-auto"> | |
| <!-- Header Section --> | |
| <div class="mb-8 mt-6"> | |
| <h1 class="text-3xl md:text-4xl font-bold text-gray-900">Ask Devin AI Assistant</h1> | |
| <p class="text-gray-600 mt-2">Get instant AI-powered answers to your coding questions, with explanations and code examples</p> | |
| </div> | |
| <div class="grid grid-cols-1 lg:grid-cols-3 gap-8"> | |
| <!-- Left Column - Chat Interface --> | |
| <div class="lg:col-span-2"> | |
| <div class="bg-white rounded-xl shadow-lg border border-gray-200 overflow-hidden h-[600px] flex flex-col"> | |
| <!-- Chat Header --> | |
| <div class="px-6 py-4 border-b border-gray-200 bg-gradient-to-r from-blue-50 to-purple-50"> | |
| <h2 class="text-xl font-bold text-gray-900 flex items-center"> | |
| <div class="w-8 h-8 bg-gradient-to-r from-blue-600 to-purple-600 rounded-full flex items-center justify-center mr-3"> | |
| <i data-feather="cpu" class="w-4 h-4 text-white"></i> | |
| </div> | |
| Devin AI Assistant | |
| <span class="ml-3 text-xs bg-green-100 text-green-800 px-2 py-1 rounded-full">Online</span> | |
| </h2> | |
| </div> | |
| <!-- Chat Messages --> | |
| <div class="flex-1 overflow-y-auto p-6" id="chat-messages"> | |
| <!-- Welcome Message --> | |
| <div class="message-ai p-4 mb-6 max-w-[85%]"> | |
| <div class="flex items-center mb-2"> | |
| <div class="w-6 h-6 bg-gradient-to-r from-purple-500 to-pink-500 rounded-full"></div> | |
| <span class="ml-2 font-semibold">Devin AI</span> | |
| <span class="ml-auto text-xs text-gray-500">Just now</span> | |
| </div> | |
| <p class="text-gray-800">Hello! I'm Devin, your AI coding assistant. I can help you with:</p> | |
| <ul class="list-disc pl-5 mt-2 text-gray-700"> | |
| <li>Explaining programming concepts</li> | |
| <li>Writing and debugging code</li> | |
| <li>Code reviews and optimization</li> | |
| <li>Architecture and best practices</li> | |
| </ul> | |
| <p class="mt-3 text-gray-800">What would you like to know today?</p> | |
| </div> | |
| <!-- Example messages --> | |
| <div class="message-user p-4 mb-6 max-w-[85%] ml-auto"> | |
| <div class="flex items-center mb-2"> | |
| <div class="w-6 h-6 bg-gradient-to-r from-blue-500 to-cyan-500 rounded-full"></div> | |
| <span class="ml-2 font-semibold text-white">You</span> | |
| <span class="ml-auto text-xs text-blue-100">2 min ago</span> | |
| </div> | |
| <p>How do I optimize React component performance?</p> | |
| </div> | |
| <div class="message-ai p-4 mb-6 max-w-[85%]"> | |
| <div class="flex items-center mb-2"> | |
| <div class="w-6 h-6 bg-gradient-to-r from-purple-500 to-pink-500 rounded-full"></div> | |
| <span class="ml-2 font-semibold">Devin AI</span> | |
| <span class="ml-auto text-xs text-gray-500">1 min ago</span> | |
| </div> | |
| <p class="text-gray-800 mb-3">React performance can be optimized using:</p> | |
| <ol class="list-decimal pl-5 text-gray-700 mb-3"> | |
| <li><strong>useMemo</strong>: Memoize expensive calculations</li> | |
| <li><strong>useCallback</strong>: Memoize function references</li> | |
| <li><strong>React.memo</strong>: Prevent unnecessary re-renders</li> | |
| <li><strong>Code splitting</strong>: Lazy load components</li> | |
| </ol> | |
| <pre class="text-sm bg-gray-800 text-gray-200 p-3 rounded-lg mt-2 overflow-x-auto"> | |
| import React, { useMemo, memo } from 'react'; | |
| // Memoized component | |
| const ExpensiveComponent = memo(({ data }) => { | |
| const processedData = useMemo(() => { | |
| return data.filter(item => item.active) | |
| .map(item => ({ ...item, processed: true })); | |
| }, [data]); | |
| return <div>{JSON.stringify(processedData)}</div>; | |
| });</pre> | |
| <p class="mt-3 text-gray-800">Would you like me to explain any of these in more detail?</p> | |
| </div> | |
| </div> | |
| <!-- Chat Input --> | |
| <div class="border-t border-gray-200 p-4"> | |
| <div class="flex items-center"> | |
| <textarea | |
| id="user-question" | |
| rows="2" | |
| placeholder="Ask Devin anything about coding..." | |
| class="flex-1 border border-gray-300 rounded-l-lg p-4 focus:outline-none focus:ring-2 focus:ring-blue-500 resize-none" | |
| ></textarea> | |
| <button | |
| id="send-question" | |
| class="bg-gradient-to-r from-blue-600 to-purple-600 text-white px-6 py-4 rounded-r-lg font-semibold hover:opacity-90 transition-opacity h-full" | |
| > | |
| <i data-feather="send" class="w-5 h-5"></i> | |
| </button> | |
| </div> | |
| <div class="flex justify-between items-center mt-2 text-sm text-gray-500"> | |
| <div> | |
| <button class="flex items-center text-gray-600 hover:text-blue-600 mr-4"> | |
| <i data-feather="code" class="w-4 h-4 mr-1"></i> | |
| Attach Code | |
| </button> | |
| </div> | |
| <div> | |
| <button class="flex items-center text-gray-600 hover:text-blue-600"> | |
| <i data-feather="trash" class="w-4 h-4 mr-1"></i> | |
| Clear Chat | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Right Column - Features & Quick Questions --> | |
| <div class="lg:col-span-1"> | |
| <!-- Quick Questions --> | |
| <div class="bg-white rounded-xl shadow-lg border border-gray-200 overflow-hidden mb-6"> | |
| <div class="px-6 py-4 border-b border-gray-200"> | |
| <h2 class="text-xl font-bold text-gray-900 flex items-center"> | |
| <i data-feather="zap" class="w-5 h-5 mr-2 text-yellow-600"></i> | |
| Quick Questions | |
| </h2> | |
| </div> | |
| <div class="p-4"> | |
| <div class="space-y-3"> | |
| <button class="quick-question-btn w-full text-left p-3 border border-gray-200 rounded-lg hover:bg-blue-50 hover:border-blue-200"> | |
| How to fix "Cannot read property of undefined" in JavaScript? | |
| </button> | |
| <button class="quick-question-btn w-full text-left p-3 border border-gray-200 rounded-lg hover:bg-blue-50 hover:border-blue-200"> | |
| Explain async/await with examples | |
| </button> | |
| <button class="quick-question-btn w-full text-left p-3 border border-gray-200 rounded-lg hover:bg-blue-50 hover:border-blue-200"> | |
| Best practices for API error handling | |
| </button> | |
| <button class="quick-question-btn w-full text-left p-3 border border-gray-200 rounded-lg hover:bg-blue-50 hover:border-blue-200"> | |
| React vs Vue vs Angular comparison | |
| </button> | |
| <button class="quick-question-btn w-full text-left p-3 border border-gray-200 rounded-lg hover:bg-blue-50 hover:border-blue-200"> | |
| How to optimize database queries? | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- AI Features --> | |
| <div class="bg-gradient-to-br from-gray-900 to-black rounded-xl shadow-lg overflow-hidden"> | |
| <div class="px-6 py-4"> | |
| <h2 class="text-xl font-bold text-white mb-4">AI Features</h2> | |
| <div class="space-y-4"> | |
| <div class="flex items-center p-3 bg-gray-800 bg-opacity-50 rounded-lg"> | |
| <div class="w-10 h-10 bg-blue-500 rounded-lg flex items-center justify-center mr-3"> | |
| <i data-feather="code" class="w-5 h-5 text-white"></i> | |
| </div> | |
| <div> | |
| <p class="font-semibold text-white">Code Generation</p> | |
| <p class="text-sm text-gray-300">Generate code from natural language</p> | |
| </div> | |
| </div> | |
| <div class="flex items-center p-3 bg-gray-800 bg-opacity-50 rounded-lg"> | |
| <div class="w-10 h-10 bg-green-500 rounded-lg flex items-center justify-center mr-3"> | |
| <i data-feather="search" class="w-5 h-5 text-white"></i> | |
| </div> | |
| <div> | |
| <p class="font-semibold text-white">Code Explanation</p> | |
| <p class="text-sm text-gray-300">Understand complex code snippets</p> | |
| </div> | |
| </div> | |
| <div class="flex items-center p-3 bg-gray-800 bg-opacity-50 rounded-lg"> | |
| <div class="w-10 h-10 bg-purple-500 rounded-lg flex items-center justify-center mr-3"> | |
| <i data-feather="check-circle" class="w-5 h-5 text-white"></i> | |
| </div> | |
| <div> | |
| <p class="font-semibold text-white">Code Review</p> | |
| <p class="text-sm text-gray-300">Get AI-powered code reviews</p> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Recent Questions --> | |
| <div class="bg-white rounded-xl shadow-lg border border-gray-200 overflow-hidden mt-6"> | |
| <div class="px-6 py-4 border-b border-gray-200"> | |
| <h2 class="text-xl font-bold text-gray-900 flex items-center"> | |
| <i data-feather="history" class="w-5 h-5 mr-2 text-gray-600"></i> | |
| Recent Questions | |
| </h2> | |
| </div> | |
| <div class="p-4"> | |
| <div class="space-y-4"> | |
| <div class="text-sm"> | |
| <p class="font-medium text-gray-900">"How to implement JWT auth?"</p> | |
| <p class="text-gray-500 text-xs mt-1">2 hours ago</p> | |
| </div> | |
| <div class="text-sm"> | |
| <p class="font-medium text-gray-900">"React useEffect cleanup"</p> | |
| <p class="text-gray-500 text-xs mt-1">Yesterday</p> | |
| </div> | |
| <div class="text-sm"> | |
| <p class="font-medium text-gray-900">"Python list comprehension speed"</p> | |
| <p class="text-gray-500 text-xs mt-1">3 days ago</p> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </main> | |
| <custom-footer></custom-footer> | |
| <script src="components/navbar.js"></script> | |
| <script src="components/sidebar.js"></script> | |
| <script src="components/footer.js"></script> | |
| <script src="script.js"></script> | |
| <script> | |
| feather.replace(); | |
| document.addEventListener('DOMContentLoaded', function() { | |
| // Update sidebar active state | |
| const sidebarLinks = document.querySelector('custom-sidebar').shadowRoot.querySelectorAll('.menu-item'); | |
| sidebarLinks.forEach(link => { | |
| link.classList.remove('active'); | |
| if (link.href && link.href.includes('ask-devin.html')) { | |
| link.classList.add('active'); | |
| } | |
| }); | |
| // Add Ask Devin to sidebar if not present | |
| const sidebar = document.querySelector('custom-sidebar'); | |
| if (sidebar) { | |
| const aiToolsGroup = sidebar.shadowRoot.querySelector('.menu-group:nth-child(2) .menu-items'); | |
| if (aiToolsGroup) { | |
| const askDevinLink = document.createElement('a'); | |
| askDevinLink.className = 'menu-item'; | |
| askDevinLink.href = 'ask-devin.html'; | |
| askDevinLink.innerHTML = '<i data-feather="message-square"></i> Ask Devin'; | |
| aiToolsGroup.appendChild(askDevinLink); | |
| feather.replace(); | |
| } | |
| } | |
| // Chat functionality | |
| const chatMessages = document.getElementById('chat-messages'); | |
| const userInput = document.getElementById('user-question'); | |
| const sendButton = document.getElementById('send-question'); | |
| function addMessage(text, isUser = true) { | |
| const messageDiv = document.createElement('div'); | |
| messageDiv.className = isUser ? 'message-user p-4 mb-6 max-w-[85%] ml-auto' : 'message-ai p1-4 mb-6 max-w-[85%]'; | |
| const timestamp = new Date().toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }); | |
| messageDiv.innerHTML = ` | |
| <div class="flex items-center mb-2"> | |
| <div class="w-6 h-6 ${isUser ? 'bg-gradient-to-r from-blue-500 to-cyan-500' : 'bg-gradient-to-r from-purple-500 to-pink-500'} rounded-full"></div> | |
| <span class="ml-2 font-semibold ${isUser ? 'text-white' : ''}">${isUser ? 'You' : 'Devin AI'}</span> | |
| <span class="ml-auto text-xs ${isUser ? 'text-blue-100' : 'text-gray-500'}">${timestamp}</span> | |
| </div> | |
| <p class="${isUser ? '' : 'text-gray-800'}">${text}</p> | |
| `; | |
| chatMessages.appendChild(messageDiv); | |
| chatMessages.scrollTop = chatMessages.scrollHeight; | |
| } | |
| function addThinkingIndicator() { | |
| const thinkingDiv = document.createElement('div'); | |
| thinkingDiv.className = 'message-ai p-4 mb-6 max-w-[85%]'; | |
| thinkingDiv.id = 'thinking-indicator'; | |
| thinkingDiv.innerHTML = ` | |
| <div class="flex items-center mb-2"> | |
| <div class="w-6 h-6 bg-gradient-to-r from-purple-500 to-pink-500 rounded-full"></div> | |
| <span class="ml-2 font-semibold">Devin AI</span> | |
| </div> | |
| <div class="thinking-dots flex space-x-1"> | |
| <span class="w-2 h-2 bg-gray-400 rounded-full"></span> | |
| <span class="w-2 h-2 bg-gray-400 rounded-full"></span> | |
| <span class="w-2 h-2 bg-gray-400 rounded-full"></span> | |
| </div> | |
| `; | |
| chatMessages.appendChild(thinkingDiv); | |
| chatMessages.scrollTop = chatMessages.scrollHeight; | |
| } | |
| function removeThinkingIndicator() { | |
| const indicator = document.getElementById('thinking-indicator'); | |
| if (indicator) { | |
| indicator.remove(); | |
| } | |
| } | |
| function simulateAIResponse(question) { | |
| const responses = [ | |
| `I'll help you with: <strong>"${question}"</strong><br><br> | |
| Based on your question, here's what I recommend:<br> | |
| 1. Understand the core concept<br> | |
| 2. Review common patterns<br> | |
| 3. Implement with best practices<br><br> | |
| Would you like me to provide code examples or more detailed explanations?`, | |
| `Great question! For <strong>"${question}"</strong>, the key considerations are:<br> | |
| • Performance implications<br> | |
| • Security best practices<br> | |
| • Maintainability and readability<br><br> | |
| I can generate sample code if you specify a programming language.`, | |
| `Regarding <strong>"${question}"</strong>:<br><br> | |
| This is a common challenge developers face. The solution typically involves:<br> | |
| 1. Proper error handling<br> | |
| 2. Efficient data structures<br> | |
| 3. Following language-specific idioms<br><br> | |
| Want me to dive deeper into any particular aspect?` | |
| ]; | |
| return responses[Math.floor(Math.random() * responses.length)]; | |
| } | |
| // Send message | |
| sendButton.addEventListener('click', function() { | |
| const question = userInput.value.trim(); | |
| if (!question) return; | |
| // Add user message | |
| addMessage(question, true); | |
| userInput.value = ''; | |
| // Show thinking indicator | |
| addThinkingIndicator(); | |
| // Simulate AI thinking | |
| setTimeout(() => { | |
| removeThinkingIndicator(); | |
| // Add AI response | |
| const response = simulateAIResponse(question); | |
| addMessage(response, false); | |
| // Replace feather icons | |
| feather.replace(); | |
| }, 1500 + Math.random() * 1000); | |
| }); | |
| // Enter key to send | |
| userInput.addEventListener('keypress', function(e) { | |
| if (e.key === 'Enter' && !e.shiftKey) { | |
| e.preventDefault(); | |
| sendButton.click(); | |
| } | |
| }); | |
| // Quick question buttons | |
| document.querySelectorAll('.quick-question-btn').forEach(btn => { | |
| btn.addEventListener('click', function() { | |
| userInput.value = this.textContent; | |
| userInput.focus(); | |
| }); | |
| }); | |
| // Clear chat button | |
| document.querySelector('button:has(i[data-feather="trash"])')?.addEventListener('click', function() { | |
| if (confirm('Clear all chat messages?')) { | |
| while (chatMessages.children.length > 1) { | |
| chatMessages.removeChild(chatMessages.lastChild); | |
| } | |
| } | |
| }); | |
| }); | |
| </script> | |
| </body> | |
| </html> |