@consilioweb/payload-support 0.6.0 → 0.6.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. package/dist/{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/BillingView/client.cjs +209 -0
  6. package/dist/views/BillingView/index.cjs +34 -0
  7. package/dist/views/ChatView/client.cjs +253 -0
  8. package/dist/views/ChatView/index.cjs +34 -0
  9. package/dist/views/CrmView/client.cjs +233 -0
  10. package/dist/views/CrmView/index.cjs +34 -0
  11. package/dist/views/EmailTrackingView/client.cjs +159 -0
  12. package/dist/views/EmailTrackingView/index.cjs +34 -0
  13. package/dist/views/ImportConversationView/client.cjs +205 -0
  14. package/dist/views/ImportConversationView/index.cjs +34 -0
  15. package/dist/views/LogsView/client.cjs +149 -0
  16. package/dist/views/LogsView/index.cjs +32 -0
  17. package/dist/views/NewTicketView/client.cjs +229 -0
  18. package/dist/views/NewTicketView/index.cjs +32 -0
  19. package/dist/views/PendingEmailsView/client.cjs +173 -0
  20. package/dist/views/PendingEmailsView/index.cjs +34 -0
  21. package/dist/views/SupportDashboardView/client.cjs +301 -0
  22. package/dist/views/SupportDashboardView/index.cjs +34 -0
  23. package/dist/views/TicketDetailView/client.cjs +850 -0
  24. package/dist/views/TicketDetailView/index.cjs +34 -0
  25. package/dist/views/TicketInboxView/client.cjs +299 -0
  26. package/dist/views/TicketInboxView/index.cjs +32 -0
  27. package/dist/views/TicketingSettingsView/client.cjs +733 -0
  28. package/dist/views/TicketingSettingsView/index.cjs +34 -0
  29. package/dist/views/TimeDashboardView/client.cjs +169 -0
  30. package/dist/views/TimeDashboardView/index.cjs +34 -0
  31. package/dist/views/shared/AdminViewHeader.cjs +68 -0
  32. package/dist/views/shared/ErrorBoundary.cjs +55 -0
  33. package/dist/views/shared/Skeleton.cjs +77 -0
  34. package/dist/views/shared/adminTokens.cjs +34 -0
  35. package/dist/views/shared/adminTokens.js +0 -1
  36. package/dist/{components/TicketConversation/config.js → views/shared/config.cjs} +5 -2
  37. package/dist/views/shared/config.js +0 -1
  38. package/dist/views/shared/index.cjs +58 -0
  39. package/dist/views/shared/index.js +0 -1
  40. package/dist/views.cjs +86 -0
  41. package/dist/views.d.cts +13 -0
  42. package/dist/views.d.ts +13 -0
  43. package/dist/views.js +13 -0
  44. package/package.json +14 -7
  45. package/src/plugin.ts +11 -11
  46. package/src/views.ts +17 -0
  47. package/dist/components/TicketConversation/components/AISummaryPanel.js +0 -76
  48. package/dist/components/TicketConversation/components/ActionPanels.js +0 -118
  49. package/dist/components/TicketConversation/components/ActivityLog.js +0 -23
  50. package/dist/components/TicketConversation/components/ClientBar.js +0 -42
  51. package/dist/components/TicketConversation/components/ClientHistory.js +0 -137
  52. package/dist/components/TicketConversation/components/CodeBlock.js +0 -152
  53. package/dist/components/TicketConversation/components/CodeBlockInserter.js +0 -155
  54. package/dist/components/TicketConversation/components/QuickActions.js +0 -65
  55. package/dist/components/TicketConversation/components/TicketHeader.js +0 -92
  56. package/dist/components/TicketConversation/components/TimeTrackingPanel.js +0 -133
  57. package/dist/components/TicketConversation/constants.js +0 -96
  58. package/dist/components/TicketConversation/context.js +0 -11
  59. package/dist/components/TicketConversation/hooks/useAI.js +0 -176
  60. package/dist/components/TicketConversation/hooks/useMessageActions.js +0 -135
  61. package/dist/components/TicketConversation/hooks/useReply.js +0 -187
  62. package/dist/components/TicketConversation/hooks/useTicketActions.js +0 -230
  63. package/dist/components/TicketConversation/hooks/useTimeTracking.js +0 -122
  64. package/dist/components/TicketConversation/hooks/useTranslation.js +0 -70
  65. package/dist/components/TicketConversation/index.js +0 -1123
  66. package/dist/components/TicketConversation/locales/en.json +0 -878
  67. package/dist/components/TicketConversation/locales/fr.json +0 -878
  68. package/dist/components/TicketConversation/types.js +0 -2
  69. package/dist/components/TicketConversation/utils.js +0 -25
  70. package/dist/styles/BillingView.module.scss +0 -311
  71. package/dist/styles/ChatView.module.scss +0 -438
  72. package/dist/styles/CommandPalette.module.scss +0 -160
  73. package/dist/styles/CrmView.module.scss +0 -554
  74. package/dist/styles/EmailTracking.module.scss +0 -238
  75. package/dist/styles/ImportConversation.module.scss +0 -267
  76. package/dist/styles/Layout.module.scss +0 -55
  77. package/dist/styles/Logs.module.scss +0 -164
  78. package/dist/styles/NewTicket.module.scss +0 -143
  79. package/dist/styles/PendingEmails.module.scss +0 -629
  80. package/dist/styles/SupportDashboard.module.scss +0 -649
  81. package/dist/styles/TicketDetail.module.scss +0 -1050
  82. package/dist/styles/TicketInbox.module.scss +0 -296
  83. package/dist/styles/TicketingSettings.module.scss +0 -358
  84. package/dist/styles/TimeDashboard.module.scss +0 -287
  85. package/dist/styles/_tokens.scss +0 -78
@@ -1,152 +0,0 @@
1
- "use client";
2
- import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
3
- import { useState } from 'react';
4
-
5
- const LANG_CONFIG = {
6
- javascript: { label: "JavaScript", accent: "#f7df1e" },
7
- js: { label: "JavaScript", accent: "#f7df1e" },
8
- typescript: { label: "TypeScript", accent: "#3178c6" },
9
- ts: { label: "TypeScript", accent: "#3178c6" },
10
- tsx: { label: "TSX", accent: "#3178c6" },
11
- jsx: { label: "JSX", accent: "#f7df1e" },
12
- php: { label: "PHP", accent: "#777bb4" },
13
- python: { label: "Python", accent: "#3776ab" },
14
- py: { label: "Python", accent: "#3776ab" },
15
- html: { label: "HTML", accent: "#e34f26" },
16
- css: { label: "CSS", accent: "#1572b6" },
17
- scss: { label: "SCSS", accent: "#cc6699" },
18
- json: { label: "JSON", accent: "#292929" },
19
- sql: { label: "SQL", accent: "#e48e00" },
20
- bash: { label: "Bash", accent: "#4eaa25" },
21
- sh: { label: "Shell", accent: "#4eaa25" },
22
- yaml: { label: "YAML", accent: "#cb171e" },
23
- yml: { label: "YAML", accent: "#cb171e" },
24
- xml: { label: "XML", accent: "#f16529" },
25
- markdown: { label: "Markdown", accent: "#083fa1" },
26
- md: { label: "Markdown", accent: "#083fa1" },
27
- diff: { label: "Diff", accent: "#41b883" },
28
- go: { label: "Go", accent: "#00add8" },
29
- rust: { label: "Rust", accent: "#dea584" },
30
- java: { label: "Java", accent: "#ed8b00" },
31
- c: { label: "C", accent: "#555555" },
32
- cpp: { label: "C++", accent: "#00599c" },
33
- ruby: { label: "Ruby", accent: "#cc342d" },
34
- swift: { label: "Swift", accent: "#f05138" },
35
- nginx: { label: "Nginx", accent: "#009639" },
36
- docker: { label: "Docker", accent: "#2496ed" },
37
- dockerfile: { label: "Dockerfile", accent: "#2496ed" },
38
- env: { label: ".env", accent: "#ecd53f" }
39
- };
40
- const DEFAULT_CONFIG = { label: "Code", accent: "#6b7280" };
41
- function SingleCodeBlock({ lang, code }) {
42
- const [copied, setCopied] = useState(false);
43
- const config = LANG_CONFIG[lang.toLowerCase()] || (lang ? { label: lang.toUpperCase(), accent: "#6b7280" } : DEFAULT_CONFIG);
44
- const handleCopy = () => {
45
- navigator.clipboard.writeText(code);
46
- setCopied(true);
47
- setTimeout(() => setCopied(false), 1500);
48
- };
49
- const lines = code.split("\n");
50
- return /* @__PURE__ */ jsxs("div", { style: {
51
- marginTop: 8,
52
- marginBottom: 8,
53
- borderRadius: 8,
54
- overflow: "hidden",
55
- border: "1px solid #334155",
56
- backgroundColor: "#0f172a",
57
- fontSize: 13
58
- }, children: [
59
- /* @__PURE__ */ jsxs("div", { style: {
60
- display: "flex",
61
- alignItems: "center",
62
- justifyContent: "space-between",
63
- padding: "6px 12px",
64
- backgroundColor: "#1e293b",
65
- borderBottom: "1px solid #334155"
66
- }, children: [
67
- /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: 8 }, children: [
68
- /* @__PURE__ */ jsx("span", { style: {
69
- display: "inline-block",
70
- width: 8,
71
- height: 8,
72
- borderRadius: "50%",
73
- backgroundColor: config.accent,
74
- flexShrink: 0
75
- } }),
76
- /* @__PURE__ */ jsx("span", { style: {
77
- fontSize: 11,
78
- fontWeight: 700,
79
- color: "#e2e8f0",
80
- letterSpacing: "0.02em"
81
- }, children: config.label })
82
- ] }),
83
- /* @__PURE__ */ jsx(
84
- "button",
85
- {
86
- onClick: handleCopy,
87
- style: {
88
- background: "none",
89
- border: "1px solid #475569",
90
- borderRadius: 4,
91
- padding: "2px 10px",
92
- fontSize: 11,
93
- color: copied ? "#4ade80" : "#94a3b8",
94
- cursor: "pointer",
95
- fontWeight: 600,
96
- transition: "color 150ms"
97
- },
98
- children: copied ? "Copi\xE9 !" : "Copier"
99
- }
100
- )
101
- ] }),
102
- /* @__PURE__ */ jsxs("div", { style: { display: "flex", overflowX: "auto" }, children: [
103
- /* @__PURE__ */ jsx("div", { style: {
104
- padding: "12px 0",
105
- borderRight: "1px solid #334155",
106
- userSelect: "none",
107
- flexShrink: 0
108
- }, children: lines.map((_, i) => /* @__PURE__ */ jsx("div", { style: {
109
- padding: "0 12px",
110
- fontSize: 12,
111
- lineHeight: "20px",
112
- color: "#475569",
113
- textAlign: "right",
114
- fontFamily: '"SF Mono", "Fira Code", "JetBrains Mono", monospace'
115
- }, children: i + 1 }, i)) }),
116
- /* @__PURE__ */ jsx("pre", { style: {
117
- margin: 0,
118
- padding: 12,
119
- overflow: "auto",
120
- flex: 1
121
- }, children: /* @__PURE__ */ jsx("code", { style: {
122
- fontSize: 12,
123
- lineHeight: "20px",
124
- fontFamily: '"SF Mono", "Fira Code", "JetBrains Mono", monospace',
125
- color: "#e2e8f0",
126
- whiteSpace: "pre"
127
- }, children: code }) })
128
- ] })
129
- ] });
130
- }
131
- function CodeBlockRenderer({ text }) {
132
- const parts = text.split(/(```[\s\S]*?```)/g);
133
- const hasCodeBlock = parts.some((p) => p.startsWith("```"));
134
- if (!hasCodeBlock) return null;
135
- return /* @__PURE__ */ jsx(Fragment, { children: parts.map((part, i) => {
136
- if (part.startsWith("```")) {
137
- const match = part.match(/^```(\w*)\n?([\s\S]*?)```$/);
138
- if (match) {
139
- const lang = match[1] || "";
140
- const code = match[2].replace(/\n$/, "");
141
- return /* @__PURE__ */ jsx(SingleCodeBlock, { lang, code }, i);
142
- }
143
- }
144
- return null;
145
- }) });
146
- }
147
- function CodeBlockRendererHtml({ html }) {
148
- const stripped = html.replace(/<[^>]+>/g, "");
149
- return /* @__PURE__ */ jsx(CodeBlockRenderer, { text: stripped });
150
- }
151
-
152
- export { CodeBlockRenderer, CodeBlockRendererHtml };
@@ -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 };