Spaces:
Running
Running
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>AI Chatbot</title> | |
| <style> | |
| :root { | |
| --primary-color: #4361ee; | |
| --secondary-color: #3f37c9; | |
| --user-message: #4361ee; | |
| --bot-message: #f8f9fa; | |
| --text-dark: #212529; | |
| --text-light: #f8f9fa; | |
| } | |
| body { | |
| font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; | |
| margin: 0; | |
| padding: 0; | |
| height: 100vh; | |
| display: flex; | |
| flex-direction: column; | |
| background-color: #f1f3f5; | |
| } | |
| .chat-container { | |
| display: flex; | |
| flex-direction: column; | |
| max-width: 800px; | |
| margin: 0 auto; | |
| height: 100vh; | |
| box-shadow: 0 0 20px rgba(0, 0, 0, 0.1); | |
| background-color: white; | |
| } | |
| .chat-header { | |
| background: linear-gradient(135deg, var(--primary-color), var(--secondary-color)); | |
| color: white; | |
| padding: 15px 20px; | |
| display: flex; | |
| justify-content: space-between; | |
| align-items: center; | |
| border-radius: 0 0 10px 10px; | |
| } | |
| .chat-header h1 { | |
| margin: 0; | |
| font-size: 1.5rem; | |
| } | |
| .status { | |
| display: flex; | |
| align-items: center; | |
| gap: 8px; | |
| } | |
| .status-indicator { | |
| width: 10px; | |
| height: 10px; | |
| border-radius: 50%; | |
| background-color: #4ade80; | |
| } | |
| .status-text { | |
| font-size: 0.9rem; | |
| } | |
| .chat-messages { | |
| flex: 1; | |
| padding: 20px; | |
| overflow-y: auto; | |
| display: flex; | |
| flex-direction: column; | |
| gap: 15px; | |
| } | |
| .message { | |
| max-width: 70%; | |
| padding: 12px 15px; | |
| border-radius: 18px; | |
| font-size: 0.95rem; | |
| line-height: 1.4; | |
| animation: fadeIn 0.3s ease-out; | |
| position: relative; | |
| } | |
| .user-message { | |
| align-self: flex-end; | |
| background-color: var(--user-message); | |
| color: var(--text-light); | |
| border-bottom-right-radius: 5px; | |
| } | |
| .bot-message { | |
| align-self: flex-start; | |
| background-color: var(--bot-message); | |
| color: var(--text-dark); | |
| border: 1px solid #dee2e6; | |
| border-bottom-left-radius: 5px; | |
| } | |
| .timestamp { | |
| font-size: 0.7rem; | |
| opacity: 0.7; | |
| margin-top: 5px; | |
| text-align: right; | |
| } | |
| .typing-indicator { | |
| display: inline-flex; | |
| gap: 5px; | |
| padding: 12px 15px; | |
| background-color: var(--bot-message); | |
| border-radius: 18px; | |
| align-self: flex-start; | |
| border: 1px solid #dee2e6; | |
| } | |
| .typing-dot { | |
| width: 8px; | |
| height: 8px; | |
| background-color: #6c757d; | |
| border-radius: 50%; | |
| animation: typingAnimation 1.4s infinite ease-in-out; | |
| } | |
| .typing-dot:nth-child(1) { animation-delay: 0s; } | |
| .typing-dot:nth-child(2) { animation-delay: 0.2s; } | |
| .typing-dot:nth-child(3) { animation-delay: 0.4s; } | |
| .input-area { | |
| display: flex; | |
| padding: 15px; | |
| border-top: 1px solid #dee2e6; | |
| background-color: white; | |
| } | |
| .message-input { | |
| flex: 1; | |
| padding: 12px 15px; | |
| border: 1px solid #dee2e6; | |
| border-radius: 24px; | |
| font-size: 0.95rem; | |
| outline: none; | |
| transition: border-color 0.3s; | |
| } | |
| .message-input:focus { | |
| border-color: var(--primary-color); | |
| } | |
| .send-button { | |
| background-color: var(--primary-color); | |
| color: white; | |
| border: none; | |
| border-radius: 50%; | |
| width: 48px; | |
| height: 48px; | |
| margin-left: 10px; | |
| cursor: pointer; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| transition: background-color 0.3s; | |
| } | |
| .send-button:hover { | |
| background-color: var(--secondary-color); | |
| } | |
| .send-icon { | |
| width: 20px; | |
| height: 20px; | |
| } | |
| @keyframes fadeIn { | |
| from { opacity: 0; transform: translateY(10px); } | |
| to { opacity: 1; transform: translateY(0); } | |
| } | |
| @keyframes typingAnimation { | |
| 0%, 60%, 100% { transform: translateY(0); } | |
| 30% { transform: translateY(-5px); } | |
| } | |
| .agent-select { | |
| padding: 5px 10px; | |
| border-radius: 15px; | |
| border: 1px solid rgba(255,255,255,0.3); | |
| background-color: rgba(255,255,255,0.1); | |
| color: white; | |
| margin-left: 10px; | |
| font-size: 0.9rem; | |
| } | |
| .history-button { | |
| background: none; | |
| border: none; | |
| color: var(--primary-color); | |
| padding: 10px; | |
| cursor: pointer; | |
| border-radius: 50%; | |
| transition: background-color 0.2s; | |
| } | |
| .history-button:hover { | |
| background-color: rgba(0,0,0,0.05); | |
| } | |
| /* History modal styles */ | |
| .history-modal { | |
| position: fixed; | |
| top: 0; | |
| left: 0; | |
| right: 0; | |
| bottom: 0; | |
| background: rgba(0,0,0,0.5); | |
| display: none; | |
| z-index: 100; | |
| padding: 20px; | |
| } | |
| .history-content { | |
| background: white; | |
| max-width: 600px; | |
| margin: 20px auto; | |
| padding: 20px; | |
| border-radius: 10px; | |
| max-height: 80vh; | |
| overflow-y: auto; | |
| } | |
| @media (max-width: 768px) { | |
| .chat-container { | |
| max-width: 100%; | |
| border-radius: 0; | |
| } | |
| .message { | |
| max-width: 85%; | |
| } | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <div class="chat-container"> | |
| <div class="chat-header"> | |
| <h1 id="agent-title">AI Assistant</h1> | |
| <select id="agent-selector" class="agent-select"> | |
| <option value="general">General Assistant</option> | |
| <option value="tech">Tech Support</option> | |
| <option value="sales">Sales Agent</option> | |
| </select> | |
| <div class="status"> | |
| <div class="status-indicator"></div> | |
| <span class="status-text">Online</span> | |
| </div> | |
| </div> | |
| <div class="chat-messages" id="chat-messages"> | |
| <!-- Messages will be added here dynamically --> | |
| <div class="message bot-message"> | |
| Hello! I'm your General Assistant. How can I help you today? | |
| <div class="timestamp">Just now</div> | |
| </div> | |
| </div> | |
| <div class="input-area"> | |
| <button id="history-button" class="history-button" title="View chat history" style="margin-right: 10px;"> | |
| <svg viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor"> | |
| <path d="M3 3v18h18M7 16l4-4-4-4m6 8l4-4-4-4"/> | |
| </svg> | |
| </button> | |
| <input type="text" class="message-input" id="user-input" placeholder="Type your message..." autocomplete="off"> | |
| <button class="send-button" id="send-button"> | |
| <svg class="send-icon" viewBox="0 0 24 24"> | |
| <path fill="currentColor" d="M2,21L23,12L2,3V10L17,12L2,14V21Z" /> | |
| </svg> | |
| </button> | |
| </div> | |
| </div> | |
| <!-- History Modal --> | |
| <div class="history-modal" id="history-modal"> | |
| <div class="history-content"> | |
| <h2>Chat History</h2> | |
| <div id="history-list"></div> | |
| <button id="close-history" class="history-close">Close</button> | |
| </div> | |
| </div> | |
| <script> | |
| const chatMessages = document.getElementById('chat-messages'); | |
| const userInput = document.getElementById('user-input'); | |
| const sendButton = document.getElementById('send-button'); | |
| // Chat state and configuration | |
| let chatState = { | |
| agent: 'general', | |
| history: [] | |
| }; | |
| // Agent configurations | |
| const agents = { | |
| general: { | |
| name: "General Assistant", | |
| responses: [ | |
| "I can help with general questions. How may I assist you today?", | |
| "I'm your general assistant. What do you need help with?" | |
| ] | |
| }, | |
| tech: { | |
| name: "Tech Support", | |
| responses: [ | |
| "I specialize in technology support. What technical issue can I help with?", | |
| "For technical issues, try restarting first. What's the specific problem?" | |
| ] | |
| }, | |
| sales: { | |
| name: "Sales Agent", | |
| responses: [ | |
| "I can help with product questions and purchases. What are you interested in?", | |
| "We have great deals today! How can I assist with your purchase?" | |
| ] | |
| } | |
| }; | |
| // DOM elements | |
| const agentTitle = document.getElementById('agent-title'); | |
| const agentSelector = document.getElementById('agent-selector'); | |
| const historyButton = document.getElementById('history-button'); | |
| const historyModal = document.getElementById('history-modal'); | |
| const historyList = document.getElementById('history-list'); | |
| // Add a message to the chat | |
| function addMessage(text, isUser) { | |
| const messageDiv = document.createElement('div'); | |
| messageDiv.classList.add('message'); | |
| messageDiv.classList.add(isUser ? 'user-message' : 'bot-message'); | |
| const textNode = document.createTextNode(text); | |
| messageDiv.appendChild(textNode); | |
| // Add timestamp | |
| const timestamp = document.createElement('div'); | |
| timestamp.classList.add('timestamp'); | |
| const now = new Date(); | |
| timestamp.textContent = now.toLocaleTimeString([], {hour: '2-digit', minute:'2-digit'}); | |
| messageDiv.appendChild(timestamp); | |
| chatMessages.appendChild(messageDiv); | |
| chatMessages.scrollTop = chatMessages.scrollHeight; | |
| return messageDiv; | |
| } | |
| // Show typing indicator | |
| function showTypingIndicator() { | |
| const typingDiv = document.createElement('div'); | |
| typingDiv.classList.add('typing-indicator'); | |
| typingDiv.id = 'typing-indicator'; | |
| for (let i = 0; i < 3; i++) { | |
| const dot = document.createElement('div'); | |
| dot.classList.add('typing-dot'); | |
| typingDiv.appendChild(dot); | |
| } | |
| chatMessages.appendChild(typingDiv); | |
| chatMessages.scrollTop = chatMessages.scrollHeight; | |
| return typingDiv; | |
| } | |
| // Remove typing indicator | |
| function removeTypingIndicator() { | |
| const typingIndicator = document.getElementById('typing-indicator'); | |
| if (typingIndicator) { | |
| typingIndicator.remove(); | |
| } | |
| } | |
| // Get agent-specific response | |
| function getBotResponse() { | |
| const agent = agents[chatState.agent]; | |
| return agent.responses[Math.floor(Math.random() * agent.responses.length)]; | |
| } | |
| // Handle sending a message | |
| function sendMessage() { | |
| const message = userInput.value.trim(); | |
| if (message === '') return; | |
| // Add user message | |
| addMessage(message, true); | |
| userInput.value = ''; | |
| // Show typing indicator | |
| const typing = showTypingIndicator(); | |
| // Simulate bot thinking | |
| setTimeout(() => { | |
| removeTypingIndicator(); | |
| // Add bot response | |
| const response = getBotResponse(); | |
| addMessage(response, false); | |
| }, 1500 + Math.random() * 2000); | |
| } | |
| // Event listeners | |
| sendButton.addEventListener('click', sendMessage); | |
| userInput.addEventListener('keypress', (e) => { | |
| if (e.key === 'Enter') { | |
| sendMessage(); | |
| } | |
| }); | |
| // Agent selector change handler | |
| agentSelector.addEventListener('change', (e) => { | |
| chatState.agent = e.target.value; | |
| agentTitle.textContent = agents[chatState.agent].name; | |
| addMessage(`Agent changed to ${agents[chatState.agent].name}`, false); | |
| }); | |
| // History button click handler | |
| historyButton.addEventListener('click', showHistory); | |
| document.getElementById('close-history').addEventListener('click', hideHistory); | |
| // Show conversation history | |
| function showHistory() { | |
| historyList.innerHTML = chatState.history.map(entry => | |
| `<div class="history-entry"> | |
| <span class="history-time">${new Date(entry.time).toLocaleString()}</span> | |
| <strong>${entry.role === 'user' ? 'You' : 'AI'}:</strong> ${entry.text} | |
| </div>` | |
| ).join(''); | |
| historyModal.style.display = 'block'; | |
| } | |
| function hideHistory() { | |
| historyModal.style.display = 'none'; | |
| } | |
| // Modified addMessage to track history | |
| function addMessage(text, isUser) { | |
| const messageDiv = document.createElement('div'); | |
| messageDiv.classList.add('message'); | |
| messageDiv.classList.add(isUser ? 'user-message' : 'bot-message'); | |
| const textNode = document.createTextNode(text); | |
| messageDiv.appendChild(textNode); | |
| const timestamp = document.createElement('div'); | |
| timestamp.classList.add('timestamp'); | |
| const now = new Date(); | |
| timestamp.textContent = now.toLocaleTimeString([], {hour: '2-digit', minute:'2-digit'}); | |
| messageDiv.appendChild(timestamp); | |
| chatMessages.appendChild(messageDiv); | |
| chatMessages.scrollTop = chatMessages.scrollHeight; | |
| // Save to history | |
| chatState.history.push({ | |
| text: text, | |
| role: isUser ? 'user' : 'bot', | |
| time: now.getTime() | |
| }); | |
| return messageDiv; | |
| } | |
| // Get agent-specific response | |
| function getBotResponse() { | |
| const agent = agents[chatState.agent]; | |
| return agent.responses[Math.floor(Math.random() * agent.responses.length)]; | |
| } | |
| // Initial greeting | |
| window.addEventListener('load', () => { | |
| chatState.history.push({ | |
| text: "Hello! I'm your General Assistant. How can I help you today?", | |
| role: 'bot', | |
| time: Date.now() | |
| }); | |
| chatMessages.scrollTop = chatMessages.scrollHeight; | |
| }); | |
| </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=alterzick/chatbot-v1" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> | |
| </html> | |
| ``` |