|
<!DOCTYPE html> |
|
<html lang="ar" dir="rtl"> |
|
<head> |
|
<meta charset="UTF-8"> |
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
|
<title>سبيدي - المساعد الذكي</title> |
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css"> |
|
<style> |
|
* { |
|
margin: 0; |
|
padding: 0; |
|
box-sizing: border-box; |
|
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; |
|
} |
|
|
|
body { |
|
background-color: #f0f2f5; |
|
height: 100vh; |
|
display: flex; |
|
flex-direction: column; |
|
} |
|
|
|
.chat-header { |
|
background-color: #ffffff; |
|
padding: 15px 20px; |
|
box-shadow: 0 2px 5px rgba(0,0,0,0.1); |
|
display: flex; |
|
align-items: center; |
|
justify-content: space-between; |
|
} |
|
|
|
.chat-header h1 { |
|
color: #1a1a1a; |
|
font-size: 1.5rem; |
|
display: flex; |
|
align-items: center; |
|
gap: 10px; |
|
} |
|
|
|
.chat-header .bot-status { |
|
background-color: #4CAF50; |
|
padding: 5px 10px; |
|
border-radius: 15px; |
|
color: white; |
|
font-size: 0.8rem; |
|
} |
|
|
|
.chat-container { |
|
flex: 1; |
|
padding: 20px; |
|
overflow-y: auto; |
|
display: flex; |
|
flex-direction: column; |
|
gap: 15px; |
|
} |
|
|
|
.message { |
|
max-width: 80%; |
|
padding: 12px 16px; |
|
border-radius: 15px; |
|
position: relative; |
|
animation: fadeIn 0.3s ease-in-out; |
|
} |
|
|
|
@keyframes fadeIn { |
|
from { opacity: 0; transform: translateY(10px); } |
|
to { opacity: 1; transform: translateY(0); } |
|
} |
|
|
|
.user-message { |
|
background-color: #0084ff; |
|
color: white; |
|
margin-left: auto; |
|
border-bottom-right-radius: 5px; |
|
} |
|
|
|
.bot-message { |
|
background-color: #f0f0f0; |
|
color: #1a1a1a; |
|
margin-right: auto; |
|
border-bottom-left-radius: 5px; |
|
} |
|
|
|
.message-time { |
|
font-size: 0.7rem; |
|
opacity: 0.7; |
|
margin-top: 5px; |
|
text-align: left; |
|
} |
|
|
|
.input-area { |
|
background-color: #ffffff; |
|
padding: 15px 20px; |
|
box-shadow: 0 -2px 5px rgba(0,0,0,0.1); |
|
} |
|
|
|
.input-container { |
|
display: flex; |
|
gap: 10px; |
|
max-width: 1200px; |
|
margin: 0 auto; |
|
} |
|
|
|
.message-input { |
|
flex: 1; |
|
padding: 12px; |
|
border: 1px solid #ddd; |
|
border-radius: 20px; |
|
outline: none; |
|
font-size: 1rem; |
|
transition: border-color 0.3s; |
|
} |
|
|
|
.message-input:focus { |
|
border-color: #0084ff; |
|
} |
|
|
|
.send-button { |
|
background-color: #0084ff; |
|
color: white; |
|
border: none; |
|
border-radius: 50%; |
|
width: 45px; |
|
height: 45px; |
|
cursor: pointer; |
|
display: flex; |
|
align-items: center; |
|
justify-content: center; |
|
transition: background-color 0.3s; |
|
} |
|
|
|
.send-button:hover { |
|
background-color: #0073e6; |
|
} |
|
|
|
.send-button:disabled { |
|
background-color: #cccccc; |
|
cursor: not-allowed; |
|
} |
|
|
|
.suggestions { |
|
display: flex; |
|
gap: 10px; |
|
margin-top: 10px; |
|
flex-wrap: wrap; |
|
justify-content: center; |
|
} |
|
|
|
.suggestion-chip { |
|
background-color: #e8f0fe; |
|
color: #1a73e8; |
|
padding: 8px 16px; |
|
border-radius: 16px; |
|
cursor: pointer; |
|
font-size: 0.9rem; |
|
transition: background-color 0.3s; |
|
border: none; |
|
} |
|
|
|
.suggestion-chip:hover { |
|
background-color: #d2e3fc; |
|
} |
|
|
|
.typing-indicator { |
|
display: none; |
|
padding: 12px 16px; |
|
background-color: #f0f0f0; |
|
border-radius: 15px; |
|
margin-right: auto; |
|
color: #666; |
|
font-size: 0.9rem; |
|
} |
|
|
|
.typing-indicator.visible { |
|
display: inline-block; |
|
} |
|
|
|
.error-message { |
|
background-color: #ffebee; |
|
color: #c62828; |
|
padding: 12px 16px; |
|
border-radius: 15px; |
|
margin-right: auto; |
|
max-width: 80%; |
|
font-size: 0.9rem; |
|
} |
|
|
|
</style> |
|
</head> |
|
<body> |
|
<div class="chat-header"> |
|
<h1> |
|
<i class="fas fa-robot"></i> |
|
سبيدي |
|
<span class="bot-status">متصل</span> |
|
</h1> |
|
<div class="header-actions"> |
|
<button onclick="clearChat()" class="suggestion-chip"> |
|
<i class="fas fa-trash"></i> |
|
مسح المحادثة |
|
</button> |
|
</div> |
|
</div> |
|
|
|
<div class="chat-container" id="chat-container"></div> |
|
|
|
<div class="input-area"> |
|
<div class="input-container"> |
|
<input type="text" |
|
class="message-input" |
|
id="message-input" |
|
placeholder="اكتب رسالتك هنا..." |
|
autocomplete="off"> |
|
<button class="send-button" onclick="sendMessage()" id="send-button"> |
|
<i class="fas fa-paper-plane"></i> |
|
</button> |
|
</div> |
|
<div class="suggestions"> |
|
<button class="suggestion-chip" onclick="sendSuggestion('كيف يمكنني تعلم البرمجة؟')"> |
|
تعلم البرمجة |
|
</button> |
|
<button class="suggestion-chip" onclick="sendSuggestion('ما هي أفضل لغة برمجة للمبتدئين؟')"> |
|
أفضل لغة برمجة |
|
</button> |
|
<button class="suggestion-chip" onclick="sendSuggestion('ما هي الذكاء الاصطناعي؟')"> |
|
الذكاء الاصطناعي |
|
</button> |
|
<button class="suggestion-chip" onclick="sendSuggestion('كيف أبدأ مشروعي الخاص؟')"> |
|
بدء مشروع |
|
</button> |
|
</div> |
|
</div> |
|
|
|
<script> |
|
let isProcessing = false; |
|
|
|
function getCurrentTime() { |
|
const now = new Date(); |
|
return now.toLocaleTimeString('ar-SA', { |
|
hour: '2-digit', |
|
minute: '2-digit' |
|
}); |
|
} |
|
|
|
function appendMessage(message, isUser = false) { |
|
const chatContainer = document.getElementById('chat-container'); |
|
const messageDiv = document.createElement('div'); |
|
messageDiv.className = `message ${isUser ? 'user-message' : 'bot-message'}`; |
|
|
|
const messageContent = document.createElement('div'); |
|
messageContent.textContent = message; |
|
|
|
const timeDiv = document.createElement('div'); |
|
timeDiv.className = 'message-time'; |
|
timeDiv.textContent = getCurrentTime(); |
|
|
|
messageDiv.appendChild(messageContent); |
|
messageDiv.appendChild(timeDiv); |
|
|
|
chatContainer.appendChild(messageDiv); |
|
chatContainer.scrollTop = chatContainer.scrollHeight; |
|
} |
|
|
|
function showTypingIndicator() { |
|
const chatContainer = document.getElementById('chat-container'); |
|
const typingDiv = document.createElement('div'); |
|
typingDiv.className = 'typing-indicator'; |
|
typingDiv.id = 'typing-indicator'; |
|
typingDiv.innerHTML = 'سبيدي يكتب <i class="fas fa-ellipsis-h"></i>'; |
|
chatContainer.appendChild(typingDiv); |
|
chatContainer.scrollTop = chatContainer.scrollHeight; |
|
} |
|
|
|
function removeTypingIndicator() { |
|
const typingIndicator = document.getElementById('typing-indicator'); |
|
if (typingIndicator) { |
|
typingIndicator.remove(); |
|
} |
|
} |
|
|
|
async function sendMessage() { |
|
if (isProcessing) return; |
|
|
|
const input = document.getElementById('message-input'); |
|
const message = input.value.trim(); |
|
const sendButton = document.getElementById('send-button'); |
|
|
|
if (message === '') return; |
|
|
|
isProcessing = true; |
|
sendButton.disabled = true; |
|
input.value = ''; |
|
|
|
appendMessage(message, true); |
|
showTypingIndicator(); |
|
|
|
try { |
|
const response = await fetch('/message', { |
|
method: 'POST', |
|
headers: { |
|
'Content-Type': 'application/json', |
|
}, |
|
body: JSON.stringify({ message: message }) |
|
}); |
|
|
|
if (!response.ok) { |
|
throw new Error('Network response was not ok'); |
|
} |
|
|
|
const data = await response.json(); |
|
removeTypingIndicator(); |
|
appendMessage(data.response); |
|
} catch (error) { |
|
removeTypingIndicator(); |
|
const errorDiv = document.createElement('div'); |
|
errorDiv.className = 'error-message'; |
|
errorDiv.textContent = 'عذراً، حدث خطأ في الاتصال. يرجى المحاولة مرة أخرى.'; |
|
document.getElementById('chat-container').appendChild(errorDiv); |
|
} finally { |
|
isProcessing = false; |
|
sendButton.disabled = false; |
|
input.focus(); |
|
} |
|
} |
|
|
|
function sendSuggestion(suggestion) { |
|
const input = document.getElementById('message-input'); |
|
input.value = suggestion; |
|
sendMessage(); |
|
} |
|
|
|
function clearChat() { |
|
const chatContainer = document.getElementById('chat-container'); |
|
chatContainer.innerHTML = ''; |
|
|
|
appendMessage('مرحباً بك! كيف يمكنني مساعدتك اليوم؟'); |
|
} |
|
|
|
|
|
document.getElementById('message-input').addEventListener('keypress', function(e) { |
|
if (e.key === 'Enter' && !isProcessing) { |
|
sendMessage(); |
|
} |
|
}); |
|
|
|
|
|
window.onload = function() { |
|
appendMessage('مرحباً بك! كيف يمكنني مساعدتك اليوم؟'); |
|
}; |
|
</script> |
|
</body> |
|
</html> |