Spaces:
Sleeping
Sleeping
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css"> | |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css"> | |
| <style> | |
| body { | |
| font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; | |
| background-color: #f4f7fb; | |
| margin: 0; | |
| padding: 0; | |
| } | |
| #chat-container { | |
| max-width: 500px; | |
| margin: auto; | |
| padding: 25px; | |
| border-radius: 15px; | |
| background-color: #fff; | |
| box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1); | |
| position: relative; | |
| } | |
| #chat-history { | |
| height: 400px; | |
| overflow-y: auto; | |
| padding: 15px; | |
| background: linear-gradient(135deg, #f3f4f8 0%, #d3e0f0 100%); | |
| border-radius: 15px; | |
| box-shadow: inset 0 0 10px rgba(0, 0, 0, 0.1); | |
| margin-bottom: 15px; | |
| } | |
| .message { | |
| padding: 12px 15px; | |
| margin: 10px 0; | |
| border-radius: 20px; | |
| font-size: 0.9em; | |
| line-height: 1.4em; | |
| position: relative; | |
| cursor: pointer; | |
| transition: background-color 0.3s; | |
| } | |
| .user-message { | |
| background: linear-gradient(135deg, #c9e6f5 0%, #91c9e6 100%); | |
| color: #006c8e; | |
| margin-left: auto; | |
| border-radius: 20px 20px 0 20px; | |
| } | |
| .bot-message { | |
| background: linear-gradient(135deg, #fce0e0 0%, #85cfb6 100%); | |
| color: #8b3e40; | |
| margin-right: auto; | |
| border-radius: 20px 20px 20px 0; | |
| } | |
| .user-icon, .bot-icon { | |
| margin-right: 10px; | |
| font-size: 1.2em; | |
| } | |
| #loading { | |
| display: none; | |
| margin: 15px 0; | |
| text-align: center; | |
| font-size: 1.2em; | |
| } | |
| #user-input { | |
| border: 1px solid #ddd; | |
| border-radius: 8px; | |
| resize: none; | |
| padding: 12px; | |
| font-size: 1em; | |
| width: calc(100% - 48px); | |
| } | |
| #user-input:focus { | |
| border-color: #007bff; | |
| outline: none; | |
| } | |
| .btn-send { | |
| background-color: #007bff; | |
| color: white; | |
| border-radius: 8px; | |
| padding: 10px 15px; | |
| border: none; | |
| cursor: pointer; | |
| font-size: 1.1em; | |
| transition: background-color 0.3s; | |
| } | |
| .btn-send:hover { | |
| background-color: #0056b3; | |
| } | |
| .btn-close { | |
| position: absolute; | |
| top: 12px; | |
| right: 12px; | |
| background-color: #dc3545; | |
| color: white; | |
| border: none; | |
| border-radius: 50%; | |
| width: 30px; | |
| height: 30px; | |
| font-size: 1.2em; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| cursor: pointer; | |
| transition: background-color 0.3s; | |
| } | |
| .btn-close:hover { | |
| background-color: #c82333; | |
| } | |
| .typing-indicator { | |
| font-style: italic; | |
| color: #888; | |
| margin-top: 10px; | |
| } | |
| .timestamp { | |
| font-size: 0.75em; | |
| color: #999; | |
| display: none; | |
| margin-top: 5px; | |
| } | |
| </style> | |
| <title>Chat Interface</title> | |
| </head> | |
| <body> | |
| <div id="chat-container" class="rounded p-4 shadow"> | |
| <input type="hidden" id="user-id" value="{{ user_id }}"> | |
| <button type="button" id="close-button" class="btn-close" aria-label="Close chat"> | |
| <i class="fas fa-times"></i> | |
| </button> | |
| <div id="chat-history" class="mb-3"></div> | |
| <div class="input-group mb-2"> | |
| <textarea id="user-input" class="form-control" rows="2" placeholder="Type your message..." aria-label="Message input"></textarea> | |
| <div class="input-group-append"> | |
| <button id="send-button" class="btn-send" aria-label="Send message"> | |
| <i class="fas fa-paper-plane"></i> | |
| </button> | |
| </div> | |
| </div> | |
| <small class="form-text text-muted">Press Shift + Enter for a new line</small> | |
| </div> | |
| <script> | |
| let chatHistoryArray = []; | |
| document.getElementById("send-button").addEventListener("click", sendMessage); | |
| document.getElementById("user-input").addEventListener("keypress", function(event) { | |
| if (event.key === "Enter" && !event.shiftKey) { | |
| event.preventDefault(); | |
| sendMessage(); | |
| } | |
| }); | |
| document.getElementById("close-button").addEventListener("click", closeChat); | |
| window.addEventListener('DOMContentLoaded', () => { | |
| sendInitialBotMessage(); | |
| }); | |
| function sendInitialBotMessage() { | |
| const userId = document.getElementById("user-id").value; | |
| const initialMessage = "Hello! How can I assist you today?"; | |
| addMessage("Bot", initialMessage, "bot-message"); | |
| chatHistoryArray.push({ userId, sender: "Bot", message: initialMessage }); | |
| } | |
| async function sendMessage() { | |
| const input = document.getElementById("user-input"); | |
| const userId = document.getElementById("user-id").value; | |
| const message = input.value.trim(); | |
| if (message === "") return; | |
| addMessage("User", message, "user-message"); | |
| chatHistoryArray.push({ userId, sender: "User", message }); | |
| input.value = ""; | |
| showTypingIndicator(); | |
| try { | |
| const response = await fetch("/chat/", { | |
| method: "POST", | |
| headers: { "Content-Type": "application/json" }, | |
| body: JSON.stringify({ message }) | |
| }); | |
| if (!response.ok) throw new Error(`HTTP error! Status: ${response.status}`); | |
| const data = await response.json(); | |
| addMessage("Bot", data.response, "bot-message"); | |
| chatHistoryArray.push({ userId, sender: "Bot", message: data.response }); | |
| } catch (error) { | |
| console.error('Error:', error); | |
| addMessage("Bot", "Sorry, something went wrong.", "bot-message"); | |
| } finally { | |
| hideTypingIndicator(); | |
| } | |
| } | |
| async function closeChat() { | |
| const userId = document.getElementById("user-id").value; | |
| try { | |
| await fetch("/hist/", { | |
| method: "POST", | |
| headers: { "Content-Type": "application/json" }, | |
| body: JSON.stringify({ history: chatHistoryArray, userId }) | |
| }); | |
| } catch (error) { | |
| console.error('Error sending chat history on close:', error); | |
| } finally { | |
| window.top.location.href = 'https://redfernstech.com/'; | |
| } | |
| } | |
| function addMessage(sender, message, className) { | |
| const chatHistory = document.getElementById("chat-history"); | |
| const messageElement = document.createElement("div"); | |
| messageElement.className = `message ${className}`; | |
| const linkRegex = /(https?:\/\/[^\s]+)/g; | |
| const formattedMessage = message.replace(linkRegex, function(url) { | |
| let linkText = url.includes("salesforce") ? "Click here" : "Visit this link."; | |
| return `<a href="${url}" target="_blank">${linkText}</a>`; | |
| }); | |
| messageElement.innerHTML = `<span class="${sender.toLowerCase()}-icon"> | |
| ${sender === "User" ? '<i class="fas fa-user"></i>' : '<img src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTa1q4s76cKilDcBElngWUNlMagmp18HjhF5A&s" alt="Bot" style="width: 20px; height: 20px; border-radius: 50%;">'} | |
| </span>${formattedMessage}<div class="timestamp">${new Date().toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })}</div>`; | |
| chatHistory.appendChild(messageElement); | |
| chatHistory.scrollTop = chatHistory.scrollHeight; | |
| } | |
| function showTypingIndicator() { | |
| const chatHistory = document.getElementById("chat-history"); | |
| const typingIndicator = document.createElement("div"); | |
| typingIndicator.className = "typing-indicator"; | |
| typingIndicator.id = "typing-indicator"; | |
| typingIndicator.innerText = "Bot is typing..."; | |
| chatHistory.appendChild(typingIndicator); | |
| chatHistory.scrollTop = chatHistory.scrollHeight; | |
| } | |
| function hideTypingIndicator() { | |
| const typingIndicator = document.getElementById("typing-indicator"); | |
| if (typingIndicator) typingIndicator.remove(); | |
| } | |
| </script> | |
| </body> | |
| </html> | |