| Current Path : /var/www/pythonian/qwen/static/ |
| Current File : /var/www/pythonian/qwen/static/chatbot.html |
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Bank Rakyat Assistant</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
<style>
body {
background: linear-gradient(135deg, #f5f7fa 0%, #e4edf5 100%);
padding-top: 20px;
height: 100vh;
margin: 0;
display: flex;
flex-direction: column;
}
.chat-container {
display: flex;
flex-direction: column;
height: 100vh;
max-width: 900px;
margin: 0 auto;
background: white;
border-radius: 15px;
box-shadow: 0 10px 30px rgba(0,0,0,0.1);
overflow: hidden;
}
.chat-header {
background: linear-gradient(90deg, #0d6efd 0%, #0b5ed7 100%);
color: white;
padding: 20px;
text-align: center;
border-bottom: 1px solid #e0e0e0;
}
#chat-messages {
flex: 1;
overflow-y: auto;
padding: 20px;
background-color: #f9fbfd;
display: flex;
flex-direction: column;
}
.message {
max-width: 80%;
margin-bottom: 15px;
display: flex;
}
.user-message {
align-self: flex-end;
}
.bot-message {
align-self: flex-start;
}
.message-content {
padding: 12px 18px;
border-radius: 18px;
box-shadow: 0 2px 6px rgba(0,0,0,0.05);
}
.user-message .message-content {
background: linear-gradient(135deg, #0d6efd 0%, #0b5ed7 100%);
color: white;
border-bottom-right-radius: 5px;
}
.bot-message .message-content {
background: white;
color: #333;
border: 1px solid #e9ecef;
border-bottom-left-radius: 5px;
}
.typing-indicator {
display: none;
align-self: flex-start;
margin-bottom: 15px;
}
.typing-content {
background: white;
padding: 12px 18px;
border-radius: 18px;
border: 1px solid #e9ecef;
border-bottom-left-radius: 5px;
min-height: 45px;
align-items: center;
}
.typing-text {
margin-right: 10px;
color: #6c757d;
font-weight: 500;
}
.typing-dots {
display: flex;
align-items: center;
}
.typing-dot {
width: 10px;
height: 10px;
background-color: #6c757d;
border-radius: 50%;
margin: 0 3px;
animation: typing 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; }
@keyframes typing {
0%, 60%, 100% { transform: translateY(0); }
30% { transform: translateY(-8px); }
}
#input-container {
padding: 20px;
background: white;
border-top: 1px solid #e0e0e0;
}
#user-input {
border-radius: 30px;
padding: 12px 20px;
border: 1px solid #dee2e6;
box-shadow: inset 0 1px 2px rgba(0,0,0,0.05);
}
#user-input:focus {
border-color: #0d6efd;
box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25);
}
.btn-send {
border-radius: 30px;
padding: 10px 25px;
margin-left: 10px;
background: linear-gradient(135deg, #0d6efd 0%, #0b5ed7 100%);
border: none;
}
.btn-send:hover {
background: linear-gradient(135deg, #0b5ed7 0%, #0a56c7 100%);
}
.message-time {
font-size: 0.7rem;
color: #6c757d;
margin-top: 5px;
text-align: right;
}
.user-message .message-time {
color: rgba(255,255,255,0.7);
}
</style>
</head>
<body>
<div class="chat-container">
<div class="chat-header">
<h3><i class="fas fa-robot me-2"></i>Balqis Assistant</h3>
<p class="mb-0">Ask me about Balqis features, setup, or usage</p>
</div>
<div id="chat-messages">
<div class="message bot-message">
<div class="message-content">
Hello! I'm your Balqis assistant. How can I help you today?
<div class="message-time">Just now</div>
</div>
</div>
</div>
<!-- Typing Indicator -->
<div id="typingIndicator" class="typing-indicator">
<div class="typing-content">
<div class="d-flex align-items-center">
<div class="spinner-border spinner-border-sm me-2" role="status" style="color: #6c757d;"></div>
<span class="typing-text">Balqis is thinking...</span>
</div>
</div>
</div>
<div id="input-container" class="d-flex">
<input type="text" id="user-input" class="form-control" placeholder="Ask about Balqis...">
<button id="send-btn" class="btn btn-primary btn-send">
<i class="fas fa-paper-plane me-1"></i> Send
</button>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
<script>
document.addEventListener('DOMContentLoaded', function() {
const chatMessages = document.getElementById('chat-messages');
const userInput = document.getElementById('user-input');
const sendBtn = document.getElementById('send-btn');
const typingIndicator = document.getElementById('typingIndicator');
// Backend endpoint (make sure your Flask app is running on this port)
const BACKEND_ENDPOINT = 'https://aibrqwen.dynaweb4.work/chat';
// Function to call your backend
async function getBotResponse(userMessage) {
// Show typing indicator immediately
showTyping();
// Wait for 2 seconds to show loading clearly
await new Promise(resolve => setTimeout(resolve, 2000));
const response = await fetch(BACKEND_ENDPOINT, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
message: userMessage
})
});
if (!response.ok) {
const errorData = await response.json();
throw new Error(errorData.error || 'API request failed');
}
const data = await response.json();
return data.response;
}
// Function to add message to chat
function addMessage(content, isUser) {
const messageDiv = document.createElement('div');
messageDiv.className = `message ${isUser ? 'user-message' : 'bot-message'}`;
const contentDiv = document.createElement('div');
contentDiv.className = 'message-content';
const textDiv = document.createElement('div');
textDiv.textContent = content;
const timeDiv = document.createElement('div');
timeDiv.className = `message-time`;
const now = new Date();
timeDiv.textContent = `${now.getHours().toString().padStart(2, '0')}:${now.getMinutes().toString().padStart(2, '0')}`;
contentDiv.appendChild(textDiv);
contentDiv.appendChild(timeDiv);
messageDiv.appendChild(contentDiv);
chatMessages.appendChild(messageDiv);
// Scroll to bottom
chatMessages.scrollTop = chatMessages.scrollHeight;
}
// Show typing indicator
function showTyping() {
typingIndicator.style.display = 'block';
chatMessages.scrollTop = chatMessages.scrollHeight;
}
// Hide typing indicator
function hideTyping() {
typingIndicator.style.display = 'none';
}
// Send message handler
async function sendMessage() {
const message = userInput.value.trim();
if (!message) return;
// Add user message
addMessage(message, true);
userInput.value = '';
try {
// Get bot response from backend (includes 2-second delay)
const response = await getBotResponse(message);
// Remove typing indicator
hideTyping();
// Add bot response
addMessage(response, false);
} catch (error) {
// Remove typing indicator
hideTyping();
// Add error message
addMessage('Error: ' + error.message, false);
console.error('API Error:', error);
}
}
// Event listeners
sendBtn.addEventListener('click', sendMessage);
userInput.addEventListener('keypress', (e) => {
if (e.key === 'Enter') {
sendMessage();
}
});
});
</script>
</body>
</html>