datakeen-session-react 1.1.140-dev.76 → 1.1.140-dev.78

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 (61) hide show
  1. package/dist/cjs/components/document-collection/DocumentCollection.js +1 -1
  2. package/dist/cjs/components/document-collection/DocumentCollection.js.map +1 -1
  3. package/dist/cjs/components/document-collection/DocumentCollectionUpload.js +9 -1
  4. package/dist/cjs/components/document-collection/DocumentCollectionUpload.js.map +1 -1
  5. package/dist/cjs/components/jdi/JDIDocumentUpload.js +1 -1
  6. package/dist/cjs/components/jdi/JDIDocumentUpload.js.map +1 -1
  7. package/dist/cjs/components/nfc-scan/NfcScanNode.js +89 -0
  8. package/dist/cjs/components/nfc-scan/NfcScanNode.js.map +1 -0
  9. package/dist/cjs/components/nfc-scan/NfcSuccessAnimation.js +40 -0
  10. package/dist/cjs/components/nfc-scan/NfcSuccessAnimation.js.map +1 -0
  11. package/dist/cjs/components/session/DocumentCheck.js +100 -35
  12. package/dist/cjs/components/session/DocumentCheck.js.map +1 -1
  13. package/dist/cjs/components/template/TemplateNodeRenderer.js +1 -1
  14. package/dist/cjs/components/template/TemplateNodeRenderer.js.map +1 -1
  15. package/dist/cjs/hooks/useNfcSseStatus.js +46 -0
  16. package/dist/cjs/hooks/useNfcSseStatus.js.map +1 -0
  17. package/dist/cjs/hooks/useUserInputForm.js +6 -1
  18. package/dist/cjs/hooks/useUserInputForm.js.map +1 -1
  19. package/dist/cjs/i18n/en.json.js +10 -1
  20. package/dist/cjs/i18n/en.json.js.map +1 -1
  21. package/dist/cjs/i18n/fr.json.js +10 -1
  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/analysis.js +1 -5
  25. package/dist/cjs/services/analysis.js.map +1 -1
  26. package/dist/cjs/services/api.js +1 -0
  27. package/dist/cjs/services/api.js.map +1 -1
  28. package/dist/cjs/services/auditTrailService.js +73 -0
  29. package/dist/cjs/services/auditTrailService.js.map +1 -1
  30. package/dist/cjs/types/session.js.map +1 -1
  31. package/dist/esm/components/document-collection/DocumentCollection.js +1 -1
  32. package/dist/esm/components/document-collection/DocumentCollection.js.map +1 -1
  33. package/dist/esm/components/document-collection/DocumentCollectionUpload.js +9 -1
  34. package/dist/esm/components/document-collection/DocumentCollectionUpload.js.map +1 -1
  35. package/dist/esm/components/jdi/JDIDocumentUpload.js +1 -1
  36. package/dist/esm/components/jdi/JDIDocumentUpload.js.map +1 -1
  37. package/dist/esm/components/nfc-scan/NfcScanNode.js +85 -0
  38. package/dist/esm/components/nfc-scan/NfcScanNode.js.map +1 -0
  39. package/dist/esm/components/nfc-scan/NfcSuccessAnimation.js +36 -0
  40. package/dist/esm/components/nfc-scan/NfcSuccessAnimation.js.map +1 -0
  41. package/dist/esm/components/session/DocumentCheck.js +100 -35
  42. package/dist/esm/components/session/DocumentCheck.js.map +1 -1
  43. package/dist/esm/components/template/TemplateNodeRenderer.js +1 -1
  44. package/dist/esm/components/template/TemplateNodeRenderer.js.map +1 -1
  45. package/dist/esm/hooks/useNfcSseStatus.js +44 -0
  46. package/dist/esm/hooks/useNfcSseStatus.js.map +1 -0
  47. package/dist/esm/hooks/useUserInputForm.js +6 -1
  48. package/dist/esm/hooks/useUserInputForm.js.map +1 -1
  49. package/dist/esm/i18n/en.json.js +10 -2
  50. package/dist/esm/i18n/en.json.js.map +1 -1
  51. package/dist/esm/i18n/fr.json.js +10 -2
  52. package/dist/esm/i18n/fr.json.js.map +1 -1
  53. package/dist/esm/index.css.js +1 -1
  54. package/dist/esm/services/analysis.js +1 -5
  55. package/dist/esm/services/analysis.js.map +1 -1
  56. package/dist/esm/services/api.js +1 -1
  57. package/dist/esm/services/api.js.map +1 -1
  58. package/dist/esm/services/auditTrailService.js +67 -1
  59. package/dist/esm/services/auditTrailService.js.map +1 -1
  60. package/dist/esm/types/session.js.map +1 -1
  61. package/package.json +1 -1
@@ -0,0 +1,89 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var tslib_es6 = require('../../node_modules/tslib/tslib.es6.js');
6
+ var jsxRuntime = require('react/jsx-runtime');
7
+ var React = require('react');
8
+ var QRCode = require('qrcode');
9
+ var useI18n = require('../../hooks/useI18n.js');
10
+ var useNfcSseStatus = require('../../hooks/useNfcSseStatus.js');
11
+ var api = require('../../services/api.js');
12
+ var MobilePageLayout = require('../ui/MobilePageLayout.js');
13
+ var Title = require('../ui/Title.js');
14
+ var Subtitle = require('../ui/Subtitle.js');
15
+ var NfcSuccessAnimation = require('./NfcSuccessAnimation.js');
16
+
17
+ var NfcScanStep = function (_a) {
18
+ var sessionId = _a.sessionId, nodeId = _a.nodeId, stepObject = _a.stepObject, template = _a.template, pageTitle = _a.pageTitle, pageDescription = _a.pageDescription;
19
+ var t = useI18n.useI18n().t;
20
+ var canvasRef = React.useRef(null);
21
+ var _b = React.useState(null), qrError = _b[0], setQrError = _b[1];
22
+ var nfcUrl = React.useMemo(function () {
23
+ var origin = typeof window !== "undefined" ? window.location.origin : "";
24
+ return "".concat(origin, "/scan/").concat(sessionId);
25
+ }, [sessionId]);
26
+ var apiBaseUrl = React.useMemo(function () { return api.getBaseURL(); }, []);
27
+ var status = useNfcSseStatus.useNfcSseStatus({
28
+ sessionId: sessionId,
29
+ apiBaseUrl: apiBaseUrl,
30
+ onCompleted: function () {
31
+ if (template) {
32
+ stepObject.goToNextStep(nodeId, template);
33
+ }
34
+ else {
35
+ stepObject.setStep(stepObject.step + 1);
36
+ }
37
+ },
38
+ }).status;
39
+ var title = pageTitle || t("nfc_scan.page_title", "Scan NFC de votre document");
40
+ var subtitle = pageDescription ||
41
+ t("nfc_scan.page_description", "Scannez le QR code ci-dessous avec votre iPhone pour lire la puce NFC de votre document d'identité.");
42
+ React.useEffect(function () {
43
+ if (status !== "pending")
44
+ return;
45
+ var generate = function () { return tslib_es6.__awaiter(void 0, void 0, void 0, function () {
46
+ var dataUrl, canvas_1, ctx_1, img_1;
47
+ return tslib_es6.__generator(this, function (_b) {
48
+ switch (_b.label) {
49
+ case 0:
50
+ if (!canvasRef.current)
51
+ return [2 /*return*/];
52
+ setQrError(null);
53
+ _b.label = 1;
54
+ case 1:
55
+ _b.trys.push([1, 3, , 4]);
56
+ return [4 /*yield*/, QRCode.toDataURL(nfcUrl, {
57
+ width: 256,
58
+ margin: 2,
59
+ color: { dark: "#000000", light: "#FFFFFF" },
60
+ })];
61
+ case 2:
62
+ dataUrl = _b.sent();
63
+ canvas_1 = canvasRef.current;
64
+ ctx_1 = canvas_1.getContext("2d");
65
+ if (ctx_1) {
66
+ img_1 = new Image();
67
+ img_1.onload = function () {
68
+ canvas_1.width = img_1.width;
69
+ canvas_1.height = img_1.height;
70
+ ctx_1.drawImage(img_1, 0, 0);
71
+ };
72
+ img_1.src = dataUrl;
73
+ }
74
+ return [3 /*break*/, 4];
75
+ case 3:
76
+ _b.sent();
77
+ setQrError(t("qr_code.generation_failed", "Erreur de génération du QR code"));
78
+ return [3 /*break*/, 4];
79
+ case 4: return [2 /*return*/];
80
+ }
81
+ });
82
+ }); };
83
+ generate();
84
+ }, [nfcUrl, status, t]);
85
+ return (jsxRuntime.jsx(MobilePageLayout.default, { footer: null, children: jsxRuntime.jsx("div", { className: "px-4 py-6 pt-11 md:px-8 md:py-8", children: jsxRuntime.jsxs("div", { className: "w-full max-w-md mx-auto space-y-6", children: [jsxRuntime.jsxs("div", { className: "text-center space-y-4 mt-16 md:mt-20", children: [jsxRuntime.jsx(Title.default, { className: "text-xl md:text-2xl lg:text-3xl", children: title }), jsxRuntime.jsx(Subtitle.default, { className: "text-sm md:text-base text-gray-600 leading-relaxed whitespace-pre-line", children: subtitle })] }), jsxRuntime.jsx("div", { className: "flex-1 flex justify-center items-center", children: status === "success" ? (jsxRuntime.jsx(NfcSuccessAnimation.default, {})) : status === "completed" ? (jsxRuntime.jsxs("div", { className: "flex flex-col items-center gap-4 p-8", children: [jsxRuntime.jsx("div", { className: "animate-spin w-10 h-10 border-2 border-gray-300 border-t-blue-500 rounded-full" }), jsxRuntime.jsx("p", { className: "text-sm text-gray-600", children: t("nfc_scan.verifying", "Vérification en cours…") })] })) : status === "opened" ? (jsxRuntime.jsxs("div", { className: "w-full max-w-sm rounded-2xl border border-emerald-200 bg-emerald-50 p-6 text-center shadow-sm", children: [jsxRuntime.jsx("div", { className: "mx-auto mb-4 flex h-14 w-14 items-center justify-center rounded-full bg-emerald-500 text-white shadow-md shadow-emerald-200", children: jsxRuntime.jsx("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", className: "h-7 w-7", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: jsxRuntime.jsx("path", { d: "M20 6 9 17l-5-5" }) }) }), jsxRuntime.jsx("p", { className: "text-base font-semibold text-gray-900", children: t("nfc_scan.qr_opened_title", "QR code scanné") }), jsxRuntime.jsx("p", { className: "mt-2 text-sm leading-relaxed text-gray-600", children: t("nfc_scan.qr_opened_description", "L'expérience NFC est ouverte sur l'iPhone. Continuez le scan sur le téléphone.") }), jsxRuntime.jsxs("div", { className: "mt-5 flex items-center justify-center gap-2 text-xs font-medium text-emerald-700", children: [jsxRuntime.jsx("span", { className: "h-2 w-2 animate-pulse rounded-full bg-emerald-500" }), t("nfc_scan.waiting_completion", "En attente de la lecture NFC")] })] })) : qrError ? (jsxRuntime.jsx("div", { className: "text-red-500 text-center p-4", children: qrError })) : (jsxRuntime.jsx("div", { className: "bg-white p-4 rounded-lg shadow-lg border-2 border-gray-200", children: jsxRuntime.jsx("canvas", { ref: canvasRef }) })) })] }) }) }));
86
+ };
87
+
88
+ exports.default = NfcScanStep;
89
+ //# sourceMappingURL=NfcScanNode.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NfcScanNode.js","sources":["../../../../../src/components/nfc-scan/NfcScanNode.tsx"],"sourcesContent":["import React, { useEffect, useMemo, useRef, useState } from \"react\";\nimport QRCode from \"qrcode\";\nimport type { SessionTemplate, stepObject } from \"../../types/session\";\nimport { useI18n } from \"../../hooks/useI18n\";\nimport { useNfcSseStatus } from \"../../hooks/useNfcSseStatus\";\nimport { getBaseURL } from \"../../services/api\";\nimport MobilePageLayout from \"../ui/MobilePageLayout\";\nimport Title from \"../ui/Title\";\nimport Subtitle from \"../ui/Subtitle\";\nimport NfcSuccessAnimation from \"./NfcSuccessAnimation\";\n\ninterface NfcScanStepProps {\n sessionId: string;\n nodeId: string;\n stepObject: stepObject;\n template?: SessionTemplate;\n pageTitle?: string;\n pageDescription?: string;\n}\n\nconst NfcScanStep: React.FC<NfcScanStepProps> = ({\n sessionId,\n nodeId,\n stepObject,\n template,\n pageTitle,\n pageDescription,\n}) => {\n const { t } = useI18n();\n const canvasRef = useRef<HTMLCanvasElement>(null);\n const [qrError, setQrError] = useState<string | null>(null);\n\n const nfcUrl = useMemo(() => {\n const origin = typeof window !== \"undefined\" ? window.location.origin : \"\";\n return `${origin}/scan/${sessionId}`;\n }, [sessionId]);\n\n const apiBaseUrl = useMemo(() => getBaseURL(), []);\n\n const { status } = useNfcSseStatus({\n sessionId,\n apiBaseUrl,\n onCompleted: () => {\n if (template) {\n stepObject.goToNextStep(nodeId, template);\n } else {\n stepObject.setStep(stepObject.step + 1);\n }\n },\n });\n\n const title =\n pageTitle || t(\"nfc_scan.page_title\", \"Scan NFC de votre document\");\n const subtitle =\n pageDescription ||\n t(\n \"nfc_scan.page_description\",\n \"Scannez le QR code ci-dessous avec votre iPhone pour lire la puce NFC de votre document d'identité.\"\n );\n\n useEffect(() => {\n if (status !== \"pending\") return;\n\n const generate = async () => {\n if (!canvasRef.current) return;\n setQrError(null);\n\n try {\n const dataUrl = await QRCode.toDataURL(nfcUrl, {\n width: 256,\n margin: 2,\n color: { dark: \"#000000\", light: \"#FFFFFF\" },\n });\n const canvas = canvasRef.current;\n const ctx = canvas.getContext(\"2d\");\n if (ctx) {\n const img = new Image();\n img.onload = () => {\n canvas.width = img.width;\n canvas.height = img.height;\n ctx.drawImage(img, 0, 0);\n };\n img.src = dataUrl;\n }\n } catch {\n setQrError(t(\"qr_code.generation_failed\", \"Erreur de génération du QR code\"));\n }\n };\n\n generate();\n }, [nfcUrl, status, t]);\n\n return (\n <MobilePageLayout footer={null}>\n <div className=\"px-4 py-6 pt-11 md:px-8 md:py-8\">\n <div className=\"w-full max-w-md mx-auto space-y-6\">\n <div className=\"text-center space-y-4 mt-16 md:mt-20\">\n <Title className=\"text-xl md:text-2xl lg:text-3xl\">{title}</Title>\n <Subtitle className=\"text-sm md:text-base text-gray-600 leading-relaxed whitespace-pre-line\">\n {subtitle}\n </Subtitle>\n </div>\n\n <div className=\"flex-1 flex justify-center items-center\">\n {status === \"success\" ? (\n <NfcSuccessAnimation />\n ) : status === \"completed\" ? (\n <div className=\"flex flex-col items-center gap-4 p-8\">\n <div className=\"animate-spin w-10 h-10 border-2 border-gray-300 border-t-blue-500 rounded-full\" />\n <p className=\"text-sm text-gray-600\">\n {t(\"nfc_scan.verifying\", \"Vérification en cours…\")}\n </p>\n </div>\n ) : status === \"opened\" ? (\n <div className=\"w-full max-w-sm rounded-2xl border border-emerald-200 bg-emerald-50 p-6 text-center shadow-sm\">\n <div className=\"mx-auto mb-4 flex h-14 w-14 items-center justify-center rounded-full bg-emerald-500 text-white shadow-md shadow-emerald-200\">\n <svg\n aria-hidden=\"true\"\n viewBox=\"0 0 24 24\"\n className=\"h-7 w-7\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M20 6 9 17l-5-5\" />\n </svg>\n </div>\n <p className=\"text-base font-semibold text-gray-900\">\n {t(\"nfc_scan.qr_opened_title\", \"QR code scanné\")}\n </p>\n <p className=\"mt-2 text-sm leading-relaxed text-gray-600\">\n {t(\n \"nfc_scan.qr_opened_description\",\n \"L'expérience NFC est ouverte sur l'iPhone. Continuez le scan sur le téléphone.\"\n )}\n </p>\n <div className=\"mt-5 flex items-center justify-center gap-2 text-xs font-medium text-emerald-700\">\n <span className=\"h-2 w-2 animate-pulse rounded-full bg-emerald-500\" />\n {t(\"nfc_scan.waiting_completion\", \"En attente de la lecture NFC\")}\n </div>\n </div>\n ) : qrError ? (\n <div className=\"text-red-500 text-center p-4\">{qrError}</div>\n ) : (\n <div className=\"bg-white p-4 rounded-lg shadow-lg border-2 border-gray-200\">\n <canvas ref={canvasRef} />\n </div>\n )}\n </div>\n </div>\n </div>\n </MobilePageLayout>\n );\n};\n\nexport default NfcScanStep;\n"],"names":["useI18n","useRef","useState","useMemo","getBaseURL","useNfcSseStatus","useEffect","__awaiter","_jsx","MobilePageLayout","_jsxs","Title","Subtitle","NfcSuccessAnimation"],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var jsxRuntime = require('react/jsx-runtime');
6
+ var React = require('react');
7
+ var useI18n = require('../../hooks/useI18n.js');
8
+
9
+ var NfcSuccessAnimation = function () {
10
+ var t = useI18n.useI18n().t;
11
+ var _a = React.useState(false), visible = _a[0], setVisible = _a[1];
12
+ React.useEffect(function () {
13
+ // Déclenche l'animation au prochain frame pour permettre la transition CSS
14
+ var id = requestAnimationFrame(function () { return setVisible(true); });
15
+ return function () { return cancelAnimationFrame(id); };
16
+ }, []);
17
+ return (jsxRuntime.jsxs("div", { className: "flex flex-col items-center gap-6 p-8", style: {
18
+ opacity: visible ? 1 : 0,
19
+ transform: visible ? "scale(1)" : "scale(0.85)",
20
+ transition: "opacity 0.4s ease, transform 0.4s ease",
21
+ }, children: [jsxRuntime.jsxs("div", { style: { position: "relative", width: 72, height: 72, flexShrink: 0 }, children: [jsxRuntime.jsx("div", { style: {
22
+ position: "absolute",
23
+ inset: 0,
24
+ borderRadius: "50%",
25
+ backgroundColor: "var(--uni-primary-color, #11e5c5)",
26
+ transformOrigin: "center center",
27
+ animation: "nfc-pulse 1.6s ease-out infinite",
28
+ pointerEvents: "none",
29
+ } }), jsxRuntime.jsxs("svg", { width: 72, height: 72, viewBox: "0 0 72 72", fill: "none", xmlns: "http://www.w3.org/2000/svg", "aria-hidden": "true", children: [jsxRuntime.jsx("circle", { cx: 36, cy: 36, r: 34, fill: "var(--uni-primary-color, #11e5c5)", style: {
30
+ opacity: visible ? 1 : 0,
31
+ transition: "opacity 0.3s ease 0.1s",
32
+ } }), jsxRuntime.jsx("polyline", { points: "20,37 30,47 52,25", stroke: "#ffffff", strokeWidth: 5, strokeLinecap: "round", strokeLinejoin: "round", fill: "none", style: {
33
+ strokeDasharray: 50,
34
+ strokeDashoffset: visible ? 0 : 50,
35
+ transition: "stroke-dashoffset 0.45s cubic-bezier(0.4, 0, 0.2, 1) 0.35s",
36
+ } })] })] }), jsxRuntime.jsxs("div", { className: "text-center space-y-1", children: [jsxRuntime.jsx("p", { className: "font-semibold text-base", style: { color: "var(--uni-secondary-color, #0a9983)" }, children: t("nfc_scan.success_title", "Documents validés") }), jsxRuntime.jsx("p", { className: "text-sm text-gray-500", children: t("nfc_scan.success_subtitle", "Lecture NFC confirmée avec succès") })] }), jsxRuntime.jsx("style", { children: "\n @keyframes nfc-pulse {\n 0% { transform: scale(1); opacity: 0.25; }\n 70% { transform: scale(1.65); opacity: 0.05; }\n 100% { transform: scale(1.65); opacity: 0; }\n }\n " })] }));
37
+ };
38
+
39
+ exports.default = NfcSuccessAnimation;
40
+ //# sourceMappingURL=NfcSuccessAnimation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NfcSuccessAnimation.js","sources":["../../../../../src/components/nfc-scan/NfcSuccessAnimation.tsx"],"sourcesContent":["import React, { useEffect, useState } from \"react\";\nimport { useI18n } from \"../../hooks/useI18n\";\n\nconst NfcSuccessAnimation: React.FC = () => {\n const { t } = useI18n();\n const [visible, setVisible] = useState(false);\n\n useEffect(() => {\n // Déclenche l'animation au prochain frame pour permettre la transition CSS\n const id = requestAnimationFrame(() => setVisible(true));\n return () => cancelAnimationFrame(id);\n }, []);\n\n return (\n <div\n className=\"flex flex-col items-center gap-6 p-8\"\n style={{\n opacity: visible ? 1 : 0,\n transform: visible ? \"scale(1)\" : \"scale(0.85)\",\n transition: \"opacity 0.4s ease, transform 0.4s ease\",\n }}\n >\n <div style={{ position: \"relative\", width: 72, height: 72, flexShrink: 0 }}>\n {/* Halo pulsant en arrière-plan */}\n <div\n style={{\n position: \"absolute\",\n inset: 0,\n borderRadius: \"50%\",\n backgroundColor: \"var(--uni-primary-color, #11e5c5)\",\n transformOrigin: \"center center\",\n animation: \"nfc-pulse 1.6s ease-out infinite\",\n pointerEvents: \"none\",\n }}\n />\n\n {/* Cercle + check SVG animé */}\n <svg\n width={72}\n height={72}\n viewBox=\"0 0 72 72\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n >\n {/* Cercle de fond rempli */}\n <circle\n cx={36}\n cy={36}\n r={34}\n fill=\"var(--uni-primary-color, #11e5c5)\"\n style={{\n opacity: visible ? 1 : 0,\n transition: \"opacity 0.3s ease 0.1s\",\n }}\n />\n {/* Trait du check — strokeDashoffset animé */}\n <polyline\n points=\"20,37 30,47 52,25\"\n stroke=\"#ffffff\"\n strokeWidth={5}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n fill=\"none\"\n style={{\n strokeDasharray: 50,\n strokeDashoffset: visible ? 0 : 50,\n transition: \"stroke-dashoffset 0.45s cubic-bezier(0.4, 0, 0.2, 1) 0.35s\",\n }}\n />\n </svg>\n </div>\n\n <div className=\"text-center space-y-1\">\n <p\n className=\"font-semibold text-base\"\n style={{ color: \"var(--uni-secondary-color, #0a9983)\" }}\n >\n {t(\"nfc_scan.success_title\", \"Documents validés\")}\n </p>\n <p className=\"text-sm text-gray-500\">\n {t(\"nfc_scan.success_subtitle\", \"Lecture NFC confirmée avec succès\")}\n </p>\n </div>\n\n <style>{`\n @keyframes nfc-pulse {\n 0% { transform: scale(1); opacity: 0.25; }\n 70% { transform: scale(1.65); opacity: 0.05; }\n 100% { transform: scale(1.65); opacity: 0; }\n }\n `}</style>\n </div>\n );\n};\n\nexport default NfcSuccessAnimation;\n"],"names":["useI18n","useState","useEffect","_jsxs","_jsx"],"mappings":"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"}
@@ -20,6 +20,7 @@ var DocumentVideoCapture = require('../document-video/DocumentVideoCapture.js');
20
20
  var lucideReact = require('lucide-react');
21
21
  var DocumentContext = require('../../context/DocumentContext.js');
22
22
  var useI18n = require('../../hooks/useI18n.js');
23
+ var auditTrailService = require('../../services/auditTrailService.js');
23
24
  var ButtonDesktop = require('../ui/ButtonDesktop.js');
24
25
  var Title = require('../ui/Title.js');
25
26
  var Subtitle = require('../ui/Subtitle.js');
@@ -29,8 +30,15 @@ var documentTemplate = require('../../services/documentTemplate.js');
29
30
  var imageProcessing = require('../../utils/imageProcessing.js');
30
31
  var retryService = require('../../services/retryService.js');
31
32
  var SessionContext = require('../../context/SessionContext.js');
33
+ var sessionService = require('../../services/sessionService.js');
34
+ var NfcScanNode = require('../nfc-scan/NfcScanNode.js');
32
35
  var europeanCountries = require('../../utils/europeanCountries.js');
33
36
 
37
+ var NFC_ELIGIBLE_DOCUMENT_TYPES = new Set([
38
+ "passport",
39
+ "idCard",
40
+ "residencePermit",
41
+ ]);
34
42
  /**
35
43
  * DocumentCheck component manages the multi-step document verification flow for a session.
36
44
  * It handles country and document type selection, document upload or photo capture, processing, and error/success handling.
@@ -109,10 +117,11 @@ var DocumentCheck = function (_a) {
109
117
  var _t = React.useState(null), fileUploaded = _t[0], setFileUploaded = _t[1];
110
118
  var _u = React.useState(null), analysisData = _u[0], setAnalysisData = _u[1];
111
119
  var _v = React.useState(null), errorCode = _v[0], setErrorCode = _v[1];
120
+ var _w = React.useState(null), nfcPreparationError = _w[0], setNfcPreparationError = _w[1];
112
121
  // Initialize retry count from session data
113
- var _w = React.useState(function () {
122
+ var _x = React.useState(function () {
114
123
  return retryService.getNodeRetryCount(session, node.id);
115
- }), retryCount = _w[0], setRetryCount = _w[1];
124
+ }), retryCount = _x[0], setRetryCount = _x[1];
116
125
  // Update retry count when session loads/changes
117
126
  React.useEffect(function () {
118
127
  if (session) {
@@ -152,10 +161,10 @@ var DocumentCheck = function (_a) {
152
161
  setDocStep(6);
153
162
  }
154
163
  }, [retryCount, node.allowResubmission, node.maxResubmissionAttempts]);
155
- var _x = React.useState({}), capturedImages = _x[0], setCapturedImages = _x[1];
156
- var _y = React.useState("before-recto"), currentPhotoStep = _y[0], setCurrentPhotoStep = _y[1];
157
- var _z = React.useState("photo"), videoFlowPhase = _z[0], setVideoFlowPhase = _z[1];
158
- var _0 = DocumentContext.useDocumentContext(), selectedDocumentType = _0.selectedDocumentType, setSelectedDocumentType = _0.setSelectedDocumentType;
164
+ var _y = React.useState({}), capturedImages = _y[0], setCapturedImages = _y[1];
165
+ var _z = React.useState("before-recto"), currentPhotoStep = _z[0], setCurrentPhotoStep = _z[1];
166
+ var _0 = React.useState("photo"), videoFlowPhase = _0[0], setVideoFlowPhase = _0[1];
167
+ var _1 = DocumentContext.useDocumentContext(), selectedDocumentType = _1.selectedDocumentType, setSelectedDocumentType = _1.setSelectedDocumentType;
159
168
  var finalAcceptedCountries = React.useMemo(function () {
160
169
  if (loadingTemplates)
161
170
  return acceptedCountries;
@@ -251,6 +260,7 @@ var DocumentCheck = function (_a) {
251
260
  setFileUploaded(null);
252
261
  setAnalysisData(null);
253
262
  setErrorCode(null);
263
+ setNfcPreparationError(null);
254
264
  // Reset retry count to 0 (will be synced to session)
255
265
  setRetryCount(0);
256
266
  setCapturedImages({});
@@ -281,6 +291,7 @@ var DocumentCheck = function (_a) {
281
291
  var _a;
282
292
  return (tslib_es6.__assign(tslib_es6.__assign({}, prev), (_a = {}, _a[side] = processedDataUrl_1, _a)));
283
293
  });
294
+ auditTrailService.logPhotoCaptured(sessionId, side);
284
295
  if (side === "recto") {
285
296
  isSingleSided = (selectedDocumentType === null || selectedDocumentType === void 0 ? void 0 : selectedDocumentType.id) === "passport" ||
286
297
  (selectedDocumentType === null || selectedDocumentType === void 0 ? void 0 : selectedDocumentType.id) === "pinkDriverLicense";
@@ -298,6 +309,7 @@ var DocumentCheck = function (_a) {
298
309
  var _a;
299
310
  return (tslib_es6.__assign(tslib_es6.__assign({}, prev), (_a = {}, _a[side] = imageData, _a)));
300
311
  });
312
+ auditTrailService.logPhotoCaptured(sessionId, side);
301
313
  if (side === "recto") {
302
314
  isSingleSided = (selectedDocumentType === null || selectedDocumentType === void 0 ? void 0 : selectedDocumentType.id) === "passport" ||
303
315
  (selectedDocumentType === null || selectedDocumentType === void 0 ? void 0 : selectedDocumentType.id) === "pinkDriverLicense";
@@ -313,6 +325,7 @@ var DocumentCheck = function (_a) {
313
325
  }); };
314
326
  var handlePhotoConfirmation = function () {
315
327
  if (capturedImages.recto) {
328
+ auditTrailService.logPhotosValidated(sessionId);
316
329
  setFileUploaded({
317
330
  front: capturedImages.recto,
318
331
  back: capturedImages.verso || null,
@@ -333,34 +346,72 @@ var DocumentCheck = function (_a) {
333
346
  }
334
347
  handleProcessingComplete(success, undefined, analysisData);
335
348
  };
336
- var handleDocumentTypeSelect = function (documentId) {
337
- var documentTemplateID = loadingTemplates
338
- ? undefined
339
- : documentTemplate.getDocumentTemplateId({
340
- acceptedCountries: finalAcceptedCountries,
341
- countryCode: selectedCountry,
342
- documentId: documentId,
343
- documentTemplates: documentTemplates,
344
- });
345
- // Find the selected document details
346
- var selectedDoc = {
347
- id: documentId,
348
- label: t("documentTypes.".concat(documentId)),
349
- hasTwoSides: documentId !== "passport" && documentId !== "pinkDriverLicense",
350
- documentTemplateId: documentTemplateID,
351
- };
352
- setSelectedDocumentType(selectedDoc);
353
- setFileUploaded(null);
354
- setAnalysisData(null);
355
- setErrorCode(null);
356
- // Don't reset retry count when selecting document type
357
- // Keep existing retry count for this node
358
- setCapturedImages({});
359
- setCurrentPhotoStep("before-recto");
360
- setVideoFlowPhase("photo");
361
- setDocStep(3);
362
- };
349
+ var handleDocumentTypeSelect = function (documentId) { return tslib_es6.__awaiter(void 0, void 0, void 0, function () {
350
+ var documentLabel, documentTemplateID, selectedDoc, selectedCountryCode, selectedDocumentInput, nfcMode, error_2;
351
+ var _a;
352
+ return tslib_es6.__generator(this, function (_b) {
353
+ switch (_b.label) {
354
+ case 0:
355
+ documentLabel = t("documentTypes.".concat(documentId), documentId);
356
+ auditTrailService.logDocumentTypeSelected(sessionId, documentId, documentLabel);
357
+ documentTemplateID = loadingTemplates
358
+ ? undefined
359
+ : documentTemplate.getDocumentTemplateId({
360
+ acceptedCountries: finalAcceptedCountries,
361
+ countryCode: selectedCountry,
362
+ documentId: documentId,
363
+ documentTemplates: documentTemplates,
364
+ });
365
+ selectedDoc = {
366
+ id: documentId,
367
+ label: t("documentTypes.".concat(documentId)),
368
+ hasTwoSides: documentId !== "passport" && documentId !== "pinkDriverLicense",
369
+ documentTemplateId: documentTemplateID,
370
+ };
371
+ selectedCountryCode = selectedCountry.toUpperCase();
372
+ selectedDocumentInput = {
373
+ countryCode: selectedCountryCode,
374
+ identityDocumentType: documentId,
375
+ identityDocumentTemplateId: documentTemplateID,
376
+ };
377
+ setSelectedDocumentType(selectedDoc);
378
+ setUserInput(function (prev) { return (tslib_es6.__assign(tslib_es6.__assign({}, prev), selectedDocumentInput)); });
379
+ setFileUploaded(null);
380
+ setAnalysisData(null);
381
+ setErrorCode(null);
382
+ setNfcPreparationError(null);
383
+ setCapturedImages({});
384
+ setCurrentPhotoStep("before-recto");
385
+ setVideoFlowPhase("photo");
386
+ if (!(node.nfcEnabled === true && NFC_ELIGIBLE_DOCUMENT_TYPES.has(documentId))) return [3 /*break*/, 5];
387
+ nfcMode = (_a = node.nfcMode) !== null && _a !== void 0 ? _a : "nfcOnly";
388
+ _b.label = 1;
389
+ case 1:
390
+ _b.trys.push([1, 3, , 4]);
391
+ return [4 /*yield*/, sessionService.updateSessionUserInput(sessionId, selectedDocumentInput)];
392
+ case 2:
393
+ _b.sent();
394
+ return [3 /*break*/, 4];
395
+ case 3:
396
+ error_2 = _b.sent();
397
+ console.error("Failed to persist NFC document selection:", error_2);
398
+ setNfcPreparationError(t("nfc_scan.preparation_failed", "Impossible de préparer le scan NFC. Veuillez réessayer."));
399
+ return [3 /*break*/, 4];
400
+ case 4:
401
+ setDocStep(nfcMode === "nfcAndApi" ? 3 : 7);
402
+ return [2 /*return*/];
403
+ case 5:
404
+ setDocStep(3);
405
+ return [2 /*return*/];
406
+ }
407
+ });
408
+ }); };
363
409
  var handleDocumentUpload = function (files) {
410
+ auditTrailService.logDocumentLoaded(sessionId, "recto");
411
+ if (files.back) {
412
+ auditTrailService.logDocumentLoaded(sessionId, "verso");
413
+ }
414
+ auditTrailService.logDocumentsValidated(sessionId);
364
415
  setFileUploaded(files);
365
416
  // Check if retry limit is reached before processing
366
417
  if (!isRetryAllowed() && retryCount > 0) {
@@ -373,6 +424,7 @@ var DocumentCheck = function (_a) {
373
424
  }
374
425
  };
375
426
  var handleProcessingComplete = function (success, _retryCount, apiAnalysisData) {
427
+ var _a;
376
428
  if (apiAnalysisData) {
377
429
  setAnalysisData(apiAnalysisData);
378
430
  // Extract and store the error code
@@ -382,6 +434,14 @@ var DocumentCheck = function (_a) {
382
434
  }
383
435
  }
384
436
  if (success) {
437
+ var shouldRunNfcAfterApi = node.nfcEnabled === true &&
438
+ ((_a = node.nfcMode) !== null && _a !== void 0 ? _a : "nfcOnly") === "nfcAndApi" &&
439
+ !!(selectedDocumentType === null || selectedDocumentType === void 0 ? void 0 : selectedDocumentType.id) &&
440
+ NFC_ELIGIBLE_DOCUMENT_TYPES.has(selectedDocumentType.id);
441
+ if (shouldRunNfcAfterApi) {
442
+ setDocStep(7);
443
+ return;
444
+ }
385
445
  // Increment currentStep in database immediately after successful analysis
386
446
  // This prevents double analysis if the user refreshes the page
387
447
  if (template) {
@@ -495,7 +555,7 @@ var DocumentCheck = function (_a) {
495
555
  return (jsxRuntime.jsxs("div", { className: "flex flex-col items-center justify-center h-full p-4 text-center", children: [jsxRuntime.jsx("div", { className: "text-red-500 text-4xl mb-4", children: "\u26A0\uFE0F" }), jsxRuntime.jsx("h2", { className: "text-xl font-bold text-red-600 mb-2", children: t("document_check.selection_error.title", "Erreur de sélection") }), jsxRuntime.jsx("p", { className: "text-gray-600 mb-4", children: t("document_check.selection_error.description", "Aucun type de document sélectionné. Veuillez revenir à l'étape précédente.") }), jsxRuntime.jsx(ButtonDesktop.default, { className: "px-4 py-2 bg-primary text-white rounded hover:bg-primary-dark transition-colors", type: "back", onClick: function () { return setDocStep(2); }, children: t("document_check.selection_error.back", "Retour à la sélection") })] }));
496
556
  }
497
557
  if (isPictureAllowed && isDownloadAllowed && !selectedMethod) {
498
- return (jsxRuntime.jsx(MobilePageLayout.default, { footer: jsxRuntime.jsx("div", { className: "w-full max-w-md mx-auto", children: jsxRuntime.jsx(ButtonDesktop.default, { type: "back", onClick: handleBack, className: "w-full text-[#3C3C40] text-center font-poppins text-sm font-medium hover:underline py-2", children: t("buttons.back", "Retour") }) }), children: jsxRuntime.jsx("div", { className: "px-4 py-6 pt-11 md:px-8 md:py-8", children: jsxRuntime.jsxs("div", { className: "w-full max-w-md mx-auto space-y-6", children: [jsxRuntime.jsxs("div", { className: "text-center space-y-4", children: [jsxRuntime.jsx(Title.default, { className: "text-xl md:text-2xl lg:text-3xl", children: t("document_check.method_selection.title", "Choisissez une méthode") }), jsxRuntime.jsx(Subtitle.default, { className: "text-sm text-gray-600 leading-relaxed", children: t("document_check.method_selection.subtitle", "Comment souhaitez-vous ajouter votre document ?") })] }), jsxRuntime.jsxs("div", { className: "grid gap-4", children: [jsxRuntime.jsxs("button", { onClick: function () { return setSelectedMethod("picture"); }, className: "flex items-center p-4 bg-white border-2 border-gray-100 rounded-xl hover:border-teal-500 transition-colors text-left group", children: [jsxRuntime.jsx("div", { className: "w-12 h-12 bg-teal-50 rounded-lg flex items-center justify-center text-teal-600 group-hover:bg-teal-100 transition-colors mr-4", children: jsxRuntime.jsx(lucideReact.Camera, { size: 24 }) }), jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("p", { className: "font-semibold text-gray-900", children: t("document_check.method_selection.picture_title", "Prendre une photo") }), jsxRuntime.jsx("p", { className: "text-sm text-gray-500", children: t("document_check.method_selection.picture_desc", "Utilisez l'appareil photo de votre appareil") })] })] }), jsxRuntime.jsxs("button", { onClick: function () { return setSelectedMethod("download"); }, className: "flex items-center p-4 bg-white border-2 border-gray-100 rounded-xl hover:border-teal-500 transition-colors text-left group", children: [jsxRuntime.jsx("div", { className: "w-12 h-12 bg-teal-50 rounded-lg flex items-center justify-center text-teal-600 group-hover:bg-teal-100 transition-colors mr-4", children: jsxRuntime.jsx(lucideReact.Upload, { size: 24 }) }), jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("p", { className: "font-semibold text-gray-900", children: t("document_check.method_selection.download_title", "Téléverser un fichier") }), jsxRuntime.jsx("p", { className: "text-sm text-gray-500", children: t("document_check.method_selection.download_desc", "Sélectionnez un fichier sur votre appareil") })] })] })] })] }) }) }));
558
+ return (jsxRuntime.jsx(MobilePageLayout.default, { footer: jsxRuntime.jsx("div", { className: "w-full max-w-md mx-auto", children: jsxRuntime.jsx(ButtonDesktop.default, { type: "back", onClick: handleBack, className: "w-full text-[#3C3C40] text-center font-poppins text-sm font-medium hover:underline py-2", children: t("buttons.back", "Retour") }) }), children: jsxRuntime.jsx("div", { className: "px-4 py-6 pt-11 md:px-8 md:py-8", children: jsxRuntime.jsxs("div", { className: "w-full max-w-md mx-auto space-y-6", children: [jsxRuntime.jsxs("div", { className: "text-center space-y-4", children: [jsxRuntime.jsx(Title.default, { className: "text-xl md:text-2xl lg:text-3xl", children: t("document_check.method_selection.title", "Choisissez une méthode") }), jsxRuntime.jsx(Subtitle.default, { className: "text-sm text-gray-600 leading-relaxed", children: t("document_check.method_selection.subtitle", "Comment souhaitez-vous ajouter votre document ?") })] }), jsxRuntime.jsxs("div", { className: "grid gap-4", children: [jsxRuntime.jsxs("button", { onClick: function () { setSelectedMethod("picture"); auditTrailService.logCaptureModeSelected(sessionId, "picture"); }, className: "flex items-center p-4 bg-white border-2 border-gray-100 rounded-xl hover:border-teal-500 transition-colors text-left group", children: [jsxRuntime.jsx("div", { className: "w-12 h-12 bg-teal-50 rounded-lg flex items-center justify-center text-teal-600 group-hover:bg-teal-100 transition-colors mr-4", children: jsxRuntime.jsx(lucideReact.Camera, { size: 24 }) }), jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("p", { className: "font-semibold text-gray-900", children: t("document_check.method_selection.picture_title", "Prendre une photo") }), jsxRuntime.jsx("p", { className: "text-sm text-gray-500", children: t("document_check.method_selection.picture_desc", "Utilisez l'appareil photo de votre appareil") })] })] }), jsxRuntime.jsxs("button", { onClick: function () { setSelectedMethod("download"); auditTrailService.logCaptureModeSelected(sessionId, "upload"); }, className: "flex items-center p-4 bg-white border-2 border-gray-100 rounded-xl hover:border-teal-500 transition-colors text-left group", children: [jsxRuntime.jsx("div", { className: "w-12 h-12 bg-teal-50 rounded-lg flex items-center justify-center text-teal-600 group-hover:bg-teal-100 transition-colors mr-4", children: jsxRuntime.jsx(lucideReact.Upload, { size: 24 }) }), jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("p", { className: "font-semibold text-gray-900", children: t("document_check.method_selection.download_title", "Téléverser un fichier") }), jsxRuntime.jsx("p", { className: "text-sm text-gray-500", children: t("document_check.method_selection.download_desc", "Sélectionnez un fichier sur votre appareil") })] })] })] })] }) }) }));
499
559
  }
500
560
  var activeMethod = selectedMethod ||
501
561
  (isPictureAllowed && isMobileCapture ? "picture" : "download");
@@ -539,7 +599,7 @@ var DocumentCheck = function (_a) {
539
599
  else {
540
600
  setDocStep(2);
541
601
  }
542
- }, initialFront: errorCode === "2.5" ? fileUploaded === null || fileUploaded === void 0 ? void 0 : fileUploaded.front : null, initialBack: errorCode === "2.5" ? fileUploaded === null || fileUploaded === void 0 ? void 0 : fileUploaded.back : null }));
602
+ }, initialFront: errorCode === "2.5" ? fileUploaded === null || fileUploaded === void 0 ? void 0 : fileUploaded.front : null, initialBack: errorCode === "2.5" ? fileUploaded === null || fileUploaded === void 0 ? void 0 : fileUploaded.back : null, sessionId: sessionId }));
543
603
  }
544
604
  case 4:
545
605
  return (jsxRuntime.jsx(JDIProcessing.default, { documentType: (selectedDocumentType === null || selectedDocumentType === void 0 ? void 0 : selectedDocumentType.id) || documentTypeId, onProcessingComplete: handleProcessingComplete, fileUploaded: fileUploaded, documentTypeId: documentTypeId, retryCount: retryCount, documentTemplateId: selectedDocumentType === null || selectedDocumentType === void 0 ? void 0 : selectedDocumentType.documentTemplateId, nodeId: node.id }));
@@ -547,6 +607,11 @@ var DocumentCheck = function (_a) {
547
607
  return (jsxRuntime.jsx(JDISuccess.default, { documentType: (selectedDocumentType === null || selectedDocumentType === void 0 ? void 0 : selectedDocumentType.id) || documentTypeId, onContinue: handleSuccessContinue, errorCode: errorCode || undefined }));
548
608
  case 6:
549
609
  return (jsxRuntime.jsx(JDIError.default, { documentType: (selectedDocumentType === null || selectedDocumentType === void 0 ? void 0 : selectedDocumentType.id) || documentTypeId, onRetry: handleRetryFromError, onContinueAnyway: handleContinueAnyway, retryCount: retryCount, predictions: analysisData || undefined, errorCode: errorCode || undefined, allowResubmission: node.allowResubmission, maxResubmissionAttempts: node.maxResubmissionAttempts, isRetryAllowed: isRetryAllowed() }));
610
+ case 7:
611
+ if (nfcPreparationError) {
612
+ return (jsxRuntime.jsx(MobilePageLayout.default, { footer: jsxRuntime.jsx("div", { className: "w-full max-w-md mx-auto", children: jsxRuntime.jsx(ButtonDesktop.default, { type: "back", onClick: function () { return setDocStep(2); }, className: "w-full text-[#3C3C40] text-center font-poppins text-sm font-medium hover:underline py-2", children: t("buttons.back", "Retour") }) }), children: jsxRuntime.jsxs("div", { className: "flex flex-col items-center justify-center h-full p-4 text-center", children: [jsxRuntime.jsx("div", { className: "text-red-500 text-4xl mb-4", children: "\u26A0\uFE0F" }), jsxRuntime.jsx("h2", { className: "text-xl font-bold text-red-600 mb-2", children: t("nfc_scan.preparation_error_title", "Erreur de préparation NFC") }), jsxRuntime.jsx("p", { className: "text-gray-600 mb-4", children: nfcPreparationError })] }) }));
613
+ }
614
+ return (jsxRuntime.jsx(NfcScanNode.default, { sessionId: sessionId, nodeId: node.id, stepObject: stepObject, template: template }));
550
615
  default:
551
616
  console.error("Invalid docStep: ".concat(docStep));
552
617
  return (jsxRuntime.jsxs("div", { className: "flex flex-col items-center justify-center h-full p-4 text-center", children: [jsxRuntime.jsx("div", { className: "text-red-500 text-4xl mb-4", children: "\u26A0\uFE0F" }), jsxRuntime.jsx("h2", { className: "text-xl font-bold text-red-600 mb-2", children: t("document_check.navigation_error.title", "Erreur de navigation") }), jsxRuntime.jsx("p", { className: "text-gray-600 mb-4", children: t("document_check.navigation_error.description", "Étape non valide. Veuillez recommencer.") }), jsxRuntime.jsx(ButtonDesktop.default, { className: "px-4 py-2 bg-primary text-white rounded hover:bg-primary-dark transition-colors", type: "back", onClick: function () { return setDocStep(0); }, children: t("document_check.navigation_error.back", "Retour au début") })] }));