datakeen-session-react 1.1.185 → 1.1.189

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 (67) hide show
  1. package/dist/cjs/components/document-video/DocumentVideoCapture.js +2 -2
  2. package/dist/cjs/components/document-video/DocumentVideoCapture.js.map +1 -1
  3. package/dist/cjs/components/document-video/document-video-flow/DocumentVideoProcessing.js +10 -11
  4. package/dist/cjs/components/document-video/document-video-flow/DocumentVideoProcessing.js.map +1 -1
  5. package/dist/cjs/components/jdi/JDIError.js +8 -4
  6. package/dist/cjs/components/jdi/JDIError.js.map +1 -1
  7. package/dist/cjs/components/jdi/JDIProcessing.js +132 -147
  8. package/dist/cjs/components/jdi/JDIProcessing.js.map +1 -1
  9. package/dist/cjs/components/session/DocumentCheck.js +36 -11
  10. package/dist/cjs/components/session/DocumentCheck.js.map +1 -1
  11. package/dist/cjs/components/session/EndFlow.js +10 -1
  12. package/dist/cjs/components/session/EndFlow.js.map +1 -1
  13. package/dist/cjs/components/session/controleJdiPolicy.js +47 -0
  14. package/dist/cjs/components/session/controleJdiPolicy.js.map +1 -0
  15. package/dist/cjs/components/signature-electronic/SignatureElectronic.js +1 -1
  16. package/dist/cjs/components/signature-electronic/SignatureElectronic.js.map +1 -1
  17. package/dist/cjs/components/signature-electronic/SignedDocumentPreview.js +6 -2
  18. package/dist/cjs/components/signature-electronic/SignedDocumentPreview.js.map +1 -1
  19. package/dist/cjs/i18n/en.json.js +9 -3
  20. package/dist/cjs/i18n/en.json.js.map +1 -1
  21. package/dist/cjs/i18n/fr.json.js +9 -3
  22. package/dist/cjs/i18n/fr.json.js.map +1 -1
  23. package/dist/cjs/index.css.js +1 -1
  24. package/dist/cjs/services/pollingService.js.map +1 -1
  25. package/dist/cjs/services/sessionService.js +15 -0
  26. package/dist/cjs/services/sessionService.js.map +1 -1
  27. package/dist/cjs/types/session.js.map +1 -1
  28. package/dist/cjs/utils/apiAnalysis.js.map +1 -1
  29. package/dist/cjs/utils/jdiCodes.js +58 -0
  30. package/dist/cjs/utils/jdiCodes.js.map +1 -0
  31. package/dist/cjs/utils/validationUtils.js +35 -2
  32. package/dist/cjs/utils/validationUtils.js.map +1 -1
  33. package/dist/esm/components/document-video/DocumentVideoCapture.js +2 -2
  34. package/dist/esm/components/document-video/DocumentVideoCapture.js.map +1 -1
  35. package/dist/esm/components/document-video/document-video-flow/DocumentVideoProcessing.js +10 -11
  36. package/dist/esm/components/document-video/document-video-flow/DocumentVideoProcessing.js.map +1 -1
  37. package/dist/esm/components/jdi/JDIError.js +8 -4
  38. package/dist/esm/components/jdi/JDIError.js.map +1 -1
  39. package/dist/esm/components/jdi/JDIProcessing.js +132 -147
  40. package/dist/esm/components/jdi/JDIProcessing.js.map +1 -1
  41. package/dist/esm/components/session/DocumentCheck.js +37 -12
  42. package/dist/esm/components/session/DocumentCheck.js.map +1 -1
  43. package/dist/esm/components/session/EndFlow.js +10 -1
  44. package/dist/esm/components/session/EndFlow.js.map +1 -1
  45. package/dist/esm/components/session/controleJdiPolicy.js +42 -0
  46. package/dist/esm/components/session/controleJdiPolicy.js.map +1 -0
  47. package/dist/esm/components/signature-electronic/SignatureElectronic.js +1 -1
  48. package/dist/esm/components/signature-electronic/SignatureElectronic.js.map +1 -1
  49. package/dist/esm/components/signature-electronic/SignedDocumentPreview.js +6 -2
  50. package/dist/esm/components/signature-electronic/SignedDocumentPreview.js.map +1 -1
  51. package/dist/esm/i18n/en.json.js +9 -3
  52. package/dist/esm/i18n/en.json.js.map +1 -1
  53. package/dist/esm/i18n/fr.json.js +9 -3
  54. package/dist/esm/i18n/fr.json.js.map +1 -1
  55. package/dist/esm/index.css.js +1 -1
  56. package/dist/esm/services/pollingService.js.map +1 -1
  57. package/dist/esm/services/sessionService.js +15 -1
  58. package/dist/esm/services/sessionService.js.map +1 -1
  59. package/dist/esm/types/session.js.map +1 -1
  60. package/dist/esm/utils/apiAnalysis.js.map +1 -1
  61. package/dist/esm/utils/jdiCodes.js +54 -0
  62. package/dist/esm/utils/jdiCodes.js.map +1 -0
  63. package/dist/esm/utils/validationUtils.js +35 -2
  64. package/dist/esm/utils/validationUtils.js.map +1 -1
  65. package/dist/types/utils/apiAnalysis.d.ts +13 -1
  66. package/docs/JOURNEY_NODE_BUILDER.md +12 -0
  67. package/package.json +1 -1
@@ -0,0 +1,47 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * Politique de routage du nœud controle-jdi quand les resoumissions sont
5
+ * épuisées sur un code bloquant — miroir de `conditionNodePolicy.ts`
6
+ * (nœud condition), extrait en fonctions pures pour rester testable sans
7
+ * monter DocumentCheck.tsx en entier.
8
+ *
9
+ * Décision produit (rétrocompat) : la sortie "false" du nœud controle-jdi
10
+ * est OPTIONNELLE. Un nœud legacy sans sortie "false" câblée doit conserver
11
+ * EXACTEMENT son comportement actuel (écran d'erreur + bouton "continuer
12
+ * quand même"). Le routage automatique true/false ne s'active que si
13
+ * l'auteur du parcours a explicitement câblé une sortie "false".
14
+ */
15
+ var DEFAULT_MAX_RESUBMISSION_ACTION = 'end-journey';
16
+ function normalizeMaxResubmissionAction(value) {
17
+ return value === 'force-true' ? 'force-true' : DEFAULT_MAX_RESUBMISSION_ACTION;
18
+ }
19
+ function hasExceededResubmissionAttempts(retryCountAfterFailure, maxAttempts) {
20
+ return retryCountAfterFailure >= maxAttempts;
21
+ }
22
+ /**
23
+ * Point de décision unique pour le routage du nœud controle-jdi après un
24
+ * résultat d'analyse.
25
+ *
26
+ * - Succès (code non bloquant) → toujours "true" (sûr même sur un nœud
27
+ * legacy à une seule arête : `findOutgoingEdge` retombe sur la première
28
+ * arête si aucune n'a le handle "true").
29
+ * - Échec, tentatives non épuisées → écran d'erreur actuel (retry possible).
30
+ * - Échec épuisé, PAS de sortie "false" câblée → écran d'erreur actuel
31
+ * inchangé (rétrocompat totale, aucune navigation automatique).
32
+ * - Échec épuisé, sortie "false" câblée → navigation automatique silencieuse
33
+ * selon `action` (miroir de `conditionMaxRetryAction`).
34
+ */
35
+ function resolveControleJdiOutcomeRoute(params) {
36
+ var hasExceededAttempts = params.hasExceededAttempts, hasFalseEdge = params.hasFalseEdge, action = params.action;
37
+ if (!hasExceededAttempts || !hasFalseEdge) {
38
+ return { handle: undefined, showErrorScreen: true };
39
+ }
40
+ return { handle: action === 'force-true' ? 'true' : 'false', showErrorScreen: false };
41
+ }
42
+
43
+ exports.DEFAULT_MAX_RESUBMISSION_ACTION = DEFAULT_MAX_RESUBMISSION_ACTION;
44
+ exports.hasExceededResubmissionAttempts = hasExceededResubmissionAttempts;
45
+ exports.normalizeMaxResubmissionAction = normalizeMaxResubmissionAction;
46
+ exports.resolveControleJdiOutcomeRoute = resolveControleJdiOutcomeRoute;
47
+ //# sourceMappingURL=controleJdiPolicy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"controleJdiPolicy.js","sources":["../../../../../src/components/session/controleJdiPolicy.ts"],"sourcesContent":["/**\n * Politique de routage du nœud controle-jdi quand les resoumissions sont\n * épuisées sur un code bloquant — miroir de `conditionNodePolicy.ts`\n * (nœud condition), extrait en fonctions pures pour rester testable sans\n * monter DocumentCheck.tsx en entier.\n *\n * Décision produit (rétrocompat) : la sortie \"false\" du nœud controle-jdi\n * est OPTIONNELLE. Un nœud legacy sans sortie \"false\" câblée doit conserver\n * EXACTEMENT son comportement actuel (écran d'erreur + bouton \"continuer\n * quand même\"). Le routage automatique true/false ne s'active que si\n * l'auteur du parcours a explicitement câblé une sortie \"false\".\n */\n\nexport type MaxResubmissionAction = 'end-journey' | 'force-true';\n\nexport const DEFAULT_MAX_RESUBMISSION_ACTION: MaxResubmissionAction = 'end-journey';\n\nexport function normalizeMaxResubmissionAction(value?: string): MaxResubmissionAction {\n return value === 'force-true' ? 'force-true' : DEFAULT_MAX_RESUBMISSION_ACTION;\n}\n\nexport function hasExceededResubmissionAttempts(\n retryCountAfterFailure: number,\n maxAttempts: number,\n): boolean {\n return retryCountAfterFailure >= maxAttempts;\n}\n\nexport interface ResolveControleJdiOutcomeRouteParams {\n /** Le code JDI reçu est-il configuré comme bloquant pour ce nœud ? */\n isBlockingCode: boolean;\n /** Le nombre de tentatives (après cet échec) a-t-il atteint/dépassé le maximum ? */\n hasExceededAttempts: boolean;\n /** Une arête sortante avec sourceHandle=\"false\" existe-t-elle sur ce nœud ? */\n hasFalseEdge: boolean;\n action: MaxResubmissionAction;\n}\n\nexport interface ControleJdiOutcomeRoute {\n /** Handle à suivre pour la navigation automatique, ou undefined si aucune navigation auto. */\n handle: 'true' | 'false' | undefined;\n /** Faut-il afficher l'écran d'erreur (JDIError) avec bouton réessayer/continuer quand même ? */\n showErrorScreen: boolean;\n}\n\n/**\n * Point de décision unique pour le routage du nœud controle-jdi après un\n * résultat d'analyse.\n *\n * - Succès (code non bloquant) → toujours \"true\" (sûr même sur un nœud\n * legacy à une seule arête : `findOutgoingEdge` retombe sur la première\n * arête si aucune n'a le handle \"true\").\n * - Échec, tentatives non épuisées → écran d'erreur actuel (retry possible).\n * - Échec épuisé, PAS de sortie \"false\" câblée → écran d'erreur actuel\n * inchangé (rétrocompat totale, aucune navigation automatique).\n * - Échec épuisé, sortie \"false\" câblée → navigation automatique silencieuse\n * selon `action` (miroir de `conditionMaxRetryAction`).\n */\nexport function resolveControleJdiOutcomeRoute(\n params: ResolveControleJdiOutcomeRouteParams,\n): ControleJdiOutcomeRoute {\n const { isBlockingCode: blocking, hasExceededAttempts, hasFalseEdge, action } = params;\n\n if (!blocking) {\n return { handle: 'true', showErrorScreen: false };\n }\n\n if (!hasExceededAttempts || !hasFalseEdge) {\n return { handle: undefined, showErrorScreen: true };\n }\n\n return { handle: action === 'force-true' ? 'true' : 'false', showErrorScreen: false };\n}\n"],"names":[],"mappings":";;AAAA;;;;;;;;;;;AAWG;AAII,IAAM,+BAA+B,GAA0B;AAEhE,SAAU,8BAA8B,CAAC,KAAc,EAAA;IAC3D,OAAO,KAAK,KAAK,YAAY,GAAG,YAAY,GAAG,+BAA+B;AAChF;AAEM,SAAU,+BAA+B,CAC7C,sBAA8B,EAC9B,WAAmB,EAAA;IAEnB,OAAO,sBAAsB,IAAI,WAAW;AAC9C;AAmBA;;;;;;;;;;;;AAYG;AACG,SAAU,8BAA8B,CAC5C,MAA4C,EAAA;AAEpC,IAAA,IAA0B,mBAAmB,GAA2B,MAAM,CAAA,mBAAjC,EAAE,YAAY,GAAa,MAAM,CAAA,YAAnB,CAAA,CAAE,MAAM,GAAK,MAAM;AAMtF,IAAA,IAAI,CAAC,mBAAmB,IAAI,CAAC,YAAY,EAAE;QACzC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,eAAe,EAAE,IAAI,EAAE;IACrD;AAEA,IAAA,OAAO,EAAE,MAAM,EAAE,MAAM,KAAK,YAAY,GAAG,MAAM,GAAG,OAAO,EAAE,eAAe,EAAE,KAAK,EAAE;AACvF;;;;;;;"}
@@ -134,7 +134,7 @@ var SignatureElectronic = function (_a) {
134
134
  }
135
135
  };
136
136
  if (showSignedDocumentPreview) {
137
- return (jsxRuntime.jsx(SignedDocumentPreview.default, { sessionId: sessionId, nodeId: node.id, nodeTitle: node.pageTitle || node.title, completedAt: signedAt, logo: (_b = session === null || session === void 0 ? void 0 : session.template) === null || _b === void 0 ? void 0 : _b.logo, onContinue: handleContinueFromPreview }));
137
+ return (jsxRuntime.jsx(SignedDocumentPreview.default, { sessionId: sessionId, nodeId: node.id, nodeTitle: node.pageTitle || node.title, completedAt: signedAt, logo: (_b = session === null || session === void 0 ? void 0 : session.template) === null || _b === void 0 ? void 0 : _b.logo, title: node.signedScreenTitle, description: node.signedScreenDescription, downloadHint: node.signedScreenDownloadHint, onContinue: handleContinueFromPreview }));
138
138
  }
139
139
  if (showSignature && external_id) {
140
140
  return (jsxRuntime.jsx(DocusealSignature.default, { sessionId: sessionId, templateId: external_id, templateName: title, onComplete: handleComplete, onBack: handleBack, prefillValues: prefillValues, readonlyFieldNames: readonlyFieldNames }));
@@ -1 +1 @@
1
- {"version":3,"file":"SignatureElectronic.js","sources":["../../../../../src/components/signature-electronic/SignatureElectronic.tsx"],"sourcesContent":["import React, { useState, useMemo, useEffect } from \"react\";\nimport type { stepObject, SessionTemplateNode, SessionData } from \"../../types/session\";\nimport type { UserInput } from \"../../types/userInput\";\nimport type { ContactInfo } from \"../../types/contactInfo\";\nimport { useTranslation } from \"react-i18next\";\nimport sdkI18n from \"../../i18n\";\nimport SignatureElectronicIntroduction from \"./SignatureElectronicIntroduction\";\nimport DocusealSignature from \"./DocusealSignature\";\nimport SignedDocumentPreview from \"./SignedDocumentPreview\";\nimport { updateSessionStatus } from \"../../services/sessionService\";\n\n/**\n * Maps an InformationFieldKey (journey field) to the corresponding UserInput key.\n * This bridges the admin-defined field names to the actual data collected in the SDK.\n */\nconst FIELD_KEY_TO_USER_INPUT: Record<string, (ui: UserInput, ci?: ContactInfo) => string | undefined> = {\n nom: (ui) => ui.lastName,\n denomination_sociale: (ui) => ui.companyName,\n prenom: (ui) => ui.firstName,\n date_naissance: (ui) => ui.birthDate,\n email: (ui, ci) => ui.email || ci?.email,\n sms: (ui, ci) => ui.sms || ui.phoneNumber || ci?.phoneNumber,\n adresse: (ui) => [ui.addressLine1, ui.addressLine2, ui.postalCode, ui.city, ui.countryCode].filter(Boolean).join(', '),\n nationalite: (ui) => ui.nationality,\n siret: (ui) => ui.siret,\n tva: (ui) => ui.tva,\n};\n\ninterface SignatureElectronicProps {\n sessionId: string;\n stepObject: stepObject;\n node: SessionTemplateNode;\n session: SessionData;\n title?: string;\n description?: string;\n external_id?: string;\n fieldMappings?: SessionTemplateNode['fieldMappings'];\n userInput?: UserInput;\n contactInfo?: ContactInfo;\n}\n\nconst SignatureElectronic: React.FC<SignatureElectronicProps> = ({\n sessionId,\n stepObject,\n node,\n session,\n title,\n description,\n external_id,\n fieldMappings,\n userInput,\n contactInfo,\n}) => {\n const { t } = useTranslation(\"translation\", { i18n: sdkI18n });\n const signatureViewStorageKey = useMemo(() => `dk-signature-open:${sessionId}:${external_id ?? \"no-template\"}`, [sessionId, external_id]);\n const [showSignature, setShowSignature] = useState<boolean>(() => {\n if (typeof window === \"undefined\") return false;\n return window.sessionStorage.getItem(signatureViewStorageKey) === \"1\";\n });\n const [showSignedDocumentPreview, setShowSignedDocumentPreview] = useState<boolean>(false);\n const [signedAt, setSignedAt] = useState<string | null>(null);\n\n useEffect(() => {\n if (typeof window === \"undefined\") return;\n\n if (showSignature) {\n window.sessionStorage.setItem(signatureViewStorageKey, \"1\");\n } else {\n window.sessionStorage.removeItem(signatureViewStorageKey);\n }\n }, [showSignature, signatureViewStorageKey]);\n\n /**\n * Build the pre-fill values object from userInput + fieldMappings.\n * Maps each configured field to its value from userInput.\n * Used by DocusealForm's `values` prop for client-side pre-filling.\n */\n const prefillValues = useMemo<Record<string, string> | undefined>(() => {\n if (!fieldMappings || !userInput) return undefined;\n\n const values: Record<string, string> = {};\n\n fieldMappings.forEach(mapping => {\n const resolver = FIELD_KEY_TO_USER_INPUT[mapping.sourceFieldId];\n let value: string | undefined;\n\n if (resolver) {\n value = resolver(userInput, contactInfo);\n } else if (userInput.customFormData) {\n const raw = userInput.customFormData[mapping.sourceFieldId];\n value = raw != null ? String(raw) : undefined;\n }\n\n if (value !== undefined && value !== '') {\n values[mapping.sourceFieldId] = value;\n }\n });\n\n return Object.keys(values).length > 0 ? values : undefined;\n }, [fieldMappings, userInput, contactInfo]);\n\n /**\n * Build the list of field names that should be read-only in the signing form.\n * Only includes fields that are both mapped AND marked as readonly by the admin.\n */\n const readonlyFieldNames = useMemo<string[] | undefined>(() => {\n if (!fieldMappings) return undefined;\n\n const names = fieldMappings\n .filter(m => m.readonly)\n .map(m => m.sourceFieldId);\n\n return names.length > 0 ? names : undefined;\n }, [fieldMappings]);\n\n const handleContinue = () => {\n setShowSignature(true);\n };\n\n const handleComplete = async () => {\n if (typeof window !== \"undefined\") {\n window.sessionStorage.removeItem(signatureViewStorageKey);\n }\n try {\n await updateSessionStatus(sessionId, \"conform\");\n } catch (err) {\n console.error(\"[SignatureElectronic] Failed to update session status:\", err);\n // Non-bloquant : l'utilisateur avance quoi qu'il arrive\n }\n // Toujours montrer le document réellement signé avant de continuer\n // (rassure l'utilisateur — pas de bascule directe vers l'étape suivante).\n setSignedAt(new Date().toISOString());\n setShowSignedDocumentPreview(true);\n };\n\n const handleContinueFromPreview = () => {\n // Progress to the next step via graph edges (pas d'arithmétique — évite de sauter dans la mauvaise branche)\n stepObject.goToNextStep(node.id, session.template);\n };\n\n const handleBack = () => {\n if (showSignature) {\n setShowSignature(false);\n } else {\n if (typeof window !== \"undefined\") {\n window.sessionStorage.removeItem(signatureViewStorageKey);\n }\n stepObject.goBack();\n }\n };\n\n if (showSignedDocumentPreview) {\n return (\n <SignedDocumentPreview\n sessionId={sessionId}\n nodeId={node.id}\n nodeTitle={node.pageTitle || node.title}\n completedAt={signedAt}\n logo={session?.template?.logo}\n onContinue={handleContinueFromPreview}\n />\n );\n }\n\n if (showSignature && external_id) {\n return (\n <DocusealSignature\n sessionId={sessionId}\n templateId={external_id}\n templateName={title}\n onComplete={handleComplete}\n onBack={handleBack}\n prefillValues={prefillValues}\n readonlyFieldNames={readonlyFieldNames}\n />\n );\n }\n\n if (showSignature && !external_id) {\n // No template configured — show error instead of silently falling back to intro\n return (\n <div className=\"flex flex-col items-center justify-center h-full p-4 text-center\">\n <div className=\"text-red-500 text-4xl mb-4\">⚠️</div>\n <h2 className=\"text-xl font-bold text-red-600 mb-2\">\n {t(\"signature.error_title\", \"Erreur\")}\n </h2>\n <p className=\"text-gray-600 mb-4\">\n {t(\"signature.no_template\", \"Le modèle de signature n'est pas configuré.\")}\n </p>\n <button\n className=\"px-4 py-2 bg-primary text-white rounded hover:bg-primary-dark transition-colors\"\n onClick={handleBack}\n >\n {t(\"buttons.back\", \"Retour\")}\n </button>\n </div>\n );\n }\n\n return (\n <SignatureElectronicIntroduction\n onContinue={handleContinue}\n onBack={stepObject.canGoBack ? handleBack : undefined}\n title={title}\n description={description}\n />\n );\n};\n\nexport default SignatureElectronic;\n"],"names":["useTranslation","sdkI18n","useMemo","useState","useEffect","__awaiter","updateSessionStatus","_jsx","SignedDocumentPreview","DocusealSignature","_jsxs","SignatureElectronicIntroduction"],"mappings":"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"}
1
+ {"version":3,"file":"SignatureElectronic.js","sources":["../../../../../src/components/signature-electronic/SignatureElectronic.tsx"],"sourcesContent":["import React, { useState, useMemo, useEffect } from \"react\";\nimport type { stepObject, SessionTemplateNode, SessionData } from \"../../types/session\";\nimport type { UserInput } from \"../../types/userInput\";\nimport type { ContactInfo } from \"../../types/contactInfo\";\nimport { useTranslation } from \"react-i18next\";\nimport sdkI18n from \"../../i18n\";\nimport SignatureElectronicIntroduction from \"./SignatureElectronicIntroduction\";\nimport DocusealSignature from \"./DocusealSignature\";\nimport SignedDocumentPreview from \"./SignedDocumentPreview\";\nimport { updateSessionStatus } from \"../../services/sessionService\";\n\n/**\n * Maps an InformationFieldKey (journey field) to the corresponding UserInput key.\n * This bridges the admin-defined field names to the actual data collected in the SDK.\n */\nconst FIELD_KEY_TO_USER_INPUT: Record<string, (ui: UserInput, ci?: ContactInfo) => string | undefined> = {\n nom: (ui) => ui.lastName,\n denomination_sociale: (ui) => ui.companyName,\n prenom: (ui) => ui.firstName,\n date_naissance: (ui) => ui.birthDate,\n email: (ui, ci) => ui.email || ci?.email,\n sms: (ui, ci) => ui.sms || ui.phoneNumber || ci?.phoneNumber,\n adresse: (ui) => [ui.addressLine1, ui.addressLine2, ui.postalCode, ui.city, ui.countryCode].filter(Boolean).join(', '),\n nationalite: (ui) => ui.nationality,\n siret: (ui) => ui.siret,\n tva: (ui) => ui.tva,\n};\n\ninterface SignatureElectronicProps {\n sessionId: string;\n stepObject: stepObject;\n node: SessionTemplateNode;\n session: SessionData;\n title?: string;\n description?: string;\n external_id?: string;\n fieldMappings?: SessionTemplateNode['fieldMappings'];\n userInput?: UserInput;\n contactInfo?: ContactInfo;\n}\n\nconst SignatureElectronic: React.FC<SignatureElectronicProps> = ({\n sessionId,\n stepObject,\n node,\n session,\n title,\n description,\n external_id,\n fieldMappings,\n userInput,\n contactInfo,\n}) => {\n const { t } = useTranslation(\"translation\", { i18n: sdkI18n });\n const signatureViewStorageKey = useMemo(() => `dk-signature-open:${sessionId}:${external_id ?? \"no-template\"}`, [sessionId, external_id]);\n const [showSignature, setShowSignature] = useState<boolean>(() => {\n if (typeof window === \"undefined\") return false;\n return window.sessionStorage.getItem(signatureViewStorageKey) === \"1\";\n });\n const [showSignedDocumentPreview, setShowSignedDocumentPreview] = useState<boolean>(false);\n const [signedAt, setSignedAt] = useState<string | null>(null);\n\n useEffect(() => {\n if (typeof window === \"undefined\") return;\n\n if (showSignature) {\n window.sessionStorage.setItem(signatureViewStorageKey, \"1\");\n } else {\n window.sessionStorage.removeItem(signatureViewStorageKey);\n }\n }, [showSignature, signatureViewStorageKey]);\n\n /**\n * Build the pre-fill values object from userInput + fieldMappings.\n * Maps each configured field to its value from userInput.\n * Used by DocusealForm's `values` prop for client-side pre-filling.\n */\n const prefillValues = useMemo<Record<string, string> | undefined>(() => {\n if (!fieldMappings || !userInput) return undefined;\n\n const values: Record<string, string> = {};\n\n fieldMappings.forEach(mapping => {\n const resolver = FIELD_KEY_TO_USER_INPUT[mapping.sourceFieldId];\n let value: string | undefined;\n\n if (resolver) {\n value = resolver(userInput, contactInfo);\n } else if (userInput.customFormData) {\n const raw = userInput.customFormData[mapping.sourceFieldId];\n value = raw != null ? String(raw) : undefined;\n }\n\n if (value !== undefined && value !== '') {\n values[mapping.sourceFieldId] = value;\n }\n });\n\n return Object.keys(values).length > 0 ? values : undefined;\n }, [fieldMappings, userInput, contactInfo]);\n\n /**\n * Build the list of field names that should be read-only in the signing form.\n * Only includes fields that are both mapped AND marked as readonly by the admin.\n */\n const readonlyFieldNames = useMemo<string[] | undefined>(() => {\n if (!fieldMappings) return undefined;\n\n const names = fieldMappings\n .filter(m => m.readonly)\n .map(m => m.sourceFieldId);\n\n return names.length > 0 ? names : undefined;\n }, [fieldMappings]);\n\n const handleContinue = () => {\n setShowSignature(true);\n };\n\n const handleComplete = async () => {\n if (typeof window !== \"undefined\") {\n window.sessionStorage.removeItem(signatureViewStorageKey);\n }\n try {\n await updateSessionStatus(sessionId, \"conform\");\n } catch (err) {\n console.error(\"[SignatureElectronic] Failed to update session status:\", err);\n // Non-bloquant : l'utilisateur avance quoi qu'il arrive\n }\n // Toujours montrer le document réellement signé avant de continuer\n // (rassure l'utilisateur — pas de bascule directe vers l'étape suivante).\n setSignedAt(new Date().toISOString());\n setShowSignedDocumentPreview(true);\n };\n\n const handleContinueFromPreview = () => {\n // Progress to the next step via graph edges (pas d'arithmétique — évite de sauter dans la mauvaise branche)\n stepObject.goToNextStep(node.id, session.template);\n };\n\n const handleBack = () => {\n if (showSignature) {\n setShowSignature(false);\n } else {\n if (typeof window !== \"undefined\") {\n window.sessionStorage.removeItem(signatureViewStorageKey);\n }\n stepObject.goBack();\n }\n };\n\n if (showSignedDocumentPreview) {\n return (\n <SignedDocumentPreview\n sessionId={sessionId}\n nodeId={node.id}\n nodeTitle={node.pageTitle || node.title}\n completedAt={signedAt}\n logo={session?.template?.logo}\n title={node.signedScreenTitle}\n description={node.signedScreenDescription}\n downloadHint={node.signedScreenDownloadHint}\n onContinue={handleContinueFromPreview}\n />\n );\n }\n\n if (showSignature && external_id) {\n return (\n <DocusealSignature\n sessionId={sessionId}\n templateId={external_id}\n templateName={title}\n onComplete={handleComplete}\n onBack={handleBack}\n prefillValues={prefillValues}\n readonlyFieldNames={readonlyFieldNames}\n />\n );\n }\n\n if (showSignature && !external_id) {\n // No template configured — show error instead of silently falling back to intro\n return (\n <div className=\"flex flex-col items-center justify-center h-full p-4 text-center\">\n <div className=\"text-red-500 text-4xl mb-4\">⚠️</div>\n <h2 className=\"text-xl font-bold text-red-600 mb-2\">\n {t(\"signature.error_title\", \"Erreur\")}\n </h2>\n <p className=\"text-gray-600 mb-4\">\n {t(\"signature.no_template\", \"Le modèle de signature n'est pas configuré.\")}\n </p>\n <button\n className=\"px-4 py-2 bg-primary text-white rounded hover:bg-primary-dark transition-colors\"\n onClick={handleBack}\n >\n {t(\"buttons.back\", \"Retour\")}\n </button>\n </div>\n );\n }\n\n return (\n <SignatureElectronicIntroduction\n onContinue={handleContinue}\n onBack={stepObject.canGoBack ? handleBack : undefined}\n title={title}\n description={description}\n />\n );\n};\n\nexport default SignatureElectronic;\n"],"names":["useTranslation","sdkI18n","useMemo","useState","useEffect","__awaiter","updateSessionStatus","_jsx","SignedDocumentPreview","DocusealSignature","_jsxs","SignatureElectronicIntroduction"],"mappings":"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"}
@@ -13,14 +13,18 @@ var LoadingState = require('../states/LoadingState.js');
13
13
  var MobilePageLayout = require('../ui/MobilePageLayout.js');
14
14
  var PageActions = require('../ui/PageActions.js');
15
15
  var Button = require('../ui/Button.js');
16
+ var Title = require('../ui/Title.js');
16
17
 
17
18
  var STATUS_POLL_INTERVAL_MS = 2000;
18
19
  // DocuSeal flags a submission "completed" before generating the flattened
19
20
  // signed PDF — 15 attempts (30s) leaves enough margin for that async step.
20
21
  var MAX_STATUS_POLL_ATTEMPTS = 15;
21
22
  var SignedDocumentPreview = function (_a) {
22
- var sessionId = _a.sessionId, nodeId = _a.nodeId, nodeTitle = _a.nodeTitle, completedAt = _a.completedAt, logo = _a.logo, onContinue = _a.onContinue;
23
+ var sessionId = _a.sessionId, nodeId = _a.nodeId, nodeTitle = _a.nodeTitle, completedAt = _a.completedAt, logo = _a.logo, propTitle = _a.title, propDescription = _a.description, propDownloadHint = _a.downloadHint, onContinue = _a.onContinue;
23
24
  var _b = reactI18next.useTranslation("translation", { i18n: index.default }), t = _b.t, i18n = _b.i18n;
25
+ var title = (propTitle === null || propTitle === void 0 ? void 0 : propTitle.trim()) || t("signed_document.title", "Votre document est signé");
26
+ var description = (propDescription === null || propDescription === void 0 ? void 0 : propDescription.trim()) || t("signed_document.ready_text", "Merci d'avoir signé le document, vous pouvez le consulter en cliquant ci-dessous :");
27
+ var downloadHint = (propDownloadHint === null || propDownloadHint === void 0 ? void 0 : propDownloadHint.trim()) || t("signed_document.download_hint", "Si vous souhaitez conserver ce document, vous pouvez le télécharger depuis cette page.");
24
28
  var _c = React.useState("polling"), status = _c[0], setStatus = _c[1];
25
29
  var _d = React.useState(null), viewUrl = _d[0], setViewUrl = _d[1];
26
30
  var cancelledRef = React.useRef(false);
@@ -123,7 +127,7 @@ var SignedDocumentPreview = function (_a) {
123
127
  year: "numeric",
124
128
  }).format(new Date(completedAt))
125
129
  : null;
126
- return (jsxRuntime.jsx(MobilePageLayout.default, { footer: jsxRuntime.jsx(PageActions.default, { primary: jsxRuntime.jsx(Button.default, { onClick: onContinue, type: "button", children: t("buttons.continue", "Continuer") }) }), children: jsxRuntime.jsxs("div", { className: "flex flex-col items-center h-full px-4 py-8 md:px-8 text-center gap-6", children: [logo && jsxRuntime.jsx("img", { src: logo, alt: "", className: "h-12 max-w-[200px] object-contain" }), status === "ready" && viewUrl && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsxs("div", { className: "w-full max-w-md bg-gray-50 rounded-lg p-4 flex items-start gap-3 text-left", children: [jsxRuntime.jsx(lucideReact.PenTool, { className: "w-5 h-5 shrink-0 mt-0.5 text-gray-500" }), jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("p", { className: "font-semibold text-gray-900 break-all", children: nodeTitle }), formattedDate && (jsxRuntime.jsxs("p", { className: "text-xs text-gray-500 mt-1", children: [t("signed_document.submitted_on", "Soumis le"), " ", formattedDate] }))] })] }), jsxRuntime.jsx("p", { className: "text-sm text-gray-600", children: t("signed_document.ready_text", "Merci d'avoir signé le document, vous pouvez le consulter en cliquant ci-dessous :") }), jsxRuntime.jsx("a", { href: viewUrl, target: "_blank", rel: "noopener noreferrer", className: "text-primary underline font-medium", children: t("signed_document.view_link", "Consulter le document ↗") }), jsxRuntime.jsx("p", { className: "text-sm text-gray-600", children: t("signed_document.download_hint", "Si vous souhaitez conserver ce document, vous pouvez le télécharger depuis cette page.") })] })), status === "error" && (jsxRuntime.jsx("p", { className: "text-sm text-gray-600 py-8", children: t("signed_document.error", "Le document n'a pas pu être chargé, mais votre signature est bien enregistrée. Vous pouvez continuer.") })), status === "declined" && (jsxRuntime.jsx("p", { className: "text-sm text-gray-600 py-8", children: t("signed_document.declined", "Vous avez refusé de signer ce document.") })), status === "expired" && (jsxRuntime.jsx("p", { className: "text-sm text-gray-600 py-8", children: t("signed_document.expired", "Le lien de signature a expiré.") }))] }) }));
130
+ return (jsxRuntime.jsx(MobilePageLayout.default, { footer: jsxRuntime.jsx(PageActions.default, { primary: jsxRuntime.jsx(Button.default, { onClick: onContinue, type: "button", children: t("buttons.continue", "Continuer") }) }), children: jsxRuntime.jsxs("div", { className: "flex flex-col items-center h-full px-4 py-8 md:px-8 text-center gap-6", children: [logo && jsxRuntime.jsx("img", { src: logo, alt: "", className: "h-12 max-w-[200px] object-contain" }), status === "ready" && viewUrl && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(Title.default, { children: title }), jsxRuntime.jsxs("div", { className: "w-full max-w-md bg-gray-50 rounded-lg p-4 flex items-start gap-3 text-left", children: [jsxRuntime.jsx(lucideReact.PenTool, { className: "w-5 h-5 shrink-0 mt-0.5 text-gray-500" }), jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("p", { className: "font-semibold text-gray-900 break-all", children: nodeTitle }), formattedDate && (jsxRuntime.jsxs("p", { className: "text-xs text-gray-500 mt-1", children: [t("signed_document.submitted_on", "Soumis le"), " ", formattedDate] }))] })] }), jsxRuntime.jsx("p", { className: "text-sm text-gray-600 whitespace-pre-line", children: description }), jsxRuntime.jsx("a", { href: viewUrl, target: "_blank", rel: "noopener noreferrer", className: "text-primary underline font-medium", children: t("signed_document.view_link", "Consulter le document ↗") }), jsxRuntime.jsx("p", { className: "text-sm text-gray-600 whitespace-pre-line", children: downloadHint })] })), status === "error" && (jsxRuntime.jsx("p", { className: "text-sm text-gray-600 py-8", children: t("signed_document.error", "Le document n'a pas pu être chargé, mais votre signature est bien enregistrée. Vous pouvez continuer.") })), status === "declined" && (jsxRuntime.jsx("p", { className: "text-sm text-gray-600 py-8", children: t("signed_document.declined", "Vous avez refusé de signer ce document.") })), status === "expired" && (jsxRuntime.jsx("p", { className: "text-sm text-gray-600 py-8", children: t("signed_document.expired", "Le lien de signature a expiré.") }))] }) }));
127
131
  };
128
132
 
129
133
  exports.default = SignedDocumentPreview;
@@ -1 +1 @@
1
- {"version":3,"file":"SignedDocumentPreview.js","sources":["../../../../../src/components/signature-electronic/SignedDocumentPreview.tsx"],"sourcesContent":["import React, { useEffect, useRef, useState } from \"react\";\nimport { PenTool } from \"lucide-react\";\nimport { useTranslation } from \"react-i18next\";\nimport sdkI18n from \"../../i18n\";\nimport { apiService } from \"../../services/api\";\nimport LoadingState from \"../states/LoadingState\";\nimport MobilePageLayout from \"../ui/MobilePageLayout\";\nimport PageActions from \"../ui/PageActions\";\nimport Button from \"../ui/Button\";\n\ninterface SignedDocumentPreviewProps {\n sessionId: string;\n nodeId: string;\n nodeTitle: string;\n completedAt: string | null;\n logo?: string;\n onContinue: () => void;\n}\n\nconst STATUS_POLL_INTERVAL_MS = 2000;\n// DocuSeal flags a submission \"completed\" before generating the flattened\n// signed PDF — 15 attempts (30s) leaves enough margin for that async step.\nconst MAX_STATUS_POLL_ATTEMPTS = 15;\n\nconst SignedDocumentPreview: React.FC<SignedDocumentPreviewProps> = ({\n sessionId,\n nodeId,\n nodeTitle,\n completedAt,\n logo,\n onContinue,\n}) => {\n const { t, i18n } = useTranslation(\"translation\", { i18n: sdkI18n });\n const [status, setStatus] = useState<\"polling\" | \"ready\" | \"error\" | \"declined\" | \"expired\">(\n \"polling\",\n );\n const [viewUrl, setViewUrl] = useState<string | null>(null);\n const cancelledRef = useRef(false);\n\n useEffect(() => {\n cancelledRef.current = false;\n let attempts = 0;\n let timer: ReturnType<typeof setTimeout> | undefined;\n\n const fetchAccessLink = async () => {\n const response = await apiService.get(\n `/session/sdk/${sessionId}/signed-document/${nodeId}/access-link`,\n );\n const token = response.data?.data?.token;\n if (!token) {\n throw new Error(\"Missing signed document access token\");\n }\n\n const baseURL = (apiService.getRawClient().defaults.baseURL || \"\").replace(\n /\\/+$/,\n \"\",\n );\n const path = `/session/sdk/${sessionId}/signed-document/${nodeId}/view?token=${token}`;\n\n if (!cancelledRef.current) {\n setViewUrl(baseURL ? `${baseURL}${path}` : path);\n setStatus(\"ready\");\n }\n };\n\n const poll = async () => {\n try {\n const statusResponse = await apiService.get(\n `/session/sdk/${sessionId}/signed-document/${nodeId}/status`,\n );\n const ready = !!statusResponse.data?.data?.ready;\n const error = statusResponse.data?.data?.error as\n | \"declined\"\n | \"expired\"\n | undefined;\n\n if (error === \"declined\" || error === \"expired\") {\n if (!cancelledRef.current) setStatus(error);\n return;\n }\n\n if (ready) {\n try {\n await fetchAccessLink();\n return;\n } catch (err) {\n // DocuSeal can report the submission \"completed\" before the\n // signed document is actually linked — treat like \"not ready\n // yet\" instead of failing permanently on the first miss.\n console.error(\n \"[SignedDocumentPreview] Failed to fetch access link:\",\n err,\n );\n }\n }\n\n attempts += 1;\n if (attempts >= MAX_STATUS_POLL_ATTEMPTS) {\n if (!cancelledRef.current) setStatus(\"error\");\n return;\n }\n timer = setTimeout(poll, STATUS_POLL_INTERVAL_MS);\n } catch (err) {\n console.error(\"[SignedDocumentPreview] Failed to poll signed document status:\", err);\n attempts += 1;\n if (attempts >= MAX_STATUS_POLL_ATTEMPTS) {\n if (!cancelledRef.current) setStatus(\"error\");\n return;\n }\n timer = setTimeout(poll, STATUS_POLL_INTERVAL_MS);\n }\n };\n\n poll();\n\n return () => {\n cancelledRef.current = true;\n if (timer) clearTimeout(timer);\n };\n }, [sessionId, nodeId]);\n\n if (status === \"polling\") {\n return (\n <LoadingState\n message={t(\"signed_document.loading\", \"Préparation du document signé...\")}\n subtitle=\"\"\n />\n );\n }\n\n const formattedDate = completedAt\n ? new Intl.DateTimeFormat(i18n.language || \"fr\", {\n day: \"numeric\",\n month: \"long\",\n year: \"numeric\",\n }).format(new Date(completedAt))\n : null;\n\n return (\n <MobilePageLayout\n footer={\n <PageActions\n primary={\n <Button onClick={onContinue} type=\"button\">\n {t(\"buttons.continue\", \"Continuer\")}\n </Button>\n }\n />\n }\n >\n <div className=\"flex flex-col items-center h-full px-4 py-8 md:px-8 text-center gap-6\">\n {logo && <img src={logo} alt=\"\" className=\"h-12 max-w-[200px] object-contain\" />}\n\n {status === \"ready\" && viewUrl && (\n <>\n <div className=\"w-full max-w-md bg-gray-50 rounded-lg p-4 flex items-start gap-3 text-left\">\n <PenTool className=\"w-5 h-5 shrink-0 mt-0.5 text-gray-500\" />\n <div>\n <p className=\"font-semibold text-gray-900 break-all\">{nodeTitle}</p>\n {formattedDate && (\n <p className=\"text-xs text-gray-500 mt-1\">\n {t(\"signed_document.submitted_on\", \"Soumis le\")} {formattedDate}\n </p>\n )}\n </div>\n </div>\n\n <p className=\"text-sm text-gray-600\">\n {t(\n \"signed_document.ready_text\",\n \"Merci d'avoir signé le document, vous pouvez le consulter en cliquant ci-dessous :\",\n )}\n </p>\n\n <a\n href={viewUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"text-primary underline font-medium\"\n >\n {t(\"signed_document.view_link\", \"Consulter le document ↗\")}\n </a>\n\n <p className=\"text-sm text-gray-600\">\n {t(\n \"signed_document.download_hint\",\n \"Si vous souhaitez conserver ce document, vous pouvez le télécharger depuis cette page.\",\n )}\n </p>\n </>\n )}\n\n {status === \"error\" && (\n <p className=\"text-sm text-gray-600 py-8\">\n {t(\n \"signed_document.error\",\n \"Le document n'a pas pu être chargé, mais votre signature est bien enregistrée. Vous pouvez continuer.\",\n )}\n </p>\n )}\n {status === \"declined\" && (\n <p className=\"text-sm text-gray-600 py-8\">\n {t(\"signed_document.declined\", \"Vous avez refusé de signer ce document.\")}\n </p>\n )}\n {status === \"expired\" && (\n <p className=\"text-sm text-gray-600 py-8\">\n {t(\"signed_document.expired\", \"Le lien de signature a expiré.\")}\n </p>\n )}\n </div>\n </MobilePageLayout>\n );\n};\n\nexport default SignedDocumentPreview;\n"],"names":["useTranslation","sdkI18n","useState","useRef","useEffect","__awaiter","apiService","_jsx","LoadingState","MobilePageLayout","PageActions","Button","_jsxs","_Fragment","PenTool"],"mappings":"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"}
1
+ {"version":3,"file":"SignedDocumentPreview.js","sources":["../../../../../src/components/signature-electronic/SignedDocumentPreview.tsx"],"sourcesContent":["import React, { useEffect, useRef, useState } from \"react\";\nimport { PenTool } from \"lucide-react\";\nimport { useTranslation } from \"react-i18next\";\nimport sdkI18n from \"../../i18n\";\nimport { apiService } from \"../../services/api\";\nimport LoadingState from \"../states/LoadingState\";\nimport MobilePageLayout from \"../ui/MobilePageLayout\";\nimport PageActions from \"../ui/PageActions\";\nimport Button from \"../ui/Button\";\nimport Title from \"../ui/Title\";\n\ninterface SignedDocumentPreviewProps {\n sessionId: string;\n nodeId: string;\n nodeTitle: string;\n completedAt: string | null;\n logo?: string;\n title?: string;\n description?: string;\n downloadHint?: string;\n onContinue: () => void;\n}\n\nconst STATUS_POLL_INTERVAL_MS = 2000;\n// DocuSeal flags a submission \"completed\" before generating the flattened\n// signed PDF — 15 attempts (30s) leaves enough margin for that async step.\nconst MAX_STATUS_POLL_ATTEMPTS = 15;\n\nconst SignedDocumentPreview: React.FC<SignedDocumentPreviewProps> = ({\n sessionId,\n nodeId,\n nodeTitle,\n completedAt,\n logo,\n title: propTitle,\n description: propDescription,\n downloadHint: propDownloadHint,\n onContinue,\n}) => {\n const { t, i18n } = useTranslation(\"translation\", { i18n: sdkI18n });\n const title = propTitle?.trim() || t(\"signed_document.title\", \"Votre document est signé\");\n const description = propDescription?.trim() || t(\n \"signed_document.ready_text\",\n \"Merci d'avoir signé le document, vous pouvez le consulter en cliquant ci-dessous :\",\n );\n const downloadHint = propDownloadHint?.trim() || t(\n \"signed_document.download_hint\",\n \"Si vous souhaitez conserver ce document, vous pouvez le télécharger depuis cette page.\",\n );\n const [status, setStatus] = useState<\"polling\" | \"ready\" | \"error\" | \"declined\" | \"expired\">(\n \"polling\",\n );\n const [viewUrl, setViewUrl] = useState<string | null>(null);\n const cancelledRef = useRef(false);\n\n useEffect(() => {\n cancelledRef.current = false;\n let attempts = 0;\n let timer: ReturnType<typeof setTimeout> | undefined;\n\n const fetchAccessLink = async () => {\n const response = await apiService.get(\n `/session/sdk/${sessionId}/signed-document/${nodeId}/access-link`,\n );\n const token = response.data?.data?.token;\n if (!token) {\n throw new Error(\"Missing signed document access token\");\n }\n\n const baseURL = (apiService.getRawClient().defaults.baseURL || \"\").replace(\n /\\/+$/,\n \"\",\n );\n const path = `/session/sdk/${sessionId}/signed-document/${nodeId}/view?token=${token}`;\n\n if (!cancelledRef.current) {\n setViewUrl(baseURL ? `${baseURL}${path}` : path);\n setStatus(\"ready\");\n }\n };\n\n const poll = async () => {\n try {\n const statusResponse = await apiService.get(\n `/session/sdk/${sessionId}/signed-document/${nodeId}/status`,\n );\n const ready = !!statusResponse.data?.data?.ready;\n const error = statusResponse.data?.data?.error as\n | \"declined\"\n | \"expired\"\n | undefined;\n\n if (error === \"declined\" || error === \"expired\") {\n if (!cancelledRef.current) setStatus(error);\n return;\n }\n\n if (ready) {\n try {\n await fetchAccessLink();\n return;\n } catch (err) {\n // DocuSeal can report the submission \"completed\" before the\n // signed document is actually linked — treat like \"not ready\n // yet\" instead of failing permanently on the first miss.\n console.error(\n \"[SignedDocumentPreview] Failed to fetch access link:\",\n err,\n );\n }\n }\n\n attempts += 1;\n if (attempts >= MAX_STATUS_POLL_ATTEMPTS) {\n if (!cancelledRef.current) setStatus(\"error\");\n return;\n }\n timer = setTimeout(poll, STATUS_POLL_INTERVAL_MS);\n } catch (err) {\n console.error(\"[SignedDocumentPreview] Failed to poll signed document status:\", err);\n attempts += 1;\n if (attempts >= MAX_STATUS_POLL_ATTEMPTS) {\n if (!cancelledRef.current) setStatus(\"error\");\n return;\n }\n timer = setTimeout(poll, STATUS_POLL_INTERVAL_MS);\n }\n };\n\n poll();\n\n return () => {\n cancelledRef.current = true;\n if (timer) clearTimeout(timer);\n };\n }, [sessionId, nodeId]);\n\n if (status === \"polling\") {\n return (\n <LoadingState\n message={t(\"signed_document.loading\", \"Préparation du document signé...\")}\n subtitle=\"\"\n />\n );\n }\n\n const formattedDate = completedAt\n ? new Intl.DateTimeFormat(i18n.language || \"fr\", {\n day: \"numeric\",\n month: \"long\",\n year: \"numeric\",\n }).format(new Date(completedAt))\n : null;\n\n return (\n <MobilePageLayout\n footer={\n <PageActions\n primary={\n <Button onClick={onContinue} type=\"button\">\n {t(\"buttons.continue\", \"Continuer\")}\n </Button>\n }\n />\n }\n >\n <div className=\"flex flex-col items-center h-full px-4 py-8 md:px-8 text-center gap-6\">\n {logo && <img src={logo} alt=\"\" className=\"h-12 max-w-[200px] object-contain\" />}\n\n {status === \"ready\" && viewUrl && (\n <>\n <Title>{title}</Title>\n\n <div className=\"w-full max-w-md bg-gray-50 rounded-lg p-4 flex items-start gap-3 text-left\">\n <PenTool className=\"w-5 h-5 shrink-0 mt-0.5 text-gray-500\" />\n <div>\n <p className=\"font-semibold text-gray-900 break-all\">{nodeTitle}</p>\n {formattedDate && (\n <p className=\"text-xs text-gray-500 mt-1\">\n {t(\"signed_document.submitted_on\", \"Soumis le\")} {formattedDate}\n </p>\n )}\n </div>\n </div>\n\n <p className=\"text-sm text-gray-600 whitespace-pre-line\">\n {description}\n </p>\n\n <a\n href={viewUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"text-primary underline font-medium\"\n >\n {t(\"signed_document.view_link\", \"Consulter le document ↗\")}\n </a>\n\n <p className=\"text-sm text-gray-600 whitespace-pre-line\">\n {downloadHint}\n </p>\n </>\n )}\n\n {status === \"error\" && (\n <p className=\"text-sm text-gray-600 py-8\">\n {t(\n \"signed_document.error\",\n \"Le document n'a pas pu être chargé, mais votre signature est bien enregistrée. Vous pouvez continuer.\",\n )}\n </p>\n )}\n {status === \"declined\" && (\n <p className=\"text-sm text-gray-600 py-8\">\n {t(\"signed_document.declined\", \"Vous avez refusé de signer ce document.\")}\n </p>\n )}\n {status === \"expired\" && (\n <p className=\"text-sm text-gray-600 py-8\">\n {t(\"signed_document.expired\", \"Le lien de signature a expiré.\")}\n </p>\n )}\n </div>\n </MobilePageLayout>\n );\n};\n\nexport default SignedDocumentPreview;\n"],"names":["useTranslation","sdkI18n","useState","useRef","useEffect","__awaiter","apiService","_jsx","LoadingState","MobilePageLayout","PageActions","Button","_jsxs","_Fragment","Title","PenTool"],"mappings":"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"}
@@ -177,7 +177,8 @@ var validation_points = {
177
177
  },
178
178
  "4.0": {
179
179
  quality: "• Image quality: Validated",
180
- readability: "• Information readability: Confirmed"
180
+ readability: "• Information readability: Confirmed",
181
+ document: "• Document: A security element on the card could not be verified due to its quality, please submit another file."
181
182
  },
182
183
  "4.1": {
183
184
  quality: "• Image quality: Validated",
@@ -189,7 +190,8 @@ var validation_points = {
189
190
  },
190
191
  "5.0": {
191
192
  quality: "• Image quality: Validated",
192
- readability: "• Information readability: Confirmed"
193
+ readability: "• Information readability: Confirmed",
194
+ document: "• Document: A security element on the card could not be verified due to its quality, please submit another file."
193
195
  },
194
196
  "6.0": {
195
197
  quality: "• Image quality: Validated",
@@ -198,7 +200,10 @@ var validation_points = {
198
200
  "7.0": {
199
201
  quality: "• Image quality: Validated",
200
202
  readability: "• Information readability: Confirmed",
201
- document: "• Document: Information on document and entered data do not match"
203
+ document: "• Document: Information on document and entered data do not match",
204
+ mismatch_first_name: "• Document: The entered first name: \"{{entered}}\" does not match the one read on the document: \"{{read}}\"",
205
+ mismatch_last_name: "• Document: The entered last name: \"{{entered}}\" does not match the one read on the document: \"{{read}}\"",
206
+ mismatch_birth_date: "• Document: The entered date of birth: \"{{entered}}\" does not match the one read on the document: \"{{read}}\""
202
207
  },
203
208
  "7.1": {
204
209
  quality: "• Image quality: Validated",
@@ -1088,6 +1093,7 @@ var inpi_verification = {
1088
1093
  var signed_document = {
1089
1094
  loading: "Preparing the signed document...",
1090
1095
  submitted_on: "Submitted on",
1096
+ title: "Your document has been signed",
1091
1097
  ready_text: "Thank you for signing the document, you can view it by clicking below:",
1092
1098
  view_link: "View the document ↗",
1093
1099
  download_hint: "If you wish to keep this document, you can download it from this page.",
@@ -1 +1 @@
1
- {"version":3,"file":"en.json.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"en.json.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -177,7 +177,8 @@ var validation_points = {
177
177
  },
178
178
  "4.0": {
179
179
  quality: "• Qualité des images : Validée",
180
- readability: "• Lisibilité des informations : Confirmée"
180
+ readability: "• Lisibilité des informations : Confirmée",
181
+ document: "• Document : Un élément de sécurité de la carte n'a pas pu être vérifié en raison de sa qualité, veuillez soumettre un autre fichier."
181
182
  },
182
183
  "4.1": {
183
184
  quality: "• Qualité des images : Validée",
@@ -189,7 +190,8 @@ var validation_points = {
189
190
  },
190
191
  "5.0": {
191
192
  quality: "• Qualité des images : Validée",
192
- readability: "• Lisibilité des informations : Confirmée"
193
+ readability: "• Lisibilité des informations : Confirmée",
194
+ document: "• Document : Un élément de sécurité de la carte n'a pas pu être vérifié en raison de sa qualité, veuillez soumettre un autre fichier."
193
195
  },
194
196
  "6.0": {
195
197
  quality: "• Qualité des images : Validée",
@@ -198,7 +200,10 @@ var validation_points = {
198
200
  "7.0": {
199
201
  quality: "• Qualité des images : Validée",
200
202
  readability: "• Lisibilité des informations : Confirmée",
201
- document: "• Document : Les informations sur le document et celles saisies ne correspondent pas"
203
+ document: "• Document : Les informations sur le document et celles saisies ne correspondent pas",
204
+ mismatch_first_name: "• Document : Le prénom saisi : \"{{entered}}\" ne correspond pas à celui lu sur la pièce : \"{{read}}\"",
205
+ mismatch_last_name: "• Document : Le nom saisi : \"{{entered}}\" ne correspond pas à celui lu sur la pièce : \"{{read}}\"",
206
+ mismatch_birth_date: "• Document : La date de naissance saisie : \"{{entered}}\" ne correspond pas à celle lue sur la pièce : \"{{read}}\""
202
207
  },
203
208
  "7.1": {
204
209
  quality: "• Qualité des images : Validée",
@@ -1088,6 +1093,7 @@ var inpi_verification = {
1088
1093
  var signed_document = {
1089
1094
  loading: "Préparation du document signé...",
1090
1095
  submitted_on: "Soumis le",
1096
+ title: "Votre document est signé",
1091
1097
  ready_text: "Merci d'avoir signé le document, vous pouvez le consulter en cliquant ci-dessous :",
1092
1098
  view_link: "Consulter le document ↗",
1093
1099
  download_hint: "Si vous souhaitez conserver ce document, vous pouvez le télécharger depuis cette page.",
@@ -1 +1 @@
1
- {"version":3,"file":"fr.json.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"fr.json.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}