chatbot-v1 / index.html
alterzick's picture
undefined - Initial Deployment
fbb0415 verified
<!DOCTYPE html>
<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>
```