@escalated-dev/escalated 0.8.0 → 0.9.0
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 +380 -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 +619 -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/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/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/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/Workflows/Builder.vue +207 -207
- 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/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,604 +1,619 @@
|
|
|
1
|
-
<script setup>
|
|
2
|
-
import { computed, inject, provide } from 'vue';
|
|
3
|
-
import { usePage, Link } from '@inertiajs/vue3';
|
|
4
|
-
import { usePluginExtensions } from '../composables/usePluginExtensions';
|
|
5
|
-
import
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
const
|
|
25
|
-
const
|
|
26
|
-
const
|
|
27
|
-
const
|
|
28
|
-
const
|
|
29
|
-
const
|
|
30
|
-
const
|
|
31
|
-
const
|
|
32
|
-
const
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
<
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
<
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
>
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
</
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
>
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
>
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
>
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
</
|
|
1
|
+
<script setup>
|
|
2
|
+
import { computed, inject, provide } from 'vue';
|
|
3
|
+
import { usePage, Link } from '@inertiajs/vue3';
|
|
4
|
+
import { usePluginExtensions } from '../composables/usePluginExtensions';
|
|
5
|
+
import { usePermissions } from '../composables/usePermissions';
|
|
6
|
+
import { useI18n } from '../composables/useI18n';
|
|
7
|
+
import ActiveChatsPanel from './ActiveChatsPanel.vue';
|
|
8
|
+
|
|
9
|
+
defineProps({
|
|
10
|
+
title: { type: String, default: 'Support' },
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
const page = usePage();
|
|
14
|
+
const hostLayout = inject('escalated-layout', null);
|
|
15
|
+
const panelConfig = inject('escalated-panel', { appName: 'Escalated', logo: null, mode: 'dark' });
|
|
16
|
+
|
|
17
|
+
const isAgent = computed(() => page.props.escalated?.is_agent);
|
|
18
|
+
const isAdmin = computed(() => page.props.escalated?.is_admin);
|
|
19
|
+
const prefix = computed(() => {
|
|
20
|
+
const p = page.props.escalated?.prefix || 'support';
|
|
21
|
+
return p.startsWith('/') ? p : `/${p}`;
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
const currentUrl = computed(() => page.url);
|
|
25
|
+
const isAdminSection = computed(() => currentUrl.value?.includes('/admin'));
|
|
26
|
+
const isAgentSection = computed(() => currentUrl.value?.includes('/agent'));
|
|
27
|
+
const isPanel = computed(() => isAdminSection.value || isAgentSection.value);
|
|
28
|
+
const isDark = computed(() => isPanel.value && panelConfig.mode !== 'light');
|
|
29
|
+
const showPoweredBy = computed(() => page.props.escalated?.show_powered_by !== false);
|
|
30
|
+
const kbEnabled = computed(() => page.props.escalated?.knowledge_base_enabled !== false);
|
|
31
|
+
const newslettersEnabled = computed(() => page.props.escalated?.features?.newsletters === true);
|
|
32
|
+
const kbPublic = computed(() => page.props.escalated?.knowledge_base_public !== false);
|
|
33
|
+
const chatEnabled = computed(() => page.props.escalated?.chat_enabled === true);
|
|
34
|
+
const activeChats = computed(() => page.props.escalated?.active_chats || []);
|
|
35
|
+
const agentId = computed(() => page.props.auth?.user?.id);
|
|
36
|
+
|
|
37
|
+
provide('esc-dark', isDark);
|
|
38
|
+
|
|
39
|
+
const { menuItems: pluginMenuItems } = usePluginExtensions();
|
|
40
|
+
const { hasPermission } = usePermissions();
|
|
41
|
+
const { t } = useI18n();
|
|
42
|
+
|
|
43
|
+
const adminLinks = computed(() => {
|
|
44
|
+
const p = prefix.value;
|
|
45
|
+
const coreLinks = [
|
|
46
|
+
{
|
|
47
|
+
href: `${p}/admin/reports`,
|
|
48
|
+
label: 'Reports',
|
|
49
|
+
icon: 'M3 13.125C3 12.504 3.504 12 4.125 12h2.25c.621 0 1.125.504 1.125 1.125v6.75C7.5 20.496 6.996 21 6.375 21h-2.25A1.125 1.125 0 013 19.875v-6.75zM9.75 8.625c0-.621.504-1.125 1.125-1.125h2.25c.621 0 1.125.504 1.125 1.125v11.25c0 .621-.504 1.125-1.125 1.125h-2.25a1.125 1.125 0 01-1.125-1.125V8.625zM16.5 4.125c0-.621.504-1.125 1.125-1.125h2.25C20.496 3 21 3.504 21 4.125v15.75c0 .621-.504 1.125-1.125 1.125h-2.25a1.125 1.125 0 01-1.125-1.125V4.125z',
|
|
50
|
+
position: 10,
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
href: `${p}/admin/tickets`,
|
|
54
|
+
label: 'Tickets',
|
|
55
|
+
icon: 'M16.5 6v.75m0 3v.75m0 3v.75m0 3V18m-9-5.25h5.25M7.5 15h3M3.375 5.25c-.621 0-1.125.504-1.125 1.125v3.026a2.999 2.999 0 010 5.198v3.026c0 .621.504 1.125 1.125 1.125h17.25c.621 0 1.125-.504 1.125-1.125v-3.026a2.999 2.999 0 010-5.198V6.375c0-.621-.504-1.125-1.125-1.125H3.375z',
|
|
56
|
+
position: 20,
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
href: `${p}/admin/departments`,
|
|
60
|
+
label: 'Departments',
|
|
61
|
+
icon: 'M2.25 7.125C2.25 6.504 2.754 6 3.375 6h6c.621 0 1.125.504 1.125 1.125v3.75c0 .621-.504 1.125-1.125 1.125h-6a1.125 1.125 0 01-1.125-1.125v-3.75zM14.25 8.625c0-.621.504-1.125 1.125-1.125h5.25c.621 0 1.125.504 1.125 1.125v8.25c0 .621-.504 1.125-1.125 1.125h-5.25a1.125 1.125 0 01-1.125-1.125v-8.25zM3.75 16.125c0-.621.504-1.125 1.125-1.125h5.25c.621 0 1.125.504 1.125 1.125v2.25c0 .621-.504 1.125-1.125 1.125h-5.25a1.125 1.125 0 01-1.125-1.125v-2.25z',
|
|
62
|
+
position: 30,
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
href: `${p}/admin/sla-policies`,
|
|
66
|
+
label: 'SLA Policies',
|
|
67
|
+
icon: 'M12 6v6h4.5m4.5 0a9 9 0 11-18 0 9 9 0 0118 0z',
|
|
68
|
+
position: 40,
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
href: `${p}/admin/kb-articles`,
|
|
72
|
+
label: 'Knowledge Base',
|
|
73
|
+
icon: 'M12 6.042A8.967 8.967 0 006 3.75c-1.052 0-2.062.18-3 .512v14.25A8.987 8.987 0 016 18c2.305 0 4.408.867 6 2.292m0-14.25a8.966 8.966 0 016-2.292c1.052 0 2.062.18 3 .512v14.25A8.987 8.987 0 0018 18a8.967 8.967 0 00-6 2.292m0-14.25v14.25',
|
|
74
|
+
position: 45,
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
href: `${p}/admin/escalation-rules`,
|
|
78
|
+
label: 'Escalation Rules',
|
|
79
|
+
icon: 'M3 4.5h14.25M3 9h9.75M3 13.5h5.25m5.25-.75L17.25 9m0 0L21 12.75M17.25 9v12',
|
|
80
|
+
position: 50,
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
href: `${p}/admin/workflows`,
|
|
84
|
+
label: 'Workflows',
|
|
85
|
+
icon: 'M9.594 3.94c.09-.542.56-.94 1.11-.94h2.593c.55 0 1.02.398 1.11.94l.213 1.281c.063.374.313.686.645.87.074.04.147.083.22.127.324.196.72.257 1.075.124l1.217-.456a1.125 1.125 0 011.37.49l1.296 2.247a1.125 1.125 0 01-.26 1.431l-1.003.827c-.293.24-.438.613-.431.992a6.759 6.759 0 010 .255c-.007.378.138.75.43.99l1.005.828c.424.35.534.954.26 1.43l-1.298 2.247a1.125 1.125 0 01-1.369.491l-1.217-.456c-.355-.133-.75-.072-1.076.124a6.57 6.57 0 01-.22.128c-.331.183-.581.495-.644.869l-.213 1.28c-.09.543-.56.941-1.11.941h-2.594c-.55 0-1.02-.398-1.11-.94l-.213-1.281c-.062-.374-.312-.686-.644-.87a6.52 6.52 0 01-.22-.127c-.325-.196-.72-.257-1.076-.124l-1.217.456a1.125 1.125 0 01-1.369-.49l-1.297-2.247a1.125 1.125 0 01.26-1.431l1.004-.827c.292-.24.437-.613.43-.992a6.932 6.932 0 010-.255c.007-.378-.138-.75-.43-.99l-1.004-.828a1.125 1.125 0 01-.26-1.43l1.297-2.247a1.125 1.125 0 011.37-.491l1.216.456c.356.133.751.072 1.076-.124.072-.044.146-.087.22-.128.332-.183.582-.495.644-.869l.214-1.281z M15 12a3 3 0 11-6 0 3 3 0 016 0z',
|
|
86
|
+
position: 53,
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
href: `${p}/admin/webhooks`,
|
|
90
|
+
label: 'Webhooks',
|
|
91
|
+
icon: 'M13.19 8.688a4.5 4.5 0 011.242 7.244l-4.5 4.5a4.5 4.5 0 01-6.364-6.364l1.757-1.757m13.35-.622l1.757-1.757a4.5 4.5 0 00-6.364-6.364l-4.5 4.5a4.5 4.5 0 001.242 7.244',
|
|
92
|
+
position: 54,
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
href: `${p}/admin/tags`,
|
|
96
|
+
label: 'Tags',
|
|
97
|
+
icon: 'M9.568 3H5.25A2.25 2.25 0 003 5.25v4.318c0 .597.237 1.17.659 1.591l9.581 9.581c.699.699 1.78.872 2.607.33a18.095 18.095 0 005.223-5.223c.542-.827.369-1.908-.33-2.607L11.16 3.66A2.25 2.25 0 009.568 3z M6 6h.008v.008H6V6z',
|
|
98
|
+
position: 60,
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
href: `${p}/admin/custom-fields`,
|
|
102
|
+
label: 'Custom Fields',
|
|
103
|
+
icon: 'M3.75 12h16.5m-16.5 3.75h16.5M3.75 19.5h16.5M5.625 4.5h12.75a1.875 1.875 0 010 3.75H5.625a1.875 1.875 0 010-3.75z',
|
|
104
|
+
position: 62,
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
href: `${p}/admin/statuses`,
|
|
108
|
+
label: 'Statuses',
|
|
109
|
+
icon: 'M9 12.75L11.25 15 15 9.75M21 12a9 9 0 11-18 0 9 9 0 0118 0z',
|
|
110
|
+
position: 64,
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
href: `${p}/admin/canned-responses`,
|
|
114
|
+
label: 'Canned Responses',
|
|
115
|
+
icon: 'M7.5 8.25h9m-9 3H12m-9.75 1.51c0 1.6 1.123 2.994 2.707 3.227 1.129.166 2.27.293 3.423.379.35.026.67.21.865.501L12 21l2.755-4.133a1.14 1.14 0 01.865-.501 48.172 48.172 0 003.423-.379c1.584-.233 2.707-1.626 2.707-3.228V6.741c0-1.602-1.123-2.995-2.707-3.228A48.394 48.394 0 0012 3c-2.392 0-4.744.175-7.043.513C3.373 3.746 2.25 5.14 2.25 6.741v6.018z',
|
|
116
|
+
position: 70,
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
href: `${p}/admin/macros`,
|
|
120
|
+
label: 'Macros',
|
|
121
|
+
icon: 'M3.75 13.5l10.5-11.25L12 10.5h8.25L9.75 21.75 12 13.5H3.75z',
|
|
122
|
+
position: 80,
|
|
123
|
+
},
|
|
124
|
+
...(newslettersEnabled.value && isAdmin.value && hasPermission('newsletters.manage')
|
|
125
|
+
? [
|
|
126
|
+
{
|
|
127
|
+
href: `${p}/admin/newsletters`,
|
|
128
|
+
label: t('newsletters.nav.newsletters'),
|
|
129
|
+
icon: 'M21.75 6.75v10.5a2.25 2.25 0 01-2.25 2.25h-15a2.25 2.25 0 01-2.25-2.25V6.75m19.5 0A2.25 2.25 0 0019.5 4.5h-15a2.25 2.25 0 00-2.25 2.25m19.5 0v.243a2.25 2.25 0 01-1.07 1.916l-7.5 4.615a2.25 2.25 0 01-2.36 0L3.32 8.91a2.25 2.25 0 01-1.07-1.916V6.75',
|
|
130
|
+
position: 81,
|
|
131
|
+
},
|
|
132
|
+
]
|
|
133
|
+
: []),
|
|
134
|
+
{
|
|
135
|
+
href: `${p}/admin/skills`,
|
|
136
|
+
label: 'Skills',
|
|
137
|
+
icon: 'M4.26 10.147a60.436 60.436 0 00-.491 6.347A48.627 48.627 0 0112 20.904a48.627 48.627 0 018.232-4.41 60.46 60.46 0 00-.491-6.347m-15.482 0a50.57 50.57 0 00-2.658-.813A59.905 59.905 0 0112 3.493a59.902 59.902 0 0110.399 5.84c-.896.248-1.783.52-2.658.814m-15.482 0A50.697 50.697 0 0112 13.489a50.702 50.702 0 017.74-3.342',
|
|
138
|
+
position: 82,
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
href: `${p}/admin/roles`,
|
|
142
|
+
label: 'Roles',
|
|
143
|
+
icon: 'M18 18.72a9.094 9.094 0 003.741-.479 3 3 0 00-4.682-2.72m.94 3.198l.001.031c0 .225-.012.447-.037.666A11.944 11.944 0 0112 21c-2.17 0-4.207-.576-5.963-1.584A6.062 6.062 0 016 18.719m12 0a5.971 5.971 0 00-.941-3.197m0 0A5.995 5.995 0 0012 12.75a5.995 5.995 0 00-5.058 2.772m0 0a3 3 0 00-4.681 2.72 8.986 8.986 0 003.74.477m.94-3.197a5.971 5.971 0 00-.94 3.197M15 6.75a3 3 0 11-6 0 3 3 0 016 0zm6 3a2.25 2.25 0 11-4.5 0 2.25 2.25 0 014.5 0zm-13.5 0a2.25 2.25 0 11-4.5 0 2.25 2.25 0 014.5 0z',
|
|
144
|
+
position: 84,
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
href: `${p}/admin/users`,
|
|
148
|
+
label: 'Users',
|
|
149
|
+
icon: 'M15 19.128a9.38 9.38 0 002.625.372 9.337 9.337 0 004.121-.952 4.125 4.125 0 00-7.533-2.493M15 19.128v-.003c0-1.113-.285-2.16-.786-3.07M15 19.128v.106A12.318 12.318 0 018.624 21c-2.331 0-4.512-.645-6.374-1.766l-.001-.109a6.375 6.375 0 0111.964-3.07M12 6.375a3.375 3.375 0 11-6.75 0 3.375 3.375 0 016.75 0zm8.25 2.25a2.625 2.625 0 11-5.25 0 2.625 2.625 0 015.25 0z',
|
|
150
|
+
position: 83,
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
href: `${p}/admin/capacity`,
|
|
154
|
+
label: 'Capacity',
|
|
155
|
+
icon: 'M3 7.5L7.5 3m0 0L12 7.5M7.5 3v13.5m13.5 0L16.5 21m0 0L12 16.5m4.5 4.5V7.5',
|
|
156
|
+
position: 85,
|
|
157
|
+
},
|
|
158
|
+
{
|
|
159
|
+
href: `${p}/admin/business-hours`,
|
|
160
|
+
label: 'Business Hours',
|
|
161
|
+
icon: 'M6.75 3v2.25M17.25 3v2.25M3 18.75V7.5a2.25 2.25 0 012.25-2.25h13.5A2.25 2.25 0 0121 7.5v11.25m-18 0A2.25 2.25 0 005.25 21h13.5A2.25 2.25 0 0021 18.75m-18 0v-7.5A2.25 2.25 0 015.25 9h13.5A2.25 2.25 0 0121 11.25v7.5',
|
|
162
|
+
position: 86,
|
|
163
|
+
},
|
|
164
|
+
{
|
|
165
|
+
href: `${p}/admin/audit-log`,
|
|
166
|
+
label: 'Audit Log',
|
|
167
|
+
icon: 'M19.5 14.25v-2.625a3.375 3.375 0 00-3.375-3.375h-1.5A1.125 1.125 0 0113.5 7.125v-1.5a3.375 3.375 0 00-3.375-3.375H8.25m0 12.75h7.5m-7.5 3H12M10.5 2.25H5.625c-.621 0-1.125.504-1.125 1.125v17.25c0 .621.504 1.125 1.125 1.125h12.75c.621 0 1.125-.504 1.125-1.125V11.25a9 9 0 00-9-9z',
|
|
168
|
+
position: 88,
|
|
169
|
+
},
|
|
170
|
+
{
|
|
171
|
+
href: `${p}/admin/api-tokens`,
|
|
172
|
+
label: 'API Tokens',
|
|
173
|
+
icon: 'M15.75 5.25a3 3 0 013 3m3 0a6 6 0 01-7.029 5.912c-.563-.097-1.159.026-1.563.43L10.5 17.25H8.25v2.25H6v2.25H2.25v-2.818c0-.597.237-1.17.659-1.591l6.499-6.499c.404-.404.527-1 .43-1.563A6 6 0 1121.75 8.25z',
|
|
174
|
+
position: 90,
|
|
175
|
+
},
|
|
176
|
+
{
|
|
177
|
+
href: `${p}/admin/custom-objects`,
|
|
178
|
+
label: 'Custom Objects',
|
|
179
|
+
icon: 'M20.25 6.375c0 2.278-3.694 4.125-8.25 4.125S3.75 8.653 3.75 6.375m16.5 0c0-2.278-3.694-4.125-8.25-4.125S3.75 4.097 3.75 6.375m16.5 0v11.25c0 2.278-3.694 4.125-8.25 4.125s-8.25-1.847-8.25-4.125V6.375m16.5 0v3.75m-16.5-3.75v3.75m16.5 0v3.75C20.25 16.153 16.556 18 12 18s-8.25-1.847-8.25-4.125v-3.75m16.5 0c0 2.278-3.694 4.125-8.25 4.125s-8.25-1.847-8.25-4.125',
|
|
180
|
+
position: 92,
|
|
181
|
+
},
|
|
182
|
+
{
|
|
183
|
+
href: `${p}/admin/plugins`,
|
|
184
|
+
label: 'Plugins',
|
|
185
|
+
icon: 'M14.25 6.087c0-.355.186-.676.401-.959.221-.29.349-.634.349-1.003 0-1.036-1.007-1.875-2.25-1.875s-2.25.84-2.25 1.875c0 .369.128.713.349 1.003.215.283.401.604.401.959v0a.64.64 0 01-.657.643 48.39 48.39 0 01-4.163-.3c.186 1.613.293 3.25.315 4.907a.656.656 0 01-.658.663v0c-.355 0-.676-.186-.959-.401a1.647 1.647 0 00-1.003-.349c-1.036 0-1.875 1.007-1.875 2.25s.84 2.25 1.875 2.25c.369 0 .713-.128 1.003-.349.283-.215.604-.401.959-.401v0c.31 0 .555.26.532.57a48.039 48.039 0 01-.642 5.056c1.518.19 3.058.309 4.616.354a.64.64 0 00.657-.643v0c0-.355-.186-.676-.401-.959a1.647 1.647 0 01-.349-1.003c0-1.035 1.008-1.875 2.25-1.875 1.243 0 2.25.84 2.25 1.875 0 .369-.128.713-.349 1.003-.215.283-.4.604-.4.959v0c0 .333.277.599.61.58a48.1 48.1 0 005.427-.63 48.05 48.05 0 00.582-4.717.532.532 0 00-.533-.57v0c-.355 0-.676.186-.959.401-.29.221-.634.349-1.003.349-1.035 0-1.875-1.007-1.875-2.25s.84-2.25 1.875-2.25c.37 0 .713.128 1.003.349.283.215.604.401.96.401v0a.656.656 0 00.658-.663 48.422 48.422 0 00-.37-5.36c-1.886.342-3.81.574-5.766.689a.578.578 0 01-.61-.58v0z',
|
|
186
|
+
position: 95,
|
|
187
|
+
},
|
|
188
|
+
{
|
|
189
|
+
href: `${p}/admin/import`,
|
|
190
|
+
label: 'Import',
|
|
191
|
+
icon: 'M3 16.5v2.25A2.25 2.25 0 005.25 21h13.5A2.25 2.25 0 0021 18.75V16.5m-13.5-9L12 3m0 0l4.5 4.5M12 3v13.5',
|
|
192
|
+
position: 97,
|
|
193
|
+
},
|
|
194
|
+
{
|
|
195
|
+
href: `${p}/admin/settings`,
|
|
196
|
+
label: 'Settings',
|
|
197
|
+
icon: 'M10.343 3.94c.09-.542.56-.94 1.11-.94h1.093c.55 0 1.02.398 1.11.94l.149.894c.07.424.384.764.78.93.398.164.855.142 1.205-.108l.737-.527a1.125 1.125 0 011.45.12l.773.774c.39.389.44 1.002.12 1.45l-.527.737c-.25.35-.272.806-.107 1.204.165.397.505.71.93.78l.893.15c.543.09.94.56.94 1.109v1.094c0 .55-.397 1.02-.94 1.11l-.893.149c-.425.07-.765.383-.93.78-.165.398-.143.854.107 1.204l.527.738c.32.447.269 1.06-.12 1.45l-.774.773a1.125 1.125 0 01-1.449.12l-.738-.527c-.35-.25-.806-.272-1.204-.107-.397.165-.71.505-.781.93l-.149.894c-.09.542-.56.94-1.11.94h-1.094c-.55 0-1.019-.398-1.11-.94l-.148-.894c-.071-.424-.384-.764-.781-.93-.398-.164-.854-.142-1.204.108l-.738.527c-.447.32-1.06.269-1.45-.12l-.773-.774a1.125 1.125 0 01-.12-1.45l.527-.737c.25-.35.273-.806.108-1.204-.165-.397-.505-.71-.93-.78l-.894-.15c-.542-.09-.94-.56-.94-1.109v-1.094c0-.55.398-1.02.94-1.11l.894-.149c.424-.07.765-.383.93-.78.165-.398.143-.854-.107-1.204l-.527-.738a1.125 1.125 0 01.12-1.45l.773-.773a1.125 1.125 0 011.45-.12l.737.527c.35.25.807.272 1.204.107.397-.165.71-.505.78-.929l.15-.894zM15 12a3 3 0 11-6 0 3 3 0 016 0z',
|
|
198
|
+
position: 100,
|
|
199
|
+
},
|
|
200
|
+
];
|
|
201
|
+
|
|
202
|
+
// Merge core admin links with plugin-provided menu items
|
|
203
|
+
const pluginLinks = pluginMenuItems.value.map((item) => ({
|
|
204
|
+
href: item.route,
|
|
205
|
+
label: item.label,
|
|
206
|
+
icon: item.icon,
|
|
207
|
+
position: item.position || 100,
|
|
208
|
+
badge: item.badge || null,
|
|
209
|
+
submenu: item.submenu || [],
|
|
210
|
+
}));
|
|
211
|
+
|
|
212
|
+
return [...coreLinks, ...pluginLinks].sort((a, b) => (a.position || 100) - (b.position || 100));
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
const agentLinks = computed(() => [
|
|
216
|
+
{
|
|
217
|
+
href: `${prefix.value}/agent`,
|
|
218
|
+
label: 'Dashboard',
|
|
219
|
+
icon: 'M2.25 12l8.954-8.955c.44-.439 1.152-.439 1.591 0L21.75 12M4.5 9.75v10.125c0 .621.504 1.125 1.125 1.125H9.75v-4.875c0-.621.504-1.125 1.125-1.125h2.25c.621 0 1.125.504 1.125 1.125V21h4.125c.621 0 1.125-.504 1.125-1.125V9.75M8.25 21h8.25',
|
|
220
|
+
},
|
|
221
|
+
{
|
|
222
|
+
href: `${prefix.value}/agent/tickets`,
|
|
223
|
+
label: 'Tickets',
|
|
224
|
+
icon: 'M16.5 6v.75m0 3v.75m0 3v.75m0 3V18m-9-5.25h5.25M7.5 15h3M3.375 5.25c-.621 0-1.125.504-1.125 1.125v3.026a2.999 2.999 0 010 5.198v3.026c0 .621.504 1.125 1.125 1.125h17.25c.621 0 1.125-.504 1.125-1.125v-3.026a2.999 2.999 0 010-5.198V6.375c0-.621-.504-1.125-1.125-1.125H3.375z',
|
|
225
|
+
},
|
|
226
|
+
]);
|
|
227
|
+
|
|
228
|
+
const userName = computed(() => page.props.auth?.user?.name || 'User');
|
|
229
|
+
const userInitial = computed(() => userName.value.charAt(0).toUpperCase());
|
|
230
|
+
|
|
231
|
+
function isActive(href) {
|
|
232
|
+
if (!currentUrl.value) return false;
|
|
233
|
+
return currentUrl.value === href || currentUrl.value.startsWith(href + '/');
|
|
234
|
+
}
|
|
235
|
+
</script>
|
|
236
|
+
|
|
237
|
+
<template>
|
|
238
|
+
<!-- MODE 1: Admin — dark sidebar layout -->
|
|
239
|
+
<div
|
|
240
|
+
v-if="isAdminSection"
|
|
241
|
+
class="flex min-h-screen bg-[var(--esc-panel-bg)]"
|
|
242
|
+
:style="{ colorScheme: panelConfig.mode === 'light' ? 'light' : 'dark' }"
|
|
243
|
+
>
|
|
244
|
+
<!-- Sidebar -->
|
|
245
|
+
<aside
|
|
246
|
+
class="fixed inset-y-0 left-0 z-30 flex w-64 flex-col border-r border-[var(--esc-panel-border)] bg-[var(--esc-panel-sidebar-bg)]"
|
|
247
|
+
>
|
|
248
|
+
<!-- Logo -->
|
|
249
|
+
<div class="flex h-16 items-center gap-3 px-5">
|
|
250
|
+
<div class="flex h-9 w-9 items-center justify-center rounded-lg bg-[var(--esc-panel-border-input)]">
|
|
251
|
+
<img
|
|
252
|
+
v-if="typeof panelConfig.logo === 'string'"
|
|
253
|
+
:src="panelConfig.logo"
|
|
254
|
+
class="h-5 w-5"
|
|
255
|
+
alt="Escalated logo"
|
|
256
|
+
/>
|
|
257
|
+
<component :is="panelConfig.logo" v-else-if="panelConfig.logo" class="h-5 w-5" />
|
|
258
|
+
<svg
|
|
259
|
+
v-else
|
|
260
|
+
class="h-5 w-5"
|
|
261
|
+
viewBox="0 0 24 24"
|
|
262
|
+
fill="none"
|
|
263
|
+
stroke-width="2.5"
|
|
264
|
+
stroke-linecap="round"
|
|
265
|
+
stroke-linejoin="round"
|
|
266
|
+
>
|
|
267
|
+
<defs>
|
|
268
|
+
<linearGradient id="esc-rainbow-admin" x1="0%" y1="0%" x2="100%" y2="100%">
|
|
269
|
+
<stop offset="0%" stop-color="#f97316" />
|
|
270
|
+
<stop offset="30%" stop-color="#eab308" />
|
|
271
|
+
<stop offset="50%" stop-color="#22c55e" />
|
|
272
|
+
<stop offset="70%" stop-color="#3b82f6" />
|
|
273
|
+
<stop offset="100%" stop-color="#8b5cf6" />
|
|
274
|
+
</linearGradient>
|
|
275
|
+
</defs>
|
|
276
|
+
<g transform="translate(12,12) scale(1.35) translate(-12,-12)">
|
|
277
|
+
<polyline points="17 11 12 6 7 11" stroke="url(#esc-rainbow-admin)" />
|
|
278
|
+
<polyline points="17 18 12 13 7 18" stroke="url(#esc-rainbow-admin)" />
|
|
279
|
+
</g>
|
|
280
|
+
</svg>
|
|
281
|
+
</div>
|
|
282
|
+
<div>
|
|
283
|
+
<span class="text-sm font-bold text-[var(--esc-panel-text)] tracking-wide">{{
|
|
284
|
+
panelConfig.appName
|
|
285
|
+
}}</span>
|
|
286
|
+
<span
|
|
287
|
+
class="ml-1.5 rounded bg-[var(--esc-panel-active)] px-1.5 py-0.5 text-[10px] font-semibold text-[var(--esc-panel-text-muted)]"
|
|
288
|
+
>ADMIN</span
|
|
289
|
+
>
|
|
290
|
+
</div>
|
|
291
|
+
</div>
|
|
292
|
+
|
|
293
|
+
<!-- Nav -->
|
|
294
|
+
<nav role="navigation" aria-label="Admin navigation" class="mt-1 flex-1 space-y-0.5 overflow-y-auto px-3">
|
|
295
|
+
<Link
|
|
296
|
+
v-for="link in adminLinks"
|
|
297
|
+
:key="link.href"
|
|
298
|
+
:href="link.href"
|
|
299
|
+
:aria-current="isActive(link.href) ? 'page' : undefined"
|
|
300
|
+
:class="[
|
|
301
|
+
'group flex items-center gap-3 rounded-lg px-3 py-2 text-[13px] font-medium transition-all',
|
|
302
|
+
isActive(link.href)
|
|
303
|
+
? 'bg-[var(--esc-panel-active)] text-[var(--esc-panel-text)]'
|
|
304
|
+
: 'text-[var(--esc-panel-text-muted)] hover:bg-[var(--esc-panel-hover)] hover:text-[var(--esc-panel-text-secondary)]',
|
|
305
|
+
]"
|
|
306
|
+
>
|
|
307
|
+
<svg
|
|
308
|
+
:class="[
|
|
309
|
+
'h-[18px] w-[18px] shrink-0',
|
|
310
|
+
isActive(link.href)
|
|
311
|
+
? 'text-[var(--esc-panel-text)]'
|
|
312
|
+
: 'text-[var(--esc-panel-text-muted)] group-hover:text-[var(--esc-panel-text-tertiary)]',
|
|
313
|
+
]"
|
|
314
|
+
fill="none"
|
|
315
|
+
stroke="currentColor"
|
|
316
|
+
stroke-width="1.5"
|
|
317
|
+
viewBox="0 0 24 24"
|
|
318
|
+
>
|
|
319
|
+
<path stroke-linecap="round" stroke-linejoin="round" :d="link.icon" />
|
|
320
|
+
</svg>
|
|
321
|
+
{{ link.label }}
|
|
322
|
+
<span
|
|
323
|
+
v-if="link.badge"
|
|
324
|
+
class="ml-auto inline-flex h-5 min-w-[20px] items-center justify-center rounded-full bg-[var(--esc-panel-accent)]/20 px-1.5 text-[10px] font-semibold text-[var(--esc-panel-accent)]"
|
|
325
|
+
>
|
|
326
|
+
{{ link.badge }}
|
|
327
|
+
</span>
|
|
328
|
+
</Link>
|
|
329
|
+
</nav>
|
|
330
|
+
|
|
331
|
+
<!-- Bottom section -->
|
|
332
|
+
<div class="border-t border-[var(--esc-panel-border)] p-3">
|
|
333
|
+
<Link
|
|
334
|
+
v-if="isAgent"
|
|
335
|
+
:href="`${prefix}/agent`"
|
|
336
|
+
class="flex items-center gap-2.5 rounded-lg px-3 py-2 text-[13px] text-[var(--esc-panel-text-muted)] transition-colors hover:bg-[var(--esc-panel-hover)] hover:text-[var(--esc-panel-text-secondary)]"
|
|
337
|
+
>
|
|
338
|
+
<svg class="h-4 w-4" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24">
|
|
339
|
+
<path
|
|
340
|
+
stroke-linecap="round"
|
|
341
|
+
stroke-linejoin="round"
|
|
342
|
+
d="M9 15L3 9m0 0l6-6M3 9h12a6 6 0 010 12h-3"
|
|
343
|
+
/>
|
|
344
|
+
</svg>
|
|
345
|
+
Agent Panel
|
|
346
|
+
</Link>
|
|
347
|
+
<Link
|
|
348
|
+
:href="prefix"
|
|
349
|
+
class="flex items-center gap-2.5 rounded-lg px-3 py-2 text-[13px] text-[var(--esc-panel-text-muted)] transition-colors hover:bg-[var(--esc-panel-hover)] hover:text-[var(--esc-panel-text-secondary)]"
|
|
350
|
+
>
|
|
351
|
+
<svg class="h-4 w-4" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24">
|
|
352
|
+
<path
|
|
353
|
+
stroke-linecap="round"
|
|
354
|
+
stroke-linejoin="round"
|
|
355
|
+
d="M15.75 9V5.25A2.25 2.25 0 0013.5 3h-6a2.25 2.25 0 00-2.25 2.25v13.5A2.25 2.25 0 007.5 21h6a2.25 2.25 0 002.25-2.25V15m3 0l3-3m0 0l-3-3m3 3H9"
|
|
356
|
+
/>
|
|
357
|
+
</svg>
|
|
358
|
+
Back to App
|
|
359
|
+
</Link>
|
|
360
|
+
|
|
361
|
+
<!-- User -->
|
|
362
|
+
<div class="mt-2 flex items-center gap-3 rounded-lg bg-[var(--esc-panel-hover)] px-3 py-2.5">
|
|
363
|
+
<div
|
|
364
|
+
class="flex h-7 w-7 items-center justify-center rounded-md bg-[var(--esc-panel-active)] text-xs font-semibold text-[var(--esc-panel-text-tertiary)]"
|
|
365
|
+
>
|
|
366
|
+
{{ userInitial }}
|
|
367
|
+
</div>
|
|
368
|
+
<span class="text-sm text-[var(--esc-panel-text-tertiary)]">{{ userName }}</span>
|
|
369
|
+
</div>
|
|
370
|
+
</div>
|
|
371
|
+
|
|
372
|
+
<!-- Powered by -->
|
|
373
|
+
<div v-if="showPoweredBy" class="px-4 pb-3">
|
|
374
|
+
<a
|
|
375
|
+
href="https://escalated.dev"
|
|
376
|
+
target="_blank"
|
|
377
|
+
rel="noopener noreferrer"
|
|
378
|
+
class="flex items-center justify-center gap-1.5 rounded-lg px-2 py-1.5 text-[11px] text-[var(--esc-panel-text-muted)] opacity-60 transition-opacity hover:opacity-100"
|
|
379
|
+
>
|
|
380
|
+
<img
|
|
381
|
+
:src="
|
|
382
|
+
isDark
|
|
383
|
+
? 'https://escalated.dev/brand/logo-icon-dark.svg'
|
|
384
|
+
: 'https://escalated.dev/brand/logo-icon-white.svg'
|
|
385
|
+
"
|
|
386
|
+
alt="Escalated logo"
|
|
387
|
+
class="h-3.5 w-3.5"
|
|
388
|
+
/>
|
|
389
|
+
Powered by Escalated
|
|
390
|
+
</a>
|
|
391
|
+
</div>
|
|
392
|
+
</aside>
|
|
393
|
+
|
|
394
|
+
<!-- Main content -->
|
|
395
|
+
<div class="flex flex-1 flex-col pl-64">
|
|
396
|
+
<!-- Top bar -->
|
|
397
|
+
<header
|
|
398
|
+
role="banner"
|
|
399
|
+
class="sticky top-0 z-20 flex h-14 items-center border-b border-[var(--esc-panel-border)] bg-[var(--esc-panel-topbar-bg)] px-6 backdrop-blur-xl"
|
|
400
|
+
>
|
|
401
|
+
<h1 class="text-sm font-semibold text-[var(--esc-panel-text)]">{{ title }}</h1>
|
|
402
|
+
</header>
|
|
403
|
+
|
|
404
|
+
<!-- Page content -->
|
|
405
|
+
<main role="main" class="flex-1 p-6">
|
|
406
|
+
<slot />
|
|
407
|
+
</main>
|
|
408
|
+
</div>
|
|
409
|
+
</div>
|
|
410
|
+
|
|
411
|
+
<!-- MODE 2: Agent — dark top-nav layout -->
|
|
412
|
+
<div
|
|
413
|
+
v-else-if="isAgentSection"
|
|
414
|
+
class="min-h-screen bg-[var(--esc-panel-bg)]"
|
|
415
|
+
:style="{ colorScheme: panelConfig.mode === 'light' ? 'light' : 'dark' }"
|
|
416
|
+
>
|
|
417
|
+
<!-- Top nav -->
|
|
418
|
+
<nav
|
|
419
|
+
class="sticky top-0 z-30 border-b border-[var(--esc-panel-border)] bg-[var(--esc-panel-sidebar-bg)] backdrop-blur-xl"
|
|
420
|
+
>
|
|
421
|
+
<div class="mx-auto flex h-14 max-w-7xl items-center justify-between px-4 sm:px-6 lg:px-8">
|
|
422
|
+
<!-- Left: branding -->
|
|
423
|
+
<div class="flex items-center gap-3">
|
|
424
|
+
<div class="flex h-8 w-8 items-center justify-center rounded-lg bg-[var(--esc-panel-border-input)]">
|
|
425
|
+
<img
|
|
426
|
+
v-if="typeof panelConfig.logo === 'string'"
|
|
427
|
+
:src="panelConfig.logo"
|
|
428
|
+
class="h-4 w-4"
|
|
429
|
+
alt="Escalated logo"
|
|
430
|
+
/>
|
|
431
|
+
<component :is="panelConfig.logo" v-else-if="panelConfig.logo" class="h-4 w-4" />
|
|
432
|
+
<svg
|
|
433
|
+
v-else
|
|
434
|
+
class="h-4 w-4"
|
|
435
|
+
viewBox="0 0 24 24"
|
|
436
|
+
fill="none"
|
|
437
|
+
stroke-width="2.5"
|
|
438
|
+
stroke-linecap="round"
|
|
439
|
+
stroke-linejoin="round"
|
|
440
|
+
>
|
|
441
|
+
<defs>
|
|
442
|
+
<linearGradient id="esc-rainbow-agent" x1="0%" y1="0%" x2="100%" y2="100%">
|
|
443
|
+
<stop offset="0%" stop-color="#f97316" />
|
|
444
|
+
<stop offset="30%" stop-color="#eab308" />
|
|
445
|
+
<stop offset="50%" stop-color="#22c55e" />
|
|
446
|
+
<stop offset="70%" stop-color="#3b82f6" />
|
|
447
|
+
<stop offset="100%" stop-color="#8b5cf6" />
|
|
448
|
+
</linearGradient>
|
|
449
|
+
</defs>
|
|
450
|
+
<g transform="translate(12,12) scale(1.35) translate(-12,-12)">
|
|
451
|
+
<polyline points="17 11 12 6 7 11" stroke="url(#esc-rainbow-agent)" />
|
|
452
|
+
<polyline points="17 18 12 13 7 18" stroke="url(#esc-rainbow-agent)" />
|
|
453
|
+
</g>
|
|
454
|
+
</svg>
|
|
455
|
+
</div>
|
|
456
|
+
<span class="text-sm font-bold text-[var(--esc-panel-text)] tracking-wide">{{
|
|
457
|
+
panelConfig.appName
|
|
458
|
+
}}</span>
|
|
459
|
+
</div>
|
|
460
|
+
|
|
461
|
+
<!-- Center: nav links -->
|
|
462
|
+
<div class="flex items-center gap-1">
|
|
463
|
+
<Link
|
|
464
|
+
v-for="link in agentLinks"
|
|
465
|
+
:key="link.href"
|
|
466
|
+
:href="link.href"
|
|
467
|
+
:aria-current="isActive(link.href) ? 'page' : undefined"
|
|
468
|
+
:class="[
|
|
469
|
+
'flex items-center gap-2 rounded-lg px-3.5 py-1.5 text-[13px] font-medium transition-all',
|
|
470
|
+
isActive(link.href)
|
|
471
|
+
? 'bg-[var(--esc-panel-active)] text-[var(--esc-panel-text)]'
|
|
472
|
+
: 'text-[var(--esc-panel-text-muted)] hover:bg-[var(--esc-panel-hover)] hover:text-[var(--esc-panel-text-secondary)]',
|
|
473
|
+
]"
|
|
474
|
+
>
|
|
475
|
+
<svg class="h-4 w-4" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24">
|
|
476
|
+
<path stroke-linecap="round" stroke-linejoin="round" :d="link.icon" />
|
|
477
|
+
</svg>
|
|
478
|
+
{{ link.label }}
|
|
479
|
+
</Link>
|
|
480
|
+
</div>
|
|
481
|
+
|
|
482
|
+
<!-- Right: user + links -->
|
|
483
|
+
<div class="flex items-center gap-3">
|
|
484
|
+
<Link
|
|
485
|
+
v-if="isAdmin"
|
|
486
|
+
:href="`${prefix}/admin/reports`"
|
|
487
|
+
class="text-[13px] text-[var(--esc-panel-text-muted)] transition-colors hover:text-[var(--esc-panel-text)]"
|
|
488
|
+
>
|
|
489
|
+
Admin
|
|
490
|
+
</Link>
|
|
491
|
+
<Link
|
|
492
|
+
:href="prefix"
|
|
493
|
+
class="text-[13px] text-[var(--esc-panel-text-muted)] transition-colors hover:text-[var(--esc-panel-text)]"
|
|
494
|
+
>
|
|
495
|
+
Back to App
|
|
496
|
+
</Link>
|
|
497
|
+
<div class="ml-1 h-5 w-px bg-[var(--esc-panel-active)]"></div>
|
|
498
|
+
<div class="flex items-center gap-2">
|
|
499
|
+
<div
|
|
500
|
+
class="flex h-7 w-7 items-center justify-center rounded-md bg-[var(--esc-panel-active)] text-[10px] font-semibold text-[var(--esc-panel-text-tertiary)]"
|
|
501
|
+
>
|
|
502
|
+
{{ userInitial }}
|
|
503
|
+
</div>
|
|
504
|
+
<span class="text-[13px] text-[var(--esc-panel-text-tertiary)]">{{ userName }}</span>
|
|
505
|
+
</div>
|
|
506
|
+
</div>
|
|
507
|
+
</div>
|
|
508
|
+
</nav>
|
|
509
|
+
|
|
510
|
+
<!-- Page content -->
|
|
511
|
+
<main class="mx-auto max-w-7xl px-4 py-6 sm:px-6 lg:px-8">
|
|
512
|
+
<slot />
|
|
513
|
+
</main>
|
|
514
|
+
|
|
515
|
+
<!-- Powered by -->
|
|
516
|
+
<footer v-if="showPoweredBy" class="border-t border-[var(--esc-panel-border)] py-3 text-center">
|
|
517
|
+
<a
|
|
518
|
+
href="https://escalated.dev"
|
|
519
|
+
target="_blank"
|
|
520
|
+
rel="noopener noreferrer"
|
|
521
|
+
class="inline-flex items-center gap-1.5 text-[11px] text-[var(--esc-panel-text-muted)] opacity-60 transition-opacity hover:opacity-100"
|
|
522
|
+
>
|
|
523
|
+
<img
|
|
524
|
+
:src="
|
|
525
|
+
isDark
|
|
526
|
+
? 'https://escalated.dev/brand/logo-icon-dark.svg'
|
|
527
|
+
: 'https://escalated.dev/brand/logo-icon-white.svg'
|
|
528
|
+
"
|
|
529
|
+
alt=""
|
|
530
|
+
class="h-3.5 w-3.5"
|
|
531
|
+
/>
|
|
532
|
+
Powered by Escalated
|
|
533
|
+
</a>
|
|
534
|
+
</footer>
|
|
535
|
+
|
|
536
|
+
<!-- Active Chats Panel (agent layout only, when chat enabled) -->
|
|
537
|
+
<ActiveChatsPanel v-if="chatEnabled && agentId" :chats="activeChats" :agent-id="agentId" />
|
|
538
|
+
</div>
|
|
539
|
+
|
|
540
|
+
<!-- MODE 3: Customer pages — use host app layout if provided -->
|
|
541
|
+
<component :is="hostLayout" v-else-if="hostLayout">
|
|
542
|
+
<template #header>
|
|
543
|
+
<div class="flex items-center justify-between">
|
|
544
|
+
<h2 class="text-xl font-semibold leading-tight text-gray-800">{{ title }}</h2>
|
|
545
|
+
<nav class="flex items-center gap-4 text-sm">
|
|
546
|
+
<Link :href="prefix" class="text-gray-600 hover:text-gray-900">My Tickets</Link>
|
|
547
|
+
<Link
|
|
548
|
+
v-if="kbEnabled && (kbPublic || page.props.auth?.user)"
|
|
549
|
+
:href="`${prefix}/kb`"
|
|
550
|
+
class="text-gray-600 hover:text-gray-900"
|
|
551
|
+
>
|
|
552
|
+
Knowledge Base
|
|
553
|
+
</Link>
|
|
554
|
+
<Link v-if="isAgent" :href="`${prefix}/agent`" class="text-gray-600 hover:text-gray-900">
|
|
555
|
+
Agent Panel
|
|
556
|
+
</Link>
|
|
557
|
+
<Link v-if="isAdmin" :href="`${prefix}/admin/reports`" class="text-gray-600 hover:text-gray-900">
|
|
558
|
+
Admin
|
|
559
|
+
</Link>
|
|
560
|
+
</nav>
|
|
561
|
+
</div>
|
|
562
|
+
</template>
|
|
563
|
+
|
|
564
|
+
<div class="mx-auto max-w-7xl px-4 py-6 sm:px-6 lg:px-8">
|
|
565
|
+
<slot />
|
|
566
|
+
</div>
|
|
567
|
+
</component>
|
|
568
|
+
|
|
569
|
+
<!-- MODE 4: Customer standalone fallback (no host layout) -->
|
|
570
|
+
<div v-else class="min-h-screen bg-gray-50">
|
|
571
|
+
<nav class="border-b border-gray-200 bg-white">
|
|
572
|
+
<div class="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
|
|
573
|
+
<div class="flex h-14 items-center justify-between">
|
|
574
|
+
<div class="flex items-center gap-6">
|
|
575
|
+
<span class="text-lg font-bold text-gray-900">{{ title }}</span>
|
|
576
|
+
<div class="flex items-center gap-4 text-sm">
|
|
577
|
+
<Link :href="prefix" class="text-gray-600 hover:text-gray-900">My Tickets</Link>
|
|
578
|
+
<Link
|
|
579
|
+
v-if="kbEnabled && (kbPublic || page.props.auth?.user)"
|
|
580
|
+
:href="`${prefix}/kb`"
|
|
581
|
+
class="text-gray-600 hover:text-gray-900"
|
|
582
|
+
>
|
|
583
|
+
Knowledge Base
|
|
584
|
+
</Link>
|
|
585
|
+
<Link v-if="isAgent" :href="`${prefix}/agent`" class="text-gray-600 hover:text-gray-900">
|
|
586
|
+
Agent Panel
|
|
587
|
+
</Link>
|
|
588
|
+
<Link
|
|
589
|
+
v-if="isAdmin"
|
|
590
|
+
:href="`${prefix}/admin/reports`"
|
|
591
|
+
class="text-gray-600 hover:text-gray-900"
|
|
592
|
+
>
|
|
593
|
+
Admin
|
|
594
|
+
</Link>
|
|
595
|
+
</div>
|
|
596
|
+
</div>
|
|
597
|
+
</div>
|
|
598
|
+
</div>
|
|
599
|
+
</nav>
|
|
600
|
+
<main class="flex-1">
|
|
601
|
+
<div class="mx-auto max-w-7xl px-4 py-6 sm:px-6 lg:px-8">
|
|
602
|
+
<slot />
|
|
603
|
+
</div>
|
|
604
|
+
</main>
|
|
605
|
+
|
|
606
|
+
<!-- Powered by -->
|
|
607
|
+
<footer v-if="showPoweredBy" class="border-t border-gray-200 py-3 text-center">
|
|
608
|
+
<a
|
|
609
|
+
href="https://escalated.dev"
|
|
610
|
+
target="_blank"
|
|
611
|
+
rel="noopener noreferrer"
|
|
612
|
+
class="inline-flex items-center gap-1.5 text-[11px] text-gray-400 transition-colors hover:text-gray-600"
|
|
613
|
+
>
|
|
614
|
+
<img src="https://escalated.dev/brand/logo-icon-white.svg" alt="Escalated logo" class="h-3.5 w-3.5" />
|
|
615
|
+
Powered by Escalated
|
|
616
|
+
</a>
|
|
617
|
+
</footer>
|
|
618
|
+
</div>
|
|
619
|
+
</template>
|