@consilioweb/payload-support 0.16.0 → 1.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 +347 -435
- package/dist/components/TicketConversation/RewriteDropdown.cjs +98 -0
- package/dist/components/TicketConversation/RewriteDropdown.js +93 -0
- package/dist/components/TicketConversation/SkeletonText.cjs +21 -0
- package/dist/components/TicketConversation/SkeletonText.js +20 -0
- package/dist/components/TicketConversation/constants.cjs +27 -0
- package/dist/components/TicketConversation/constants.js +26 -1
- package/dist/components/TicketConversation/hooks/useDocumentIdFromUrl.cjs +20 -0
- package/dist/components/TicketConversation/hooks/useDocumentIdFromUrl.js +19 -0
- package/dist/components/TicketConversation/index.cjs +10 -147
- package/dist/components/TicketConversation/index.js +4 -141
- package/dist/index.cjs +1604 -671
- package/dist/index.d.cts +3 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +1602 -671
- package/dist/views/BillingView/client.cjs +40 -54
- package/dist/views/BillingView/client.js +40 -54
- package/dist/views/ChatView/client.cjs +4 -3
- package/dist/views/ChatView/client.js +4 -3
- package/dist/views/CrmView/client.cjs +7 -7
- package/dist/views/CrmView/client.js +7 -7
- package/dist/views/EmailTrackingView/client.cjs +6 -5
- package/dist/views/EmailTrackingView/client.js +6 -5
- package/dist/views/ImportConversationView/client.cjs +4 -4
- package/dist/views/ImportConversationView/client.js +4 -4
- package/dist/views/LogsView/client.cjs +3 -2
- package/dist/views/LogsView/client.js +3 -2
- package/dist/views/NewTicketView/client.cjs +1 -1
- package/dist/views/NewTicketView/client.js +1 -1
- package/dist/views/PendingEmailsView/client.cjs +7 -6
- package/dist/views/PendingEmailsView/client.js +7 -6
- package/dist/views/SupportDashboardView/client.cjs +19 -22
- package/dist/views/SupportDashboardView/client.js +19 -22
- package/dist/views/TicketDetailView/NextActionItem.cjs +40 -0
- package/dist/views/TicketDetailView/NextActionItem.js +34 -0
- package/dist/views/TicketDetailView/RewriteDropdown.cjs +80 -0
- package/dist/views/TicketDetailView/RewriteDropdown.js +78 -0
- package/dist/views/TicketDetailView/client.cjs +59 -190
- package/dist/views/TicketDetailView/client.js +52 -183
- package/dist/views/TicketDetailView/constants.cjs +20 -0
- package/dist/views/TicketDetailView/constants.js +16 -0
- package/dist/views/TicketDetailView/helpers.cjs +23 -0
- package/dist/views/TicketDetailView/helpers.js +20 -0
- package/dist/views/TicketDetailView/types.cjs +2 -0
- package/dist/views/TicketDetailView/types.js +1 -0
- package/dist/views/TicketInboxView/client.cjs +14 -10
- package/dist/views/TicketInboxView/client.js +14 -10
- package/dist/views/TicketingSettingsView/client.cjs +101 -96
- package/dist/views/TicketingSettingsView/client.js +92 -88
- package/dist/views/TimeDashboardView/client.cjs +2 -2
- package/dist/views/TimeDashboardView/client.js +2 -2
- package/dist/views/shared/StatusPill.cjs +23 -12
- package/dist/views/shared/StatusPill.js +23 -12
- package/dist/views/shared/dateLocale.cjs +5 -0
- package/dist/views/shared/dateLocale.js +3 -0
- package/package.json +23 -15
- package/src/__tests__/generateTrackingToken.test.ts +53 -0
- package/src/__tests__/integration/ai-agent.test.ts +46 -0
- package/src/__tests__/integration/auth.test.ts +43 -0
- package/src/__tests__/integration/automation-rules.test.ts +68 -0
- package/src/__tests__/integration/buildTestPayload.ts +52 -0
- package/src/__tests__/integration/channels.test.ts +52 -0
- package/src/__tests__/integration/core-behaviors.test.ts +58 -0
- package/src/__tests__/integration/dashboard-volume.test.ts +31 -0
- package/src/__tests__/integration/digest.test.ts +48 -0
- package/src/__tests__/integration/invoice-pdf.test.ts +30 -0
- package/src/__tests__/integration/isolation.test.ts +81 -0
- package/src/__tests__/integration/mentions-invoice.test.ts +50 -0
- package/src/__tests__/integration/nps.test.ts +37 -0
- package/src/__tests__/integration/sanitization.test.ts +35 -0
- package/src/__tests__/integration/sla-pause.test.ts +39 -0
- package/src/__tests__/integration/smoke.test.ts +26 -0
- package/src/__tests__/integration/snooze.test.ts +68 -0
- package/src/__tests__/integration/teams.test.ts +38 -0
- package/src/__tests__/rateLimiter.test.ts +89 -0
- package/src/__tests__/sanitizeHtml.test.ts +165 -0
- package/src/__tests__/sla.test.ts +258 -0
- package/src/collections/AutomationRules.ts +66 -0
- package/src/collections/NotificationQueue.ts +30 -0
- package/src/collections/SatisfactionSurveys.ts +11 -2
- package/src/collections/SupportClients.ts +58 -1
- package/src/collections/SupportTeam.ts +27 -0
- package/src/collections/TicketActivityLog.ts +9 -4
- package/src/collections/TicketMessages.ts +129 -31
- package/src/collections/Tickets.ts +31 -73
- package/src/collections/index.ts +3 -0
- package/src/components/TicketConversation/RewriteDropdown.tsx +86 -0
- package/src/components/TicketConversation/SkeletonText.tsx +23 -0
- package/src/components/TicketConversation/constants.ts +29 -0
- package/src/components/TicketConversation/hooks/useDocumentIdFromUrl.ts +21 -0
- package/src/components/TicketConversation/index.tsx +4 -152
- package/src/endpoints/admin-chat-stream.ts +3 -4
- package/src/endpoints/admin-chat.ts +11 -20
- package/src/endpoints/admin-stats.ts +70 -32
- package/src/endpoints/ai-agent.ts +36 -0
- package/src/endpoints/apply-macro.ts +8 -14
- package/src/endpoints/auth-2fa.ts +12 -12
- package/src/endpoints/auto-close.ts +6 -10
- package/src/endpoints/billing.ts +17 -4
- package/src/endpoints/bulk-action.ts +7 -12
- package/src/endpoints/channels.ts +89 -0
- package/src/endpoints/chat-stream.ts +3 -4
- package/src/endpoints/chat.ts +7 -12
- package/src/endpoints/chatbot.ts +2 -2
- package/src/endpoints/client-intelligence.ts +4 -4
- package/src/endpoints/delete-account.ts +9 -16
- package/src/endpoints/email-stats.ts +2 -2
- package/src/endpoints/escalate.ts +2 -2
- package/src/endpoints/export-csv.ts +2 -2
- package/src/endpoints/export-data.ts +5 -8
- package/src/endpoints/import-conversation.ts +6 -10
- package/src/endpoints/index.ts +18 -1
- package/src/endpoints/invite-collaborator.ts +30 -15
- package/src/endpoints/invoice.ts +127 -0
- package/src/endpoints/kb-search.ts +2 -2
- package/src/endpoints/login.ts +12 -4
- package/src/endpoints/merge-clients.ts +14 -19
- package/src/endpoints/merge-tickets.ts +11 -18
- package/src/endpoints/oauth-google.ts +86 -39
- package/src/endpoints/pending-emails-process.ts +15 -25
- package/src/endpoints/process-digests.ts +93 -0
- package/src/endpoints/process-scheduled.ts +6 -10
- package/src/endpoints/process-snooze.ts +78 -0
- package/src/endpoints/purge-logs.ts +2 -2
- package/src/endpoints/resend-notification.ts +3 -4
- package/src/endpoints/round-robin-config.ts +3 -4
- package/src/endpoints/satisfaction.ts +21 -14
- package/src/endpoints/search.ts +5 -8
- package/src/endpoints/seed-kb.ts +3 -4
- package/src/endpoints/send-reminder.ts +6 -9
- package/src/endpoints/settings.ts +5 -2
- package/src/endpoints/signature.ts +3 -4
- package/src/endpoints/sla-check.ts +2 -2
- package/src/endpoints/split-ticket.ts +7 -12
- package/src/endpoints/statuses.ts +2 -2
- package/src/endpoints/ticket-feedback.ts +4 -6
- package/src/endpoints/ticket-synthesis.ts +2 -2
- package/src/endpoints/track-open.ts +16 -28
- package/src/endpoints/transfer-ticket.ts +21 -9
- package/src/endpoints/user-prefs.ts +3 -4
- package/src/hooks/automationRules.ts +84 -0
- package/src/hooks/checkSLA.ts +48 -16
- package/src/plugin.ts +6 -0
- package/src/portal/LiveChat.tsx +2 -63
- package/src/portal/auth/tickets/detail/CloseTicketButton.tsx +10 -0
- package/src/portal/auth/tickets/detail/MarkSolutionButton.tsx +14 -2
- package/src/portal/auth/tickets/detail/MessageActions.tsx +37 -18
- package/src/portal/auth/tickets/detail/ReopenTicketButton.tsx +10 -0
- package/src/portal/auth/tickets/detail/TransferAndInviteActions.tsx +3 -2
- package/src/portal/auth/tickets/detail/page.tsx +2 -2
- package/src/portal/helpers.ts +46 -0
- package/src/portal/login/page.tsx +3 -8
- package/src/portal/types.ts +15 -0
- package/src/types/lucide-react.d.ts +34 -0
- package/src/types/payload-config.d.ts +10 -0
- package/src/utils/adminNotification.ts +2 -2
- package/src/utils/aiAgent.ts +147 -0
- package/src/utils/auth.ts +5 -4
- package/src/utils/channels.ts +36 -0
- package/src/utils/db.ts +73 -0
- package/src/utils/emailTemplate.ts +8 -1
- package/src/utils/fireWebhooks.ts +4 -6
- package/src/utils/generateTicketSynthesis.ts +7 -12
- package/src/utils/invoicePdf.ts +88 -0
- package/src/utils/notificationQueue.ts +36 -0
- package/src/utils/readSettings.ts +22 -6
- package/src/utils/sanitizeHtml.ts +57 -0
- package/src/utils/slugs.ts +6 -0
- package/src/utils/teamAccess.ts +27 -0
- package/src/utils/ticketAccess.ts +53 -0
- package/src/utils/webhookDispatcher.ts +4 -6
- package/src/views/BillingView/client.tsx +49 -37
- package/src/views/ChatView/client.tsx +4 -3
- package/src/views/CrmView/client.tsx +7 -7
- package/src/views/EmailTrackingView/client.tsx +7 -6
- package/src/views/ImportConversationView/client.tsx +4 -4
- package/src/views/LogsView/client.tsx +3 -2
- package/src/views/NewTicketView/client.tsx +1 -1
- package/src/views/PendingEmailsView/client.tsx +7 -6
- package/src/views/SupportDashboardView/client.tsx +21 -21
- package/src/views/TicketDetailView/NextActionItem.tsx +30 -0
- package/src/views/TicketDetailView/RewriteDropdown.tsx +63 -0
- package/src/views/TicketDetailView/client.tsx +54 -179
- package/src/views/TicketDetailView/constants.ts +23 -0
- package/src/views/TicketDetailView/helpers.ts +17 -0
- package/src/views/TicketDetailView/types.ts +10 -0
- package/src/views/TicketInboxView/client.tsx +16 -10
- package/src/views/TicketingSettingsView/client.tsx +90 -87
- package/src/views/TimeDashboardView/client.tsx +2 -2
- package/src/views/shared/StatusPill.tsx +24 -12
- package/src/views/shared/dateLocale.ts +5 -0
- package/src/views/shared/locales/en.json +708 -0
- package/src/views/shared/locales/fr.json +708 -0
|
@@ -9,141 +9,13 @@ import { CodeBlockInserter } from '../../components/TicketConversation/component
|
|
|
9
9
|
import { getFeatures } from '../shared/config.js';
|
|
10
10
|
import { computeSlaState, formatSlaRemaining } from '../shared/sla.js';
|
|
11
11
|
import { useTranslation } from '../../components/TicketConversation/hooks/useTranslation.js';
|
|
12
|
+
import { DATE_LOCALE } from '../shared/dateLocale.js';
|
|
12
13
|
import s from '../../styles/TicketDetail.module.scss';
|
|
14
|
+
import { STATUS_STYLE, ALIASES } from './constants.js';
|
|
15
|
+
import { dateLabel, timeAgo } from './helpers.js';
|
|
16
|
+
import { RewriteDropdown } from './RewriteDropdown.js';
|
|
17
|
+
import { NextActionItem } from './NextActionItem.js';
|
|
13
18
|
|
|
14
|
-
const ALIASES = [
|
|
15
|
-
{ value: "Support Consilioweb", label: "En tant que : Support Consilioweb" },
|
|
16
|
-
{ value: "contact@consilioweb.fr", label: "En tant que : contact@consilioweb.fr" }
|
|
17
|
-
];
|
|
18
|
-
const STATUS_STYLE = {
|
|
19
|
-
open: { bg: "#dbeafe", color: "#1e40af" },
|
|
20
|
-
waiting_client: { bg: "#fef3c7", color: "#92400e" },
|
|
21
|
-
resolved: { bg: "#dcfce7", color: "#166534" }
|
|
22
|
-
};
|
|
23
|
-
function timeAgo(d) {
|
|
24
|
-
const date = new Date(d), now = /* @__PURE__ */ new Date();
|
|
25
|
-
if (date.toDateString() === now.toDateString()) return date.toLocaleTimeString("fr-FR", { hour: "2-digit", minute: "2-digit" });
|
|
26
|
-
const y = new Date(now);
|
|
27
|
-
y.setDate(y.getDate() - 1);
|
|
28
|
-
if (date.toDateString() === y.toDateString()) return `Hier, ${date.toLocaleTimeString("fr-FR", { hour: "2-digit", minute: "2-digit" })}`;
|
|
29
|
-
return date.toLocaleDateString("fr-FR", { day: "numeric", month: "short", hour: "2-digit", minute: "2-digit" });
|
|
30
|
-
}
|
|
31
|
-
function dateLabel(d) {
|
|
32
|
-
const date = new Date(d), now = /* @__PURE__ */ new Date();
|
|
33
|
-
if (date.toDateString() === now.toDateString()) return "Aujourd'hui";
|
|
34
|
-
const y = new Date(now);
|
|
35
|
-
y.setDate(y.getDate() - 1);
|
|
36
|
-
if (date.toDateString() === y.toDateString()) return "Hier";
|
|
37
|
-
return date.toLocaleDateString("fr-FR", { day: "numeric", month: "long" });
|
|
38
|
-
}
|
|
39
|
-
const REWRITE_STYLES = [
|
|
40
|
-
{ id: "auto", label: "\u270F\uFE0F Auto", desc: "Garde le ton actuel" },
|
|
41
|
-
{ id: "tutoyer", label: "\u{1F44B} Tutoyer", desc: "Passe en tu" },
|
|
42
|
-
{ id: "vouvoyer", label: "\u{1F3A9} Vouvoyer", desc: "Passe en vous" },
|
|
43
|
-
{ id: "formel", label: "\u{1F4BC} Formel", desc: "Ton professionnel" },
|
|
44
|
-
{ id: "amical", label: "\u{1F60A} Amical", desc: "Ton chaleureux" },
|
|
45
|
-
{ id: "court", label: "\u26A1 Court", desc: "Version concise" }
|
|
46
|
-
];
|
|
47
|
-
const RewriteDropdown = ({ disabled, loading, onSelect, toolbarBtnClass }) => {
|
|
48
|
-
const [open, setOpen] = useState(false);
|
|
49
|
-
const ref = useRef(null);
|
|
50
|
-
useEffect(() => {
|
|
51
|
-
if (!open) return;
|
|
52
|
-
const close = (e) => {
|
|
53
|
-
if (ref.current && !ref.current.contains(e.target)) setOpen(false);
|
|
54
|
-
};
|
|
55
|
-
document.addEventListener("mousedown", close);
|
|
56
|
-
return () => document.removeEventListener("mousedown", close);
|
|
57
|
-
}, [open]);
|
|
58
|
-
return /* @__PURE__ */ jsxs("div", { ref, style: { position: "relative", display: "inline-block" }, children: [
|
|
59
|
-
/* @__PURE__ */ jsxs(
|
|
60
|
-
"button",
|
|
61
|
-
{
|
|
62
|
-
type: "button",
|
|
63
|
-
className: toolbarBtnClass,
|
|
64
|
-
onClick: () => setOpen(!open),
|
|
65
|
-
disabled,
|
|
66
|
-
style: { fontSize: 11, fontWeight: 700, padding: "4px 10px", width: "auto", display: "flex", alignItems: "center", gap: 4 },
|
|
67
|
-
children: [
|
|
68
|
-
loading ? "..." : "\u270F\uFE0F Reformuler",
|
|
69
|
-
!loading && /* @__PURE__ */ jsx("span", { style: { fontSize: 9, opacity: 0.6 }, children: "\u25BC" })
|
|
70
|
-
]
|
|
71
|
-
}
|
|
72
|
-
),
|
|
73
|
-
open && !disabled && !loading && /* @__PURE__ */ jsx("div", { style: {
|
|
74
|
-
position: "absolute",
|
|
75
|
-
bottom: "100%",
|
|
76
|
-
left: 0,
|
|
77
|
-
marginBottom: 4,
|
|
78
|
-
background: "#fff",
|
|
79
|
-
border: "1px solid #e5e7eb",
|
|
80
|
-
borderRadius: 8,
|
|
81
|
-
boxShadow: "0 4px 16px rgba(0,0,0,0.12)",
|
|
82
|
-
zIndex: 100,
|
|
83
|
-
minWidth: 180,
|
|
84
|
-
overflow: "hidden"
|
|
85
|
-
}, children: REWRITE_STYLES.map((style) => /* @__PURE__ */ jsxs(
|
|
86
|
-
"button",
|
|
87
|
-
{
|
|
88
|
-
type: "button",
|
|
89
|
-
onClick: () => {
|
|
90
|
-
setOpen(false);
|
|
91
|
-
onSelect(style.id);
|
|
92
|
-
},
|
|
93
|
-
style: {
|
|
94
|
-
display: "flex",
|
|
95
|
-
flexDirection: "column",
|
|
96
|
-
width: "100%",
|
|
97
|
-
padding: "8px 12px",
|
|
98
|
-
border: "none",
|
|
99
|
-
background: "transparent",
|
|
100
|
-
cursor: "pointer",
|
|
101
|
-
textAlign: "left",
|
|
102
|
-
borderBottom: "1px solid #f3f4f6"
|
|
103
|
-
},
|
|
104
|
-
onMouseEnter: (e) => {
|
|
105
|
-
e.currentTarget.style.background = "#f9fafb";
|
|
106
|
-
},
|
|
107
|
-
onMouseLeave: (e) => {
|
|
108
|
-
e.currentTarget.style.background = "transparent";
|
|
109
|
-
},
|
|
110
|
-
children: [
|
|
111
|
-
/* @__PURE__ */ jsx("span", { style: { fontSize: 12, fontWeight: 600 }, children: style.label }),
|
|
112
|
-
/* @__PURE__ */ jsx("span", { style: { fontSize: 10, color: "#9ca3af" }, children: style.desc })
|
|
113
|
-
]
|
|
114
|
-
},
|
|
115
|
-
style.id
|
|
116
|
-
)) })
|
|
117
|
-
] });
|
|
118
|
-
};
|
|
119
|
-
function NextActionItem({ action, index, onToggle }) {
|
|
120
|
-
const [pending, setPending] = useState(false);
|
|
121
|
-
const labelMap = { now: "Maintenant", today: "Aujourd'hui", "this-week": "Cette semaine" };
|
|
122
|
-
const done = !!action.done;
|
|
123
|
-
return /* @__PURE__ */ jsxs("li", { className: s.aiCardNextAction, children: [
|
|
124
|
-
/* @__PURE__ */ jsx(
|
|
125
|
-
"button",
|
|
126
|
-
{
|
|
127
|
-
type: "button",
|
|
128
|
-
className: `${s.aiCardNextCheck} ${done ? s.aiCardNextCheckDone : ""}`,
|
|
129
|
-
onClick: async () => {
|
|
130
|
-
setPending(true);
|
|
131
|
-
try {
|
|
132
|
-
await onToggle(!done);
|
|
133
|
-
} finally {
|
|
134
|
-
setPending(false);
|
|
135
|
-
}
|
|
136
|
-
},
|
|
137
|
-
"aria-pressed": done,
|
|
138
|
-
"aria-label": done ? "Marquer non fait" : "Marquer fait",
|
|
139
|
-
disabled: pending,
|
|
140
|
-
children: done && /* @__PURE__ */ jsx("span", { "aria-hidden": true, children: "\u2713" })
|
|
141
|
-
}
|
|
142
|
-
),
|
|
143
|
-
/* @__PURE__ */ jsx("span", { className: `${s.aiCardNextLabel} ${done ? s.aiCardNextLabelDone : ""}`, children: action.label }),
|
|
144
|
-
/* @__PURE__ */ jsx("span", { className: s.aiCardNextWhen, children: labelMap[action.priority] || action.priority })
|
|
145
|
-
] });
|
|
146
|
-
}
|
|
147
19
|
const TicketDetailClient = () => {
|
|
148
20
|
const { t } = useTranslation();
|
|
149
21
|
const searchParams = useSearchParams();
|
|
@@ -703,7 +575,7 @@ ${uploadedLinks.join("\n")}` : replyBody.trim() || "[Contenu enrichi]";
|
|
|
703
575
|
const initials = client ? `${(client.firstName?.[0] || "").toUpperCase()}${(client.lastName?.[0] || "").toUpperCase()}` : "?";
|
|
704
576
|
return /* @__PURE__ */ jsxs("div", { className: s.page, children: [
|
|
705
577
|
/* @__PURE__ */ jsxs("div", { className: s.topBar, children: [
|
|
706
|
-
/* @__PURE__ */ jsx(Link, { href: "/admin/support/inbox", className: s.backLink, "aria-label": "
|
|
578
|
+
/* @__PURE__ */ jsx(Link, { href: "/admin/support/inbox", className: s.backLink, "aria-label": t("detail.backToInbox"), children: "\u2190" }),
|
|
707
579
|
/* @__PURE__ */ jsxs("div", { className: s.ticketMeta, children: [
|
|
708
580
|
/* @__PURE__ */ jsxs("span", { className: s.ticketNumber, children: [
|
|
709
581
|
/* @__PURE__ */ jsx("span", { children: ticket.ticketNumber }),
|
|
@@ -756,7 +628,7 @@ ${uploadedLinks.join("\n")}` : replyBody.trim() || "[Contenu enrichi]";
|
|
|
756
628
|
});
|
|
757
629
|
if (slaInfo.state !== "breach") return null;
|
|
758
630
|
const duration = formatSlaRemaining(slaInfo.remainingMs).replace(/^−/, "");
|
|
759
|
-
const target = slaInfo.due ? new Date(slaInfo.due).toLocaleString(
|
|
631
|
+
const target = slaInfo.due ? new Date(slaInfo.due).toLocaleString(DATE_LOCALE, { day: "2-digit", month: "short", hour: "2-digit", minute: "2-digit" }) : "";
|
|
760
632
|
return /* @__PURE__ */ jsxs("div", { className: s.slaBanner, role: "alert", children: [
|
|
761
633
|
/* @__PURE__ */ jsx("span", { className: s.slaBannerIcon, "aria-hidden": true, children: /* @__PURE__ */ jsxs("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
762
634
|
/* @__PURE__ */ jsx("path", { d: "M12 9v4M12 17h.01" }),
|
|
@@ -827,19 +699,19 @@ ${uploadedLinks.join("\n")}` : replyBody.trim() || "[Contenu enrichi]";
|
|
|
827
699
|
/* @__PURE__ */ jsxs("div", { className: s.messageHeader, children: [
|
|
828
700
|
/* @__PURE__ */ jsx("span", { className: s.messageAuthor, children: msg.fromAlias || (isAdmin ? "Support" : msg.authorType === "email" ? "Email" : client?.firstName || "Client") }),
|
|
829
701
|
/* @__PURE__ */ jsx("span", { className: s.messageTime, children: timeAgo(msg.createdAt) }),
|
|
830
|
-
msg.isInternal && /* @__PURE__ */ jsx("span", { className: s.badge, style: { background: "#fef3c7", color: "#92400e" }, children: "
|
|
831
|
-
msg.isSolution && /* @__PURE__ */ jsx("span", { className: s.badge, style: { background: "#dcfce7", color: "#166534" }, children: "
|
|
702
|
+
msg.isInternal && /* @__PURE__ */ jsx("span", { className: s.badge, style: { background: "#fef3c7", color: "#92400e" }, children: t("detail.badgeInternal") }),
|
|
703
|
+
msg.isSolution && /* @__PURE__ */ jsx("span", { className: s.badge, style: { background: "#dcfce7", color: "#166534" }, children: t("detail.badgeSolution") }),
|
|
832
704
|
/* @__PURE__ */ jsx("span", { className: s.messageMeta, children: isAdmin && !msg.isInternal && (() => {
|
|
833
705
|
const ext = msg;
|
|
834
706
|
if (ext.emailOpenedAt) {
|
|
835
|
-
const d = new Date(ext.emailOpenedAt).toLocaleString(
|
|
707
|
+
const d = new Date(ext.emailOpenedAt).toLocaleString(DATE_LOCALE, { day: "numeric", month: "short", hour: "2-digit", minute: "2-digit" });
|
|
836
708
|
return /* @__PURE__ */ jsxs("span", { style: { color: "#16a34a", cursor: "help" }, title: `Ouvert le ${d}`, children: [
|
|
837
709
|
"\u2713\u2713 Lu ",
|
|
838
710
|
d
|
|
839
711
|
] });
|
|
840
712
|
}
|
|
841
713
|
if (ext.emailSentAt) {
|
|
842
|
-
const d = new Date(ext.emailSentAt).toLocaleString(
|
|
714
|
+
const d = new Date(ext.emailSentAt).toLocaleString(DATE_LOCALE, { day: "numeric", month: "short", hour: "2-digit", minute: "2-digit" });
|
|
843
715
|
return /* @__PURE__ */ jsxs("span", { style: { color: "#2563eb", cursor: "help" }, title: `Envoy\xE9 le ${d}`, children: [
|
|
844
716
|
"\u2713 Envoy\xE9 ",
|
|
845
717
|
d
|
|
@@ -858,7 +730,7 @@ ${uploadedLinks.join("\n")}` : replyBody.trim() || "[Contenu enrichi]";
|
|
|
858
730
|
setEditingHtml(html);
|
|
859
731
|
setEditingBody(text);
|
|
860
732
|
},
|
|
861
|
-
placeholder: "
|
|
733
|
+
placeholder: t("detail.editPlaceholder"),
|
|
862
734
|
minHeight: 120,
|
|
863
735
|
onFileUpload: async (file) => {
|
|
864
736
|
try {
|
|
@@ -876,8 +748,8 @@ ${uploadedLinks.join("\n")}` : replyBody.trim() || "[Contenu enrichi]";
|
|
|
876
748
|
}
|
|
877
749
|
),
|
|
878
750
|
/* @__PURE__ */ jsxs("div", { style: { display: "flex", gap: 6, justifyContent: "flex-end" }, children: [
|
|
879
|
-
/* @__PURE__ */ jsx("button", { onClick: cancelEditMessage, disabled: editSaving, style: { padding: "5px 12px", fontSize: 12, borderRadius: 5, border: "1px solid var(--theme-elevation-200)", background: "var(--theme-elevation-0)", color: "var(--theme-text)", cursor: "pointer" }, children: "
|
|
880
|
-
/* @__PURE__ */ jsx("button", { onClick: saveEditMessage, disabled: editSaving || !editingBody.trim(), style: { padding: "5px 12px", fontSize: 12, fontWeight: 600, borderRadius: 5, border: "none", background: "#2563eb", color: "#fff", cursor: editSaving ? "wait" : "pointer", opacity: editSaving ? 0.6 : 1 }, children: editSaving ? "
|
|
751
|
+
/* @__PURE__ */ jsx("button", { onClick: cancelEditMessage, disabled: editSaving, style: { padding: "5px 12px", fontSize: 12, borderRadius: 5, border: "1px solid var(--theme-elevation-200)", background: "var(--theme-elevation-0)", color: "var(--theme-text)", cursor: "pointer" }, children: t("common.cancel") }),
|
|
752
|
+
/* @__PURE__ */ jsx("button", { onClick: saveEditMessage, disabled: editSaving || !editingBody.trim(), style: { padding: "5px 12px", fontSize: 12, fontWeight: 600, borderRadius: 5, border: "none", background: "#2563eb", color: "#fff", cursor: editSaving ? "wait" : "pointer", opacity: editSaving ? 0.6 : 1 }, children: editSaving ? t("detail.editSaving") : t("detail.editSave") })
|
|
881
753
|
] })
|
|
882
754
|
] }) : msg.deletedAt ? /* @__PURE__ */ jsx("div", { className: s.messageBody, style: { color: "#94a3b8", fontStyle: "italic" }, children: t("detail.messageDeleted") }) : msg.bodyHtml && hasCodeBlocks(msg.bodyHtml.replace(/<[^>]+>/g, "")) ? /* @__PURE__ */ jsx(CodeBlockRendererHtml, { html: msg.bodyHtml }) : msg.bodyHtml ? /* @__PURE__ */ jsx("div", { className: `${s.messageBody} ${s.rteDisplay}`, dangerouslySetInnerHTML: { __html: msg.bodyHtml } }) : hasCodeBlocks(msg.body) ? /* @__PURE__ */ jsx(MessageWithCodeBlocks, { text: msg.body, style: { fontSize: "13px", lineHeight: 1.5 } }) : /* @__PURE__ */ jsx("div", { className: s.messageBody, children: msg.body }),
|
|
883
755
|
Array.isArray(msg.attachments) && msg.attachments.length > 0 && /* @__PURE__ */ jsx("div", { className: s.attachments, children: msg.attachments.map((att, i) => {
|
|
@@ -890,7 +762,7 @@ ${uploadedLinks.join("\n")}` : replyBody.trim() || "[Contenu enrichi]";
|
|
|
890
762
|
}) })
|
|
891
763
|
] }),
|
|
892
764
|
editingMsgId !== msg.id && !msg.deletedAt && /* @__PURE__ */ jsxs("div", { className: s.messageActions, children: [
|
|
893
|
-
/* @__PURE__ */ jsx("button", { className: s.actionIcon, title: "
|
|
765
|
+
/* @__PURE__ */ jsx("button", { className: s.actionIcon, title: t("detail.editMessage"), "aria-label": t("detail.editMessageLabel"), onClick: () => startEditMessage(msg), style: { fontSize: 11, width: "auto", padding: "4px 8px" }, children: t("detail.editMessage") }),
|
|
894
766
|
/* @__PURE__ */ jsx("button", { className: `${s.actionIcon} ${s.danger}`, title: t("actions.deleteMessage"), "aria-label": t("actions.deleteMessage"), onClick: () => handleDeleteMessage(msg.id), style: { fontSize: 11, width: "auto", padding: "4px 8px" }, children: t("actions.deleteMessage") }),
|
|
895
767
|
features.splitTicket && !msg.isInternal && /* @__PURE__ */ jsx("button", { className: s.actionIcon, title: t("actions.extractMessage"), "aria-label": t("actions.extractToNewTicket"), onClick: () => {
|
|
896
768
|
setSplitModal({ messageId: msg.id, preview: msg.body.slice(0, 200) });
|
|
@@ -986,7 +858,7 @@ ${uploadedLinks.join("\n")}` : replyBody.trim() || "[Contenu enrichi]";
|
|
|
986
858
|
},
|
|
987
859
|
disabled: applyingMacro,
|
|
988
860
|
style: { marginLeft: 0 },
|
|
989
|
-
"aria-label": "
|
|
861
|
+
"aria-label": t("detail.macros"),
|
|
990
862
|
children: [
|
|
991
863
|
/* @__PURE__ */ jsx("option", { value: "", children: applyingMacro ? t("detail.applyingMacro") : t("detail.macros") }),
|
|
992
864
|
macros.map((m) => /* @__PURE__ */ jsx("option", { value: m.id, children: m.name }, m.id))
|
|
@@ -994,7 +866,7 @@ ${uploadedLinks.join("\n")}` : replyBody.trim() || "[Contenu enrichi]";
|
|
|
994
866
|
}
|
|
995
867
|
),
|
|
996
868
|
/* @__PURE__ */ jsx("span", { className: s.toolbarDivider }),
|
|
997
|
-
features.canned && cannedResponses.length > 0 && /* @__PURE__ */ jsxs("select", { className: s.cannedSelect, "aria-label": "
|
|
869
|
+
features.canned && cannedResponses.length > 0 && /* @__PURE__ */ jsxs("select", { className: s.cannedSelect, "aria-label": t("detail.cannedResponses"), onChange: (e) => {
|
|
998
870
|
const cr = cannedResponses.find((c) => String(c.id) === e.target.value);
|
|
999
871
|
if (cr) {
|
|
1000
872
|
let b = cr.body;
|
|
@@ -1039,11 +911,8 @@ ${uploadedLinks.join("\n")}` : replyBody.trim() || "[Contenu enrichi]";
|
|
|
1039
911
|
}
|
|
1040
912
|
),
|
|
1041
913
|
pendingFiles.length > 0 && /* @__PURE__ */ jsx("div", { className: s.uploadPreview, children: pendingFiles.map((f, i) => /* @__PURE__ */ jsxs("div", { className: s.uploadPreviewItem, children: [
|
|
1042
|
-
/* @__PURE__ */
|
|
1043
|
-
|
|
1044
|
-
f.name
|
|
1045
|
-
] }),
|
|
1046
|
-
/* @__PURE__ */ jsx("button", { className: s.uploadRemoveBtn, "aria-label": `Retirer ${f.name}`, onClick: () => setPendingFiles((prev) => prev.filter((_, j) => j !== i)), children: "\xD7" })
|
|
914
|
+
/* @__PURE__ */ jsx("span", { children: t("detail.uploadItem", { name: f.name }) }),
|
|
915
|
+
/* @__PURE__ */ jsx("button", { className: s.uploadRemoveBtn, "aria-label": t("detail.removeUpload", { name: f.name }), onClick: () => setPendingFiles((prev) => prev.filter((_, j) => j !== i)), children: "\xD7" })
|
|
1047
916
|
] }, i)) })
|
|
1048
917
|
] }),
|
|
1049
918
|
/* @__PURE__ */ jsxs("div", { className: s.composerFooter, children: [
|
|
@@ -1062,8 +931,8 @@ ${uploadedLinks.join("\n")}` : replyBody.trim() || "[Contenu enrichi]";
|
|
|
1062
931
|
},
|
|
1063
932
|
style: { fontSize: "12px", padding: "4px 8px", fontWeight: 600, borderRadius: 6, border: "1px solid var(--theme-elevation-200)", background: "var(--theme-elevation-0)", color: "var(--theme-text)" },
|
|
1064
933
|
children: [
|
|
1065
|
-
/* @__PURE__ */ jsx("option", { value: "admin", children: "
|
|
1066
|
-
/* @__PURE__ */ jsx("option", { value: "client", children: "
|
|
934
|
+
/* @__PURE__ */ jsx("option", { value: "admin", children: t("detail.sendAsSupport") }),
|
|
935
|
+
/* @__PURE__ */ jsx("option", { value: "client", children: t("detail.sendAsClient") })
|
|
1067
936
|
]
|
|
1068
937
|
}
|
|
1069
938
|
),
|
|
@@ -1098,7 +967,7 @@ ${uploadedLinks.join("\n")}` : replyBody.trim() || "[Contenu enrichi]";
|
|
|
1098
967
|
/* @__PURE__ */ jsx("kbd", { children: "\u2318" }),
|
|
1099
968
|
/* @__PURE__ */ jsx("kbd", { children: "\u21B5" })
|
|
1100
969
|
] }),
|
|
1101
|
-
/* @__PURE__ */ jsx("button", { className: `${s.sendBtn} ${isInternal ? s.sendBtnInternal : ""}`, onClick: handleSend, disabled: sending || !replyBody.trim(), "data-action": "send-reply", children: sending ? t("detail.sending") : sendAsClient ? "
|
|
970
|
+
/* @__PURE__ */ jsx("button", { className: `${s.sendBtn} ${isInternal ? s.sendBtnInternal : ""}`, onClick: handleSend, disabled: sending || !replyBody.trim(), "data-action": "send-reply", children: sending ? t("detail.sending") : sendAsClient ? t("detail.addClientMessage") : isInternal ? t("detail.sendNote") : t("detail.sendReply") })
|
|
1102
971
|
] })
|
|
1103
972
|
]
|
|
1104
973
|
}
|
|
@@ -1171,7 +1040,7 @@ ${uploadedLinks.join("\n")}` : replyBody.trim() || "[Contenu enrichi]";
|
|
|
1171
1040
|
clientSummary && clientSummary.summary && /* @__PURE__ */ jsxs("div", { className: `${s.sideSection} ${s.aiCard}`, children: [
|
|
1172
1041
|
/* @__PURE__ */ jsxs("div", { className: s.aiCardTitle, children: [
|
|
1173
1042
|
/* @__PURE__ */ jsx("span", { className: s.aiCardIcon, "aria-hidden": true, children: "\u2728" }),
|
|
1174
|
-
"
|
|
1043
|
+
t("detail.aiCard.title")
|
|
1175
1044
|
] }),
|
|
1176
1045
|
/* @__PURE__ */ jsx("p", { className: s.aiCardLead, children: clientSummary.summary }),
|
|
1177
1046
|
clientSummary.recurringTopics && clientSummary.recurringTopics.length > 0 && /* @__PURE__ */ jsx("div", { className: s.aiCardChips, children: clientSummary.recurringTopics.slice(0, 5).map((tp, i) => /* @__PURE__ */ jsx("span", { className: s.aiChip, children: tp.topic }, `tp-${i}`)) }),
|
|
@@ -1250,12 +1119,12 @@ ${uploadedLinks.join("\n")}` : replyBody.trim() || "[Contenu enrichi]";
|
|
|
1250
1119
|
":",
|
|
1251
1120
|
String(timerSeconds % 60).padStart(2, "0")
|
|
1252
1121
|
] }),
|
|
1253
|
-
!timerRunning ? /* @__PURE__ */ jsx("button", { className: s.timerBtn, onClick: () => setTimerRunning(true), "aria-label": "
|
|
1122
|
+
!timerRunning ? /* @__PURE__ */ jsx("button", { className: s.timerBtn, onClick: () => setTimerRunning(true), "aria-label": t("detail.timerStart"), children: timerSeconds > 0 ? "\u25B6" : "\u25B6 Go" }) : /* @__PURE__ */ jsx("button", { className: `${s.timerBtn} ${s.timerBtnRunning}`, onClick: () => setTimerRunning(false), "aria-label": t("detail.timerPause"), children: "\u23F8 Pause" }),
|
|
1254
1123
|
timerSeconds >= 60 && !timerRunning && /* @__PURE__ */ jsxs("button", { className: `${s.timerBtn} ${s.timerBtnGhost}`, onClick: () => {
|
|
1255
1124
|
handleTimerSave();
|
|
1256
1125
|
localStorage.removeItem(`timer-sec-${ticketId}`);
|
|
1257
1126
|
localStorage.removeItem(`timer-run-${ticketId}`);
|
|
1258
|
-
}, "aria-label": "
|
|
1127
|
+
}, "aria-label": t("detail.timerSave"), children: [
|
|
1259
1128
|
"\u{1F4BE} ",
|
|
1260
1129
|
Math.round(timerSeconds / 60),
|
|
1261
1130
|
"m"
|
|
@@ -1274,11 +1143,11 @@ ${uploadedLinks.join("\n")}` : replyBody.trim() || "[Contenu enrichi]";
|
|
|
1274
1143
|
fetchAll();
|
|
1275
1144
|
} catch {
|
|
1276
1145
|
}
|
|
1277
|
-
}, style: { fontSize: 11 }, children: "
|
|
1146
|
+
}, style: { fontSize: 11 }, children: t("detail.addTime") })
|
|
1278
1147
|
] }),
|
|
1279
1148
|
/* @__PURE__ */ jsxs("div", { style: { marginTop: 8, fontSize: 11, color: "var(--theme-elevation-500)" }, children: [
|
|
1280
1149
|
/* @__PURE__ */ jsxs("div", { style: { display: "flex", justifyContent: "space-between", padding: "2px 0", alignItems: "center" }, children: [
|
|
1281
|
-
/* @__PURE__ */ jsx("span", { children: "
|
|
1150
|
+
/* @__PURE__ */ jsx("span", { children: t("detail.billing.billable") }),
|
|
1282
1151
|
/* @__PURE__ */ jsx(
|
|
1283
1152
|
"button",
|
|
1284
1153
|
{
|
|
@@ -1291,12 +1160,12 @@ ${uploadedLinks.join("\n")}` : replyBody.trim() || "[Contenu enrichi]";
|
|
|
1291
1160
|
}
|
|
1292
1161
|
},
|
|
1293
1162
|
style: { fontWeight: 600, color: ticket.billable !== false ? "#16a34a" : "#dc2626", background: "none", border: "none", cursor: "pointer", fontSize: 11, textDecoration: "underline" },
|
|
1294
|
-
children: ticket.billable !== false ? "
|
|
1163
|
+
children: ticket.billable !== false ? t("detail.billing.yes") : t("detail.billing.no")
|
|
1295
1164
|
}
|
|
1296
1165
|
)
|
|
1297
1166
|
] }),
|
|
1298
1167
|
totalMin > 0 && /* @__PURE__ */ jsxs("div", { style: { display: "flex", justifyContent: "space-between", padding: "2px 0" }, children: [
|
|
1299
|
-
/* @__PURE__ */ jsx("span", { children: "
|
|
1168
|
+
/* @__PURE__ */ jsx("span", { children: t("detail.billing.estimatedAmount") }),
|
|
1300
1169
|
/* @__PURE__ */ jsxs("span", { style: { fontWeight: 700, color: "var(--theme-text)" }, children: [
|
|
1301
1170
|
(totalMin / 60 * 60).toFixed(0),
|
|
1302
1171
|
"\u20AC"
|
|
@@ -1304,7 +1173,7 @@ ${uploadedLinks.join("\n")}` : replyBody.trim() || "[Contenu enrichi]";
|
|
|
1304
1173
|
] })
|
|
1305
1174
|
] }),
|
|
1306
1175
|
timeEntries.length > 0 && /* @__PURE__ */ jsx("div", { style: { marginTop: 8, fontSize: 11 }, children: timeEntries.slice(0, 6).map((e) => /* @__PURE__ */ jsxs("div", { style: { display: "flex", justifyContent: "space-between", padding: "3px 0", color: "var(--theme-elevation-500)" }, children: [
|
|
1307
|
-
/* @__PURE__ */ jsx("span", { children: new Date(e.date).toLocaleDateString(
|
|
1176
|
+
/* @__PURE__ */ jsx("span", { children: new Date(e.date).toLocaleDateString(DATE_LOCALE, { day: "numeric", month: "short" }) }),
|
|
1308
1177
|
/* @__PURE__ */ jsxs("span", { title: e.description, style: { fontWeight: 600, cursor: e.description ? "help" : "default" }, children: [
|
|
1309
1178
|
e.duration,
|
|
1310
1179
|
"min"
|
|
@@ -1316,7 +1185,7 @@ ${uploadedLinks.join("\n")}` : replyBody.trim() || "[Contenu enrichi]";
|
|
|
1316
1185
|
/* @__PURE__ */ jsxs("div", { className: s.tagsWrap, children: [
|
|
1317
1186
|
tags.map((tag) => /* @__PURE__ */ jsxs("span", { className: s.tagChip, children: [
|
|
1318
1187
|
tag,
|
|
1319
|
-
/* @__PURE__ */ jsx("button", { className: s.tagRemove, "aria-label":
|
|
1188
|
+
/* @__PURE__ */ jsx("button", { className: s.tagRemove, "aria-label": t("detail.removeTag", { tag }), onClick: () => handleRemoveTag(tag), children: "\xD7" })
|
|
1320
1189
|
] }, tag)),
|
|
1321
1190
|
addingTag ? /* @__PURE__ */ jsx(
|
|
1322
1191
|
"input",
|
|
@@ -1332,17 +1201,17 @@ ${uploadedLinks.join("\n")}` : replyBody.trim() || "[Contenu enrichi]";
|
|
|
1332
1201
|
}
|
|
1333
1202
|
},
|
|
1334
1203
|
onBlur: handleAddTag,
|
|
1335
|
-
placeholder: "
|
|
1204
|
+
placeholder: t("detail.tagPlaceholder"),
|
|
1336
1205
|
autoFocus: true
|
|
1337
1206
|
}
|
|
1338
|
-
) : /* @__PURE__ */ jsx("button", { className: s.tagAddBtn, onClick: () => setAddingTag(true), "aria-label": "
|
|
1207
|
+
) : /* @__PURE__ */ jsx("button", { className: s.tagAddBtn, onClick: () => setAddingTag(true), "aria-label": t("detail.addTag"), children: t("detail.addTagBtn") })
|
|
1339
1208
|
] })
|
|
1340
1209
|
] }),
|
|
1341
1210
|
/* @__PURE__ */ jsxs("div", { className: s.sideSection, children: [
|
|
1342
|
-
/* @__PURE__ */ jsx("div", { className: s.sideSectionTitle, children: "
|
|
1211
|
+
/* @__PURE__ */ jsx("div", { className: s.sideSectionTitle, children: t("detail.billing.title") }),
|
|
1343
1212
|
/* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", gap: 8 }, children: [
|
|
1344
1213
|
/* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between" }, children: [
|
|
1345
|
-
/* @__PURE__ */ jsx("span", { style: { fontSize: 12 }, children: "
|
|
1214
|
+
/* @__PURE__ */ jsx("span", { style: { fontSize: 12 }, children: t("detail.billing.type") }),
|
|
1346
1215
|
/* @__PURE__ */ jsxs(
|
|
1347
1216
|
"select",
|
|
1348
1217
|
{
|
|
@@ -1361,14 +1230,14 @@ ${uploadedLinks.join("\n")}` : replyBody.trim() || "[Contenu enrichi]";
|
|
|
1361
1230
|
},
|
|
1362
1231
|
style: { fontSize: 12, padding: "4px 8px", borderRadius: 6, border: "1px solid #e5e7eb", background: "#fff" },
|
|
1363
1232
|
children: [
|
|
1364
|
-
/* @__PURE__ */ jsx("option", { value: "hourly", children: "
|
|
1365
|
-
/* @__PURE__ */ jsx("option", { value: "flat", children: "
|
|
1233
|
+
/* @__PURE__ */ jsx("option", { value: "hourly", children: t("detail.billing.hourly") }),
|
|
1234
|
+
/* @__PURE__ */ jsx("option", { value: "flat", children: t("detail.billing.flat") })
|
|
1366
1235
|
]
|
|
1367
1236
|
}
|
|
1368
1237
|
)
|
|
1369
1238
|
] }),
|
|
1370
1239
|
ticket?.billingType === "flat" && /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between" }, children: [
|
|
1371
|
-
/* @__PURE__ */ jsx("span", { style: { fontSize: 12 }, children: "
|
|
1240
|
+
/* @__PURE__ */ jsx("span", { style: { fontSize: 12 }, children: t("detail.billing.flatAmount") }),
|
|
1372
1241
|
/* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: 4 }, children: [
|
|
1373
1242
|
/* @__PURE__ */ jsx(
|
|
1374
1243
|
"input",
|
|
@@ -1396,7 +1265,7 @@ ${uploadedLinks.join("\n")}` : replyBody.trim() || "[Contenu enrichi]";
|
|
|
1396
1265
|
] })
|
|
1397
1266
|
] }),
|
|
1398
1267
|
/* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between" }, children: [
|
|
1399
|
-
/* @__PURE__ */ jsx("span", { style: { fontSize: 12 }, children: "
|
|
1268
|
+
/* @__PURE__ */ jsx("span", { style: { fontSize: 12 }, children: t("detail.billing.billedAmount") }),
|
|
1400
1269
|
/* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: 4 }, children: [
|
|
1401
1270
|
/* @__PURE__ */ jsx(
|
|
1402
1271
|
"input",
|
|
@@ -1424,7 +1293,7 @@ ${uploadedLinks.join("\n")}` : replyBody.trim() || "[Contenu enrichi]";
|
|
|
1424
1293
|
] })
|
|
1425
1294
|
] }),
|
|
1426
1295
|
/* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between" }, children: [
|
|
1427
|
-
/* @__PURE__ */ jsx("span", { style: { fontSize: 12 }, children: "
|
|
1296
|
+
/* @__PURE__ */ jsx("span", { style: { fontSize: 12 }, children: t("detail.billing.payment") }),
|
|
1428
1297
|
/* @__PURE__ */ jsxs(
|
|
1429
1298
|
"select",
|
|
1430
1299
|
{
|
|
@@ -1443,16 +1312,16 @@ ${uploadedLinks.join("\n")}` : replyBody.trim() || "[Contenu enrichi]";
|
|
|
1443
1312
|
},
|
|
1444
1313
|
style: { fontSize: 12, padding: "4px 8px", borderRadius: 6, border: "1px solid #e5e7eb", background: "#fff" },
|
|
1445
1314
|
children: [
|
|
1446
|
-
/* @__PURE__ */ jsx("option", { value: "unpaid", children: "
|
|
1447
|
-
/* @__PURE__ */ jsx("option", { value: "partial", children: "
|
|
1448
|
-
/* @__PURE__ */ jsx("option", { value: "paid", children: "
|
|
1315
|
+
/* @__PURE__ */ jsx("option", { value: "unpaid", children: t("detail.billing.unpaid") }),
|
|
1316
|
+
/* @__PURE__ */ jsx("option", { value: "partial", children: t("detail.billing.partial") }),
|
|
1317
|
+
/* @__PURE__ */ jsx("option", { value: "paid", children: t("detail.billing.paid") })
|
|
1449
1318
|
]
|
|
1450
1319
|
}
|
|
1451
1320
|
)
|
|
1452
1321
|
] })
|
|
1453
1322
|
] })
|
|
1454
1323
|
] }),
|
|
1455
|
-
summaryLoading && /* @__PURE__ */ jsx("div", { className: s.sideSection, children: /* @__PURE__ */ jsx("div", { style: { fontSize: 11, color: "var(--theme-elevation-400)", textAlign: "center", padding: 8 }, children: "
|
|
1324
|
+
summaryLoading && /* @__PURE__ */ jsx("div", { className: s.sideSection, children: /* @__PURE__ */ jsx("div", { style: { fontSize: 11, color: "var(--theme-elevation-400)", textAlign: "center", padding: 8 }, children: t("detail.loadingSummary") }) })
|
|
1456
1325
|
] }),
|
|
1457
1326
|
sidebarTab === "client" && /* @__PURE__ */ jsxs("div", { role: "tabpanel", id: "sidebar-panel-client", "aria-labelledby": "sidebar-tab-client", children: [
|
|
1458
1327
|
client && /* @__PURE__ */ jsxs("div", { className: s.sideSection, children: [
|
|
@@ -1480,7 +1349,7 @@ ${uploadedLinks.join("\n")}` : replyBody.trim() || "[Contenu enrichi]";
|
|
|
1480
1349
|
/* @__PURE__ */ jsx("span", { className: s.previousTicketsSubject, children: pt.subject || `#${pt.id}` }),
|
|
1481
1350
|
/* @__PURE__ */ jsxs("span", { className: s.previousTicketsMeta, children: [
|
|
1482
1351
|
pt.status ? /* @__PURE__ */ jsx("span", { className: s.previousTicketsStatus, children: pt.status }) : null,
|
|
1483
|
-
/* @__PURE__ */ jsx("span", { className: s.previousTicketsDate, children: new Date(pt.createdAt).toLocaleDateString(
|
|
1352
|
+
/* @__PURE__ */ jsx("span", { className: s.previousTicketsDate, children: new Date(pt.createdAt).toLocaleDateString(DATE_LOCALE, { day: "numeric", month: "short", year: "numeric" }) })
|
|
1484
1353
|
] })
|
|
1485
1354
|
] }) }, pt.id)) })
|
|
1486
1355
|
] })
|
|
@@ -1498,16 +1367,16 @@ ${uploadedLinks.join("\n")}` : replyBody.trim() || "[Contenu enrichi]";
|
|
|
1498
1367
|
] })
|
|
1499
1368
|
] }),
|
|
1500
1369
|
undoToast && /* @__PURE__ */ jsxs("div", { className: s.undoToast, role: "alert", children: [
|
|
1501
|
-
/* @__PURE__ */ jsx("span", { children: "
|
|
1502
|
-
/* @__PURE__ */ jsx("button", { className: s.undoBtn, onClick: handleUndoDelete, children: "
|
|
1370
|
+
/* @__PURE__ */ jsx("span", { children: t("detail.messageDeletedToast") }),
|
|
1371
|
+
/* @__PURE__ */ jsx("button", { className: s.undoBtn, onClick: handleUndoDelete, children: t("common.cancel") })
|
|
1503
1372
|
] }),
|
|
1504
1373
|
splitModal && /* @__PURE__ */ jsx("div", { className: s.splitOverlay, onClick: (e) => {
|
|
1505
1374
|
if (e.target === e.currentTarget) {
|
|
1506
1375
|
setSplitModal(null);
|
|
1507
1376
|
setSplitSubject("");
|
|
1508
1377
|
}
|
|
1509
|
-
}, children: /* @__PURE__ */ jsxs("div", { className: s.splitModal, role: "dialog", "aria-label": "
|
|
1510
|
-
/* @__PURE__ */ jsx("h3", { className: s.splitTitle, children: "
|
|
1378
|
+
}, children: /* @__PURE__ */ jsxs("div", { className: s.splitModal, role: "dialog", "aria-label": t("actions.extractToNewTicket"), children: [
|
|
1379
|
+
/* @__PURE__ */ jsx("h3", { className: s.splitTitle, children: t("actions.extractToNewTicket") }),
|
|
1511
1380
|
/* @__PURE__ */ jsx("div", { className: s.splitPreview, children: splitModal.preview }),
|
|
1512
1381
|
/* @__PURE__ */ jsx(
|
|
1513
1382
|
"input",
|
|
@@ -1518,7 +1387,7 @@ ${uploadedLinks.join("\n")}` : replyBody.trim() || "[Contenu enrichi]";
|
|
|
1518
1387
|
onKeyDown: (e) => {
|
|
1519
1388
|
if (e.key === "Enter") handleSplitConfirm();
|
|
1520
1389
|
},
|
|
1521
|
-
placeholder: "
|
|
1390
|
+
placeholder: t("detail.split.subjectPlaceholder"),
|
|
1522
1391
|
autoFocus: true
|
|
1523
1392
|
}
|
|
1524
1393
|
),
|
|
@@ -1526,8 +1395,8 @@ ${uploadedLinks.join("\n")}` : replyBody.trim() || "[Contenu enrichi]";
|
|
|
1526
1395
|
/* @__PURE__ */ jsx("button", { className: s.splitCancelBtn, onClick: () => {
|
|
1527
1396
|
setSplitModal(null);
|
|
1528
1397
|
setSplitSubject("");
|
|
1529
|
-
}, children: "
|
|
1530
|
-
/* @__PURE__ */ jsx("button", { className: s.splitConfirmBtn, onClick: handleSplitConfirm, disabled: !splitSubject.trim(), children: "
|
|
1398
|
+
}, children: t("common.cancel") }),
|
|
1399
|
+
/* @__PURE__ */ jsx("button", { className: s.splitConfirmBtn, onClick: handleSplitConfirm, disabled: !splitSubject.trim(), children: t("detail.split.createBtn") })
|
|
1531
1400
|
] })
|
|
1532
1401
|
] }) })
|
|
1533
1402
|
] });
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const ALIASES = (process.env.NEXT_PUBLIC_SUPPORT_SEND_ALIASES || "").split(",").map((v) => v.trim()).filter(Boolean).map((value) => ({ value, label: `En tant que : ${value}` }));
|
|
4
|
+
const STATUS_STYLE = {
|
|
5
|
+
open: { bg: "#dbeafe", color: "#1e40af" },
|
|
6
|
+
waiting_client: { bg: "#fef3c7", color: "#92400e" },
|
|
7
|
+
resolved: { bg: "#dcfce7", color: "#166534" }
|
|
8
|
+
};
|
|
9
|
+
const REWRITE_STYLES = [
|
|
10
|
+
{ id: "auto", label: "\u270F\uFE0F Auto", desc: "Garde le ton actuel" },
|
|
11
|
+
{ id: "tutoyer", label: "\u{1F44B} Tutoyer", desc: "Passe en tu" },
|
|
12
|
+
{ id: "vouvoyer", label: "\u{1F3A9} Vouvoyer", desc: "Passe en vous" },
|
|
13
|
+
{ id: "formel", label: "\u{1F4BC} Formel", desc: "Ton professionnel" },
|
|
14
|
+
{ id: "amical", label: "\u{1F60A} Amical", desc: "Ton chaleureux" },
|
|
15
|
+
{ id: "court", label: "\u26A1 Court", desc: "Version concise" }
|
|
16
|
+
];
|
|
17
|
+
|
|
18
|
+
exports.ALIASES = ALIASES;
|
|
19
|
+
exports.REWRITE_STYLES = REWRITE_STYLES;
|
|
20
|
+
exports.STATUS_STYLE = STATUS_STYLE;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
const ALIASES = (process.env.NEXT_PUBLIC_SUPPORT_SEND_ALIASES || "").split(",").map((v) => v.trim()).filter(Boolean).map((value) => ({ value, label: `En tant que : ${value}` }));
|
|
2
|
+
const STATUS_STYLE = {
|
|
3
|
+
open: { bg: "#dbeafe", color: "#1e40af" },
|
|
4
|
+
waiting_client: { bg: "#fef3c7", color: "#92400e" },
|
|
5
|
+
resolved: { bg: "#dcfce7", color: "#166534" }
|
|
6
|
+
};
|
|
7
|
+
const REWRITE_STYLES = [
|
|
8
|
+
{ id: "auto", label: "\u270F\uFE0F Auto", desc: "Garde le ton actuel" },
|
|
9
|
+
{ id: "tutoyer", label: "\u{1F44B} Tutoyer", desc: "Passe en tu" },
|
|
10
|
+
{ id: "vouvoyer", label: "\u{1F3A9} Vouvoyer", desc: "Passe en vous" },
|
|
11
|
+
{ id: "formel", label: "\u{1F4BC} Formel", desc: "Ton professionnel" },
|
|
12
|
+
{ id: "amical", label: "\u{1F60A} Amical", desc: "Ton chaleureux" },
|
|
13
|
+
{ id: "court", label: "\u26A1 Court", desc: "Version concise" }
|
|
14
|
+
];
|
|
15
|
+
|
|
16
|
+
export { ALIASES, REWRITE_STYLES, STATUS_STYLE };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var dateLocale = require('../shared/dateLocale');
|
|
4
|
+
|
|
5
|
+
function timeAgo(d) {
|
|
6
|
+
const date = new Date(d), now = /* @__PURE__ */ new Date();
|
|
7
|
+
if (date.toDateString() === now.toDateString()) return date.toLocaleTimeString(dateLocale.DATE_LOCALE, { hour: "2-digit", minute: "2-digit" });
|
|
8
|
+
const y = new Date(now);
|
|
9
|
+
y.setDate(y.getDate() - 1);
|
|
10
|
+
if (date.toDateString() === y.toDateString()) return `Hier, ${date.toLocaleTimeString(dateLocale.DATE_LOCALE, { hour: "2-digit", minute: "2-digit" })}`;
|
|
11
|
+
return date.toLocaleDateString(dateLocale.DATE_LOCALE, { day: "numeric", month: "short", hour: "2-digit", minute: "2-digit" });
|
|
12
|
+
}
|
|
13
|
+
function dateLabel(d) {
|
|
14
|
+
const date = new Date(d), now = /* @__PURE__ */ new Date();
|
|
15
|
+
if (date.toDateString() === now.toDateString()) return "Aujourd'hui";
|
|
16
|
+
const y = new Date(now);
|
|
17
|
+
y.setDate(y.getDate() - 1);
|
|
18
|
+
if (date.toDateString() === y.toDateString()) return "Hier";
|
|
19
|
+
return date.toLocaleDateString(dateLocale.DATE_LOCALE, { day: "numeric", month: "long" });
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
exports.dateLabel = dateLabel;
|
|
23
|
+
exports.timeAgo = timeAgo;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { DATE_LOCALE } from '../shared/dateLocale.js';
|
|
2
|
+
|
|
3
|
+
function timeAgo(d) {
|
|
4
|
+
const date = new Date(d), now = /* @__PURE__ */ new Date();
|
|
5
|
+
if (date.toDateString() === now.toDateString()) return date.toLocaleTimeString(DATE_LOCALE, { hour: "2-digit", minute: "2-digit" });
|
|
6
|
+
const y = new Date(now);
|
|
7
|
+
y.setDate(y.getDate() - 1);
|
|
8
|
+
if (date.toDateString() === y.toDateString()) return `Hier, ${date.toLocaleTimeString(DATE_LOCALE, { hour: "2-digit", minute: "2-digit" })}`;
|
|
9
|
+
return date.toLocaleDateString(DATE_LOCALE, { day: "numeric", month: "short", hour: "2-digit", minute: "2-digit" });
|
|
10
|
+
}
|
|
11
|
+
function dateLabel(d) {
|
|
12
|
+
const date = new Date(d), now = /* @__PURE__ */ new Date();
|
|
13
|
+
if (date.toDateString() === now.toDateString()) return "Aujourd'hui";
|
|
14
|
+
const y = new Date(now);
|
|
15
|
+
y.setDate(y.getDate() - 1);
|
|
16
|
+
if (date.toDateString() === y.toDateString()) return "Hier";
|
|
17
|
+
return date.toLocaleDateString(DATE_LOCALE, { day: "numeric", month: "long" });
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export { dateLabel, timeAgo };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|