diff --git a/index.html b/index.html index 99c965c..a5071e4 100644 --- a/index.html +++ b/index.html @@ -970,6 +970,157 @@ } } + + /* ── Chat Widget ─────────────────────────────────────────── */ + .chat-widget { + position: fixed; + bottom: 24px; + right: 24px; + z-index: 9999; + font-size: 14px; + line-height: 1.5; + } + .chat-toggle { + display: flex; + align-items: center; + gap: 8px; + padding: 12px 20px; + background: var(--accent); + color: #fff; + border: none; + border-radius: 60px; + font-size: 14px; + font-weight: 600; + cursor: pointer; + box-shadow: 0 4px 20px rgba(79, 142, 247, 0.35); + transition: opacity 0.25s, transform 0.25s; + } + .chat-toggle:hover { + opacity: 0.9; + transform: scale(1.04); + } + .chat-toggle svg { flex-shrink: 0; } + .chat-panel { + display: none; + flex-direction: column; + position: fixed; + bottom: 80px; + right: 24px; + width: 360px; + max-height: 520px; + background: var(--bg-card); + border: 1px solid var(--border); + border-radius: var(--radius-card); + box-shadow: var(--shadow); + overflow: hidden; + animation: chatSlideUp 0.28s ease; + } + .chat-panel.open { display: flex; } + @keyframes chatSlideUp { + from { opacity: 0; transform: translateY(16px); } + to { opacity: 1; transform: translateY(0); } + } + .chat-header { + display: flex; + align-items: center; + justify-content: space-between; + padding: 16px 20px; + background: var(--accent-dim); + border-bottom: 1px solid var(--border); + font-weight: 600; + color: var(--text); + } + .chat-header button { + background: none; + border: none; + color: var(--text-muted); + cursor: pointer; + font-size: 16px; + padding: 0 4px; + line-height: 1; + } + .chat-header button:hover { color: var(--text); } + .chat-msgs { + flex: 1; + overflow-y: auto; + padding: 16px 20px; + display: flex; + flex-direction: column; + gap: 10px; + min-height: 200px; + max-height: 340px; + } + .chat-msg { + max-width: 85%; + padding: 10px 14px; + border-radius: 14px; + line-height: 1.45; + word-wrap: break-word; + font-size: 13px; + } + .chat-msg-bot { + align-self: flex-start; + background: var(--bg-inner); + border-bottom-left-radius: 4px; + } + .chat-msg-user { + align-self: flex-end; + background: var(--accent-dim); + border-bottom-right-radius: 4px; + } + .chat-msg-thinking { + align-self: flex-start; + background: var(--bg-inner); + border-bottom-left-radius: 4px; + opacity: 0.6; + } + .chat-input-row { + display: flex; + gap: 8px; + padding: 12px 16px; + border-top: 1px solid var(--border); + background: var(--bg-inner); + } + .chat-input-row input { + flex: 1; + padding: 9px 14px; + border: 1px solid var(--border); + border-radius: var(--radius); + background: var(--bg-input); + color: var(--text); + font-size: 13px; + outline: none; + } + .chat-input-row input:focus { + border-color: var(--accent); + box-shadow: 0 0 0 2px rgba(79, 142, 247, 0.15); + } + .chat-input-row button { + padding: 9px 18px; + background: var(--accent); + color: #fff; + border: none; + border-radius: var(--radius); + font-weight: 600; + font-size: 13px; + cursor: pointer; + transition: opacity 0.2s; + white-space: nowrap; + } + .chat-input-row button:hover { opacity: 0.9; } + .chat-input-row button:disabled { opacity: 0.5; cursor: default; } + + @media (max-width: 480px) { + .chat-panel { + right: 10px; + left: 10px; + width: auto; + bottom: 72px; + max-height: 60vh; + } + .chat-widget { bottom: 14px; right: 14px; } + .chat-toggle { padding: 10px 16px; font-size: 13px; } + } @@ -1702,7 +1853,195 @@ } }); }); + + /* ── Chat Widget ──────────────────────────────────────────── */ + const CHAT_URL = "https://n8n.derez.ai/webhook/a58d00c4-f0c9-40cd-bb50-4f45f0442ef0"; + let chatId = null; + let chatOpen = false; + let chatBusy = false; + let greeted = false; + + function chatToggle() { + chatOpen = !chatOpen; + document.getElementById("chat-panel").classList.toggle("open", chatOpen); + document.getElementById("chat-toggle-btn").classList.toggle("active", chatOpen); + if (chatOpen) { + if (!chatId) { + chatId = String(Math.floor(100000 + Math.random() * 900000)); + chatAppendMsg("bot", "Hi! I'm your Sales Agent. Ask me about plans, setup, pricing, integrations, or anything about your AI agent."); + } + document.getElementById("chat-input").focus(); + } + } + + function chatClose() { + if (chatOpen) chatToggle(); + } + + function chatAppendMsg(role, text) { + const msgs = document.getElementById("chat-msgs"); + const div = document.createElement("div"); + div.className = "chat-msg chat-msg-" + role; + div.textContent = text; + msgs.appendChild(div); + msgs.scrollTop = msgs.scrollHeight; + return div; + } + + function chatKey(e) { + if (e.key === "Enter") chatSend(); + } + + async function chatSend() { + const input = document.getElementById("chat-input"); + const btn = document.getElementById("chat-send-btn"); + const msg = input.value.trim(); + if (!msg || chatBusy) return; + chatBusy = true; + chatAppendMsg("user", msg); + input.value = ""; + btn.disabled = true; + btn.textContent = "…"; + + const think = chatAppendMsg("bot", "…"); + think.className = "chat-msg chat-msg-thinking"; + + try { + const res = await fetch(CHAT_URL, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ message: msg, sessionId: chatId }), + }); + const json = await res.json(); + const first = Array.isArray(json) ? json[0] : json; + const reply = + typeof json === "string" + ? json + : (first && (first.output || first.message || first.reply || first.response || first.text)) || + JSON.stringify(json); + think.remove(); + chatAppendMsg("bot", reply); + } catch (err) { + think.remove(); + chatAppendMsg("bot", "Sorry, I couldn't connect right now. Please try again later."); + } finally { + chatBusy = false; + btn.disabled = false; + btn.textContent = "Send"; + document.getElementById("chat-input").focus(); + } + } + + /* ── Visitor Probe — auto-open after 15s ────────────────── */ + (function () { + let fired = false; + setTimeout(function () { + fetch("https://ipinfo.io/json") + .then(function (r) { return r.json(); }) + .then(function (geo) { fireProbe(geo); }) + .catch(function () { fireProbe(null); }); + }, 15000); + + function fireProbe(geo) { + if (fired) return; + fired = true; + const cid = chatId || String(Math.floor(100000 + Math.random() * 900000)); + const ua = navigator.userAgent; + + let lines = [ + "NEW VISITOR — 15s Probe", + "========================================", + "", + "- Page section: hero", + "- Scroll depth: " + Math.min(100, Math.round((window.pageYOffset / Math.max(1, document.documentElement.scrollHeight - window.innerHeight)) * 100)) + "%", + "- Time on page: 15 seconds", + "- Timestamp: " + new Date().toUTCString(), + "", + "--- BROWSER & DEVICE ---", + "- Browser: " + (/Edg\/([\d.]+)/.test(ua) ? "Edge " + RegExp.$1 : /Chrome\/([\d.]+)/.test(ua) ? "Chrome " + RegExp.$1 : /Firefox\/([\d.]+)/.test(ua) ? "Firefox " + RegExp.$1 : /Version\/([\d.]+).*Safari/.test(ua) ? "Safari " + RegExp.$1 : "Unknown"), + "- OS: " + (/Windows NT 10/.test(ua) ? "Windows 10/11" : /Mac OS X/.test(ua) ? "macOS" : /Android/.test(ua) ? "Android" : /iPhone/.test(ua) ? "iOS" : /Linux/.test(ua) ? "Linux" : "Unknown"), + "- Device: " + (/Mobi|Android|iPhone/.test(ua) ? "Mobile" : "Desktop"), + "- Screen: " + screen.width + "x" + screen.height, + "- Language: " + navigator.language, + "- User Agent: " + ua, + "", + "--- PAGE ---", + "- URL: " + window.location.href, + "- Referrer: " + (document.referrer || "direct / none"), + "- Title: " + document.title, + ]; + if (geo) { + lines.push(""); + lines.push("--- LOCATION ---"); + if (geo.country) lines.push("- Country: " + geo.country); + if (geo.city) lines.push("- City: " + geo.city); + if (geo.org) lines.push("- ISP: " + geo.org); + } + lines.push(""); + lines.push("- Chat ID: " + cid); + + const payload = { + message: lines.join("\n"), + sessionId: cid, + }; + + fetch(CHAT_URL, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify(payload), + }) + .then(function (r) { + const ct = r.headers.get("content-type") || ""; + if (ct.indexOf("json") !== -1) return r.json(); + return r.text().then(function (t) { return { output: t }; }); + }) + .then(function (d) { + const item = Array.isArray(d) ? d[0] : d; + const reply = (item && (item.output || item.message || item.reply || item.response || item.text)) || null; + if (reply) { + if (!chatId) chatId = cid; + chatAppendMsg("bot", reply); + greeted = true; + if (!chatOpen) chatToggle(); + } + }) + .catch(function () {}); + } + })(); + + /* ── Scroll-close ────────────────────────────────────────── */ + (function () { + let scrolled = false; + window.addEventListener("scroll", function () { + if (chatOpen && !scrolled) { + scrolled = true; + setTimeout(function () { scrolled = false; }, 500); + chatClose(); + } + }, { passive: true }); + })(); + +
+ +
+
+ Sales Agent + +
+
+
+ + +
+
+
+ \ No newline at end of file