@consilioweb/payload-support 0.6.0 → 0.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. package/dist/{styles/theme.css → components/TicketConversation.css} +13 -326
  2. package/dist/components/TicketConversation.js +3004 -0
  3. package/dist/index.cjs +11 -11
  4. package/dist/index.js +11 -11
  5. package/dist/views.cjs +6184 -0
  6. package/dist/{views/TicketingSettingsView/TicketingSettings.module.scss → views.css} +66 -138
  7. package/dist/views.d.cts +30 -0
  8. package/dist/views.d.ts +30 -0
  9. package/dist/views.js +6165 -0
  10. package/package.json +14 -7
  11. package/src/plugin.ts +11 -11
  12. package/src/views.ts +17 -0
  13. package/dist/components/TicketConversation/components/AISummaryPanel.js +0 -76
  14. package/dist/components/TicketConversation/components/ActionPanels.js +0 -118
  15. package/dist/components/TicketConversation/components/ActivityLog.js +0 -23
  16. package/dist/components/TicketConversation/components/ClientBar.js +0 -42
  17. package/dist/components/TicketConversation/components/ClientHistory.js +0 -137
  18. package/dist/components/TicketConversation/components/CodeBlock.js +0 -152
  19. package/dist/components/TicketConversation/components/CodeBlockInserter.js +0 -155
  20. package/dist/components/TicketConversation/components/QuickActions.js +0 -65
  21. package/dist/components/TicketConversation/components/TicketHeader.js +0 -92
  22. package/dist/components/TicketConversation/components/TimeTrackingPanel.js +0 -133
  23. package/dist/components/TicketConversation/config.js +0 -41
  24. package/dist/components/TicketConversation/constants.js +0 -96
  25. package/dist/components/TicketConversation/context.js +0 -11
  26. package/dist/components/TicketConversation/hooks/useAI.js +0 -176
  27. package/dist/components/TicketConversation/hooks/useMessageActions.js +0 -135
  28. package/dist/components/TicketConversation/hooks/useReply.js +0 -187
  29. package/dist/components/TicketConversation/hooks/useTicketActions.js +0 -230
  30. package/dist/components/TicketConversation/hooks/useTimeTracking.js +0 -122
  31. package/dist/components/TicketConversation/hooks/useTranslation.js +0 -70
  32. package/dist/components/TicketConversation/index.js +0 -1123
  33. package/dist/components/TicketConversation/locales/en.json +0 -878
  34. package/dist/components/TicketConversation/locales/fr.json +0 -878
  35. package/dist/components/TicketConversation/types.js +0 -2
  36. package/dist/components/TicketConversation/utils.js +0 -25
  37. package/dist/styles/BillingView.module.scss +0 -311
  38. package/dist/styles/ChatView.module.scss +0 -438
  39. package/dist/styles/CommandPalette.module.scss +0 -160
  40. package/dist/styles/CrmView.module.scss +0 -554
  41. package/dist/styles/EmailTracking.module.scss +0 -238
  42. package/dist/styles/ImportConversation.module.scss +0 -267
  43. package/dist/styles/Layout.module.scss +0 -55
  44. package/dist/styles/Logs.module.scss +0 -164
  45. package/dist/styles/NewTicket.module.scss +0 -143
  46. package/dist/styles/PendingEmails.module.scss +0 -629
  47. package/dist/styles/SupportDashboard.module.scss +0 -649
  48. package/dist/styles/TicketDetail.module.scss +0 -1050
  49. package/dist/styles/TicketInbox.module.scss +0 -296
  50. package/dist/styles/TicketingSettings.module.scss +0 -358
  51. package/dist/styles/TimeDashboard.module.scss +0 -287
  52. package/dist/styles/_tokens.scss +0 -78
  53. package/dist/views/BillingView/client.js +0 -204
  54. package/dist/views/BillingView/index.js +0 -29
  55. package/dist/views/ChatView/client.js +0 -252
  56. package/dist/views/ChatView/index.js +0 -29
  57. package/dist/views/CrmView/client.js +0 -232
  58. package/dist/views/CrmView/index.js +0 -29
  59. package/dist/views/EmailTrackingView/client.js +0 -154
  60. package/dist/views/EmailTrackingView/index.js +0 -29
  61. package/dist/views/ImportConversationView/client.js +0 -204
  62. package/dist/views/ImportConversationView/index.js +0 -29
  63. package/dist/views/LogsView/client.js +0 -148
  64. package/dist/views/LogsView/index.js +0 -27
  65. package/dist/views/NewTicketView/client.js +0 -224
  66. package/dist/views/NewTicketView/index.js +0 -27
  67. package/dist/views/PendingEmailsView/client.js +0 -172
  68. package/dist/views/PendingEmailsView/index.js +0 -29
  69. package/dist/views/SupportDashboardView/client.js +0 -296
  70. package/dist/views/SupportDashboardView/index.js +0 -29
  71. package/dist/views/TicketDetailView/client.js +0 -844
  72. package/dist/views/TicketDetailView/index.js +0 -29
  73. package/dist/views/TicketInboxView/client.js +0 -294
  74. package/dist/views/TicketInboxView/index.js +0 -27
  75. package/dist/views/TicketingSettingsView/client.js +0 -728
  76. package/dist/views/TicketingSettingsView/index.js +0 -29
  77. package/dist/views/TimeDashboardView/client.js +0 -164
  78. package/dist/views/TimeDashboardView/index.js +0 -29
  79. package/dist/views/shared/AdminViewHeader.js +0 -67
  80. package/dist/views/shared/ErrorBoundary.js +0 -50
  81. package/dist/views/shared/Skeleton.js +0 -72
  82. package/dist/views/shared/adminTokens.js +0 -32
  83. package/dist/views/shared/config.js +0 -41
  84. package/dist/views/shared/index.js +0 -6
@@ -1,29 +0,0 @@
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 { TicketingSettingsClient } from './client';
6
-
7
- const TicketingSettingsView = ({ 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: "TicketingSettingsView", children: /* @__PURE__ */ jsx(TicketingSettingsClient, {}) })
24
- }
25
- );
26
- };
27
- var TicketingSettingsView_default = TicketingSettingsView;
28
-
29
- export { TicketingSettingsView, TicketingSettingsView_default as default };
@@ -1,164 +0,0 @@
1
- "use client";
2
- import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
3
- import React, { useState, useCallback, useEffect } from 'react';
4
- import { useTranslation } from '../../components/TicketConversation/hooks/useTranslation';
5
-
6
- function formatDuration(minutes) {
7
- const h = Math.floor(minutes / 60);
8
- const m = minutes % 60;
9
- if (h === 0) return `${m}min`;
10
- if (m === 0) return `${h}h`;
11
- return `${h}h${m}m`;
12
- }
13
- function getWeekNumber(d) {
14
- const oneJan = new Date(d.getFullYear(), 0, 1);
15
- return Math.ceil(((d.getTime() - oneJan.getTime()) / 864e5 + oneJan.getDay() + 1) / 7);
16
- }
17
- function getMonthRange(offset) {
18
- const now = /* @__PURE__ */ new Date();
19
- const start = new Date(now.getFullYear(), now.getMonth() + offset, 1);
20
- const end = new Date(now.getFullYear(), now.getMonth() + offset + 1, 0);
21
- return { from: start.toISOString().split("T")[0], to: end.toISOString().split("T")[0] };
22
- }
23
- const MONTHS_FR = ["Jan", "Fev", "Mar", "Avr", "Mai", "Jun", "Jul", "Aou", "Sep", "Oct", "Nov", "Dec"];
24
- const TimeDashboardClient = () => {
25
- const { t } = useTranslation();
26
- const [entries, setEntries] = useState([]);
27
- const [loading, setLoading] = useState(true);
28
- const [from, setFrom] = useState(() => getMonthRange(0).from);
29
- const [to, setTo] = useState(() => getMonthRange(0).to);
30
- const [groupBy, setGroupBy] = useState("day");
31
- const fetchEntries = useCallback(async () => {
32
- setLoading(true);
33
- try {
34
- const params = new URLSearchParams({ limit: "500", depth: "2", sort: "-date" });
35
- if (from) params.set("where[date][greater_than_equal]", from);
36
- if (to) params.set("where[date][less_than_equal]", to);
37
- const res = await fetch(`/api/time-entries?${params}`);
38
- if (res.ok) {
39
- const json = await res.json();
40
- setEntries(json.docs || []);
41
- }
42
- } catch {
43
- }
44
- setLoading(false);
45
- }, [from, to]);
46
- useEffect(() => {
47
- fetchEntries();
48
- }, [fetchEntries]);
49
- const totalMinutes = entries.reduce((sum, e) => sum + (e.duration || 0), 0);
50
- const grouped = React.useMemo(() => {
51
- const map = /* @__PURE__ */ new Map();
52
- for (const entry of entries) {
53
- let key;
54
- if (groupBy === "day") {
55
- key = entry.date ? entry.date.split("T")[0] : "Sans date";
56
- } else if (groupBy === "week") {
57
- const d = new Date(entry.date);
58
- key = `Semaine ${getWeekNumber(d)} (${MONTHS_FR[d.getMonth()]} ${d.getFullYear()})`;
59
- } else {
60
- const ticket = typeof entry.ticket === "object" ? entry.ticket : null;
61
- const project = ticket && typeof ticket.project === "object" ? ticket.project : null;
62
- key = project?.name || "Sans projet";
63
- }
64
- if (!map.has(key)) map.set(key, []);
65
- map.get(key).push(entry);
66
- }
67
- return Array.from(map.entries()).map(([label, items]) => ({ label, entries: items, totalMinutes: items.reduce((sum, e) => sum + (e.duration || 0), 0) }));
68
- }, [entries, groupBy]);
69
- const dailyChart = React.useMemo(() => {
70
- const dayMap = /* @__PURE__ */ new Map();
71
- for (const entry of entries) {
72
- const day = entry.date ? entry.date.split("T")[0] : null;
73
- if (day) dayMap.set(day, (dayMap.get(day) || 0) + (entry.duration || 0));
74
- }
75
- return Array.from(dayMap.entries()).sort(([a], [b]) => a.localeCompare(b)).slice(-30).map(([day, mins]) => ({ day, minutes: mins }));
76
- }, [entries]);
77
- const maxDailyMinutes = Math.max(...dailyChart.map((d) => d.minutes), 1);
78
- const setPeriod = (range) => {
79
- setFrom(range.from);
80
- setTo(range.to);
81
- };
82
- const S = {
83
- page: { padding: "20px 30px", maxWidth: 1100, margin: "0 auto" },
84
- btn: { padding: "6px 12px", borderRadius: 6, border: "1px solid var(--theme-elevation-200)", fontSize: 12, cursor: "pointer", background: "var(--theme-elevation-0)", color: "var(--theme-text)" },
85
- btnPrimary: { padding: "6px 12px", borderRadius: 6, border: "none", fontSize: 12, cursor: "pointer", background: "#2563eb", color: "#fff", fontWeight: 600 },
86
- kpis: { display: "grid", gridTemplateColumns: "repeat(3, 1fr)", gap: 12, marginBottom: 20 },
87
- kpiCard: { padding: "16px 20px", borderRadius: 10, border: "1px solid var(--theme-elevation-150)" },
88
- groupCard: { marginBottom: 12, borderRadius: 10, border: "1px solid var(--theme-elevation-150)", overflow: "hidden" },
89
- groupHeader: { display: "flex", justifyContent: "space-between", padding: "10px 16px", background: "var(--theme-elevation-50)", borderBottom: "1px solid var(--theme-elevation-150)" },
90
- table: { width: "100%", borderCollapse: "collapse", fontSize: 12 },
91
- td: { padding: "6px 8px", borderBottom: "1px solid var(--theme-elevation-100)" }
92
- };
93
- return /* @__PURE__ */ jsxs("div", { style: S.page, children: [
94
- /* @__PURE__ */ jsxs("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 16 }, children: [
95
- /* @__PURE__ */ jsxs("div", { children: [
96
- /* @__PURE__ */ jsx("h1", { style: { fontSize: 22, fontWeight: 700, margin: 0 }, children: t("timeDashboard.title") }),
97
- /* @__PURE__ */ jsx("p", { style: { fontSize: 13, color: "var(--theme-elevation-500)", margin: "4px 0 0" }, children: t("timeDashboard.subtitle") })
98
- ] }),
99
- /* @__PURE__ */ jsx("a", { href: "/admin/collections/time-entries/create", style: { ...S.btnPrimary, textDecoration: "none", display: "inline-block" }, children: t("timeDashboard.newEntry") })
100
- ] }),
101
- /* @__PURE__ */ jsxs("div", { style: { marginBottom: 16 }, children: [
102
- /* @__PURE__ */ jsxs("div", { style: { display: "flex", gap: 6, marginBottom: 8 }, children: [
103
- /* @__PURE__ */ jsx("button", { style: S.btnPrimary, onClick: () => setPeriod(getMonthRange(0)), children: t("timeDashboard.filters.thisMonth") }),
104
- /* @__PURE__ */ jsx("button", { style: S.btn, onClick: () => setPeriod(getMonthRange(-1)), children: t("timeDashboard.filters.lastMonth") }),
105
- /* @__PURE__ */ jsx("button", { style: S.btn, onClick: () => setPeriod(getMonthRange(-2)), children: t("timeDashboard.filters.twoMonthsAgo") })
106
- ] }),
107
- /* @__PURE__ */ jsxs("div", { style: { display: "flex", gap: 12, alignItems: "flex-end" }, children: [
108
- /* @__PURE__ */ jsxs("div", { children: [
109
- /* @__PURE__ */ jsx("label", { style: { fontSize: 11, fontWeight: 600, display: "block", marginBottom: 4, color: "var(--theme-elevation-500)" }, children: t("timeDashboard.filters.from") }),
110
- /* @__PURE__ */ jsx("input", { type: "date", value: from, onChange: (e) => setFrom(e.target.value), style: { padding: "6px 10px", borderRadius: 6, border: "1px solid var(--theme-elevation-200)", fontSize: 12, color: "var(--theme-text)", background: "var(--theme-elevation-0)" } })
111
- ] }),
112
- /* @__PURE__ */ jsxs("div", { children: [
113
- /* @__PURE__ */ jsx("label", { style: { fontSize: 11, fontWeight: 600, display: "block", marginBottom: 4, color: "var(--theme-elevation-500)" }, children: t("timeDashboard.filters.to") }),
114
- /* @__PURE__ */ jsx("input", { type: "date", value: to, onChange: (e) => setTo(e.target.value), style: { padding: "6px 10px", borderRadius: 6, border: "1px solid var(--theme-elevation-200)", fontSize: 12, color: "var(--theme-text)", background: "var(--theme-elevation-0)" } })
115
- ] }),
116
- /* @__PURE__ */ jsxs("div", { children: [
117
- /* @__PURE__ */ jsx("label", { style: { fontSize: 11, fontWeight: 600, display: "block", marginBottom: 4, color: "var(--theme-elevation-500)" }, children: t("timeDashboard.filters.groupBy") }),
118
- /* @__PURE__ */ jsxs("select", { value: groupBy, onChange: (e) => setGroupBy(e.target.value), style: { padding: "6px 10px", borderRadius: 6, border: "1px solid var(--theme-elevation-200)", fontSize: 12, color: "var(--theme-text)", background: "var(--theme-elevation-0)" }, children: [
119
- /* @__PURE__ */ jsx("option", { value: "day", children: t("timeDashboard.filters.day") }),
120
- /* @__PURE__ */ jsx("option", { value: "week", children: t("timeDashboard.filters.week") }),
121
- /* @__PURE__ */ jsx("option", { value: "project", children: t("timeDashboard.filters.project") })
122
- ] })
123
- ] })
124
- ] })
125
- ] }),
126
- loading ? /* @__PURE__ */ jsx("div", { style: { padding: 40, textAlign: "center", color: "#94a3b8" }, children: t("common.loading") }) : /* @__PURE__ */ jsxs(Fragment, { children: [
127
- /* @__PURE__ */ jsxs("div", { style: S.kpis, children: [
128
- /* @__PURE__ */ jsxs("div", { style: S.kpiCard, children: [
129
- /* @__PURE__ */ jsx("div", { style: { fontSize: 11, color: "var(--theme-elevation-500)" }, children: t("timeDashboard.kpis.totalTime") }),
130
- /* @__PURE__ */ jsx("div", { style: { fontSize: 24, fontWeight: 700, color: "#2563eb" }, children: formatDuration(totalMinutes) })
131
- ] }),
132
- /* @__PURE__ */ jsxs("div", { style: S.kpiCard, children: [
133
- /* @__PURE__ */ jsx("div", { style: { fontSize: 11, color: "var(--theme-elevation-500)" }, children: t("timeDashboard.kpis.entries") }),
134
- /* @__PURE__ */ jsx("div", { style: { fontSize: 24, fontWeight: 700, color: "#d97706" }, children: entries.length })
135
- ] }),
136
- /* @__PURE__ */ jsxs("div", { style: S.kpiCard, children: [
137
- /* @__PURE__ */ jsx("div", { style: { fontSize: 11, color: "var(--theme-elevation-500)" }, children: t("timeDashboard.kpis.dailyAverage") }),
138
- /* @__PURE__ */ jsx("div", { style: { fontSize: 24, fontWeight: 700, color: "#ea580c" }, children: dailyChart.length > 0 ? formatDuration(Math.round(totalMinutes / dailyChart.length)) : "-" })
139
- ] })
140
- ] }),
141
- dailyChart.length > 0 && /* @__PURE__ */ jsxs("div", { style: { padding: 16, borderRadius: 10, border: "1px solid var(--theme-elevation-150)", marginBottom: 20 }, children: [
142
- /* @__PURE__ */ jsx("div", { style: { fontSize: 13, fontWeight: 700, marginBottom: 8 }, children: t("timeDashboard.chart.title") }),
143
- /* @__PURE__ */ jsx("div", { style: { display: "flex", alignItems: "flex-end", gap: 3, height: 80 }, children: dailyChart.map((d) => /* @__PURE__ */ jsx("div", { style: { flex: 1, background: "#3b82f6", borderRadius: "3px 3px 0 0", height: `${Math.max(d.minutes / maxDailyMinutes * 100, 4)}%` }, title: `${d.day}: ${formatDuration(d.minutes)}` }, d.day)) })
144
- ] }),
145
- grouped.length === 0 ? /* @__PURE__ */ jsx("div", { style: { padding: 40, textAlign: "center", color: "#94a3b8" }, children: t("timeDashboard.empty") }) : grouped.map((group) => /* @__PURE__ */ jsxs("div", { style: S.groupCard, children: [
146
- /* @__PURE__ */ jsxs("div", { style: S.groupHeader, children: [
147
- /* @__PURE__ */ jsx("span", { style: { fontWeight: 700 }, children: group.label }),
148
- /* @__PURE__ */ jsx("span", { style: { fontWeight: 700, color: "#2563eb" }, children: formatDuration(group.totalMinutes) })
149
- ] }),
150
- /* @__PURE__ */ jsx("table", { style: S.table, children: /* @__PURE__ */ jsx("tbody", { children: group.entries.map((entry) => {
151
- const ticket = typeof entry.ticket === "object" ? entry.ticket : null;
152
- return /* @__PURE__ */ jsxs("tr", { children: [
153
- /* @__PURE__ */ jsx("td", { style: S.td, children: ticket ? /* @__PURE__ */ jsx("a", { href: `/admin/collections/tickets/${ticket.id}`, style: { color: "#2563eb", textDecoration: "none", fontWeight: 600 }, children: ticket.ticketNumber || `#${ticket.id}` }) : "-" }),
154
- /* @__PURE__ */ jsx("td", { style: S.td, children: ticket?.subject || "" }),
155
- /* @__PURE__ */ jsx("td", { style: { ...S.td, color: "var(--theme-elevation-500)" }, children: entry.description || "-" }),
156
- /* @__PURE__ */ jsx("td", { style: { ...S.td, textAlign: "right", fontWeight: 600 }, children: formatDuration(entry.duration) })
157
- ] }, entry.id);
158
- }) }) })
159
- ] }, group.label))
160
- ] })
161
- ] });
162
- };
163
-
164
- export { TimeDashboardClient };
@@ -1,29 +0,0 @@
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 { TimeDashboardClient } from './client';
6
-
7
- const TimeDashboardView = ({ 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: "TimeDashboardView", children: /* @__PURE__ */ jsx(TimeDashboardClient, {}) })
24
- }
25
- );
26
- };
27
- var TimeDashboardView_default = TimeDashboardView;
28
-
29
- export { TimeDashboardView, TimeDashboardView_default as default };
@@ -1,67 +0,0 @@
1
- "use client";
2
- import { jsxs, jsx } from 'react/jsx-runtime';
3
- import { V } from './adminTokens';
4
-
5
- const AdminViewHeader = ({
6
- icon,
7
- title,
8
- subtitle,
9
- breadcrumb,
10
- actions
11
- }) => {
12
- return /* @__PURE__ */ jsxs(
13
- "div",
14
- {
15
- style: {
16
- display: "flex",
17
- justifyContent: "space-between",
18
- alignItems: "flex-start",
19
- marginBottom: 20
20
- },
21
- children: [
22
- /* @__PURE__ */ jsxs("div", { children: [
23
- breadcrumb && /* @__PURE__ */ jsx("div", { style: { marginBottom: 6 }, children: /* @__PURE__ */ jsxs(
24
- "a",
25
- {
26
- href: breadcrumb.href,
27
- style: {
28
- fontSize: 12,
29
- fontWeight: 700,
30
- color: V.cyan,
31
- textDecoration: "none",
32
- textTransform: "uppercase"
33
- },
34
- children: [
35
- "\u2190 ",
36
- breadcrumb.label
37
- ]
38
- }
39
- ) }),
40
- /* @__PURE__ */ jsxs(
41
- "h1",
42
- {
43
- style: {
44
- fontSize: 28,
45
- fontWeight: 600,
46
- letterSpacing: 0,
47
- margin: 0,
48
- color: V.text,
49
- display: "flex",
50
- alignItems: "center",
51
- gap: 10
52
- },
53
- children: [
54
- /* @__PURE__ */ jsx("span", { style: { color: V.cyan, display: "flex", alignItems: "center" }, children: icon }),
55
- title
56
- ]
57
- }
58
- ),
59
- subtitle && /* @__PURE__ */ jsx("p", { style: { color: V.textSecondary, margin: "4px 0 0", fontSize: 14 }, children: subtitle })
60
- ] }),
61
- actions && /* @__PURE__ */ jsx("div", { style: { display: "flex", gap: 8 }, children: actions })
62
- ]
63
- }
64
- );
65
- };
66
-
67
- export { AdminViewHeader };
@@ -1,50 +0,0 @@
1
- "use client";
2
- import { jsxs, jsx } from 'react/jsx-runtime';
3
- import React from 'react';
4
-
5
- class AdminErrorBoundary extends React.Component {
6
- constructor(props) {
7
- super(props);
8
- this.state = { hasError: false, error: null };
9
- }
10
- static getDerivedStateFromError(error) {
11
- return { hasError: true, error };
12
- }
13
- componentDidCatch(error, errorInfo) {
14
- console.error(`[${this.props.viewName || "AdminView"}] Error:`, error, errorInfo);
15
- }
16
- render() {
17
- if (this.state.hasError) {
18
- if (this.props.fallback) {
19
- return this.props.fallback;
20
- }
21
- return /* @__PURE__ */ jsxs("div", { style: {
22
- padding: "40px",
23
- textAlign: "center",
24
- color: "#dc2626"
25
- }, children: [
26
- /* @__PURE__ */ jsx("h2", { style: { marginBottom: "16px", fontSize: "18px" }, children: "Une erreur est survenue" }),
27
- /* @__PURE__ */ jsx("p", { style: { marginBottom: "24px", color: "#6b7280", fontSize: "14px" }, children: this.state.error?.message || "Erreur inattendue" }),
28
- /* @__PURE__ */ jsx(
29
- "button",
30
- {
31
- onClick: () => this.setState({ hasError: false, error: null }),
32
- style: {
33
- padding: "8px 20px",
34
- backgroundColor: "#2563eb",
35
- color: "#fff",
36
- border: "none",
37
- borderRadius: "6px",
38
- cursor: "pointer",
39
- fontSize: "14px"
40
- },
41
- children: "Reessayer"
42
- }
43
- )
44
- ] });
45
- }
46
- return this.props.children;
47
- }
48
- }
49
-
50
- export { AdminErrorBoundary };
@@ -1,72 +0,0 @@
1
- "use client";
2
- import { jsx, jsxs } from 'react/jsx-runtime';
3
- import { useEffect } from 'react';
4
-
5
- const styleId = "skeleton-shimmer-style";
6
- function injectSkeletonStyles() {
7
- if (typeof document === "undefined") return;
8
- if (document.getElementById(styleId)) return;
9
- const style = document.createElement("style");
10
- style.id = styleId;
11
- style.textContent = `
12
- @keyframes skeleton-shimmer {
13
- 0% { background-position: 200% 0; }
14
- 100% { background-position: -200% 0; }
15
- }
16
- `;
17
- document.head.appendChild(style);
18
- }
19
- function Skeleton({ width = "100%", height = "20px", borderRadius = "4px", style }) {
20
- useEffect(() => {
21
- injectSkeletonStyles();
22
- }, []);
23
- return /* @__PURE__ */ jsx(
24
- "div",
25
- {
26
- style: {
27
- width,
28
- height,
29
- borderRadius,
30
- background: "linear-gradient(90deg, #e5e7eb 25%, #f3f4f6 50%, #e5e7eb 75%)",
31
- backgroundSize: "200% 100%",
32
- animation: "skeleton-shimmer 1.5s infinite",
33
- ...style
34
- }
35
- }
36
- );
37
- }
38
- function SkeletonText({ lines = 3, width = "100%" }) {
39
- return /* @__PURE__ */ jsx("div", { style: { display: "flex", flexDirection: "column", gap: "8px", width }, children: Array.from({ length: lines }).map((_, i) => /* @__PURE__ */ jsx(Skeleton, { height: "16px", width: i === lines - 1 ? "60%" : "100%" }, i)) });
40
- }
41
- function SkeletonCard({ height = "200px" }) {
42
- return /* @__PURE__ */ jsxs("div", { style: {
43
- border: "1px solid #e5e7eb",
44
- borderRadius: "8px",
45
- padding: "20px",
46
- display: "flex",
47
- flexDirection: "column",
48
- gap: "12px",
49
- minHeight: height
50
- }, children: [
51
- /* @__PURE__ */ jsx(Skeleton, { height: "24px", width: "40%" }),
52
- /* @__PURE__ */ jsx(SkeletonText, { lines: 3 }),
53
- /* @__PURE__ */ jsx(Skeleton, { height: "32px", width: "120px", borderRadius: "6px" })
54
- ] });
55
- }
56
- function SkeletonTable({ rows = 5, columns = 4 }) {
57
- return /* @__PURE__ */ jsxs("div", { style: { width: "100%" }, children: [
58
- /* @__PURE__ */ jsx("div", { style: { display: "flex", gap: "16px", padding: "12px 0", borderBottom: "2px solid #e5e7eb" }, children: Array.from({ length: columns }).map((_, i) => /* @__PURE__ */ jsx(Skeleton, { height: "16px", width: `${100 / columns}%` }, i)) }),
59
- Array.from({ length: rows }).map((_, rowIdx) => /* @__PURE__ */ jsx("div", { style: { display: "flex", gap: "16px", padding: "12px 0", borderBottom: "1px solid #f3f4f6" }, children: Array.from({ length: columns }).map((_2, colIdx) => /* @__PURE__ */ jsx(Skeleton, { height: "14px", width: `${100 / columns}%` }, colIdx)) }, rowIdx))
60
- ] });
61
- }
62
- function SkeletonDashboard() {
63
- return /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "24px", padding: "20px 0" }, children: [
64
- /* @__PURE__ */ jsx("div", { style: { display: "grid", gridTemplateColumns: "repeat(auto-fit, minmax(200px, 1fr))", gap: "16px" }, children: Array.from({ length: 4 }).map((_, i) => /* @__PURE__ */ jsxs("div", { style: { padding: "20px", border: "1px solid #e5e7eb", borderRadius: "8px" }, children: [
65
- /* @__PURE__ */ jsx(Skeleton, { height: "14px", width: "60%", style: { marginBottom: "8px" } }),
66
- /* @__PURE__ */ jsx(Skeleton, { height: "32px", width: "40%" })
67
- ] }, i)) }),
68
- /* @__PURE__ */ jsx(SkeletonTable, { rows: 5, columns: 4 })
69
- ] });
70
- }
71
-
72
- export { Skeleton, SkeletonCard, SkeletonDashboard, SkeletonTable, SkeletonText };
@@ -1,32 +0,0 @@
1
- "use client";
2
- const V = {
3
- text: "var(--theme-text)",
4
- textSecondary: "var(--theme-elevation-500)",
5
- bg: "var(--theme-elevation-50)",
6
- bgCard: "var(--theme-elevation-100)",
7
- border: "var(--theme-elevation-300)",
8
- // Professional palette
9
- blue: "#2563eb",
10
- amber: "#d97706",
11
- orange: "#ea580c",
12
- green: "#16a34a",
13
- red: "#dc2626",
14
- // Legacy aliases (backward compat for views not yet updated)
15
- cyan: "#2563eb",
16
- yellow: "#d97706"
17
- };
18
- const btnStyle = (bg, opts) => ({
19
- padding: opts?.small ? "6px 12px" : "8px 14px",
20
- borderRadius: 6,
21
- border: `1px solid var(--theme-elevation-300)`,
22
- backgroundColor: bg,
23
- color: "#fff",
24
- fontWeight: 600,
25
- fontSize: opts?.small ? 12 : 13,
26
- cursor: opts?.disabled ? "not-allowed" : "pointer",
27
- opacity: opts?.disabled ? 0.5 : 1,
28
- textDecoration: "none",
29
- whiteSpace: "nowrap"
30
- });
31
-
32
- export { V, btnStyle };
@@ -1,41 +0,0 @@
1
- "use client";
2
- const DEFAULT_FEATURES = {
3
- timeTracking: true,
4
- ai: true,
5
- satisfaction: true,
6
- chat: true,
7
- emailTracking: true,
8
- canned: true,
9
- merge: true,
10
- snooze: true,
11
- externalMessages: true,
12
- clientHistory: true,
13
- activityLog: true,
14
- splitTicket: true,
15
- scheduledReplies: true,
16
- autoClose: true,
17
- autoCloseDays: 7,
18
- roundRobin: false
19
- };
20
- const STORAGE_KEY = "ticketing_features";
21
- function getFeatures() {
22
- if (typeof window === "undefined") return DEFAULT_FEATURES;
23
- try {
24
- const stored = localStorage.getItem(STORAGE_KEY);
25
- if (stored) {
26
- const parsed = JSON.parse(stored);
27
- return { ...DEFAULT_FEATURES, ...parsed };
28
- }
29
- } catch {
30
- }
31
- return DEFAULT_FEATURES;
32
- }
33
- function saveFeatures(features) {
34
- if (typeof window === "undefined") return;
35
- try {
36
- localStorage.setItem(STORAGE_KEY, JSON.stringify(features));
37
- } catch {
38
- }
39
- }
40
-
41
- export { DEFAULT_FEATURES, getFeatures, saveFeatures };
@@ -1,6 +0,0 @@
1
- "use client";
2
- export { AdminErrorBoundary } from './ErrorBoundary';
3
- export { V, btnStyle } from './adminTokens';
4
- export { AdminViewHeader } from './AdminViewHeader';
5
- export { Skeleton, SkeletonCard, SkeletonDashboard, SkeletonTable, SkeletonText } from './Skeleton';
6
- export { DEFAULT_FEATURES, getFeatures, saveFeatures } from './config';