@consilioweb/payload-support 0.5.2 → 0.6.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.
Files changed (85) hide show
  1. package/dist/components/TicketConversation/components/AISummaryPanel.js +76 -0
  2. package/dist/components/TicketConversation/components/ActionPanels.js +118 -0
  3. package/dist/components/TicketConversation/components/ActivityLog.js +23 -0
  4. package/dist/components/TicketConversation/components/ClientBar.js +42 -0
  5. package/dist/components/TicketConversation/components/ClientHistory.js +137 -0
  6. package/dist/components/TicketConversation/components/CodeBlock.js +152 -0
  7. package/dist/components/TicketConversation/components/CodeBlockInserter.js +155 -0
  8. package/dist/components/TicketConversation/components/QuickActions.js +65 -0
  9. package/dist/components/TicketConversation/components/TicketHeader.js +92 -0
  10. package/dist/components/TicketConversation/components/TimeTrackingPanel.js +133 -0
  11. package/dist/components/TicketConversation/config.js +41 -0
  12. package/dist/components/TicketConversation/constants.js +96 -0
  13. package/dist/components/TicketConversation/context.js +11 -0
  14. package/dist/components/TicketConversation/hooks/useAI.js +176 -0
  15. package/dist/components/TicketConversation/hooks/useMessageActions.js +135 -0
  16. package/dist/components/TicketConversation/hooks/useReply.js +187 -0
  17. package/dist/components/TicketConversation/hooks/useTicketActions.js +230 -0
  18. package/dist/components/TicketConversation/hooks/useTimeTracking.js +122 -0
  19. package/dist/components/TicketConversation/hooks/useTranslation.js +70 -0
  20. package/dist/components/TicketConversation/index.js +1123 -0
  21. package/dist/components/TicketConversation/locales/en.json +878 -0
  22. package/dist/components/TicketConversation/locales/fr.json +878 -0
  23. package/dist/components/TicketConversation/types.js +2 -0
  24. package/dist/components/TicketConversation/utils.js +25 -0
  25. package/dist/index.cjs +2 -2
  26. package/dist/index.js +2 -2
  27. package/dist/styles/BillingView.module.scss +311 -0
  28. package/dist/styles/ChatView.module.scss +438 -0
  29. package/dist/styles/CommandPalette.module.scss +160 -0
  30. package/dist/styles/CrmView.module.scss +554 -0
  31. package/dist/styles/EmailTracking.module.scss +238 -0
  32. package/dist/styles/ImportConversation.module.scss +267 -0
  33. package/dist/styles/Layout.module.scss +55 -0
  34. package/dist/styles/Logs.module.scss +164 -0
  35. package/dist/styles/NewTicket.module.scss +143 -0
  36. package/dist/styles/PendingEmails.module.scss +629 -0
  37. package/dist/styles/SupportDashboard.module.scss +649 -0
  38. package/dist/styles/TicketDetail.module.scss +1050 -0
  39. package/dist/styles/TicketInbox.module.scss +296 -0
  40. package/dist/styles/TicketingSettings.module.scss +358 -0
  41. package/dist/styles/TimeDashboard.module.scss +287 -0
  42. package/dist/styles/_tokens.scss +78 -0
  43. package/dist/styles/theme.css +633 -0
  44. package/dist/views/BillingView/client.js +204 -0
  45. package/dist/views/BillingView/index.js +29 -0
  46. package/dist/views/ChatView/client.js +252 -0
  47. package/dist/views/ChatView/index.js +29 -0
  48. package/dist/views/CrmView/client.js +232 -0
  49. package/dist/views/CrmView/index.js +29 -0
  50. package/dist/views/EmailTrackingView/client.js +154 -0
  51. package/dist/views/EmailTrackingView/index.js +29 -0
  52. package/dist/views/ImportConversationView/client.js +204 -0
  53. package/dist/views/ImportConversationView/index.js +29 -0
  54. package/dist/views/LogsView/client.js +148 -0
  55. package/dist/views/LogsView/index.js +27 -0
  56. package/dist/views/NewTicketView/client.js +224 -0
  57. package/dist/views/NewTicketView/index.js +27 -0
  58. package/dist/views/PendingEmailsView/client.js +172 -0
  59. package/dist/views/PendingEmailsView/index.js +29 -0
  60. package/dist/views/SupportDashboardView/client.js +296 -0
  61. package/dist/views/SupportDashboardView/index.js +29 -0
  62. package/dist/views/TicketDetailView/client.js +844 -0
  63. package/dist/views/TicketDetailView/index.js +29 -0
  64. package/dist/views/TicketInboxView/client.js +294 -0
  65. package/dist/views/TicketInboxView/index.js +27 -0
  66. package/dist/{views.css → views/TicketingSettingsView/TicketingSettings.module.scss} +138 -66
  67. package/dist/views/TicketingSettingsView/client.js +728 -0
  68. package/dist/views/TicketingSettingsView/index.js +29 -0
  69. package/dist/views/TimeDashboardView/client.js +164 -0
  70. package/dist/views/TimeDashboardView/index.js +29 -0
  71. package/dist/views/shared/AdminViewHeader.js +67 -0
  72. package/dist/views/shared/ErrorBoundary.js +50 -0
  73. package/dist/views/shared/Skeleton.js +72 -0
  74. package/dist/views/shared/adminTokens.js +32 -0
  75. package/dist/views/shared/config.js +41 -0
  76. package/dist/views/shared/index.js +6 -0
  77. package/package.json +8 -12
  78. package/src/collections/Tickets.ts +1 -1
  79. package/src/components/TicketConversation/index.tsx +21 -2
  80. package/src/plugin.ts +3 -2
  81. package/dist/views.cjs +0 -6172
  82. package/dist/views.d.cts +0 -30
  83. package/dist/views.d.ts +0 -30
  84. package/dist/views.js +0 -6153
  85. package/src/views.ts +0 -16
@@ -0,0 +1,29 @@
1
+ import { jsx } from 'react/jsx-runtime';
2
+ import { DefaultTemplate } from '@payloadcms/next/templates';
3
+ import { redirect } from 'next/navigation';
4
+ import { AdminErrorBoundary } from '../shared/ErrorBoundary';
5
+ import { TicketDetailClient } from './client';
6
+
7
+ const TicketDetailView = ({ initPageResult }) => {
8
+ const { req, visibleEntities } = initPageResult;
9
+ if (!req.user) {
10
+ redirect("/admin/login");
11
+ }
12
+ return /* @__PURE__ */ jsx(
13
+ DefaultTemplate,
14
+ {
15
+ i18n: req.i18n,
16
+ locale: initPageResult.locale,
17
+ params: {},
18
+ payload: req.payload,
19
+ permissions: initPageResult.permissions,
20
+ searchParams: {},
21
+ user: req.user,
22
+ visibleEntities,
23
+ children: /* @__PURE__ */ jsx(AdminErrorBoundary, { viewName: "TicketDetailView", children: /* @__PURE__ */ jsx(TicketDetailClient, {}) })
24
+ }
25
+ );
26
+ };
27
+ var TicketDetailView_default = TicketDetailView;
28
+
29
+ export { TicketDetailView, TicketDetailView_default as default };
@@ -0,0 +1,294 @@
1
+ "use client";
2
+ import { jsxs, jsx } from 'react/jsx-runtime';
3
+ import { useState, useCallback, useEffect } from 'react';
4
+ import { useSearchParams } from 'next/navigation';
5
+ import Link from 'next/link';
6
+ import { useTranslation } from '../../components/TicketConversation/hooks/useTranslation';
7
+
8
+ const STATUS_DOTS = {
9
+ open: "#22c55e",
10
+ waiting_client: "#eab308",
11
+ resolved: "#94a3b8"
12
+ };
13
+ const STATUS_LABEL_KEYS = {
14
+ open: "inbox.tabs.open",
15
+ waiting_client: "inbox.tabs.waiting",
16
+ resolved: "inbox.tabs.resolved"
17
+ };
18
+ const PRIORITY_COLORS = {
19
+ urgent: "#ef4444",
20
+ high: "#f97316",
21
+ normal: "transparent",
22
+ low: "transparent"
23
+ };
24
+ const CATEGORY_LABEL_KEYS = {
25
+ bug: "ticket.category.bug",
26
+ content: "ticket.category.content",
27
+ feature: "ticket.category.feature",
28
+ question: "ticket.category.question",
29
+ hosting: "ticket.category.hosting"
30
+ };
31
+ function relativeTime(dateStr) {
32
+ const diff = Date.now() - new Date(dateStr).getTime();
33
+ const mins = Math.floor(diff / 6e4);
34
+ if (mins < 1) return "maintenant";
35
+ if (mins < 60) return `${mins}m`;
36
+ const hours = Math.floor(mins / 60);
37
+ if (hours < 24) return `${hours}h`;
38
+ const days = Math.floor(hours / 24);
39
+ if (days < 7) return `${days}j`;
40
+ return new Date(dateStr).toLocaleDateString("fr-FR", { day: "numeric", month: "short" });
41
+ }
42
+ const TicketInboxClient = () => {
43
+ const { t } = useTranslation();
44
+ const searchParams = useSearchParams();
45
+ const [tickets, setTickets] = useState([]);
46
+ const [loading, setLoading] = useState(true);
47
+ const [tab, setTab] = useState(() => {
48
+ const urlTab = searchParams.get("tab");
49
+ if (urlTab && ["all", "open", "waiting_client", "resolved"].includes(urlTab)) return urlTab;
50
+ return "all";
51
+ });
52
+ const [search, setSearch] = useState("");
53
+ const [sort, setSort] = useState("-updatedAt");
54
+ const [counts, setCounts] = useState({ all: 0, open: 0, waiting: 0, resolved: 0 });
55
+ const [selectedIdx, setSelectedIdx] = useState(-1);
56
+ const [checkedIds, setCheckedIds] = useState(/* @__PURE__ */ new Set());
57
+ const [bulkAction, setBulkAction] = useState("");
58
+ const [bulkProcessing, setBulkProcessing] = useState(false);
59
+ const toggleCheck = (id) => {
60
+ setCheckedIds((prev) => {
61
+ const next = new Set(prev);
62
+ if (next.has(id)) next.delete(id);
63
+ else next.add(id);
64
+ return next;
65
+ });
66
+ };
67
+ const handleBulkAction = async (action) => {
68
+ if (checkedIds.size === 0) return;
69
+ setBulkProcessing(true);
70
+ try {
71
+ const res = await fetch("/api/support/bulk-action", {
72
+ method: "POST",
73
+ headers: { "Content-Type": "application/json" },
74
+ credentials: "include",
75
+ body: JSON.stringify({ ticketIds: Array.from(checkedIds), action })
76
+ });
77
+ if (res.ok) {
78
+ setCheckedIds(/* @__PURE__ */ new Set());
79
+ setBulkAction("");
80
+ fetchTickets();
81
+ }
82
+ } catch {
83
+ }
84
+ setBulkProcessing(false);
85
+ };
86
+ const fetchTickets = useCallback(async () => {
87
+ const params = [`limit=30`, `sort=${sort}`, `depth=1`, `select[id]=true`, `select[ticketNumber]=true`, `select[subject]=true`, `select[status]=true`, `select[priority]=true`, `select[category]=true`, `select[client]=true`, `select[updatedAt]=true`, `select[lastClientMessageAt]=true`, `select[lastAdminReadAt]=true`];
88
+ if (tab !== "all") params.push(`where[status][equals]=${tab}`);
89
+ if (search.trim()) {
90
+ params.push(`where[or][0][subject][contains]=${encodeURIComponent(search)}`);
91
+ params.push(`where[or][1][ticketNumber][contains]=${encodeURIComponent(search)}`);
92
+ }
93
+ try {
94
+ const url = `/api/tickets?${params.join("&")}`;
95
+ const res = await fetch(url, { credentials: "include" });
96
+ if (res.ok) {
97
+ const d = await res.json();
98
+ setTickets(d.docs || []);
99
+ } else {
100
+ console.error("[inbox] Fetch failed:", res.status, await res.text().catch(() => ""));
101
+ }
102
+ } catch (err) {
103
+ console.error("[inbox] Fetch error:", err);
104
+ }
105
+ setLoading(false);
106
+ }, [tab, sort, search]);
107
+ useEffect(() => {
108
+ setLoading(true);
109
+ fetchTickets();
110
+ }, [fetchTickets]);
111
+ useEffect(() => {
112
+ const fetchCounts = async () => {
113
+ try {
114
+ const [all, openRes, waiting, resolved] = await Promise.all([
115
+ fetch("/api/tickets?limit=0&depth=0", { credentials: "include" }),
116
+ fetch("/api/tickets?limit=0&depth=0&where[status][equals]=open", { credentials: "include" }),
117
+ fetch("/api/tickets?limit=0&depth=0&where[status][equals]=waiting_client", { credentials: "include" }),
118
+ fetch("/api/tickets?limit=0&depth=0&where[status][equals]=resolved", { credentials: "include" })
119
+ ]);
120
+ const [a, o, w, r] = await Promise.all([all.json(), openRes.json(), waiting.json(), resolved.json()]);
121
+ setCounts({ all: a.totalDocs || 0, open: o.totalDocs || 0, waiting: w.totalDocs || 0, resolved: r.totalDocs || 0 });
122
+ } catch {
123
+ }
124
+ };
125
+ fetchCounts();
126
+ }, []);
127
+ useEffect(() => {
128
+ const iv = setInterval(fetchTickets, 6e4);
129
+ return () => clearInterval(iv);
130
+ }, [fetchTickets]);
131
+ useEffect(() => {
132
+ const handleKey = (e) => {
133
+ if (e.target instanceof HTMLInputElement || e.target instanceof HTMLTextAreaElement) return;
134
+ if (e.key === "j" || e.key === "ArrowDown") {
135
+ e.preventDefault();
136
+ setSelectedIdx((p) => Math.min(p + 1, tickets.length - 1));
137
+ }
138
+ if (e.key === "k" || e.key === "ArrowUp") {
139
+ e.preventDefault();
140
+ setSelectedIdx((p) => Math.max(p - 1, 0));
141
+ }
142
+ if (e.key === "Enter" && selectedIdx >= 0 && tickets[selectedIdx]) {
143
+ window.location.href = `/admin/support/ticket?id=${tickets[selectedIdx].id}`;
144
+ }
145
+ };
146
+ window.addEventListener("keydown", handleKey);
147
+ return () => window.removeEventListener("keydown", handleKey);
148
+ }, [tickets, selectedIdx]);
149
+ const tabs = [
150
+ { key: "all", label: t("inbox.tabs.all"), count: counts.all },
151
+ { key: "open", label: t("inbox.tabs.open"), count: counts.open },
152
+ { key: "waiting_client", label: t("inbox.tabs.waiting"), count: counts.waiting },
153
+ { key: "resolved", label: t("inbox.tabs.resolved"), count: counts.resolved }
154
+ ];
155
+ const S = {
156
+ page: { padding: "20px 30px", maxWidth: 1100, margin: "0 auto" },
157
+ header: { display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 16 },
158
+ title: { fontSize: 24, fontWeight: 700, margin: 0, color: "var(--theme-text)" },
159
+ headerRight: { display: "flex", gap: 10, alignItems: "center" },
160
+ searchWrap: { position: "relative", display: "flex", alignItems: "center" },
161
+ searchInput: { padding: "6px 12px 6px 30px", borderRadius: 8, border: "1px solid var(--theme-elevation-200)", fontSize: 13, background: "var(--theme-elevation-0)", color: "var(--theme-text)", width: 200 },
162
+ newTicketBtn: { padding: "7px 14px", borderRadius: 8, background: "#2563eb", color: "#fff", fontSize: 13, fontWeight: 600, textDecoration: "none", whiteSpace: "nowrap" },
163
+ tabsRow: { display: "flex", gap: 4, marginBottom: 12, borderBottom: "1px solid var(--theme-elevation-200)", paddingBottom: 8 },
164
+ tab: { padding: "6px 12px", borderRadius: 6, border: "none", background: "none", cursor: "pointer", fontSize: 13, color: "var(--theme-elevation-500)", fontWeight: 500 },
165
+ tabActive: { background: "var(--theme-elevation-100)", color: "var(--theme-text)", fontWeight: 700 },
166
+ sortRow: { display: "flex", alignItems: "center", marginBottom: 12 },
167
+ sortSelect: { padding: "4px 10px", borderRadius: 6, border: "1px solid var(--theme-elevation-200)", fontSize: 12, background: "var(--theme-elevation-0)", color: "var(--theme-text)", cursor: "pointer" },
168
+ loading: { padding: 40, textAlign: "center", color: "#94a3b8" },
169
+ empty: { padding: 60, textAlign: "center", color: "#94a3b8" },
170
+ list: { display: "flex", flexDirection: "column", gap: 1 },
171
+ row: { display: "grid", gridTemplateColumns: "20px 10px 60px 70px 1fr 140px 80px 4px 50px 10px", gap: 8, alignItems: "center", padding: "10px 12px", borderRadius: 8, textDecoration: "none", color: "var(--theme-text)", fontSize: 13, cursor: "pointer", transition: "background 100ms", background: "var(--theme-elevation-0)" },
172
+ statusDot: { width: 8, height: 8, borderRadius: "50%" },
173
+ priorityBar: { width: 4, height: 20, borderRadius: 2 },
174
+ unreadDot: { width: 8, height: 8, borderRadius: "50%", background: "#2563eb" },
175
+ keyboardHints: { display: "flex", gap: 12, marginTop: 16, fontSize: 11, color: "var(--theme-elevation-400)" }
176
+ };
177
+ return /* @__PURE__ */ jsxs("div", { style: S.page, children: [
178
+ /* @__PURE__ */ jsxs("div", { style: S.header, children: [
179
+ /* @__PURE__ */ jsx("h1", { style: S.title, children: t("inbox.title") }),
180
+ /* @__PURE__ */ jsxs("div", { style: S.headerRight, children: [
181
+ /* @__PURE__ */ jsx("div", { style: S.searchWrap, children: /* @__PURE__ */ jsx(
182
+ "input",
183
+ {
184
+ type: "text",
185
+ style: S.searchInput,
186
+ placeholder: t("inbox.searchPlaceholder"),
187
+ value: search,
188
+ onChange: (e) => setSearch(e.target.value)
189
+ }
190
+ ) }),
191
+ /* @__PURE__ */ jsx(Link, { href: "/admin/support/new-ticket", style: S.newTicketBtn, children: t("inbox.newTicketBtn") })
192
+ ] })
193
+ ] }),
194
+ /* @__PURE__ */ jsx("div", { style: S.tabsRow, children: tabs.map((tb) => /* @__PURE__ */ jsxs(
195
+ "button",
196
+ {
197
+ style: { ...S.tab, ...tab === tb.key ? S.tabActive : {} },
198
+ onClick: () => {
199
+ setTab(tb.key);
200
+ setSelectedIdx(-1);
201
+ },
202
+ children: [
203
+ tb.label,
204
+ " ",
205
+ /* @__PURE__ */ jsxs("span", { style: { opacity: 0.6 }, children: [
206
+ "(",
207
+ tb.count,
208
+ ")"
209
+ ] })
210
+ ]
211
+ },
212
+ tb.key
213
+ )) }),
214
+ /* @__PURE__ */ jsx("div", { style: S.sortRow, children: checkedIds.size > 0 ? /* @__PURE__ */ jsxs("div", { style: { display: "flex", gap: 8, alignItems: "center", flex: 1 }, children: [
215
+ /* @__PURE__ */ jsx("span", { style: { fontSize: 13, fontWeight: 600, color: "var(--theme-text)" }, children: checkedIds.size > 1 ? t("inbox.selectedPlural", { count: String(checkedIds.size) }) : t("inbox.selected", { count: String(checkedIds.size) }) }),
216
+ /* @__PURE__ */ jsx("button", { style: S.sortSelect, onClick: () => handleBulkAction("close"), disabled: bulkProcessing, children: t("inbox.closeAction") }),
217
+ /* @__PURE__ */ jsx("button", { style: S.sortSelect, onClick: () => handleBulkAction("reopen"), disabled: bulkProcessing, children: t("inbox.reopenAction") }),
218
+ /* @__PURE__ */ jsxs("select", { style: S.sortSelect, value: bulkAction, onChange: (e) => {
219
+ if (e.target.value) handleBulkAction(e.target.value);
220
+ setBulkAction("");
221
+ }, children: [
222
+ /* @__PURE__ */ jsx("option", { value: "", children: t("inbox.moreActions") }),
223
+ /* @__PURE__ */ jsx("option", { value: "set_priority", children: t("inbox.changePriority") }),
224
+ /* @__PURE__ */ jsx("option", { value: "delete", children: t("inbox.deleteAction") })
225
+ ] }),
226
+ /* @__PURE__ */ jsx("button", { style: { ...S.sortSelect, marginLeft: "auto" }, onClick: () => setCheckedIds(/* @__PURE__ */ new Set()), children: t("inbox.deselect") })
227
+ ] }) : /* @__PURE__ */ jsxs("select", { style: S.sortSelect, value: sort, onChange: (e) => setSort(e.target.value), children: [
228
+ /* @__PURE__ */ jsx("option", { value: "-updatedAt", children: t("inbox.sort.newest") }),
229
+ /* @__PURE__ */ jsx("option", { value: "updatedAt", children: t("inbox.sort.oldest") }),
230
+ /* @__PURE__ */ jsx("option", { value: "-createdAt", children: t("inbox.sort.created") }),
231
+ /* @__PURE__ */ jsx("option", { value: "priority", children: t("inbox.sort.priority") })
232
+ ] }) }),
233
+ loading ? /* @__PURE__ */ jsx("div", { style: S.loading, children: t("common.loading") }) : tickets.length === 0 ? /* @__PURE__ */ jsx("div", { style: S.empty, children: t("inbox.empty") }) : /* @__PURE__ */ jsx("div", { style: S.list, children: tickets.map((tk, idx) => {
234
+ const clientObj = typeof tk.client === "object" ? tk.client : null;
235
+ const clientName = clientObj ? `${clientObj.firstName || ""} ${clientObj.lastName || ""}`.trim() : "";
236
+ const clientCompany = clientObj?.company || "";
237
+ const displayClient = clientName ? `${clientName}${clientCompany ? `, ${clientCompany}` : ""}` : "--";
238
+ const isUnread = tk.lastClientMessageAt && (!tk.lastAdminReadAt || new Date(tk.lastClientMessageAt) > new Date(tk.lastAdminReadAt));
239
+ const priorityColor = PRIORITY_COLORS[tk.priority] || "transparent";
240
+ return /* @__PURE__ */ jsxs(
241
+ "a",
242
+ {
243
+ href: `/admin/support/ticket?id=${tk.id}`,
244
+ style: { ...S.row, ...idx === selectedIdx ? { background: "var(--theme-elevation-100)" } : {} },
245
+ onClick: (e) => {
246
+ e.preventDefault();
247
+ window.location.href = `/admin/support/ticket?id=${tk.id}`;
248
+ },
249
+ children: [
250
+ /* @__PURE__ */ jsx(
251
+ "input",
252
+ {
253
+ type: "checkbox",
254
+ checked: checkedIds.has(tk.id),
255
+ onClick: (e) => e.stopPropagation(),
256
+ onChange: () => toggleCheck(tk.id),
257
+ style: { width: 14, height: 14, cursor: "pointer", accentColor: "#2563eb" }
258
+ }
259
+ ),
260
+ /* @__PURE__ */ jsx("div", { style: { ...S.statusDot, backgroundColor: STATUS_DOTS[tk.status] || "#94a3b8" } }),
261
+ /* @__PURE__ */ jsx("span", { style: { fontSize: 11, color: "var(--theme-elevation-500)" }, children: STATUS_LABEL_KEYS[tk.status] ? t(STATUS_LABEL_KEYS[tk.status]) : tk.status }),
262
+ /* @__PURE__ */ jsx("span", { style: { fontWeight: 600, fontSize: 12, color: "var(--theme-elevation-400)" }, children: tk.ticketNumber }),
263
+ /* @__PURE__ */ jsx("span", { style: { fontWeight: 500 }, children: tk.subject }),
264
+ /* @__PURE__ */ jsx("span", { style: { fontSize: 12, color: "var(--theme-elevation-500)", overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }, children: displayClient }),
265
+ tk.category ? /* @__PURE__ */ jsxs("span", { style: { fontSize: 11, color: "var(--theme-elevation-400)" }, children: [
266
+ "[",
267
+ CATEGORY_LABEL_KEYS[tk.category] ? t(CATEGORY_LABEL_KEYS[tk.category]) : tk.category,
268
+ "]"
269
+ ] }) : /* @__PURE__ */ jsx("span", {}),
270
+ /* @__PURE__ */ jsx("div", { style: { ...S.priorityBar, backgroundColor: priorityColor } }),
271
+ /* @__PURE__ */ jsx("span", { style: { fontSize: 11, color: "var(--theme-elevation-400)", textAlign: "right" }, children: relativeTime(tk.updatedAt) }),
272
+ isUnread ? /* @__PURE__ */ jsx("div", { style: S.unreadDot }) : /* @__PURE__ */ jsx("span", {})
273
+ ]
274
+ },
275
+ tk.id
276
+ );
277
+ }) }),
278
+ /* @__PURE__ */ jsxs("div", { style: S.keyboardHints, children: [
279
+ /* @__PURE__ */ jsxs("span", { children: [
280
+ /* @__PURE__ */ jsx("kbd", { children: "\u2191" }),
281
+ /* @__PURE__ */ jsx("kbd", { children: "\u2193" }),
282
+ " ",
283
+ t("inbox.keyboardNavigate")
284
+ ] }),
285
+ /* @__PURE__ */ jsxs("span", { children: [
286
+ /* @__PURE__ */ jsx("kbd", { children: "\u21B5" }),
287
+ " ",
288
+ t("inbox.keyboardOpen")
289
+ ] })
290
+ ] })
291
+ ] });
292
+ };
293
+
294
+ export { TicketInboxClient };
@@ -0,0 +1,27 @@
1
+ import { jsx } from 'react/jsx-runtime';
2
+ import { DefaultTemplate } from '@payloadcms/next/templates';
3
+ import { redirect } from 'next/navigation';
4
+ import { AdminErrorBoundary } from '../shared/ErrorBoundary';
5
+ import { TicketInboxClient } from './client';
6
+
7
+ const TicketInboxView = ({ initPageResult }) => {
8
+ const { req, visibleEntities } = initPageResult;
9
+ if (!req.user) redirect("/admin/login");
10
+ return /* @__PURE__ */ jsx(
11
+ DefaultTemplate,
12
+ {
13
+ i18n: req.i18n,
14
+ locale: initPageResult.locale,
15
+ params: {},
16
+ payload: req.payload,
17
+ permissions: initPageResult.permissions,
18
+ searchParams: {},
19
+ user: req.user,
20
+ visibleEntities,
21
+ children: /* @__PURE__ */ jsx(AdminErrorBoundary, { viewName: "TicketInboxView", children: /* @__PURE__ */ jsx(TicketInboxClient, {}) })
22
+ }
23
+ );
24
+ };
25
+ var TicketInboxView_default = TicketInboxView;
26
+
27
+ export { TicketInboxView, TicketInboxView_default as default };