@consilioweb/payload-support 2.0.1 → 3.0.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 (215) hide show
  1. package/README.md +636 -402
  2. package/dist/components/RichTextEditor/index.d.ts +19 -0
  3. package/dist/components/TicketConversation/RewriteDropdown.d.ts +6 -0
  4. package/dist/components/TicketConversation/SkeletonText.d.ts +4 -0
  5. package/dist/components/TicketConversation/components/AISummaryPanel.d.ts +14 -0
  6. package/dist/components/TicketConversation/components/ActionPanels.d.ts +47 -0
  7. package/dist/components/TicketConversation/components/ActivityLog.d.ts +5 -0
  8. package/dist/components/TicketConversation/components/ClientBar.d.ts +5 -0
  9. package/dist/components/TicketConversation/components/ClientHistory.d.ts +24 -0
  10. package/dist/components/TicketConversation/components/CodeBlock.d.ts +26 -0
  11. package/dist/components/TicketConversation/components/CodeBlockInserter.d.ts +12 -0
  12. package/dist/components/TicketConversation/components/QuickActions.d.ts +32 -0
  13. package/dist/components/TicketConversation/components/TicketHeader.d.ts +19 -0
  14. package/dist/components/TicketConversation/components/TimeTrackingPanel.d.ts +24 -0
  15. package/dist/components/TicketConversation/config.d.ts +10 -0
  16. package/dist/components/TicketConversation/config.js +1 -40
  17. package/dist/components/TicketConversation/constants.d.ts +56 -0
  18. package/dist/components/TicketConversation/context.d.ts +53 -0
  19. package/dist/components/TicketConversation/hooks/useAI.d.ts +21 -0
  20. package/dist/components/TicketConversation/hooks/useDocumentIdFromUrl.d.ts +3 -0
  21. package/dist/components/TicketConversation/hooks/useFeatures.d.ts +23 -0
  22. package/dist/components/TicketConversation/hooks/useFeatures.js +61 -0
  23. package/dist/components/TicketConversation/hooks/useMessageActions.d.ts +20 -0
  24. package/dist/components/TicketConversation/hooks/useReply.d.ts +27 -0
  25. package/dist/components/TicketConversation/hooks/useTicketActions.d.ts +58 -0
  26. package/dist/components/TicketConversation/hooks/useTimeTracking.d.ts +18 -0
  27. package/dist/components/TicketConversation/hooks/useTranslation.d.ts +33 -0
  28. package/dist/components/TicketConversation/index.d.ts +4 -0
  29. package/dist/components/TicketConversation/index.js +2 -2
  30. package/dist/components/TicketConversation/types.d.ts +56 -0
  31. package/dist/components/TicketConversation/utils.d.ts +2 -0
  32. package/dist/index.cjs +392 -320
  33. package/dist/index.d.cts +100 -3
  34. package/dist/index.d.ts +100 -3
  35. package/dist/index.js +388 -321
  36. package/dist/utils/features.d.ts +123 -0
  37. package/dist/utils/features.js +147 -0
  38. package/dist/views/BillingView/client.d.ts +2 -0
  39. package/dist/views/BillingView/index.d.ts +4 -0
  40. package/dist/views/ChatView/client.d.ts +2 -0
  41. package/dist/views/ChatView/client.js +9 -9
  42. package/dist/views/ChatView/index.d.ts +4 -0
  43. package/dist/views/CrmView/client.d.ts +2 -0
  44. package/dist/views/CrmView/client.js +6 -9
  45. package/dist/views/CrmView/index.d.ts +4 -0
  46. package/dist/views/EmailTrackingView/client.d.ts +2 -0
  47. package/dist/views/EmailTrackingView/index.d.ts +4 -0
  48. package/dist/views/ImportConversationView/client.d.ts +2 -0
  49. package/dist/views/ImportConversationView/index.d.ts +4 -0
  50. package/dist/views/LogsView/client.d.ts +2 -0
  51. package/dist/views/LogsView/index.d.ts +4 -0
  52. package/dist/views/NewTicketView/client.d.ts +2 -0
  53. package/dist/views/NewTicketView/index.d.ts +4 -0
  54. package/dist/views/PendingEmailsView/client.d.ts +2 -0
  55. package/dist/views/PendingEmailsView/index.d.ts +4 -0
  56. package/dist/views/SupportDashboardView/client.d.ts +2 -0
  57. package/dist/views/SupportDashboardView/index.d.ts +4 -0
  58. package/dist/views/TicketDetailView/NextActionItem.d.ts +6 -0
  59. package/dist/views/TicketDetailView/RewriteDropdown.d.ts +7 -0
  60. package/dist/views/TicketDetailView/client.d.ts +2 -0
  61. package/dist/views/TicketDetailView/client.js +2 -2
  62. package/dist/views/TicketDetailView/constants.d.ts +13 -0
  63. package/dist/views/TicketDetailView/helpers.d.ts +2 -0
  64. package/dist/views/TicketDetailView/index.d.ts +4 -0
  65. package/dist/views/TicketDetailView/types.d.ts +40 -0
  66. package/dist/views/TicketInboxView/client.d.ts +2 -0
  67. package/dist/views/TicketInboxView/client.js +5 -5
  68. package/dist/views/TicketInboxView/index.d.ts +4 -0
  69. package/dist/views/TicketingSettingsView/client.d.ts +2 -0
  70. package/dist/views/TicketingSettingsView/client.js +5 -4
  71. package/dist/views/TicketingSettingsView/index.d.ts +4 -0
  72. package/dist/views/TimeDashboardView/client.d.ts +2 -0
  73. package/dist/views/TimeDashboardView/index.d.ts +4 -0
  74. package/dist/views/shared/AdminViewHeader.d.ts +13 -0
  75. package/dist/views/shared/ErrorBoundary.d.ts +17 -0
  76. package/dist/views/shared/Skeleton.d.ts +21 -0
  77. package/dist/views/shared/StatusPill.d.ts +8 -0
  78. package/dist/views/shared/adminTokens.d.ts +19 -0
  79. package/dist/views/shared/config.d.ts +8 -0
  80. package/dist/views/shared/config.js +1 -40
  81. package/dist/views/shared/dateLocale.d.ts +5 -0
  82. package/dist/views/shared/index.d.ts +12 -0
  83. package/dist/views/shared/index.js +2 -1
  84. package/dist/views/shared/sla.d.ts +14 -0
  85. package/dist/views.d.ts +13 -13
  86. package/package.json +16 -31
  87. package/src/collections/SupportClients.ts +29 -0
  88. package/src/collections/TicketCollaborators.ts +6 -1
  89. package/src/collections/TicketMessages.ts +46 -24
  90. package/src/collections/Tickets.ts +117 -79
  91. package/src/collections/TimeEntries.ts +57 -32
  92. package/src/components/TicketConversation/config.ts +16 -80
  93. package/src/components/TicketConversation/hooks/useFeatures.ts +109 -0
  94. package/src/components/TicketConversation/index.tsx +2 -2
  95. package/src/endpoints/ai.ts +2 -1
  96. package/src/endpoints/client-intelligence.ts +2 -1
  97. package/src/endpoints/process-scheduled.ts +13 -8
  98. package/src/endpoints/round-robin-config.ts +30 -20
  99. package/src/endpoints/settings.ts +28 -77
  100. package/src/index.ts +6 -2
  101. package/src/portal/LiveChat.tsx +33 -22
  102. package/src/portal/auth/tickets/detail/TicketPolling.tsx +5 -1
  103. package/src/types/lucide-react.d.ts +10 -2
  104. package/src/utils/aiAgent.ts +2 -1
  105. package/src/utils/aiProvider.ts +21 -0
  106. package/src/utils/features.ts +297 -0
  107. package/src/utils/fireWebhooks.ts +6 -0
  108. package/src/utils/generateTicketSynthesis.ts +2 -1
  109. package/src/utils/index.ts +4 -2
  110. package/src/utils/readSettings.ts +82 -9
  111. package/src/utils/webhookDispatcher.ts +19 -7
  112. package/src/views/ChatView/client.tsx +13 -9
  113. package/src/views/CrmView/client.tsx +10 -11
  114. package/src/views/TicketDetailView/client.tsx +2 -2
  115. package/src/views/TicketInboxView/client.tsx +10 -5
  116. package/src/views/TicketingSettingsView/client.tsx +8 -6
  117. package/src/views/shared/config.ts +14 -80
  118. package/src/views/shared/index.ts +3 -1
  119. package/dist/components/RichTextEditor/index.cjs +0 -279
  120. package/dist/components/TicketConversation/RewriteDropdown.cjs +0 -98
  121. package/dist/components/TicketConversation/SkeletonText.cjs +0 -21
  122. package/dist/components/TicketConversation/components/AISummaryPanel.cjs +0 -85
  123. package/dist/components/TicketConversation/components/ActionPanels.cjs +0 -193
  124. package/dist/components/TicketConversation/components/ActivityLog.cjs +0 -24
  125. package/dist/components/TicketConversation/components/ClientBar.cjs +0 -43
  126. package/dist/components/TicketConversation/components/ClientHistory.cjs +0 -138
  127. package/dist/components/TicketConversation/components/CodeBlock.cjs +0 -171
  128. package/dist/components/TicketConversation/components/CodeBlockInserter.cjs +0 -156
  129. package/dist/components/TicketConversation/components/QuickActions.cjs +0 -87
  130. package/dist/components/TicketConversation/components/TicketHeader.cjs +0 -93
  131. package/dist/components/TicketConversation/components/TimeTrackingPanel.cjs +0 -134
  132. package/dist/components/TicketConversation/config.cjs +0 -44
  133. package/dist/components/TicketConversation/constants.cjs +0 -127
  134. package/dist/components/TicketConversation/context.cjs +0 -13
  135. package/dist/components/TicketConversation/hooks/useAI.cjs +0 -196
  136. package/dist/components/TicketConversation/hooks/useDocumentIdFromUrl.cjs +0 -20
  137. package/dist/components/TicketConversation/hooks/useMessageActions.cjs +0 -136
  138. package/dist/components/TicketConversation/hooks/useReply.cjs +0 -188
  139. package/dist/components/TicketConversation/hooks/useTicketActions.cjs +0 -290
  140. package/dist/components/TicketConversation/hooks/useTimeTracking.cjs +0 -123
  141. package/dist/components/TicketConversation/hooks/useTranslation.cjs +0 -101
  142. package/dist/components/TicketConversation/index.cjs +0 -1114
  143. package/dist/components/TicketConversation/types.cjs +0 -2
  144. package/dist/components/TicketConversation/utils.cjs +0 -27
  145. package/dist/views/BillingView/client.cjs +0 -469
  146. package/dist/views/BillingView/index.cjs +0 -34
  147. package/dist/views/ChatView/client.cjs +0 -301
  148. package/dist/views/ChatView/index.cjs +0 -34
  149. package/dist/views/CrmView/client.cjs +0 -458
  150. package/dist/views/CrmView/index.cjs +0 -34
  151. package/dist/views/EmailTrackingView/client.cjs +0 -171
  152. package/dist/views/EmailTrackingView/index.cjs +0 -34
  153. package/dist/views/ImportConversationView/client.cjs +0 -238
  154. package/dist/views/ImportConversationView/index.cjs +0 -34
  155. package/dist/views/LogsView/client.cjs +0 -148
  156. package/dist/views/LogsView/index.cjs +0 -32
  157. package/dist/views/NewTicketView/client.cjs +0 -213
  158. package/dist/views/NewTicketView/index.cjs +0 -32
  159. package/dist/views/PendingEmailsView/client.cjs +0 -471
  160. package/dist/views/PendingEmailsView/index.cjs +0 -34
  161. package/dist/views/SupportDashboardView/client.cjs +0 -437
  162. package/dist/views/SupportDashboardView/index.cjs +0 -34
  163. package/dist/views/TicketDetailView/NextActionItem.cjs +0 -40
  164. package/dist/views/TicketDetailView/RewriteDropdown.cjs +0 -80
  165. package/dist/views/TicketDetailView/client.cjs +0 -1412
  166. package/dist/views/TicketDetailView/constants.cjs +0 -20
  167. package/dist/views/TicketDetailView/helpers.cjs +0 -23
  168. package/dist/views/TicketDetailView/index.cjs +0 -34
  169. package/dist/views/TicketDetailView/types.cjs +0 -2
  170. package/dist/views/TicketInboxView/client.cjs +0 -359
  171. package/dist/views/TicketInboxView/index.cjs +0 -32
  172. package/dist/views/TicketingSettingsView/client.cjs +0 -740
  173. package/dist/views/TicketingSettingsView/index.cjs +0 -34
  174. package/dist/views/TimeDashboardView/client.cjs +0 -180
  175. package/dist/views/TimeDashboardView/index.cjs +0 -34
  176. package/dist/views/shared/AdminViewHeader.cjs +0 -68
  177. package/dist/views/shared/ErrorBoundary.cjs +0 -55
  178. package/dist/views/shared/Skeleton.cjs +0 -77
  179. package/dist/views/shared/StatusPill.cjs +0 -47
  180. package/dist/views/shared/adminTokens.cjs +0 -34
  181. package/dist/views/shared/config.cjs +0 -44
  182. package/dist/views/shared/dateLocale.cjs +0 -5
  183. package/dist/views/shared/index.cjs +0 -72
  184. package/dist/views/shared/sla.cjs +0 -37
  185. package/dist/views.cjs +0 -86
  186. package/dist/views.d.cts +0 -13
  187. package/src/__tests__/aiSummaryRendering.test.ts +0 -21
  188. package/src/__tests__/authResponses.test.ts +0 -69
  189. package/src/__tests__/capabilities.test.ts +0 -71
  190. package/src/__tests__/generateTrackingToken.test.ts +0 -67
  191. package/src/__tests__/integration/ai-agent.test.ts +0 -46
  192. package/src/__tests__/integration/auth.test.ts +0 -43
  193. package/src/__tests__/integration/automation-rules.test.ts +0 -68
  194. package/src/__tests__/integration/buildTestPayload.ts +0 -52
  195. package/src/__tests__/integration/channels.test.ts +0 -52
  196. package/src/__tests__/integration/core-behaviors.test.ts +0 -81
  197. package/src/__tests__/integration/dashboard-volume.test.ts +0 -31
  198. package/src/__tests__/integration/digest.test.ts +0 -48
  199. package/src/__tests__/integration/invoice-pdf.test.ts +0 -30
  200. package/src/__tests__/integration/isolation.test.ts +0 -81
  201. package/src/__tests__/integration/mentions-invoice.test.ts +0 -50
  202. package/src/__tests__/integration/nps.test.ts +0 -37
  203. package/src/__tests__/integration/per-team-sla.test.ts +0 -44
  204. package/src/__tests__/integration/push.test.ts +0 -75
  205. package/src/__tests__/integration/sanitization.test.ts +0 -35
  206. package/src/__tests__/integration/sla-pause.test.ts +0 -39
  207. package/src/__tests__/integration/smoke.test.ts +0 -26
  208. package/src/__tests__/integration/snooze.test.ts +0 -68
  209. package/src/__tests__/integration/teams.test.ts +0 -38
  210. package/src/__tests__/rateLimiter.test.ts +0 -83
  211. package/src/__tests__/sanitizeHtml.test.ts +0 -165
  212. package/src/__tests__/sla.test.ts +0 -258
  213. package/src/__tests__/trackOpenEndpoint.test.ts +0 -54
  214. package/src/__tests__/translations.test.ts +0 -67
  215. package/src/__tests__/webhookSecurity.test.ts +0 -58
@@ -1,34 +0,0 @@
1
- 'use strict';
2
-
3
- Object.defineProperty(exports, '__esModule', { value: true });
4
-
5
- var jsxRuntime = require('react/jsx-runtime');
6
- var templates = require('@payloadcms/next/templates');
7
- var navigation = require('next/navigation');
8
- var ErrorBoundary = require('../shared/ErrorBoundary');
9
- var client = require('./client');
10
-
11
- const TicketingSettingsView = ({ initPageResult }) => {
12
- const { req, visibleEntities } = initPageResult;
13
- if (!req.user) {
14
- navigation.redirect("/admin/login");
15
- }
16
- return /* @__PURE__ */ jsxRuntime.jsx(
17
- templates.DefaultTemplate,
18
- {
19
- i18n: req.i18n,
20
- locale: initPageResult.locale,
21
- params: {},
22
- payload: req.payload,
23
- permissions: initPageResult.permissions,
24
- searchParams: {},
25
- user: req.user,
26
- visibleEntities,
27
- children: /* @__PURE__ */ jsxRuntime.jsx(ErrorBoundary.AdminErrorBoundary, { viewName: "TicketingSettingsView", children: /* @__PURE__ */ jsxRuntime.jsx(client.TicketingSettingsClient, {}) })
28
- }
29
- );
30
- };
31
- var TicketingSettingsView_default = TicketingSettingsView;
32
-
33
- exports.TicketingSettingsView = TicketingSettingsView;
34
- exports.default = TicketingSettingsView_default;
@@ -1,180 +0,0 @@
1
- 'use strict';
2
-
3
- var jsxRuntime = require('react/jsx-runtime');
4
- var React = require('react');
5
- var Skeleton = require('../shared/Skeleton');
6
- var useTranslation = require('../../components/TicketConversation/hooks/useTranslation');
7
- var styles = require('../../styles/TimeDashboard.module.scss');
8
-
9
- function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
10
-
11
- var React__default = /*#__PURE__*/_interopDefault(React);
12
- var styles__default = /*#__PURE__*/_interopDefault(styles);
13
-
14
- function formatDuration(minutes) {
15
- const h = Math.floor(minutes / 60);
16
- const m = minutes % 60;
17
- if (h === 0) return `${m}min`;
18
- if (m === 0) return `${h}h`;
19
- return `${h}h${m}m`;
20
- }
21
- function getWeekNumber(d) {
22
- const oneJan = new Date(d.getFullYear(), 0, 1);
23
- return Math.ceil(((d.getTime() - oneJan.getTime()) / 864e5 + oneJan.getDay() + 1) / 7);
24
- }
25
- function getMonthRange(offset) {
26
- const now = /* @__PURE__ */ new Date();
27
- const start = new Date(now.getFullYear(), now.getMonth() + offset, 1);
28
- const end = new Date(now.getFullYear(), now.getMonth() + offset + 1, 0);
29
- return { from: start.toISOString().split("T")[0], to: end.toISOString().split("T")[0] };
30
- }
31
- const MONTHS_FR = ["Jan", "Fev", "Mar", "Avr", "Mai", "Jun", "Jul", "Aou", "Sep", "Oct", "Nov", "Dec"];
32
- const TimeDashboardClient = () => {
33
- const { t } = useTranslation.useTranslation();
34
- const [entries, setEntries] = React.useState([]);
35
- const [loading, setLoading] = React.useState(true);
36
- const [from, setFrom] = React.useState(() => getMonthRange(0).from);
37
- const [to, setTo] = React.useState(() => getMonthRange(0).to);
38
- const [groupBy, setGroupBy] = React.useState("day");
39
- const fetchEntries = React.useCallback(async () => {
40
- setLoading(true);
41
- try {
42
- const params = new URLSearchParams({
43
- limit: "500",
44
- depth: "2",
45
- sort: "-date"
46
- });
47
- if (from) params.set("where[date][greater_than_equal]", from);
48
- if (to) params.set("where[date][less_than_equal]", to);
49
- const res = await fetch(`/api/time-entries?${params}`);
50
- if (res.ok) {
51
- const json = await res.json();
52
- setEntries(json.docs || []);
53
- }
54
- } catch {
55
- }
56
- setLoading(false);
57
- }, [from, to]);
58
- React.useEffect(() => {
59
- fetchEntries();
60
- }, [fetchEntries]);
61
- const totalMinutes = entries.reduce((sum, e) => sum + (e.duration || 0), 0);
62
- const totalEntries = entries.length;
63
- const grouped = React__default.default.useMemo(() => {
64
- const map = /* @__PURE__ */ new Map();
65
- for (const entry of entries) {
66
- let key;
67
- if (groupBy === "day") {
68
- key = entry.date ? entry.date.split("T")[0] : t("timeDashboard.noDate");
69
- } else if (groupBy === "week") {
70
- const d = new Date(entry.date);
71
- key = `Semaine ${getWeekNumber(d)} (${MONTHS_FR[d.getMonth()]} ${d.getFullYear()})`;
72
- } else {
73
- const ticket = typeof entry.ticket === "object" ? entry.ticket : null;
74
- const project = ticket && typeof ticket.project === "object" ? ticket.project : null;
75
- key = project?.name || t("billing.noProject");
76
- }
77
- if (!map.has(key)) map.set(key, []);
78
- map.get(key).push(entry);
79
- }
80
- return Array.from(map.entries()).map(([label, items]) => ({
81
- label,
82
- entries: items,
83
- totalMinutes: items.reduce((sum, e) => sum + (e.duration || 0), 0)
84
- }));
85
- }, [entries, groupBy]);
86
- const dailyChart = React__default.default.useMemo(() => {
87
- const dayMap = /* @__PURE__ */ new Map();
88
- for (const entry of entries) {
89
- const day = entry.date ? entry.date.split("T")[0] : null;
90
- if (day) {
91
- dayMap.set(day, (dayMap.get(day) || 0) + (entry.duration || 0));
92
- }
93
- }
94
- return Array.from(dayMap.entries()).sort(([a], [b]) => a.localeCompare(b)).slice(-30).map(([day, mins]) => ({ day, minutes: mins }));
95
- }, [entries]);
96
- const maxDailyMinutes = Math.max(...dailyChart.map((d) => d.minutes), 1);
97
- const setPeriod = (range) => {
98
- setFrom(range.from);
99
- setTo(range.to);
100
- };
101
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: styles__default.default.page, children: [
102
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: styles__default.default.header, children: [
103
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: styles__default.default.headerLeft, children: [
104
- /* @__PURE__ */ jsxRuntime.jsx("h1", { className: styles__default.default.title, children: t("timeDashboard.title") }),
105
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: styles__default.default.subtitle, children: t("timeDashboard.subtitle") })
106
- ] }),
107
- /* @__PURE__ */ jsxRuntime.jsx("a", { href: "/admin/collections/time-entries/create", className: styles__default.default.newEntryBtn, children: t("timeDashboard.newEntry") })
108
- ] }),
109
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: styles__default.default.filters, children: [
110
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: styles__default.default.quickPeriod, children: [
111
- /* @__PURE__ */ jsxRuntime.jsx("button", { className: styles__default.default.btnPrimary, onClick: () => setPeriod(getMonthRange(0)), children: t("timeDashboard.filters.thisMonth") }),
112
- /* @__PURE__ */ jsxRuntime.jsx("button", { className: styles__default.default.btnSecondary, onClick: () => setPeriod(getMonthRange(-1)), children: t("timeDashboard.filters.lastMonth") }),
113
- /* @__PURE__ */ jsxRuntime.jsx("button", { className: styles__default.default.btnAmber, onClick: () => setPeriod(getMonthRange(-2)), children: t("timeDashboard.filters.twoMonthsAgo") })
114
- ] }),
115
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: styles__default.default.filterRow, children: [
116
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: styles__default.default.fieldGroup, children: [
117
- /* @__PURE__ */ jsxRuntime.jsx("label", { className: styles__default.default.label, children: t("timeDashboard.filters.from") }),
118
- /* @__PURE__ */ jsxRuntime.jsx("input", { type: "date", value: from, onChange: (e) => setFrom(e.target.value), className: styles__default.default.input })
119
- ] }),
120
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: styles__default.default.fieldGroup, children: [
121
- /* @__PURE__ */ jsxRuntime.jsx("label", { className: styles__default.default.label, children: t("timeDashboard.filters.to") }),
122
- /* @__PURE__ */ jsxRuntime.jsx("input", { type: "date", value: to, onChange: (e) => setTo(e.target.value), className: styles__default.default.input })
123
- ] }),
124
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: styles__default.default.fieldGroup, children: [
125
- /* @__PURE__ */ jsxRuntime.jsx("label", { className: styles__default.default.label, children: t("timeDashboard.filters.groupBy") }),
126
- /* @__PURE__ */ jsxRuntime.jsxs("select", { value: groupBy, onChange: (e) => setGroupBy(e.target.value), className: styles__default.default.select, children: [
127
- /* @__PURE__ */ jsxRuntime.jsx("option", { value: "day", children: t("timeDashboard.filters.day") }),
128
- /* @__PURE__ */ jsxRuntime.jsx("option", { value: "week", children: t("timeDashboard.filters.week") }),
129
- /* @__PURE__ */ jsxRuntime.jsx("option", { value: "project", children: t("timeDashboard.filters.project") })
130
- ] })
131
- ] })
132
- ] })
133
- ] }),
134
- loading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: styles__default.default.loading, children: /* @__PURE__ */ jsxRuntime.jsx(Skeleton.SkeletonDashboard, {}) }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
135
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: styles__default.default.kpis, children: [
136
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: styles__default.default.kpiCardPrimary, children: [
137
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: styles__default.default.kpiLabel, children: t("timeDashboard.kpis.totalTime") }),
138
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: styles__default.default.kpiPrimary, children: formatDuration(totalMinutes) })
139
- ] }),
140
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: styles__default.default.kpiCardAmber, children: [
141
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: styles__default.default.kpiLabel, children: t("timeDashboard.kpis.entries") }),
142
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: styles__default.default.kpiAmber, children: totalEntries })
143
- ] }),
144
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: styles__default.default.kpiCardOrange, children: [
145
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: styles__default.default.kpiLabel, children: t("timeDashboard.kpis.dailyAverage") }),
146
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: styles__default.default.kpiOrange, children: dailyChart.length > 0 ? formatDuration(Math.round(totalMinutes / dailyChart.length)) : "-" })
147
- ] })
148
- ] }),
149
- dailyChart.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: styles__default.default.chartWrap, children: [
150
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: styles__default.default.chartHeader, children: t("timeDashboard.chart.title") }),
151
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: styles__default.default.chartBars, children: dailyChart.map((d) => /* @__PURE__ */ jsxRuntime.jsx(
152
- "div",
153
- {
154
- className: styles__default.default.chartBar,
155
- style: { height: `${Math.max(d.minutes / maxDailyMinutes * 100, 4)}%` },
156
- title: `${d.day}: ${formatDuration(d.minutes)}`
157
- },
158
- d.day
159
- )) })
160
- ] }),
161
- grouped.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: styles__default.default.empty, children: t("timeDashboard.empty") }) : grouped.map((group) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: styles__default.default.groupCard, children: [
162
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: styles__default.default.groupHeader, children: [
163
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: styles__default.default.groupLabel, children: group.label }),
164
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: styles__default.default.groupTotal, children: formatDuration(group.totalMinutes) })
165
- ] }),
166
- /* @__PURE__ */ jsxRuntime.jsx("table", { className: styles__default.default.table, children: /* @__PURE__ */ jsxRuntime.jsx("tbody", { children: group.entries.map((entry) => {
167
- const ticket = typeof entry.ticket === "object" ? entry.ticket : null;
168
- return /* @__PURE__ */ jsxRuntime.jsxs("tr", { className: styles__default.default.entryRow, children: [
169
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: styles__default.default.tdTicket, children: ticket ? /* @__PURE__ */ jsxRuntime.jsx("a", { href: `/admin/collections/tickets/${ticket.id}`, className: styles__default.default.ticketLink, children: ticket.ticketNumber || `#${ticket.id}` }) : "-" }),
170
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: styles__default.default.tdSubject, children: ticket?.subject || "" }),
171
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: styles__default.default.tdDescription, children: entry.description || "-" }),
172
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: styles__default.default.tdDuration, children: formatDuration(entry.duration) })
173
- ] }, entry.id);
174
- }) }) })
175
- ] }, group.label))
176
- ] })
177
- ] });
178
- };
179
-
180
- exports.TimeDashboardClient = TimeDashboardClient;
@@ -1,34 +0,0 @@
1
- 'use strict';
2
-
3
- Object.defineProperty(exports, '__esModule', { value: true });
4
-
5
- var jsxRuntime = require('react/jsx-runtime');
6
- var templates = require('@payloadcms/next/templates');
7
- var navigation = require('next/navigation');
8
- var ErrorBoundary = require('../shared/ErrorBoundary');
9
- var client = require('./client');
10
-
11
- const TimeDashboardView = ({ initPageResult }) => {
12
- const { req, visibleEntities } = initPageResult;
13
- if (!req.user) {
14
- navigation.redirect("/admin/login");
15
- }
16
- return /* @__PURE__ */ jsxRuntime.jsx(
17
- templates.DefaultTemplate,
18
- {
19
- i18n: req.i18n,
20
- locale: initPageResult.locale,
21
- params: {},
22
- payload: req.payload,
23
- permissions: initPageResult.permissions,
24
- searchParams: {},
25
- user: req.user,
26
- visibleEntities,
27
- children: /* @__PURE__ */ jsxRuntime.jsx(ErrorBoundary.AdminErrorBoundary, { viewName: "TimeDashboardView", children: /* @__PURE__ */ jsxRuntime.jsx(client.TimeDashboardClient, {}) })
28
- }
29
- );
30
- };
31
- var TimeDashboardView_default = TimeDashboardView;
32
-
33
- exports.TimeDashboardView = TimeDashboardView;
34
- exports.default = TimeDashboardView_default;
@@ -1,68 +0,0 @@
1
- 'use strict';
2
-
3
- var jsxRuntime = require('react/jsx-runtime');
4
- var adminTokens = require('./adminTokens');
5
-
6
- const AdminViewHeader = ({
7
- icon,
8
- title,
9
- subtitle,
10
- breadcrumb,
11
- actions
12
- }) => {
13
- return /* @__PURE__ */ jsxRuntime.jsxs(
14
- "div",
15
- {
16
- style: {
17
- display: "flex",
18
- justifyContent: "space-between",
19
- alignItems: "flex-start",
20
- marginBottom: 20
21
- },
22
- children: [
23
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
24
- breadcrumb && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { marginBottom: 6 }, children: /* @__PURE__ */ jsxRuntime.jsxs(
25
- "a",
26
- {
27
- href: breadcrumb.href,
28
- style: {
29
- fontSize: 12,
30
- fontWeight: 700,
31
- color: adminTokens.V.cyan,
32
- textDecoration: "none",
33
- textTransform: "uppercase"
34
- },
35
- children: [
36
- "\u2190 ",
37
- breadcrumb.label
38
- ]
39
- }
40
- ) }),
41
- /* @__PURE__ */ jsxRuntime.jsxs(
42
- "h1",
43
- {
44
- style: {
45
- fontSize: 28,
46
- fontWeight: 600,
47
- letterSpacing: 0,
48
- margin: 0,
49
- color: adminTokens.V.text,
50
- display: "flex",
51
- alignItems: "center",
52
- gap: 10
53
- },
54
- children: [
55
- /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: adminTokens.V.cyan, display: "flex", alignItems: "center" }, children: icon }),
56
- title
57
- ]
58
- }
59
- ),
60
- subtitle && /* @__PURE__ */ jsxRuntime.jsx("p", { style: { color: adminTokens.V.textSecondary, margin: "4px 0 0", fontSize: 14 }, children: subtitle })
61
- ] }),
62
- actions && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { display: "flex", gap: 8 }, children: actions })
63
- ]
64
- }
65
- );
66
- };
67
-
68
- exports.AdminViewHeader = AdminViewHeader;
@@ -1,55 +0,0 @@
1
- 'use strict';
2
-
3
- var jsxRuntime = require('react/jsx-runtime');
4
- var React = require('react');
5
-
6
- function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
7
-
8
- var React__default = /*#__PURE__*/_interopDefault(React);
9
-
10
- class AdminErrorBoundary extends React__default.default.Component {
11
- constructor(props) {
12
- super(props);
13
- this.state = { hasError: false, error: null };
14
- }
15
- static getDerivedStateFromError(error) {
16
- return { hasError: true, error };
17
- }
18
- componentDidCatch(error, errorInfo) {
19
- console.error(`[${this.props.viewName || "AdminView"}] Error:`, error, errorInfo);
20
- }
21
- render() {
22
- if (this.state.hasError) {
23
- if (this.props.fallback) {
24
- return this.props.fallback;
25
- }
26
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: {
27
- padding: "40px",
28
- textAlign: "center",
29
- color: "#dc2626"
30
- }, children: [
31
- /* @__PURE__ */ jsxRuntime.jsx("h2", { style: { marginBottom: "16px", fontSize: "18px" }, children: "Une erreur est survenue" }),
32
- /* @__PURE__ */ jsxRuntime.jsx("p", { style: { marginBottom: "24px", color: "#6b7280", fontSize: "14px" }, children: this.state.error?.message || "Erreur inattendue" }),
33
- /* @__PURE__ */ jsxRuntime.jsx(
34
- "button",
35
- {
36
- onClick: () => this.setState({ hasError: false, error: null }),
37
- style: {
38
- padding: "8px 20px",
39
- backgroundColor: "#2563eb",
40
- color: "#fff",
41
- border: "none",
42
- borderRadius: "6px",
43
- cursor: "pointer",
44
- fontSize: "14px"
45
- },
46
- children: "Reessayer"
47
- }
48
- )
49
- ] });
50
- }
51
- return this.props.children;
52
- }
53
- }
54
-
55
- exports.AdminErrorBoundary = AdminErrorBoundary;
@@ -1,77 +0,0 @@
1
- 'use strict';
2
-
3
- var jsxRuntime = require('react/jsx-runtime');
4
- var react = require('react');
5
-
6
- const styleId = "skeleton-shimmer-style";
7
- function injectSkeletonStyles() {
8
- if (typeof document === "undefined") return;
9
- if (document.getElementById(styleId)) return;
10
- const style = document.createElement("style");
11
- style.id = styleId;
12
- style.textContent = `
13
- @keyframes skeleton-shimmer {
14
- 0% { background-position: 200% 0; }
15
- 100% { background-position: -200% 0; }
16
- }
17
- `;
18
- document.head.appendChild(style);
19
- }
20
- function Skeleton({ width = "100%", height = "20px", borderRadius = "4px", style }) {
21
- react.useEffect(() => {
22
- injectSkeletonStyles();
23
- }, []);
24
- return /* @__PURE__ */ jsxRuntime.jsx(
25
- "div",
26
- {
27
- style: {
28
- width,
29
- height,
30
- borderRadius,
31
- background: "linear-gradient(90deg, #e5e7eb 25%, #f3f4f6 50%, #e5e7eb 75%)",
32
- backgroundSize: "200% 100%",
33
- animation: "skeleton-shimmer 1.5s infinite",
34
- ...style
35
- }
36
- }
37
- );
38
- }
39
- function SkeletonText({ lines = 3, width = "100%" }) {
40
- return /* @__PURE__ */ jsxRuntime.jsx("div", { style: { display: "flex", flexDirection: "column", gap: "8px", width }, children: Array.from({ length: lines }).map((_, i) => /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { height: "16px", width: i === lines - 1 ? "60%" : "100%" }, i)) });
41
- }
42
- function SkeletonCard({ height = "200px" }) {
43
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: {
44
- border: "1px solid #e5e7eb",
45
- borderRadius: "8px",
46
- padding: "20px",
47
- display: "flex",
48
- flexDirection: "column",
49
- gap: "12px",
50
- minHeight: height
51
- }, children: [
52
- /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { height: "24px", width: "40%" }),
53
- /* @__PURE__ */ jsxRuntime.jsx(SkeletonText, { lines: 3 }),
54
- /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { height: "32px", width: "120px", borderRadius: "6px" })
55
- ] });
56
- }
57
- function SkeletonTable({ rows = 5, columns = 4 }) {
58
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { width: "100%" }, children: [
59
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: { display: "flex", gap: "16px", padding: "12px 0", borderBottom: "2px solid #e5e7eb" }, children: Array.from({ length: columns }).map((_, i) => /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { height: "16px", width: `${100 / columns}%` }, i)) }),
60
- Array.from({ length: rows }).map((_, rowIdx) => /* @__PURE__ */ jsxRuntime.jsx("div", { style: { display: "flex", gap: "16px", padding: "12px 0", borderBottom: "1px solid #f3f4f6" }, children: Array.from({ length: columns }).map((_2, colIdx) => /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { height: "14px", width: `${100 / columns}%` }, colIdx)) }, rowIdx))
61
- ] });
62
- }
63
- function SkeletonDashboard() {
64
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "24px", padding: "20px 0" }, children: [
65
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: { display: "grid", gridTemplateColumns: "repeat(auto-fit, minmax(200px, 1fr))", gap: "16px" }, children: Array.from({ length: 4 }).map((_, i) => /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { padding: "20px", border: "1px solid #e5e7eb", borderRadius: "8px" }, children: [
66
- /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { height: "14px", width: "60%", style: { marginBottom: "8px" } }),
67
- /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { height: "32px", width: "40%" })
68
- ] }, i)) }),
69
- /* @__PURE__ */ jsxRuntime.jsx(SkeletonTable, { rows: 5, columns: 4 })
70
- ] });
71
- }
72
-
73
- exports.Skeleton = Skeleton;
74
- exports.SkeletonCard = SkeletonCard;
75
- exports.SkeletonDashboard = SkeletonDashboard;
76
- exports.SkeletonTable = SkeletonTable;
77
- exports.SkeletonText = SkeletonText;
@@ -1,47 +0,0 @@
1
- 'use strict';
2
-
3
- var jsxRuntime = require('react/jsx-runtime');
4
- var useTranslation = require('../../components/TicketConversation/hooks/useTranslation');
5
- var s = require('./StatusPill.module.scss');
6
-
7
- function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
8
-
9
- var s__default = /*#__PURE__*/_interopDefault(s);
10
-
11
- const VARIANT_CLS = {
12
- open: s__default.default.open,
13
- pending: s__default.default.pending,
14
- waiting_client: s__default.default.pending,
15
- resolved: s__default.default.resolved,
16
- closed: s__default.default.neutral,
17
- escalated: s__default.default.escalated,
18
- "sla-breach": s__default.default.breach
19
- };
20
- const STATUS_I18N_KEY = {
21
- open: "ticket.status.open",
22
- pending: "ticket.status.pending",
23
- waiting_client: "ticket.status.waitingClient",
24
- resolved: "ticket.status.resolved",
25
- closed: "ticket.status.closed",
26
- escalated: "ticket.status.escalated",
27
- "sla-breach": "ticket.status.slaBreached"
28
- };
29
- const StatusPill = ({ status, label, className }) => {
30
- const { t } = useTranslation.useTranslation();
31
- const cls = VARIANT_CLS[status] || VARIANT_CLS.open;
32
- const text = label ?? (STATUS_I18N_KEY[status] ? t(STATUS_I18N_KEY[status]) : status);
33
- return /* @__PURE__ */ jsxRuntime.jsxs(
34
- "span",
35
- {
36
- className: [s__default.default.pill, cls, className].filter(Boolean).join(" "),
37
- role: "status",
38
- "aria-label": `${t("ticket.status.label")} : ${text}`,
39
- children: [
40
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: s__default.default.dot, "aria-hidden": true }),
41
- text
42
- ]
43
- }
44
- );
45
- };
46
-
47
- exports.StatusPill = StatusPill;
@@ -1,34 +0,0 @@
1
- 'use strict';
2
-
3
- const V = {
4
- text: "var(--theme-text)",
5
- textSecondary: "var(--theme-elevation-500)",
6
- bg: "var(--theme-elevation-50)",
7
- bgCard: "var(--theme-elevation-100)",
8
- border: "var(--theme-elevation-300)",
9
- // Professional palette
10
- blue: "#2563eb",
11
- amber: "#d97706",
12
- orange: "#ea580c",
13
- green: "#16a34a",
14
- red: "#dc2626",
15
- // Legacy aliases (backward compat for views not yet updated)
16
- cyan: "#2563eb",
17
- yellow: "#d97706"
18
- };
19
- const btnStyle = (bg, opts) => ({
20
- padding: opts?.small ? "6px 12px" : "8px 14px",
21
- borderRadius: 6,
22
- border: `1px solid var(--theme-elevation-300)`,
23
- backgroundColor: bg,
24
- color: "#fff",
25
- fontWeight: 600,
26
- fontSize: opts?.small ? 12 : 13,
27
- cursor: opts?.disabled ? "not-allowed" : "pointer",
28
- opacity: opts?.disabled ? 0.5 : 1,
29
- textDecoration: "none",
30
- whiteSpace: "nowrap"
31
- });
32
-
33
- exports.V = V;
34
- exports.btnStyle = btnStyle;
@@ -1,44 +0,0 @@
1
- 'use strict';
2
-
3
- const DEFAULT_FEATURES = {
4
- timeTracking: true,
5
- ai: true,
6
- satisfaction: true,
7
- chat: true,
8
- emailTracking: true,
9
- canned: true,
10
- merge: true,
11
- snooze: true,
12
- externalMessages: true,
13
- clientHistory: true,
14
- activityLog: true,
15
- splitTicket: true,
16
- scheduledReplies: true,
17
- autoClose: true,
18
- autoCloseDays: 7,
19
- roundRobin: false
20
- };
21
- const STORAGE_KEY = "ticketing_features";
22
- function getFeatures() {
23
- if (typeof window === "undefined") return DEFAULT_FEATURES;
24
- try {
25
- const stored = localStorage.getItem(STORAGE_KEY);
26
- if (stored) {
27
- const parsed = JSON.parse(stored);
28
- return { ...DEFAULT_FEATURES, ...parsed };
29
- }
30
- } catch {
31
- }
32
- return DEFAULT_FEATURES;
33
- }
34
- function saveFeatures(features) {
35
- if (typeof window === "undefined") return;
36
- try {
37
- localStorage.setItem(STORAGE_KEY, JSON.stringify(features));
38
- } catch {
39
- }
40
- }
41
-
42
- exports.DEFAULT_FEATURES = DEFAULT_FEATURES;
43
- exports.getFeatures = getFeatures;
44
- exports.saveFeatures = saveFeatures;
@@ -1,5 +0,0 @@
1
- 'use strict';
2
-
3
- const DATE_LOCALE = "fr-FR";
4
-
5
- exports.DATE_LOCALE = DATE_LOCALE;
@@ -1,72 +0,0 @@
1
- 'use strict';
2
-
3
- var ErrorBoundary = require('./ErrorBoundary');
4
- var adminTokens = require('./adminTokens');
5
- var AdminViewHeader = require('./AdminViewHeader');
6
- var Skeleton = require('./Skeleton');
7
- var config = require('./config');
8
- var StatusPill = require('./StatusPill');
9
- var sla = require('./sla');
10
-
11
-
12
-
13
- Object.defineProperty(exports, "AdminErrorBoundary", {
14
- enumerable: true,
15
- get: function () { return ErrorBoundary.AdminErrorBoundary; }
16
- });
17
- Object.defineProperty(exports, "V", {
18
- enumerable: true,
19
- get: function () { return adminTokens.V; }
20
- });
21
- Object.defineProperty(exports, "btnStyle", {
22
- enumerable: true,
23
- get: function () { return adminTokens.btnStyle; }
24
- });
25
- Object.defineProperty(exports, "AdminViewHeader", {
26
- enumerable: true,
27
- get: function () { return AdminViewHeader.AdminViewHeader; }
28
- });
29
- Object.defineProperty(exports, "Skeleton", {
30
- enumerable: true,
31
- get: function () { return Skeleton.Skeleton; }
32
- });
33
- Object.defineProperty(exports, "SkeletonCard", {
34
- enumerable: true,
35
- get: function () { return Skeleton.SkeletonCard; }
36
- });
37
- Object.defineProperty(exports, "SkeletonDashboard", {
38
- enumerable: true,
39
- get: function () { return Skeleton.SkeletonDashboard; }
40
- });
41
- Object.defineProperty(exports, "SkeletonTable", {
42
- enumerable: true,
43
- get: function () { return Skeleton.SkeletonTable; }
44
- });
45
- Object.defineProperty(exports, "SkeletonText", {
46
- enumerable: true,
47
- get: function () { return Skeleton.SkeletonText; }
48
- });
49
- Object.defineProperty(exports, "DEFAULT_FEATURES", {
50
- enumerable: true,
51
- get: function () { return config.DEFAULT_FEATURES; }
52
- });
53
- Object.defineProperty(exports, "getFeatures", {
54
- enumerable: true,
55
- get: function () { return config.getFeatures; }
56
- });
57
- Object.defineProperty(exports, "saveFeatures", {
58
- enumerable: true,
59
- get: function () { return config.saveFeatures; }
60
- });
61
- Object.defineProperty(exports, "StatusPill", {
62
- enumerable: true,
63
- get: function () { return StatusPill.StatusPill; }
64
- });
65
- Object.defineProperty(exports, "computeSlaState", {
66
- enumerable: true,
67
- get: function () { return sla.computeSlaState; }
68
- });
69
- Object.defineProperty(exports, "formatSlaRemaining", {
70
- enumerable: true,
71
- get: function () { return sla.formatSlaRemaining; }
72
- });