| |
| <!doctype html> |
| <html><head><meta charset="utf-8"/><title>Simple Chat</title> |
| <meta name="viewport" content="width=device-width,initial-scale=1"/> |
| <style> |
| :root { --bg:#f6f7f9; --card:#fff; --me:#dff1ff; --bot:#ffffff; --text:#23262b; --muted:#8a9099; } |
| body { margin:0; font-family:system-ui,-apple-system,Segoe UI,Roboto,Arial,sans-serif; background:var(--bg); color:var(--text); } |
| .app { max-width:840px; margin:24px auto; padding:0 16px; } |
| .card { background:var(--card); border:1px solid #e3e6ea; border-radius:14px; box-shadow:0 1px 2px rgba(0,0,0,.04); overflow:hidden; } |
| .header { padding:14px 16px; border-bottom:1px solid #e9edf2; font-weight:600; } |
| .chat { height:480px; overflow:auto; padding:16px; display:flex; flex-direction:column; gap:12px; } |
| .row { display:flex; } |
| .row.me { justify-content:flex-end; } |
| .bubble { max-width:70%; padding:10px 12px; border-radius:12px; line-height:1.35; white-space:pre-wrap; } |
| .me .bubble { background:var(--me); border:1px solid #c3e5ff; } |
| .bot .bubble { background:var(--bot); border:1px solid #e5e8ec; } |
| .footer { display:flex; gap:8px; padding:12px; border-top:1px solid #e9edf2; } |
| input[type=text] { flex:1; padding:10px 12px; border-radius:10px; border:1px solid #d5dbe3; font-size:15px; } |
| button { padding:10px 14px; border-radius:10px; border:1px solid #2b6cb0; background:#2b6cb0; color:#fff; font-weight:600; cursor:pointer; } |
| button:disabled { opacity:.6; cursor:not-allowed; } |
| .hint { color:var(--muted); font-size:12px; padding:0 16px 12px; } |
| </style></head> |
| <body> |
| <div class="app"><div class="card"> |
| <div class="header">Traditional Chatbot (Local)</div> |
| <div id="chat" class="chat"></div> |
| <div class="hint">Try: <code>reverse: hello world</code>, <code>help</code>, <code>capabilities</code></div> |
| <div class="footer"> |
| <input id="msg" type="text" placeholder="Type a message..." autofocus /> |
| <button id="send">Send</button> |
| </div> |
| </div></div> |
| <script> |
| const API = "http://127.0.0.1:3978/plain-chat"; |
| const chat = document.getElementById("chat"); |
| const input = document.getElementById("msg"); |
| const sendBtn = document.getElementById("send"); |
| function addBubble(text, who) { |
| const row = document.createElement("div"); row.className = "row " + who; |
| const wrap = document.createElement("div"); wrap.className = who === "me" ? "me" : "bot"; |
| const b = document.createElement("div"); b.className = "bubble"; b.textContent = text; |
| wrap.appendChild(b); row.appendChild(wrap); chat.appendChild(row); chat.scrollTop = chat.scrollHeight; |
| } |
| async function send() { |
| const text = input.value.trim(); if (!text) return; input.value = ""; addBubble(text, "me"); sendBtn.disabled = true; |
| try { |
| const res = await fetch(API, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ text }) }); |
| if (!res.ok) throw new Error("HTTP " + res.status); |
| const data = await res.json(); addBubble(data.reply ?? "(no reply)", "bot"); |
| } catch (err) { addBubble("Error: " + err.message, "bot"); } |
| finally { sendBtn.disabled = false; input.focus(); } |
| } |
| sendBtn.addEventListener("click", send); |
| input.addEventListener("keydown", (e)=>{ if (e.key === "Enter") send(); }); |
| addBubble("Connected to local bot at /plain-chat", "bot"); |
| </script> |
| </body></html> |
|
|