@consilioweb/payload-support 2.0.0 → 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.
- package/README.md +656 -355
- package/dist/components/RichTextEditor/index.d.ts +19 -0
- package/dist/components/TicketConversation/RewriteDropdown.d.ts +6 -0
- package/dist/components/TicketConversation/SkeletonText.d.ts +4 -0
- package/dist/components/TicketConversation/components/AISummaryPanel.d.ts +14 -0
- package/dist/components/TicketConversation/components/ActionPanels.d.ts +47 -0
- package/dist/components/TicketConversation/components/ActivityLog.d.ts +5 -0
- package/dist/components/TicketConversation/components/ClientBar.d.ts +5 -0
- package/dist/components/TicketConversation/components/ClientHistory.d.ts +24 -0
- package/dist/components/TicketConversation/components/CodeBlock.d.ts +26 -0
- package/dist/components/TicketConversation/components/CodeBlockInserter.d.ts +12 -0
- package/dist/components/TicketConversation/components/QuickActions.d.ts +32 -0
- package/dist/components/TicketConversation/components/TicketHeader.d.ts +19 -0
- package/dist/components/TicketConversation/components/TimeTrackingPanel.d.ts +24 -0
- package/dist/components/TicketConversation/config.d.ts +10 -0
- package/dist/components/TicketConversation/config.js +1 -40
- package/dist/components/TicketConversation/constants.d.ts +56 -0
- package/dist/components/TicketConversation/context.d.ts +53 -0
- package/dist/components/TicketConversation/hooks/useAI.d.ts +21 -0
- package/dist/components/TicketConversation/hooks/useDocumentIdFromUrl.d.ts +3 -0
- package/dist/components/TicketConversation/hooks/useFeatures.d.ts +23 -0
- package/dist/components/TicketConversation/hooks/useFeatures.js +61 -0
- package/dist/components/TicketConversation/hooks/useMessageActions.d.ts +20 -0
- package/dist/components/TicketConversation/hooks/useReply.d.ts +27 -0
- package/dist/components/TicketConversation/hooks/useTicketActions.d.ts +58 -0
- package/dist/components/TicketConversation/hooks/useTimeTracking.d.ts +18 -0
- package/dist/components/TicketConversation/hooks/useTranslation.d.ts +33 -0
- package/dist/components/TicketConversation/hooks/useTranslation.js +22 -3
- package/dist/components/TicketConversation/index.d.ts +4 -0
- package/dist/components/TicketConversation/index.js +2 -2
- package/dist/components/TicketConversation/types.d.ts +56 -0
- package/dist/components/TicketConversation/utils.d.ts +2 -0
- package/dist/index.cjs +392 -320
- package/dist/index.d.cts +100 -3
- package/dist/index.d.ts +100 -3
- package/dist/index.js +388 -321
- package/dist/utils/features.d.ts +123 -0
- package/dist/utils/features.js +147 -0
- package/dist/views/BillingView/client.d.ts +2 -0
- package/dist/views/BillingView/index.d.ts +4 -0
- package/dist/views/ChatView/client.d.ts +2 -0
- package/dist/views/ChatView/client.js +9 -9
- package/dist/views/ChatView/index.d.ts +4 -0
- package/dist/views/CrmView/client.d.ts +2 -0
- package/dist/views/CrmView/client.js +6 -9
- package/dist/views/CrmView/index.d.ts +4 -0
- package/dist/views/EmailTrackingView/client.d.ts +2 -0
- package/dist/views/EmailTrackingView/index.d.ts +4 -0
- package/dist/views/ImportConversationView/client.d.ts +2 -0
- package/dist/views/ImportConversationView/index.d.ts +4 -0
- package/dist/views/LogsView/client.d.ts +2 -0
- package/dist/views/LogsView/index.d.ts +4 -0
- package/dist/views/NewTicketView/client.d.ts +2 -0
- package/dist/views/NewTicketView/index.d.ts +4 -0
- package/dist/views/PendingEmailsView/client.d.ts +2 -0
- package/dist/views/PendingEmailsView/index.d.ts +4 -0
- package/dist/views/SupportDashboardView/client.d.ts +2 -0
- package/dist/views/SupportDashboardView/client.js +1 -1
- package/dist/views/SupportDashboardView/index.d.ts +4 -0
- package/dist/views/TicketDetailView/NextActionItem.d.ts +6 -0
- package/dist/views/TicketDetailView/RewriteDropdown.d.ts +7 -0
- package/dist/views/TicketDetailView/client.d.ts +2 -0
- package/dist/views/TicketDetailView/client.js +2 -2
- package/dist/views/TicketDetailView/constants.d.ts +13 -0
- package/dist/views/TicketDetailView/helpers.d.ts +2 -0
- package/dist/views/TicketDetailView/index.d.ts +4 -0
- package/dist/views/TicketDetailView/types.d.ts +40 -0
- package/dist/views/TicketInboxView/client.d.ts +2 -0
- package/dist/views/TicketInboxView/client.js +5 -5
- package/dist/views/TicketInboxView/index.d.ts +4 -0
- package/dist/views/TicketingSettingsView/client.d.ts +2 -0
- package/dist/views/TicketingSettingsView/client.js +6 -5
- package/dist/views/TicketingSettingsView/index.d.ts +4 -0
- package/dist/views/TimeDashboardView/client.d.ts +2 -0
- package/dist/views/TimeDashboardView/index.d.ts +4 -0
- package/dist/views/shared/AdminViewHeader.d.ts +13 -0
- package/dist/views/shared/ErrorBoundary.d.ts +17 -0
- package/dist/views/shared/Skeleton.d.ts +21 -0
- package/dist/views/shared/StatusPill.d.ts +8 -0
- package/dist/views/shared/adminTokens.d.ts +19 -0
- package/dist/views/shared/config.d.ts +8 -0
- package/dist/views/shared/config.js +1 -40
- package/dist/views/shared/dateLocale.d.ts +5 -0
- package/dist/views/shared/index.d.ts +12 -0
- package/dist/views/shared/index.js +2 -1
- package/dist/views/shared/locales/en.json +708 -0
- package/dist/views/shared/locales/fr.json +708 -0
- package/dist/views/shared/sla.d.ts +14 -0
- package/dist/views.d.ts +13 -13
- package/package.json +26 -41
- package/src/collections/SupportClients.ts +29 -0
- package/src/collections/TicketCollaborators.ts +6 -1
- package/src/collections/TicketMessages.ts +46 -24
- package/src/collections/Tickets.ts +117 -79
- package/src/collections/TimeEntries.ts +57 -32
- package/src/components/TicketConversation/config.ts +16 -80
- package/src/components/TicketConversation/hooks/useFeatures.ts +109 -0
- package/src/components/TicketConversation/hooks/useTranslation.ts +38 -4
- package/src/components/TicketConversation/index.tsx +2 -2
- package/src/endpoints/ai.ts +2 -1
- package/src/endpoints/client-intelligence.ts +2 -1
- package/src/endpoints/process-scheduled.ts +13 -8
- package/src/endpoints/round-robin-config.ts +30 -20
- package/src/endpoints/settings.ts +28 -77
- package/src/index.ts +6 -2
- package/src/portal/LiveChat.tsx +33 -22
- package/src/portal/auth/tickets/detail/TicketPolling.tsx +5 -1
- package/src/types/lucide-react.d.ts +10 -2
- package/src/utils/aiAgent.ts +2 -1
- package/src/utils/aiProvider.ts +21 -0
- package/src/utils/features.ts +297 -0
- package/src/utils/fireWebhooks.ts +6 -0
- package/src/utils/generateTicketSynthesis.ts +2 -1
- package/src/utils/index.ts +4 -2
- package/src/utils/readSettings.ts +82 -9
- package/src/utils/webhookDispatcher.ts +19 -7
- package/src/views/ChatView/client.tsx +13 -9
- package/src/views/CrmView/client.tsx +10 -11
- package/src/views/SupportDashboardView/client.tsx +1 -1
- package/src/views/TicketDetailView/client.tsx +2 -2
- package/src/views/TicketInboxView/client.tsx +10 -5
- package/src/views/TicketingSettingsView/client.tsx +9 -7
- package/src/views/shared/config.ts +14 -80
- package/src/views/shared/index.ts +3 -1
- package/src/views/shared/locales/en.json +2 -2
- package/src/views/shared/locales/fr.json +2 -2
- package/dist/components/RichTextEditor/index.cjs +0 -279
- package/dist/components/TicketConversation/RewriteDropdown.cjs +0 -98
- package/dist/components/TicketConversation/SkeletonText.cjs +0 -21
- package/dist/components/TicketConversation/components/AISummaryPanel.cjs +0 -85
- package/dist/components/TicketConversation/components/ActionPanels.cjs +0 -193
- package/dist/components/TicketConversation/components/ActivityLog.cjs +0 -24
- package/dist/components/TicketConversation/components/ClientBar.cjs +0 -43
- package/dist/components/TicketConversation/components/ClientHistory.cjs +0 -138
- package/dist/components/TicketConversation/components/CodeBlock.cjs +0 -171
- package/dist/components/TicketConversation/components/CodeBlockInserter.cjs +0 -156
- package/dist/components/TicketConversation/components/QuickActions.cjs +0 -87
- package/dist/components/TicketConversation/components/TicketHeader.cjs +0 -93
- package/dist/components/TicketConversation/components/TimeTrackingPanel.cjs +0 -134
- package/dist/components/TicketConversation/config.cjs +0 -44
- package/dist/components/TicketConversation/constants.cjs +0 -127
- package/dist/components/TicketConversation/context.cjs +0 -13
- package/dist/components/TicketConversation/hooks/useAI.cjs +0 -196
- package/dist/components/TicketConversation/hooks/useDocumentIdFromUrl.cjs +0 -20
- package/dist/components/TicketConversation/hooks/useMessageActions.cjs +0 -136
- package/dist/components/TicketConversation/hooks/useReply.cjs +0 -188
- package/dist/components/TicketConversation/hooks/useTicketActions.cjs +0 -290
- package/dist/components/TicketConversation/hooks/useTimeTracking.cjs +0 -123
- package/dist/components/TicketConversation/hooks/useTranslation.cjs +0 -78
- package/dist/components/TicketConversation/index.cjs +0 -1114
- package/dist/components/TicketConversation/types.cjs +0 -2
- package/dist/components/TicketConversation/utils.cjs +0 -27
- package/dist/views/BillingView/client.cjs +0 -469
- package/dist/views/BillingView/index.cjs +0 -34
- package/dist/views/ChatView/client.cjs +0 -301
- package/dist/views/ChatView/index.cjs +0 -34
- package/dist/views/CrmView/client.cjs +0 -458
- package/dist/views/CrmView/index.cjs +0 -34
- package/dist/views/EmailTrackingView/client.cjs +0 -171
- package/dist/views/EmailTrackingView/index.cjs +0 -34
- package/dist/views/ImportConversationView/client.cjs +0 -238
- package/dist/views/ImportConversationView/index.cjs +0 -34
- package/dist/views/LogsView/client.cjs +0 -148
- package/dist/views/LogsView/index.cjs +0 -32
- package/dist/views/NewTicketView/client.cjs +0 -213
- package/dist/views/NewTicketView/index.cjs +0 -32
- package/dist/views/PendingEmailsView/client.cjs +0 -471
- package/dist/views/PendingEmailsView/index.cjs +0 -34
- package/dist/views/SupportDashboardView/client.cjs +0 -437
- package/dist/views/SupportDashboardView/index.cjs +0 -34
- package/dist/views/TicketDetailView/NextActionItem.cjs +0 -40
- package/dist/views/TicketDetailView/RewriteDropdown.cjs +0 -80
- package/dist/views/TicketDetailView/client.cjs +0 -1412
- package/dist/views/TicketDetailView/constants.cjs +0 -20
- package/dist/views/TicketDetailView/helpers.cjs +0 -23
- package/dist/views/TicketDetailView/index.cjs +0 -34
- package/dist/views/TicketDetailView/types.cjs +0 -2
- package/dist/views/TicketInboxView/client.cjs +0 -359
- package/dist/views/TicketInboxView/index.cjs +0 -32
- package/dist/views/TicketingSettingsView/client.cjs +0 -740
- package/dist/views/TicketingSettingsView/index.cjs +0 -34
- package/dist/views/TimeDashboardView/client.cjs +0 -180
- package/dist/views/TimeDashboardView/index.cjs +0 -34
- package/dist/views/shared/AdminViewHeader.cjs +0 -68
- package/dist/views/shared/ErrorBoundary.cjs +0 -55
- package/dist/views/shared/Skeleton.cjs +0 -77
- package/dist/views/shared/StatusPill.cjs +0 -47
- package/dist/views/shared/adminTokens.cjs +0 -34
- package/dist/views/shared/config.cjs +0 -44
- package/dist/views/shared/dateLocale.cjs +0 -5
- package/dist/views/shared/index.cjs +0 -72
- package/dist/views/shared/sla.cjs +0 -37
- package/dist/views.cjs +0 -86
- package/dist/views.d.cts +0 -13
- package/src/__tests__/aiSummaryRendering.test.ts +0 -21
- package/src/__tests__/authResponses.test.ts +0 -69
- package/src/__tests__/capabilities.test.ts +0 -71
- package/src/__tests__/generateTrackingToken.test.ts +0 -67
- package/src/__tests__/integration/ai-agent.test.ts +0 -46
- package/src/__tests__/integration/auth.test.ts +0 -43
- package/src/__tests__/integration/automation-rules.test.ts +0 -68
- package/src/__tests__/integration/buildTestPayload.ts +0 -52
- package/src/__tests__/integration/channels.test.ts +0 -52
- package/src/__tests__/integration/core-behaviors.test.ts +0 -81
- package/src/__tests__/integration/dashboard-volume.test.ts +0 -31
- package/src/__tests__/integration/digest.test.ts +0 -48
- package/src/__tests__/integration/invoice-pdf.test.ts +0 -30
- package/src/__tests__/integration/isolation.test.ts +0 -81
- package/src/__tests__/integration/mentions-invoice.test.ts +0 -50
- package/src/__tests__/integration/nps.test.ts +0 -37
- package/src/__tests__/integration/per-team-sla.test.ts +0 -44
- package/src/__tests__/integration/push.test.ts +0 -75
- package/src/__tests__/integration/sanitization.test.ts +0 -35
- package/src/__tests__/integration/sla-pause.test.ts +0 -39
- package/src/__tests__/integration/smoke.test.ts +0 -26
- package/src/__tests__/integration/snooze.test.ts +0 -68
- package/src/__tests__/integration/teams.test.ts +0 -38
- package/src/__tests__/rateLimiter.test.ts +0 -83
- package/src/__tests__/sanitizeHtml.test.ts +0 -165
- package/src/__tests__/sla.test.ts +0 -258
- package/src/__tests__/trackOpenEndpoint.test.ts +0 -54
- package/src/__tests__/webhookSecurity.test.ts +0 -58
|
@@ -1,193 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
var jsxRuntime = require('react/jsx-runtime');
|
|
4
|
-
var react = require('react');
|
|
5
|
-
var constants = require('../constants');
|
|
6
|
-
|
|
7
|
-
function MergePanel({
|
|
8
|
-
mergeTarget,
|
|
9
|
-
setMergeTarget,
|
|
10
|
-
mergeTargetInfo,
|
|
11
|
-
setMergeTargetInfo,
|
|
12
|
-
mergeError,
|
|
13
|
-
setMergeError,
|
|
14
|
-
merging,
|
|
15
|
-
handleMergeLookup,
|
|
16
|
-
handleMerge
|
|
17
|
-
}) {
|
|
18
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { padding: "14px 18px", borderRadius: "8px", backgroundColor: "#fdf2f8", border: "1px solid #fbcfe8", marginBottom: "14px" }, children: [
|
|
19
|
-
/* @__PURE__ */ jsxRuntime.jsx("h4", { style: { fontSize: "13px", fontWeight: 600, marginBottom: "10px", color: "#831843" }, children: "Fusionner ce ticket dans un autre" }),
|
|
20
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", gap: "8px", alignItems: "center", marginBottom: "8px" }, children: [
|
|
21
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
22
|
-
"input",
|
|
23
|
-
{
|
|
24
|
-
type: "text",
|
|
25
|
-
value: mergeTarget,
|
|
26
|
-
onChange: (e) => {
|
|
27
|
-
setMergeTarget(e.target.value);
|
|
28
|
-
setMergeTargetInfo(null);
|
|
29
|
-
setMergeError("");
|
|
30
|
-
},
|
|
31
|
-
placeholder: "TK-0001",
|
|
32
|
-
style: { ...constants.s.input, width: "130px" }
|
|
33
|
-
}
|
|
34
|
-
),
|
|
35
|
-
/* @__PURE__ */ jsxRuntime.jsx("button", { onClick: handleMergeLookup, style: { ...constants.s.outlineBtn("#ec4899"), fontSize: "12px", padding: "6px 14px" }, children: "Rechercher" }),
|
|
36
|
-
mergeError && /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: "12px", color: "#be185d", fontWeight: 600 }, children: mergeError })
|
|
37
|
-
] }),
|
|
38
|
-
mergeTargetInfo && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", gap: "8px", alignItems: "center" }, children: [
|
|
39
|
-
/* @__PURE__ */ jsxRuntime.jsxs("span", { style: { fontSize: "13px", fontWeight: 600 }, children: [
|
|
40
|
-
mergeTargetInfo.ticketNumber,
|
|
41
|
-
" \u2014 ",
|
|
42
|
-
mergeTargetInfo.subject
|
|
43
|
-
] }),
|
|
44
|
-
/* @__PURE__ */ jsxRuntime.jsx("button", { onClick: handleMerge, disabled: merging, style: { ...constants.s.btn("#ec4899", merging), color: "#fff", fontSize: "12px", padding: "6px 14px" }, children: merging ? "Fusion..." : "Confirmer la fusion" })
|
|
45
|
-
] })
|
|
46
|
-
] });
|
|
47
|
-
}
|
|
48
|
-
function ExtMessagePanel({
|
|
49
|
-
extMsgBody,
|
|
50
|
-
setExtMsgBody,
|
|
51
|
-
extMsgAuthor,
|
|
52
|
-
setExtMsgAuthor,
|
|
53
|
-
extMsgDate,
|
|
54
|
-
setExtMsgDate,
|
|
55
|
-
extMsgFiles,
|
|
56
|
-
setExtMsgFiles,
|
|
57
|
-
sendingExtMsg,
|
|
58
|
-
handleSendExtMsg,
|
|
59
|
-
handleExtFileChange
|
|
60
|
-
}) {
|
|
61
|
-
const extFileInputRef = react.useRef(null);
|
|
62
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { padding: "14px 18px", borderRadius: "8px", backgroundColor: "#eef2ff", border: "1px solid #c7d2fe", marginBottom: "14px" }, children: [
|
|
63
|
-
/* @__PURE__ */ jsxRuntime.jsx("h4", { style: { fontSize: "13px", fontWeight: 600, marginBottom: "10px", color: "#312e81" }, children: "Ajouter un message re\xE7u (email, SMS, WhatsApp...)" }),
|
|
64
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
65
|
-
"textarea",
|
|
66
|
-
{
|
|
67
|
-
value: extMsgBody,
|
|
68
|
-
onChange: (e) => setExtMsgBody(e.target.value),
|
|
69
|
-
placeholder: "Coller le contenu du message re\xE7u...",
|
|
70
|
-
rows: 3,
|
|
71
|
-
style: { ...constants.s.input, width: "100%", resize: "vertical", marginBottom: "10px" }
|
|
72
|
-
}
|
|
73
|
-
),
|
|
74
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", gap: "8px", alignItems: "center", flexWrap: "wrap", marginBottom: "10px" }, children: [
|
|
75
|
-
/* @__PURE__ */ jsxRuntime.jsxs("select", { value: extMsgAuthor, onChange: (e) => setExtMsgAuthor(e.target.value), style: { ...constants.s.input, fontSize: "12px" }, children: [
|
|
76
|
-
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "client", children: "Envoy\xE9 par le client" }),
|
|
77
|
-
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "admin", children: "Envoy\xE9 par le support" })
|
|
78
|
-
] }),
|
|
79
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
80
|
-
"input",
|
|
81
|
-
{
|
|
82
|
-
type: "datetime-local",
|
|
83
|
-
value: extMsgDate,
|
|
84
|
-
onChange: (e) => setExtMsgDate(e.target.value),
|
|
85
|
-
style: { ...constants.s.input, fontSize: "12px" }
|
|
86
|
-
}
|
|
87
|
-
),
|
|
88
|
-
/* @__PURE__ */ jsxRuntime.jsx("input", { ref: extFileInputRef, type: "file", multiple: true, onChange: handleExtFileChange, style: { display: "none" }, accept: "image/*,.pdf,.doc,.docx,.txt,.zip" }),
|
|
89
|
-
/* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", onClick: () => extFileInputRef.current?.click(), style: { ...constants.s.ghostBtn("#6b7280"), fontSize: "12px", padding: "6px 12px" }, children: "+ PJ" })
|
|
90
|
-
] }),
|
|
91
|
-
extMsgFiles.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { marginBottom: "10px", display: "flex", gap: "6px", flexWrap: "wrap" }, children: extMsgFiles.map((file, i) => /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { ...constants.s.badge("#f1f5f9", "#374151"), display: "inline-flex", alignItems: "center", gap: "4px" }, children: [
|
|
92
|
-
file.name,
|
|
93
|
-
/* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", onClick: () => setExtMsgFiles((prev) => prev.filter((_, idx) => idx !== i)), style: { border: "none", background: "none", color: "#ef4444", fontWeight: 700, cursor: "pointer", fontSize: "14px", lineHeight: 1 }, children: "\xD7" })
|
|
94
|
-
] }, i)) }),
|
|
95
|
-
/* @__PURE__ */ jsxRuntime.jsx("button", { onClick: handleSendExtMsg, disabled: sendingExtMsg || !extMsgBody.trim(), style: constants.s.btn("#1d2b4d", sendingExtMsg || !extMsgBody.trim()), children: sendingExtMsg ? "Ajout..." : "Ajouter (sans notification)" })
|
|
96
|
-
] });
|
|
97
|
-
}
|
|
98
|
-
const REMINDER_DELAYS = [
|
|
99
|
-
{ hours: 24, label: "24 h" },
|
|
100
|
-
{ hours: 48, label: "48 h" },
|
|
101
|
-
{ hours: 72, label: "72 h" }
|
|
102
|
-
];
|
|
103
|
-
function ReminderPanel({
|
|
104
|
-
clientFirstName,
|
|
105
|
-
clientEmail,
|
|
106
|
-
reminderHours,
|
|
107
|
-
setReminderHours,
|
|
108
|
-
reminderSending,
|
|
109
|
-
reminderError,
|
|
110
|
-
handleSendReminder
|
|
111
|
-
}) {
|
|
112
|
-
const deadline = new Date(Date.now() + reminderHours * 60 * 60 * 1e3);
|
|
113
|
-
const deadlineLabel = deadline.toLocaleString("fr-FR", {
|
|
114
|
-
weekday: "long",
|
|
115
|
-
day: "numeric",
|
|
116
|
-
month: "long",
|
|
117
|
-
hour: "2-digit",
|
|
118
|
-
minute: "2-digit"
|
|
119
|
-
});
|
|
120
|
-
const name = clientFirstName?.trim() || "le client";
|
|
121
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { padding: "14px 18px", borderRadius: "8px", backgroundColor: "#fff7ed", border: "1px solid #fed7aa", marginBottom: "14px" }, children: [
|
|
122
|
-
/* @__PURE__ */ jsxRuntime.jsxs("h4", { style: { fontSize: "13px", fontWeight: 600, marginBottom: "8px", color: "#9a3412" }, children: [
|
|
123
|
-
"Relancer ",
|
|
124
|
-
name,
|
|
125
|
-
" \u2014 fermeture automatique sans r\xE9ponse"
|
|
126
|
-
] }),
|
|
127
|
-
clientEmail ? /* @__PURE__ */ jsxRuntime.jsxs("p", { style: { fontSize: "12px", color: "#7c2d12", margin: "0 0 12px 0", lineHeight: 1.5 }, children: [
|
|
128
|
-
"Un email de relance g\xE9n\xE9rique sera envoy\xE9 \xE0 ",
|
|
129
|
-
/* @__PURE__ */ jsxRuntime.jsx("strong", { children: clientEmail }),
|
|
130
|
-
". Sans retour de sa part avant l'\xE9ch\xE9ance, le ticket sera automatiquement r\xE9solu (via le cron auto-close)."
|
|
131
|
-
] }) : /* @__PURE__ */ jsxRuntime.jsx("p", { style: { fontSize: "12px", color: "#b91c1c", margin: "0 0 12px 0", fontWeight: 600 }, children: "Ce client n'a pas d'adresse email : impossible d'envoyer une relance." }),
|
|
132
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", gap: "6px", alignItems: "center", flexWrap: "wrap", marginBottom: "12px" }, children: [
|
|
133
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: "12px", fontWeight: 600, color: "#9a3412" }, children: "Fermer dans :" }),
|
|
134
|
-
REMINDER_DELAYS.map((d) => {
|
|
135
|
-
const active = reminderHours === d.hours;
|
|
136
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
137
|
-
"button",
|
|
138
|
-
{
|
|
139
|
-
type: "button",
|
|
140
|
-
onClick: () => setReminderHours(d.hours),
|
|
141
|
-
style: {
|
|
142
|
-
...active ? constants.s.btn(constants.C.orange) : constants.s.outlineBtn("#ea580c"),
|
|
143
|
-
fontSize: "12px",
|
|
144
|
-
padding: "6px 14px"
|
|
145
|
-
},
|
|
146
|
-
children: d.label
|
|
147
|
-
},
|
|
148
|
-
d.hours
|
|
149
|
-
);
|
|
150
|
-
})
|
|
151
|
-
] }),
|
|
152
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: { fontSize: "12px", color: "#7c2d12", marginBottom: "12px" }, children: [
|
|
153
|
-
"Fermeture automatique pr\xE9vue le ",
|
|
154
|
-
/* @__PURE__ */ jsxRuntime.jsx("strong", { children: deadlineLabel }),
|
|
155
|
-
" sans r\xE9ponse."
|
|
156
|
-
] }),
|
|
157
|
-
reminderError && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontSize: "12px", color: "#b91c1c", fontWeight: 600, marginBottom: "10px" }, children: reminderError }),
|
|
158
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
159
|
-
"button",
|
|
160
|
-
{
|
|
161
|
-
onClick: handleSendReminder,
|
|
162
|
-
disabled: reminderSending || !clientEmail,
|
|
163
|
-
style: { ...constants.s.btn(constants.C.orange, reminderSending || !clientEmail), color: "#fff", fontSize: "13px", padding: "8px 18px" },
|
|
164
|
-
children: reminderSending ? "Envoi..." : "Confirmer la relance"
|
|
165
|
-
}
|
|
166
|
-
)
|
|
167
|
-
] });
|
|
168
|
-
}
|
|
169
|
-
function SnoozePanel({ snoozeSaving, handleSnooze }) {
|
|
170
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { padding: "14px 18px", borderRadius: "8px", backgroundColor: "#eef8f7", border: "1px solid #b8dcda", marginBottom: "14px" }, children: [
|
|
171
|
-
/* @__PURE__ */ jsxRuntime.jsx("h4", { style: { fontSize: "13px", fontWeight: 600, marginBottom: "10px", color: "#5b21b6" }, children: "Snooze \u2014 masquer temporairement" }),
|
|
172
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", gap: "8px", flexWrap: "wrap", alignItems: "center" }, children: [
|
|
173
|
-
/* @__PURE__ */ jsxRuntime.jsx("button", { onClick: () => handleSnooze(1), disabled: snoozeSaving, style: { ...constants.s.outlineBtn("#17807c", snoozeSaving), fontSize: "12px" }, children: "1 jour" }),
|
|
174
|
-
/* @__PURE__ */ jsxRuntime.jsx("button", { onClick: () => handleSnooze(3), disabled: snoozeSaving, style: { ...constants.s.outlineBtn("#17807c", snoozeSaving), fontSize: "12px" }, children: "3 jours" }),
|
|
175
|
-
/* @__PURE__ */ jsxRuntime.jsx("button", { onClick: () => handleSnooze(7), disabled: snoozeSaving, style: { ...constants.s.outlineBtn("#17807c", snoozeSaving), fontSize: "12px" }, children: "1 semaine" }),
|
|
176
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
177
|
-
"input",
|
|
178
|
-
{
|
|
179
|
-
type: "datetime-local",
|
|
180
|
-
onChange: (e) => {
|
|
181
|
-
if (e.target.value) handleSnooze(null, e.target.value);
|
|
182
|
-
},
|
|
183
|
-
style: { ...constants.s.input, fontSize: "12px" }
|
|
184
|
-
}
|
|
185
|
-
)
|
|
186
|
-
] })
|
|
187
|
-
] });
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
exports.ExtMessagePanel = ExtMessagePanel;
|
|
191
|
-
exports.MergePanel = MergePanel;
|
|
192
|
-
exports.ReminderPanel = ReminderPanel;
|
|
193
|
-
exports.SnoozePanel = SnoozePanel;
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
var jsxRuntime = require('react/jsx-runtime');
|
|
4
|
-
var react = require('react');
|
|
5
|
-
var constants = require('../constants');
|
|
6
|
-
|
|
7
|
-
function ActivityLog({ activityLog }) {
|
|
8
|
-
const [showActivity, setShowActivity] = react.useState(false);
|
|
9
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: constants.s.section, children: [
|
|
10
|
-
/* @__PURE__ */ jsxRuntime.jsxs("h4", { style: { ...constants.s.sectionTitle, cursor: "pointer" }, onClick: () => setShowActivity(!showActivity), children: [
|
|
11
|
-
"Historique ",
|
|
12
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { style: constants.s.badge("#f1f5f9", "#475569"), children: activityLog.length }),
|
|
13
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: "12px", color: constants.C.textMuted, transition: "transform 0.2s", display: "inline-block", transform: showActivity ? "rotate(90deg)" : "none" }, children: "\u25B6" })
|
|
14
|
-
] }),
|
|
15
|
-
showActivity && (activityLog.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("p", { style: { fontSize: "12px", color: constants.C.textMuted, fontStyle: "italic" }, children: "Aucune activit\xE9 enregistr\xE9e." }) : /* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontSize: "12px", display: "flex", flexDirection: "column", gap: "2px", borderLeft: "2px solid #bfdbfe", paddingLeft: "14px", marginLeft: "4px" }, children: activityLog.map((entry) => /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", gap: "10px", alignItems: "center", padding: "5px 0", borderBottom: "1px solid #f8fafc" }, children: [
|
|
16
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: constants.C.textMuted, fontSize: "11px", whiteSpace: "nowrap", fontWeight: 500 }, children: new Date(entry.createdAt).toLocaleString("fr-FR", { day: "numeric", month: "short", hour: "2-digit", minute: "2-digit" }) }),
|
|
17
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { style: constants.s.badge(entry.actorType === "admin" ? "#eff6ff" : "#dcfce7", entry.actorType === "admin" ? "#1e40af" : "#166534"), children: entry.actorType || "system" }),
|
|
18
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: "#374151", fontWeight: 500 }, children: (entry.detail || entry.action).replace(/\[object Object\]/g, "(utilisateur)") }),
|
|
19
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: constants.C.textMuted, fontSize: "11px" }, children: entry.actorEmail })
|
|
20
|
-
] }, entry.id)) }))
|
|
21
|
-
] });
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
exports.ActivityLog = ActivityLog;
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
var jsxRuntime = require('react/jsx-runtime');
|
|
4
|
-
var constants = require('../constants');
|
|
5
|
-
|
|
6
|
-
function ClientBar({ client }) {
|
|
7
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: {
|
|
8
|
-
display: "flex",
|
|
9
|
-
alignItems: "center",
|
|
10
|
-
gap: "12px",
|
|
11
|
-
padding: "10px 16px",
|
|
12
|
-
borderRadius: "8px",
|
|
13
|
-
backgroundColor: "var(--theme-elevation-100)",
|
|
14
|
-
marginBottom: "16px",
|
|
15
|
-
flexWrap: "wrap"
|
|
16
|
-
}, children: [
|
|
17
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: "16px" }, children: "\u{1F464}" }),
|
|
18
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontWeight: 700, fontSize: "13px", color: constants.C.textPrimary }, children: client.company }),
|
|
19
|
-
/* @__PURE__ */ jsxRuntime.jsxs("span", { style: { color: constants.C.textSecondary, fontSize: "13px" }, children: [
|
|
20
|
-
client.firstName,
|
|
21
|
-
" ",
|
|
22
|
-
client.lastName
|
|
23
|
-
] }),
|
|
24
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: constants.C.textMuted, fontSize: "12px" }, children: "|" }),
|
|
25
|
-
/* @__PURE__ */ jsxRuntime.jsx("a", { href: `mailto:${client.email}`, style: { color: "#2563eb", fontSize: "12px", fontWeight: 600, textDecoration: "none" }, children: client.email }),
|
|
26
|
-
client.phone && /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: constants.C.textSecondary, fontSize: "12px" }, children: client.phone }),
|
|
27
|
-
/* @__PURE__ */ jsxRuntime.jsxs("span", { style: { marginLeft: "auto", display: "inline-flex", gap: "8px", alignItems: "center" }, children: [
|
|
28
|
-
/* @__PURE__ */ jsxRuntime.jsx("a", { href: `/admin/collections/support-clients/${client.id}`, style: { ...constants.s.ghostBtn("#475569"), fontSize: "11px", padding: "4px 10px", textDecoration: "none" }, children: "Fiche client" }),
|
|
29
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
30
|
-
"button",
|
|
31
|
-
{
|
|
32
|
-
type: "button",
|
|
33
|
-
onClick: () => window.open(`/api/admin/impersonate?clientId=${client.id}`, "_blank"),
|
|
34
|
-
style: { ...constants.s.ghostBtn("#17807c"), fontSize: "11px", padding: "4px 10px" },
|
|
35
|
-
title: "Se connecter au portail support en tant que ce client",
|
|
36
|
-
children: "Voir en tant que client"
|
|
37
|
-
}
|
|
38
|
-
)
|
|
39
|
-
] })
|
|
40
|
-
] });
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
exports.ClientBar = ClientBar;
|
|
@@ -1,138 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
var jsxRuntime = require('react/jsx-runtime');
|
|
4
|
-
var react = require('react');
|
|
5
|
-
var constants = require('../constants');
|
|
6
|
-
|
|
7
|
-
function ClientHistory({
|
|
8
|
-
client: _client,
|
|
9
|
-
clientTickets,
|
|
10
|
-
clientProjects,
|
|
11
|
-
clientNotes,
|
|
12
|
-
onNotesChange,
|
|
13
|
-
onNotesSave,
|
|
14
|
-
savingNotes,
|
|
15
|
-
notesSaved
|
|
16
|
-
}) {
|
|
17
|
-
const [showClientHistory, setShowClientHistory] = react.useState(false);
|
|
18
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: constants.s.section, children: [
|
|
19
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
20
|
-
"button",
|
|
21
|
-
{
|
|
22
|
-
type: "button",
|
|
23
|
-
onClick: () => setShowClientHistory(!showClientHistory),
|
|
24
|
-
style: {
|
|
25
|
-
background: "none",
|
|
26
|
-
border: `1px dashed ${constants.C.border}`,
|
|
27
|
-
borderRadius: "6px",
|
|
28
|
-
padding: "8px 14px",
|
|
29
|
-
cursor: "pointer",
|
|
30
|
-
color: constants.C.textSecondary,
|
|
31
|
-
fontSize: "13px",
|
|
32
|
-
fontWeight: 600,
|
|
33
|
-
width: "100%",
|
|
34
|
-
textAlign: "left",
|
|
35
|
-
display: "flex",
|
|
36
|
-
alignItems: "center",
|
|
37
|
-
justifyContent: "space-between"
|
|
38
|
-
},
|
|
39
|
-
children: [
|
|
40
|
-
/* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
|
|
41
|
-
"Historique client (",
|
|
42
|
-
clientTickets.length,
|
|
43
|
-
" ticket",
|
|
44
|
-
clientTickets.length !== 1 ? "s" : "",
|
|
45
|
-
", ",
|
|
46
|
-
clientProjects.length,
|
|
47
|
-
" projet",
|
|
48
|
-
clientProjects.length !== 1 ? "s" : "",
|
|
49
|
-
")"
|
|
50
|
-
] }),
|
|
51
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: "12px", transition: "transform 0.2s", display: "inline-block", transform: showClientHistory ? "rotate(90deg)" : "none" }, children: "\u25B6" })
|
|
52
|
-
]
|
|
53
|
-
}
|
|
54
|
-
),
|
|
55
|
-
showClientHistory && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { marginTop: "10px", padding: "14px 18px", borderRadius: "8px", backgroundColor: constants.C.white, border: `1px solid ${constants.C.border}` }, children: [
|
|
56
|
-
/* @__PURE__ */ jsxRuntime.jsx("h5", { style: { fontSize: "12px", fontWeight: 600, color: constants.C.textSecondary, marginBottom: "8px" }, children: "Derniers tickets" }),
|
|
57
|
-
clientTickets.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("p", { style: { fontSize: "12px", color: constants.C.textMuted, fontStyle: "italic", marginBottom: "14px" }, children: "Aucun autre ticket" }) : /* @__PURE__ */ jsxRuntime.jsx("div", { style: { display: "flex", flexDirection: "column", gap: "4px", marginBottom: "14px" }, children: clientTickets.map((t) => {
|
|
58
|
-
const st = constants.statusLabels[t.status] || constants.statusLabels.open;
|
|
59
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
60
|
-
"a",
|
|
61
|
-
{
|
|
62
|
-
href: `/admin/support/ticket?id=${t.id}`,
|
|
63
|
-
style: {
|
|
64
|
-
display: "flex",
|
|
65
|
-
alignItems: "center",
|
|
66
|
-
gap: "8px",
|
|
67
|
-
padding: "6px 10px",
|
|
68
|
-
borderRadius: "6px",
|
|
69
|
-
border: `1px solid ${constants.C.border}`,
|
|
70
|
-
textDecoration: "none",
|
|
71
|
-
fontSize: "12px",
|
|
72
|
-
color: "#374151",
|
|
73
|
-
backgroundColor: "#fafafa"
|
|
74
|
-
},
|
|
75
|
-
children: [
|
|
76
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontFamily: "'SF Mono', 'Fira Code', 'JetBrains Mono', 'Cascadia Code', monospace", fontWeight: 600, color: constants.C.textMuted, fontSize: "11px", whiteSpace: "nowrap" }, children: t.ticketNumber }),
|
|
77
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { style: { flex: 1, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap", fontWeight: 600 }, children: t.subject }),
|
|
78
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { style: constants.s.badge(st.bg, st.color), children: st.label }),
|
|
79
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: "10px", color: constants.C.textMuted, whiteSpace: "nowrap" }, children: new Date(t.createdAt).toLocaleDateString("fr-FR", { day: "numeric", month: "short" }) })
|
|
80
|
-
]
|
|
81
|
-
},
|
|
82
|
-
t.id
|
|
83
|
-
);
|
|
84
|
-
}) }),
|
|
85
|
-
/* @__PURE__ */ jsxRuntime.jsx("h5", { style: { fontSize: "12px", fontWeight: 600, color: constants.C.textSecondary, marginBottom: "8px" }, children: "Projets" }),
|
|
86
|
-
clientProjects.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("p", { style: { fontSize: "12px", color: constants.C.textMuted, fontStyle: "italic", marginBottom: "14px" }, children: "Aucun projet" }) : /* @__PURE__ */ jsxRuntime.jsx("div", { style: { display: "flex", gap: "6px", flexWrap: "wrap", marginBottom: "14px" }, children: clientProjects.map((p) => {
|
|
87
|
-
const ps = constants.projectStatusLabels[p.status] || constants.projectStatusLabels.active;
|
|
88
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
89
|
-
"a",
|
|
90
|
-
{
|
|
91
|
-
href: `/admin/collections/projects/${p.id}`,
|
|
92
|
-
style: {
|
|
93
|
-
display: "inline-flex",
|
|
94
|
-
alignItems: "center",
|
|
95
|
-
gap: "6px",
|
|
96
|
-
padding: "5px 10px",
|
|
97
|
-
borderRadius: "6px",
|
|
98
|
-
border: `1px solid ${constants.C.border}`,
|
|
99
|
-
textDecoration: "none",
|
|
100
|
-
fontSize: "12px",
|
|
101
|
-
fontWeight: 600,
|
|
102
|
-
color: "#374151",
|
|
103
|
-
backgroundColor: "#fafafa"
|
|
104
|
-
},
|
|
105
|
-
children: [
|
|
106
|
-
p.name,
|
|
107
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { style: constants.s.badge(ps.bg, ps.color), children: ps.label })
|
|
108
|
-
]
|
|
109
|
-
},
|
|
110
|
-
p.id
|
|
111
|
-
);
|
|
112
|
-
}) }),
|
|
113
|
-
/* @__PURE__ */ jsxRuntime.jsx("h5", { style: { fontSize: "12px", fontWeight: 600, color: constants.C.textSecondary, marginBottom: "8px" }, children: "Notes internes" }),
|
|
114
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
115
|
-
"textarea",
|
|
116
|
-
{
|
|
117
|
-
value: clientNotes,
|
|
118
|
-
onChange: (e) => onNotesChange(e.target.value),
|
|
119
|
-
rows: 3,
|
|
120
|
-
style: { ...constants.s.input, width: "100%", resize: "vertical", fontSize: "12px", marginBottom: "8px" },
|
|
121
|
-
placeholder: "Notes sur ce client..."
|
|
122
|
-
}
|
|
123
|
-
),
|
|
124
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
125
|
-
"button",
|
|
126
|
-
{
|
|
127
|
-
type: "button",
|
|
128
|
-
onClick: onNotesSave,
|
|
129
|
-
disabled: savingNotes,
|
|
130
|
-
style: { ...constants.s.btn(notesSaved ? "#16a34a" : constants.C.blue, savingNotes), fontSize: "11px", padding: "5px 12px" },
|
|
131
|
-
children: notesSaved ? "Sauvegarde OK" : savingNotes ? "Sauvegarde..." : "Sauvegarder les notes"
|
|
132
|
-
}
|
|
133
|
-
)
|
|
134
|
-
] })
|
|
135
|
-
] });
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
exports.ClientHistory = ClientHistory;
|
|
@@ -1,171 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
var jsxRuntime = require('react/jsx-runtime');
|
|
4
|
-
var react = require('react');
|
|
5
|
-
|
|
6
|
-
const LANG_CONFIG = {
|
|
7
|
-
javascript: { label: "JavaScript", accent: "#f7df1e" },
|
|
8
|
-
js: { label: "JavaScript", accent: "#f7df1e" },
|
|
9
|
-
typescript: { label: "TypeScript", accent: "#3178c6" },
|
|
10
|
-
ts: { label: "TypeScript", accent: "#3178c6" },
|
|
11
|
-
tsx: { label: "TSX", accent: "#3178c6" },
|
|
12
|
-
jsx: { label: "JSX", accent: "#f7df1e" },
|
|
13
|
-
php: { label: "PHP", accent: "#777bb4" },
|
|
14
|
-
python: { label: "Python", accent: "#3776ab" },
|
|
15
|
-
py: { label: "Python", accent: "#3776ab" },
|
|
16
|
-
html: { label: "HTML", accent: "#e34f26" },
|
|
17
|
-
css: { label: "CSS", accent: "#1572b6" },
|
|
18
|
-
scss: { label: "SCSS", accent: "#cc6699" },
|
|
19
|
-
json: { label: "JSON", accent: "#292929" },
|
|
20
|
-
sql: { label: "SQL", accent: "#e48e00" },
|
|
21
|
-
bash: { label: "Bash", accent: "#4eaa25" },
|
|
22
|
-
sh: { label: "Shell", accent: "#4eaa25" },
|
|
23
|
-
yaml: { label: "YAML", accent: "#cb171e" },
|
|
24
|
-
yml: { label: "YAML", accent: "#cb171e" },
|
|
25
|
-
xml: { label: "XML", accent: "#f16529" },
|
|
26
|
-
markdown: { label: "Markdown", accent: "#083fa1" },
|
|
27
|
-
md: { label: "Markdown", accent: "#083fa1" },
|
|
28
|
-
diff: { label: "Diff", accent: "#41b883" },
|
|
29
|
-
go: { label: "Go", accent: "#00add8" },
|
|
30
|
-
rust: { label: "Rust", accent: "#dea584" },
|
|
31
|
-
java: { label: "Java", accent: "#ed8b00" },
|
|
32
|
-
c: { label: "C", accent: "#555555" },
|
|
33
|
-
cpp: { label: "C++", accent: "#00599c" },
|
|
34
|
-
ruby: { label: "Ruby", accent: "#cc342d" },
|
|
35
|
-
swift: { label: "Swift", accent: "#f05138" },
|
|
36
|
-
nginx: { label: "Nginx", accent: "#009639" },
|
|
37
|
-
docker: { label: "Docker", accent: "#2496ed" },
|
|
38
|
-
dockerfile: { label: "Dockerfile", accent: "#2496ed" },
|
|
39
|
-
env: { label: ".env", accent: "#ecd53f" }
|
|
40
|
-
};
|
|
41
|
-
const DEFAULT_CONFIG = { label: "Code", accent: "#6b7280" };
|
|
42
|
-
function SingleCodeBlock({ lang, code }) {
|
|
43
|
-
const [copied, setCopied] = react.useState(false);
|
|
44
|
-
const config = LANG_CONFIG[lang.toLowerCase()] || (lang ? { label: lang.toUpperCase(), accent: "#6b7280" } : DEFAULT_CONFIG);
|
|
45
|
-
const handleCopy = () => {
|
|
46
|
-
navigator.clipboard.writeText(code);
|
|
47
|
-
setCopied(true);
|
|
48
|
-
setTimeout(() => setCopied(false), 1500);
|
|
49
|
-
};
|
|
50
|
-
const lines = code.split("\n");
|
|
51
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: {
|
|
52
|
-
marginTop: 8,
|
|
53
|
-
marginBottom: 8,
|
|
54
|
-
borderRadius: 8,
|
|
55
|
-
overflow: "hidden",
|
|
56
|
-
border: "1px solid #334155",
|
|
57
|
-
backgroundColor: "#0f172a",
|
|
58
|
-
fontSize: 13
|
|
59
|
-
}, children: [
|
|
60
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: {
|
|
61
|
-
display: "flex",
|
|
62
|
-
alignItems: "center",
|
|
63
|
-
justifyContent: "space-between",
|
|
64
|
-
padding: "6px 12px",
|
|
65
|
-
backgroundColor: "#1e293b",
|
|
66
|
-
borderBottom: "1px solid #334155"
|
|
67
|
-
}, children: [
|
|
68
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: 8 }, children: [
|
|
69
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { style: {
|
|
70
|
-
display: "inline-block",
|
|
71
|
-
width: 8,
|
|
72
|
-
height: 8,
|
|
73
|
-
borderRadius: "50%",
|
|
74
|
-
backgroundColor: config.accent,
|
|
75
|
-
flexShrink: 0
|
|
76
|
-
} }),
|
|
77
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { style: {
|
|
78
|
-
fontSize: 11,
|
|
79
|
-
fontWeight: 700,
|
|
80
|
-
color: "#e2e8f0",
|
|
81
|
-
letterSpacing: "0.02em"
|
|
82
|
-
}, children: config.label })
|
|
83
|
-
] }),
|
|
84
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
85
|
-
"button",
|
|
86
|
-
{
|
|
87
|
-
onClick: handleCopy,
|
|
88
|
-
style: {
|
|
89
|
-
background: "none",
|
|
90
|
-
border: "1px solid #475569",
|
|
91
|
-
borderRadius: 4,
|
|
92
|
-
padding: "2px 10px",
|
|
93
|
-
fontSize: 11,
|
|
94
|
-
color: copied ? "#4ade80" : "#94a3b8",
|
|
95
|
-
cursor: "pointer",
|
|
96
|
-
fontWeight: 600,
|
|
97
|
-
transition: "color 150ms"
|
|
98
|
-
},
|
|
99
|
-
children: copied ? "Copi\xE9 !" : "Copier"
|
|
100
|
-
}
|
|
101
|
-
)
|
|
102
|
-
] }),
|
|
103
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", overflowX: "auto" }, children: [
|
|
104
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { style: {
|
|
105
|
-
padding: "12px 0",
|
|
106
|
-
borderRight: "1px solid #334155",
|
|
107
|
-
userSelect: "none",
|
|
108
|
-
flexShrink: 0
|
|
109
|
-
}, children: lines.map((_, i) => /* @__PURE__ */ jsxRuntime.jsx("div", { style: {
|
|
110
|
-
padding: "0 12px",
|
|
111
|
-
fontSize: 12,
|
|
112
|
-
lineHeight: "20px",
|
|
113
|
-
color: "#475569",
|
|
114
|
-
textAlign: "right",
|
|
115
|
-
fontFamily: '"SF Mono", "Fira Code", "JetBrains Mono", monospace'
|
|
116
|
-
}, children: i + 1 }, i)) }),
|
|
117
|
-
/* @__PURE__ */ jsxRuntime.jsx("pre", { style: {
|
|
118
|
-
margin: 0,
|
|
119
|
-
padding: 12,
|
|
120
|
-
overflow: "auto",
|
|
121
|
-
flex: 1
|
|
122
|
-
}, children: /* @__PURE__ */ jsxRuntime.jsx("code", { style: {
|
|
123
|
-
fontSize: 12,
|
|
124
|
-
lineHeight: "20px",
|
|
125
|
-
fontFamily: '"SF Mono", "Fira Code", "JetBrains Mono", monospace',
|
|
126
|
-
color: "#e2e8f0",
|
|
127
|
-
whiteSpace: "pre"
|
|
128
|
-
}, children: code }) })
|
|
129
|
-
] })
|
|
130
|
-
] });
|
|
131
|
-
}
|
|
132
|
-
function hasCodeBlocks(text) {
|
|
133
|
-
return /```[\s\S]*?```/.test(text);
|
|
134
|
-
}
|
|
135
|
-
function MessageWithCodeBlocks({ text, style }) {
|
|
136
|
-
const parts = text.split(/(```[\s\S]*?```)/g);
|
|
137
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { style, children: parts.map((part, i) => {
|
|
138
|
-
if (part.startsWith("```")) {
|
|
139
|
-
const match = part.match(/^```(\w*)\n?([\s\S]*?)```$/);
|
|
140
|
-
if (match) {
|
|
141
|
-
const lang = match[1] || "";
|
|
142
|
-
const code = match[2].replace(/\n$/, "");
|
|
143
|
-
return /* @__PURE__ */ jsxRuntime.jsx(SingleCodeBlock, { lang, code }, i);
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
if (!part) return null;
|
|
147
|
-
return /* @__PURE__ */ jsxRuntime.jsx("span", { style: { whiteSpace: "pre-wrap" }, children: part }, i);
|
|
148
|
-
}) });
|
|
149
|
-
}
|
|
150
|
-
function htmlToText(html) {
|
|
151
|
-
return html.replace(/<br\s*\/?>/gi, "\n").replace(/<\/(p|div|li|h[1-6]|tr|pre)>/gi, "\n").replace(/<\/?(ul|ol|table|tbody|thead)[^>]*>/gi, "").replace(/<[^>]+>/g, "").replace(/ /g, " ").replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, '"').replace(/'/g, "'").replace(/\n{3,}/g, "\n\n").trim();
|
|
152
|
-
}
|
|
153
|
-
function MessageWithCodeBlocksHtml({ html, style }) {
|
|
154
|
-
const text = htmlToText(html);
|
|
155
|
-
if (!hasCodeBlocks(text)) return null;
|
|
156
|
-
return /* @__PURE__ */ jsxRuntime.jsx(MessageWithCodeBlocks, { text, style });
|
|
157
|
-
}
|
|
158
|
-
function CodeBlockRenderer({ text }) {
|
|
159
|
-
if (!hasCodeBlocks(text)) return null;
|
|
160
|
-
return /* @__PURE__ */ jsxRuntime.jsx(MessageWithCodeBlocks, { text });
|
|
161
|
-
}
|
|
162
|
-
function CodeBlockRendererHtml({ html }) {
|
|
163
|
-
const text = htmlToText(html);
|
|
164
|
-
return /* @__PURE__ */ jsxRuntime.jsx(CodeBlockRenderer, { text });
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
exports.CodeBlockRenderer = CodeBlockRenderer;
|
|
168
|
-
exports.CodeBlockRendererHtml = CodeBlockRendererHtml;
|
|
169
|
-
exports.MessageWithCodeBlocks = MessageWithCodeBlocks;
|
|
170
|
-
exports.MessageWithCodeBlocksHtml = MessageWithCodeBlocksHtml;
|
|
171
|
-
exports.hasCodeBlocks = hasCodeBlocks;
|