| <!DOCTYPE html> |
| <html lang="en"> |
| <head> |
| <meta charset="UTF-8"> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| <title>Kidney Key Chat</title> |
| <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet"> |
| <style> |
| body { |
| background: linear-gradient(135deg, #e0eafc 0%, #cfdef3 100%); |
| min-height: 100vh; |
| } |
| .app-container { |
| max-width: 700px; |
| margin: 40px auto; |
| background: #fff; |
| border-radius: 18px; |
| box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.18); |
| padding: 32px 28px 24px 28px; |
| } |
| .chat-container { |
| height: 400px; |
| overflow-y: auto; |
| border: 1.5px solid #b6c6e0; |
| padding: 24px 18px; |
| margin-bottom: 24px; |
| border-radius: 12px; |
| background: #f8fbff; |
| } |
| .message { |
| margin-bottom: 18px; |
| padding: 14px 18px; |
| border-radius: 12px; |
| font-size: 1.08rem; |
| line-height: 1.5; |
| max-width: 80%; |
| word-break: break-word; |
| box-shadow: 0 2px 8px rgba(80, 120, 200, 0.07); |
| } |
| .user-message { |
| background: linear-gradient(90deg, #a1c4fd 0%, #c2e9fb 100%); |
| color: #1a237e; |
| margin-left: auto; |
| text-align: right; |
| } |
| .bot-message { |
| background: linear-gradient(90deg, #fbc2eb 0%, #a6c1ee 100%); |
| color: #4a148c; |
| margin-right: auto; |
| text-align: left; |
| } |
| .loading { |
| display: none; |
| text-align: center; |
| margin: 10px 0; |
| } |
| .sms-button { |
| margin-top: 10px; |
| } |
| .app-title { |
| font-family: 'Segoe UI', 'Roboto', Arial, sans-serif; |
| font-weight: 700; |
| font-size: 2.3rem; |
| color: #283593; |
| letter-spacing: 1px; |
| } |
| .app-desc { |
| font-size: 1.08rem; |
| color: #374151; |
| margin-bottom: 28px; |
| margin-top: 8px; |
| background: #e3f0ff; |
| border-radius: 8px; |
| padding: 12px 18px; |
| } |
| .input-group input { |
| font-size: 1.08rem; |
| border-radius: 8px 0 0 8px; |
| } |
| .input-group .btn-primary { |
| border-radius: 0 8px 8px 0; |
| font-weight: 600; |
| background: linear-gradient(90deg, #43cea2 0%, #185a9d 100%); |
| border: none; |
| } |
| .input-group .btn-primary:hover { |
| background: linear-gradient(90deg, #185a9d 0%, #43cea2 100%); |
| } |
| .btn-success.sms-button { |
| background: linear-gradient(90deg, #f7971e 0%, #ffd200 100%); |
| color: #333; |
| border: none; |
| font-weight: 600; |
| } |
| .btn-success.sms-button:hover { |
| background: linear-gradient(90deg, #ffd200 0%, #f7971e 100%); |
| color: #222; |
| } |
| @media (max-width: 600px) { |
| .app-container { |
| padding: 10px 2px 18px 2px; |
| } |
| .chat-container { |
| padding: 10px 4px; |
| } |
| } |
| </style> |
| </head> |
| <body> |
| <div class="app-container"> |
| <h1 class="text-center app-title mb-2">Kidney Key Chat</h1> |
| <div class="app-desc text-center"> |
| <strong>What is this?</strong> <br> |
| Kidney Key Chat is an AI-powered assistant designed to help healthcare professionals and patients with questions about renal dosing, dialysis, and medication adjustments for kidney function. <br><br> |
| <strong>How does it work?</strong> <br> |
| Just type your question below (e.g., "How do you dose amoxicillin in CKD?"). The app uses Retrieval-Augmented Generation (RAG) to search a curated knowledge base of clinical PDFs, finds the most relevant information, and generates a clear, referenced answer. You can also send the chatbot's response to your phone via SMS for easy reference. |
| </div> |
| <div class="chat-container" id="chatContainer"> |
| |
| </div> |
| <div class="loading" id="loading"> |
| <div class="spinner-border text-primary" role="status"> |
| <span class="visually-hidden">Loading...</span> |
| </div> |
| </div> |
| <div class="input-group mb-3"> |
| <input type="text" id="userInput" class="form-control" placeholder="Type your question here..."> |
| <button class="btn btn-primary" onclick="sendMessage()">Send</button> |
| </div> |
| <div class="text-center"> |
| <button class="btn btn-success sms-button" onclick="sendLastResponse()" id="smsButton" style="display: none;"> |
| Send Last Response via SMS |
| </button> |
| </div> |
| </div> |
| <script> |
| let lastBotResponse = ''; |
| function addMessage(message, isUser) { |
| const chatContainer = document.getElementById('chatContainer'); |
| const messageDiv = document.createElement('div'); |
| messageDiv.className = `message ${isUser ? 'user-message' : 'bot-message'}`; |
| messageDiv.textContent = message; |
| chatContainer.appendChild(messageDiv); |
| chatContainer.scrollTop = chatContainer.scrollHeight; |
| } |
| function showLoading() { |
| document.getElementById('loading').style.display = 'block'; |
| } |
| function hideLoading() { |
| document.getElementById('loading').style.display = 'none'; |
| } |
| async function sendMessage() { |
| const userInput = document.getElementById('userInput'); |
| const message = userInput.value.trim(); |
| if (!message) return; |
| addMessage(message, true); |
| userInput.value = ''; |
| showLoading(); |
| try { |
| const response = await fetch('/chat', { |
| method: 'POST', |
| headers: { |
| 'Content-Type': 'application/json', |
| }, |
| body: JSON.stringify({ question: message }), |
| }); |
| const data = await response.json(); |
| if (response.ok) { |
| lastBotResponse = data.answer; |
| addMessage(data.answer, false); |
| document.getElementById('smsButton').style.display = 'inline-block'; |
| } else { |
| addMessage('Error: ' + data.error, false); |
| } |
| } catch (error) { |
| addMessage('Error: Could not connect to the server', false); |
| } finally { |
| hideLoading(); |
| } |
| } |
| async function sendLastResponse() { |
| if (!lastBotResponse) return; |
| showLoading(); |
| try { |
| const response = await fetch('/send-sms', { |
| method: 'POST', |
| headers: { |
| 'Content-Type': 'application/json', |
| }, |
| body: JSON.stringify({ message: lastBotResponse }), |
| }); |
| const data = await response.json(); |
| if (response.ok) { |
| alert('Message sent successfully!'); |
| } else { |
| alert('Error: ' + data.error); |
| } |
| } catch (error) { |
| alert('Error: Could not send SMS'); |
| } finally { |
| hideLoading(); |
| } |
| } |
| document.getElementById('userInput').addEventListener('keypress', function(e) { |
| if (e.key === 'Enter') { |
| sendMessage(); |
| } |
| }); |
| </script> |
| </body> |
| </html> |