feat: 前端HESUPIPE品牌化+管道文案+GDPR提示
- 品牌色橙#f08a31→HESUPIPE蓝#066fc0(取自官网主题CSS a:hover/导航主色),7槽位色板三处同步:theme.js/widget.js内联副本/style.css :root - chat.html/widget.js/js/chat.js:标题HESUPIPE Support、管道场景描述、欢迎语、热门话题Get Quotation/Pipe Specifications/Delivery & Shipping、WhatsApp+8615937108317、邮箱hesu@hesuu.com - 邀请卡文案管道化(pipe specs, MOQ, delivery timing)+GDPR小字;聊天面板footer GDPR行(复用.chat-footer) - admin.html VOLT→HESUPIPE;头像PIL重绘为品牌蓝底白H(512/128px) - widget-test.html色值同步+断言基准更新(浏览器断言9/9 Δ=0);.gitignore排除.playwright-mcp/ Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
@@ -6,3 +6,4 @@ __pycache__/
|
||||
data/
|
||||
.superpowers/
|
||||
*.db
|
||||
.playwright-mcp/
|
||||
|
||||
@@ -392,7 +392,7 @@ python -m pytest -q && git add -A && git commit -m "feat: 会话编排建材化+
|
||||
**Files:**
|
||||
- Modify: `app/main.py`、`app/services/email_service.py`、`app/api/routes/chat_rest.py`、`app/services/rate_limit.py`、`app/config.py`(如有 DB 默认名)
|
||||
|
||||
- [ ] **Step 1: 逐文件更名**
|
||||
- [x] **Step 1: 逐文件更名**
|
||||
|
||||
| 文件 | 改动 |
|
||||
|---|---|
|
||||
@@ -402,14 +402,14 @@ python -m pytest -q && git add -A && git commit -m "feat: 会话编排建材化+
|
||||
| `app/services/rate_limit.py` | docstring "Mirrors hesu's" 更新 |
|
||||
| `app/config.py` + `.env.example` | DATABASE_URL 默认 `data/hesupipe_ai_kefu.db` |
|
||||
|
||||
- [ ] **Step 2: 全局残留扫描**
|
||||
- [x] **Step 2: 全局残留扫描**
|
||||
|
||||
```bash
|
||||
grep -rin "汽车\|vehicle\|byd\|toyota\|hesu auto\|borderlesscar\|VOLT\|XYH\|cc-ai-kefu\|cc_ai_kefu\|car\b\|cars\|什么车\|车型\|车价" app/ tests/ scripts/ --include="*.py" | grep -v "docs/"
|
||||
```
|
||||
预期:无输出(docstring/注释里的行业残留一并清零;`car\b|cars|什么车|车型` 抓 boundary_filter 话术池等用户可见输出)。
|
||||
|
||||
- [ ] **Step 3: 全量测试 + Commit**
|
||||
- [x] **Step 3: 全量测试 + Commit**
|
||||
|
||||
```bash
|
||||
python -m pytest -q && git add -A && git commit -m "chore: 服务端品牌与行业残留更名清零"
|
||||
@@ -422,7 +422,7 @@ python -m pytest -q && git add -A && git commit -m "chore: 服务端品牌与行
|
||||
**Files:**
|
||||
- Modify: `docker-compose.yml`、`deploy.sh`、`openresty.conf`、`.env.example`
|
||||
|
||||
- [ ] **Step 1: 更名**
|
||||
- [x] **Step 1: 更名**
|
||||
|
||||
| 文件 | 改动 |
|
||||
|---|---|
|
||||
@@ -431,14 +431,14 @@ python -m pytest -q && git add -A && git commit -m "chore: 服务端品牌与行
|
||||
| `openresty.conf` | upstream `cc_ai_kefu`→`hesupipe_ai_kefu`;127.0.0.1:8016→8017;alias `/www/cc_ai_kefu/`→`/www/hesupipe_ai_kefu/`;日志名同步(含注释掉的 HTTPS 段) |
|
||||
| `.env.example` | `APP_PORT=8017`;`PUSH_EXTERNAL_KEY_PREFIX=ai-kefu-jc`;`PUSH_ENABLED=false`(开发期) |
|
||||
|
||||
- [ ] **Step 2: 残留扫描**
|
||||
- [x] **Step 2: 残留扫描**
|
||||
|
||||
```bash
|
||||
grep -rn "cc_ai_kefu\|cc-ai-kefu\|8016" docker-compose.yml deploy.sh openresty.conf .env.example
|
||||
```
|
||||
预期:无输出。
|
||||
|
||||
- [ ] **Step 3: 测试 + Commit**
|
||||
- [x] **Step 3: 测试 + Commit**
|
||||
|
||||
```bash
|
||||
python -m pytest -q && git add -A && git commit -m "chore: 部署配置更名(hs-ai-kefu/8017/hesupipe_ai_kefu)"
|
||||
@@ -452,14 +452,14 @@ python -m pytest -q && git add -A && git commit -m "chore: 部署配置更名(hs
|
||||
- Modify: `static/chat.html`、`static/widget.js`、`static/js/chat.js`、`static/js/theme.js`、`static/admin.html`、`static/widget-test.html`
|
||||
- Test: `tests/test_invite_static.py`、`tests/test_theme_static.py`
|
||||
|
||||
- [ ] **Step 1: 了解静态测试的真实性质(避免走错路)**
|
||||
- [x] **Step 1: 了解静态测试的真实性质(避免走错路)**
|
||||
|
||||
`tests/test_invite_static.py`/`test_theme_static.py` 是**结构回归网**,不是文案断言——
|
||||
它们断言的是邀请卡面板出厂 hide、pointer-events、回流顺序、theme.js 与 widget.js
|
||||
调色板逐字同步、无残留旧色 hex 等结构性质。所以本任务的测试策略是:
|
||||
**直接改前端文件,然后跑结构回归测试防破坏**(它们会在你漏改某处色值/结构时指路)。
|
||||
|
||||
- [ ] **Step 2: 前端文案与配置**
|
||||
- [x] **Step 2: 前端文案与配置**
|
||||
|
||||
| 文件 | 改动 |
|
||||
|---|---|
|
||||
@@ -471,14 +471,14 @@ python -m pytest -q && git add -A && git commit -m "chore: 部署配置更名(hs
|
||||
| `widget.js` | **GDPR 行**:首次对话邀请卡/首条消息附加 "By chatting, you agree to our privacy policy."(链接指向 hesupipe.com 隐私政策页,URL 实施时与需求方确认,可先 `https://hesupipe.com/privacy-policy/` 占位) |
|
||||
| 头像 | `kefu.png`/`kefu-small.png` 替换(需求方提供 logo 或用品牌蓝底 "H" 字母临时生成) |
|
||||
|
||||
- [ ] **Step 3: 跑静态断言与全量测试至绿**
|
||||
- [x] **Step 3: 跑静态断言与全量测试至绿**
|
||||
|
||||
```bash
|
||||
python -m pytest tests/test_invite_static.py tests/test_theme_static.py -q
|
||||
python -m pytest -q
|
||||
```
|
||||
|
||||
- [ ] **Step 4: 残留扫描 + Commit**
|
||||
- [x] **Step 4: 残留扫描 + Commit**
|
||||
|
||||
```bash
|
||||
grep -rin "HESU Support\|hesu auto\|vehicle\|VOLT\|borderlesscar\|1903717\|f08a31" static/ | grep -v blog
|
||||
|
||||
+5
-5
@@ -3,7 +3,7 @@
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>VOLT - 管理后台</title>
|
||||
<title>HESUPIPE - 管理后台</title>
|
||||
<style>
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; background: #f0f2f5; color: #333; height: 100vh; overflow: hidden; }
|
||||
@@ -119,7 +119,7 @@
|
||||
|
||||
<div class="login-wrap" id="loginWrap">
|
||||
<div class="login-box">
|
||||
<h2>VOLT 管理后台</h2>
|
||||
<h2>HESUPIPE 管理后台</h2>
|
||||
<input type="password" id="loginPwd" placeholder="请输入管理密码" autofocus>
|
||||
<button onclick="doLogin()">登录</button>
|
||||
<div class="login-error" id="loginErr">密码错误</div>
|
||||
@@ -128,7 +128,7 @@
|
||||
|
||||
<div class="app" id="app">
|
||||
<div class="header">
|
||||
<h1>VOLT - 沟通记录</h1>
|
||||
<h1>HESUPIPE - 沟通记录</h1>
|
||||
<div class="header-right">
|
||||
<button class="btn-logs" id="btnLogs" onclick="toggleLogs()">推送日志</button>
|
||||
<select id="filterIntent" onchange="resetAndLoad()">
|
||||
@@ -339,8 +339,8 @@ function selectConv(convId) {
|
||||
var html = '';
|
||||
d.messages.forEach(function(m) {
|
||||
var cls = m.role === 'user' ? 'user' : 'assistant';
|
||||
var avatar = m.role === 'user' ? '客' : 'V';
|
||||
var roleLabel = m.role === 'user' ? '客户' : 'VOLT';
|
||||
var avatar = m.role === 'user' ? '客' : 'H';
|
||||
var roleLabel = m.role === 'user' ? '客户' : 'HESUPIPE';
|
||||
|
||||
html += '<div class="msg-row ' + cls + '">';
|
||||
html += '<div class="msg-avatar ' + cls + '">' + avatar + '</div>';
|
||||
|
||||
+9
-7
@@ -3,7 +3,7 @@
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
||||
<title>VOLT</title>
|
||||
<title>HESUPIPE Support</title>
|
||||
<link rel="stylesheet" href="/static/css/style.css">
|
||||
<script src="/static/js/theme.js"></script>
|
||||
</head>
|
||||
@@ -12,7 +12,7 @@
|
||||
<div class="chat-header">
|
||||
<div class="avatar"><span class="avatar-emoji">🤖</span><img class="avatar-img" alt="" src="/static/kefu-small.png"></div>
|
||||
<div class="info">
|
||||
<h1>HESU Support</h1>
|
||||
<h1>HESUPIPE Support</h1>
|
||||
<div class="availability">Online now - Usually replies in minutes</div>
|
||||
</div>
|
||||
<!-- <div class="actions">
|
||||
@@ -30,14 +30,14 @@
|
||||
<div style="display:flex;align-items:center;gap:14px;">
|
||||
<div class="help-content">
|
||||
<div class="help-title">How can we help?</div>
|
||||
<div class="help-description">Ask about vehicles, market support, quotation, shipping and delivery.</div>
|
||||
<div class="help-description">Ask about pipe specifications, quotations, MOQ, shipping and delivery.</div>
|
||||
</div>
|
||||
<div class="help-actions">
|
||||
<a href="https://wa.me/+8619037179250" target="_blank" class="call-btn whatsapp-btn">
|
||||
<a href="https://wa.me/+8615937108317" target="_blank" class="call-btn whatsapp-btn">
|
||||
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z"></path></svg>
|
||||
<span>WhatsApp</span>
|
||||
</a>
|
||||
<a href="mailto:info@borderlesscar.com" class="call-btn email-btn">
|
||||
<a href="mailto:hesu@hesuu.com" class="call-btn email-btn">
|
||||
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z"></path><polyline points="22,6 12,13 2,6"></polyline></svg>
|
||||
<span>Email</span>
|
||||
</a>
|
||||
@@ -48,7 +48,7 @@
|
||||
<div class="chat-separator"></div>
|
||||
<div class="chat-messages" id="messages">
|
||||
<div class="message assistant">
|
||||
<div class="bubble">Hey there! Looking for a ride? Tell me what you need.</div>
|
||||
<div class="bubble">What kind of piping project are you working on?</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -61,7 +61,8 @@
|
||||
<div class="popular-topics-label">POPULAR TOPICS</div>
|
||||
<div class="popular-topics-grid">
|
||||
<button class="popular-topic-btn" data-topic="Get Quotation">Get Quotation</button>
|
||||
<button class="popular-topic-btn" data-topic="Distributor Cooperation">Distributor Cooperation</button>
|
||||
<button class="popular-topic-btn" data-topic="Pipe Specifications">Pipe Specifications</button>
|
||||
<button class="popular-topic-btn" data-topic="Delivery & Shipping">Delivery & Shipping</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="chat-separator-topics"></div>
|
||||
@@ -75,6 +76,7 @@
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="chat-footer"><span class="footer-left">By chatting, you agree to our <a href="https://hesupipe.com/privacy-policy/" target="_blank" rel="noopener">privacy policy</a>.</span></div>
|
||||
</div>
|
||||
|
||||
<script src="/static/js/chat.js"></script>
|
||||
|
||||
+12
-7
@@ -5,13 +5,13 @@
|
||||
}
|
||||
|
||||
:root {
|
||||
--w-primary: #f08a31;
|
||||
--w-primary-rgb: 240, 138, 49;
|
||||
--w-gradient-end: #f08e2c;
|
||||
--w-deep-text: #8a4c1d;
|
||||
--w-caption-text: #c16d2d;
|
||||
--w-soft-bg: #fef8f4;
|
||||
--w-border-soft: #f0d3bd;
|
||||
--w-primary: #066fc0;
|
||||
--w-primary-rgb: 6, 111, 192;
|
||||
--w-gradient-end: #0666bb;
|
||||
--w-deep-text: #14517a;
|
||||
--w-caption-text: #2174ab;
|
||||
--w-soft-bg: #f3f9fe;
|
||||
--w-border-soft: #bbdcf2;
|
||||
--bg: #f5f5f5;
|
||||
--chat-bg: #ffffff;
|
||||
--ai-bubble: #f0f0f0;
|
||||
@@ -457,6 +457,11 @@ html, body {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.chat-footer a {
|
||||
color: var(--w-caption-text);
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
/* Mobile */
|
||||
@media (max-width: 600px) {
|
||||
.chat-container {
|
||||
|
||||
+2
-2
@@ -29,8 +29,8 @@
|
||||
(function () {
|
||||
// 联系方式配置(与 widget.js 的 data-* 机制一致)
|
||||
var chatScript = document.currentScript || document.querySelector('script[src*="chat.js"]');
|
||||
var whatsapp = (chatScript && chatScript.getAttribute("data-whatsapp")) || "https://wa.me/+8619037179250";
|
||||
var email = (chatScript && chatScript.getAttribute("data-email")) || "mailto:info@borderlesscar.com";
|
||||
var whatsapp = (chatScript && chatScript.getAttribute("data-whatsapp")) || "https://wa.me/+8615937108317";
|
||||
var email = (chatScript && chatScript.getAttribute("data-email")) || "mailto:hesu@hesuu.com";
|
||||
var waBtn = document.querySelector('.whatsapp-btn');
|
||||
var emBtn = document.querySelector('.email-btn');
|
||||
if (waBtn) waBtn.href = whatsapp;
|
||||
|
||||
+8
-8
@@ -4,16 +4,16 @@
|
||||
(function (global) {
|
||||
"use strict";
|
||||
|
||||
var DEFAULT_COLOR = "#f08a31";
|
||||
var DEFAULT_COLOR = "#066fc0";
|
||||
|
||||
var DEFAULT_PALETTE = {
|
||||
primary: "#f08a31",
|
||||
primaryRgb: "240,138,49",
|
||||
gradientEnd: "#f08e2c",
|
||||
deepText: "#8a4c1d",
|
||||
captionText: "#c16d2d",
|
||||
softBg: "#fef8f4",
|
||||
borderSoft: "#f0d3bd"
|
||||
primary: "#066fc0",
|
||||
primaryRgb: "6,111,192",
|
||||
gradientEnd: "#0666bb",
|
||||
deepText: "#14517a",
|
||||
captionText: "#2174ab",
|
||||
softBg: "#f3f9fe",
|
||||
borderSoft: "#bbdcf2"
|
||||
};
|
||||
|
||||
function clampNum(v, lo, hi) {
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 904 B |
Binary file not shown.
|
Before Width: | Height: | Size: 666 KiB After Width: | Height: | Size: 4.0 KiB |
+12
-12
@@ -24,11 +24,11 @@
|
||||
p { color: #666; line-height: 1.6; }
|
||||
ul { color: #666; }
|
||||
.test-list li { margin-bottom: 8px; }
|
||||
.test-list li::before { content: "☐ "; color: #f08a31; font-weight: bold; }
|
||||
.test-list li::before { content: "☐ "; color: #066fc0; font-weight: bold; }
|
||||
#assertions div { padding: 4px 0; border-bottom: 1px solid #eee; font-family: Consolas, monospace; font-size: 13px; }
|
||||
#assertions div:last-child { border-bottom: none; }
|
||||
#colorPicker { width: 48px; height: 32px; padding: 0; border: 1px solid #ccc; border-radius: 4px; vertical-align: middle; cursor: pointer; }
|
||||
.btn { padding: 8px 16px; background: #f08a31; color: white; border: none; border-radius: 4px; cursor: pointer; margin-right: 6px; }
|
||||
.btn { padding: 8px 16px; background: #066fc0; color: white; border: none; border-radius: 4px; cursor: pointer; margin-right: 6px; }
|
||||
.btn:hover { opacity: 0.9; }
|
||||
</style>
|
||||
</head>
|
||||
@@ -39,11 +39,11 @@
|
||||
<p><strong>Expected behavior:</strong></p>
|
||||
<ul class="test-list">
|
||||
<li>Invite card appears after 5 seconds</li>
|
||||
<li>Invite card has orange gradient header with robot emoji</li>
|
||||
<li>Two topic buttons: "Get Quotation" and "Distributor Cooperation"</li>
|
||||
<li>Invite card has blue gradient header with robot emoji</li>
|
||||
<li>Three topic buttons: "Get Quotation", "Pipe Specifications" and "Delivery & Shipping"</li>
|
||||
<li>Action buttons: "Start Chat" and "No Thanks"</li>
|
||||
<li>Click "Get Quotation" → invite closes → chat opens → message auto-sends</li>
|
||||
<li>Click "Distributor Cooperation" → invite closes → chat opens → message auto-sends</li>
|
||||
<li>Click "Pipe Specifications" → invite closes → chat opens → message auto-sends</li>
|
||||
<li>Click "Start Chat" → invite closes → chat opens</li>
|
||||
<li>Click "No Thanks" → invite permanently closes</li>
|
||||
<li>Click "No Thanks" or X → refresh → invite stays hidden AND the old card area stays clickable (no invisible overlay; regression 2026-09-01)</li>
|
||||
@@ -64,9 +64,9 @@
|
||||
<h2>Theme Color Preview</h2>
|
||||
<p>Pick a color and Apply, or use a preset. Each click tears down the old widget (host + script + invite dismissal state) and re-embeds with <code>data-color</code>. "Test Broken Avatar" points <code>data-avatar</code> at a missing image to verify the 🤖 emoji fallback.</p>
|
||||
<p>
|
||||
<input type="color" id="colorPicker" value="#f08a31">
|
||||
<input type="color" id="colorPicker" value="#066fc0">
|
||||
<button class="btn" onclick="applyColor()">Apply</button>
|
||||
<button class="btn" onclick="applyColor('#f08a31')">Orange</button>
|
||||
<button class="btn" onclick="applyColor('#066fc0')">Brand Blue</button>
|
||||
<button class="btn" onclick="applyColor('#1a73e8')">Blue</button>
|
||||
<button class="btn" onclick="applyColor('#16a34a')">Green</button>
|
||||
<button class="btn" onclick="applyColor('#7c3aed')">Purple</button>
|
||||
@@ -103,7 +103,7 @@
|
||||
"data-mobile": "true",
|
||||
"data-debug": "true",
|
||||
"data-whatsapp": "https://wa.me/8613800138000",
|
||||
"data-email": "mailto:demo@hesu-auto.com"
|
||||
"data-email": "mailto:demo@hesupipe.com"
|
||||
};
|
||||
|
||||
var rebuildLoading = false, rebuildPending = null;
|
||||
@@ -142,9 +142,9 @@
|
||||
}
|
||||
|
||||
/* ===== 断言面板(spec §8.2) ===== */
|
||||
var CURRENT_HARDCODED = { // 现状代表值(spec §4),Δ ≤ 8/通道
|
||||
primary: "#f08a31", gradientEnd: "#F08A34", deepText: "#8C4D1D",
|
||||
captionText: "#C16C2E", softBg: "#FFF8F3", borderSoft: "#F0D5BF"
|
||||
var CURRENT_HARDCODED = { // 现状代表值(HESUPIPE 品牌蓝 #066fc0 派生),Δ ≤ 8/通道
|
||||
primary: "#066fc0", gradientEnd: "#0666bb", deepText: "#14517a",
|
||||
captionText: "#2174ab", softBg: "#f3f9fe", borderSoft: "#bbdcf2"
|
||||
};
|
||||
function hexToRgb6(h) {
|
||||
h = String(h).replace(/^#/, "");
|
||||
@@ -161,7 +161,7 @@
|
||||
if (!t || !d) {
|
||||
rows.push("❌ theme.js / widget debug 钩子未就绪");
|
||||
} else {
|
||||
var p = t.derivePalette("#f08a31");
|
||||
var p = t.derivePalette("#066fc0");
|
||||
Object.keys(CURRENT_HARDCODED).forEach(function (k) {
|
||||
var delta = channelDelta(p[k], CURRENT_HARDCODED[k]);
|
||||
check("default " + k + " Δ≤8", delta <= 8, p[k] + " vs " + CURRENT_HARDCODED[k] + ", Δ=" + delta);
|
||||
|
||||
+22
-16
@@ -7,25 +7,25 @@
|
||||
// Save config immediately (before DOM ready)
|
||||
var position = script.getAttribute("data-position") || "bottom-right";
|
||||
var theme = script.getAttribute("data-theme") || "light";
|
||||
var title = script.getAttribute("data-title") || "HESU Support";
|
||||
var title = script.getAttribute("data-title") || "HESUPIPE Support";
|
||||
var autoOpen = script.getAttribute("data-auto-open") === "true";
|
||||
var whatsapp = script.getAttribute("data-whatsapp") || "https://wa.me/+8619037179250";
|
||||
var email = script.getAttribute("data-email") || "mailto:info@borderlesscar.com";
|
||||
var whatsapp = script.getAttribute("data-whatsapp") || "https://wa.me/+8615937108317";
|
||||
var email = script.getAttribute("data-email") || "mailto:hesu@hesuu.com";
|
||||
var autoInvite = script.getAttribute("data-auto-invite") !== "false";
|
||||
var isMobile = script.getAttribute("data-mobile") === "true";
|
||||
var wsBase = new URL(script.src).origin;
|
||||
|
||||
/* ===== 主题派生单元:与 static/js/theme.js 逐字同步,tests/test_theme_static.py 强制;只可整块替换,不可单边修改 ===== */
|
||||
var DEFAULT_COLOR = "#f08a31";
|
||||
var DEFAULT_COLOR = "#066fc0";
|
||||
|
||||
var DEFAULT_PALETTE = {
|
||||
primary: "#f08a31",
|
||||
primaryRgb: "240,138,49",
|
||||
gradientEnd: "#f08e2c",
|
||||
deepText: "#8a4c1d",
|
||||
captionText: "#c16d2d",
|
||||
softBg: "#fef8f4",
|
||||
borderSoft: "#f0d3bd"
|
||||
primary: "#066fc0",
|
||||
primaryRgb: "6,111,192",
|
||||
gradientEnd: "#0666bb",
|
||||
deepText: "#14517a",
|
||||
captionText: "#2174ab",
|
||||
softBg: "#f3f9fe",
|
||||
borderSoft: "#bbdcf2"
|
||||
};
|
||||
|
||||
function clampNum(v, lo, hi) {
|
||||
@@ -219,6 +219,7 @@
|
||||
".chat-footer { padding:10px 10px; background:white; display:flex; align-items:center; justify-content:space-between; font-size:11px; color:var(--w-caption-text); gap:20px; }",
|
||||
".chat-footer .footer-left { flex:1; }",
|
||||
".chat-footer .footer-right { flex-shrink:0; }",
|
||||
".chat-footer a { color:var(--w-caption-text); text-decoration:underline; }",
|
||||
|
||||
// Typing
|
||||
".typing { display:none; align-self:flex-start; padding:8px 12px; background:" + c.bubble + "; border-radius:12px; }",
|
||||
@@ -275,6 +276,8 @@
|
||||
".invite-start-btn:hover { opacity:0.95; }",
|
||||
".invite-dismiss-btn { border-radius:20px; border:1px solid var(--w-border-soft); background:white; padding:14px 20px; color:var(--w-deep-text); font-size:14px; font-weight:500; cursor:pointer; transition:background 0.2s; }",
|
||||
".invite-dismiss-btn:hover { background:#FEFEFE; }",
|
||||
".invite-privacy { padding:2px 16px 12px; font-size:11px; color:var(--w-caption-text); text-align:center; }",
|
||||
".invite-privacy a { color:var(--w-caption-text); text-decoration:underline; }",
|
||||
|
||||
// Responsive
|
||||
"@media(max-width:450px){ .chat-panel{width:calc(100vw - 20px);height:calc(100vh - 200px);bottom:60px;right:0px;} .invite-panel{width:calc(100vw - 24px);} .invite-topics{grid-template-columns:1fr;} }",
|
||||
@@ -297,19 +300,20 @@
|
||||
'</div></div>',
|
||||
'<div class="ended" id="w-ended">Chat ended. We\'ll be in touch!</div>',
|
||||
'<div class="panel-top">',
|
||||
'<div class="help-block"><div style="display:flex;align-items:center;gap:14px;"><div class="help-content"><div class="help-title">How can we help?</div><div class="help-description">Ask about vehicles, market support, quotation, shipping and delivery.</div></div><div class="help-actions"><a href="' + whatsapp + '" target="_blank" class="call-btn whatsapp-btn"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z"></path></svg><span>WhatsApp</span></a><a href="' + email + '" class="call-btn email-btn"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z"></path><polyline points="22,6 12,13 2,6"></polyline></svg><span>Email</span></a></div></div></div>',
|
||||
'<div class="help-block"><div style="display:flex;align-items:center;gap:14px;"><div class="help-content"><div class="help-title">How can we help?</div><div class="help-description">Ask about pipe specifications, quotations, MOQ, shipping and delivery.</div></div><div class="help-actions"><a href="' + whatsapp + '" target="_blank" class="call-btn whatsapp-btn"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z"></path></svg><span>WhatsApp</span></a><a href="' + email + '" class="call-btn email-btn"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z"></path><polyline points="22,6 12,13 2,6"></polyline></svg><span>Email</span></a></div></div></div>',
|
||||
'</div>',
|
||||
'<div class="chat-separator"></div>',
|
||||
'<div class="panel-messages" id="w-msgs">',
|
||||
'<div class="msg-wrapper"><div class="msg ai">Hey! What kind of car are you looking for?</div></div>',
|
||||
'<div class="msg-wrapper"><div class="msg ai">What kind of piping project are you working on?</div></div>',
|
||||
'</div>',
|
||||
'<div class="typing" id="w-typing"><span></span><span></span><span></span></div>',
|
||||
'<div class="popular-topics-fixed" id="w-popular-topics"><div class="popular-topics-label">POPULAR TOPICS</div><div class="popular-topics-grid"><button class="popular-topic-btn" data-topic="Get Quotation">Get Quotation</button><button class="popular-topic-btn" data-topic="Distributor Cooperation">Distributor Cooperation</button></div></div>',
|
||||
'<div class="popular-topics-fixed" id="w-popular-topics"><div class="popular-topics-label">POPULAR TOPICS</div><div class="popular-topics-grid"><button class="popular-topic-btn" data-topic="Get Quotation">Get Quotation</button><button class="popular-topic-btn" data-topic="Pipe Specifications">Pipe Specifications</button><button class="popular-topic-btn" data-topic="Delivery & Shipping">Delivery & Shipping</button></div></div>',
|
||||
'<div class="chat-separator-topics"></div>',
|
||||
'<div class="input-container"><div class="input-wrapper">',
|
||||
'<input type="text" id="w-input" placeholder="Type a message...">',
|
||||
'<button id="w-send"><span style="font-size:16px;">➤</span><span>Send</span></button>',
|
||||
'</div></div>',
|
||||
'<div class="chat-footer"><span class="footer-left">By chatting, you agree to our <a href="https://hesupipe.com/privacy-policy/" target="_blank" rel="noopener">privacy policy</a>.</span></div>',
|
||||
].join("");
|
||||
|
||||
// Invite card HTML template
|
||||
@@ -320,7 +324,7 @@
|
||||
'<div class="invite-icon"><span class="avatar-emoji">🤖</span><img class="avatar-img" alt="" src="'+avatarUrl+'"><span class="invite-status-dot"></span></div>',
|
||||
'</div>',
|
||||
'<div class="invite-header-content">',
|
||||
'<div class="invite-title">Chat with us for available vehicles, delivery timing and distributor cooperation.</div>',
|
||||
'<div class="invite-title">Chat with us for pipe specs, MOQ, delivery timing and quotations.</div>',
|
||||
'</div>',
|
||||
'<div class="invite-header-actions">',
|
||||
'<button class="invite-close-btn" aria-label="Close">',
|
||||
@@ -339,7 +343,8 @@
|
||||
'<div class="invite-body">',
|
||||
'<div class="invite-topics">',
|
||||
'<button class="invite-topic-btn" data-topic="Get Quotation">Get Quotation</button>',
|
||||
'<button class="invite-topic-btn" data-topic="Distributor Cooperation">Distributor Cooperation</button>',
|
||||
'<button class="invite-topic-btn" data-topic="Pipe Specifications">Pipe Specifications</button>',
|
||||
'<button class="invite-topic-btn" data-topic="Delivery & Shipping">Delivery & Shipping</button>',
|
||||
'</div>',
|
||||
'</div>',
|
||||
'<div class="chat-separator"></div>',
|
||||
@@ -350,6 +355,7 @@
|
||||
'</button>',
|
||||
'<button class="invite-dismiss-btn">No Thanks</button>',
|
||||
'</div>',
|
||||
'<div class="invite-privacy">By chatting, you agree to our <a href="https://hesupipe.com/privacy-policy/" target="_blank" rel="noopener">privacy policy</a>.</div>',
|
||||
'</div>',
|
||||
'</div>'
|
||||
].join("");
|
||||
|
||||
Reference in New Issue
Block a user