mirror of
https://github.com/dartdavros/chatballs.git
synced 2026-10-14 13:19:01 +03:00
159 lines
17 KiB
HTML
159 lines
17 KiB
HTML
<!DOCTYPE html>
|
||
<html>
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||
<script src="./support.js"></script>
|
||
</head>
|
||
<body>
|
||
<x-dc>
|
||
<helmet>
|
||
<style>
|
||
*{box-sizing:border-box;}
|
||
@keyframes wcTyping{0%,80%,100%{opacity:.25;transform:translateY(0);}40%{opacity:1;transform:translateY(-2px);}}
|
||
</style>
|
||
</helmet>
|
||
|
||
<div style="display:flex;flex-direction:column;height:100%;width:100%;background:#fff;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,'Helvetica Neue',Arial,sans-serif;color:#1f1f1f;-webkit-font-smoothing:antialiased;overflow:hidden;">
|
||
|
||
<!-- HEADER -->
|
||
<div style="flex:none;background:#1677ff;padding:14px 16px;display:flex;align-items:center;gap:11px;">
|
||
<div style="width:36px;height:36px;border-radius:10px;background:rgba(255,255,255,0.18);display:flex;align-items:center;justify-content:center;flex:none;font-size:15px;font-weight:700;color:#fff;">F</div>
|
||
<div style="flex:1;min-width:0;">
|
||
<div style="font-size:14.5px;font-weight:600;color:#fff;line-height:1.2;">Foxray</div>
|
||
<div style="display:flex;align-items:center;gap:6px;margin-top:2px;"><span style="width:7px;height:7px;border-radius:50%;background:{{ statusDot }};flex:none;"></span><span style="font-size:11.5px;color:rgba(255,255,255,0.92);">{{ statusLabel }}</span></div>
|
||
</div>
|
||
<button style="width:30px;height:30px;border-radius:8px;border:none;background:rgba(255,255,255,0.14);display:flex;align-items:center;justify-content:center;cursor:pointer;flex:none;" style-hover="background:rgba(255,255,255,0.26);"><svg viewBox="0 0 24 24" width="17" height="17" fill="none" stroke="#fff" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><line x1="5" y1="12" x2="19" y2="12"/></svg></button>
|
||
</div>
|
||
|
||
<!-- BODY -->
|
||
<div style="flex:1;min-height:0;overflow-y:auto;background:#f7f8fa;padding:16px 14px;">
|
||
|
||
<!-- WELCOME + CONSENT -->
|
||
<sc-if value="{{ isWelcome }}" hint-placeholder-val="{{ false }}">
|
||
<div style="display:flex;flex-direction:column;align-items:center;text-align:center;padding:20px 12px 8px;">
|
||
<div style="width:56px;height:56px;border-radius:16px;background:#e6f4ff;display:flex;align-items:center;justify-content:center;margin-bottom:14px;"><span style="font-size:24px;font-weight:700;color:#1677ff;">F</span></div>
|
||
<h3 style="margin:0;font-size:17px;font-weight:700;color:#1f1f1f;">Чат Foxray</h3>
|
||
<p style="margin:8px 0 0;font-size:13px;color:#595959;line-height:1.5;max-width:280px;">Здравствуйте! Помогу подобрать тариф и ответить на вопросы по Foxray. Чем можем помочь?</p>
|
||
</div>
|
||
<div style="margin-top:18px;background:#fff;border:1px solid #f0f0f0;border-radius:12px;padding:14px;">
|
||
<div style="font-size:12px;color:#595959;line-height:1.5;">Продолжая, вы соглашаетесь на обработку сообщений для ответа на обращение. <a href="#" style="color:#1677ff;text-decoration:none;">Политика обработки данных</a> · ред. v3.</div>
|
||
</div>
|
||
</sc-if>
|
||
|
||
<!-- UNAVAILABLE -->
|
||
<sc-if value="{{ isUnavailable }}" hint-placeholder-val="{{ false }}">
|
||
<div style="display:flex;flex-direction:column;align-items:center;text-align:center;padding:26px 14px;">
|
||
<div style="width:52px;height:52px;border-radius:50%;background:#fff7e6;display:flex;align-items:center;justify-content:center;margin-bottom:14px;"><svg viewBox="0 0 24 24" width="26" height="26" fill="none" stroke="#d48806" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M10.29 3.86 1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0Z"/><line x1="12" y1="9" x2="12" y2="13"/><line x1="12" y1="17" x2="12.01" y2="17"/></svg></div>
|
||
<h3 style="margin:0;font-size:15px;font-weight:700;color:#1f1f1f;">Чат временно недоступен</h3>
|
||
<p style="margin:8px 0 0;font-size:13px;color:#595959;line-height:1.5;max-width:280px;">Мы не можем принять сообщение прямо сейчас. Напишите нам в другом канале — ответим как можно скорее.</p>
|
||
<div style="display:flex;flex-direction:column;gap:9px;width:100%;max-width:280px;margin-top:18px;">
|
||
<a href="#" style="display:flex;align-items:center;gap:10px;padding:11px 13px;border:1px solid #efdbff;background:#fff;border-radius:10px;text-decoration:none;" style-hover="border-color:#6b5be0;"><span style="width:26px;height:26px;border-radius:7px;background:#f2f0ff;display:flex;align-items:center;justify-content:center;flex:none;"><span style="width:9px;height:9px;border-radius:50%;background:#6b5be0;"></span></span><span style="font-size:13px;font-weight:500;color:#262626;flex:1;text-align:left;">Написать в MAX</span><svg viewBox="0 0 24 24" width="15" height="15" fill="none" stroke="#bfbfbf" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="9 18 15 12 9 6"/></svg></a>
|
||
<a href="#" style="display:flex;align-items:center;gap:10px;padding:11px 13px;border:1px solid #d6ebfa;background:#fff;border-radius:10px;text-decoration:none;" style-hover="border-color:#2f8fd0;"><span style="width:26px;height:26px;border-radius:7px;background:#eaf6fd;display:flex;align-items:center;justify-content:center;flex:none;"><span style="width:9px;height:9px;border-radius:50%;background:#2f8fd0;"></span></span><span style="font-size:13px;font-weight:500;color:#262626;flex:1;text-align:left;">Написать в Telegram</span><svg viewBox="0 0 24 24" width="15" height="15" fill="none" stroke="#bfbfbf" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="9 18 15 12 9 6"/></svg></a>
|
||
</div>
|
||
</div>
|
||
</sc-if>
|
||
|
||
<!-- CONVERSATION (ai / operator / checkout) -->
|
||
<sc-if value="{{ isConversation }}" hint-placeholder-val="{{ true }}">
|
||
<div style="text-align:center;margin-bottom:14px;"><span style="display:inline-block;padding:3px 11px;border-radius:20px;background:#eef0f2;font-size:11px;color:#8c8c8c;">Сегодня</span></div>
|
||
|
||
<!-- client -->
|
||
<div style="display:flex;justify-content:flex-end;margin-bottom:10px;"><div style="max-width:78%;"><div style="background:#1677ff;color:#fff;border-radius:14px 14px 4px 14px;padding:9px 13px;font-size:13.5px;line-height:1.45;">Здравствуйте! Чем Max отличается от Pro?</div><div style="font-size:10.5px;color:#bfbfbf;margin:3px 4px 0 0;text-align:right;">14:01 · доставлено</div></div></div>
|
||
|
||
<!-- AI -->
|
||
<div style="display:flex;gap:8px;margin-bottom:10px;"><div style="width:28px;height:28px;border-radius:50%;background:#eef0f2;border:1px solid #e3e6ea;display:flex;align-items:center;justify-content:center;flex:none;"><svg viewBox="0 0 24 24" width="15" height="15" fill="none" stroke="#8c8c8c" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="8" r="3.2"/><path d="M5.5 20a6.5 6.5 0 0 1 13 0"/></svg></div><div style="max-width:78%;"><div style="background:#fff;border:1px solid #eee;border-radius:14px 14px 14px 4px;padding:9px 13px;font-size:13.5px;line-height:1.45;color:#262626;">Pro — для одного пользователя (₽4 900/мес), Max — командный с расширенными лимитами и приоритетной поддержкой (₽9 900/мес). При оплате за год — скидка 20%.</div><div style="font-size:10.5px;color:#bfbfbf;margin:3px 0 0 4px;">Оператор · 14:01</div></div></div>
|
||
|
||
<!-- client -->
|
||
<div style="display:flex;justify-content:flex-end;margin-bottom:10px;"><div style="max-width:78%;"><div style="background:#1677ff;color:#fff;border-radius:14px 14px 4px 14px;padding:9px 13px;font-size:13.5px;line-height:1.45;">Нас 6 человек, берём Max на год.</div><div style="font-size:10.5px;color:#bfbfbf;margin:3px 4px 0 0;text-align:right;">14:02 · доставлено</div></div></div>
|
||
|
||
<!-- OPERATOR handoff + reply -->
|
||
<sc-if value="{{ isOperator }}" hint-placeholder-val="{{ false }}">
|
||
<div style="text-align:center;margin:14px 0 12px;"><span style="display:inline-flex;align-items:center;gap:6px;padding:5px 13px;border-radius:20px;background:#e6f4ff;border:1px solid #91caff;font-size:11.5px;color:#0958d9;font-weight:500;"><svg viewBox="0 0 24 24" width="12" height="12" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/></svg>Подключился специалист · история уже у него</span></div>
|
||
<div style="display:flex;gap:8px;margin-bottom:10px;"><div style="width:28px;height:28px;border-radius:50%;background:#1677ff;color:#fff;display:flex;align-items:center;justify-content:center;flex:none;font-size:11px;font-weight:600;">АК</div><div style="max-width:78%;"><div style="background:#fff;border:1px solid #eee;border-radius:14px 14px 14px 4px;padding:9px 13px;font-size:13.5px;line-height:1.45;color:#262626;">Здравствуйте! Анна, Foxray. Помогу с оформлением Max на 6 мест с годовой скидкой — подготовлю ссылку на оплату.</div><div style="font-size:10.5px;color:#bfbfbf;margin:3px 0 0 4px;">Анна · специалист · 14:03</div></div></div>
|
||
</sc-if>
|
||
|
||
<!-- AI typing (ai-only) -->
|
||
<sc-if value="{{ isAI }}" hint-placeholder-val="{{ false }}">
|
||
<div style="display:flex;gap:8px;margin-bottom:4px;"><div style="width:28px;height:28px;border-radius:50%;background:#eef0f2;border:1px solid #e3e6ea;display:flex;align-items:center;justify-content:center;flex:none;"><svg viewBox="0 0 24 24" width="15" height="15" fill="none" stroke="#8c8c8c" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="8" r="3.2"/><path d="M5.5 20a6.5 6.5 0 0 1 13 0"/></svg></div><div style="background:#fff;border:1px solid #eee;border-radius:14px 14px 14px 4px;padding:12px 14px;display:flex;align-items:center;gap:5px;"><span style="width:6px;height:6px;border-radius:50%;background:#b37feb;animation:wcTyping 1.2s infinite ease-in-out;"></span><span style="width:6px;height:6px;border-radius:50%;background:#b37feb;animation:wcTyping 1.2s infinite ease-in-out .2s;"></span><span style="width:6px;height:6px;border-radius:50%;background:#b37feb;animation:wcTyping 1.2s infinite ease-in-out .4s;"></span></div></div>
|
||
</sc-if>
|
||
|
||
<!-- CHECKOUT card -->
|
||
<sc-if value="{{ isCheckout }}" hint-placeholder-val="{{ false }}">
|
||
<div style="display:flex;gap:8px;margin-bottom:6px;"><div style="width:28px;height:28px;border-radius:50%;background:#1677ff;color:#fff;display:flex;align-items:center;justify-content:center;flex:none;font-size:11px;font-weight:600;">АК</div><div style="max-width:84%;width:100%;"><div style="background:#fff;border:1px solid #e8e8e8;border-radius:14px;overflow:hidden;box-shadow:0 1px 3px rgba(0,0,0,0.06);">
|
||
<div style="padding:13px 15px 11px;border-bottom:1px solid #f5f5f5;"><div style="font-size:11px;font-weight:600;letter-spacing:0.04em;color:#722ed1;margin-bottom:6px;">ОФОРМЛЕНИЕ ПОКУПКИ</div><div style="font-size:15px;font-weight:700;color:#1f1f1f;">Foxray Max · 6 мест</div><div style="display:flex;align-items:baseline;gap:7px;margin-top:7px;"><span style="font-size:21px;font-weight:700;color:#1f1f1f;">₽95 040</span><span style="font-size:12px;color:#8c8c8c;">/ год · −20%</span></div><div style="font-size:11.5px;color:#bfbfbf;margin-top:3px;text-decoration:line-through;">₽118 800 без скидки</div></div>
|
||
<div style="padding:11px 15px 13px;"><a href="#" style="display:flex;align-items:center;justify-content:center;gap:7px;height:40px;border-radius:9px;background:#1677ff;color:#fff;font-size:13.5px;font-weight:600;text-decoration:none;" style-hover="background:#0958d9;">Перейти к покупке<svg viewBox="0 0 24 24" width="15" height="15" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12h14"/><polyline points="12 5 19 12 12 19"/></svg></a><div style="font-size:10.5px;color:#bfbfbf;text-align:center;margin-top:8px;">Оплата на защищённой странице Foxray</div></div>
|
||
</div><div style="font-size:10.5px;color:#bfbfbf;margin:3px 0 0 4px;">Анна · специалист · 14:04</div></div></div>
|
||
</sc-if>
|
||
</sc-if>
|
||
|
||
</div>
|
||
|
||
<!-- COMPOSER -->
|
||
<sc-if value="{{ showComposer }}" hint-placeholder-val="{{ true }}">
|
||
<div style="flex:none;background:#fff;border-top:1px solid #f0f0f0;padding:10px 12px 12px;">
|
||
<sc-if value="{{ showQuick }}" hint-placeholder-val="{{ false }}">
|
||
<div style="display:flex;gap:7px;flex-wrap:wrap;margin-bottom:9px;">
|
||
<button style="padding:6px 12px;border-radius:16px;border:1px solid #d6e4ff;background:#f0f7ff;color:#0958d9;font-size:12px;font-weight:500;cursor:pointer;" style-hover="background:#e6f4ff;">Сравнить тарифы</button>
|
||
<button style="padding:6px 12px;border-radius:16px;border:1px solid #d6e4ff;background:#f0f7ff;color:#0958d9;font-size:12px;font-weight:500;cursor:pointer;" style-hover="background:#e6f4ff;">Есть ли пробный период?</button>
|
||
<button style="padding:6px 12px;border-radius:16px;border:1px solid #d6e4ff;background:#f0f7ff;color:#0958d9;font-size:12px;font-weight:500;cursor:pointer;" style-hover="background:#e6f4ff;">Оплата за год</button>
|
||
</div>
|
||
</sc-if>
|
||
<div style="display:flex;align-items:flex-end;gap:8px;border:1px solid #e8e8e8;border-radius:12px;padding:6px 6px 6px 12px;background:#fff;" style-focus="border-color:#1677ff;">
|
||
<button style="width:30px;height:30px;border-radius:7px;border:none;background:transparent;display:flex;align-items:center;justify-content:center;cursor:pointer;color:#8c8c8c;flex:none;" style-hover="background:#f5f5f5;color:#262626;"><svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="m21.44 11.05-9.19 9.19a6 6 0 0 1-8.49-8.49l8.57-8.57A4 4 0 1 1 18 8.84l-8.59 8.57a2 2 0 0 1-2.83-2.83l8.49-8.48"/></svg></button>
|
||
<textarea rows="1" placeholder="Напишите сообщение…" style="flex:1;border:none;outline:none;resize:none;font-size:13.5px;line-height:1.5;color:#262626;font-family:inherit;padding:6px 0;max-height:90px;"></textarea>
|
||
<button style="width:34px;height:34px;border-radius:8px;border:none;background:#1677ff;display:flex;align-items:center;justify-content:center;cursor:pointer;flex:none;" style-hover="background:#0958d9;"><svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="#fff" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="22" y1="2" x2="11" y2="13"/><polygon points="22 2 15 22 11 13 2 9 22 2"/></svg></button>
|
||
</div>
|
||
</div>
|
||
</sc-if>
|
||
|
||
<!-- CONSENT ACTION (welcome) -->
|
||
<sc-if value="{{ isWelcome }}" hint-placeholder-val="{{ false }}">
|
||
<div style="flex:none;background:#fff;border-top:1px solid #f0f0f0;padding:12px 14px 14px;">
|
||
<button style="width:100%;height:44px;border-radius:10px;border:none;background:#1677ff;color:#fff;font-size:14px;font-weight:600;cursor:pointer;" style-hover="background:#0958d9;">Принять и начать чат</button>
|
||
</div>
|
||
</sc-if>
|
||
|
||
<!-- UNAVAILABLE: no false-send -->
|
||
<sc-if value="{{ isUnavailable }}" hint-placeholder-val="{{ false }}">
|
||
<div style="flex:none;background:#fafafa;border-top:1px solid #f0f0f0;padding:12px 14px;display:flex;align-items:center;gap:9px;justify-content:center;">
|
||
<svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="#bfbfbf" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="4.9" y1="4.9" x2="19.1" y2="19.1"/></svg>
|
||
<span style="font-size:12px;color:#8c8c8c;">Отправка сообщений недоступна</span>
|
||
</div>
|
||
</sc-if>
|
||
</div>
|
||
</x-dc>
|
||
<script type="text/x-dc" data-dc-script data-props="{
|
||
"$preview": { "width": 380, "height": 580 },
|
||
"state": { "editor": "enum", "options": ["welcome", "ai", "operator", "checkout", "unavailable"], "default": "ai", "tsType": "string" }
|
||
}">
|
||
class Component extends DCLogic {
|
||
renderVals() {
|
||
const state = this.props.state ?? 'ai';
|
||
const isWelcome = state === 'welcome';
|
||
const isAI = state === 'ai';
|
||
const isOperator = state === 'operator';
|
||
const isCheckout = state === 'checkout';
|
||
const isUnavailable = state === 'unavailable';
|
||
const isConversation = isAI || isOperator || isCheckout;
|
||
|
||
const status = isOperator || isCheckout
|
||
? { statusLabel: 'Отвечает специалист', statusDot: '#52c41a' }
|
||
: isUnavailable
|
||
? { statusLabel: 'Временно недоступен', statusDot: '#faad14' }
|
||
: isWelcome
|
||
? { statusLabel: 'Обычно отвечаем за пару минут', statusDot: '#52c41a' }
|
||
: { statusLabel: 'Оператор · на связи', statusDot: '#52c41a' };
|
||
|
||
return {
|
||
isWelcome, isAI, isOperator, isCheckout, isUnavailable, isConversation,
|
||
...status,
|
||
showComposer: isConversation,
|
||
showQuick: isAI,
|
||
};
|
||
}
|
||
}
|
||
</script>
|
||
</body>
|
||
</html>
|