diff --git a/public/agent-odoo4projects/agent.css b/public/agent-odoo4projects/agent.css new file mode 100644 index 0000000..01bce80 --- /dev/null +++ b/public/agent-odoo4projects/agent.css @@ -0,0 +1,214 @@ +/* ================= Chat Toggle Button ================= */ +#cw-chatToggle { + position: fixed; + bottom: 24px; + right: 24px; + width: 100px; + height: 50px; + border: none; + border-radius: 25px; + padding: 0; + background: none; + cursor: pointer; + display: flex; + justify-content: center; + align-items: center; + z-index: 100000; + box-shadow: rgba(50, 50, 93, 0.25) 0px 13px 27px -5px, + rgba(0, 0, 0, 0.3) 0px 8px 16px -8px; + transition: transform 0.3s ease; +} + +#cw-chatToggle:hover { + transform: translateY(-5px); +} + +#cw-chatToggle img { + width: 80%; + height: 80%; + object-fit: contain; + display: block; + user-select: none; +} + +/* ================= Chat Widget ================= */ +#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; + overflow: hidden; +} + +#cw-chatWidget.active { + display: flex; +} + +#cw-chatWidget .cw-header { + display: flex; + justify-content: center; + padding: 16px 0 10px 0; + background: #f8f9f9; +} + +#cw-chatWidget .cw-header img { + width: 80%; + height: auto; + object-fit: contain; + user-select: none; +} + +/* Status Bar */ +#cw-status { + padding: 10px; + background-color: #f0f0f0; + border-bottom: 1px solid #ddd; + max-height: 0; + transition: max-height 0.5s ease, padding 0.5s ease; +} + +/* Messages */ +#cw-chatMessages { + flex: 1; + overflow-y: auto; + padding: 16px; + font-size: 0.875rem; + line-height: 1.4; + background: #fafafa; + scroll-behavior: smooth; +} + +/* Form */ +#cw-chatForm { + display: flex; + border-top: 1px solid #ddd; +} + +#cw-chatInput { + flex: 1; + border: none; + padding: 8px 20px; + font-size: 1rem; + border-radius: 0 0 0 12px; + outline: none; +} + +#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; +} + +/* Messages 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; +} + +/* ================= Wizard ================= */ +.wizard-headline { + text-align: center; + font-size: 24px; + font-weight: bold; + padding: 20px 0; + background-color: #f8f9f9; + color: #2c3e50; + border-bottom: 2px solid #ddd; +} + +.wizard { + display: flex; + justify-content: space-between; + list-style: none; + padding: 0; + margin: 0; + width: 100%; + background-color: #e0e0e0; +} + +.wizard li { + flex: 1; + display: flex; + flex-direction: column; + border-right: 2px solid #fff; + color: white; + box-sizing: border-box; +} + +.wizard li:last-child { + border-right: none; +} + +.wizard .header { + display: flex; + justify-content: center; + align-items: center; + gap: 8px; + padding: 10px; + font-weight: bold; + font-size: 16px; + text-align: center; +} + +.wizard .text { + padding: 20px 10px; + text-align: center; + font-size: 14px; + flex-grow: 1; +} + +/* Wizard state colors */ +.wizard li.open { + background-color: #7f8c8d; +} + +.wizard li.open .header { + background-color: #5d6d7e; +} + +.wizard li.done { + background-color: #1e8449; +} + +.wizard li.done .header { + background-color: #145a32; +} + +.wizard i { + font-size: 18px; +} diff --git a/public/agent-odoo4projects/agent.js b/public/agent-odoo4projects/agent.js new file mode 100644 index 0000000..0c02099 --- /dev/null +++ b/public/agent-odoo4projects/agent.js @@ -0,0 +1,127 @@ +// ================= CONFIG ================= +const baseUrl = 'http://localhost:8000'; // Base URL for all resources + +const config = { + cssUrl: `${baseUrl}/agent.css`, // CSS file + api: `https://002-001-5dd6e535-4d1c-46bc-9bd9-42ad4bc5f082.odoo4projects.com/webhook/702862fd-dd17-4a34-8efb-e9056d2c50df/chat`, // Backend webhook endpoint + buttonImage: `${baseUrl}/images/4.svg`, // Chat toggle button image + logoImage: `${baseUrl}/images/logo.svg`, // Logo image for chat widget + preamble: 'Hallo! Wie kann ich Ihnen helfen?' // Initial bot message +}; + +// ================= WIDGET HTML ================= +const widgetHTML = ` +
+
+ +
+
+
+ + +
+
+
+ +`; + +// ================= UTILS ================= +function loadCSS(url) { + const link = document.createElement('link'); + link.rel = 'stylesheet'; + link.href = url; + document.head.appendChild(link); +} + +function appendMessage(chatMessages, 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; +} + +// ================= MAIN ================= +document.addEventListener('DOMContentLoaded', () => { + try { + // Load CSS + loadCSS(config.cssUrl); + + // Inject chat widget HTML + document.body.insertAdjacentHTML('beforeend', widgetHTML); + document.dispatchEvent(new CustomEvent('JSsucks')); + + // ================= DOM REFERENCES ================= + 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 statusDiv = document.getElementById('cw-status'); + + const chatid = crypto.randomUUID(); + let chatOpened = false; + + // ================= BOT COMMUNICATION ================= + async function sendMessageToBot(messageText) { + chatWidget.classList.add('active'); + appendMessage(chatMessages, messageText, 'user'); + chatInput.value = ''; + chatInput.focus(); + + try { + const res = await fetch(config.api, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ + action: 'sendMessage', + chatid, + chatInput: messageText + }) + }); + + const data = await res.json(); + + if (data.status) { + statusDiv.innerHTML = data.status; + requestAnimationFrame(() => { + statusDiv.style.maxHeight = statusDiv.scrollHeight + 'px'; + statusDiv.style.padding = '10px'; + }); + } else { + statusDiv.style.maxHeight = '0'; + statusDiv.style.padding = '0 10px'; + } + + appendMessage(chatMessages, data.output, 'bot'); + } catch (error) { + appendMessage(chatMessages, 'Fehler beim Verbinden mit dem Server. Bitte versuchen Sie es später erneut.', 'bot'); + console.error(error); + } + } + + window.sendMessageToBot = sendMessageToBot; + + // ================= EVENT LISTENERS ================= + chatToggle.addEventListener('click', () => { + const isVisible = chatWidget.classList.contains('active'); + chatWidget.classList.toggle('active', !isVisible); + + if (!isVisible && !chatOpened) { + appendMessage(chatMessages, config.preamble, 'bot'); + chatOpened = true; + } + }); + + chatForm.addEventListener('submit', (e) => { + e.preventDefault(); + const input = chatInput.value.trim(); + if (input) sendMessageToBot(input); + }); + + } catch (err) { + console.error('Failed to initialize chat widget:', err); + } +}); diff --git a/public/agent-odoo4projects/images/4.svg b/public/agent-odoo4projects/images/4.svg new file mode 100644 index 0000000..e03b455 --- /dev/null +++ b/public/agent-odoo4projects/images/4.svg @@ -0,0 +1,72 @@ + + + + + + + + + + + + + + + + + + + diff --git a/public/agent-odoo4projects/images/logo.svg b/public/agent-odoo4projects/images/logo.svg new file mode 100644 index 0000000..40f82b9 --- /dev/null +++ b/public/agent-odoo4projects/images/logo.svg @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/agent-odoo4projects/index.html b/public/agent-odoo4projects/index.html new file mode 100644 index 0000000..7139900 --- /dev/null +++ b/public/agent-odoo4projects/index.html @@ -0,0 +1,18 @@ + + + + + + OD8N - Odoo & n8n Automation Experts + + + + + + + + + + + + diff --git a/public/agent-odoo4projects/start b/public/agent-odoo4projects/start new file mode 100755 index 0000000..3b95089 --- /dev/null +++ b/public/agent-odoo4projects/start @@ -0,0 +1,20 @@ +#!/usr/bin/env python3 +from flask import Flask, send_from_directory +import os + +app = Flask(__name__) +directory = os.getcwd() # serve current directory + +@app.route("/", defaults={"path": "index.html"}) +@app.route("/") +def serve_file(path): + # If file exists, serve it + if os.path.isfile(os.path.join(directory, path)): + return send_from_directory(directory, path) + else: + return f"File not found: {path}", 404 + +if __name__ == "__main__": + # debug=True enables auto-reload when this file changes + app.run(host="0.0.0.0", port=8000, debug=True) +