@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.
Files changed (193) hide show
  1. package/README.md +347 -435
  2. package/dist/components/TicketConversation/RewriteDropdown.cjs +98 -0
  3. package/dist/components/TicketConversation/RewriteDropdown.js +93 -0
  4. package/dist/components/TicketConversation/SkeletonText.cjs +21 -0
  5. package/dist/components/TicketConversation/SkeletonText.js +20 -0
  6. package/dist/components/TicketConversation/constants.cjs +27 -0
  7. package/dist/components/TicketConversation/constants.js +26 -1
  8. package/dist/components/TicketConversation/hooks/useDocumentIdFromUrl.cjs +20 -0
  9. package/dist/components/TicketConversation/hooks/useDocumentIdFromUrl.js +19 -0
  10. package/dist/components/TicketConversation/index.cjs +10 -147
  11. package/dist/components/TicketConversation/index.js +4 -141
  12. package/dist/index.cjs +1604 -671
  13. package/dist/index.d.cts +3 -0
  14. package/dist/index.d.ts +3 -0
  15. package/dist/index.js +1602 -671
  16. package/dist/views/BillingView/client.cjs +40 -54
  17. package/dist/views/BillingView/client.js +40 -54
  18. package/dist/views/ChatView/client.cjs +4 -3
  19. package/dist/views/ChatView/client.js +4 -3
  20. package/dist/views/CrmView/client.cjs +7 -7
  21. package/dist/views/CrmView/client.js +7 -7
  22. package/dist/views/EmailTrackingView/client.cjs +6 -5
  23. package/dist/views/EmailTrackingView/client.js +6 -5
  24. package/dist/views/ImportConversationView/client.cjs +4 -4
  25. package/dist/views/ImportConversationView/client.js +4 -4
  26. package/dist/views/LogsView/client.cjs +3 -2
  27. package/dist/views/LogsView/client.js +3 -2
  28. package/dist/views/NewTicketView/client.cjs +1 -1
  29. package/dist/views/NewTicketView/client.js +1 -1
  30. package/dist/views/PendingEmailsView/client.cjs +7 -6
  31. package/dist/views/PendingEmailsView/client.js +7 -6
  32. package/dist/views/SupportDashboardView/client.cjs +19 -22
  33. package/dist/views/SupportDashboardView/client.js +19 -22
  34. package/dist/views/TicketDetailView/NextActionItem.cjs +40 -0
  35. package/dist/views/TicketDetailView/NextActionItem.js +34 -0
  36. package/dist/views/TicketDetailView/RewriteDropdown.cjs +80 -0
  37. package/dist/views/TicketDetailView/RewriteDropdown.js +78 -0
  38. package/dist/views/TicketDetailView/client.cjs +59 -190
  39. package/dist/views/TicketDetailView/client.js +52 -183
  40. package/dist/views/TicketDetailView/constants.cjs +20 -0
  41. package/dist/views/TicketDetailView/constants.js +16 -0
  42. package/dist/views/TicketDetailView/helpers.cjs +23 -0
  43. package/dist/views/TicketDetailView/helpers.js +20 -0
  44. package/dist/views/TicketDetailView/types.cjs +2 -0
  45. package/dist/views/TicketDetailView/types.js +1 -0
  46. package/dist/views/TicketInboxView/client.cjs +14 -10
  47. package/dist/views/TicketInboxView/client.js +14 -10
  48. package/dist/views/TicketingSettingsView/client.cjs +101 -96
  49. package/dist/views/TicketingSettingsView/client.js +92 -88
  50. package/dist/views/TimeDashboardView/client.cjs +2 -2
  51. package/dist/views/TimeDashboardView/client.js +2 -2
  52. package/dist/views/shared/StatusPill.cjs +23 -12
  53. package/dist/views/shared/StatusPill.js +23 -12
  54. package/dist/views/shared/dateLocale.cjs +5 -0
  55. package/dist/views/shared/dateLocale.js +3 -0
  56. package/package.json +23 -15
  57. package/src/__tests__/generateTrackingToken.test.ts +53 -0
  58. package/src/__tests__/integration/ai-agent.test.ts +46 -0
  59. package/src/__tests__/integration/auth.test.ts +43 -0
  60. package/src/__tests__/integration/automation-rules.test.ts +68 -0
  61. package/src/__tests__/integration/buildTestPayload.ts +52 -0
  62. package/src/__tests__/integration/channels.test.ts +52 -0
  63. package/src/__tests__/integration/core-behaviors.test.ts +58 -0
  64. package/src/__tests__/integration/dashboard-volume.test.ts +31 -0
  65. package/src/__tests__/integration/digest.test.ts +48 -0
  66. package/src/__tests__/integration/invoice-pdf.test.ts +30 -0
  67. package/src/__tests__/integration/isolation.test.ts +81 -0
  68. package/src/__tests__/integration/mentions-invoice.test.ts +50 -0
  69. package/src/__tests__/integration/nps.test.ts +37 -0
  70. package/src/__tests__/integration/sanitization.test.ts +35 -0
  71. package/src/__tests__/integration/sla-pause.test.ts +39 -0
  72. package/src/__tests__/integration/smoke.test.ts +26 -0
  73. package/src/__tests__/integration/snooze.test.ts +68 -0
  74. package/src/__tests__/integration/teams.test.ts +38 -0
  75. package/src/__tests__/rateLimiter.test.ts +89 -0
  76. package/src/__tests__/sanitizeHtml.test.ts +165 -0
  77. package/src/__tests__/sla.test.ts +258 -0
  78. package/src/collections/AutomationRules.ts +66 -0
  79. package/src/collections/NotificationQueue.ts +30 -0
  80. package/src/collections/SatisfactionSurveys.ts +11 -2
  81. package/src/collections/SupportClients.ts +58 -1
  82. package/src/collections/SupportTeam.ts +27 -0
  83. package/src/collections/TicketActivityLog.ts +9 -4
  84. package/src/collections/TicketMessages.ts +129 -31
  85. package/src/collections/Tickets.ts +31 -73
  86. package/src/collections/index.ts +3 -0
  87. package/src/components/TicketConversation/RewriteDropdown.tsx +86 -0
  88. package/src/components/TicketConversation/SkeletonText.tsx +23 -0
  89. package/src/components/TicketConversation/constants.ts +29 -0
  90. package/src/components/TicketConversation/hooks/useDocumentIdFromUrl.ts +21 -0
  91. package/src/components/TicketConversation/index.tsx +4 -152
  92. package/src/endpoints/admin-chat-stream.ts +3 -4
  93. package/src/endpoints/admin-chat.ts +11 -20
  94. package/src/endpoints/admin-stats.ts +70 -32
  95. package/src/endpoints/ai-agent.ts +36 -0
  96. package/src/endpoints/apply-macro.ts +8 -14
  97. package/src/endpoints/auth-2fa.ts +12 -12
  98. package/src/endpoints/auto-close.ts +6 -10
  99. package/src/endpoints/billing.ts +17 -4
  100. package/src/endpoints/bulk-action.ts +7 -12
  101. package/src/endpoints/channels.ts +89 -0
  102. package/src/endpoints/chat-stream.ts +3 -4
  103. package/src/endpoints/chat.ts +7 -12
  104. package/src/endpoints/chatbot.ts +2 -2
  105. package/src/endpoints/client-intelligence.ts +4 -4
  106. package/src/endpoints/delete-account.ts +9 -16
  107. package/src/endpoints/email-stats.ts +2 -2
  108. package/src/endpoints/escalate.ts +2 -2
  109. package/src/endpoints/export-csv.ts +2 -2
  110. package/src/endpoints/export-data.ts +5 -8
  111. package/src/endpoints/import-conversation.ts +6 -10
  112. package/src/endpoints/index.ts +18 -1
  113. package/src/endpoints/invite-collaborator.ts +30 -15
  114. package/src/endpoints/invoice.ts +127 -0
  115. package/src/endpoints/kb-search.ts +2 -2
  116. package/src/endpoints/login.ts +12 -4
  117. package/src/endpoints/merge-clients.ts +14 -19
  118. package/src/endpoints/merge-tickets.ts +11 -18
  119. package/src/endpoints/oauth-google.ts +86 -39
  120. package/src/endpoints/pending-emails-process.ts +15 -25
  121. package/src/endpoints/process-digests.ts +93 -0
  122. package/src/endpoints/process-scheduled.ts +6 -10
  123. package/src/endpoints/process-snooze.ts +78 -0
  124. package/src/endpoints/purge-logs.ts +2 -2
  125. package/src/endpoints/resend-notification.ts +3 -4
  126. package/src/endpoints/round-robin-config.ts +3 -4
  127. package/src/endpoints/satisfaction.ts +21 -14
  128. package/src/endpoints/search.ts +5 -8
  129. package/src/endpoints/seed-kb.ts +3 -4
  130. package/src/endpoints/send-reminder.ts +6 -9
  131. package/src/endpoints/settings.ts +5 -2
  132. package/src/endpoints/signature.ts +3 -4
  133. package/src/endpoints/sla-check.ts +2 -2
  134. package/src/endpoints/split-ticket.ts +7 -12
  135. package/src/endpoints/statuses.ts +2 -2
  136. package/src/endpoints/ticket-feedback.ts +4 -6
  137. package/src/endpoints/ticket-synthesis.ts +2 -2
  138. package/src/endpoints/track-open.ts +16 -28
  139. package/src/endpoints/transfer-ticket.ts +21 -9
  140. package/src/endpoints/user-prefs.ts +3 -4
  141. package/src/hooks/automationRules.ts +84 -0
  142. package/src/hooks/checkSLA.ts +48 -16
  143. package/src/plugin.ts +6 -0
  144. package/src/portal/LiveChat.tsx +2 -63
  145. package/src/portal/auth/tickets/detail/CloseTicketButton.tsx +10 -0
  146. package/src/portal/auth/tickets/detail/MarkSolutionButton.tsx +14 -2
  147. package/src/portal/auth/tickets/detail/MessageActions.tsx +37 -18
  148. package/src/portal/auth/tickets/detail/ReopenTicketButton.tsx +10 -0
  149. package/src/portal/auth/tickets/detail/TransferAndInviteActions.tsx +3 -2
  150. package/src/portal/auth/tickets/detail/page.tsx +2 -2
  151. package/src/portal/helpers.ts +46 -0
  152. package/src/portal/login/page.tsx +3 -8
  153. package/src/portal/types.ts +15 -0
  154. package/src/types/lucide-react.d.ts +34 -0
  155. package/src/types/payload-config.d.ts +10 -0
  156. package/src/utils/adminNotification.ts +2 -2
  157. package/src/utils/aiAgent.ts +147 -0
  158. package/src/utils/auth.ts +5 -4
  159. package/src/utils/channels.ts +36 -0
  160. package/src/utils/db.ts +73 -0
  161. package/src/utils/emailTemplate.ts +8 -1
  162. package/src/utils/fireWebhooks.ts +4 -6
  163. package/src/utils/generateTicketSynthesis.ts +7 -12
  164. package/src/utils/invoicePdf.ts +88 -0
  165. package/src/utils/notificationQueue.ts +36 -0
  166. package/src/utils/readSettings.ts +22 -6
  167. package/src/utils/sanitizeHtml.ts +57 -0
  168. package/src/utils/slugs.ts +6 -0
  169. package/src/utils/teamAccess.ts +27 -0
  170. package/src/utils/ticketAccess.ts +53 -0
  171. package/src/utils/webhookDispatcher.ts +4 -6
  172. package/src/views/BillingView/client.tsx +49 -37
  173. package/src/views/ChatView/client.tsx +4 -3
  174. package/src/views/CrmView/client.tsx +7 -7
  175. package/src/views/EmailTrackingView/client.tsx +7 -6
  176. package/src/views/ImportConversationView/client.tsx +4 -4
  177. package/src/views/LogsView/client.tsx +3 -2
  178. package/src/views/NewTicketView/client.tsx +1 -1
  179. package/src/views/PendingEmailsView/client.tsx +7 -6
  180. package/src/views/SupportDashboardView/client.tsx +21 -21
  181. package/src/views/TicketDetailView/NextActionItem.tsx +30 -0
  182. package/src/views/TicketDetailView/RewriteDropdown.tsx +63 -0
  183. package/src/views/TicketDetailView/client.tsx +54 -179
  184. package/src/views/TicketDetailView/constants.ts +23 -0
  185. package/src/views/TicketDetailView/helpers.ts +17 -0
  186. package/src/views/TicketDetailView/types.ts +10 -0
  187. package/src/views/TicketInboxView/client.tsx +16 -10
  188. package/src/views/TicketingSettingsView/client.tsx +90 -87
  189. package/src/views/TimeDashboardView/client.tsx +2 -2
  190. package/src/views/shared/StatusPill.tsx +24 -12
  191. package/src/views/shared/dateLocale.ts +5 -0
  192. package/src/views/shared/locales/en.json +708 -0
  193. package/src/views/shared/locales/fr.json +708 -0
@@ -1,8 +1,8 @@
1
1
  "use client";
2
2
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
3
- import { useState, useEffect } from 'react';
3
+ import React, { useState, useEffect } from 'react';
4
4
  import { Settings, Mail, Bot, Clock, Timer, Globe, FileSignature } from 'lucide-react';
5
- import { V, btnStyle } from '../shared/adminTokens.js';
5
+ import { btnStyle, V } from '../shared/adminTokens.js';
6
6
  import { AdminViewHeader } from '../shared/AdminViewHeader.js';
7
7
  import { getFeatures, saveFeatures, DEFAULT_FEATURES } from '../../components/TicketConversation/config.js';
8
8
  import { useTranslation } from '../../components/TicketConversation/hooks/useTranslation.js';
@@ -97,31 +97,35 @@ async function saveUserPrefs(prefs) {
97
97
  return false;
98
98
  }
99
99
  }
100
- const FEATURE_LIST = [
101
- // Core
102
- { key: "canned", label: "R\xE9ponses rapides", description: "Templates de r\xE9ponses pr\xE9-enregistr\xE9es avec variables dynamiques", category: "core" },
103
- { key: "scheduledReplies", label: "R\xE9ponses programm\xE9es", description: "Envoyer une r\xE9ponse \xE0 une date/heure future", category: "core" },
104
- { key: "activityLog", label: "Journal d'activit\xE9", description: "Timeline des actions sur chaque ticket (changements de statut, assignation...)", category: "core" },
105
- // Communication
106
- { key: "emailTracking", label: "Suivi des emails", description: "Tracking d'envoi et d'ouverture des notifications email", category: "communication" },
107
- { key: "chat", label: "Live Chat", description: "Chat en temps r\xE9el avec conversion en ticket", category: "communication" },
108
- { key: "externalMessages", label: "Messages externes", description: "Ajouter manuellement des messages re\xE7us par email, SMS, WhatsApp...", category: "communication" },
109
- // Productivity
110
- { key: "ai", label: "Intelligence Artificielle", description: "Analyse de sentiment, synth\xE8se, suggestion de r\xE9ponse, reformulation", category: "productivity" },
111
- { key: "timeTracking", label: "Suivi du temps", description: "Timer, entr\xE9es manuelles, facturation", category: "productivity" },
112
- { key: "satisfaction", label: "Enqu\xEAtes satisfaction", description: "Score CSAT apr\xE8s r\xE9solution du ticket", category: "productivity" },
113
- // Advanced
114
- { key: "merge", label: "Fusion de tickets", description: "Combiner deux tickets en un seul", category: "advanced" },
115
- { key: "splitTicket", label: "Extraction de message", description: "Extraire un message en nouveau ticket li\xE9", category: "advanced" },
116
- { key: "snooze", label: "Snooze", description: "Masquer temporairement un ticket et rappel automatique", category: "advanced" },
117
- { key: "clientHistory", label: "Historique client", description: "Tickets pass\xE9s, projets et notes internes du client", category: "advanced" }
118
- ];
119
- const CATEGORIES = [
120
- { key: "core", label: "Fonctionnalit\xE9s de base", color: V.blue },
121
- { key: "communication", label: "Communication", color: V.green },
122
- { key: "productivity", label: "Productivit\xE9", color: V.amber },
123
- { key: "advanced", label: "Avanc\xE9", color: "#7c3aed" }
124
- ];
100
+ function getFeatureList(t) {
101
+ return [
102
+ // Core
103
+ { key: "canned", label: t("settingsView.features.canned.label"), description: t("settingsView.features.canned.description"), category: "core" },
104
+ { key: "scheduledReplies", label: t("settingsView.features.scheduledReplies.label"), description: t("settingsView.features.scheduledReplies.description"), category: "core" },
105
+ { key: "activityLog", label: t("settingsView.features.activityLog.label"), description: t("settingsView.features.activityLog.description"), category: "core" },
106
+ // Communication
107
+ { key: "emailTracking", label: t("settingsView.features.emailTracking.label"), description: t("settingsView.features.emailTracking.description"), category: "communication" },
108
+ { key: "chat", label: t("settingsView.features.chat.label"), description: t("settingsView.features.chat.description"), category: "communication" },
109
+ { key: "externalMessages", label: t("settingsView.features.externalMessages.label"), description: t("settingsView.features.externalMessages.description"), category: "communication" },
110
+ // Productivity
111
+ { key: "ai", label: t("settingsView.features.ai.label"), description: t("settingsView.features.ai.description"), category: "productivity" },
112
+ { key: "timeTracking", label: t("settingsView.features.timeTracking.label"), description: t("settingsView.features.timeTracking.description"), category: "productivity" },
113
+ { key: "satisfaction", label: t("settingsView.features.satisfaction.label"), description: t("settingsView.features.satisfaction.description"), category: "productivity" },
114
+ // Advanced
115
+ { key: "merge", label: t("settingsView.features.merge.label"), description: t("settingsView.features.merge.description"), category: "advanced" },
116
+ { key: "splitTicket", label: t("settingsView.features.splitTicket.label"), description: t("settingsView.features.splitTicket.description"), category: "advanced" },
117
+ { key: "snooze", label: t("settingsView.features.snooze.label"), description: t("settingsView.features.snooze.description"), category: "advanced" },
118
+ { key: "clientHistory", label: t("settingsView.features.clientHistory.label"), description: t("settingsView.features.clientHistory.description"), category: "advanced" }
119
+ ];
120
+ }
121
+ function getCategories(t) {
122
+ return [
123
+ { key: "core", label: t("settingsView.categories.core"), color: V.blue },
124
+ { key: "communication", label: t("settingsView.categories.communication"), color: V.green },
125
+ { key: "productivity", label: t("settingsView.categories.productivity"), color: V.amber },
126
+ { key: "advanced", label: t("settingsView.categories.advanced"), color: "#7c3aed" }
127
+ ];
128
+ }
125
129
  const Toggle = ({ checked, onChange, color = V.blue, size = "md" }) => {
126
130
  const w = size === "sm" ? 36 : 40;
127
131
  const h = size === "sm" ? 20 : 22;
@@ -200,6 +204,8 @@ const FieldRow = ({ label, description, children }) => /* @__PURE__ */ jsxs("div
200
204
  ] });
201
205
  const TicketingSettingsClient = () => {
202
206
  const { t } = useTranslation();
207
+ const FEATURE_LIST = React.useMemo(() => getFeatureList(t), [t]);
208
+ const CATEGORIES = React.useMemo(() => getCategories(t), [t]);
203
209
  const [features, setFeatures] = useState(() => getFeatures());
204
210
  const [settings, setSettings] = useState(DEFAULT_SETTINGS);
205
211
  const [signature, setSignature] = useState("");
@@ -345,13 +351,13 @@ const TicketingSettingsClient = () => {
345
351
  /* @__PURE__ */ jsxs(
346
352
  CollapsibleSection,
347
353
  {
348
- title: "Configuration Email",
354
+ title: t("settingsView.emailConfig"),
349
355
  icon: /* @__PURE__ */ jsx(Mail, { size: 16 }),
350
356
  color: "#ea580c",
351
357
  defaultOpen: false,
352
358
  children: [
353
- /* @__PURE__ */ jsx("p", { className: ts.sectionDescription, children: "Parametres d'envoi des notifications email. L'adresse SMTP est configuree via les variables d'environnement du serveur." }),
354
- /* @__PURE__ */ jsx(FieldRow, { label: "Adresse expediteur", description: "Adresse email affichee dans le champ From", children: /* @__PURE__ */ jsx(
359
+ /* @__PURE__ */ jsx("p", { className: ts.sectionDescription, children: t("settingsView.emailDescription") }),
360
+ /* @__PURE__ */ jsx(FieldRow, { label: t("settingsView.senderAddress"), description: t("settingsView.senderAddressDesc"), children: /* @__PURE__ */ jsx(
355
361
  "input",
356
362
  {
357
363
  type: "email",
@@ -361,7 +367,7 @@ const TicketingSettingsClient = () => {
361
367
  className: ts.input
362
368
  }
363
369
  ) }),
364
- /* @__PURE__ */ jsx(FieldRow, { label: "Nom expediteur", description: "Nom affiche a cote de l'adresse email", children: /* @__PURE__ */ jsx(
370
+ /* @__PURE__ */ jsx(FieldRow, { label: t("settingsView.senderName"), description: t("settingsView.senderNameDesc"), children: /* @__PURE__ */ jsx(
365
371
  "input",
366
372
  {
367
373
  type: "text",
@@ -371,7 +377,7 @@ const TicketingSettingsClient = () => {
371
377
  className: ts.input
372
378
  }
373
379
  ) }),
374
- /* @__PURE__ */ jsx(FieldRow, { label: "Adresse Reply-To", description: "Si differente de l'adresse expediteur", children: /* @__PURE__ */ jsx(
380
+ /* @__PURE__ */ jsx(FieldRow, { label: t("settingsView.replyTo"), description: t("settingsView.replyToDesc"), children: /* @__PURE__ */ jsx(
375
381
  "input",
376
382
  {
377
383
  type: "email",
@@ -382,7 +388,7 @@ const TicketingSettingsClient = () => {
382
388
  }
383
389
  ) }),
384
390
  /* @__PURE__ */ jsx("div", { className: ts.separator }),
385
- /* @__PURE__ */ jsx(FieldRow, { label: "Serveur SMTP", description: "Configure via variables d'environnement", children: /* @__PURE__ */ jsx(
391
+ /* @__PURE__ */ jsx(FieldRow, { label: t("settingsView.smtpServer"), description: t("settingsView.smtpServerDesc"), children: /* @__PURE__ */ jsx(
386
392
  "input",
387
393
  {
388
394
  type: "text",
@@ -391,7 +397,7 @@ const TicketingSettingsClient = () => {
391
397
  className: ts.inputReadonly
392
398
  }
393
399
  ) }),
394
- /* @__PURE__ */ jsx(FieldRow, { label: "Port SMTP", children: /* @__PURE__ */ jsx(
400
+ /* @__PURE__ */ jsx(FieldRow, { label: t("settingsView.smtpPort"), children: /* @__PURE__ */ jsx(
395
401
  "input",
396
402
  {
397
403
  type: "text",
@@ -407,14 +413,14 @@ const TicketingSettingsClient = () => {
407
413
  /* @__PURE__ */ jsxs(
408
414
  CollapsibleSection,
409
415
  {
410
- title: "Intelligence Artificielle",
416
+ title: t("settingsView.aiTitle"),
411
417
  icon: /* @__PURE__ */ jsx(Bot, { size: 16 }),
412
418
  color: "#7c3aed",
413
419
  defaultOpen: false,
414
- badge: features.ai ? /* @__PURE__ */ jsx("span", { className: ts.badge, style: { backgroundColor: "#dcfce7", color: "#166534" }, children: "Active" }) : /* @__PURE__ */ jsx("span", { className: ts.badge, style: { backgroundColor: "#fee2e2", color: "#991b1b" }, children: "Inactive" }),
420
+ badge: features.ai ? /* @__PURE__ */ jsx("span", { className: ts.badge, style: { backgroundColor: "#dcfce7", color: "#166534" }, children: t("settingsView.aiBadgeActive") }) : /* @__PURE__ */ jsx("span", { className: ts.badge, style: { backgroundColor: "#fee2e2", color: "#991b1b" }, children: t("settingsView.aiBadgeInactive") }),
415
421
  children: [
416
- /* @__PURE__ */ jsx("p", { className: ts.sectionDescription, children: `Configurez le fournisseur d'IA et activez/d\xE9sactivez chaque fonctionnalit\xE9 ind\xE9pendamment. Les fonctionnalit\xE9s IA n\xE9cessitent que le flag "Intelligence Artificielle" soit actif dans la section pr\xE9c\xE9dente.` }),
417
- /* @__PURE__ */ jsx(FieldRow, { label: "Fournisseur", description: "Service d'IA utilise pour l'analyse", children: /* @__PURE__ */ jsxs(
422
+ /* @__PURE__ */ jsx("p", { className: ts.sectionDescription, children: t("settingsView.aiDescription") }),
423
+ /* @__PURE__ */ jsx(FieldRow, { label: t("settingsView.aiProvider"), description: t("settingsView.aiProviderDesc"), children: /* @__PURE__ */ jsxs(
418
424
  "select",
419
425
  {
420
426
  value: settings.ai.provider,
@@ -428,7 +434,7 @@ const TicketingSettingsClient = () => {
428
434
  ]
429
435
  }
430
436
  ) }),
431
- settings.ai.provider !== "ollama" && /* @__PURE__ */ jsx(FieldRow, { label: "Cle API", description: "Cle secrete du fournisseur (non stockee en clair)", children: /* @__PURE__ */ jsxs("div", { className: ts.apiKeyRow, children: [
437
+ settings.ai.provider !== "ollama" && /* @__PURE__ */ jsx(FieldRow, { label: t("settingsView.aiApiKey"), description: t("settingsView.aiApiKeyDesc"), children: /* @__PURE__ */ jsxs("div", { className: ts.apiKeyRow, children: [
432
438
  /* @__PURE__ */ jsx(
433
439
  "input",
434
440
  {
@@ -445,11 +451,11 @@ const TicketingSettingsClient = () => {
445
451
  {
446
452
  onClick: () => setShowApiKey(!showApiKey),
447
453
  className: ts.apiKeyToggle,
448
- children: showApiKey ? "Masquer" : "Afficher"
454
+ children: showApiKey ? t("settingsView.hideKey") : t("settingsView.showKey")
449
455
  }
450
456
  )
451
457
  ] }) }),
452
- /* @__PURE__ */ jsx(FieldRow, { label: "Modele", description: "Nom du modele a utiliser", children: /* @__PURE__ */ jsx(
458
+ /* @__PURE__ */ jsx(FieldRow, { label: t("settingsView.aiModel"), description: t("settingsView.aiModelDesc"), children: /* @__PURE__ */ jsx(
453
459
  "input",
454
460
  {
455
461
  type: "text",
@@ -460,12 +466,12 @@ const TicketingSettingsClient = () => {
460
466
  }
461
467
  ) }),
462
468
  /* @__PURE__ */ jsx("div", { className: ts.separator }),
463
- /* @__PURE__ */ jsx("p", { className: ts.aiSubFeaturesLabel, children: "Fonctionnalit\xE9s IA individuelles" }),
469
+ /* @__PURE__ */ jsx("p", { className: ts.aiSubFeaturesLabel, children: t("settingsView.aiSubFeatures") }),
464
470
  [
465
- { key: "enableSentiment", label: "Analyse de sentiment", desc: "Detecte le niveau de frustration ou satisfaction du client" },
466
- { key: "enableSynthesis", label: "Synthese automatique", desc: "Resume les conversations longues en quelques phrases" },
467
- { key: "enableSuggestion", label: "Suggestion de reponse", desc: "Propose un brouillon de reponse base sur le contexte" },
468
- { key: "enableRewrite", label: "Reformulation", desc: "Reformule un message pour le rendre plus professionnel" }
471
+ { key: "enableSentiment", label: t("settingsView.aiSentiment"), desc: t("settingsView.aiSentimentDesc") },
472
+ { key: "enableSynthesis", label: t("settingsView.aiSynthesis"), desc: t("settingsView.aiSynthesisDesc") },
473
+ { key: "enableSuggestion", label: t("settingsView.aiSuggestion"), desc: t("settingsView.aiSuggestionDesc") },
474
+ { key: "enableRewrite", label: t("settingsView.aiRewrite"), desc: t("settingsView.aiRewriteDesc") }
469
475
  ].map((item) => /* @__PURE__ */ jsxs("div", { className: ts.aiToggleRow, children: [
470
476
  /* @__PURE__ */ jsx(
471
477
  Toggle,
@@ -487,13 +493,13 @@ const TicketingSettingsClient = () => {
487
493
  /* @__PURE__ */ jsxs(
488
494
  CollapsibleSection,
489
495
  {
490
- title: "SLA (Accords de niveau de service)",
496
+ title: t("settingsView.slaTitle"),
491
497
  icon: /* @__PURE__ */ jsx(Clock, { size: 16 }),
492
498
  color: "#0891b2",
493
499
  defaultOpen: false,
494
500
  children: [
495
- /* @__PURE__ */ jsx("p", { className: ts.sectionDescription, children: "Definissez les delais de reponse et de resolution attendus. Ces seuils sont utilises pour le suivi de performance et les alertes d'escalade." }),
496
- /* @__PURE__ */ jsx(FieldRow, { label: "Premiere reponse", description: "D\xE9lai maximum en minutes (d\xE9faut : 120 = 2h)", children: /* @__PURE__ */ jsxs("div", { className: ts.slaInline, children: [
501
+ /* @__PURE__ */ jsx("p", { className: ts.sectionDescription, children: t("settingsView.slaDescription") }),
502
+ /* @__PURE__ */ jsx(FieldRow, { label: t("settingsView.slaFirstResponse"), description: t("settingsView.slaFirstResponseDesc"), children: /* @__PURE__ */ jsxs("div", { className: ts.slaInline, children: [
497
503
  /* @__PURE__ */ jsx(
498
504
  "input",
499
505
  {
@@ -505,14 +511,15 @@ const TicketingSettingsClient = () => {
505
511
  }
506
512
  ),
507
513
  /* @__PURE__ */ jsxs("span", { className: ts.slaHint, children: [
508
- "minutes (",
514
+ t("settingsView.minutes"),
515
+ " (",
509
516
  Math.floor(settings.sla.firstResponseMinutes / 60),
510
517
  "h",
511
518
  String(settings.sla.firstResponseMinutes % 60).padStart(2, "0"),
512
519
  ")"
513
520
  ] })
514
521
  ] }) }),
515
- /* @__PURE__ */ jsx(FieldRow, { label: "R\xE9solution", description: "D\xE9lai maximum en minutes (d\xE9faut : 1440 = 24h)", children: /* @__PURE__ */ jsxs("div", { className: ts.slaInline, children: [
522
+ /* @__PURE__ */ jsx(FieldRow, { label: t("settingsView.slaResolution"), description: t("settingsView.slaResolutionDesc"), children: /* @__PURE__ */ jsxs("div", { className: ts.slaInline, children: [
516
523
  /* @__PURE__ */ jsx(
517
524
  "input",
518
525
  {
@@ -524,7 +531,8 @@ const TicketingSettingsClient = () => {
524
531
  }
525
532
  ),
526
533
  /* @__PURE__ */ jsxs("span", { className: ts.slaHint, children: [
527
- "minutes (",
534
+ t("settingsView.minutes"),
535
+ " (",
528
536
  Math.floor(settings.sla.resolutionMinutes / 60),
529
537
  "h",
530
538
  String(settings.sla.resolutionMinutes % 60).padStart(2, "0"),
@@ -542,12 +550,12 @@ const TicketingSettingsClient = () => {
542
550
  }
543
551
  ),
544
552
  /* @__PURE__ */ jsxs("div", { children: [
545
- /* @__PURE__ */ jsx("span", { className: ts.inlineLabel, children: "Heures ouvrables uniquement" }),
546
- /* @__PURE__ */ jsx("div", { className: ts.inlineDesc, children: "Le decompte SLA est suspendu en dehors des heures de bureau (Lun-Ven, 9h-18h)" })
553
+ /* @__PURE__ */ jsx("span", { className: ts.inlineLabel, children: t("settingsView.businessHoursOnly") }),
554
+ /* @__PURE__ */ jsx("div", { className: ts.inlineDesc, children: t("settingsView.businessHoursDesc") })
547
555
  ] })
548
556
  ] }),
549
557
  /* @__PURE__ */ jsx("div", { className: ts.separator }),
550
- /* @__PURE__ */ jsx(FieldRow, { label: "Email d'escalade", description: "Adresse notifiee en cas de depassement SLA", children: /* @__PURE__ */ jsx(
558
+ /* @__PURE__ */ jsx(FieldRow, { label: t("settingsView.escalationEmail"), description: t("settingsView.escalationEmailDesc"), children: /* @__PURE__ */ jsx(
551
559
  "input",
552
560
  {
553
561
  type: "email",
@@ -563,7 +571,7 @@ const TicketingSettingsClient = () => {
563
571
  /* @__PURE__ */ jsxs(
564
572
  CollapsibleSection,
565
573
  {
566
- title: "Fermeture automatique",
574
+ title: t("settingsView.autoCloseTitle"),
567
575
  icon: /* @__PURE__ */ jsx(Timer, { size: 16 }),
568
576
  color: "#d97706",
569
577
  defaultOpen: false,
@@ -572,7 +580,7 @@ const TicketingSettingsClient = () => {
572
580
  "j"
573
581
  ] }) : /* @__PURE__ */ jsx("span", { className: ts.badge, style: { backgroundColor: "#e5e7eb", color: "#374151" }, children: "Off" }),
574
582
  children: [
575
- /* @__PURE__ */ jsx("p", { className: ts.sectionDescription, children: "Les tickets en attente client sans reponse seront automatiquement resolus apres le delai configure. Un email de rappel est envoye avant la fermeture." }),
583
+ /* @__PURE__ */ jsx("p", { className: ts.sectionDescription, children: t("settingsView.autoCloseDescription") }),
576
584
  /* @__PURE__ */ jsxs("div", { className: ts.toggleRow, style: { paddingBottom: 14 }, children: [
577
585
  /* @__PURE__ */ jsx(
578
586
  Toggle,
@@ -582,10 +590,10 @@ const TicketingSettingsClient = () => {
582
590
  color: "#d97706"
583
591
  }
584
592
  ),
585
- /* @__PURE__ */ jsx("span", { className: ts.inlineLabel, children: "Activer la fermeture automatique" })
593
+ /* @__PURE__ */ jsx("span", { className: ts.inlineLabel, children: t("settingsView.autoCloseEnable") })
586
594
  ] }),
587
595
  settings.autoClose.enabled && /* @__PURE__ */ jsxs(Fragment, { children: [
588
- /* @__PURE__ */ jsx(FieldRow, { label: "Delai avant fermeture", description: "Nombre de jours sans reponse du client", children: /* @__PURE__ */ jsxs("div", { className: ts.slaInline, children: [
596
+ /* @__PURE__ */ jsx(FieldRow, { label: t("settingsView.autoCloseDelay"), description: t("settingsView.autoCloseDelayDesc"), children: /* @__PURE__ */ jsxs("div", { className: ts.slaInline, children: [
589
597
  /* @__PURE__ */ jsx(
590
598
  "input",
591
599
  {
@@ -597,9 +605,9 @@ const TicketingSettingsClient = () => {
597
605
  className: ts.numberInput
598
606
  }
599
607
  ),
600
- /* @__PURE__ */ jsx("span", { className: ts.slaHint, children: "jours" })
608
+ /* @__PURE__ */ jsx("span", { className: ts.slaHint, children: t("settingsView.days") })
601
609
  ] }) }),
602
- /* @__PURE__ */ jsx(FieldRow, { label: "Rappel avant fermeture", description: "Email de rappel envoye X jours avant", children: /* @__PURE__ */ jsxs("div", { className: ts.slaInline, children: [
610
+ /* @__PURE__ */ jsx(FieldRow, { label: t("settingsView.autoCloseReminder"), description: t("settingsView.autoCloseReminderDesc"), children: /* @__PURE__ */ jsxs("div", { className: ts.slaInline, children: [
603
611
  /* @__PURE__ */ jsx(
604
612
  "input",
605
613
  {
@@ -611,11 +619,7 @@ const TicketingSettingsClient = () => {
611
619
  className: ts.numberInput
612
620
  }
613
621
  ),
614
- /* @__PURE__ */ jsxs("span", { className: ts.slaHint, children: [
615
- "jours avant (rappel a J-",
616
- settings.autoClose.reminderDaysBefore,
617
- ")"
618
- ] })
622
+ /* @__PURE__ */ jsx("span", { className: ts.slaHint, children: t("settingsView.autoCloseDaysBeforeReminder", { count: String(settings.autoClose.reminderDaysBefore) }) })
619
623
  ] }) })
620
624
  ] })
621
625
  ]
@@ -629,27 +633,27 @@ const TicketingSettingsClient = () => {
629
633
  background: "linear-gradient(135deg, #dbeafe 0%, #ede9fe 100%)",
630
634
  border: "1px solid #c7d2fe"
631
635
  }, children: [
632
- /* @__PURE__ */ jsx("div", { style: { fontWeight: 700, fontSize: 15, color: "#1e293b" }, children: "Mes preferences" }),
633
- /* @__PURE__ */ jsx("div", { style: { fontSize: 13, color: "#64748b", marginTop: 2 }, children: "Ces reglages sont propres a votre compte et ne s'appliquent qu'a vous." })
636
+ /* @__PURE__ */ jsx("div", { style: { fontWeight: 700, fontSize: 15, color: "#1e293b" }, children: t("settingsView.myPreferences") }),
637
+ /* @__PURE__ */ jsx("div", { style: { fontSize: 13, color: "#64748b", marginTop: 2 }, children: t("settingsView.myPreferencesDesc") })
634
638
  ] }),
635
639
  /* @__PURE__ */ jsxs(
636
640
  CollapsibleSection,
637
641
  {
638
- title: "Langue et localisation",
642
+ title: t("settingsView.localeTitle"),
639
643
  icon: /* @__PURE__ */ jsx(Globe, { size: 16 }),
640
644
  color: "#16a34a",
641
645
  defaultOpen: false,
642
646
  children: [
643
- /* @__PURE__ */ jsx("p", { className: ts.sectionDescription, children: "Langue de l'interface du module de support et des notifications email envoyees aux clients." }),
644
- /* @__PURE__ */ jsx(FieldRow, { label: "Langue", description: "Langue principale du module", children: /* @__PURE__ */ jsxs(
647
+ /* @__PURE__ */ jsx("p", { className: ts.sectionDescription, children: t("settingsView.localeDescription") }),
648
+ /* @__PURE__ */ jsx(FieldRow, { label: t("settingsView.language"), description: t("settingsView.languageDesc"), children: /* @__PURE__ */ jsxs(
645
649
  "select",
646
650
  {
647
651
  value: settings.locale.language,
648
652
  onChange: (e) => updateLocale("language", e.target.value),
649
653
  className: ts.select,
650
654
  children: [
651
- /* @__PURE__ */ jsx("option", { value: "fr", children: "Francais" }),
652
- /* @__PURE__ */ jsx("option", { value: "en", children: "English" })
655
+ /* @__PURE__ */ jsx("option", { value: "fr", children: t("settingsView.french") }),
656
+ /* @__PURE__ */ jsx("option", { value: "en", children: t("settingsView.english") })
653
657
  ]
654
658
  }
655
659
  ) })
@@ -659,12 +663,12 @@ const TicketingSettingsClient = () => {
659
663
  /* @__PURE__ */ jsxs(
660
664
  CollapsibleSection,
661
665
  {
662
- title: "Signature email",
666
+ title: t("settingsView.signatureTitle"),
663
667
  icon: /* @__PURE__ */ jsx(FileSignature, { size: 16 }),
664
668
  color: "#6366f1",
665
669
  defaultOpen: false,
666
670
  children: [
667
- /* @__PURE__ */ jsx("p", { className: ts.sectionDescription, children: "Signature ajoutee automatiquement en bas de chaque reponse email envoyee au client. Supporte le texte brut et le HTML basique." }),
671
+ /* @__PURE__ */ jsx("p", { className: ts.sectionDescription, children: t("settingsView.signatureDescription") }),
668
672
  /* @__PURE__ */ jsx(
669
673
  "textarea",
670
674
  {
@@ -673,7 +677,7 @@ const TicketingSettingsClient = () => {
673
677
  setSignature(e.target.value);
674
678
  setSaved(false);
675
679
  },
676
- placeholder: "Cordialement,\nL'equipe ConsilioWEB",
680
+ placeholder: t("settingsView.signaturePlaceholder"),
677
681
  rows: 6,
678
682
  className: ts.signatureTextarea
679
683
  }
@@ -681,28 +685,28 @@ const TicketingSettingsClient = () => {
681
685
  ]
682
686
  }
683
687
  ),
684
- /* @__PURE__ */ jsxs(CollapsibleSection, { title: "Purge des logs", icon: /* @__PURE__ */ jsx(Settings, { size: 18 }), color: "#ef4444", defaultOpen: false, children: [
685
- /* @__PURE__ */ jsx("p", { className: ts.sectionDescription, children: "Supprimez les anciens logs pour lib\xE9rer de l'espace. Cette action est irr\xE9versible." }),
688
+ /* @__PURE__ */ jsxs(CollapsibleSection, { title: t("settingsView.purgeTitle"), icon: /* @__PURE__ */ jsx(Settings, { size: 18 }), color: "#ef4444", defaultOpen: false, children: [
689
+ /* @__PURE__ */ jsx("p", { className: ts.sectionDescription, children: t("settingsView.purgeDescription") }),
686
690
  /* @__PURE__ */ jsx("div", { className: ts.purgeGroup, children: ["email-logs", "auth-logs"].map((col) => /* @__PURE__ */ jsxs("div", { className: ts.purgeCategory, children: [
687
- /* @__PURE__ */ jsx("span", { className: ts.purgeCategoryLabel, children: col === "email-logs" ? "Logs Email" : "Logs Auth" }),
691
+ /* @__PURE__ */ jsx("span", { className: ts.purgeCategoryLabel, children: col === "email-logs" ? t("settingsView.purgeEmailLogs") : t("settingsView.purgeAuthLogs") }),
688
692
  /* @__PURE__ */ jsx("div", { className: ts.purgeButtons, children: [
689
- { label: "7 jours", days: 7 },
690
- { label: "30 jours", days: 30 },
691
- { label: "90 jours", days: 90 },
692
- { label: "Tout", days: 0 }
693
+ { label: t("settingsView.purge7days"), days: 7 },
694
+ { label: t("settingsView.purge30days"), days: 30 },
695
+ { label: t("settingsView.purge90days"), days: 90 },
696
+ { label: t("settingsView.purgeAllLabel"), days: 0 }
693
697
  ].map((opt) => /* @__PURE__ */ jsx(
694
698
  "button",
695
699
  {
696
700
  onClick: async () => {
697
- if (!window.confirm(`Supprimer les logs ${col} de plus de ${opt.days || "tous les"} jours ?`)) return;
701
+ if (!window.confirm(t("settingsView.purgeConfirm", { collection: col, days: opt.days === 0 ? t("settingsView.purgeAllLabel") : String(opt.days) }))) return;
698
702
  try {
699
703
  const res = await fetch(`/api/support/purge-logs?collection=${col}&days=${opt.days}`, { method: "DELETE", credentials: "include" });
700
704
  if (res.ok) {
701
705
  const d = await res.json();
702
- alert(`${d.purged} log(s) supprim\xE9(s)`);
706
+ alert(`${d.purged} ${t("settingsView.purgeDone")}`);
703
707
  }
704
708
  } catch {
705
- alert("Erreur");
709
+ alert(t("import.errorTitle"));
706
710
  }
707
711
  },
708
712
  style: { ...btnStyle(opt.days === 0 ? "#ef4444" : "var(--theme-elevation-500)", { small: true }), fontSize: 11 },
@@ -713,14 +717,14 @@ const TicketingSettingsClient = () => {
713
717
  ] }, col)) })
714
718
  ] }),
715
719
  /* @__PURE__ */ jsxs("div", { className: ts.bottomBar, children: [
716
- /* @__PURE__ */ jsx("button", { onClick: handleReset, style: btnStyle("var(--theme-elevation-400)", { small: true }), children: "R\xE9initialiser tout" }),
720
+ /* @__PURE__ */ jsx("button", { onClick: handleReset, style: btnStyle("var(--theme-elevation-400)", { small: true }), children: t("settingsView.resetAll") }),
717
721
  /* @__PURE__ */ jsx(
718
722
  "button",
719
723
  {
720
724
  onClick: handleSave,
721
725
  disabled: saving,
722
726
  style: btnStyle(saved ? V.green : V.blue, { small: true }),
723
- children: saving ? "Sauvegarde..." : saved ? "\u2713 Sauvegard\xE9" : "Sauvegarder les modifications"
727
+ children: saving ? t("settingsView.saving") : saved ? t("settingsView.saved2") : t("settingsView.saveChanges")
724
728
  }
725
729
  )
726
730
  ] })
@@ -65,14 +65,14 @@ const TimeDashboardClient = () => {
65
65
  for (const entry of entries) {
66
66
  let key;
67
67
  if (groupBy === "day") {
68
- key = entry.date ? entry.date.split("T")[0] : "Sans date";
68
+ key = entry.date ? entry.date.split("T")[0] : t("timeDashboard.noDate");
69
69
  } else if (groupBy === "week") {
70
70
  const d = new Date(entry.date);
71
71
  key = `Semaine ${getWeekNumber(d)} (${MONTHS_FR[d.getMonth()]} ${d.getFullYear()})`;
72
72
  } else {
73
73
  const ticket = typeof entry.ticket === "object" ? entry.ticket : null;
74
74
  const project = ticket && typeof ticket.project === "object" ? ticket.project : null;
75
- key = project?.name || "Sans projet";
75
+ key = project?.name || t("billing.noProject");
76
76
  }
77
77
  if (!map.has(key)) map.set(key, []);
78
78
  map.get(key).push(entry);
@@ -59,14 +59,14 @@ const TimeDashboardClient = () => {
59
59
  for (const entry of entries) {
60
60
  let key;
61
61
  if (groupBy === "day") {
62
- key = entry.date ? entry.date.split("T")[0] : "Sans date";
62
+ key = entry.date ? entry.date.split("T")[0] : t("timeDashboard.noDate");
63
63
  } else if (groupBy === "week") {
64
64
  const d = new Date(entry.date);
65
65
  key = `Semaine ${getWeekNumber(d)} (${MONTHS_FR[d.getMonth()]} ${d.getFullYear()})`;
66
66
  } else {
67
67
  const ticket = typeof entry.ticket === "object" ? entry.ticket : null;
68
68
  const project = ticket && typeof ticket.project === "object" ? ticket.project : null;
69
- key = project?.name || "Sans projet";
69
+ key = project?.name || t("billing.noProject");
70
70
  }
71
71
  if (!map.has(key)) map.set(key, []);
72
72
  map.get(key).push(entry);
@@ -1,30 +1,41 @@
1
1
  'use strict';
2
2
 
3
3
  var jsxRuntime = require('react/jsx-runtime');
4
+ var useTranslation = require('../../components/TicketConversation/hooks/useTranslation');
4
5
  var s = require('./StatusPill.module.scss');
5
6
 
6
7
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
7
8
 
8
9
  var s__default = /*#__PURE__*/_interopDefault(s);
9
10
 
10
- const VARIANT_MAP = {
11
- open: { cls: s__default.default.open, defaultLabel: "Ouvert" },
12
- pending: { cls: s__default.default.pending, defaultLabel: "En attente" },
13
- waiting_client: { cls: s__default.default.pending, defaultLabel: "Attente client" },
14
- resolved: { cls: s__default.default.resolved, defaultLabel: "R\xE9solu" },
15
- closed: { cls: s__default.default.neutral, defaultLabel: "Ferm\xE9" },
16
- escalated: { cls: s__default.default.escalated, defaultLabel: "Escalad\xE9" },
17
- "sla-breach": { cls: s__default.default.breach, defaultLabel: "SLA d\xE9pass\xE9" }
11
+ const VARIANT_CLS = {
12
+ open: s__default.default.open,
13
+ pending: s__default.default.pending,
14
+ waiting_client: s__default.default.pending,
15
+ resolved: s__default.default.resolved,
16
+ closed: s__default.default.neutral,
17
+ escalated: s__default.default.escalated,
18
+ "sla-breach": s__default.default.breach
19
+ };
20
+ const STATUS_I18N_KEY = {
21
+ open: "ticket.status.open",
22
+ pending: "ticket.status.pending",
23
+ waiting_client: "ticket.status.waitingClient",
24
+ resolved: "ticket.status.resolved",
25
+ closed: "ticket.status.closed",
26
+ escalated: "ticket.status.escalated",
27
+ "sla-breach": "ticket.status.slaBreached"
18
28
  };
19
29
  const StatusPill = ({ status, label, className }) => {
20
- const v = VARIANT_MAP[status] || VARIANT_MAP.open;
21
- const text = label ?? v.defaultLabel;
30
+ const { t } = useTranslation.useTranslation();
31
+ const cls = VARIANT_CLS[status] || VARIANT_CLS.open;
32
+ const text = label ?? (STATUS_I18N_KEY[status] ? t(STATUS_I18N_KEY[status]) : status);
22
33
  return /* @__PURE__ */ jsxRuntime.jsxs(
23
34
  "span",
24
35
  {
25
- className: [s__default.default.pill, v.cls, className].filter(Boolean).join(" "),
36
+ className: [s__default.default.pill, cls, className].filter(Boolean).join(" "),
26
37
  role: "status",
27
- "aria-label": `Statut : ${text}`,
38
+ "aria-label": `${t("ticket.status.label")} : ${text}`,
28
39
  children: [
29
40
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: s__default.default.dot, "aria-hidden": true }),
30
41
  text
@@ -1,24 +1,35 @@
1
1
  import { jsxs, jsx } from 'react/jsx-runtime';
2
+ import { useTranslation } from '../../components/TicketConversation/hooks/useTranslation.js';
2
3
  import s from './StatusPill.module.scss';
3
4
 
4
- const VARIANT_MAP = {
5
- open: { cls: s.open, defaultLabel: "Ouvert" },
6
- pending: { cls: s.pending, defaultLabel: "En attente" },
7
- waiting_client: { cls: s.pending, defaultLabel: "Attente client" },
8
- resolved: { cls: s.resolved, defaultLabel: "R\xE9solu" },
9
- closed: { cls: s.neutral, defaultLabel: "Ferm\xE9" },
10
- escalated: { cls: s.escalated, defaultLabel: "Escalad\xE9" },
11
- "sla-breach": { cls: s.breach, defaultLabel: "SLA d\xE9pass\xE9" }
5
+ const VARIANT_CLS = {
6
+ open: s.open,
7
+ pending: s.pending,
8
+ waiting_client: s.pending,
9
+ resolved: s.resolved,
10
+ closed: s.neutral,
11
+ escalated: s.escalated,
12
+ "sla-breach": s.breach
13
+ };
14
+ const STATUS_I18N_KEY = {
15
+ open: "ticket.status.open",
16
+ pending: "ticket.status.pending",
17
+ waiting_client: "ticket.status.waitingClient",
18
+ resolved: "ticket.status.resolved",
19
+ closed: "ticket.status.closed",
20
+ escalated: "ticket.status.escalated",
21
+ "sla-breach": "ticket.status.slaBreached"
12
22
  };
13
23
  const StatusPill = ({ status, label, className }) => {
14
- const v = VARIANT_MAP[status] || VARIANT_MAP.open;
15
- const text = label ?? v.defaultLabel;
24
+ const { t } = useTranslation();
25
+ const cls = VARIANT_CLS[status] || VARIANT_CLS.open;
26
+ const text = label ?? (STATUS_I18N_KEY[status] ? t(STATUS_I18N_KEY[status]) : status);
16
27
  return /* @__PURE__ */ jsxs(
17
28
  "span",
18
29
  {
19
- className: [s.pill, v.cls, className].filter(Boolean).join(" "),
30
+ className: [s.pill, cls, className].filter(Boolean).join(" "),
20
31
  role: "status",
21
- "aria-label": `Statut : ${text}`,
32
+ "aria-label": `${t("ticket.status.label")} : ${text}`,
22
33
  children: [
23
34
  /* @__PURE__ */ jsx("span", { className: s.dot, "aria-hidden": true }),
24
35
  text
@@ -0,0 +1,5 @@
1
+ 'use strict';
2
+
3
+ const DATE_LOCALE = "fr-FR";
4
+
5
+ exports.DATE_LOCALE = DATE_LOCALE;
@@ -0,0 +1,3 @@
1
+ const DATE_LOCALE = "fr-FR";
2
+
3
+ export { DATE_LOCALE };