@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.
- package/dist/{styles/theme.css → components/TicketConversation.css} +13 -326
- package/dist/components/TicketConversation.js +3004 -0
- package/dist/index.cjs +11 -11
- package/dist/index.js +11 -11
- package/dist/views.cjs +6184 -0
- package/dist/{views/TicketingSettingsView/TicketingSettings.module.scss → views.css} +66 -138
- package/dist/views.d.cts +30 -0
- package/dist/views.d.ts +30 -0
- package/dist/views.js +6165 -0
- package/package.json +14 -7
- package/src/plugin.ts +11 -11
- package/src/views.ts +17 -0
- package/dist/components/TicketConversation/components/AISummaryPanel.js +0 -76
- package/dist/components/TicketConversation/components/ActionPanels.js +0 -118
- package/dist/components/TicketConversation/components/ActivityLog.js +0 -23
- package/dist/components/TicketConversation/components/ClientBar.js +0 -42
- package/dist/components/TicketConversation/components/ClientHistory.js +0 -137
- package/dist/components/TicketConversation/components/CodeBlock.js +0 -152
- package/dist/components/TicketConversation/components/CodeBlockInserter.js +0 -155
- package/dist/components/TicketConversation/components/QuickActions.js +0 -65
- package/dist/components/TicketConversation/components/TicketHeader.js +0 -92
- package/dist/components/TicketConversation/components/TimeTrackingPanel.js +0 -133
- package/dist/components/TicketConversation/config.js +0 -41
- package/dist/components/TicketConversation/constants.js +0 -96
- package/dist/components/TicketConversation/context.js +0 -11
- package/dist/components/TicketConversation/hooks/useAI.js +0 -176
- package/dist/components/TicketConversation/hooks/useMessageActions.js +0 -135
- package/dist/components/TicketConversation/hooks/useReply.js +0 -187
- package/dist/components/TicketConversation/hooks/useTicketActions.js +0 -230
- package/dist/components/TicketConversation/hooks/useTimeTracking.js +0 -122
- package/dist/components/TicketConversation/hooks/useTranslation.js +0 -70
- package/dist/components/TicketConversation/index.js +0 -1123
- package/dist/components/TicketConversation/locales/en.json +0 -878
- package/dist/components/TicketConversation/locales/fr.json +0 -878
- package/dist/components/TicketConversation/types.js +0 -2
- package/dist/components/TicketConversation/utils.js +0 -25
- package/dist/styles/BillingView.module.scss +0 -311
- package/dist/styles/ChatView.module.scss +0 -438
- package/dist/styles/CommandPalette.module.scss +0 -160
- package/dist/styles/CrmView.module.scss +0 -554
- package/dist/styles/EmailTracking.module.scss +0 -238
- package/dist/styles/ImportConversation.module.scss +0 -267
- package/dist/styles/Layout.module.scss +0 -55
- package/dist/styles/Logs.module.scss +0 -164
- package/dist/styles/NewTicket.module.scss +0 -143
- package/dist/styles/PendingEmails.module.scss +0 -629
- package/dist/styles/SupportDashboard.module.scss +0 -649
- package/dist/styles/TicketDetail.module.scss +0 -1050
- package/dist/styles/TicketInbox.module.scss +0 -296
- package/dist/styles/TicketingSettings.module.scss +0 -358
- package/dist/styles/TimeDashboard.module.scss +0 -287
- package/dist/styles/_tokens.scss +0 -78
- package/dist/views/BillingView/client.js +0 -204
- package/dist/views/BillingView/index.js +0 -29
- package/dist/views/ChatView/client.js +0 -252
- package/dist/views/ChatView/index.js +0 -29
- package/dist/views/CrmView/client.js +0 -232
- package/dist/views/CrmView/index.js +0 -29
- package/dist/views/EmailTrackingView/client.js +0 -154
- package/dist/views/EmailTrackingView/index.js +0 -29
- package/dist/views/ImportConversationView/client.js +0 -204
- package/dist/views/ImportConversationView/index.js +0 -29
- package/dist/views/LogsView/client.js +0 -148
- package/dist/views/LogsView/index.js +0 -27
- package/dist/views/NewTicketView/client.js +0 -224
- package/dist/views/NewTicketView/index.js +0 -27
- package/dist/views/PendingEmailsView/client.js +0 -172
- package/dist/views/PendingEmailsView/index.js +0 -29
- package/dist/views/SupportDashboardView/client.js +0 -296
- package/dist/views/SupportDashboardView/index.js +0 -29
- package/dist/views/TicketDetailView/client.js +0 -844
- package/dist/views/TicketDetailView/index.js +0 -29
- package/dist/views/TicketInboxView/client.js +0 -294
- package/dist/views/TicketInboxView/index.js +0 -27
- package/dist/views/TicketingSettingsView/client.js +0 -728
- package/dist/views/TicketingSettingsView/index.js +0 -29
- package/dist/views/TimeDashboardView/client.js +0 -164
- package/dist/views/TimeDashboardView/index.js +0 -29
- package/dist/views/shared/AdminViewHeader.js +0 -67
- package/dist/views/shared/ErrorBoundary.js +0 -50
- package/dist/views/shared/Skeleton.js +0 -72
- package/dist/views/shared/adminTokens.js +0 -32
- package/dist/views/shared/config.js +0 -41
- package/dist/views/shared/index.js +0 -6
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@consilioweb/payload-support",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.1",
|
|
4
4
|
"description": "Payload CMS plugin — professional support & ticketing system with AI, SLA, time tracking, live chat, and more",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -27,13 +27,20 @@
|
|
|
27
27
|
"default": "./dist/client.cjs"
|
|
28
28
|
}
|
|
29
29
|
},
|
|
30
|
-
"./views
|
|
31
|
-
"
|
|
32
|
-
|
|
30
|
+
"./views": {
|
|
31
|
+
"import": {
|
|
32
|
+
"types": "./dist/views.d.ts",
|
|
33
|
+
"default": "./dist/views.js"
|
|
34
|
+
},
|
|
35
|
+
"require": {
|
|
36
|
+
"types": "./dist/views.d.cts",
|
|
37
|
+
"default": "./dist/views.cjs"
|
|
38
|
+
}
|
|
33
39
|
},
|
|
34
|
-
"./components
|
|
35
|
-
"
|
|
36
|
-
|
|
40
|
+
"./components/TicketConversation": {
|
|
41
|
+
"import": {
|
|
42
|
+
"default": "./dist/components/TicketConversation.js"
|
|
43
|
+
}
|
|
37
44
|
}
|
|
38
45
|
},
|
|
39
46
|
"files": [
|
package/src/plugin.ts
CHANGED
|
@@ -106,26 +106,26 @@ export function supportPlugin(config?: SupportPluginConfig): Plugin {
|
|
|
106
106
|
(incomingConfig.admin?.components?.views as Record<string, AdminViewConfig>) || {}
|
|
107
107
|
|
|
108
108
|
const supportViews: Record<string, AdminViewConfig> = {
|
|
109
|
-
'support-inbox': viewConfig(`${viewsBase}
|
|
110
|
-
'support-dashboard': viewConfig(`${viewsBase}
|
|
111
|
-
'support-ticket': viewConfig(`${viewsBase}
|
|
112
|
-
'support-new-ticket': viewConfig(`${viewsBase}
|
|
113
|
-
'support-settings': viewConfig(`${viewsBase}
|
|
114
|
-
'support-logs': viewConfig(`${viewsBase}
|
|
115
|
-
'support-crm': viewConfig(`${viewsBase}
|
|
109
|
+
'support-inbox': viewConfig(`${viewsBase}#TicketInboxView`, `${bp}/inbox`),
|
|
110
|
+
'support-dashboard': viewConfig(`${viewsBase}#SupportDashboardView`, `${bp}/dashboard`),
|
|
111
|
+
'support-ticket': viewConfig(`${viewsBase}#TicketDetailView`, `${bp}/ticket`),
|
|
112
|
+
'support-new-ticket': viewConfig(`${viewsBase}#NewTicketView`, `${bp}/new-ticket`),
|
|
113
|
+
'support-settings': viewConfig(`${viewsBase}#TicketingSettingsView`, `${bp}/settings`),
|
|
114
|
+
'support-logs': viewConfig(`${viewsBase}#LogsView`, `${bp}/logs`),
|
|
115
|
+
'support-crm': viewConfig(`${viewsBase}#CrmView`, `${bp}/crm`),
|
|
116
116
|
}
|
|
117
117
|
|
|
118
118
|
if (features.chat) {
|
|
119
|
-
supportViews['support-chat'] = viewConfig(`${viewsBase}
|
|
119
|
+
supportViews['support-chat'] = viewConfig(`${viewsBase}#ChatView`, `${bp}/chat`)
|
|
120
120
|
}
|
|
121
121
|
if (features.pendingEmails) {
|
|
122
|
-
supportViews['support-emails'] = viewConfig(`${viewsBase}
|
|
122
|
+
supportViews['support-emails'] = viewConfig(`${viewsBase}#PendingEmailsView`, `${bp}/emails`)
|
|
123
123
|
}
|
|
124
124
|
if (features.emailTracking) {
|
|
125
|
-
supportViews['support-tracking'] = viewConfig(`${viewsBase}
|
|
125
|
+
supportViews['support-tracking'] = viewConfig(`${viewsBase}#EmailTrackingView`, `${bp}/tracking`)
|
|
126
126
|
}
|
|
127
127
|
if (features.timeTracking) {
|
|
128
|
-
supportViews['support-time'] = viewConfig(`${viewsBase}
|
|
128
|
+
supportViews['support-time'] = viewConfig(`${viewsBase}#TimeDashboardView`, `${bp}/time`)
|
|
129
129
|
}
|
|
130
130
|
|
|
131
131
|
// ─── Endpoints ───────────────────────────────────────
|
package/src/views.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// Admin views barrel — server components exported for Payload importMap
|
|
2
|
+
// Pattern copied from @consilioweb/payload-admin-theme which works reliably
|
|
3
|
+
// with Next.js transpilePackages.
|
|
4
|
+
|
|
5
|
+
export { default as TicketInboxView } from './views/TicketInboxView/index'
|
|
6
|
+
export { default as TicketDetailView } from './views/TicketDetailView/index'
|
|
7
|
+
export { default as SupportDashboardView } from './views/SupportDashboardView/index'
|
|
8
|
+
export { default as NewTicketView } from './views/NewTicketView/index'
|
|
9
|
+
export { default as TicketingSettingsView } from './views/TicketingSettingsView/index'
|
|
10
|
+
export { default as LogsView } from './views/LogsView/index'
|
|
11
|
+
export { default as ChatView } from './views/ChatView/index'
|
|
12
|
+
export { default as CrmView } from './views/CrmView/index'
|
|
13
|
+
export { default as PendingEmailsView } from './views/PendingEmailsView/index'
|
|
14
|
+
export { default as EmailTrackingView } from './views/EmailTrackingView/index'
|
|
15
|
+
export { default as BillingView } from './views/BillingView/index'
|
|
16
|
+
export { default as TimeDashboardView } from './views/TimeDashboardView/index'
|
|
17
|
+
export { default as ImportConversationView } from './views/ImportConversationView/index'
|
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
3
|
-
import { s } from '../constants';
|
|
4
|
-
|
|
5
|
-
function AISummaryPanel({
|
|
6
|
-
showAiSummary,
|
|
7
|
-
setShowAiSummary,
|
|
8
|
-
aiSummary,
|
|
9
|
-
aiGenerating,
|
|
10
|
-
aiSaving,
|
|
11
|
-
aiSaved,
|
|
12
|
-
handleAiGenerate,
|
|
13
|
-
handleAiSave
|
|
14
|
-
}) {
|
|
15
|
-
return /* @__PURE__ */ jsxs("div", { style: { marginBottom: "14px" }, children: [
|
|
16
|
-
/* @__PURE__ */ jsx(
|
|
17
|
-
"button",
|
|
18
|
-
{
|
|
19
|
-
onClick: () => {
|
|
20
|
-
setShowAiSummary(!showAiSummary);
|
|
21
|
-
if (!showAiSummary && !aiSummary) handleAiGenerate();
|
|
22
|
-
},
|
|
23
|
-
style: {
|
|
24
|
-
...s.ghostBtn("#7c3aed", false),
|
|
25
|
-
fontSize: "12px",
|
|
26
|
-
display: "inline-flex",
|
|
27
|
-
alignItems: "center",
|
|
28
|
-
gap: "6px"
|
|
29
|
-
},
|
|
30
|
-
children: showAiSummary ? "Masquer la synth\xE8se IA" : "Synth\xE8se IA"
|
|
31
|
-
}
|
|
32
|
-
),
|
|
33
|
-
showAiSummary && /* @__PURE__ */ jsxs("div", { style: {
|
|
34
|
-
marginTop: "10px",
|
|
35
|
-
padding: "14px 18px",
|
|
36
|
-
borderRadius: "8px",
|
|
37
|
-
backgroundColor: "#faf5ff",
|
|
38
|
-
border: "1px solid #e9d5ff"
|
|
39
|
-
}, children: [
|
|
40
|
-
/* @__PURE__ */ jsxs("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: "10px" }, children: [
|
|
41
|
-
/* @__PURE__ */ jsx("h4", { style: { fontSize: "13px", fontWeight: 600, color: "#7c3aed", margin: 0 }, children: "Synth\xE8se IA" }),
|
|
42
|
-
/* @__PURE__ */ jsxs("div", { style: { display: "flex", gap: "6px" }, children: [
|
|
43
|
-
/* @__PURE__ */ jsx(
|
|
44
|
-
"button",
|
|
45
|
-
{
|
|
46
|
-
onClick: handleAiGenerate,
|
|
47
|
-
disabled: aiGenerating,
|
|
48
|
-
style: { ...s.outlineBtn("#7c3aed", aiGenerating), fontSize: "11px", padding: "4px 10px" },
|
|
49
|
-
children: aiGenerating ? "G\xE9n\xE9ration..." : "R\xE9g\xE9n\xE9rer"
|
|
50
|
-
}
|
|
51
|
-
),
|
|
52
|
-
aiSummary && !aiGenerating && /* @__PURE__ */ jsx(
|
|
53
|
-
"button",
|
|
54
|
-
{
|
|
55
|
-
onClick: handleAiSave,
|
|
56
|
-
disabled: aiSaving || aiSaved,
|
|
57
|
-
style: { ...s.btn(aiSaved ? "#16a34a" : "#2563eb", aiSaving), fontSize: "11px", padding: "4px 10px" },
|
|
58
|
-
children: aiSaved ? "Sauvegard\xE9" : aiSaving ? "Sauvegarde..." : "Sauvegarder (note interne)"
|
|
59
|
-
}
|
|
60
|
-
)
|
|
61
|
-
] })
|
|
62
|
-
] }),
|
|
63
|
-
aiGenerating ? /* @__PURE__ */ jsx("div", { style: { display: "flex", alignItems: "center", gap: "10px", color: "#7c3aed", fontSize: "13px" }, children: "Analyse de la conversation en cours..." }) : aiSummary ? /* @__PURE__ */ jsx(
|
|
64
|
-
"div",
|
|
65
|
-
{
|
|
66
|
-
style: { fontSize: "13px", lineHeight: "1.7", color: "#1e1b4b", whiteSpace: "pre-wrap" },
|
|
67
|
-
dangerouslySetInnerHTML: {
|
|
68
|
-
__html: aiSummary.replace(/\*\*(.*?)\*\*/g, "<strong>$1</strong>").replace(/\n/g, "<br/>")
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
) : /* @__PURE__ */ jsx("p", { style: { color: "#999", fontStyle: "italic", fontSize: "13px", margin: 0 }, children: `Cliquez sur "R\xE9g\xE9n\xE9rer" pour lancer l'analyse` })
|
|
72
|
-
] })
|
|
73
|
-
] });
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
export { AISummaryPanel };
|
|
@@ -1,118 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
3
|
-
import { useRef } from 'react';
|
|
4
|
-
import { s } from '../constants';
|
|
5
|
-
|
|
6
|
-
function MergePanel({
|
|
7
|
-
mergeTarget,
|
|
8
|
-
setMergeTarget,
|
|
9
|
-
mergeTargetInfo,
|
|
10
|
-
setMergeTargetInfo,
|
|
11
|
-
mergeError,
|
|
12
|
-
setMergeError,
|
|
13
|
-
merging,
|
|
14
|
-
handleMergeLookup,
|
|
15
|
-
handleMerge
|
|
16
|
-
}) {
|
|
17
|
-
return /* @__PURE__ */ jsxs("div", { style: { padding: "14px 18px", borderRadius: "8px", backgroundColor: "#fdf2f8", border: "1px solid #fbcfe8", marginBottom: "14px" }, children: [
|
|
18
|
-
/* @__PURE__ */ jsx("h4", { style: { fontSize: "13px", fontWeight: 600, marginBottom: "10px", color: "#831843" }, children: "Fusionner ce ticket dans un autre" }),
|
|
19
|
-
/* @__PURE__ */ jsxs("div", { style: { display: "flex", gap: "8px", alignItems: "center", marginBottom: "8px" }, children: [
|
|
20
|
-
/* @__PURE__ */ jsx(
|
|
21
|
-
"input",
|
|
22
|
-
{
|
|
23
|
-
type: "text",
|
|
24
|
-
value: mergeTarget,
|
|
25
|
-
onChange: (e) => {
|
|
26
|
-
setMergeTarget(e.target.value);
|
|
27
|
-
setMergeTargetInfo(null);
|
|
28
|
-
setMergeError("");
|
|
29
|
-
},
|
|
30
|
-
placeholder: "TK-0001",
|
|
31
|
-
style: { ...s.input, width: "130px" }
|
|
32
|
-
}
|
|
33
|
-
),
|
|
34
|
-
/* @__PURE__ */ jsx("button", { onClick: handleMergeLookup, style: { ...s.outlineBtn("#ec4899"), fontSize: "12px", padding: "6px 14px" }, children: "Rechercher" }),
|
|
35
|
-
mergeError && /* @__PURE__ */ jsx("span", { style: { fontSize: "12px", color: "#be185d", fontWeight: 600 }, children: mergeError })
|
|
36
|
-
] }),
|
|
37
|
-
mergeTargetInfo && /* @__PURE__ */ jsxs("div", { style: { display: "flex", gap: "8px", alignItems: "center" }, children: [
|
|
38
|
-
/* @__PURE__ */ jsxs("span", { style: { fontSize: "13px", fontWeight: 600 }, children: [
|
|
39
|
-
mergeTargetInfo.ticketNumber,
|
|
40
|
-
" \u2014 ",
|
|
41
|
-
mergeTargetInfo.subject
|
|
42
|
-
] }),
|
|
43
|
-
/* @__PURE__ */ jsx("button", { onClick: handleMerge, disabled: merging, style: { ...s.btn("#ec4899", merging), color: "#fff", fontSize: "12px", padding: "6px 14px" }, children: merging ? "Fusion..." : "Confirmer la fusion" })
|
|
44
|
-
] })
|
|
45
|
-
] });
|
|
46
|
-
}
|
|
47
|
-
function ExtMessagePanel({
|
|
48
|
-
extMsgBody,
|
|
49
|
-
setExtMsgBody,
|
|
50
|
-
extMsgAuthor,
|
|
51
|
-
setExtMsgAuthor,
|
|
52
|
-
extMsgDate,
|
|
53
|
-
setExtMsgDate,
|
|
54
|
-
extMsgFiles,
|
|
55
|
-
setExtMsgFiles,
|
|
56
|
-
sendingExtMsg,
|
|
57
|
-
handleSendExtMsg,
|
|
58
|
-
handleExtFileChange
|
|
59
|
-
}) {
|
|
60
|
-
const extFileInputRef = useRef(null);
|
|
61
|
-
return /* @__PURE__ */ jsxs("div", { style: { padding: "14px 18px", borderRadius: "8px", backgroundColor: "#eef2ff", border: "1px solid #c7d2fe", marginBottom: "14px" }, children: [
|
|
62
|
-
/* @__PURE__ */ jsx("h4", { style: { fontSize: "13px", fontWeight: 600, marginBottom: "10px", color: "#312e81" }, children: "Ajouter un message re\xE7u (email, SMS, WhatsApp...)" }),
|
|
63
|
-
/* @__PURE__ */ jsx(
|
|
64
|
-
"textarea",
|
|
65
|
-
{
|
|
66
|
-
value: extMsgBody,
|
|
67
|
-
onChange: (e) => setExtMsgBody(e.target.value),
|
|
68
|
-
placeholder: "Coller le contenu du message re\xE7u...",
|
|
69
|
-
rows: 3,
|
|
70
|
-
style: { ...s.input, width: "100%", resize: "vertical", marginBottom: "10px" }
|
|
71
|
-
}
|
|
72
|
-
),
|
|
73
|
-
/* @__PURE__ */ jsxs("div", { style: { display: "flex", gap: "8px", alignItems: "center", flexWrap: "wrap", marginBottom: "10px" }, children: [
|
|
74
|
-
/* @__PURE__ */ jsxs("select", { value: extMsgAuthor, onChange: (e) => setExtMsgAuthor(e.target.value), style: { ...s.input, fontSize: "12px" }, children: [
|
|
75
|
-
/* @__PURE__ */ jsx("option", { value: "client", children: "Envoy\xE9 par le client" }),
|
|
76
|
-
/* @__PURE__ */ jsx("option", { value: "admin", children: "Envoy\xE9 par le support" })
|
|
77
|
-
] }),
|
|
78
|
-
/* @__PURE__ */ jsx(
|
|
79
|
-
"input",
|
|
80
|
-
{
|
|
81
|
-
type: "datetime-local",
|
|
82
|
-
value: extMsgDate,
|
|
83
|
-
onChange: (e) => setExtMsgDate(e.target.value),
|
|
84
|
-
style: { ...s.input, fontSize: "12px" }
|
|
85
|
-
}
|
|
86
|
-
),
|
|
87
|
-
/* @__PURE__ */ jsx("input", { ref: extFileInputRef, type: "file", multiple: true, onChange: handleExtFileChange, style: { display: "none" }, accept: "image/*,.pdf,.doc,.docx,.txt,.zip" }),
|
|
88
|
-
/* @__PURE__ */ jsx("button", { type: "button", onClick: () => extFileInputRef.current?.click(), style: { ...s.ghostBtn("#6b7280"), fontSize: "12px", padding: "6px 12px" }, children: "+ PJ" })
|
|
89
|
-
] }),
|
|
90
|
-
extMsgFiles.length > 0 && /* @__PURE__ */ jsx("div", { style: { marginBottom: "10px", display: "flex", gap: "6px", flexWrap: "wrap" }, children: extMsgFiles.map((file, i) => /* @__PURE__ */ jsxs("span", { style: { ...s.badge("#f1f5f9", "#374151"), display: "inline-flex", alignItems: "center", gap: "4px" }, children: [
|
|
91
|
-
file.name,
|
|
92
|
-
/* @__PURE__ */ 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" })
|
|
93
|
-
] }, i)) }),
|
|
94
|
-
/* @__PURE__ */ jsx("button", { onClick: handleSendExtMsg, disabled: sendingExtMsg || !extMsgBody.trim(), style: s.btn("#818cf8", sendingExtMsg || !extMsgBody.trim()), children: sendingExtMsg ? "Ajout..." : "Ajouter (sans notification)" })
|
|
95
|
-
] });
|
|
96
|
-
}
|
|
97
|
-
function SnoozePanel({ snoozeSaving, handleSnooze }) {
|
|
98
|
-
return /* @__PURE__ */ jsxs("div", { style: { padding: "14px 18px", borderRadius: "8px", backgroundColor: "#faf5ff", border: "1px solid #e9d5ff", marginBottom: "14px" }, children: [
|
|
99
|
-
/* @__PURE__ */ jsx("h4", { style: { fontSize: "13px", fontWeight: 600, marginBottom: "10px", color: "#5b21b6" }, children: "Snooze \u2014 masquer temporairement" }),
|
|
100
|
-
/* @__PURE__ */ jsxs("div", { style: { display: "flex", gap: "8px", flexWrap: "wrap", alignItems: "center" }, children: [
|
|
101
|
-
/* @__PURE__ */ jsx("button", { onClick: () => handleSnooze(1), disabled: snoozeSaving, style: { ...s.outlineBtn("#8b5cf6", snoozeSaving), fontSize: "12px" }, children: "1 jour" }),
|
|
102
|
-
/* @__PURE__ */ jsx("button", { onClick: () => handleSnooze(3), disabled: snoozeSaving, style: { ...s.outlineBtn("#8b5cf6", snoozeSaving), fontSize: "12px" }, children: "3 jours" }),
|
|
103
|
-
/* @__PURE__ */ jsx("button", { onClick: () => handleSnooze(7), disabled: snoozeSaving, style: { ...s.outlineBtn("#8b5cf6", snoozeSaving), fontSize: "12px" }, children: "1 semaine" }),
|
|
104
|
-
/* @__PURE__ */ jsx(
|
|
105
|
-
"input",
|
|
106
|
-
{
|
|
107
|
-
type: "datetime-local",
|
|
108
|
-
onChange: (e) => {
|
|
109
|
-
if (e.target.value) handleSnooze(null, e.target.value);
|
|
110
|
-
},
|
|
111
|
-
style: { ...s.input, fontSize: "12px" }
|
|
112
|
-
}
|
|
113
|
-
)
|
|
114
|
-
] })
|
|
115
|
-
] });
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
export { ExtMessagePanel, MergePanel, SnoozePanel };
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
3
|
-
import { useState } from 'react';
|
|
4
|
-
import { s, C } from '../constants';
|
|
5
|
-
|
|
6
|
-
function ActivityLog({ activityLog }) {
|
|
7
|
-
const [showActivity, setShowActivity] = useState(false);
|
|
8
|
-
return /* @__PURE__ */ jsxs("div", { style: s.section, children: [
|
|
9
|
-
/* @__PURE__ */ jsxs("h4", { style: { ...s.sectionTitle, cursor: "pointer" }, onClick: () => setShowActivity(!showActivity), children: [
|
|
10
|
-
"Historique ",
|
|
11
|
-
/* @__PURE__ */ jsx("span", { style: s.badge("#f1f5f9", "#475569"), children: activityLog.length }),
|
|
12
|
-
/* @__PURE__ */ jsx("span", { style: { fontSize: "12px", color: C.textMuted, transition: "transform 0.2s", display: "inline-block", transform: showActivity ? "rotate(90deg)" : "none" }, children: "\u25B6" })
|
|
13
|
-
] }),
|
|
14
|
-
showActivity && (activityLog.length === 0 ? /* @__PURE__ */ jsx("p", { style: { fontSize: "12px", color: C.textMuted, fontStyle: "italic" }, children: "Aucune activit\xE9 enregistr\xE9e." }) : /* @__PURE__ */ jsx("div", { style: { fontSize: "12px", display: "flex", flexDirection: "column", gap: "2px", borderLeft: "2px solid #bfdbfe", paddingLeft: "14px", marginLeft: "4px" }, children: activityLog.map((entry) => /* @__PURE__ */ jsxs("div", { style: { display: "flex", gap: "10px", alignItems: "center", padding: "5px 0", borderBottom: "1px solid #f8fafc" }, children: [
|
|
15
|
-
/* @__PURE__ */ jsx("span", { style: { color: 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" }) }),
|
|
16
|
-
/* @__PURE__ */ jsx("span", { style: s.badge(entry.actorType === "admin" ? "#eff6ff" : "#dcfce7", entry.actorType === "admin" ? "#1e40af" : "#166534"), children: entry.actorType || "system" }),
|
|
17
|
-
/* @__PURE__ */ jsx("span", { style: { color: "#374151", fontWeight: 500 }, children: (entry.detail || entry.action).replace(/\[object Object\]/g, "(utilisateur)") }),
|
|
18
|
-
/* @__PURE__ */ jsx("span", { style: { color: C.textMuted, fontSize: "11px" }, children: entry.actorEmail })
|
|
19
|
-
] }, entry.id)) }))
|
|
20
|
-
] });
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export { ActivityLog };
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
3
|
-
import { C, s } from '../constants';
|
|
4
|
-
|
|
5
|
-
function ClientBar({ client }) {
|
|
6
|
-
return /* @__PURE__ */ jsxs("div", { style: {
|
|
7
|
-
display: "flex",
|
|
8
|
-
alignItems: "center",
|
|
9
|
-
gap: "12px",
|
|
10
|
-
padding: "10px 16px",
|
|
11
|
-
borderRadius: "8px",
|
|
12
|
-
backgroundColor: "var(--theme-elevation-100)",
|
|
13
|
-
marginBottom: "16px",
|
|
14
|
-
flexWrap: "wrap"
|
|
15
|
-
}, children: [
|
|
16
|
-
/* @__PURE__ */ jsx("span", { style: { fontSize: "16px" }, children: "\u{1F464}" }),
|
|
17
|
-
/* @__PURE__ */ jsx("span", { style: { fontWeight: 700, fontSize: "13px", color: C.textPrimary }, children: client.company }),
|
|
18
|
-
/* @__PURE__ */ jsxs("span", { style: { color: C.textSecondary, fontSize: "13px" }, children: [
|
|
19
|
-
client.firstName,
|
|
20
|
-
" ",
|
|
21
|
-
client.lastName
|
|
22
|
-
] }),
|
|
23
|
-
/* @__PURE__ */ jsx("span", { style: { color: C.textMuted, fontSize: "12px" }, children: "|" }),
|
|
24
|
-
/* @__PURE__ */ jsx("a", { href: `mailto:${client.email}`, style: { color: "#2563eb", fontSize: "12px", fontWeight: 600, textDecoration: "none" }, children: client.email }),
|
|
25
|
-
client.phone && /* @__PURE__ */ jsx("span", { style: { color: C.textSecondary, fontSize: "12px" }, children: client.phone }),
|
|
26
|
-
/* @__PURE__ */ jsxs("span", { style: { marginLeft: "auto", display: "inline-flex", gap: "8px", alignItems: "center" }, children: [
|
|
27
|
-
/* @__PURE__ */ jsx("a", { href: `/admin/collections/support-clients/${client.id}`, style: { ...s.ghostBtn("#475569"), fontSize: "11px", padding: "4px 10px", textDecoration: "none" }, children: "Fiche client" }),
|
|
28
|
-
/* @__PURE__ */ jsx(
|
|
29
|
-
"button",
|
|
30
|
-
{
|
|
31
|
-
type: "button",
|
|
32
|
-
onClick: () => window.open(`/api/admin/impersonate?clientId=${client.id}`, "_blank"),
|
|
33
|
-
style: { ...s.ghostBtn("#7c3aed"), fontSize: "11px", padding: "4px 10px" },
|
|
34
|
-
title: "Se connecter au portail support en tant que ce client",
|
|
35
|
-
children: "Voir en tant que client"
|
|
36
|
-
}
|
|
37
|
-
)
|
|
38
|
-
] })
|
|
39
|
-
] });
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
export { ClientBar };
|
|
@@ -1,137 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
3
|
-
import { useState } from 'react';
|
|
4
|
-
import { s, C, statusLabels, projectStatusLabels } from '../constants';
|
|
5
|
-
|
|
6
|
-
function ClientHistory({
|
|
7
|
-
client: _client,
|
|
8
|
-
clientTickets,
|
|
9
|
-
clientProjects,
|
|
10
|
-
clientNotes,
|
|
11
|
-
onNotesChange,
|
|
12
|
-
onNotesSave,
|
|
13
|
-
savingNotes,
|
|
14
|
-
notesSaved
|
|
15
|
-
}) {
|
|
16
|
-
const [showClientHistory, setShowClientHistory] = useState(false);
|
|
17
|
-
return /* @__PURE__ */ jsxs("div", { style: s.section, children: [
|
|
18
|
-
/* @__PURE__ */ jsxs(
|
|
19
|
-
"button",
|
|
20
|
-
{
|
|
21
|
-
type: "button",
|
|
22
|
-
onClick: () => setShowClientHistory(!showClientHistory),
|
|
23
|
-
style: {
|
|
24
|
-
background: "none",
|
|
25
|
-
border: `1px dashed ${C.border}`,
|
|
26
|
-
borderRadius: "6px",
|
|
27
|
-
padding: "8px 14px",
|
|
28
|
-
cursor: "pointer",
|
|
29
|
-
color: C.textSecondary,
|
|
30
|
-
fontSize: "13px",
|
|
31
|
-
fontWeight: 600,
|
|
32
|
-
width: "100%",
|
|
33
|
-
textAlign: "left",
|
|
34
|
-
display: "flex",
|
|
35
|
-
alignItems: "center",
|
|
36
|
-
justifyContent: "space-between"
|
|
37
|
-
},
|
|
38
|
-
children: [
|
|
39
|
-
/* @__PURE__ */ jsxs("span", { children: [
|
|
40
|
-
"Historique client (",
|
|
41
|
-
clientTickets.length,
|
|
42
|
-
" ticket",
|
|
43
|
-
clientTickets.length !== 1 ? "s" : "",
|
|
44
|
-
", ",
|
|
45
|
-
clientProjects.length,
|
|
46
|
-
" projet",
|
|
47
|
-
clientProjects.length !== 1 ? "s" : "",
|
|
48
|
-
")"
|
|
49
|
-
] }),
|
|
50
|
-
/* @__PURE__ */ jsx("span", { style: { fontSize: "12px", transition: "transform 0.2s", display: "inline-block", transform: showClientHistory ? "rotate(90deg)" : "none" }, children: "\u25B6" })
|
|
51
|
-
]
|
|
52
|
-
}
|
|
53
|
-
),
|
|
54
|
-
showClientHistory && /* @__PURE__ */ jsxs("div", { style: { marginTop: "10px", padding: "14px 18px", borderRadius: "8px", backgroundColor: C.white, border: `1px solid ${C.border}` }, children: [
|
|
55
|
-
/* @__PURE__ */ jsx("h5", { style: { fontSize: "12px", fontWeight: 600, color: C.textSecondary, marginBottom: "8px" }, children: "Derniers tickets" }),
|
|
56
|
-
clientTickets.length === 0 ? /* @__PURE__ */ jsx("p", { style: { fontSize: "12px", color: C.textMuted, fontStyle: "italic", marginBottom: "14px" }, children: "Aucun autre ticket" }) : /* @__PURE__ */ jsx("div", { style: { display: "flex", flexDirection: "column", gap: "4px", marginBottom: "14px" }, children: clientTickets.map((t) => {
|
|
57
|
-
const st = statusLabels[t.status] || statusLabels.open;
|
|
58
|
-
return /* @__PURE__ */ jsxs(
|
|
59
|
-
"a",
|
|
60
|
-
{
|
|
61
|
-
href: `/admin/support/ticket?id=${t.id}`,
|
|
62
|
-
style: {
|
|
63
|
-
display: "flex",
|
|
64
|
-
alignItems: "center",
|
|
65
|
-
gap: "8px",
|
|
66
|
-
padding: "6px 10px",
|
|
67
|
-
borderRadius: "6px",
|
|
68
|
-
border: `1px solid ${C.border}`,
|
|
69
|
-
textDecoration: "none",
|
|
70
|
-
fontSize: "12px",
|
|
71
|
-
color: "#374151",
|
|
72
|
-
backgroundColor: "#fafafa"
|
|
73
|
-
},
|
|
74
|
-
children: [
|
|
75
|
-
/* @__PURE__ */ jsx("span", { style: { fontFamily: "'SF Mono', 'Fira Code', 'JetBrains Mono', 'Cascadia Code', monospace", fontWeight: 600, color: C.textMuted, fontSize: "11px", whiteSpace: "nowrap" }, children: t.ticketNumber }),
|
|
76
|
-
/* @__PURE__ */ jsx("span", { style: { flex: 1, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap", fontWeight: 600 }, children: t.subject }),
|
|
77
|
-
/* @__PURE__ */ jsx("span", { style: s.badge(st.bg, st.color), children: st.label }),
|
|
78
|
-
/* @__PURE__ */ jsx("span", { style: { fontSize: "10px", color: C.textMuted, whiteSpace: "nowrap" }, children: new Date(t.createdAt).toLocaleDateString("fr-FR", { day: "numeric", month: "short" }) })
|
|
79
|
-
]
|
|
80
|
-
},
|
|
81
|
-
t.id
|
|
82
|
-
);
|
|
83
|
-
}) }),
|
|
84
|
-
/* @__PURE__ */ jsx("h5", { style: { fontSize: "12px", fontWeight: 600, color: C.textSecondary, marginBottom: "8px" }, children: "Projets" }),
|
|
85
|
-
clientProjects.length === 0 ? /* @__PURE__ */ jsx("p", { style: { fontSize: "12px", color: C.textMuted, fontStyle: "italic", marginBottom: "14px" }, children: "Aucun projet" }) : /* @__PURE__ */ jsx("div", { style: { display: "flex", gap: "6px", flexWrap: "wrap", marginBottom: "14px" }, children: clientProjects.map((p) => {
|
|
86
|
-
const ps = projectStatusLabels[p.status] || projectStatusLabels.active;
|
|
87
|
-
return /* @__PURE__ */ jsxs(
|
|
88
|
-
"a",
|
|
89
|
-
{
|
|
90
|
-
href: `/admin/collections/projects/${p.id}`,
|
|
91
|
-
style: {
|
|
92
|
-
display: "inline-flex",
|
|
93
|
-
alignItems: "center",
|
|
94
|
-
gap: "6px",
|
|
95
|
-
padding: "5px 10px",
|
|
96
|
-
borderRadius: "6px",
|
|
97
|
-
border: `1px solid ${C.border}`,
|
|
98
|
-
textDecoration: "none",
|
|
99
|
-
fontSize: "12px",
|
|
100
|
-
fontWeight: 600,
|
|
101
|
-
color: "#374151",
|
|
102
|
-
backgroundColor: "#fafafa"
|
|
103
|
-
},
|
|
104
|
-
children: [
|
|
105
|
-
p.name,
|
|
106
|
-
/* @__PURE__ */ jsx("span", { style: s.badge(ps.bg, ps.color), children: ps.label })
|
|
107
|
-
]
|
|
108
|
-
},
|
|
109
|
-
p.id
|
|
110
|
-
);
|
|
111
|
-
}) }),
|
|
112
|
-
/* @__PURE__ */ jsx("h5", { style: { fontSize: "12px", fontWeight: 600, color: C.textSecondary, marginBottom: "8px" }, children: "Notes internes" }),
|
|
113
|
-
/* @__PURE__ */ jsx(
|
|
114
|
-
"textarea",
|
|
115
|
-
{
|
|
116
|
-
value: clientNotes,
|
|
117
|
-
onChange: (e) => onNotesChange(e.target.value),
|
|
118
|
-
rows: 3,
|
|
119
|
-
style: { ...s.input, width: "100%", resize: "vertical", fontSize: "12px", marginBottom: "8px" },
|
|
120
|
-
placeholder: "Notes sur ce client..."
|
|
121
|
-
}
|
|
122
|
-
),
|
|
123
|
-
/* @__PURE__ */ jsx(
|
|
124
|
-
"button",
|
|
125
|
-
{
|
|
126
|
-
type: "button",
|
|
127
|
-
onClick: onNotesSave,
|
|
128
|
-
disabled: savingNotes,
|
|
129
|
-
style: { ...s.btn(notesSaved ? "#16a34a" : C.blue, savingNotes), fontSize: "11px", padding: "5px 12px" },
|
|
130
|
-
children: notesSaved ? "Sauvegarde OK" : savingNotes ? "Sauvegarde..." : "Sauvegarder les notes"
|
|
131
|
-
}
|
|
132
|
-
)
|
|
133
|
-
] })
|
|
134
|
-
] });
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
export { ClientHistory };
|
|
@@ -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 };
|