@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,155 +0,0 @@
1
- "use client";
2
- import { jsxs, jsx } from 'react/jsx-runtime';
3
- import { useState, useRef, useEffect } from 'react';
4
-
5
- const LANGUAGES = [
6
- { value: "javascript", label: "JavaScript" },
7
- { value: "typescript", label: "TypeScript" },
8
- { value: "php", label: "PHP" },
9
- { value: "python", label: "Python" },
10
- { value: "html", label: "HTML" },
11
- { value: "css", label: "CSS" },
12
- { value: "scss", label: "SCSS" },
13
- { value: "json", label: "JSON" },
14
- { value: "sql", label: "SQL" },
15
- { value: "bash", label: "Bash" },
16
- { value: "yaml", label: "YAML" },
17
- { value: "xml", label: "XML" },
18
- { value: "markdown", label: "Markdown" },
19
- { value: "diff", label: "Diff" },
20
- { value: "go", label: "Go" },
21
- { value: "rust", label: "Rust" },
22
- { value: "java", label: "Java" },
23
- { value: "ruby", label: "Ruby" },
24
- { value: "swift", label: "Swift" },
25
- { value: "docker", label: "Dockerfile" },
26
- { value: "nginx", label: "Nginx" },
27
- { value: "env", label: ".env" }
28
- ];
29
- function CodeBlockInserter({ onInsert, className, style }) {
30
- const [open, setOpen] = useState(false);
31
- const [filter, setFilter] = useState("");
32
- const dropdownRef = useRef(null);
33
- const inputRef = useRef(null);
34
- useEffect(() => {
35
- if (open && inputRef.current) inputRef.current.focus();
36
- }, [open]);
37
- useEffect(() => {
38
- const handleClickOutside = (e) => {
39
- if (dropdownRef.current && !dropdownRef.current.contains(e.target)) {
40
- setOpen(false);
41
- setFilter("");
42
- }
43
- };
44
- if (open) document.addEventListener("mousedown", handleClickOutside);
45
- return () => document.removeEventListener("mousedown", handleClickOutside);
46
- }, [open]);
47
- const filtered = filter ? LANGUAGES.filter((l) => l.label.toLowerCase().includes(filter.toLowerCase()) || l.value.includes(filter.toLowerCase())) : LANGUAGES;
48
- const handleSelect = (lang) => {
49
- onInsert(`
50
- \`\`\`${lang}
51
-
52
- \`\`\`
53
- `);
54
- setOpen(false);
55
- setFilter("");
56
- };
57
- return /* @__PURE__ */ jsxs("div", { ref: dropdownRef, style: { position: "relative", display: "inline-block" }, children: [
58
- /* @__PURE__ */ jsx(
59
- "button",
60
- {
61
- onClick: () => setOpen(!open),
62
- className,
63
- style: {
64
- fontSize: 11,
65
- fontWeight: 700,
66
- padding: "4px 10px",
67
- width: "auto",
68
- cursor: "pointer",
69
- ...style
70
- },
71
- type: "button",
72
- "aria-label": "Ins\xE9rer un bloc de code",
73
- "data-tooltip": "Bloc de code",
74
- children: "</> Code"
75
- }
76
- ),
77
- open && /* @__PURE__ */ jsxs("div", { style: {
78
- position: "absolute",
79
- bottom: "100%",
80
- left: 0,
81
- marginBottom: 4,
82
- width: 200,
83
- maxHeight: 280,
84
- backgroundColor: "#1e293b",
85
- border: "1px solid #334155",
86
- borderRadius: 8,
87
- boxShadow: "0 8px 24px rgba(0,0,0,0.4)",
88
- zIndex: 1e3,
89
- overflow: "hidden",
90
- display: "flex",
91
- flexDirection: "column"
92
- }, children: [
93
- /* @__PURE__ */ jsx("div", { style: { padding: "8px 8px 4px" }, children: /* @__PURE__ */ jsx(
94
- "input",
95
- {
96
- ref: inputRef,
97
- type: "text",
98
- value: filter,
99
- onChange: (e) => setFilter(e.target.value),
100
- onKeyDown: (e) => {
101
- if (e.key === "Escape") {
102
- setOpen(false);
103
- setFilter("");
104
- }
105
- if (e.key === "Enter" && filtered.length > 0) handleSelect(filtered[0].value);
106
- },
107
- placeholder: "Rechercher...",
108
- style: {
109
- width: "100%",
110
- padding: "6px 10px",
111
- fontSize: 12,
112
- backgroundColor: "#0f172a",
113
- border: "1px solid #334155",
114
- borderRadius: 6,
115
- color: "#e2e8f0",
116
- outline: "none",
117
- boxSizing: "border-box"
118
- }
119
- }
120
- ) }),
121
- /* @__PURE__ */ jsxs("div", { style: { overflowY: "auto", maxHeight: 230, padding: "4px 0" }, children: [
122
- filtered.map((lang) => /* @__PURE__ */ jsx(
123
- "button",
124
- {
125
- onClick: () => handleSelect(lang.value),
126
- style: {
127
- display: "block",
128
- width: "100%",
129
- padding: "6px 12px",
130
- fontSize: 12,
131
- fontWeight: 500,
132
- color: "#e2e8f0",
133
- backgroundColor: "transparent",
134
- border: "none",
135
- cursor: "pointer",
136
- textAlign: "left"
137
- },
138
- onMouseEnter: (e) => {
139
- e.target.style.backgroundColor = "#334155";
140
- },
141
- onMouseLeave: (e) => {
142
- e.target.style.backgroundColor = "transparent";
143
- },
144
- type: "button",
145
- children: lang.label
146
- },
147
- lang.value
148
- )),
149
- filtered.length === 0 && /* @__PURE__ */ jsx("div", { style: { padding: "12px", fontSize: 12, color: "#64748b", textAlign: "center" }, children: "Aucun langage trouv\xE9" })
150
- ] })
151
- ] })
152
- ] });
153
- }
154
-
155
- export { CodeBlockInserter };
@@ -1,65 +0,0 @@
1
- "use client";
2
- import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
3
- import { s, C } from '../constants';
4
-
5
- function QuickActions({
6
- statusTransitions,
7
- statusUpdating,
8
- onStatusChange,
9
- snoozeUntil,
10
- snoozeSaving,
11
- onCancelSnooze,
12
- showMerge: _showMerge,
13
- showExtMsg: _showExtMsg,
14
- showSnooze: _showSnooze,
15
- onToggleMerge,
16
- onToggleExtMsg,
17
- onToggleSnooze,
18
- onNextTicket,
19
- showNextTicket,
20
- nextTicketId,
21
- nextTicketInfo,
22
- onCloseNextTicket
23
- }) {
24
- return /* @__PURE__ */ jsxs(Fragment, { children: [
25
- /* @__PURE__ */ jsxs("div", { style: { display: "flex", gap: "8px", flexWrap: "wrap", marginBottom: "16px", alignItems: "center" }, children: [
26
- statusTransitions.map((a) => /* @__PURE__ */ jsx(
27
- "button",
28
- {
29
- onClick: () => onStatusChange(a.status),
30
- disabled: statusUpdating,
31
- style: s.outlineBtn(a.color, statusUpdating),
32
- children: a.label
33
- },
34
- a.status
35
- )),
36
- snoozeUntil && new Date(snoozeUntil) > /* @__PURE__ */ new Date() && /* @__PURE__ */ jsx("button", { onClick: onCancelSnooze, disabled: snoozeSaving, style: { ...s.ghostBtn("#7c3aed", snoozeSaving), fontSize: "12px", padding: "5px 10px" }, children: "Annuler snooze" }),
37
- /* @__PURE__ */ jsx("span", { style: { borderLeft: `1px solid ${C.border}`, height: "20px", margin: "0 4px" } }),
38
- /* @__PURE__ */ jsx("button", { onClick: onToggleMerge, style: s.ghostBtn("#be185d"), children: "Fusionner" }),
39
- /* @__PURE__ */ jsx("button", { onClick: onToggleExtMsg, style: s.ghostBtn("#4f46e5"), children: "+ Message re\xE7u" }),
40
- /* @__PURE__ */ jsx("button", { onClick: onToggleSnooze, style: s.ghostBtn("#7c3aed"), children: "Snooze" }),
41
- /* @__PURE__ */ jsx("button", { onClick: onNextTicket, style: s.ghostBtn("#16a34a"), children: "Ticket suivant" })
42
- ] }),
43
- showNextTicket && /* @__PURE__ */ jsxs("div", { style: { padding: "10px 14px", borderRadius: "8px", backgroundColor: "#f0fdf4", border: `1px solid ${C.border}`, marginBottom: "14px", display: "flex", alignItems: "center", justifyContent: "space-between" }, children: [
44
- nextTicketId ? /* @__PURE__ */ jsxs(Fragment, { children: [
45
- /* @__PURE__ */ jsxs("span", { style: { fontSize: "13px", color: "#166534", fontWeight: 600 }, children: [
46
- "Ticket suivant : ",
47
- /* @__PURE__ */ jsx("strong", { children: nextTicketInfo })
48
- ] }),
49
- /* @__PURE__ */ jsx(
50
- "button",
51
- {
52
- onClick: () => {
53
- window.location.href = `/admin/support/ticket?id=${nextTicketId}`;
54
- },
55
- style: { ...s.btn(C.statusResolved), color: C.white, fontSize: "12px", padding: "5px 14px" },
56
- children: "Ouvrir"
57
- }
58
- )
59
- ] }) : /* @__PURE__ */ jsx("span", { style: { fontSize: "13px", color: "#166534", fontWeight: 700 }, children: nextTicketInfo }),
60
- /* @__PURE__ */ jsx("button", { onClick: onCloseNextTicket, style: { border: "none", background: "none", color: C.textMuted, cursor: "pointer", fontSize: "16px", fontWeight: 700, marginLeft: "8px" }, children: "\xD7" })
61
- ] })
62
- ] });
63
- }
64
-
65
- export { QuickActions };
@@ -1,92 +0,0 @@
1
- "use client";
2
- import { jsxs, jsx } from 'react/jsx-runtime';
3
- import { C, statusLabels, s } from '../constants';
4
-
5
- const sourceLabels = {
6
- email: "Email",
7
- "live-chat": "Live Chat",
8
- portal: "Portail",
9
- admin: "Admin"
10
- };
11
- function TicketHeader({
12
- ticketNumber,
13
- currentStatus,
14
- clientSentiment,
15
- ticketSource,
16
- chatSession,
17
- snoozeUntil,
18
- satisfaction,
19
- copiedLink,
20
- onCopyLink
21
- }) {
22
- return /* @__PURE__ */ jsxs("div", { style: {
23
- display: "flex",
24
- alignItems: "center",
25
- gap: "10px",
26
- padding: "10px 14px",
27
- borderRadius: "8px",
28
- backgroundColor: "var(--theme-elevation-100)",
29
- marginBottom: "12px",
30
- flexWrap: "wrap"
31
- }, children: [
32
- ticketNumber && /* @__PURE__ */ jsx("span", { style: { fontFamily: "'SF Mono', 'Fira Code', 'JetBrains Mono', 'Cascadia Code', monospace", fontWeight: 700, fontSize: "14px", color: C.textPrimary }, children: ticketNumber }),
33
- currentStatus && (() => {
34
- const st = statusLabels[currentStatus] || statusLabels.open;
35
- return /* @__PURE__ */ jsx("span", { style: s.badge(st.bg, st.color), children: st.label });
36
- })(),
37
- clientSentiment && /* @__PURE__ */ jsxs(
38
- "span",
39
- {
40
- style: { ...s.badge(`${clientSentiment.color}15`, clientSentiment.color), fontSize: "11px" },
41
- title: `Sentiment : ${clientSentiment.label}`,
42
- children: [
43
- clientSentiment.emoji,
44
- " ",
45
- clientSentiment.label
46
- ]
47
- }
48
- ),
49
- ticketSource && ticketSource !== "portal" && /* @__PURE__ */ jsx("span", { style: s.badge("#f1f5f9", "#475569"), children: sourceLabels[ticketSource] || ticketSource }),
50
- chatSession && ticketSource === "live-chat" && /* @__PURE__ */ jsxs("span", { style: { fontSize: "11px", color: C.textMuted }, children: [
51
- "Session : ",
52
- chatSession.slice(0, 16),
53
- "..."
54
- ] }),
55
- snoozeUntil && new Date(snoozeUntil) > /* @__PURE__ */ new Date() && /* @__PURE__ */ jsxs("span", { style: s.badge("#f5f3ff", "#7c3aed"), children: [
56
- "Snooz\xE9 ",
57
- new Date(snoozeUntil).toLocaleDateString("fr-FR", { day: "numeric", month: "short", hour: "2-digit", minute: "2-digit" })
58
- ] }),
59
- satisfaction && /* @__PURE__ */ jsxs("span", { style: s.badge(
60
- satisfaction.rating >= 4 ? "#dcfce7" : satisfaction.rating >= 3 ? "#fef9c3" : "#fee2e2",
61
- satisfaction.rating >= 4 ? "#166534" : satisfaction.rating >= 3 ? "#854d0e" : "#991b1b"
62
- ), children: [
63
- Array.from({ length: 5 }, (_, i) => i < satisfaction.rating ? "\u2605" : "\u2606").join(""),
64
- " ",
65
- satisfaction.rating,
66
- "/5"
67
- ] }),
68
- /* @__PURE__ */ jsxs("span", { style: { marginLeft: "auto", display: "inline-flex", alignItems: "center", gap: "4px" }, children: [
69
- /* @__PURE__ */ jsx(
70
- "button",
71
- {
72
- onClick: () => onCopyLink("admin"),
73
- title: "Copier le lien admin",
74
- style: { background: "none", border: "none", cursor: "pointer", fontSize: "13px", opacity: copiedLink === "admin" ? 1 : 0.5, padding: "2px 4px" },
75
- children: copiedLink === "admin" ? "\u2705" : "\u{1F4CB}"
76
- }
77
- ),
78
- /* @__PURE__ */ jsx(
79
- "button",
80
- {
81
- onClick: () => onCopyLink("client"),
82
- title: "Copier le lien client",
83
- style: { background: "none", border: "none", cursor: "pointer", fontSize: "13px", opacity: copiedLink === "client" ? 1 : 0.5, padding: "2px 4px" },
84
- children: copiedLink === "client" ? "\u2705" : "\u{1F517}"
85
- }
86
- ),
87
- copiedLink && /* @__PURE__ */ jsx("span", { style: { fontSize: "11px", color: "#16a34a", fontWeight: 600 }, children: "Copi\xE9" })
88
- ] })
89
- ] });
90
- }
91
-
92
- export { TicketHeader };
@@ -1,133 +0,0 @@
1
- "use client";
2
- import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
3
- import { s, C } from '../constants';
4
-
5
- function TimeTrackingPanel({
6
- timeEntries,
7
- totalMinutes,
8
- timerRunning,
9
- timerSeconds,
10
- setTimerSeconds,
11
- timerDescription,
12
- setTimerDescription,
13
- handleTimerStart,
14
- handleTimerStop,
15
- handleTimerSave,
16
- handleTimerDiscard,
17
- duration,
18
- setDuration,
19
- timeDescription,
20
- setTimeDescription,
21
- handleAddTime,
22
- addingTime,
23
- timeSuccess
24
- }) {
25
- const totalH = Math.floor(totalMinutes / 60);
26
- const totalM = totalMinutes % 60;
27
- return /* @__PURE__ */ jsxs("div", { style: s.section, children: [
28
- /* @__PURE__ */ jsxs("h4", { style: s.sectionTitle, children: [
29
- "Temps",
30
- totalMinutes > 0 && /* @__PURE__ */ jsxs("span", { style: s.badge("#fef3c7", "#92400e"), children: [
31
- totalH,
32
- "h",
33
- String(totalM).padStart(2, "0"),
34
- " total"
35
- ] })
36
- ] }),
37
- /* @__PURE__ */ jsxs("div", { style: {
38
- display: "flex",
39
- alignItems: "center",
40
- gap: "10px",
41
- flexWrap: "wrap",
42
- padding: "12px 16px",
43
- borderRadius: "10px",
44
- marginBottom: "14px",
45
- backgroundColor: timerRunning ? "#fef2f2" : "var(--theme-elevation-100)",
46
- border: timerRunning ? "1px solid #fca5a5" : "1px solid var(--theme-elevation-300)"
47
- }, children: [
48
- /* @__PURE__ */ jsxs("div", { style: {
49
- fontFamily: "monospace",
50
- fontSize: "24px",
51
- fontWeight: 700,
52
- color: timerRunning ? "#dc2626" : "var(--theme-text)",
53
- minWidth: "90px"
54
- }, children: [
55
- String(Math.floor(timerSeconds / 3600)).padStart(2, "0"),
56
- ":",
57
- String(Math.floor(timerSeconds % 3600 / 60)).padStart(2, "0"),
58
- ":",
59
- String(timerSeconds % 60).padStart(2, "0")
60
- ] }),
61
- !timerRunning && timerSeconds > 0 && /* @__PURE__ */ jsx("div", { style: { display: "flex", alignItems: "center", gap: "4px" }, children: [-5, -1, 1, 5, 15, 30].map((m) => /* @__PURE__ */ jsx(
62
- "button",
63
- {
64
- onClick: () => setTimerSeconds((p) => Math.max(0, p + m * 60)),
65
- style: { width: Math.abs(m) >= 15 ? "32px" : "28px", height: "28px", borderRadius: "6px", border: "1px solid #e2e8f0", background: "white", cursor: "pointer", fontSize: Math.abs(m) >= 15 ? "12px" : "14px", fontWeight: 700, color: "#64748b" },
66
- title: `${m > 0 ? "+" : ""}${m} min`,
67
- children: m > 0 ? `+${m}` : String(m)
68
- },
69
- m
70
- )) }),
71
- !timerRunning && timerSeconds === 0 && /* @__PURE__ */ jsx("button", { onClick: () => handleTimerStart(true), style: { ...s.btn("#dc2626", false), fontSize: "12px", padding: "6px 16px", display: "flex", alignItems: "center", gap: "6px" }, children: "\u25B6 D\xE9marrer" }),
72
- timerRunning && /* @__PURE__ */ jsx("button", { onClick: handleTimerStop, style: { ...s.btn("#374151", false), fontSize: "12px", padding: "6px 16px", display: "flex", alignItems: "center", gap: "6px" }, children: "\u23F8 Pause" }),
73
- !timerRunning && timerSeconds > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
74
- /* @__PURE__ */ jsx("button", { onClick: () => handleTimerStart(false), style: { ...s.btn("#dc2626", false), fontSize: "12px", padding: "6px 14px" }, children: "\u25B6 Reprendre" }),
75
- /* @__PURE__ */ jsx(
76
- "input",
77
- {
78
- type: "text",
79
- value: timerDescription,
80
- onChange: (e) => setTimerDescription(e.target.value),
81
- placeholder: "Description...",
82
- style: { ...s.input, fontSize: "12px", flex: 1, minWidth: "120px" }
83
- }
84
- ),
85
- /* @__PURE__ */ jsxs(
86
- "button",
87
- {
88
- onClick: handleTimerSave,
89
- disabled: addingTime || timerSeconds < 60,
90
- style: { ...s.btn("#16a34a", addingTime || timerSeconds < 60), fontSize: "12px", padding: "6px 14px" },
91
- title: timerSeconds < 60 ? "Minimum 1 minute" : `Sauvegarder ${Math.round(timerSeconds / 60)} min`,
92
- children: [
93
- "\u{1F4BE} ",
94
- Math.round(timerSeconds / 60),
95
- " min"
96
- ]
97
- }
98
- ),
99
- /* @__PURE__ */ jsx("button", { onClick: handleTimerDiscard, style: { background: "none", border: "none", cursor: "pointer", fontSize: "14px", color: "#94a3b8", padding: "4px" }, title: "Annuler", children: "\u2715" })
100
- ] }),
101
- timerRunning && /* @__PURE__ */ jsx("span", { style: { fontSize: "11px", color: "#dc2626", fontWeight: 600 }, children: "\u25CF Enregistrement en cours \u2014 session maintenue active" })
102
- ] }),
103
- /* @__PURE__ */ jsxs("div", { style: { display: "flex", gap: "8px", alignItems: "flex-end", flexWrap: "wrap", marginBottom: "14px" }, children: [
104
- /* @__PURE__ */ jsxs("div", { children: [
105
- /* @__PURE__ */ jsx("label", { style: { display: "block", fontSize: "11px", color: C.textSecondary, marginBottom: "3px", fontWeight: 600 }, children: "Min" }),
106
- /* @__PURE__ */ jsx("input", { type: "number", min: "1", value: duration, onChange: (e) => setDuration(e.target.value), placeholder: "30", style: { ...s.input, width: "80px" } })
107
- ] }),
108
- /* @__PURE__ */ jsxs("div", { style: { flex: 1 }, children: [
109
- /* @__PURE__ */ jsx("label", { style: { display: "block", fontSize: "11px", color: C.textSecondary, marginBottom: "3px", fontWeight: 600 }, children: "Description" }),
110
- /* @__PURE__ */ jsx("input", { type: "text", value: timeDescription, onChange: (e) => setTimeDescription(e.target.value), placeholder: "Travail effectu\xE9...", style: { ...s.input, width: "100%" } })
111
- ] }),
112
- /* @__PURE__ */ jsx("button", { onClick: handleAddTime, disabled: addingTime || !duration, style: s.btn(C.amber, addingTime || !duration), children: addingTime ? "..." : "+ Temps" }),
113
- timeSuccess && /* @__PURE__ */ jsx("span", { style: { fontSize: "12px", color: "#16a34a", fontWeight: 600 }, children: timeSuccess })
114
- ] }),
115
- timeEntries.length > 0 && /* @__PURE__ */ jsx("div", { style: { fontSize: "12px" }, children: /* @__PURE__ */ jsxs("table", { style: { width: "100%", borderCollapse: "collapse" }, children: [
116
- /* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsxs("tr", { style: { borderBottom: `1px solid ${C.border}` }, children: [
117
- /* @__PURE__ */ jsx("th", { style: { textAlign: "left", padding: "6px 8px", fontWeight: 600, fontSize: "11px", color: C.textSecondary }, children: "Date" }),
118
- /* @__PURE__ */ jsx("th", { style: { textAlign: "left", padding: "6px 8px", fontWeight: 600, fontSize: "11px", color: C.textSecondary }, children: "Dur\xE9e" }),
119
- /* @__PURE__ */ jsx("th", { style: { textAlign: "left", padding: "6px 8px", fontWeight: 600, fontSize: "11px", color: C.textSecondary }, children: "Description" })
120
- ] }) }),
121
- /* @__PURE__ */ jsx("tbody", { children: timeEntries.map((entry) => /* @__PURE__ */ jsxs("tr", { style: { borderBottom: "1px solid #f1f5f9" }, children: [
122
- /* @__PURE__ */ jsx("td", { style: { padding: "6px 8px", color: "#374151" }, children: new Date(entry.date).toLocaleDateString("fr-FR", { day: "numeric", month: "short" }) }),
123
- /* @__PURE__ */ jsxs("td", { style: { padding: "6px 8px", fontWeight: 600, color: "#374151" }, children: [
124
- entry.duration,
125
- " min"
126
- ] }),
127
- /* @__PURE__ */ jsx("td", { style: { padding: "6px 8px", color: C.textSecondary }, children: entry.description || "\u2014" })
128
- ] }, entry.id)) })
129
- ] }) })
130
- ] });
131
- }
132
-
133
- export { TimeTrackingPanel };
@@ -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,96 +0,0 @@
1
- "use client";
2
- const statusLabels = {
3
- open: { label: "Ouvert", bg: "#dbeafe", color: "#1e40af" },
4
- waiting_client: { label: "Attente", bg: "#fef3c7", color: "#92400e" },
5
- resolved: { label: "R\xE9solu", bg: "#dcfce7", color: "#166534" }
6
- };
7
- const projectStatusLabels = {
8
- active: { label: "Actif", bg: "#dcfce7", color: "#166534" },
9
- paused: { label: "En pause", bg: "#fef3c7", color: "#92400e" },
10
- completed: { label: "Termin\xE9", bg: "#e5e7eb", color: "#374151" }
11
- };
12
- const C = {
13
- blue: "#2563eb",
14
- amber: "#d97706",
15
- orange: "#ea580c",
16
- black: "var(--theme-text)",
17
- white: "#fff",
18
- bg: "#fafafa",
19
- textPrimary: "var(--theme-text)",
20
- textSecondary: "#6b7280",
21
- textMuted: "#9ca3af",
22
- border: "#e2e8f0",
23
- statusOpen: "#2563eb",
24
- statusProgress: "#ea580c",
25
- statusWaiting: "#d97706",
26
- statusResolved: "#16a34a",
27
- statusClosed: "#6b7280",
28
- adminBg: "#f8fafc",
29
- adminBorder: "#2563eb",
30
- clientBg: "#fafafa",
31
- clientBorder: "#e2e8f0",
32
- emailBg: "#fffbeb",
33
- emailBorder: "#ea580c",
34
- internalBg: "#fefce8",
35
- internalBorder: "#d97706"
36
- };
37
- const s = {
38
- section: { borderTop: `1px solid ${C.border}`, paddingTop: "18px", marginTop: "20px" },
39
- sectionTitle: { fontSize: "14px", fontWeight: 600, marginBottom: "12px", display: "flex", alignItems: "center", gap: "8px" },
40
- btn: (bg, disabled) => {
41
- const hex = bg.replace("#", "");
42
- const r = parseInt(hex.substring(0, 2), 16) || 0;
43
- const g = parseInt(hex.substring(2, 4), 16) || 0;
44
- const b = parseInt(hex.substring(4, 6), 16) || 0;
45
- const luminance = (0.299 * r + 0.587 * g + 0.114 * b) / 255;
46
- const textColor = luminance > 0.6 ? "#374151" : C.white;
47
- return {
48
- padding: "7px 14px",
49
- borderRadius: "6px",
50
- border: `1px solid ${C.border}`,
51
- backgroundColor: bg,
52
- color: textColor,
53
- fontWeight: 600,
54
- fontSize: "13px",
55
- cursor: disabled ? "not-allowed" : "pointer",
56
- opacity: disabled ? 0.5 : 1,
57
- whiteSpace: "nowrap"
58
- };
59
- },
60
- ghostBtn: (color, disabled) => ({
61
- padding: "7px 14px",
62
- borderRadius: "6px",
63
- border: `1px solid ${C.border}`,
64
- backgroundColor: "transparent",
65
- color,
66
- fontWeight: 600,
67
- fontSize: "13px",
68
- cursor: disabled ? "not-allowed" : "pointer",
69
- opacity: disabled ? 0.5 : 1,
70
- whiteSpace: "nowrap"
71
- }),
72
- outlineBtn: (color, disabled) => ({
73
- padding: "7px 14px",
74
- borderRadius: "6px",
75
- border: `1px solid ${color}`,
76
- backgroundColor: "transparent",
77
- color,
78
- fontWeight: 600,
79
- fontSize: "13px",
80
- cursor: disabled ? "not-allowed" : "pointer",
81
- opacity: disabled ? 0.5 : 1,
82
- whiteSpace: "nowrap"
83
- }),
84
- input: { padding: "8px 12px", borderRadius: "6px", border: `1px solid ${C.border}`, fontSize: "14px", color: "#374151", backgroundColor: C.white },
85
- badge: (bg, color) => ({
86
- display: "inline-block",
87
- padding: "2px 8px",
88
- borderRadius: "4px",
89
- fontSize: "11px",
90
- fontWeight: 600,
91
- backgroundColor: bg,
92
- color
93
- })
94
- };
95
-
96
- export { C, projectStatusLabels, s, statusLabels };
@@ -1,11 +0,0 @@
1
- "use client";
2
- import { createContext, useContext } from 'react';
3
-
4
- const TicketContext = createContext(null);
5
- function useTicketContext() {
6
- const ctx = useContext(TicketContext);
7
- if (!ctx) throw new Error("useTicketContext must be used within TicketContext.Provider");
8
- return ctx;
9
- }
10
-
11
- export { TicketContext, useTicketContext };