Cognito / cognito-widget.js
prelington's picture
Create cognito-widget.js
9fd5a58 verified
// cognito-widget.js
(function () {
if (window.CognitoWidgetInitialized) return;
window.CognitoWidgetInitialized = true;
const CONFIG = {
apiBase: window.COGNITO_API_BASE || "https://your-cognito-server.example.com",
apiKey: window.COGNITO_API_KEY || null, // optional if you protect endpoint with a key
placeholder: "Ask Cognito...",
title: "Cognito",
welcome: "Hi — I'm Cognito. How can I help?",
};
// minimal CSS
const css = `
.cognito-chat-btn { position: fixed; right: 20px; bottom: 20px; z-index: 100000; background: #0b5fff; color: #fff; border-radius: 28px; padding: 12px 16px; cursor: pointer; box-shadow: 0 6px 18px rgba(11,95,255,0.2); font-family: Arial, sans-serif; }
.cognito-panel { position: fixed; right: 20px; bottom: 80px; width: 360px; max-width: 90vw; z-index: 100000; border-radius: 12px; box-shadow: 0 10px 40px rgba(0,0,0,0.2); overflow: hidden; font-family: Arial, sans-serif; background: #fff; display: none; flex-direction: column; }
.cognito-header { padding: 12px; background: #0b5fff; color: #fff; font-weight: bold; display:flex; align-items:center; justify-content:space-between }
.cognito-body { padding: 12px; height: 320px; overflow:auto; background:#f7f7fb }
.cognito-input-row { display:flex; padding: 8px; border-top:1px solid #eee; background:#fff }
.cognito-input { flex:1; padding:8px 10px; border-radius:8px; border:1px solid #ddd; outline:none }
.cognito-send { margin-left:8px; padding:8px 12px; border-radius:8px; border:none; background:#0b5fff; color:#fff; cursor:pointer }
.cognito-msg { margin-bottom:8px; padding:8px 10px; border-radius:8px; max-width:85% }
.cognito-msg.user { background:#0b5fff; color:#fff; margin-left:auto }
.cognito-msg.bot { background:#fff; color:#111; border:1px solid #eee }
`;
const styleEl = document.createElement("style");
styleEl.innerHTML = css;
document.head.appendChild(styleEl);
const btn = document.createElement("button");
btn.className = "cognito-chat-btn";
btn.innerText = CONFIG.title;
document.body.appendChild(btn);
const panel = document.createElement("div");
panel.className = "cognito-panel";
panel.innerHTML = `
<div class="cognito-header">${CONFIG.title} <span style="font-size:12px;opacity:.9">AI assistant</span></div>
<div class="cognito-body">
<div class="cognito-msg bot">${CONFIG.welcome}</div>
</div>
<div class="cognito-input-row">
<input class="cognito-input" placeholder="${CONFIG.placeholder}" />
<button class="cognito-send">Send</button>
</div>
`;
document.body.appendChild(panel);
btn.addEventListener("click", () => {
panel.style.display = panel.style.display === "flex" ? "none" : "flex";
panel.style.flexDirection = "column";
});
const bodyEl = panel.querySelector(".cognito-body");
const inputEl = panel.querySelector(".cognito-input");
const sendBtn = panel.querySelector(".cognito-send");
function appendMessage(text, who="bot") {
const m = document.createElement("div");
m.className = "cognito-msg " + (who==="user" ? "user" : "bot");
m.innerText = text;
bodyEl.appendChild(m);
bodyEl.scrollTop = bodyEl.scrollHeight;
}
async function sendMessage(content) {
appendMessage(content, "user");
inputEl.value = "";
const payload = {
messages: [
{role: "user", content}
]
};
const headers = {"Content-Type": "application/json"};
if (CONFIG.apiKey) headers["x-api-key"] = CONFIG.apiKey;
try {
const res = await fetch(CONFIG.apiBase + "/chat", {
method: "POST",
headers,
body: JSON.stringify(payload)
});
if (!res.ok) {
const txt = await res.text();
appendMessage("Error: " + res.status + " - " + txt, "bot");
return;
}
const data = await res.json();
appendMessage(data.reply || JSON.stringify(data), "bot");
} catch (err) {
appendMessage("Network error: " + err.message, "bot");
}
}
sendBtn.addEventListener("click", () => {
const v = inputEl.value.trim();
if (!v) return;
sendMessage(v);
});
inputEl.addEventListener("keydown", (e) => {
if (e.key === "Enter") {
e.preventDefault();
sendBtn.click();
}
});
// Expose small API to host page
window.CognitoWidget = {
open: () => { panel.style.display = "flex"; },
close: () => { panel.style.display = "none"; },
send: (text) => sendMessage(text),
appendSystem: (text) => appendMessage(text, "bot")
};
})();