.
This commit is contained in:
+41
-2
@@ -606,6 +606,31 @@ function customerHashSeed(item, fallback = 0) {
|
||||
return [...raw].reduce((acc, char, index) => (acc + char.charCodeAt(0) * (index + 1)) % 997, fallback);
|
||||
}
|
||||
|
||||
function normalizedCustomerTags(item) {
|
||||
return Array.isArray(item?.tags)
|
||||
? item.tags.map((tag) => String(tag || '').trim().toLowerCase()).filter(Boolean)
|
||||
: [];
|
||||
}
|
||||
|
||||
function isFacebookCustomer(item) {
|
||||
const tags = normalizedCustomerTags(item);
|
||||
return tags.includes('facebook') || tags.includes('facebook-lead');
|
||||
}
|
||||
|
||||
function isFacebookLeadInteraction(item) {
|
||||
const subject = String(item?.subject || item?.title || '').trim().toLowerCase();
|
||||
if (subject.startsWith('[facebook]')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const customerId = item?.customer_id || item?.customerId || '';
|
||||
if (!customerId) {
|
||||
return false;
|
||||
}
|
||||
const customer = state.customers.items.find((entry) => entry.customer_id === customerId) || null;
|
||||
return isFacebookCustomer(customer);
|
||||
}
|
||||
|
||||
function customerInitials(name) {
|
||||
const parts = String(name || '')
|
||||
.trim()
|
||||
@@ -619,6 +644,9 @@ function customerInitials(name) {
|
||||
}
|
||||
|
||||
function customerLeadSourceMeta(item, index) {
|
||||
if (isFacebookCustomer(item)) {
|
||||
return { label: 'Facebook', className: 'lead-badge source-facebook' };
|
||||
}
|
||||
const variants = [
|
||||
{ label: 'Instagram', className: 'lead-badge source-instagram' },
|
||||
{ label: 'WhatsApp', className: 'lead-badge source-whatsapp' },
|
||||
@@ -629,6 +657,9 @@ function customerLeadSourceMeta(item, index) {
|
||||
}
|
||||
|
||||
function customerLeadStatusMeta(item, index) {
|
||||
if (isFacebookCustomer(item)) {
|
||||
return { label: 'Новый', className: 'lead-badge status-new' };
|
||||
}
|
||||
const variants = [
|
||||
{ label: 'Переговоры', className: 'lead-badge status-negotiation' },
|
||||
{ label: 'Квалификация', className: 'lead-badge status-qualification' },
|
||||
@@ -656,7 +687,9 @@ function customerLeadScoreClass(score) {
|
||||
}
|
||||
|
||||
function customerLeadCompany(item) {
|
||||
const tags = Array.isArray(item?.tags) ? item.tags.filter(Boolean) : [];
|
||||
const tags = (Array.isArray(item?.tags) ? item.tags : [])
|
||||
.map((tag) => String(tag || '').trim())
|
||||
.filter((tag) => tag && !['facebook', 'facebook-lead', 'hot-lead'].includes(tag.toLowerCase()));
|
||||
if (tags.length) {
|
||||
return tags[0];
|
||||
}
|
||||
@@ -3620,12 +3653,14 @@ async function createInteraction() {
|
||||
|
||||
function renderInteractionCard(item) {
|
||||
const meta = statusMeta(item.status);
|
||||
const facebookLead = isFacebookLeadInteraction(item);
|
||||
const cardClass = item.status === 'escalated'
|
||||
? 'pipeline-card escalated'
|
||||
: item.status === 'closed'
|
||||
? 'pipeline-card closed'
|
||||
: 'pipeline-card';
|
||||
const badges = [
|
||||
facebookLead ? '<span class="micro-badge facebook">Facebook</span>' : '',
|
||||
`<span class="micro-badge channel">${escapeHtml(channelLabel(item.channel))}</span>`,
|
||||
item.queue_id ? `<span class="micro-badge queue">${escapeHtml(item.queue_id)}</span>` : '',
|
||||
item.assigned_to ? `<span class="micro-badge assignee">${escapeHtml(item.assigned_to)}</span>` : '',
|
||||
@@ -3643,6 +3678,7 @@ function renderInteractionCard(item) {
|
||||
<p class="card-meta-line">Обновлено: ${escapeHtml(formatIsoShort(item.updated_at))}</p>
|
||||
<div class="card-divider"></div>
|
||||
<div class="row-actions">
|
||||
${facebookLead ? `<button type="button" data-reply-action="facebook" data-interaction-id="${escapeHtml(item.interaction_id)}">Ответить</button>` : ''}
|
||||
<button onclick="assignInteraction('${item.interaction_id}')">Назначить</button>
|
||||
<button onclick="escalateInteraction('${item.interaction_id}')">Передать на 2 линию</button>
|
||||
<button onclick="closeInteraction('${item.interaction_id}')">Закрыть</button>
|
||||
@@ -3748,7 +3784,9 @@ function buildUnifiedInboxInteractionItem(item) {
|
||||
if (!bucket) {
|
||||
return null;
|
||||
}
|
||||
const facebookLead = isFacebookLeadInteraction(item);
|
||||
const badges = [
|
||||
facebookLead ? renderUnifiedInboxBadge('Facebook', 'facebook') : '',
|
||||
renderUnifiedInboxBadge(channelLabel(item.channel), 'channel'),
|
||||
item.queue_id ? renderUnifiedInboxBadge(item.queue_id, 'queue') : '',
|
||||
item.assigned_to ? renderUnifiedInboxBadge(item.assigned_to, 'owner') : '',
|
||||
@@ -3768,6 +3806,7 @@ function buildUnifiedInboxInteractionItem(item) {
|
||||
],
|
||||
customerId: item.customer_id || '',
|
||||
interactionId: item.interaction_id,
|
||||
canReply: facebookLead,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -3890,6 +3929,7 @@ function renderUnifiedInboxCard(item) {
|
||||
const actions = [
|
||||
`<button type="button" data-inbox-action="open" data-inbox-kind="${escapeHtml(item.kind)}" data-thread-id="${escapeHtml(item.threadId || '')}" data-interaction-id="${escapeHtml(item.interactionId || '')}" data-call-id="${escapeHtml(item.callId || '')}" data-customer-id="${escapeHtml(item.customerId || '')}">${escapeHtml(unifiedInboxActionLabel(item))}</button>`,
|
||||
item.customerId ? `<button type="button" data-inbox-action="customer" data-customer-id="${escapeHtml(item.customerId)}">К клиенту</button>` : '',
|
||||
item.canReply ? `<button type="button" data-reply-action="facebook" data-interaction-id="${escapeHtml(item.interactionId || '')}">Ответить</button>` : '',
|
||||
].filter(Boolean).join('');
|
||||
|
||||
return `
|
||||
@@ -6493,4 +6533,3 @@ async function init() {
|
||||
}
|
||||
|
||||
init();
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||
<link href="https://fonts.googleapis.com/css2?family=Manrope:wght@500;600;700;800&family=IBM+Plex+Sans:wght@400;500;600&display=swap" rel="stylesheet" />
|
||||
<link rel="stylesheet" href="/operator/assets/styles.css?v=track21-voice-name-edit1" />
|
||||
<link rel="stylesheet" href="/operator/assets/styles.css?v=track41-facebook-leads1" />
|
||||
</head>
|
||||
<body>
|
||||
<div class="app-shell">
|
||||
@@ -640,6 +640,6 @@
|
||||
|
||||
<script src="/operator/assets/access-guards.js?v=track16-voice-transcript1"></script>
|
||||
<script src="/operator/assets/sip-0.21.2.min.js?v=track16-voice-transcript1"></script>
|
||||
<script src="/operator/assets/app.js?v=track40-voice-name-edit1"></script>
|
||||
<script src="/operator/assets/app.js?v=track41-facebook-leads1"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -928,6 +928,11 @@ textarea::placeholder {
|
||||
background: #e5f8ea;
|
||||
}
|
||||
|
||||
.source-facebook {
|
||||
color: #1657d8;
|
||||
background: #e7efff;
|
||||
}
|
||||
|
||||
.source-site {
|
||||
color: #3465f3;
|
||||
background: #e8f0ff;
|
||||
@@ -3153,6 +3158,12 @@ textarea::placeholder {
|
||||
color: var(--primary);
|
||||
}
|
||||
|
||||
.micro-badge.facebook {
|
||||
background: #e7efff;
|
||||
border-color: #bfd2ff;
|
||||
color: #1657d8;
|
||||
}
|
||||
|
||||
.micro-badge.queue {
|
||||
background: #f4f6fa;
|
||||
border-color: #dde4ef;
|
||||
|
||||
Reference in New Issue
Block a user