@escalated-dev/escalated 0.8.0 → 0.11.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -21
- package/README.md +388 -361
- package/package.json +85 -84
- package/src/components/ActiveChatsPanel.vue +246 -246
- package/src/components/AdminDashboard.stories.js +1423 -1423
- package/src/components/AttachmentList.vue +65 -65
- package/src/components/ChatActionBar.vue +226 -226
- package/src/components/ChatBubble.vue +162 -162
- package/src/components/ChatComposer.vue +308 -308
- package/src/components/ChatQueue.vue +222 -222
- package/src/components/ChatThread.vue +197 -197
- package/src/components/CustomTicketActions.stories.js +71 -0
- package/src/components/CustomTicketActions.vue +101 -0
- package/src/components/EscalatedLayout.vue +628 -604
- package/src/components/FollowButton.vue +20 -1
- package/src/components/MentionDropdown.vue +154 -154
- package/src/components/MetricComparison.vue +89 -89
- package/src/components/PercentileChart.vue +67 -67
- package/src/components/PeriodSelector.vue +98 -98
- package/src/components/PresenceIndicator.vue +228 -213
- package/src/components/ReplyComposer.vue +336 -336
- package/src/components/ReplyThread.vue +153 -153
- package/src/components/ReportChart.vue +395 -395
- package/src/components/ReportExportButton.vue +108 -108
- package/src/components/SaveViewDialog.vue +172 -172
- package/src/components/SavedViewSidebar.vue +208 -208
- package/src/components/SkillTagManager.vue +3 -0
- package/src/components/SnoozeButton.vue +247 -247
- package/src/components/TicketFilters.vue +270 -270
- package/src/components/TicketList.vue +655 -655
- package/src/components/TicketSidebar.vue +4 -0
- package/src/components/TicketSplitDialog.vue +98 -98
- package/src/components/TicketSubjects.stories.js +63 -0
- package/src/components/TicketSubjects.vue +107 -0
- package/src/components/TwoFactorSetup.vue +1 -37
- package/src/components/VariableTokenInput.vue +111 -111
- package/src/components/WorkflowActionConfig.vue +287 -287
- package/src/components/WorkflowActionList.vue +350 -350
- package/src/components/WorkflowConditionBuilder.vue +265 -265
- package/src/components/WorkflowTriggerSelector.vue +125 -125
- package/src/components/admin/newsletters/AnalyticsTiles.stories.js +14 -0
- package/src/components/admin/newsletters/AnalyticsTiles.vue +55 -0
- package/src/components/admin/newsletters/DeliveriesTable.stories.js +28 -0
- package/src/components/admin/newsletters/DeliveriesTable.vue +104 -0
- package/src/components/admin/newsletters/DynamicFilterBuilder.stories.js +11 -0
- package/src/components/admin/newsletters/DynamicFilterBuilder.vue +53 -0
- package/src/components/admin/newsletters/ListMemberTable.stories.js +12 -0
- package/src/components/admin/newsletters/ListMemberTable.vue +53 -0
- package/src/components/admin/newsletters/MarkdownEditor.stories.js +6 -0
- package/src/components/admin/newsletters/MarkdownEditor.vue +53 -0
- package/src/components/admin/newsletters/MergeFieldDropdown.stories.js +6 -0
- package/src/components/admin/newsletters/MergeFieldDropdown.vue +84 -0
- package/src/components/admin/newsletters/PreviewIframe.stories.js +7 -0
- package/src/components/admin/newsletters/PreviewIframe.vue +40 -0
- package/src/components/admin/newsletters/SummaryTiles.stories.js +8 -0
- package/src/components/admin/newsletters/SummaryTiles.vue +63 -0
- package/src/composables/useChat.js +187 -187
- package/src/composables/useI18n.js +102 -102
- package/src/composables/useMentions.js +134 -134
- package/src/composables/usePermissions.js +31 -0
- package/src/composables/useRealtime.js +182 -182
- package/src/index.js +85 -84
- package/src/locales/README.md +13 -13
- package/src/locales/ar.json +727 -727
- package/src/locales/de.json +690 -690
- package/src/locales/en.json +889 -729
- package/src/locales/es.json +691 -691
- package/src/locales/fr.json +691 -691
- package/src/locales/index.js +16 -16
- package/src/locales/it.json +727 -727
- package/src/locales/ja.json +727 -727
- package/src/locales/ko.json +727 -727
- package/src/locales/nl.json +727 -727
- package/src/locales/pl.json +727 -727
- package/src/locales/pt-BR.json +727 -727
- package/src/locales/ru.json +727 -727
- package/src/locales/tr.json +727 -727
- package/src/locales/zh-CN.json +727 -727
- package/src/pages/Admin/Automations/Form.vue +280 -0
- package/src/pages/Admin/Automations/Index.vue +230 -0
- package/src/pages/Admin/Newsletters/Compose.vue +192 -0
- package/src/pages/Admin/Newsletters/Edit.vue +24 -0
- package/src/pages/Admin/Newsletters/Index.vue +141 -0
- package/src/pages/Admin/Newsletters/Lists/Create.vue +64 -0
- package/src/pages/Admin/Newsletters/Lists/Index.vue +59 -0
- package/src/pages/Admin/Newsletters/Lists/Show.vue +53 -0
- package/src/pages/Admin/Newsletters/Settings.vue +85 -0
- package/src/pages/Admin/Newsletters/Show.vue +140 -0
- package/src/pages/Admin/Newsletters/Templates/Create.vue +11 -0
- package/src/pages/Admin/Newsletters/Templates/Index.vue +54 -0
- package/src/pages/Admin/Newsletters/Templates/Show.vue +65 -0
- package/src/pages/Admin/Newsletters/usePreview.js +44 -0
- package/src/pages/Admin/Plugins/Index.vue +10 -2
- package/src/pages/Admin/Reports/AgentDetail.vue +132 -132
- package/src/pages/Admin/Reports/AgentRanking.vue +246 -246
- package/src/pages/Admin/Reports/Cohorts.vue +180 -180
- package/src/pages/Admin/Reports/Comparison.vue +141 -141
- package/src/pages/Admin/Reports/Dashboard.vue +226 -226
- package/src/pages/Admin/Reports/ResolutionTimes.vue +164 -164
- package/src/pages/Admin/Reports/ResponseTimes.vue +164 -164
- package/src/pages/Admin/Reports/SlaTrends.vue +183 -183
- package/src/pages/Admin/Settings/DatabaseConnection.vue +228 -0
- package/src/pages/Admin/Settings/PublicTickets.vue +163 -0
- package/src/pages/Admin/Settings/SsoSettings.vue +157 -4
- package/src/pages/Admin/Settings/TwoFactor.vue +32 -6
- package/src/pages/Admin/Settings.vue +1008 -1008
- package/src/pages/Admin/Skills/Form.vue +30 -10
- package/src/pages/Admin/Tickets/Index.vue +126 -126
- package/src/pages/Admin/Tickets/Show.vue +254 -249
- package/src/pages/Admin/Users/Index.vue +145 -145
- package/src/pages/Admin/Webhooks/DeliveryLog.vue +1 -2
- package/src/pages/Admin/Workflows/Builder.vue +207 -207
- package/src/pages/Admin/Workflows/Form.vue +24 -0
- package/src/pages/Admin/Workflows/Index.vue +235 -235
- package/src/pages/Admin/Workflows/Logs.vue +286 -286
- package/src/pages/Agent/TicketIndex.vue +112 -112
- package/src/pages/Agent/TicketShow.vue +547 -494
- package/src/pages/Customer/Index.vue +56 -56
- package/src/pages/Customer/KnowledgeBase/Article.vue +129 -129
- package/src/pages/Plugin/Page.vue +61 -0
- package/src/plugin.js +175 -175
- package/src/utils/mentionHighlight.js +24 -24
- package/src/widget/EscalatedWidget.vue +804 -804
- package/src/widget/index.js +254 -254
|
@@ -1,1008 +1,1008 @@
|
|
|
1
|
-
<script setup>
|
|
2
|
-
import EscalatedLayout from '../../components/EscalatedLayout.vue';
|
|
3
|
-
import PluginSlot from '../../components/PluginSlot.vue';
|
|
4
|
-
import { useForm, usePage } from '@inertiajs/vue3';
|
|
5
|
-
import { computed } from 'vue';
|
|
6
|
-
import { usePluginExtensions } from '../../composables/usePluginExtensions';
|
|
7
|
-
|
|
8
|
-
const props = defineProps({ settings: Object, departments: Array });
|
|
9
|
-
const page = usePage();
|
|
10
|
-
|
|
11
|
-
const form = useForm({
|
|
12
|
-
guest_tickets_enabled: props.settings.guest_tickets_enabled,
|
|
13
|
-
allow_customer_close: props.settings.allow_customer_close,
|
|
14
|
-
auto_close_resolved_after_days: props.settings.auto_close_resolved_after_days,
|
|
15
|
-
max_attachments_per_reply: props.settings.max_attachments_per_reply,
|
|
16
|
-
max_attachment_size_kb: props.settings.max_attachment_size_kb,
|
|
17
|
-
ticket_reference_prefix: props.settings.ticket_reference_prefix,
|
|
18
|
-
inbound_email_enabled: props.settings.inbound_email_enabled ?? false,
|
|
19
|
-
inbound_email_adapter: props.settings.inbound_email_adapter ?? 'mailgun',
|
|
20
|
-
inbound_email_address: props.settings.inbound_email_address ?? '',
|
|
21
|
-
mailgun_signing_key: props.settings.mailgun_signing_key ?? '',
|
|
22
|
-
postmark_inbound_token: props.settings.postmark_inbound_token ?? '',
|
|
23
|
-
ses_region: props.settings.ses_region ?? '',
|
|
24
|
-
ses_topic_arn: props.settings.ses_topic_arn ?? '',
|
|
25
|
-
imap_host: props.settings.imap_host ?? '',
|
|
26
|
-
imap_port: props.settings.imap_port ?? 993,
|
|
27
|
-
imap_encryption: props.settings.imap_encryption ?? 'ssl',
|
|
28
|
-
imap_username: props.settings.imap_username ?? '',
|
|
29
|
-
imap_password: props.settings.imap_password ?? '',
|
|
30
|
-
imap_mailbox: props.settings.imap_mailbox ?? 'INBOX',
|
|
31
|
-
show_powered_by: props.settings.show_powered_by ?? true,
|
|
32
|
-
widget_enabled: props.settings.widget_enabled ?? false,
|
|
33
|
-
widget_color: props.settings.widget_color ?? '#4F46E5',
|
|
34
|
-
widget_position: props.settings.widget_position ?? 'bottom-right',
|
|
35
|
-
widget_greeting: props.settings.widget_greeting ?? 'Hi there! How can we help?',
|
|
36
|
-
widget_departments: props.settings.widget_departments ?? '',
|
|
37
|
-
knowledge_base_enabled: props.settings.knowledge_base_enabled ?? true,
|
|
38
|
-
knowledge_base_public: props.settings.knowledge_base_public ?? true,
|
|
39
|
-
knowledge_base_feedback_enabled: props.settings.knowledge_base_feedback_enabled ?? true,
|
|
40
|
-
// Chat settings
|
|
41
|
-
chat_enabled: props.settings.chat_enabled ?? false,
|
|
42
|
-
chat_sound_notifications: props.settings.chat_sound_notifications ?? true,
|
|
43
|
-
chat_pre_chat_name: props.settings.chat_pre_chat_name ?? true,
|
|
44
|
-
chat_pre_chat_email: props.settings.chat_pre_chat_email ?? true,
|
|
45
|
-
chat_pre_chat_department: props.settings.chat_pre_chat_department ?? false,
|
|
46
|
-
chat_routing_strategy: props.settings.chat_routing_strategy ?? 'round_robin',
|
|
47
|
-
chat_offline_behavior: props.settings.chat_offline_behavior ?? 'ticket_form',
|
|
48
|
-
chat_max_queue: props.settings.chat_max_queue ?? 10,
|
|
49
|
-
chat_concurrent_limit: props.settings.chat_concurrent_limit ?? 5,
|
|
50
|
-
chat_auto_close_minutes: props.settings.chat_auto_close_minutes ?? 30,
|
|
51
|
-
chat_queue_message: props.settings.chat_queue_message ?? '',
|
|
52
|
-
chat_offline_message: props.settings.chat_offline_message ?? '',
|
|
53
|
-
// Widget theme
|
|
54
|
-
widget_primary_color: props.settings.widget_primary_color ?? '#4F46E5',
|
|
55
|
-
widget_background_color: props.settings.widget_background_color ?? '#ffffff',
|
|
56
|
-
widget_text_color: props.settings.widget_text_color ?? '#1f2937',
|
|
57
|
-
widget_agent_bubble_color: props.settings.widget_agent_bubble_color ?? '#4F46E5',
|
|
58
|
-
widget_customer_bubble_color: props.settings.widget_customer_bubble_color ?? '#f3f4f6',
|
|
59
|
-
widget_header_background: props.settings.widget_header_background ?? '#4F46E5',
|
|
60
|
-
widget_font_family: props.settings.widget_font_family ?? 'system',
|
|
61
|
-
widget_border_radius: props.settings.widget_border_radius ?? 12,
|
|
62
|
-
widget_launcher_size: props.settings.widget_launcher_size ?? 'medium',
|
|
63
|
-
widget_show_branding: props.settings.widget_show_branding ?? true,
|
|
64
|
-
widget_custom_css: props.settings.widget_custom_css ?? '',
|
|
65
|
-
widget_pre_chat_message: props.settings.widget_pre_chat_message ?? '',
|
|
66
|
-
widget_chat_header_text: props.settings.widget_chat_header_text ?? 'Support',
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
const webhookBaseUrl = computed(() => {
|
|
70
|
-
const prefix = page.props.escalated?.prefix || 'support';
|
|
71
|
-
const origin = typeof window !== 'undefined' ? window.location.origin : '';
|
|
72
|
-
return `${origin}/${prefix}/inbound`;
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
const { getPageComponents } = usePluginExtensions();
|
|
76
|
-
|
|
77
|
-
function submit() {
|
|
78
|
-
form.post(route('escalated.admin.settings.update'));
|
|
79
|
-
}
|
|
80
|
-
</script>
|
|
81
|
-
|
|
82
|
-
<template>
|
|
83
|
-
<EscalatedLayout title="Settings">
|
|
84
|
-
<form class="mx-auto max-w-2xl space-y-6" @submit.prevent="submit">
|
|
85
|
-
<!-- General -->
|
|
86
|
-
<div class="rounded-xl border border-[var(--esc-panel-border)] bg-[var(--esc-panel-surface)] p-6">
|
|
87
|
-
<h3 class="mb-5 text-sm font-semibold text-[var(--esc-panel-text)]">General</h3>
|
|
88
|
-
<div class="space-y-5">
|
|
89
|
-
<label class="flex items-center justify-between">
|
|
90
|
-
<div>
|
|
91
|
-
<span class="text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
92
|
-
>Guest Tickets</span
|
|
93
|
-
>
|
|
94
|
-
<p class="mt-0.5 text-xs text-[var(--esc-panel-text-muted)]">
|
|
95
|
-
Allow visitors to submit tickets without signing in
|
|
96
|
-
</p>
|
|
97
|
-
</div>
|
|
98
|
-
<button
|
|
99
|
-
type="button"
|
|
100
|
-
:class="[
|
|
101
|
-
'relative inline-flex h-6 w-11 shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors',
|
|
102
|
-
form.guest_tickets_enabled ? 'bg-emerald-500' : 'bg-neutral-700',
|
|
103
|
-
]"
|
|
104
|
-
@click="form.guest_tickets_enabled = !form.guest_tickets_enabled"
|
|
105
|
-
>
|
|
106
|
-
<span
|
|
107
|
-
:class="[
|
|
108
|
-
'pointer-events-none inline-block h-5 w-5 transform rounded-full bg-white shadow ring-0 transition-transform',
|
|
109
|
-
form.guest_tickets_enabled ? 'translate-x-5' : 'translate-x-0',
|
|
110
|
-
]"
|
|
111
|
-
/>
|
|
112
|
-
</button>
|
|
113
|
-
</label>
|
|
114
|
-
|
|
115
|
-
<label class="flex items-center justify-between">
|
|
116
|
-
<div>
|
|
117
|
-
<span class="text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
118
|
-
>Allow Customer Close</span
|
|
119
|
-
>
|
|
120
|
-
<p class="mt-0.5 text-xs text-[var(--esc-panel-text-muted)]">
|
|
121
|
-
Let customers close their own tickets
|
|
122
|
-
</p>
|
|
123
|
-
</div>
|
|
124
|
-
<button
|
|
125
|
-
type="button"
|
|
126
|
-
:class="[
|
|
127
|
-
'relative inline-flex h-6 w-11 shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors',
|
|
128
|
-
form.allow_customer_close ? 'bg-emerald-500' : 'bg-neutral-700',
|
|
129
|
-
]"
|
|
130
|
-
@click="form.allow_customer_close = !form.allow_customer_close"
|
|
131
|
-
>
|
|
132
|
-
<span
|
|
133
|
-
:class="[
|
|
134
|
-
'pointer-events-none inline-block h-5 w-5 transform rounded-full bg-white shadow ring-0 transition-transform',
|
|
135
|
-
form.allow_customer_close ? 'translate-x-5' : 'translate-x-0',
|
|
136
|
-
]"
|
|
137
|
-
/>
|
|
138
|
-
</button>
|
|
139
|
-
</label>
|
|
140
|
-
|
|
141
|
-
<div>
|
|
142
|
-
<label class="block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
143
|
-
>Auto-close resolved tickets after</label
|
|
144
|
-
>
|
|
145
|
-
<p class="mt-0.5 text-xs text-[var(--esc-panel-text-muted)]">
|
|
146
|
-
Days after resolution before auto-closing (0 to disable)
|
|
147
|
-
</p>
|
|
148
|
-
<div class="mt-2 flex items-center gap-2">
|
|
149
|
-
<input
|
|
150
|
-
v-model.number="form.auto_close_resolved_after_days"
|
|
151
|
-
type="number"
|
|
152
|
-
min="0"
|
|
153
|
-
max="365"
|
|
154
|
-
class="w-24 rounded-lg border border-[var(--esc-panel-border-input)] bg-[var(--esc-panel-surface-alt)] px-3 py-2 text-sm text-[var(--esc-panel-text-secondary)] focus:border-[var(--esc-panel-border-input)] focus:outline-none focus:ring-1 focus:ring-[var(--esc-panel-border-input)]"
|
|
155
|
-
/>
|
|
156
|
-
<span class="text-sm text-[var(--esc-panel-text-muted)]">days</span>
|
|
157
|
-
</div>
|
|
158
|
-
</div>
|
|
159
|
-
</div>
|
|
160
|
-
</div>
|
|
161
|
-
|
|
162
|
-
<!-- Limits -->
|
|
163
|
-
<div class="rounded-xl border border-[var(--esc-panel-border)] bg-[var(--esc-panel-surface)] p-6">
|
|
164
|
-
<h3 class="mb-5 text-sm font-semibold text-[var(--esc-panel-text)]">Limits</h3>
|
|
165
|
-
<div class="space-y-5">
|
|
166
|
-
<div>
|
|
167
|
-
<label class="block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
168
|
-
>Max attachments per reply</label
|
|
169
|
-
>
|
|
170
|
-
<input
|
|
171
|
-
v-model.number="form.max_attachments_per_reply"
|
|
172
|
-
type="number"
|
|
173
|
-
min="1"
|
|
174
|
-
max="20"
|
|
175
|
-
class="mt-2 w-24 rounded-lg border border-[var(--esc-panel-border-input)] bg-[var(--esc-panel-surface-alt)] px-3 py-2 text-sm text-[var(--esc-panel-text-secondary)] focus:border-[var(--esc-panel-border-input)] focus:outline-none focus:ring-1 focus:ring-[var(--esc-panel-border-input)]"
|
|
176
|
-
/>
|
|
177
|
-
</div>
|
|
178
|
-
<div>
|
|
179
|
-
<label class="block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
180
|
-
>Max attachment size</label
|
|
181
|
-
>
|
|
182
|
-
<div class="mt-2 flex items-center gap-2">
|
|
183
|
-
<input
|
|
184
|
-
v-model.number="form.max_attachment_size_kb"
|
|
185
|
-
type="number"
|
|
186
|
-
min="512"
|
|
187
|
-
max="102400"
|
|
188
|
-
step="512"
|
|
189
|
-
class="w-32 rounded-lg border border-[var(--esc-panel-border-input)] bg-[var(--esc-panel-surface-alt)] px-3 py-2 text-sm text-[var(--esc-panel-text-secondary)] focus:border-[var(--esc-panel-border-input)] focus:outline-none focus:ring-1 focus:ring-[var(--esc-panel-border-input)]"
|
|
190
|
-
/>
|
|
191
|
-
<span class="text-sm text-[var(--esc-panel-text-muted)]"
|
|
192
|
-
>KB ({{ Math.round(form.max_attachment_size_kb / 1024) }} MB)</span
|
|
193
|
-
>
|
|
194
|
-
</div>
|
|
195
|
-
</div>
|
|
196
|
-
</div>
|
|
197
|
-
</div>
|
|
198
|
-
|
|
199
|
-
<!-- Tickets -->
|
|
200
|
-
<div class="rounded-xl border border-[var(--esc-panel-border)] bg-[var(--esc-panel-surface)] p-6">
|
|
201
|
-
<h3 class="mb-5 text-sm font-semibold text-[var(--esc-panel-text)]">Tickets</h3>
|
|
202
|
-
<div class="space-y-5">
|
|
203
|
-
<div>
|
|
204
|
-
<label class="block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
205
|
-
>Reference Prefix</label
|
|
206
|
-
>
|
|
207
|
-
<p class="mt-0.5 text-xs text-[var(--esc-panel-text-muted)]">
|
|
208
|
-
Prefix for ticket references (e.g. ESC produces ESC-00001)
|
|
209
|
-
</p>
|
|
210
|
-
<input
|
|
211
|
-
v-model="form.ticket_reference_prefix"
|
|
212
|
-
type="text"
|
|
213
|
-
maxlength="10"
|
|
214
|
-
class="mt-2 w-32 rounded-lg border border-[var(--esc-panel-border-input)] bg-[var(--esc-panel-surface-alt)] px-3 py-2 text-sm text-[var(--esc-panel-text-secondary)] uppercase focus:border-[var(--esc-panel-border-input)] focus:outline-none focus:ring-1 focus:ring-[var(--esc-panel-border-input)]"
|
|
215
|
-
/>
|
|
216
|
-
</div>
|
|
217
|
-
</div>
|
|
218
|
-
</div>
|
|
219
|
-
|
|
220
|
-
<!-- Inbound Email -->
|
|
221
|
-
<div class="rounded-xl border border-[var(--esc-panel-border)] bg-[var(--esc-panel-surface)] p-6">
|
|
222
|
-
<h3 class="mb-5 text-sm font-semibold text-[var(--esc-panel-text)]">Inbound Email</h3>
|
|
223
|
-
<div class="space-y-5">
|
|
224
|
-
<label class="flex items-center justify-between">
|
|
225
|
-
<div>
|
|
226
|
-
<span class="text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
227
|
-
>Inbound Email</span
|
|
228
|
-
>
|
|
229
|
-
<p class="mt-0.5 text-xs text-[var(--esc-panel-text-muted)]">
|
|
230
|
-
Allow creating and replying to tickets via email
|
|
231
|
-
</p>
|
|
232
|
-
</div>
|
|
233
|
-
<button
|
|
234
|
-
type="button"
|
|
235
|
-
:class="[
|
|
236
|
-
'relative inline-flex h-6 w-11 shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors',
|
|
237
|
-
form.inbound_email_enabled ? 'bg-emerald-500' : 'bg-neutral-700',
|
|
238
|
-
]"
|
|
239
|
-
@click="form.inbound_email_enabled = !form.inbound_email_enabled"
|
|
240
|
-
>
|
|
241
|
-
<span
|
|
242
|
-
:class="[
|
|
243
|
-
'pointer-events-none inline-block h-5 w-5 transform rounded-full bg-white shadow ring-0 transition-transform',
|
|
244
|
-
form.inbound_email_enabled ? 'translate-x-5' : 'translate-x-0',
|
|
245
|
-
]"
|
|
246
|
-
/>
|
|
247
|
-
</button>
|
|
248
|
-
</label>
|
|
249
|
-
|
|
250
|
-
<template v-if="form.inbound_email_enabled">
|
|
251
|
-
<div>
|
|
252
|
-
<label class="block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
253
|
-
>Email Provider</label
|
|
254
|
-
>
|
|
255
|
-
<p class="mt-0.5 text-xs text-[var(--esc-panel-text-muted)]">
|
|
256
|
-
How inbound emails are received
|
|
257
|
-
</p>
|
|
258
|
-
<select
|
|
259
|
-
v-model="form.inbound_email_adapter"
|
|
260
|
-
class="mt-2 w-48 rounded-lg border border-[var(--esc-panel-border-input)] bg-[var(--esc-panel-surface-alt)] px-3 py-2 text-sm text-[var(--esc-panel-text-secondary)] focus:border-[var(--esc-panel-border-input)] focus:outline-none focus:ring-1 focus:ring-[var(--esc-panel-border-input)]"
|
|
261
|
-
>
|
|
262
|
-
<option value="mailgun">Mailgun</option>
|
|
263
|
-
<option value="postmark">Postmark</option>
|
|
264
|
-
<option value="ses">AWS SES</option>
|
|
265
|
-
<option value="imap">IMAP</option>
|
|
266
|
-
</select>
|
|
267
|
-
</div>
|
|
268
|
-
|
|
269
|
-
<div>
|
|
270
|
-
<label class="block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
271
|
-
>Support Email Address</label
|
|
272
|
-
>
|
|
273
|
-
<p class="mt-0.5 text-xs text-[var(--esc-panel-text-muted)]">
|
|
274
|
-
The email address customers will send emails to (e.g. support@example.com)
|
|
275
|
-
</p>
|
|
276
|
-
<input
|
|
277
|
-
v-model="form.inbound_email_address"
|
|
278
|
-
type="email"
|
|
279
|
-
placeholder="support@example.com"
|
|
280
|
-
class="mt-2 w-full max-w-sm rounded-lg border border-[var(--esc-panel-border-input)] bg-[var(--esc-panel-surface-alt)] px-3 py-2 text-sm text-[var(--esc-panel-text-secondary)] focus:border-[var(--esc-panel-border-input)] focus:outline-none focus:ring-1 focus:ring-[var(--esc-panel-border-input)]"
|
|
281
|
-
/>
|
|
282
|
-
</div>
|
|
283
|
-
|
|
284
|
-
<!-- Mailgun -->
|
|
285
|
-
<template v-if="form.inbound_email_adapter === 'mailgun'">
|
|
286
|
-
<div>
|
|
287
|
-
<label class="block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
288
|
-
>Signing Key</label
|
|
289
|
-
>
|
|
290
|
-
<input
|
|
291
|
-
v-model="form.mailgun_signing_key"
|
|
292
|
-
type="password"
|
|
293
|
-
class="mt-2 w-full max-w-sm rounded-lg border border-[var(--esc-panel-border-input)] bg-[var(--esc-panel-surface-alt)] px-3 py-2 text-sm text-[var(--esc-panel-text-secondary)] focus:border-[var(--esc-panel-border-input)] focus:outline-none focus:ring-1 focus:ring-[var(--esc-panel-border-input)]"
|
|
294
|
-
/>
|
|
295
|
-
</div>
|
|
296
|
-
<div>
|
|
297
|
-
<label class="block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
298
|
-
>Webhook URL</label
|
|
299
|
-
>
|
|
300
|
-
<p class="mt-0.5 text-xs text-[var(--esc-panel-text-muted)]">
|
|
301
|
-
Configure this URL in your Mailgun dashboard
|
|
302
|
-
</p>
|
|
303
|
-
<input
|
|
304
|
-
:value="`${webhookBaseUrl}/mailgun`"
|
|
305
|
-
type="text"
|
|
306
|
-
readonly
|
|
307
|
-
class="mt-2 w-full max-w-lg rounded-lg border border-[var(--esc-panel-border-input)] bg-[var(--esc-panel-surface-alt)] px-3 py-2 text-sm text-[var(--esc-panel-text-tertiary)] select-all cursor-default focus:outline-none"
|
|
308
|
-
/>
|
|
309
|
-
</div>
|
|
310
|
-
</template>
|
|
311
|
-
|
|
312
|
-
<!-- Postmark -->
|
|
313
|
-
<template v-if="form.inbound_email_adapter === 'postmark'">
|
|
314
|
-
<div>
|
|
315
|
-
<label class="block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
316
|
-
>Inbound Token</label
|
|
317
|
-
>
|
|
318
|
-
<input
|
|
319
|
-
v-model="form.postmark_inbound_token"
|
|
320
|
-
type="password"
|
|
321
|
-
class="mt-2 w-full max-w-sm rounded-lg border border-[var(--esc-panel-border-input)] bg-[var(--esc-panel-surface-alt)] px-3 py-2 text-sm text-[var(--esc-panel-text-secondary)] focus:border-[var(--esc-panel-border-input)] focus:outline-none focus:ring-1 focus:ring-[var(--esc-panel-border-input)]"
|
|
322
|
-
/>
|
|
323
|
-
</div>
|
|
324
|
-
<div>
|
|
325
|
-
<label class="block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
326
|
-
>Webhook URL</label
|
|
327
|
-
>
|
|
328
|
-
<p class="mt-0.5 text-xs text-[var(--esc-panel-text-muted)]">
|
|
329
|
-
Configure this URL in your Postmark server settings
|
|
330
|
-
</p>
|
|
331
|
-
<input
|
|
332
|
-
:value="`${webhookBaseUrl}/postmark`"
|
|
333
|
-
type="text"
|
|
334
|
-
readonly
|
|
335
|
-
class="mt-2 w-full max-w-lg rounded-lg border border-[var(--esc-panel-border-input)] bg-[var(--esc-panel-surface-alt)] px-3 py-2 text-sm text-[var(--esc-panel-text-tertiary)] select-all cursor-default focus:outline-none"
|
|
336
|
-
/>
|
|
337
|
-
</div>
|
|
338
|
-
</template>
|
|
339
|
-
|
|
340
|
-
<!-- AWS SES -->
|
|
341
|
-
<template v-if="form.inbound_email_adapter === 'ses'">
|
|
342
|
-
<div>
|
|
343
|
-
<label class="block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
344
|
-
>Region</label
|
|
345
|
-
>
|
|
346
|
-
<input
|
|
347
|
-
v-model="form.ses_region"
|
|
348
|
-
type="text"
|
|
349
|
-
placeholder="us-east-1"
|
|
350
|
-
class="mt-2 w-48 rounded-lg border border-[var(--esc-panel-border-input)] bg-[var(--esc-panel-surface-alt)] px-3 py-2 text-sm text-[var(--esc-panel-text-secondary)] focus:border-[var(--esc-panel-border-input)] focus:outline-none focus:ring-1 focus:ring-[var(--esc-panel-border-input)]"
|
|
351
|
-
/>
|
|
352
|
-
</div>
|
|
353
|
-
<div>
|
|
354
|
-
<label class="block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
355
|
-
>Topic ARN</label
|
|
356
|
-
>
|
|
357
|
-
<input
|
|
358
|
-
v-model="form.ses_topic_arn"
|
|
359
|
-
type="text"
|
|
360
|
-
placeholder="arn:aws:sns:us-east-1:123456789:ses-inbound"
|
|
361
|
-
class="mt-2 w-full max-w-lg rounded-lg border border-[var(--esc-panel-border-input)] bg-[var(--esc-panel-surface-alt)] px-3 py-2 text-sm text-[var(--esc-panel-text-secondary)] focus:border-[var(--esc-panel-border-input)] focus:outline-none focus:ring-1 focus:ring-[var(--esc-panel-border-input)]"
|
|
362
|
-
/>
|
|
363
|
-
</div>
|
|
364
|
-
<div>
|
|
365
|
-
<label class="block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
366
|
-
>Webhook URL</label
|
|
367
|
-
>
|
|
368
|
-
<p class="mt-0.5 text-xs text-[var(--esc-panel-text-muted)]">
|
|
369
|
-
Configure this URL as your SNS subscription endpoint
|
|
370
|
-
</p>
|
|
371
|
-
<input
|
|
372
|
-
:value="`${webhookBaseUrl}/ses`"
|
|
373
|
-
type="text"
|
|
374
|
-
readonly
|
|
375
|
-
class="mt-2 w-full max-w-lg rounded-lg border border-[var(--esc-panel-border-input)] bg-[var(--esc-panel-surface-alt)] px-3 py-2 text-sm text-[var(--esc-panel-text-tertiary)] select-all cursor-default focus:outline-none"
|
|
376
|
-
/>
|
|
377
|
-
</div>
|
|
378
|
-
</template>
|
|
379
|
-
|
|
380
|
-
<!-- IMAP -->
|
|
381
|
-
<template v-if="form.inbound_email_adapter === 'imap'">
|
|
382
|
-
<div>
|
|
383
|
-
<label class="block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
384
|
-
>Host</label
|
|
385
|
-
>
|
|
386
|
-
<input
|
|
387
|
-
v-model="form.imap_host"
|
|
388
|
-
type="text"
|
|
389
|
-
placeholder="imap.example.com"
|
|
390
|
-
class="mt-2 w-full max-w-sm rounded-lg border border-[var(--esc-panel-border-input)] bg-[var(--esc-panel-surface-alt)] px-3 py-2 text-sm text-[var(--esc-panel-text-secondary)] focus:border-[var(--esc-panel-border-input)] focus:outline-none focus:ring-1 focus:ring-[var(--esc-panel-border-input)]"
|
|
391
|
-
/>
|
|
392
|
-
</div>
|
|
393
|
-
<div class="flex items-end gap-4">
|
|
394
|
-
<div>
|
|
395
|
-
<label class="block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
396
|
-
>Port</label
|
|
397
|
-
>
|
|
398
|
-
<input
|
|
399
|
-
v-model.number="form.imap_port"
|
|
400
|
-
type="number"
|
|
401
|
-
min="1"
|
|
402
|
-
max="65535"
|
|
403
|
-
class="mt-2 w-24 rounded-lg border border-[var(--esc-panel-border-input)] bg-[var(--esc-panel-surface-alt)] px-3 py-2 text-sm text-[var(--esc-panel-text-secondary)] focus:border-[var(--esc-panel-border-input)] focus:outline-none focus:ring-1 focus:ring-[var(--esc-panel-border-input)]"
|
|
404
|
-
/>
|
|
405
|
-
</div>
|
|
406
|
-
<div>
|
|
407
|
-
<label class="block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
408
|
-
>Encryption</label
|
|
409
|
-
>
|
|
410
|
-
<select
|
|
411
|
-
v-model="form.imap_encryption"
|
|
412
|
-
class="mt-2 w-28 rounded-lg border border-[var(--esc-panel-border-input)] bg-[var(--esc-panel-surface-alt)] px-3 py-2 text-sm text-[var(--esc-panel-text-secondary)] focus:border-[var(--esc-panel-border-input)] focus:outline-none focus:ring-1 focus:ring-[var(--esc-panel-border-input)]"
|
|
413
|
-
>
|
|
414
|
-
<option value="ssl">SSL</option>
|
|
415
|
-
<option value="tls">TLS</option>
|
|
416
|
-
<option value="none">None</option>
|
|
417
|
-
</select>
|
|
418
|
-
</div>
|
|
419
|
-
</div>
|
|
420
|
-
<div>
|
|
421
|
-
<label class="block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
422
|
-
>Username</label
|
|
423
|
-
>
|
|
424
|
-
<input
|
|
425
|
-
v-model="form.imap_username"
|
|
426
|
-
type="text"
|
|
427
|
-
class="mt-2 w-full max-w-sm rounded-lg border border-[var(--esc-panel-border-input)] bg-[var(--esc-panel-surface-alt)] px-3 py-2 text-sm text-[var(--esc-panel-text-secondary)] focus:border-[var(--esc-panel-border-input)] focus:outline-none focus:ring-1 focus:ring-[var(--esc-panel-border-input)]"
|
|
428
|
-
/>
|
|
429
|
-
</div>
|
|
430
|
-
<div>
|
|
431
|
-
<label class="block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
432
|
-
>Password</label
|
|
433
|
-
>
|
|
434
|
-
<input
|
|
435
|
-
v-model="form.imap_password"
|
|
436
|
-
type="password"
|
|
437
|
-
class="mt-2 w-full max-w-sm rounded-lg border border-[var(--esc-panel-border-input)] bg-[var(--esc-panel-surface-alt)] px-3 py-2 text-sm text-[var(--esc-panel-text-secondary)] focus:border-[var(--esc-panel-border-input)] focus:outline-none focus:ring-1 focus:ring-[var(--esc-panel-border-input)]"
|
|
438
|
-
/>
|
|
439
|
-
</div>
|
|
440
|
-
<div>
|
|
441
|
-
<label class="block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
442
|
-
>Mailbox</label
|
|
443
|
-
>
|
|
444
|
-
<input
|
|
445
|
-
v-model="form.imap_mailbox"
|
|
446
|
-
type="text"
|
|
447
|
-
placeholder="INBOX"
|
|
448
|
-
class="mt-2 w-48 rounded-lg border border-[var(--esc-panel-border-input)] bg-[var(--esc-panel-surface-alt)] px-3 py-2 text-sm text-[var(--esc-panel-text-secondary)] focus:border-[var(--esc-panel-border-input)] focus:outline-none focus:ring-1 focus:ring-[var(--esc-panel-border-input)]"
|
|
449
|
-
/>
|
|
450
|
-
</div>
|
|
451
|
-
</template>
|
|
452
|
-
</template>
|
|
453
|
-
</div>
|
|
454
|
-
</div>
|
|
455
|
-
|
|
456
|
-
<!-- Knowledge Base -->
|
|
457
|
-
<div class="rounded-xl border border-[var(--esc-panel-border)] bg-[var(--esc-panel-surface)] p-6">
|
|
458
|
-
<h3 class="mb-5 text-sm font-semibold text-[var(--esc-panel-text)]">Knowledge Base</h3>
|
|
459
|
-
<div class="space-y-5">
|
|
460
|
-
<label class="flex items-center justify-between">
|
|
461
|
-
<div>
|
|
462
|
-
<span class="text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
463
|
-
>Enable Knowledge Base</span
|
|
464
|
-
>
|
|
465
|
-
<p class="mt-0.5 text-xs text-[var(--esc-panel-text-muted)]">
|
|
466
|
-
Show the knowledge base to customers and visitors
|
|
467
|
-
</p>
|
|
468
|
-
</div>
|
|
469
|
-
<button
|
|
470
|
-
type="button"
|
|
471
|
-
:class="[
|
|
472
|
-
'relative inline-flex h-6 w-11 shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors',
|
|
473
|
-
form.knowledge_base_enabled ? 'bg-emerald-500' : 'bg-neutral-700',
|
|
474
|
-
]"
|
|
475
|
-
@click="form.knowledge_base_enabled = !form.knowledge_base_enabled"
|
|
476
|
-
>
|
|
477
|
-
<span
|
|
478
|
-
:class="[
|
|
479
|
-
'pointer-events-none inline-block h-5 w-5 transform rounded-full bg-white shadow ring-0 transition-transform',
|
|
480
|
-
form.knowledge_base_enabled ? 'translate-x-5' : 'translate-x-0',
|
|
481
|
-
]"
|
|
482
|
-
/>
|
|
483
|
-
</button>
|
|
484
|
-
</label>
|
|
485
|
-
<label class="flex items-center justify-between">
|
|
486
|
-
<div>
|
|
487
|
-
<span class="text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
488
|
-
>Public Access</span
|
|
489
|
-
>
|
|
490
|
-
<p class="mt-0.5 text-xs text-[var(--esc-panel-text-muted)]">
|
|
491
|
-
Allow unauthenticated visitors to browse the knowledge base
|
|
492
|
-
</p>
|
|
493
|
-
</div>
|
|
494
|
-
<button
|
|
495
|
-
type="button"
|
|
496
|
-
:class="[
|
|
497
|
-
'relative inline-flex h-6 w-11 shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors',
|
|
498
|
-
form.knowledge_base_public ? 'bg-emerald-500' : 'bg-neutral-700',
|
|
499
|
-
]"
|
|
500
|
-
@click="form.knowledge_base_public = !form.knowledge_base_public"
|
|
501
|
-
>
|
|
502
|
-
<span
|
|
503
|
-
:class="[
|
|
504
|
-
'pointer-events-none inline-block h-5 w-5 transform rounded-full bg-white shadow ring-0 transition-transform',
|
|
505
|
-
form.knowledge_base_public ? 'translate-x-5' : 'translate-x-0',
|
|
506
|
-
]"
|
|
507
|
-
/>
|
|
508
|
-
</button>
|
|
509
|
-
</label>
|
|
510
|
-
<label class="flex items-center justify-between">
|
|
511
|
-
<div>
|
|
512
|
-
<span class="text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
513
|
-
>Article Feedback</span
|
|
514
|
-
>
|
|
515
|
-
<p class="mt-0.5 text-xs text-[var(--esc-panel-text-muted)]">
|
|
516
|
-
Show helpful / not helpful buttons on articles
|
|
517
|
-
</p>
|
|
518
|
-
</div>
|
|
519
|
-
<button
|
|
520
|
-
type="button"
|
|
521
|
-
:class="[
|
|
522
|
-
'relative inline-flex h-6 w-11 shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors',
|
|
523
|
-
form.knowledge_base_feedback_enabled ? 'bg-emerald-500' : 'bg-neutral-700',
|
|
524
|
-
]"
|
|
525
|
-
@click="form.knowledge_base_feedback_enabled = !form.knowledge_base_feedback_enabled"
|
|
526
|
-
>
|
|
527
|
-
<span
|
|
528
|
-
:class="[
|
|
529
|
-
'pointer-events-none inline-block h-5 w-5 transform rounded-full bg-white shadow ring-0 transition-transform',
|
|
530
|
-
form.knowledge_base_feedback_enabled ? 'translate-x-5' : 'translate-x-0',
|
|
531
|
-
]"
|
|
532
|
-
/>
|
|
533
|
-
</button>
|
|
534
|
-
</label>
|
|
535
|
-
</div>
|
|
536
|
-
</div>
|
|
537
|
-
|
|
538
|
-
<!-- Branding -->
|
|
539
|
-
<div class="rounded-xl border border-[var(--esc-panel-border)] bg-[var(--esc-panel-surface)] p-6">
|
|
540
|
-
<h3 class="mb-5 text-sm font-semibold text-[var(--esc-panel-text)]">Branding</h3>
|
|
541
|
-
<div class="space-y-5">
|
|
542
|
-
<label class="flex items-center justify-between">
|
|
543
|
-
<div>
|
|
544
|
-
<span class="text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
545
|
-
>Show "Powered by Escalated"</span
|
|
546
|
-
>
|
|
547
|
-
<p class="mt-0.5 text-xs text-[var(--esc-panel-text-muted)]">
|
|
548
|
-
Display attribution badge in the support portal footer
|
|
549
|
-
</p>
|
|
550
|
-
</div>
|
|
551
|
-
<button
|
|
552
|
-
type="button"
|
|
553
|
-
:class="[
|
|
554
|
-
'relative inline-flex h-6 w-11 shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors',
|
|
555
|
-
form.show_powered_by ? 'bg-emerald-500' : 'bg-neutral-700',
|
|
556
|
-
]"
|
|
557
|
-
@click="form.show_powered_by = !form.show_powered_by"
|
|
558
|
-
>
|
|
559
|
-
<span
|
|
560
|
-
:class="[
|
|
561
|
-
'pointer-events-none inline-block h-5 w-5 transform rounded-full bg-white shadow ring-0 transition-transform',
|
|
562
|
-
form.show_powered_by ? 'translate-x-5' : 'translate-x-0',
|
|
563
|
-
]"
|
|
564
|
-
/>
|
|
565
|
-
</button>
|
|
566
|
-
</label>
|
|
567
|
-
</div>
|
|
568
|
-
</div>
|
|
569
|
-
|
|
570
|
-
<!-- Support Widget -->
|
|
571
|
-
<div class="rounded-xl border border-[var(--esc-panel-border)] bg-[var(--esc-panel-surface)] p-6">
|
|
572
|
-
<h3 class="mb-5 text-sm font-semibold text-[var(--esc-panel-text)]">Support Widget</h3>
|
|
573
|
-
<div class="space-y-5">
|
|
574
|
-
<label class="flex items-center justify-between">
|
|
575
|
-
<div>
|
|
576
|
-
<span class="text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
577
|
-
>Enable Widget</span
|
|
578
|
-
>
|
|
579
|
-
<p class="mt-0.5 text-xs text-[var(--esc-panel-text-muted)]">
|
|
580
|
-
Show an embeddable support widget on your site
|
|
581
|
-
</p>
|
|
582
|
-
</div>
|
|
583
|
-
<button
|
|
584
|
-
type="button"
|
|
585
|
-
:class="[
|
|
586
|
-
'relative inline-flex h-6 w-11 shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors',
|
|
587
|
-
form.widget_enabled ? 'bg-emerald-500' : 'bg-neutral-700',
|
|
588
|
-
]"
|
|
589
|
-
@click="form.widget_enabled = !form.widget_enabled"
|
|
590
|
-
>
|
|
591
|
-
<span
|
|
592
|
-
:class="[
|
|
593
|
-
'pointer-events-none inline-block h-5 w-5 transform rounded-full bg-white shadow ring-0 transition-transform',
|
|
594
|
-
form.widget_enabled ? 'translate-x-5' : 'translate-x-0',
|
|
595
|
-
]"
|
|
596
|
-
/>
|
|
597
|
-
</button>
|
|
598
|
-
</label>
|
|
599
|
-
<template v-if="form.widget_enabled">
|
|
600
|
-
<div>
|
|
601
|
-
<label class="block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
602
|
-
>Widget Color</label
|
|
603
|
-
>
|
|
604
|
-
<p class="mt-0.5 text-xs text-[var(--esc-panel-text-muted)]">
|
|
605
|
-
Primary color for the widget button and header
|
|
606
|
-
</p>
|
|
607
|
-
<div class="mt-2 flex items-center gap-3">
|
|
608
|
-
<input
|
|
609
|
-
v-model="form.widget_color"
|
|
610
|
-
type="color"
|
|
611
|
-
class="h-9 w-12 cursor-pointer rounded-lg border border-[var(--esc-panel-border-input)] bg-[var(--esc-panel-surface-alt)] p-0.5"
|
|
612
|
-
/>
|
|
613
|
-
<input
|
|
614
|
-
v-model="form.widget_color"
|
|
615
|
-
type="text"
|
|
616
|
-
maxlength="7"
|
|
617
|
-
class="w-28 rounded-lg border border-[var(--esc-panel-border-input)] bg-[var(--esc-panel-surface-alt)] px-3 py-2 text-sm text-[var(--esc-panel-text-secondary)] uppercase focus:border-[var(--esc-panel-border-input)] focus:outline-none focus:ring-1 focus:ring-[var(--esc-panel-border-input)]"
|
|
618
|
-
/>
|
|
619
|
-
</div>
|
|
620
|
-
</div>
|
|
621
|
-
<div>
|
|
622
|
-
<label class="block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
623
|
-
>Position</label
|
|
624
|
-
>
|
|
625
|
-
<select
|
|
626
|
-
v-model="form.widget_position"
|
|
627
|
-
class="mt-2 w-48 rounded-lg border border-[var(--esc-panel-border-input)] bg-[var(--esc-panel-surface-alt)] px-3 py-2 text-sm text-[var(--esc-panel-text-secondary)] focus:border-[var(--esc-panel-border-input)] focus:outline-none focus:ring-1 focus:ring-[var(--esc-panel-border-input)]"
|
|
628
|
-
>
|
|
629
|
-
<option value="bottom-right">Bottom Right</option>
|
|
630
|
-
<option value="bottom-left">Bottom Left</option>
|
|
631
|
-
</select>
|
|
632
|
-
</div>
|
|
633
|
-
<div>
|
|
634
|
-
<label class="block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
635
|
-
>Greeting Message</label
|
|
636
|
-
>
|
|
637
|
-
<input
|
|
638
|
-
v-model="form.widget_greeting"
|
|
639
|
-
type="text"
|
|
640
|
-
maxlength="255"
|
|
641
|
-
class="mt-2 w-full max-w-sm rounded-lg border border-[var(--esc-panel-border-input)] bg-[var(--esc-panel-surface-alt)] px-3 py-2 text-sm text-[var(--esc-panel-text-secondary)] focus:border-[var(--esc-panel-border-input)] focus:outline-none focus:ring-1 focus:ring-[var(--esc-panel-border-input)]"
|
|
642
|
-
/>
|
|
643
|
-
</div>
|
|
644
|
-
<div v-if="departments?.length">
|
|
645
|
-
<label class="block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
646
|
-
>Departments</label
|
|
647
|
-
>
|
|
648
|
-
<p class="mt-0.5 text-xs text-[var(--esc-panel-text-muted)]">
|
|
649
|
-
Select which departments appear in the widget (leave empty for all)
|
|
650
|
-
</p>
|
|
651
|
-
<div class="mt-2 space-y-2">
|
|
652
|
-
<label v-for="dept in departments" :key="dept.id" class="flex items-center gap-2">
|
|
653
|
-
<input
|
|
654
|
-
type="checkbox"
|
|
655
|
-
:value="dept.id"
|
|
656
|
-
:checked="
|
|
657
|
-
form.widget_departments.split(',').filter(Boolean).includes(String(dept.id))
|
|
658
|
-
"
|
|
659
|
-
class="rounded border-[var(--esc-panel-border-input)] bg-[var(--esc-panel-surface-alt)] text-emerald-500 focus:ring-emerald-500"
|
|
660
|
-
@change="
|
|
661
|
-
(e) => {
|
|
662
|
-
const ids = form.widget_departments.split(',').filter(Boolean);
|
|
663
|
-
if (e.target.checked) {
|
|
664
|
-
ids.push(String(dept.id));
|
|
665
|
-
} else {
|
|
666
|
-
const idx = ids.indexOf(String(dept.id));
|
|
667
|
-
if (idx > -1) ids.splice(idx, 1);
|
|
668
|
-
}
|
|
669
|
-
form.widget_departments = ids.join(',');
|
|
670
|
-
}
|
|
671
|
-
"
|
|
672
|
-
/>
|
|
673
|
-
<span class="text-sm text-[var(--esc-panel-text-secondary)]">{{ dept.name }}</span>
|
|
674
|
-
</label>
|
|
675
|
-
</div>
|
|
676
|
-
</div>
|
|
677
|
-
<div
|
|
678
|
-
class="rounded-lg border border-[var(--esc-panel-border)] bg-[var(--esc-panel-surface-alt)] p-4"
|
|
679
|
-
>
|
|
680
|
-
<label class="block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
681
|
-
>Embed Code</label
|
|
682
|
-
>
|
|
683
|
-
<p class="mt-0.5 text-xs text-[var(--esc-panel-text-muted)]">
|
|
684
|
-
Add this snippet to your website to show the support widget
|
|
685
|
-
</p>
|
|
686
|
-
<code
|
|
687
|
-
class="mt-2 block whitespace-pre-wrap break-all rounded-lg bg-[var(--esc-panel-bg)] p-3 text-xs text-[var(--esc-panel-text-tertiary)] select-all"
|
|
688
|
-
><script src="/{{ page.props.escalated?.prefix || 'support' }}/widget/embed.js"
|
|
689
|
-
data-color="{{ form.widget_color }}" data-position="{{
|
|
690
|
-
form.widget_position
|
|
691
|
-
}}"></script></code
|
|
692
|
-
>
|
|
693
|
-
</div>
|
|
694
|
-
</template>
|
|
695
|
-
</div>
|
|
696
|
-
</div>
|
|
697
|
-
|
|
698
|
-
<!-- Live Chat -->
|
|
699
|
-
<div class="rounded-xl border border-[var(--esc-panel-border)] bg-[var(--esc-panel-surface)] p-6">
|
|
700
|
-
<h3 class="mb-5 text-sm font-semibold text-[var(--esc-panel-text)]">Live Chat</h3>
|
|
701
|
-
<div class="space-y-5">
|
|
702
|
-
<label class="flex items-center justify-between">
|
|
703
|
-
<div>
|
|
704
|
-
<span class="text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
705
|
-
>Enable Live Chat</span
|
|
706
|
-
>
|
|
707
|
-
<p class="mt-0.5 text-xs text-[var(--esc-panel-text-muted)]">
|
|
708
|
-
Allow customers to start real-time chat sessions
|
|
709
|
-
</p>
|
|
710
|
-
</div>
|
|
711
|
-
<input
|
|
712
|
-
v-model="form.chat_enabled"
|
|
713
|
-
type="checkbox"
|
|
714
|
-
:true-value="true"
|
|
715
|
-
:false-value="false"
|
|
716
|
-
class="h-4 w-4 rounded border-[var(--esc-panel-border-input)] bg-[var(--esc-panel-surface-alt)] text-[var(--esc-panel-accent)] focus:ring-[var(--esc-panel-accent)]/20"
|
|
717
|
-
/>
|
|
718
|
-
</label>
|
|
719
|
-
<label class="flex items-center justify-between">
|
|
720
|
-
<div>
|
|
721
|
-
<span class="text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
722
|
-
>Sound Notifications</span
|
|
723
|
-
>
|
|
724
|
-
<p class="mt-0.5 text-xs text-[var(--esc-panel-text-muted)]">
|
|
725
|
-
Play sound on new chat messages
|
|
726
|
-
</p>
|
|
727
|
-
</div>
|
|
728
|
-
<input
|
|
729
|
-
v-model="form.chat_sound_notifications"
|
|
730
|
-
type="checkbox"
|
|
731
|
-
:true-value="true"
|
|
732
|
-
:false-value="false"
|
|
733
|
-
class="h-4 w-4 rounded border-[var(--esc-panel-border-input)] bg-[var(--esc-panel-surface-alt)] text-[var(--esc-panel-accent)] focus:ring-[var(--esc-panel-accent)]/20"
|
|
734
|
-
/>
|
|
735
|
-
</label>
|
|
736
|
-
</div>
|
|
737
|
-
</div>
|
|
738
|
-
|
|
739
|
-
<!-- Chat Routing -->
|
|
740
|
-
<div
|
|
741
|
-
v-if="form.chat_enabled"
|
|
742
|
-
class="rounded-xl border border-[var(--esc-panel-border)] bg-[var(--esc-panel-surface)] p-6"
|
|
743
|
-
>
|
|
744
|
-
<h3 class="mb-5 text-sm font-semibold text-[var(--esc-panel-text)]">Chat Routing</h3>
|
|
745
|
-
<div class="space-y-5">
|
|
746
|
-
<div>
|
|
747
|
-
<label class="mb-1 block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
748
|
-
>Routing Strategy</label
|
|
749
|
-
>
|
|
750
|
-
<select
|
|
751
|
-
v-model="form.chat_routing_strategy"
|
|
752
|
-
class="w-full rounded-lg border border-[var(--esc-panel-border-input)] bg-[var(--esc-panel-surface)] px-3 py-2 text-sm text-[var(--esc-panel-text-secondary)]"
|
|
753
|
-
>
|
|
754
|
-
<option value="round_robin">Round Robin</option>
|
|
755
|
-
<option value="least_active">Least Active</option>
|
|
756
|
-
<option value="manual">Manual (Queue)</option>
|
|
757
|
-
</select>
|
|
758
|
-
</div>
|
|
759
|
-
<div>
|
|
760
|
-
<label class="mb-1 block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
761
|
-
>Offline Behavior</label
|
|
762
|
-
>
|
|
763
|
-
<select
|
|
764
|
-
v-model="form.chat_offline_behavior"
|
|
765
|
-
class="w-full rounded-lg border border-[var(--esc-panel-border-input)] bg-[var(--esc-panel-surface)] px-3 py-2 text-sm text-[var(--esc-panel-text-secondary)]"
|
|
766
|
-
>
|
|
767
|
-
<option value="ticket_form">Show Ticket Form</option>
|
|
768
|
-
<option value="offline_message">Show Offline Message</option>
|
|
769
|
-
<option value="hide">Hide Chat</option>
|
|
770
|
-
</select>
|
|
771
|
-
</div>
|
|
772
|
-
<div class="grid grid-cols-2 gap-4">
|
|
773
|
-
<div>
|
|
774
|
-
<label class="mb-1 block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
775
|
-
>Max Queue Size</label
|
|
776
|
-
>
|
|
777
|
-
<input
|
|
778
|
-
v-model.number="form.chat_max_queue"
|
|
779
|
-
type="number"
|
|
780
|
-
min="1"
|
|
781
|
-
class="w-full rounded-lg border border-[var(--esc-panel-border-input)] bg-[var(--esc-panel-surface)] px-3 py-2 text-sm text-[var(--esc-panel-text-secondary)]"
|
|
782
|
-
/>
|
|
783
|
-
</div>
|
|
784
|
-
<div>
|
|
785
|
-
<label class="mb-1 block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
786
|
-
>Concurrent Limit</label
|
|
787
|
-
>
|
|
788
|
-
<input
|
|
789
|
-
v-model.number="form.chat_concurrent_limit"
|
|
790
|
-
type="number"
|
|
791
|
-
min="1"
|
|
792
|
-
class="w-full rounded-lg border border-[var(--esc-panel-border-input)] bg-[var(--esc-panel-surface)] px-3 py-2 text-sm text-[var(--esc-panel-text-secondary)]"
|
|
793
|
-
/>
|
|
794
|
-
</div>
|
|
795
|
-
</div>
|
|
796
|
-
<div>
|
|
797
|
-
<label class="mb-1 block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
798
|
-
>Auto-close after (minutes)</label
|
|
799
|
-
>
|
|
800
|
-
<input
|
|
801
|
-
v-model.number="form.chat_auto_close_minutes"
|
|
802
|
-
type="number"
|
|
803
|
-
min="1"
|
|
804
|
-
class="w-full rounded-lg border border-[var(--esc-panel-border-input)] bg-[var(--esc-panel-surface)] px-3 py-2 text-sm text-[var(--esc-panel-text-secondary)]"
|
|
805
|
-
/>
|
|
806
|
-
</div>
|
|
807
|
-
<div>
|
|
808
|
-
<label class="mb-1 block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
809
|
-
>Queue Message</label
|
|
810
|
-
>
|
|
811
|
-
<input
|
|
812
|
-
v-model="form.chat_queue_message"
|
|
813
|
-
type="text"
|
|
814
|
-
placeholder="You're in the queue..."
|
|
815
|
-
class="w-full rounded-lg border border-[var(--esc-panel-border-input)] bg-[var(--esc-panel-surface)] px-3 py-2 text-sm text-[var(--esc-panel-text-secondary)] placeholder-[var(--esc-panel-text-muted)]"
|
|
816
|
-
/>
|
|
817
|
-
</div>
|
|
818
|
-
<div>
|
|
819
|
-
<label class="mb-1 block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
820
|
-
>Offline Message</label
|
|
821
|
-
>
|
|
822
|
-
<input
|
|
823
|
-
v-model="form.chat_offline_message"
|
|
824
|
-
type="text"
|
|
825
|
-
placeholder="Sorry, we're not available right now..."
|
|
826
|
-
class="w-full rounded-lg border border-[var(--esc-panel-border-input)] bg-[var(--esc-panel-surface)] px-3 py-2 text-sm text-[var(--esc-panel-text-secondary)] placeholder-[var(--esc-panel-text-muted)]"
|
|
827
|
-
/>
|
|
828
|
-
</div>
|
|
829
|
-
</div>
|
|
830
|
-
</div>
|
|
831
|
-
|
|
832
|
-
<!-- Widget Theme -->
|
|
833
|
-
<div class="rounded-xl border border-[var(--esc-panel-border)] bg-[var(--esc-panel-surface)] p-6">
|
|
834
|
-
<h3 class="mb-5 text-sm font-semibold text-[var(--esc-panel-text)]">Widget Theme</h3>
|
|
835
|
-
<div class="space-y-5">
|
|
836
|
-
<div class="grid grid-cols-2 gap-4">
|
|
837
|
-
<div>
|
|
838
|
-
<label class="mb-1 block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
839
|
-
>Primary Color</label
|
|
840
|
-
>
|
|
841
|
-
<input
|
|
842
|
-
v-model="form.widget_primary_color"
|
|
843
|
-
type="color"
|
|
844
|
-
class="h-10 w-full cursor-pointer rounded-lg border border-[var(--esc-panel-border-input)]"
|
|
845
|
-
/>
|
|
846
|
-
</div>
|
|
847
|
-
<div>
|
|
848
|
-
<label class="mb-1 block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
849
|
-
>Header Background</label
|
|
850
|
-
>
|
|
851
|
-
<input
|
|
852
|
-
v-model="form.widget_header_background"
|
|
853
|
-
type="color"
|
|
854
|
-
class="h-10 w-full cursor-pointer rounded-lg border border-[var(--esc-panel-border-input)]"
|
|
855
|
-
/>
|
|
856
|
-
</div>
|
|
857
|
-
<div>
|
|
858
|
-
<label class="mb-1 block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
859
|
-
>Agent Bubble Color</label
|
|
860
|
-
>
|
|
861
|
-
<input
|
|
862
|
-
v-model="form.widget_agent_bubble_color"
|
|
863
|
-
type="color"
|
|
864
|
-
class="h-10 w-full cursor-pointer rounded-lg border border-[var(--esc-panel-border-input)]"
|
|
865
|
-
/>
|
|
866
|
-
</div>
|
|
867
|
-
<div>
|
|
868
|
-
<label class="mb-1 block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
869
|
-
>Customer Bubble Color</label
|
|
870
|
-
>
|
|
871
|
-
<input
|
|
872
|
-
v-model="form.widget_customer_bubble_color"
|
|
873
|
-
type="color"
|
|
874
|
-
class="h-10 w-full cursor-pointer rounded-lg border border-[var(--esc-panel-border-input)]"
|
|
875
|
-
/>
|
|
876
|
-
</div>
|
|
877
|
-
<div>
|
|
878
|
-
<label class="mb-1 block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
879
|
-
>Background Color</label
|
|
880
|
-
>
|
|
881
|
-
<input
|
|
882
|
-
v-model="form.widget_background_color"
|
|
883
|
-
type="color"
|
|
884
|
-
class="h-10 w-full cursor-pointer rounded-lg border border-[var(--esc-panel-border-input)]"
|
|
885
|
-
/>
|
|
886
|
-
</div>
|
|
887
|
-
<div>
|
|
888
|
-
<label class="mb-1 block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
889
|
-
>Text Color</label
|
|
890
|
-
>
|
|
891
|
-
<input
|
|
892
|
-
v-model="form.widget_text_color"
|
|
893
|
-
type="color"
|
|
894
|
-
class="h-10 w-full cursor-pointer rounded-lg border border-[var(--esc-panel-border-input)]"
|
|
895
|
-
/>
|
|
896
|
-
</div>
|
|
897
|
-
</div>
|
|
898
|
-
<div>
|
|
899
|
-
<label class="mb-1 block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
900
|
-
>Font Family</label
|
|
901
|
-
>
|
|
902
|
-
<select
|
|
903
|
-
v-model="form.widget_font_family"
|
|
904
|
-
class="w-full rounded-lg border border-[var(--esc-panel-border-input)] bg-[var(--esc-panel-surface)] px-3 py-2 text-sm text-[var(--esc-panel-text-secondary)]"
|
|
905
|
-
>
|
|
906
|
-
<option value="system">System Default</option>
|
|
907
|
-
<option value="Inter">Inter</option>
|
|
908
|
-
<option value="Roboto">Roboto</option>
|
|
909
|
-
<option value="Open Sans">Open Sans</option>
|
|
910
|
-
<option value="Lato">Lato</option>
|
|
911
|
-
<option value="Poppins">Poppins</option>
|
|
912
|
-
<option value="Nunito">Nunito</option>
|
|
913
|
-
</select>
|
|
914
|
-
</div>
|
|
915
|
-
<div>
|
|
916
|
-
<label class="mb-1 block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
917
|
-
>Border Radius ({{ form.widget_border_radius }}px)</label
|
|
918
|
-
>
|
|
919
|
-
<input
|
|
920
|
-
v-model.number="form.widget_border_radius"
|
|
921
|
-
type="range"
|
|
922
|
-
min="0"
|
|
923
|
-
max="20"
|
|
924
|
-
class="w-full"
|
|
925
|
-
/>
|
|
926
|
-
</div>
|
|
927
|
-
<div>
|
|
928
|
-
<label class="mb-1 block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
929
|
-
>Launcher Size</label
|
|
930
|
-
>
|
|
931
|
-
<div class="flex gap-3">
|
|
932
|
-
<label
|
|
933
|
-
v-for="size in ['small', 'medium', 'large']"
|
|
934
|
-
:key="size"
|
|
935
|
-
class="flex items-center gap-2"
|
|
936
|
-
>
|
|
937
|
-
<input
|
|
938
|
-
v-model="form.widget_launcher_size"
|
|
939
|
-
type="radio"
|
|
940
|
-
:value="size"
|
|
941
|
-
class="text-[var(--esc-panel-accent)] focus:ring-[var(--esc-panel-accent)]/20"
|
|
942
|
-
/>
|
|
943
|
-
<span class="text-sm capitalize text-[var(--esc-panel-text-secondary)]">{{
|
|
944
|
-
size
|
|
945
|
-
}}</span>
|
|
946
|
-
</label>
|
|
947
|
-
</div>
|
|
948
|
-
</div>
|
|
949
|
-
<label class="flex items-center justify-between">
|
|
950
|
-
<span class="text-sm font-medium text-[var(--esc-panel-text-secondary)]">Show Branding</span>
|
|
951
|
-
<input
|
|
952
|
-
v-model="form.widget_show_branding"
|
|
953
|
-
type="checkbox"
|
|
954
|
-
:true-value="true"
|
|
955
|
-
:false-value="false"
|
|
956
|
-
class="h-4 w-4 rounded border-[var(--esc-panel-border-input)] bg-[var(--esc-panel-surface-alt)] text-[var(--esc-panel-accent)] focus:ring-[var(--esc-panel-accent)]/20"
|
|
957
|
-
/>
|
|
958
|
-
</label>
|
|
959
|
-
<div>
|
|
960
|
-
<label class="mb-1 block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
961
|
-
>Pre-chat Message</label
|
|
962
|
-
>
|
|
963
|
-
<input
|
|
964
|
-
v-model="form.widget_pre_chat_message"
|
|
965
|
-
type="text"
|
|
966
|
-
class="w-full rounded-lg border border-[var(--esc-panel-border-input)] bg-[var(--esc-panel-surface)] px-3 py-2 text-sm text-[var(--esc-panel-text-secondary)] placeholder-[var(--esc-panel-text-muted)]"
|
|
967
|
-
/>
|
|
968
|
-
</div>
|
|
969
|
-
<div>
|
|
970
|
-
<label class="mb-1 block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
971
|
-
>Chat Header Text</label
|
|
972
|
-
>
|
|
973
|
-
<input
|
|
974
|
-
v-model="form.widget_chat_header_text"
|
|
975
|
-
type="text"
|
|
976
|
-
class="w-full rounded-lg border border-[var(--esc-panel-border-input)] bg-[var(--esc-panel-surface)] px-3 py-2 text-sm text-[var(--esc-panel-text-secondary)] placeholder-[var(--esc-panel-text-muted)]"
|
|
977
|
-
/>
|
|
978
|
-
</div>
|
|
979
|
-
<div>
|
|
980
|
-
<label class="mb-1 block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
981
|
-
>Custom CSS</label
|
|
982
|
-
>
|
|
983
|
-
<textarea
|
|
984
|
-
v-model="form.widget_custom_css"
|
|
985
|
-
rows="4"
|
|
986
|
-
placeholder=".esc-w-panel { /* custom styles */ }"
|
|
987
|
-
class="w-full rounded-lg border border-[var(--esc-panel-border-input)] bg-[var(--esc-panel-surface)] px-3 py-2 font-mono text-xs text-[var(--esc-panel-text-secondary)] placeholder-[var(--esc-panel-text-muted)]"
|
|
988
|
-
></textarea>
|
|
989
|
-
</div>
|
|
990
|
-
</div>
|
|
991
|
-
</div>
|
|
992
|
-
|
|
993
|
-
<PluginSlot slot="admin.settings.extra" :components="getPageComponents('admin.settings', 'extra')" />
|
|
994
|
-
|
|
995
|
-
<!-- Submit -->
|
|
996
|
-
<div class="flex items-center justify-end gap-3">
|
|
997
|
-
<span v-if="form.recentlySuccessful" class="text-sm text-emerald-400">Saved.</span>
|
|
998
|
-
<button
|
|
999
|
-
type="submit"
|
|
1000
|
-
:disabled="form.processing"
|
|
1001
|
-
class="rounded-lg bg-gradient-to-r from-[var(--esc-panel-accent)] to-[var(--esc-panel-accent-secondary)] px-5 py-2 text-sm font-medium text-white shadow-lg shadow-[var(--esc-panel-bg)]/20 transition-all hover:from-[var(--esc-panel-accent-hover)] hover:to-[var(--esc-panel-accent-secondary-hover)] disabled:opacity-50"
|
|
1002
|
-
>
|
|
1003
|
-
{{ form.processing ? 'Saving...' : 'Save Settings' }}
|
|
1004
|
-
</button>
|
|
1005
|
-
</div>
|
|
1006
|
-
</form>
|
|
1007
|
-
</EscalatedLayout>
|
|
1008
|
-
</template>
|
|
1
|
+
<script setup>
|
|
2
|
+
import EscalatedLayout from '../../components/EscalatedLayout.vue';
|
|
3
|
+
import PluginSlot from '../../components/PluginSlot.vue';
|
|
4
|
+
import { useForm, usePage } from '@inertiajs/vue3';
|
|
5
|
+
import { computed } from 'vue';
|
|
6
|
+
import { usePluginExtensions } from '../../composables/usePluginExtensions';
|
|
7
|
+
|
|
8
|
+
const props = defineProps({ settings: Object, departments: Array });
|
|
9
|
+
const page = usePage();
|
|
10
|
+
|
|
11
|
+
const form = useForm({
|
|
12
|
+
guest_tickets_enabled: props.settings.guest_tickets_enabled,
|
|
13
|
+
allow_customer_close: props.settings.allow_customer_close,
|
|
14
|
+
auto_close_resolved_after_days: props.settings.auto_close_resolved_after_days,
|
|
15
|
+
max_attachments_per_reply: props.settings.max_attachments_per_reply,
|
|
16
|
+
max_attachment_size_kb: props.settings.max_attachment_size_kb,
|
|
17
|
+
ticket_reference_prefix: props.settings.ticket_reference_prefix,
|
|
18
|
+
inbound_email_enabled: props.settings.inbound_email_enabled ?? false,
|
|
19
|
+
inbound_email_adapter: props.settings.inbound_email_adapter ?? 'mailgun',
|
|
20
|
+
inbound_email_address: props.settings.inbound_email_address ?? '',
|
|
21
|
+
mailgun_signing_key: props.settings.mailgun_signing_key ?? '',
|
|
22
|
+
postmark_inbound_token: props.settings.postmark_inbound_token ?? '',
|
|
23
|
+
ses_region: props.settings.ses_region ?? '',
|
|
24
|
+
ses_topic_arn: props.settings.ses_topic_arn ?? '',
|
|
25
|
+
imap_host: props.settings.imap_host ?? '',
|
|
26
|
+
imap_port: props.settings.imap_port ?? 993,
|
|
27
|
+
imap_encryption: props.settings.imap_encryption ?? 'ssl',
|
|
28
|
+
imap_username: props.settings.imap_username ?? '',
|
|
29
|
+
imap_password: props.settings.imap_password ?? '',
|
|
30
|
+
imap_mailbox: props.settings.imap_mailbox ?? 'INBOX',
|
|
31
|
+
show_powered_by: props.settings.show_powered_by ?? true,
|
|
32
|
+
widget_enabled: props.settings.widget_enabled ?? false,
|
|
33
|
+
widget_color: props.settings.widget_color ?? '#4F46E5',
|
|
34
|
+
widget_position: props.settings.widget_position ?? 'bottom-right',
|
|
35
|
+
widget_greeting: props.settings.widget_greeting ?? 'Hi there! How can we help?',
|
|
36
|
+
widget_departments: props.settings.widget_departments ?? '',
|
|
37
|
+
knowledge_base_enabled: props.settings.knowledge_base_enabled ?? true,
|
|
38
|
+
knowledge_base_public: props.settings.knowledge_base_public ?? true,
|
|
39
|
+
knowledge_base_feedback_enabled: props.settings.knowledge_base_feedback_enabled ?? true,
|
|
40
|
+
// Chat settings
|
|
41
|
+
chat_enabled: props.settings.chat_enabled ?? false,
|
|
42
|
+
chat_sound_notifications: props.settings.chat_sound_notifications ?? true,
|
|
43
|
+
chat_pre_chat_name: props.settings.chat_pre_chat_name ?? true,
|
|
44
|
+
chat_pre_chat_email: props.settings.chat_pre_chat_email ?? true,
|
|
45
|
+
chat_pre_chat_department: props.settings.chat_pre_chat_department ?? false,
|
|
46
|
+
chat_routing_strategy: props.settings.chat_routing_strategy ?? 'round_robin',
|
|
47
|
+
chat_offline_behavior: props.settings.chat_offline_behavior ?? 'ticket_form',
|
|
48
|
+
chat_max_queue: props.settings.chat_max_queue ?? 10,
|
|
49
|
+
chat_concurrent_limit: props.settings.chat_concurrent_limit ?? 5,
|
|
50
|
+
chat_auto_close_minutes: props.settings.chat_auto_close_minutes ?? 30,
|
|
51
|
+
chat_queue_message: props.settings.chat_queue_message ?? '',
|
|
52
|
+
chat_offline_message: props.settings.chat_offline_message ?? '',
|
|
53
|
+
// Widget theme
|
|
54
|
+
widget_primary_color: props.settings.widget_primary_color ?? '#4F46E5',
|
|
55
|
+
widget_background_color: props.settings.widget_background_color ?? '#ffffff',
|
|
56
|
+
widget_text_color: props.settings.widget_text_color ?? '#1f2937',
|
|
57
|
+
widget_agent_bubble_color: props.settings.widget_agent_bubble_color ?? '#4F46E5',
|
|
58
|
+
widget_customer_bubble_color: props.settings.widget_customer_bubble_color ?? '#f3f4f6',
|
|
59
|
+
widget_header_background: props.settings.widget_header_background ?? '#4F46E5',
|
|
60
|
+
widget_font_family: props.settings.widget_font_family ?? 'system',
|
|
61
|
+
widget_border_radius: props.settings.widget_border_radius ?? 12,
|
|
62
|
+
widget_launcher_size: props.settings.widget_launcher_size ?? 'medium',
|
|
63
|
+
widget_show_branding: props.settings.widget_show_branding ?? true,
|
|
64
|
+
widget_custom_css: props.settings.widget_custom_css ?? '',
|
|
65
|
+
widget_pre_chat_message: props.settings.widget_pre_chat_message ?? '',
|
|
66
|
+
widget_chat_header_text: props.settings.widget_chat_header_text ?? 'Support',
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
const webhookBaseUrl = computed(() => {
|
|
70
|
+
const prefix = page.props.escalated?.prefix || 'support';
|
|
71
|
+
const origin = typeof window !== 'undefined' ? window.location.origin : '';
|
|
72
|
+
return `${origin}/${prefix}/inbound`;
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
const { getPageComponents } = usePluginExtensions();
|
|
76
|
+
|
|
77
|
+
function submit() {
|
|
78
|
+
form.post(route('escalated.admin.settings.update'));
|
|
79
|
+
}
|
|
80
|
+
</script>
|
|
81
|
+
|
|
82
|
+
<template>
|
|
83
|
+
<EscalatedLayout title="Settings">
|
|
84
|
+
<form class="mx-auto max-w-2xl space-y-6" @submit.prevent="submit">
|
|
85
|
+
<!-- General -->
|
|
86
|
+
<div class="rounded-xl border border-[var(--esc-panel-border)] bg-[var(--esc-panel-surface)] p-6">
|
|
87
|
+
<h3 class="mb-5 text-sm font-semibold text-[var(--esc-panel-text)]">General</h3>
|
|
88
|
+
<div class="space-y-5">
|
|
89
|
+
<label class="flex items-center justify-between">
|
|
90
|
+
<div>
|
|
91
|
+
<span class="text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
92
|
+
>Guest Tickets</span
|
|
93
|
+
>
|
|
94
|
+
<p class="mt-0.5 text-xs text-[var(--esc-panel-text-muted)]">
|
|
95
|
+
Allow visitors to submit tickets without signing in
|
|
96
|
+
</p>
|
|
97
|
+
</div>
|
|
98
|
+
<button
|
|
99
|
+
type="button"
|
|
100
|
+
:class="[
|
|
101
|
+
'relative inline-flex h-6 w-11 shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors',
|
|
102
|
+
form.guest_tickets_enabled ? 'bg-emerald-500' : 'bg-neutral-700',
|
|
103
|
+
]"
|
|
104
|
+
@click="form.guest_tickets_enabled = !form.guest_tickets_enabled"
|
|
105
|
+
>
|
|
106
|
+
<span
|
|
107
|
+
:class="[
|
|
108
|
+
'pointer-events-none inline-block h-5 w-5 transform rounded-full bg-white shadow ring-0 transition-transform',
|
|
109
|
+
form.guest_tickets_enabled ? 'translate-x-5' : 'translate-x-0',
|
|
110
|
+
]"
|
|
111
|
+
/>
|
|
112
|
+
</button>
|
|
113
|
+
</label>
|
|
114
|
+
|
|
115
|
+
<label class="flex items-center justify-between">
|
|
116
|
+
<div>
|
|
117
|
+
<span class="text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
118
|
+
>Allow Customer Close</span
|
|
119
|
+
>
|
|
120
|
+
<p class="mt-0.5 text-xs text-[var(--esc-panel-text-muted)]">
|
|
121
|
+
Let customers close their own tickets
|
|
122
|
+
</p>
|
|
123
|
+
</div>
|
|
124
|
+
<button
|
|
125
|
+
type="button"
|
|
126
|
+
:class="[
|
|
127
|
+
'relative inline-flex h-6 w-11 shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors',
|
|
128
|
+
form.allow_customer_close ? 'bg-emerald-500' : 'bg-neutral-700',
|
|
129
|
+
]"
|
|
130
|
+
@click="form.allow_customer_close = !form.allow_customer_close"
|
|
131
|
+
>
|
|
132
|
+
<span
|
|
133
|
+
:class="[
|
|
134
|
+
'pointer-events-none inline-block h-5 w-5 transform rounded-full bg-white shadow ring-0 transition-transform',
|
|
135
|
+
form.allow_customer_close ? 'translate-x-5' : 'translate-x-0',
|
|
136
|
+
]"
|
|
137
|
+
/>
|
|
138
|
+
</button>
|
|
139
|
+
</label>
|
|
140
|
+
|
|
141
|
+
<div>
|
|
142
|
+
<label class="block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
143
|
+
>Auto-close resolved tickets after</label
|
|
144
|
+
>
|
|
145
|
+
<p class="mt-0.5 text-xs text-[var(--esc-panel-text-muted)]">
|
|
146
|
+
Days after resolution before auto-closing (0 to disable)
|
|
147
|
+
</p>
|
|
148
|
+
<div class="mt-2 flex items-center gap-2">
|
|
149
|
+
<input
|
|
150
|
+
v-model.number="form.auto_close_resolved_after_days"
|
|
151
|
+
type="number"
|
|
152
|
+
min="0"
|
|
153
|
+
max="365"
|
|
154
|
+
class="w-24 rounded-lg border border-[var(--esc-panel-border-input)] bg-[var(--esc-panel-surface-alt)] px-3 py-2 text-sm text-[var(--esc-panel-text-secondary)] focus:border-[var(--esc-panel-border-input)] focus:outline-none focus:ring-1 focus:ring-[var(--esc-panel-border-input)]"
|
|
155
|
+
/>
|
|
156
|
+
<span class="text-sm text-[var(--esc-panel-text-muted)]">days</span>
|
|
157
|
+
</div>
|
|
158
|
+
</div>
|
|
159
|
+
</div>
|
|
160
|
+
</div>
|
|
161
|
+
|
|
162
|
+
<!-- Limits -->
|
|
163
|
+
<div class="rounded-xl border border-[var(--esc-panel-border)] bg-[var(--esc-panel-surface)] p-6">
|
|
164
|
+
<h3 class="mb-5 text-sm font-semibold text-[var(--esc-panel-text)]">Limits</h3>
|
|
165
|
+
<div class="space-y-5">
|
|
166
|
+
<div>
|
|
167
|
+
<label class="block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
168
|
+
>Max attachments per reply</label
|
|
169
|
+
>
|
|
170
|
+
<input
|
|
171
|
+
v-model.number="form.max_attachments_per_reply"
|
|
172
|
+
type="number"
|
|
173
|
+
min="1"
|
|
174
|
+
max="20"
|
|
175
|
+
class="mt-2 w-24 rounded-lg border border-[var(--esc-panel-border-input)] bg-[var(--esc-panel-surface-alt)] px-3 py-2 text-sm text-[var(--esc-panel-text-secondary)] focus:border-[var(--esc-panel-border-input)] focus:outline-none focus:ring-1 focus:ring-[var(--esc-panel-border-input)]"
|
|
176
|
+
/>
|
|
177
|
+
</div>
|
|
178
|
+
<div>
|
|
179
|
+
<label class="block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
180
|
+
>Max attachment size</label
|
|
181
|
+
>
|
|
182
|
+
<div class="mt-2 flex items-center gap-2">
|
|
183
|
+
<input
|
|
184
|
+
v-model.number="form.max_attachment_size_kb"
|
|
185
|
+
type="number"
|
|
186
|
+
min="512"
|
|
187
|
+
max="102400"
|
|
188
|
+
step="512"
|
|
189
|
+
class="w-32 rounded-lg border border-[var(--esc-panel-border-input)] bg-[var(--esc-panel-surface-alt)] px-3 py-2 text-sm text-[var(--esc-panel-text-secondary)] focus:border-[var(--esc-panel-border-input)] focus:outline-none focus:ring-1 focus:ring-[var(--esc-panel-border-input)]"
|
|
190
|
+
/>
|
|
191
|
+
<span class="text-sm text-[var(--esc-panel-text-muted)]"
|
|
192
|
+
>KB ({{ Math.round(form.max_attachment_size_kb / 1024) }} MB)</span
|
|
193
|
+
>
|
|
194
|
+
</div>
|
|
195
|
+
</div>
|
|
196
|
+
</div>
|
|
197
|
+
</div>
|
|
198
|
+
|
|
199
|
+
<!-- Tickets -->
|
|
200
|
+
<div class="rounded-xl border border-[var(--esc-panel-border)] bg-[var(--esc-panel-surface)] p-6">
|
|
201
|
+
<h3 class="mb-5 text-sm font-semibold text-[var(--esc-panel-text)]">Tickets</h3>
|
|
202
|
+
<div class="space-y-5">
|
|
203
|
+
<div>
|
|
204
|
+
<label class="block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
205
|
+
>Reference Prefix</label
|
|
206
|
+
>
|
|
207
|
+
<p class="mt-0.5 text-xs text-[var(--esc-panel-text-muted)]">
|
|
208
|
+
Prefix for ticket references (e.g. ESC produces ESC-00001)
|
|
209
|
+
</p>
|
|
210
|
+
<input
|
|
211
|
+
v-model="form.ticket_reference_prefix"
|
|
212
|
+
type="text"
|
|
213
|
+
maxlength="10"
|
|
214
|
+
class="mt-2 w-32 rounded-lg border border-[var(--esc-panel-border-input)] bg-[var(--esc-panel-surface-alt)] px-3 py-2 text-sm text-[var(--esc-panel-text-secondary)] uppercase focus:border-[var(--esc-panel-border-input)] focus:outline-none focus:ring-1 focus:ring-[var(--esc-panel-border-input)]"
|
|
215
|
+
/>
|
|
216
|
+
</div>
|
|
217
|
+
</div>
|
|
218
|
+
</div>
|
|
219
|
+
|
|
220
|
+
<!-- Inbound Email -->
|
|
221
|
+
<div class="rounded-xl border border-[var(--esc-panel-border)] bg-[var(--esc-panel-surface)] p-6">
|
|
222
|
+
<h3 class="mb-5 text-sm font-semibold text-[var(--esc-panel-text)]">Inbound Email</h3>
|
|
223
|
+
<div class="space-y-5">
|
|
224
|
+
<label class="flex items-center justify-between">
|
|
225
|
+
<div>
|
|
226
|
+
<span class="text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
227
|
+
>Inbound Email</span
|
|
228
|
+
>
|
|
229
|
+
<p class="mt-0.5 text-xs text-[var(--esc-panel-text-muted)]">
|
|
230
|
+
Allow creating and replying to tickets via email
|
|
231
|
+
</p>
|
|
232
|
+
</div>
|
|
233
|
+
<button
|
|
234
|
+
type="button"
|
|
235
|
+
:class="[
|
|
236
|
+
'relative inline-flex h-6 w-11 shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors',
|
|
237
|
+
form.inbound_email_enabled ? 'bg-emerald-500' : 'bg-neutral-700',
|
|
238
|
+
]"
|
|
239
|
+
@click="form.inbound_email_enabled = !form.inbound_email_enabled"
|
|
240
|
+
>
|
|
241
|
+
<span
|
|
242
|
+
:class="[
|
|
243
|
+
'pointer-events-none inline-block h-5 w-5 transform rounded-full bg-white shadow ring-0 transition-transform',
|
|
244
|
+
form.inbound_email_enabled ? 'translate-x-5' : 'translate-x-0',
|
|
245
|
+
]"
|
|
246
|
+
/>
|
|
247
|
+
</button>
|
|
248
|
+
</label>
|
|
249
|
+
|
|
250
|
+
<template v-if="form.inbound_email_enabled">
|
|
251
|
+
<div>
|
|
252
|
+
<label class="block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
253
|
+
>Email Provider</label
|
|
254
|
+
>
|
|
255
|
+
<p class="mt-0.5 text-xs text-[var(--esc-panel-text-muted)]">
|
|
256
|
+
How inbound emails are received
|
|
257
|
+
</p>
|
|
258
|
+
<select
|
|
259
|
+
v-model="form.inbound_email_adapter"
|
|
260
|
+
class="mt-2 w-48 rounded-lg border border-[var(--esc-panel-border-input)] bg-[var(--esc-panel-surface-alt)] px-3 py-2 text-sm text-[var(--esc-panel-text-secondary)] focus:border-[var(--esc-panel-border-input)] focus:outline-none focus:ring-1 focus:ring-[var(--esc-panel-border-input)]"
|
|
261
|
+
>
|
|
262
|
+
<option value="mailgun">Mailgun</option>
|
|
263
|
+
<option value="postmark">Postmark</option>
|
|
264
|
+
<option value="ses">AWS SES</option>
|
|
265
|
+
<option value="imap">IMAP</option>
|
|
266
|
+
</select>
|
|
267
|
+
</div>
|
|
268
|
+
|
|
269
|
+
<div>
|
|
270
|
+
<label class="block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
271
|
+
>Support Email Address</label
|
|
272
|
+
>
|
|
273
|
+
<p class="mt-0.5 text-xs text-[var(--esc-panel-text-muted)]">
|
|
274
|
+
The email address customers will send emails to (e.g. support@example.com)
|
|
275
|
+
</p>
|
|
276
|
+
<input
|
|
277
|
+
v-model="form.inbound_email_address"
|
|
278
|
+
type="email"
|
|
279
|
+
placeholder="support@example.com"
|
|
280
|
+
class="mt-2 w-full max-w-sm rounded-lg border border-[var(--esc-panel-border-input)] bg-[var(--esc-panel-surface-alt)] px-3 py-2 text-sm text-[var(--esc-panel-text-secondary)] focus:border-[var(--esc-panel-border-input)] focus:outline-none focus:ring-1 focus:ring-[var(--esc-panel-border-input)]"
|
|
281
|
+
/>
|
|
282
|
+
</div>
|
|
283
|
+
|
|
284
|
+
<!-- Mailgun -->
|
|
285
|
+
<template v-if="form.inbound_email_adapter === 'mailgun'">
|
|
286
|
+
<div>
|
|
287
|
+
<label class="block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
288
|
+
>Signing Key</label
|
|
289
|
+
>
|
|
290
|
+
<input
|
|
291
|
+
v-model="form.mailgun_signing_key"
|
|
292
|
+
type="password"
|
|
293
|
+
class="mt-2 w-full max-w-sm rounded-lg border border-[var(--esc-panel-border-input)] bg-[var(--esc-panel-surface-alt)] px-3 py-2 text-sm text-[var(--esc-panel-text-secondary)] focus:border-[var(--esc-panel-border-input)] focus:outline-none focus:ring-1 focus:ring-[var(--esc-panel-border-input)]"
|
|
294
|
+
/>
|
|
295
|
+
</div>
|
|
296
|
+
<div>
|
|
297
|
+
<label class="block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
298
|
+
>Webhook URL</label
|
|
299
|
+
>
|
|
300
|
+
<p class="mt-0.5 text-xs text-[var(--esc-panel-text-muted)]">
|
|
301
|
+
Configure this URL in your Mailgun dashboard
|
|
302
|
+
</p>
|
|
303
|
+
<input
|
|
304
|
+
:value="`${webhookBaseUrl}/mailgun`"
|
|
305
|
+
type="text"
|
|
306
|
+
readonly
|
|
307
|
+
class="mt-2 w-full max-w-lg rounded-lg border border-[var(--esc-panel-border-input)] bg-[var(--esc-panel-surface-alt)] px-3 py-2 text-sm text-[var(--esc-panel-text-tertiary)] select-all cursor-default focus:outline-none"
|
|
308
|
+
/>
|
|
309
|
+
</div>
|
|
310
|
+
</template>
|
|
311
|
+
|
|
312
|
+
<!-- Postmark -->
|
|
313
|
+
<template v-if="form.inbound_email_adapter === 'postmark'">
|
|
314
|
+
<div>
|
|
315
|
+
<label class="block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
316
|
+
>Inbound Token</label
|
|
317
|
+
>
|
|
318
|
+
<input
|
|
319
|
+
v-model="form.postmark_inbound_token"
|
|
320
|
+
type="password"
|
|
321
|
+
class="mt-2 w-full max-w-sm rounded-lg border border-[var(--esc-panel-border-input)] bg-[var(--esc-panel-surface-alt)] px-3 py-2 text-sm text-[var(--esc-panel-text-secondary)] focus:border-[var(--esc-panel-border-input)] focus:outline-none focus:ring-1 focus:ring-[var(--esc-panel-border-input)]"
|
|
322
|
+
/>
|
|
323
|
+
</div>
|
|
324
|
+
<div>
|
|
325
|
+
<label class="block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
326
|
+
>Webhook URL</label
|
|
327
|
+
>
|
|
328
|
+
<p class="mt-0.5 text-xs text-[var(--esc-panel-text-muted)]">
|
|
329
|
+
Configure this URL in your Postmark server settings
|
|
330
|
+
</p>
|
|
331
|
+
<input
|
|
332
|
+
:value="`${webhookBaseUrl}/postmark`"
|
|
333
|
+
type="text"
|
|
334
|
+
readonly
|
|
335
|
+
class="mt-2 w-full max-w-lg rounded-lg border border-[var(--esc-panel-border-input)] bg-[var(--esc-panel-surface-alt)] px-3 py-2 text-sm text-[var(--esc-panel-text-tertiary)] select-all cursor-default focus:outline-none"
|
|
336
|
+
/>
|
|
337
|
+
</div>
|
|
338
|
+
</template>
|
|
339
|
+
|
|
340
|
+
<!-- AWS SES -->
|
|
341
|
+
<template v-if="form.inbound_email_adapter === 'ses'">
|
|
342
|
+
<div>
|
|
343
|
+
<label class="block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
344
|
+
>Region</label
|
|
345
|
+
>
|
|
346
|
+
<input
|
|
347
|
+
v-model="form.ses_region"
|
|
348
|
+
type="text"
|
|
349
|
+
placeholder="us-east-1"
|
|
350
|
+
class="mt-2 w-48 rounded-lg border border-[var(--esc-panel-border-input)] bg-[var(--esc-panel-surface-alt)] px-3 py-2 text-sm text-[var(--esc-panel-text-secondary)] focus:border-[var(--esc-panel-border-input)] focus:outline-none focus:ring-1 focus:ring-[var(--esc-panel-border-input)]"
|
|
351
|
+
/>
|
|
352
|
+
</div>
|
|
353
|
+
<div>
|
|
354
|
+
<label class="block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
355
|
+
>Topic ARN</label
|
|
356
|
+
>
|
|
357
|
+
<input
|
|
358
|
+
v-model="form.ses_topic_arn"
|
|
359
|
+
type="text"
|
|
360
|
+
placeholder="arn:aws:sns:us-east-1:123456789:ses-inbound"
|
|
361
|
+
class="mt-2 w-full max-w-lg rounded-lg border border-[var(--esc-panel-border-input)] bg-[var(--esc-panel-surface-alt)] px-3 py-2 text-sm text-[var(--esc-panel-text-secondary)] focus:border-[var(--esc-panel-border-input)] focus:outline-none focus:ring-1 focus:ring-[var(--esc-panel-border-input)]"
|
|
362
|
+
/>
|
|
363
|
+
</div>
|
|
364
|
+
<div>
|
|
365
|
+
<label class="block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
366
|
+
>Webhook URL</label
|
|
367
|
+
>
|
|
368
|
+
<p class="mt-0.5 text-xs text-[var(--esc-panel-text-muted)]">
|
|
369
|
+
Configure this URL as your SNS subscription endpoint
|
|
370
|
+
</p>
|
|
371
|
+
<input
|
|
372
|
+
:value="`${webhookBaseUrl}/ses`"
|
|
373
|
+
type="text"
|
|
374
|
+
readonly
|
|
375
|
+
class="mt-2 w-full max-w-lg rounded-lg border border-[var(--esc-panel-border-input)] bg-[var(--esc-panel-surface-alt)] px-3 py-2 text-sm text-[var(--esc-panel-text-tertiary)] select-all cursor-default focus:outline-none"
|
|
376
|
+
/>
|
|
377
|
+
</div>
|
|
378
|
+
</template>
|
|
379
|
+
|
|
380
|
+
<!-- IMAP -->
|
|
381
|
+
<template v-if="form.inbound_email_adapter === 'imap'">
|
|
382
|
+
<div>
|
|
383
|
+
<label class="block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
384
|
+
>Host</label
|
|
385
|
+
>
|
|
386
|
+
<input
|
|
387
|
+
v-model="form.imap_host"
|
|
388
|
+
type="text"
|
|
389
|
+
placeholder="imap.example.com"
|
|
390
|
+
class="mt-2 w-full max-w-sm rounded-lg border border-[var(--esc-panel-border-input)] bg-[var(--esc-panel-surface-alt)] px-3 py-2 text-sm text-[var(--esc-panel-text-secondary)] focus:border-[var(--esc-panel-border-input)] focus:outline-none focus:ring-1 focus:ring-[var(--esc-panel-border-input)]"
|
|
391
|
+
/>
|
|
392
|
+
</div>
|
|
393
|
+
<div class="flex items-end gap-4">
|
|
394
|
+
<div>
|
|
395
|
+
<label class="block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
396
|
+
>Port</label
|
|
397
|
+
>
|
|
398
|
+
<input
|
|
399
|
+
v-model.number="form.imap_port"
|
|
400
|
+
type="number"
|
|
401
|
+
min="1"
|
|
402
|
+
max="65535"
|
|
403
|
+
class="mt-2 w-24 rounded-lg border border-[var(--esc-panel-border-input)] bg-[var(--esc-panel-surface-alt)] px-3 py-2 text-sm text-[var(--esc-panel-text-secondary)] focus:border-[var(--esc-panel-border-input)] focus:outline-none focus:ring-1 focus:ring-[var(--esc-panel-border-input)]"
|
|
404
|
+
/>
|
|
405
|
+
</div>
|
|
406
|
+
<div>
|
|
407
|
+
<label class="block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
408
|
+
>Encryption</label
|
|
409
|
+
>
|
|
410
|
+
<select
|
|
411
|
+
v-model="form.imap_encryption"
|
|
412
|
+
class="mt-2 w-28 rounded-lg border border-[var(--esc-panel-border-input)] bg-[var(--esc-panel-surface-alt)] px-3 py-2 text-sm text-[var(--esc-panel-text-secondary)] focus:border-[var(--esc-panel-border-input)] focus:outline-none focus:ring-1 focus:ring-[var(--esc-panel-border-input)]"
|
|
413
|
+
>
|
|
414
|
+
<option value="ssl">SSL</option>
|
|
415
|
+
<option value="tls">TLS</option>
|
|
416
|
+
<option value="none">None</option>
|
|
417
|
+
</select>
|
|
418
|
+
</div>
|
|
419
|
+
</div>
|
|
420
|
+
<div>
|
|
421
|
+
<label class="block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
422
|
+
>Username</label
|
|
423
|
+
>
|
|
424
|
+
<input
|
|
425
|
+
v-model="form.imap_username"
|
|
426
|
+
type="text"
|
|
427
|
+
class="mt-2 w-full max-w-sm rounded-lg border border-[var(--esc-panel-border-input)] bg-[var(--esc-panel-surface-alt)] px-3 py-2 text-sm text-[var(--esc-panel-text-secondary)] focus:border-[var(--esc-panel-border-input)] focus:outline-none focus:ring-1 focus:ring-[var(--esc-panel-border-input)]"
|
|
428
|
+
/>
|
|
429
|
+
</div>
|
|
430
|
+
<div>
|
|
431
|
+
<label class="block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
432
|
+
>Password</label
|
|
433
|
+
>
|
|
434
|
+
<input
|
|
435
|
+
v-model="form.imap_password"
|
|
436
|
+
type="password"
|
|
437
|
+
class="mt-2 w-full max-w-sm rounded-lg border border-[var(--esc-panel-border-input)] bg-[var(--esc-panel-surface-alt)] px-3 py-2 text-sm text-[var(--esc-panel-text-secondary)] focus:border-[var(--esc-panel-border-input)] focus:outline-none focus:ring-1 focus:ring-[var(--esc-panel-border-input)]"
|
|
438
|
+
/>
|
|
439
|
+
</div>
|
|
440
|
+
<div>
|
|
441
|
+
<label class="block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
442
|
+
>Mailbox</label
|
|
443
|
+
>
|
|
444
|
+
<input
|
|
445
|
+
v-model="form.imap_mailbox"
|
|
446
|
+
type="text"
|
|
447
|
+
placeholder="INBOX"
|
|
448
|
+
class="mt-2 w-48 rounded-lg border border-[var(--esc-panel-border-input)] bg-[var(--esc-panel-surface-alt)] px-3 py-2 text-sm text-[var(--esc-panel-text-secondary)] focus:border-[var(--esc-panel-border-input)] focus:outline-none focus:ring-1 focus:ring-[var(--esc-panel-border-input)]"
|
|
449
|
+
/>
|
|
450
|
+
</div>
|
|
451
|
+
</template>
|
|
452
|
+
</template>
|
|
453
|
+
</div>
|
|
454
|
+
</div>
|
|
455
|
+
|
|
456
|
+
<!-- Knowledge Base -->
|
|
457
|
+
<div class="rounded-xl border border-[var(--esc-panel-border)] bg-[var(--esc-panel-surface)] p-6">
|
|
458
|
+
<h3 class="mb-5 text-sm font-semibold text-[var(--esc-panel-text)]">Knowledge Base</h3>
|
|
459
|
+
<div class="space-y-5">
|
|
460
|
+
<label class="flex items-center justify-between">
|
|
461
|
+
<div>
|
|
462
|
+
<span class="text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
463
|
+
>Enable Knowledge Base</span
|
|
464
|
+
>
|
|
465
|
+
<p class="mt-0.5 text-xs text-[var(--esc-panel-text-muted)]">
|
|
466
|
+
Show the knowledge base to customers and visitors
|
|
467
|
+
</p>
|
|
468
|
+
</div>
|
|
469
|
+
<button
|
|
470
|
+
type="button"
|
|
471
|
+
:class="[
|
|
472
|
+
'relative inline-flex h-6 w-11 shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors',
|
|
473
|
+
form.knowledge_base_enabled ? 'bg-emerald-500' : 'bg-neutral-700',
|
|
474
|
+
]"
|
|
475
|
+
@click="form.knowledge_base_enabled = !form.knowledge_base_enabled"
|
|
476
|
+
>
|
|
477
|
+
<span
|
|
478
|
+
:class="[
|
|
479
|
+
'pointer-events-none inline-block h-5 w-5 transform rounded-full bg-white shadow ring-0 transition-transform',
|
|
480
|
+
form.knowledge_base_enabled ? 'translate-x-5' : 'translate-x-0',
|
|
481
|
+
]"
|
|
482
|
+
/>
|
|
483
|
+
</button>
|
|
484
|
+
</label>
|
|
485
|
+
<label class="flex items-center justify-between">
|
|
486
|
+
<div>
|
|
487
|
+
<span class="text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
488
|
+
>Public Access</span
|
|
489
|
+
>
|
|
490
|
+
<p class="mt-0.5 text-xs text-[var(--esc-panel-text-muted)]">
|
|
491
|
+
Allow unauthenticated visitors to browse the knowledge base
|
|
492
|
+
</p>
|
|
493
|
+
</div>
|
|
494
|
+
<button
|
|
495
|
+
type="button"
|
|
496
|
+
:class="[
|
|
497
|
+
'relative inline-flex h-6 w-11 shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors',
|
|
498
|
+
form.knowledge_base_public ? 'bg-emerald-500' : 'bg-neutral-700',
|
|
499
|
+
]"
|
|
500
|
+
@click="form.knowledge_base_public = !form.knowledge_base_public"
|
|
501
|
+
>
|
|
502
|
+
<span
|
|
503
|
+
:class="[
|
|
504
|
+
'pointer-events-none inline-block h-5 w-5 transform rounded-full bg-white shadow ring-0 transition-transform',
|
|
505
|
+
form.knowledge_base_public ? 'translate-x-5' : 'translate-x-0',
|
|
506
|
+
]"
|
|
507
|
+
/>
|
|
508
|
+
</button>
|
|
509
|
+
</label>
|
|
510
|
+
<label class="flex items-center justify-between">
|
|
511
|
+
<div>
|
|
512
|
+
<span class="text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
513
|
+
>Article Feedback</span
|
|
514
|
+
>
|
|
515
|
+
<p class="mt-0.5 text-xs text-[var(--esc-panel-text-muted)]">
|
|
516
|
+
Show helpful / not helpful buttons on articles
|
|
517
|
+
</p>
|
|
518
|
+
</div>
|
|
519
|
+
<button
|
|
520
|
+
type="button"
|
|
521
|
+
:class="[
|
|
522
|
+
'relative inline-flex h-6 w-11 shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors',
|
|
523
|
+
form.knowledge_base_feedback_enabled ? 'bg-emerald-500' : 'bg-neutral-700',
|
|
524
|
+
]"
|
|
525
|
+
@click="form.knowledge_base_feedback_enabled = !form.knowledge_base_feedback_enabled"
|
|
526
|
+
>
|
|
527
|
+
<span
|
|
528
|
+
:class="[
|
|
529
|
+
'pointer-events-none inline-block h-5 w-5 transform rounded-full bg-white shadow ring-0 transition-transform',
|
|
530
|
+
form.knowledge_base_feedback_enabled ? 'translate-x-5' : 'translate-x-0',
|
|
531
|
+
]"
|
|
532
|
+
/>
|
|
533
|
+
</button>
|
|
534
|
+
</label>
|
|
535
|
+
</div>
|
|
536
|
+
</div>
|
|
537
|
+
|
|
538
|
+
<!-- Branding -->
|
|
539
|
+
<div class="rounded-xl border border-[var(--esc-panel-border)] bg-[var(--esc-panel-surface)] p-6">
|
|
540
|
+
<h3 class="mb-5 text-sm font-semibold text-[var(--esc-panel-text)]">Branding</h3>
|
|
541
|
+
<div class="space-y-5">
|
|
542
|
+
<label class="flex items-center justify-between">
|
|
543
|
+
<div>
|
|
544
|
+
<span class="text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
545
|
+
>Show "Powered by Escalated"</span
|
|
546
|
+
>
|
|
547
|
+
<p class="mt-0.5 text-xs text-[var(--esc-panel-text-muted)]">
|
|
548
|
+
Display attribution badge in the support portal footer
|
|
549
|
+
</p>
|
|
550
|
+
</div>
|
|
551
|
+
<button
|
|
552
|
+
type="button"
|
|
553
|
+
:class="[
|
|
554
|
+
'relative inline-flex h-6 w-11 shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors',
|
|
555
|
+
form.show_powered_by ? 'bg-emerald-500' : 'bg-neutral-700',
|
|
556
|
+
]"
|
|
557
|
+
@click="form.show_powered_by = !form.show_powered_by"
|
|
558
|
+
>
|
|
559
|
+
<span
|
|
560
|
+
:class="[
|
|
561
|
+
'pointer-events-none inline-block h-5 w-5 transform rounded-full bg-white shadow ring-0 transition-transform',
|
|
562
|
+
form.show_powered_by ? 'translate-x-5' : 'translate-x-0',
|
|
563
|
+
]"
|
|
564
|
+
/>
|
|
565
|
+
</button>
|
|
566
|
+
</label>
|
|
567
|
+
</div>
|
|
568
|
+
</div>
|
|
569
|
+
|
|
570
|
+
<!-- Support Widget -->
|
|
571
|
+
<div class="rounded-xl border border-[var(--esc-panel-border)] bg-[var(--esc-panel-surface)] p-6">
|
|
572
|
+
<h3 class="mb-5 text-sm font-semibold text-[var(--esc-panel-text)]">Support Widget</h3>
|
|
573
|
+
<div class="space-y-5">
|
|
574
|
+
<label class="flex items-center justify-between">
|
|
575
|
+
<div>
|
|
576
|
+
<span class="text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
577
|
+
>Enable Widget</span
|
|
578
|
+
>
|
|
579
|
+
<p class="mt-0.5 text-xs text-[var(--esc-panel-text-muted)]">
|
|
580
|
+
Show an embeddable support widget on your site
|
|
581
|
+
</p>
|
|
582
|
+
</div>
|
|
583
|
+
<button
|
|
584
|
+
type="button"
|
|
585
|
+
:class="[
|
|
586
|
+
'relative inline-flex h-6 w-11 shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors',
|
|
587
|
+
form.widget_enabled ? 'bg-emerald-500' : 'bg-neutral-700',
|
|
588
|
+
]"
|
|
589
|
+
@click="form.widget_enabled = !form.widget_enabled"
|
|
590
|
+
>
|
|
591
|
+
<span
|
|
592
|
+
:class="[
|
|
593
|
+
'pointer-events-none inline-block h-5 w-5 transform rounded-full bg-white shadow ring-0 transition-transform',
|
|
594
|
+
form.widget_enabled ? 'translate-x-5' : 'translate-x-0',
|
|
595
|
+
]"
|
|
596
|
+
/>
|
|
597
|
+
</button>
|
|
598
|
+
</label>
|
|
599
|
+
<template v-if="form.widget_enabled">
|
|
600
|
+
<div>
|
|
601
|
+
<label class="block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
602
|
+
>Widget Color</label
|
|
603
|
+
>
|
|
604
|
+
<p class="mt-0.5 text-xs text-[var(--esc-panel-text-muted)]">
|
|
605
|
+
Primary color for the widget button and header
|
|
606
|
+
</p>
|
|
607
|
+
<div class="mt-2 flex items-center gap-3">
|
|
608
|
+
<input
|
|
609
|
+
v-model="form.widget_color"
|
|
610
|
+
type="color"
|
|
611
|
+
class="h-9 w-12 cursor-pointer rounded-lg border border-[var(--esc-panel-border-input)] bg-[var(--esc-panel-surface-alt)] p-0.5"
|
|
612
|
+
/>
|
|
613
|
+
<input
|
|
614
|
+
v-model="form.widget_color"
|
|
615
|
+
type="text"
|
|
616
|
+
maxlength="7"
|
|
617
|
+
class="w-28 rounded-lg border border-[var(--esc-panel-border-input)] bg-[var(--esc-panel-surface-alt)] px-3 py-2 text-sm text-[var(--esc-panel-text-secondary)] uppercase focus:border-[var(--esc-panel-border-input)] focus:outline-none focus:ring-1 focus:ring-[var(--esc-panel-border-input)]"
|
|
618
|
+
/>
|
|
619
|
+
</div>
|
|
620
|
+
</div>
|
|
621
|
+
<div>
|
|
622
|
+
<label class="block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
623
|
+
>Position</label
|
|
624
|
+
>
|
|
625
|
+
<select
|
|
626
|
+
v-model="form.widget_position"
|
|
627
|
+
class="mt-2 w-48 rounded-lg border border-[var(--esc-panel-border-input)] bg-[var(--esc-panel-surface-alt)] px-3 py-2 text-sm text-[var(--esc-panel-text-secondary)] focus:border-[var(--esc-panel-border-input)] focus:outline-none focus:ring-1 focus:ring-[var(--esc-panel-border-input)]"
|
|
628
|
+
>
|
|
629
|
+
<option value="bottom-right">Bottom Right</option>
|
|
630
|
+
<option value="bottom-left">Bottom Left</option>
|
|
631
|
+
</select>
|
|
632
|
+
</div>
|
|
633
|
+
<div>
|
|
634
|
+
<label class="block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
635
|
+
>Greeting Message</label
|
|
636
|
+
>
|
|
637
|
+
<input
|
|
638
|
+
v-model="form.widget_greeting"
|
|
639
|
+
type="text"
|
|
640
|
+
maxlength="255"
|
|
641
|
+
class="mt-2 w-full max-w-sm rounded-lg border border-[var(--esc-panel-border-input)] bg-[var(--esc-panel-surface-alt)] px-3 py-2 text-sm text-[var(--esc-panel-text-secondary)] focus:border-[var(--esc-panel-border-input)] focus:outline-none focus:ring-1 focus:ring-[var(--esc-panel-border-input)]"
|
|
642
|
+
/>
|
|
643
|
+
</div>
|
|
644
|
+
<div v-if="departments?.length">
|
|
645
|
+
<label class="block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
646
|
+
>Departments</label
|
|
647
|
+
>
|
|
648
|
+
<p class="mt-0.5 text-xs text-[var(--esc-panel-text-muted)]">
|
|
649
|
+
Select which departments appear in the widget (leave empty for all)
|
|
650
|
+
</p>
|
|
651
|
+
<div class="mt-2 space-y-2">
|
|
652
|
+
<label v-for="dept in departments" :key="dept.id" class="flex items-center gap-2">
|
|
653
|
+
<input
|
|
654
|
+
type="checkbox"
|
|
655
|
+
:value="dept.id"
|
|
656
|
+
:checked="
|
|
657
|
+
form.widget_departments.split(',').filter(Boolean).includes(String(dept.id))
|
|
658
|
+
"
|
|
659
|
+
class="rounded border-[var(--esc-panel-border-input)] bg-[var(--esc-panel-surface-alt)] text-emerald-500 focus:ring-emerald-500"
|
|
660
|
+
@change="
|
|
661
|
+
(e) => {
|
|
662
|
+
const ids = form.widget_departments.split(',').filter(Boolean);
|
|
663
|
+
if (e.target.checked) {
|
|
664
|
+
ids.push(String(dept.id));
|
|
665
|
+
} else {
|
|
666
|
+
const idx = ids.indexOf(String(dept.id));
|
|
667
|
+
if (idx > -1) ids.splice(idx, 1);
|
|
668
|
+
}
|
|
669
|
+
form.widget_departments = ids.join(',');
|
|
670
|
+
}
|
|
671
|
+
"
|
|
672
|
+
/>
|
|
673
|
+
<span class="text-sm text-[var(--esc-panel-text-secondary)]">{{ dept.name }}</span>
|
|
674
|
+
</label>
|
|
675
|
+
</div>
|
|
676
|
+
</div>
|
|
677
|
+
<div
|
|
678
|
+
class="rounded-lg border border-[var(--esc-panel-border)] bg-[var(--esc-panel-surface-alt)] p-4"
|
|
679
|
+
>
|
|
680
|
+
<label class="block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
681
|
+
>Embed Code</label
|
|
682
|
+
>
|
|
683
|
+
<p class="mt-0.5 text-xs text-[var(--esc-panel-text-muted)]">
|
|
684
|
+
Add this snippet to your website to show the support widget
|
|
685
|
+
</p>
|
|
686
|
+
<code
|
|
687
|
+
class="mt-2 block whitespace-pre-wrap break-all rounded-lg bg-[var(--esc-panel-bg)] p-3 text-xs text-[var(--esc-panel-text-tertiary)] select-all"
|
|
688
|
+
><script src="/{{ page.props.escalated?.prefix || 'support' }}/widget/embed.js"
|
|
689
|
+
data-color="{{ form.widget_color }}" data-position="{{
|
|
690
|
+
form.widget_position
|
|
691
|
+
}}"></script></code
|
|
692
|
+
>
|
|
693
|
+
</div>
|
|
694
|
+
</template>
|
|
695
|
+
</div>
|
|
696
|
+
</div>
|
|
697
|
+
|
|
698
|
+
<!-- Live Chat -->
|
|
699
|
+
<div class="rounded-xl border border-[var(--esc-panel-border)] bg-[var(--esc-panel-surface)] p-6">
|
|
700
|
+
<h3 class="mb-5 text-sm font-semibold text-[var(--esc-panel-text)]">Live Chat</h3>
|
|
701
|
+
<div class="space-y-5">
|
|
702
|
+
<label class="flex items-center justify-between">
|
|
703
|
+
<div>
|
|
704
|
+
<span class="text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
705
|
+
>Enable Live Chat</span
|
|
706
|
+
>
|
|
707
|
+
<p class="mt-0.5 text-xs text-[var(--esc-panel-text-muted)]">
|
|
708
|
+
Allow customers to start real-time chat sessions
|
|
709
|
+
</p>
|
|
710
|
+
</div>
|
|
711
|
+
<input
|
|
712
|
+
v-model="form.chat_enabled"
|
|
713
|
+
type="checkbox"
|
|
714
|
+
:true-value="true"
|
|
715
|
+
:false-value="false"
|
|
716
|
+
class="h-4 w-4 rounded border-[var(--esc-panel-border-input)] bg-[var(--esc-panel-surface-alt)] text-[var(--esc-panel-accent)] focus:ring-[var(--esc-panel-accent)]/20"
|
|
717
|
+
/>
|
|
718
|
+
</label>
|
|
719
|
+
<label class="flex items-center justify-between">
|
|
720
|
+
<div>
|
|
721
|
+
<span class="text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
722
|
+
>Sound Notifications</span
|
|
723
|
+
>
|
|
724
|
+
<p class="mt-0.5 text-xs text-[var(--esc-panel-text-muted)]">
|
|
725
|
+
Play sound on new chat messages
|
|
726
|
+
</p>
|
|
727
|
+
</div>
|
|
728
|
+
<input
|
|
729
|
+
v-model="form.chat_sound_notifications"
|
|
730
|
+
type="checkbox"
|
|
731
|
+
:true-value="true"
|
|
732
|
+
:false-value="false"
|
|
733
|
+
class="h-4 w-4 rounded border-[var(--esc-panel-border-input)] bg-[var(--esc-panel-surface-alt)] text-[var(--esc-panel-accent)] focus:ring-[var(--esc-panel-accent)]/20"
|
|
734
|
+
/>
|
|
735
|
+
</label>
|
|
736
|
+
</div>
|
|
737
|
+
</div>
|
|
738
|
+
|
|
739
|
+
<!-- Chat Routing -->
|
|
740
|
+
<div
|
|
741
|
+
v-if="form.chat_enabled"
|
|
742
|
+
class="rounded-xl border border-[var(--esc-panel-border)] bg-[var(--esc-panel-surface)] p-6"
|
|
743
|
+
>
|
|
744
|
+
<h3 class="mb-5 text-sm font-semibold text-[var(--esc-panel-text)]">Chat Routing</h3>
|
|
745
|
+
<div class="space-y-5">
|
|
746
|
+
<div>
|
|
747
|
+
<label class="mb-1 block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
748
|
+
>Routing Strategy</label
|
|
749
|
+
>
|
|
750
|
+
<select
|
|
751
|
+
v-model="form.chat_routing_strategy"
|
|
752
|
+
class="w-full rounded-lg border border-[var(--esc-panel-border-input)] bg-[var(--esc-panel-surface)] px-3 py-2 text-sm text-[var(--esc-panel-text-secondary)]"
|
|
753
|
+
>
|
|
754
|
+
<option value="round_robin">Round Robin</option>
|
|
755
|
+
<option value="least_active">Least Active</option>
|
|
756
|
+
<option value="manual">Manual (Queue)</option>
|
|
757
|
+
</select>
|
|
758
|
+
</div>
|
|
759
|
+
<div>
|
|
760
|
+
<label class="mb-1 block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
761
|
+
>Offline Behavior</label
|
|
762
|
+
>
|
|
763
|
+
<select
|
|
764
|
+
v-model="form.chat_offline_behavior"
|
|
765
|
+
class="w-full rounded-lg border border-[var(--esc-panel-border-input)] bg-[var(--esc-panel-surface)] px-3 py-2 text-sm text-[var(--esc-panel-text-secondary)]"
|
|
766
|
+
>
|
|
767
|
+
<option value="ticket_form">Show Ticket Form</option>
|
|
768
|
+
<option value="offline_message">Show Offline Message</option>
|
|
769
|
+
<option value="hide">Hide Chat</option>
|
|
770
|
+
</select>
|
|
771
|
+
</div>
|
|
772
|
+
<div class="grid grid-cols-2 gap-4">
|
|
773
|
+
<div>
|
|
774
|
+
<label class="mb-1 block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
775
|
+
>Max Queue Size</label
|
|
776
|
+
>
|
|
777
|
+
<input
|
|
778
|
+
v-model.number="form.chat_max_queue"
|
|
779
|
+
type="number"
|
|
780
|
+
min="1"
|
|
781
|
+
class="w-full rounded-lg border border-[var(--esc-panel-border-input)] bg-[var(--esc-panel-surface)] px-3 py-2 text-sm text-[var(--esc-panel-text-secondary)]"
|
|
782
|
+
/>
|
|
783
|
+
</div>
|
|
784
|
+
<div>
|
|
785
|
+
<label class="mb-1 block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
786
|
+
>Concurrent Limit</label
|
|
787
|
+
>
|
|
788
|
+
<input
|
|
789
|
+
v-model.number="form.chat_concurrent_limit"
|
|
790
|
+
type="number"
|
|
791
|
+
min="1"
|
|
792
|
+
class="w-full rounded-lg border border-[var(--esc-panel-border-input)] bg-[var(--esc-panel-surface)] px-3 py-2 text-sm text-[var(--esc-panel-text-secondary)]"
|
|
793
|
+
/>
|
|
794
|
+
</div>
|
|
795
|
+
</div>
|
|
796
|
+
<div>
|
|
797
|
+
<label class="mb-1 block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
798
|
+
>Auto-close after (minutes)</label
|
|
799
|
+
>
|
|
800
|
+
<input
|
|
801
|
+
v-model.number="form.chat_auto_close_minutes"
|
|
802
|
+
type="number"
|
|
803
|
+
min="1"
|
|
804
|
+
class="w-full rounded-lg border border-[var(--esc-panel-border-input)] bg-[var(--esc-panel-surface)] px-3 py-2 text-sm text-[var(--esc-panel-text-secondary)]"
|
|
805
|
+
/>
|
|
806
|
+
</div>
|
|
807
|
+
<div>
|
|
808
|
+
<label class="mb-1 block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
809
|
+
>Queue Message</label
|
|
810
|
+
>
|
|
811
|
+
<input
|
|
812
|
+
v-model="form.chat_queue_message"
|
|
813
|
+
type="text"
|
|
814
|
+
placeholder="You're in the queue..."
|
|
815
|
+
class="w-full rounded-lg border border-[var(--esc-panel-border-input)] bg-[var(--esc-panel-surface)] px-3 py-2 text-sm text-[var(--esc-panel-text-secondary)] placeholder-[var(--esc-panel-text-muted)]"
|
|
816
|
+
/>
|
|
817
|
+
</div>
|
|
818
|
+
<div>
|
|
819
|
+
<label class="mb-1 block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
820
|
+
>Offline Message</label
|
|
821
|
+
>
|
|
822
|
+
<input
|
|
823
|
+
v-model="form.chat_offline_message"
|
|
824
|
+
type="text"
|
|
825
|
+
placeholder="Sorry, we're not available right now..."
|
|
826
|
+
class="w-full rounded-lg border border-[var(--esc-panel-border-input)] bg-[var(--esc-panel-surface)] px-3 py-2 text-sm text-[var(--esc-panel-text-secondary)] placeholder-[var(--esc-panel-text-muted)]"
|
|
827
|
+
/>
|
|
828
|
+
</div>
|
|
829
|
+
</div>
|
|
830
|
+
</div>
|
|
831
|
+
|
|
832
|
+
<!-- Widget Theme -->
|
|
833
|
+
<div class="rounded-xl border border-[var(--esc-panel-border)] bg-[var(--esc-panel-surface)] p-6">
|
|
834
|
+
<h3 class="mb-5 text-sm font-semibold text-[var(--esc-panel-text)]">Widget Theme</h3>
|
|
835
|
+
<div class="space-y-5">
|
|
836
|
+
<div class="grid grid-cols-2 gap-4">
|
|
837
|
+
<div>
|
|
838
|
+
<label class="mb-1 block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
839
|
+
>Primary Color</label
|
|
840
|
+
>
|
|
841
|
+
<input
|
|
842
|
+
v-model="form.widget_primary_color"
|
|
843
|
+
type="color"
|
|
844
|
+
class="h-10 w-full cursor-pointer rounded-lg border border-[var(--esc-panel-border-input)]"
|
|
845
|
+
/>
|
|
846
|
+
</div>
|
|
847
|
+
<div>
|
|
848
|
+
<label class="mb-1 block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
849
|
+
>Header Background</label
|
|
850
|
+
>
|
|
851
|
+
<input
|
|
852
|
+
v-model="form.widget_header_background"
|
|
853
|
+
type="color"
|
|
854
|
+
class="h-10 w-full cursor-pointer rounded-lg border border-[var(--esc-panel-border-input)]"
|
|
855
|
+
/>
|
|
856
|
+
</div>
|
|
857
|
+
<div>
|
|
858
|
+
<label class="mb-1 block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
859
|
+
>Agent Bubble Color</label
|
|
860
|
+
>
|
|
861
|
+
<input
|
|
862
|
+
v-model="form.widget_agent_bubble_color"
|
|
863
|
+
type="color"
|
|
864
|
+
class="h-10 w-full cursor-pointer rounded-lg border border-[var(--esc-panel-border-input)]"
|
|
865
|
+
/>
|
|
866
|
+
</div>
|
|
867
|
+
<div>
|
|
868
|
+
<label class="mb-1 block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
869
|
+
>Customer Bubble Color</label
|
|
870
|
+
>
|
|
871
|
+
<input
|
|
872
|
+
v-model="form.widget_customer_bubble_color"
|
|
873
|
+
type="color"
|
|
874
|
+
class="h-10 w-full cursor-pointer rounded-lg border border-[var(--esc-panel-border-input)]"
|
|
875
|
+
/>
|
|
876
|
+
</div>
|
|
877
|
+
<div>
|
|
878
|
+
<label class="mb-1 block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
879
|
+
>Background Color</label
|
|
880
|
+
>
|
|
881
|
+
<input
|
|
882
|
+
v-model="form.widget_background_color"
|
|
883
|
+
type="color"
|
|
884
|
+
class="h-10 w-full cursor-pointer rounded-lg border border-[var(--esc-panel-border-input)]"
|
|
885
|
+
/>
|
|
886
|
+
</div>
|
|
887
|
+
<div>
|
|
888
|
+
<label class="mb-1 block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
889
|
+
>Text Color</label
|
|
890
|
+
>
|
|
891
|
+
<input
|
|
892
|
+
v-model="form.widget_text_color"
|
|
893
|
+
type="color"
|
|
894
|
+
class="h-10 w-full cursor-pointer rounded-lg border border-[var(--esc-panel-border-input)]"
|
|
895
|
+
/>
|
|
896
|
+
</div>
|
|
897
|
+
</div>
|
|
898
|
+
<div>
|
|
899
|
+
<label class="mb-1 block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
900
|
+
>Font Family</label
|
|
901
|
+
>
|
|
902
|
+
<select
|
|
903
|
+
v-model="form.widget_font_family"
|
|
904
|
+
class="w-full rounded-lg border border-[var(--esc-panel-border-input)] bg-[var(--esc-panel-surface)] px-3 py-2 text-sm text-[var(--esc-panel-text-secondary)]"
|
|
905
|
+
>
|
|
906
|
+
<option value="system">System Default</option>
|
|
907
|
+
<option value="Inter">Inter</option>
|
|
908
|
+
<option value="Roboto">Roboto</option>
|
|
909
|
+
<option value="Open Sans">Open Sans</option>
|
|
910
|
+
<option value="Lato">Lato</option>
|
|
911
|
+
<option value="Poppins">Poppins</option>
|
|
912
|
+
<option value="Nunito">Nunito</option>
|
|
913
|
+
</select>
|
|
914
|
+
</div>
|
|
915
|
+
<div>
|
|
916
|
+
<label class="mb-1 block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
917
|
+
>Border Radius ({{ form.widget_border_radius }}px)</label
|
|
918
|
+
>
|
|
919
|
+
<input
|
|
920
|
+
v-model.number="form.widget_border_radius"
|
|
921
|
+
type="range"
|
|
922
|
+
min="0"
|
|
923
|
+
max="20"
|
|
924
|
+
class="w-full"
|
|
925
|
+
/>
|
|
926
|
+
</div>
|
|
927
|
+
<div>
|
|
928
|
+
<label class="mb-1 block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
929
|
+
>Launcher Size</label
|
|
930
|
+
>
|
|
931
|
+
<div class="flex gap-3">
|
|
932
|
+
<label
|
|
933
|
+
v-for="size in ['small', 'medium', 'large']"
|
|
934
|
+
:key="size"
|
|
935
|
+
class="flex items-center gap-2"
|
|
936
|
+
>
|
|
937
|
+
<input
|
|
938
|
+
v-model="form.widget_launcher_size"
|
|
939
|
+
type="radio"
|
|
940
|
+
:value="size"
|
|
941
|
+
class="text-[var(--esc-panel-accent)] focus:ring-[var(--esc-panel-accent)]/20"
|
|
942
|
+
/>
|
|
943
|
+
<span class="text-sm capitalize text-[var(--esc-panel-text-secondary)]">{{
|
|
944
|
+
size
|
|
945
|
+
}}</span>
|
|
946
|
+
</label>
|
|
947
|
+
</div>
|
|
948
|
+
</div>
|
|
949
|
+
<label class="flex items-center justify-between">
|
|
950
|
+
<span class="text-sm font-medium text-[var(--esc-panel-text-secondary)]">Show Branding</span>
|
|
951
|
+
<input
|
|
952
|
+
v-model="form.widget_show_branding"
|
|
953
|
+
type="checkbox"
|
|
954
|
+
:true-value="true"
|
|
955
|
+
:false-value="false"
|
|
956
|
+
class="h-4 w-4 rounded border-[var(--esc-panel-border-input)] bg-[var(--esc-panel-surface-alt)] text-[var(--esc-panel-accent)] focus:ring-[var(--esc-panel-accent)]/20"
|
|
957
|
+
/>
|
|
958
|
+
</label>
|
|
959
|
+
<div>
|
|
960
|
+
<label class="mb-1 block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
961
|
+
>Pre-chat Message</label
|
|
962
|
+
>
|
|
963
|
+
<input
|
|
964
|
+
v-model="form.widget_pre_chat_message"
|
|
965
|
+
type="text"
|
|
966
|
+
class="w-full rounded-lg border border-[var(--esc-panel-border-input)] bg-[var(--esc-panel-surface)] px-3 py-2 text-sm text-[var(--esc-panel-text-secondary)] placeholder-[var(--esc-panel-text-muted)]"
|
|
967
|
+
/>
|
|
968
|
+
</div>
|
|
969
|
+
<div>
|
|
970
|
+
<label class="mb-1 block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
971
|
+
>Chat Header Text</label
|
|
972
|
+
>
|
|
973
|
+
<input
|
|
974
|
+
v-model="form.widget_chat_header_text"
|
|
975
|
+
type="text"
|
|
976
|
+
class="w-full rounded-lg border border-[var(--esc-panel-border-input)] bg-[var(--esc-panel-surface)] px-3 py-2 text-sm text-[var(--esc-panel-text-secondary)] placeholder-[var(--esc-panel-text-muted)]"
|
|
977
|
+
/>
|
|
978
|
+
</div>
|
|
979
|
+
<div>
|
|
980
|
+
<label class="mb-1 block text-sm font-medium text-[var(--esc-panel-text-secondary)]"
|
|
981
|
+
>Custom CSS</label
|
|
982
|
+
>
|
|
983
|
+
<textarea
|
|
984
|
+
v-model="form.widget_custom_css"
|
|
985
|
+
rows="4"
|
|
986
|
+
placeholder=".esc-w-panel { /* custom styles */ }"
|
|
987
|
+
class="w-full rounded-lg border border-[var(--esc-panel-border-input)] bg-[var(--esc-panel-surface)] px-3 py-2 font-mono text-xs text-[var(--esc-panel-text-secondary)] placeholder-[var(--esc-panel-text-muted)]"
|
|
988
|
+
></textarea>
|
|
989
|
+
</div>
|
|
990
|
+
</div>
|
|
991
|
+
</div>
|
|
992
|
+
|
|
993
|
+
<PluginSlot slot="admin.settings.extra" :components="getPageComponents('admin.settings', 'extra')" />
|
|
994
|
+
|
|
995
|
+
<!-- Submit -->
|
|
996
|
+
<div class="flex items-center justify-end gap-3">
|
|
997
|
+
<span v-if="form.recentlySuccessful" class="text-sm text-emerald-400">Saved.</span>
|
|
998
|
+
<button
|
|
999
|
+
type="submit"
|
|
1000
|
+
:disabled="form.processing"
|
|
1001
|
+
class="rounded-lg bg-gradient-to-r from-[var(--esc-panel-accent)] to-[var(--esc-panel-accent-secondary)] px-5 py-2 text-sm font-medium text-white shadow-lg shadow-[var(--esc-panel-bg)]/20 transition-all hover:from-[var(--esc-panel-accent-hover)] hover:to-[var(--esc-panel-accent-secondary-hover)] disabled:opacity-50"
|
|
1002
|
+
>
|
|
1003
|
+
{{ form.processing ? 'Saving...' : 'Save Settings' }}
|
|
1004
|
+
</button>
|
|
1005
|
+
</div>
|
|
1006
|
+
</form>
|
|
1007
|
+
</EscalatedLayout>
|
|
1008
|
+
</template>
|