Files
od8n_homepage/public/widget.js
2025-07-27 18:08:01 -03:00

352 lines
9.3 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

(function () {
const preamble = `
We use what we preach — this chatbot is powered by our own n8n automation 🤖 to help you quickly find what you need.
Want to talk to a real automation expert? Just buy a service pack 💼 — it includes a 1-hour get-to-know session with our team 👥.
If its not the right fit, no worries — well refund you 💸.
`;
const logo="logo.svg"
const api='https://ai.odoo4projects.com/webhook/81742473-b50b-4845-a5f9-916d9fe60876/chat'
// Elements
const chatToggle = document.getElementById('cw-chatToggle');
const chatWidget = document.getElementById('cw-chatWidget');
const chatForm = document.getElementById('cw-chatForm');
const chatInput = document.getElementById('cw-chatInput');
const chatMessages = document.getElementById('cw-chatMessages');
const sessionId = crypto.randomUUID();
let chatOpened = false;
function appendMessage(text, sender) {
const msg = document.createElement('div');
msg.classList.add('cw-message', sender === 'user' ? 'user' : 'bot');
msg.innerHTML = text;
chatMessages.appendChild(msg);
chatMessages.scrollTop = chatMessages.scrollHeight;
}
chatToggle.addEventListener('click', () => {
const isVisible = chatWidget.classList.toggle('active');
if (isVisible && !chatOpened) {
appendMessage(
preamble,
'bot'
);
chatOpened = true;
}
});
chatForm.addEventListener('submit', async (e) => {
e.preventDefault();
const input = chatInput.value.trim();
if (!input) return;
appendMessage(input, 'user');
chatInput.value = '';
chatInput.focus();
try {
const response = await fetch(api, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ action: 'sendMessage', sessionId, chatInput: input })
});
const data = await response.json();
console.log("12344")
const statusDiv = document.getElementById('cw-status');
console.log("ASS")
console.log(data)
if (data.status) {
statusDiv.innerHTML = data.status;
// Wait one frame to ensure DOM is updated
requestAnimationFrame(() => {
statusDiv.style.padding = '10px';
statusDiv.style.maxHeight = statusDiv.scrollHeight + 'px';
});
} else {
statusDiv.style.maxHeight = '0';
statusDiv.style.padding = '0 10px';
}
appendMessage(data.output, 'bot');
} catch (error) {
appendMessage('Fehler beim Verbinden mit dem Server. Bitte versuchen Sie es später erneut.', 'bot');
console.error(error);
}
});
function handleBuyClick(buttonId, message) {
const btn = document.getElementById(buttonId);
if (!btn) return;
btn.addEventListener('click', (e) => {
e.preventDefault();
if (!chatWidget.classList.contains('active')) {
chatWidget.classList.add('active');
if (!chatOpened) {
appendMessage(preamble, 'bot');
chatOpened = true;
}
}
appendMessage(message, 'user');
fetch(api, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ action: 'sendMessage', sessionId, chatInput: message })
})
.then((response) => response.json())
.then((data) => {
appendMessage(data.output, 'bot');
})
.catch((error) => {
appendMessage('Fehler beim Verbinden mit dem Server. Bitte versuchen Sie es später erneut.', 'bot');
console.error(error);
});
});
}
handleBuyClick('buy-3h', 'I want to buy the 3 Hours pack for $450.');
handleBuyClick('buy-5h', 'I want to buy the 5 Hours pack for $675.');
handleBuyClick('buy-10h', 'I want to buy the 10 Hours pack for $1200.');
handleBuyClick('buy-bundle', 'I want to buy the ODOO and N8N bundle for $395 per year.');
})();
document.addEventListener('DOMContentLoaded', () => {
const widgetHTML = `
<button id="cw-chatToggle" aria-label="Toggle chat widget" type="button">
<img src="logo.svg" alt="Logo"><span class="text-xs">Agent</span>
</button>
<div id="cw-chatWidget" role="region" aria-live="polite" aria-label="Customer support chat widget">
<div class="logo-container">
<img src="logo.svg" alt="Logo" />
</div>
<div class="header">Kundenservice</div>
<div id="cw-status"></div>
<div id="cw-chatMessages"></div>
<form id="cw-chatForm" autocomplete="off">
<input type="text" id="cw-chatInput" placeholder="Type your message..." required autocomplete="off" />
<button type="submit">Senden</button>
</form>
</div>
`;
document.body.insertAdjacentHTML('beforeend', widgetHTML);
const style = document.createElement('style');
style.textContent = `
/* cw.css */
/* Container */
#cw-chatToggle {
position: fixed;
bottom: 24px;
right: 24px;
background-color: #FFA500;
color: white;
padding: 12px 16px;
border-radius: 25px;
font-weight: 600;
cursor: pointer;
display: flex;
flex-direction: column;
align-items: center;
gap: 4px;
z-index: 100000;
border: none;
user-select: none;
transition: background-color 0.3s ease;
}
#cw-chatToggle:hover {
transform: translateY(-5px);
}
#cw-chatToggle div {
display: flex;
align-items: center;
gap: 8px;
}
#cw-chatToggle img {
image-rendering: pixelated;
image-rendering: optimizeQuality;
image-rendering: -webkit-optimize-contrast; /* Chrome */
image-rendering: crisp-edges; /* Fallback */
}
#cw-chatToggle span.text-sm {
font-weight: 500;
font-size: 0.875rem; /* 14px */
}
#cw-chatToggle span.text-xs {
font-size: 0.75rem; /* 12px */
}
/* Chat widget container */
#cw-chatWidget {
display: none;
position: fixed;
bottom: 100px;
right: 24px;
width: 500px;
max-height: 70vh;
background: white;
border: 1px solid #ccc;
border-radius: 12px;
flex-direction: column;
z-index: 100000;
font-family: system-ui, sans-serif;
}
#cw-chatWidget.active {
display: flex;
}
/* Logo container */
#cw-chatWidget .logo-container {
display: flex;
justify-content: center;
padding-top: 16px;
padding-bottom: 10px;
}
#cw-chatWidget .logo-container img {
height: 60px;
user-select: none;
image-rendering: optimizeQuality;
image-rendering: pixelated;
image-rendering: -webkit-optimize-contrast; /* Chrome */
image-rendering: crisp-edges; /* Fallback */
}
/* Header */
#cw-status {
padding: 10px 10px;
background-color: #f0f0f0;
border-bottom: 1px solid #ddd;
max-height: 0;
transition: max-height 0.5s ease-in-out, padding 0.5s ease-in-out;
}
#cw-chatWidget .header {
background-color: #0070c0;
color: white;
padding: 8px 16px;
font-weight: 600;
text-align: center;
user-select: none;
}
/* Messages container */
#cw-chatMessages {
flex: 1 1 auto;
overflow-y: auto;
padding: 16px;
font-size: 0.875rem;
line-height: 1.4;
user-select: text;
scroll-behavior: smooth;
background: #fafafa;
}
/* Chat form */
#cw-chatForm {
display: flex;
margin: 0px;
border-top: 1px solid #ddd;
}
#cw-chatInput {
flex: 1;
border: none;
padding: 8px 20px;
font-size: 1rem;
outline-offset: 2px;
border-radius: 0 0 0 12px;
}
#cw-chatInput:focus {
outline: 0px solid #0070c0;
}
#cw-chatForm button {
background-color: #0070c0;
border: none;
color: white;
padding: 0 16px;
cursor: pointer;
font-weight: 600;
border-radius: 0 0 12px 0;
transition: background-color 0.3s ease;
}
#cw-chatForm button:hover {
background-color: #005a9e;
}
/* Message bubbles */
.cw-message {
max-width: 75%;
margin-bottom: 8px;
padding: 8px 12px;
border-radius: 12px;
word-wrap: break-word;
white-space: pre-wrap;
}
.cw-message.user {
background-color: #DCF8C6;
color: #333;
margin-left: auto;
text-align: right;
}
.cw-message.bot {
background-color: #E0E0E0;
color: #333;
margin-right: auto;
text-align: left;
}
.button {
display: inline-block;
padding: 12px 24px;
background-color: #4CAF50; /* Green */
color: white;
text-align: center;
text-decoration: none;
border-radius: 8px;
font-size: 16px;
font-weight: bold;
transition: background-color 0.3s ease, box-shadow 0.3s ease;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}
.button:hover {
background-color: #45a049;
box-shadow: 0 6px 10px rgba(0, 0, 0, 0.15);
}
.button:active {
background-color: #3e8e41;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
}
/* Responsive adjustments */
@media (max-width: 600px) {
#cw-chatWidget {
width: 90%;
max-height: 60vh;
bottom: 80px;
right: 5%;
}
#cw-chatToggle {
bottom: 16px;
right: 16px;
}
}
`;
document.head.appendChild(style);
});