datakeen-session-react 1.1.200-dev.2 → 1.1.200-dev.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/components/nfc-scan/NfcScanNode.js +26 -3
- package/dist/cjs/i18n/en.json.js +3 -0
- package/dist/cjs/i18n/es.json.js +3 -0
- package/dist/cjs/i18n/fr.json.js +3 -0
- package/dist/cjs/utils/isMobileDevice.js +11 -0
- package/dist/esm/components/nfc-scan/NfcScanNode.js +27 -4
- package/dist/esm/i18n/en.json.js +3 -0
- package/dist/esm/i18n/es.json.js +3 -0
- package/dist/esm/i18n/fr.json.js +3 -0
- package/dist/esm/utils/isMobileDevice.js +11 -1
- package/package.json +1 -1
|
@@ -18,6 +18,12 @@ var Title = require('../ui/Title.js');
|
|
|
18
18
|
var Subtitle = require('../ui/Subtitle.js');
|
|
19
19
|
var NfcSuccessAnimation = require('./NfcSuccessAnimation.js');
|
|
20
20
|
|
|
21
|
+
// App native NFC iOS « ID Scan ». Safari n'ouvre jamais l'app via une redirection JS ni via un
|
|
22
|
+
// Universal Link du même domaine que la page (Apple TN3155) : on passe par le schéma custom déclaré
|
|
23
|
+
// par l'app, sur un geste utilisateur. L'hôte du lien = backend Datakeen, que l'app utilise pour
|
|
24
|
+
// choisir l'environnement (même rôle que `intent://<host>/scan/<id>` sur Android).
|
|
25
|
+
var IOS_APP_SCHEME = "datakeenscannerswift";
|
|
26
|
+
var IOS_APP_STORE_URL = "https://apps.apple.com/app/id6762505375";
|
|
21
27
|
var NfcScanStep = function (_a) {
|
|
22
28
|
var sessionId = _a.sessionId, nodeId = _a.nodeId, stepObject = _a.stepObject, template = _a.template, pageTitle = _a.pageTitle, pageDescription = _a.pageDescription, onBack = _a.onBack, onContinueWithoutChip = _a.onContinueWithoutChip;
|
|
23
29
|
var t = useI18n.useI18n().t;
|
|
@@ -27,11 +33,26 @@ var NfcScanStep = function (_a) {
|
|
|
27
33
|
var _d = React.useState(false), isResetting = _d[0], setIsResetting = _d[1];
|
|
28
34
|
// Sur mobile, on ouvre directement l'app de scan au lieu d'afficher un QR code inutile.
|
|
29
35
|
var isMobile = React.useMemo(function () { return isMobileDevice.isMobileDevice(); }, []);
|
|
36
|
+
var isIOS = React.useMemo(function () { return isMobileDevice.isIOSDevice(); }, []);
|
|
30
37
|
var nfcUrl = React.useMemo(function () {
|
|
31
38
|
var origin = typeof window !== "undefined" ? window.location.origin : "";
|
|
32
39
|
return "".concat(origin, "/scan/").concat(sessionId);
|
|
33
40
|
}, [sessionId]);
|
|
34
41
|
var apiBaseUrl = React.useMemo(function () { return api.getBaseURL(); }, []);
|
|
42
|
+
var iosAppLinks = React.useMemo(function () {
|
|
43
|
+
var host = new URL(apiBaseUrl, window.location.href).host;
|
|
44
|
+
return {
|
|
45
|
+
open: "".concat(IOS_APP_SCHEME, "://").concat(host, "/scan/").concat(sessionId),
|
|
46
|
+
// Lu par le bouton « Reprendre ma session » de l'app au premier lancement après installation.
|
|
47
|
+
resume: "https://".concat(host, "/scan/").concat(sessionId),
|
|
48
|
+
};
|
|
49
|
+
}, [apiBaseUrl, sessionId]);
|
|
50
|
+
// Best effort : l'App Store ne transmet aucun contexte à l'app installée (pas d'équivalent du
|
|
51
|
+
// Play Install Referrer), le presse-papier sert de relais. Échec silencieux (permission refusée).
|
|
52
|
+
var copyResumeLink = function () {
|
|
53
|
+
var _a;
|
|
54
|
+
(_a = navigator.clipboard) === null || _a === void 0 ? void 0 : _a.writeText(iosAppLinks.resume).catch(function () { return undefined; });
|
|
55
|
+
};
|
|
35
56
|
var status = useNfcSseStatus.useNfcSseStatus({
|
|
36
57
|
sessionId: sessionId,
|
|
37
58
|
apiBaseUrl: apiBaseUrl,
|
|
@@ -50,13 +71,15 @@ var NfcScanStep = function (_a) {
|
|
|
50
71
|
// Sur mobile : ouvrir directement l'application de scan (pas de QR à se scanner soi-même).
|
|
51
72
|
// Une seule fois, tant que le scan n'a pas progressé. Le SSE reste actif pour faire avancer
|
|
52
73
|
// le parcours quand la lecture est terminée.
|
|
74
|
+
// Pas sur iOS : la redirection resterait dans Safari et quitterait la page (SSE fermé, parcours
|
|
75
|
+
// bloqué). On y affiche des boutons à la place, et la page reste ouverte pendant le scan.
|
|
53
76
|
var hasRedirectedRef = React.useRef(false);
|
|
54
77
|
React.useEffect(function () {
|
|
55
|
-
if (!isMobile || status !== "pending" || hasRedirectedRef.current)
|
|
78
|
+
if (!isMobile || isIOS || status !== "pending" || hasRedirectedRef.current)
|
|
56
79
|
return;
|
|
57
80
|
hasRedirectedRef.current = true;
|
|
58
81
|
window.location.assign(nfcUrl);
|
|
59
|
-
}, [isMobile, status, nfcUrl]);
|
|
82
|
+
}, [isMobile, isIOS, status, nfcUrl]);
|
|
60
83
|
React.useEffect(function () {
|
|
61
84
|
if (isMobile)
|
|
62
85
|
return; // pas de QR sur mobile (redirection directe)
|
|
@@ -141,7 +164,7 @@ var NfcScanStep = function (_a) {
|
|
|
141
164
|
return (jsxRuntime.jsx(MobilePageLayout.default, { footer: footer, 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 flex-col justify-center items-center gap-4", 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 === "failed" ? (jsxRuntime.jsxs("div", { className: "flex flex-col items-center gap-2 p-8 text-center", children: [jsxRuntime.jsx("p", { className: "text-base font-semibold text-red-600", children: t("nfc_scan.failed_title", "Le scan n'a pas pu être vérifié") }), jsxRuntime.jsx("p", { className: "text-sm text-gray-600 leading-relaxed", children: t("nfc_scan.failed_description", "Après plusieurs tentatives, la lecture de votre document n'a pas pu être validée.") }), resetError && (jsxRuntime.jsx("p", { className: "text-sm text-red-600", role: "alert", children: resetError }))] })) : (
|
|
142
165
|
// Contenu principal QR/mobile — reste monté pour "pending" ET "opened", pour ne
|
|
143
166
|
// jamais démonter le canvas déjà généré.
|
|
144
|
-
jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [qrError ? (jsxRuntime.jsx("div", { className: "text-red-500 text-center p-4", children: qrError })) : isMobile ? (jsxRuntime.jsxs("div", { className: "flex flex-col items-center gap-4 p-8 text-center", 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.opening_app", "Ouverture de l'application…") }), jsxRuntime.jsx("a", { href: nfcUrl, className: "text-sm font-medium text-blue-600 underline", children: t("nfc_scan.open_app_link", "Ouvrir l'application") })] })) : (jsxRuntime.jsx("div", { className: "bg-white p-4 rounded-lg shadow-lg border-2 border-gray-200", children: jsxRuntime.jsx("canvas", { ref: canvasRef }) })), status === "opened" && (jsxRuntime.jsxs("div", { className: "text-center space-y-1", children: [jsxRuntime.jsx("p", { className: "text-sm font-semibold", style: { color: "var(--uni-secondary-color, #0a9983)" }, children: t("nfc_scan.qr_opened_title", "QR code scanné") }), jsxRuntime.jsx("p", { className: "text-xs text-gray-500 leading-relaxed", children: t("nfc_scan.qr_opened_description", "L'expérience NFC est ouverte sur votre smartphone. Continuez le scan sur votre téléphone.") }), jsxRuntime.jsxs("div", { className: "flex items-center justify-center gap-2 text-xs text-gray-500 pt-1", children: [jsxRuntime.jsx("span", { className: "h-2 w-2 rounded-full animate-pulse", style: { backgroundColor: "var(--uni-primary-color, #11e5c5)" } }), t("nfc_scan.waiting_completion", "En attente de la lecture NFC")] })] }))] })) })] }) }) }));
|
|
167
|
+
jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [qrError ? (jsxRuntime.jsx("div", { className: "text-red-500 text-center p-4", children: qrError })) : isIOS ? (jsxRuntime.jsxs("div", { className: "flex w-full flex-col items-center gap-3 p-4 text-center", children: [jsxRuntime.jsx("a", { href: iosAppLinks.open, className: "flex h-[48px] w-full items-center justify-center rounded-[12px] text-sm font-medium hover:brightness-110 active:brightness-90", style: { backgroundColor: "var(--dk-btn-bg)", color: "var(--dk-btn-text)" }, children: t("nfc_scan.open_app_link", "Ouvrir l'application") }), jsxRuntime.jsx("a", { href: IOS_APP_STORE_URL, onClick: copyResumeLink, className: "flex h-[48px] w-full items-center justify-center rounded-[12px] border border-gray-300 text-sm font-medium text-gray-600 hover:bg-black/5", children: t("nfc_scan.install_app_link", "Installer l'application") }), jsxRuntime.jsx("p", { className: "text-xs text-gray-500 leading-relaxed", children: t("nfc_scan.install_app_hint", "Après l'installation, revenez sur cette page et appuyez sur « Ouvrir l'application ».") })] })) : isMobile ? (jsxRuntime.jsxs("div", { className: "flex flex-col items-center gap-4 p-8 text-center", 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.opening_app", "Ouverture de l'application…") }), jsxRuntime.jsx("a", { href: nfcUrl, className: "text-sm font-medium text-blue-600 underline", children: t("nfc_scan.open_app_link", "Ouvrir l'application") })] })) : (jsxRuntime.jsx("div", { className: "bg-white p-4 rounded-lg shadow-lg border-2 border-gray-200", children: jsxRuntime.jsx("canvas", { ref: canvasRef }) })), status === "opened" && (jsxRuntime.jsxs("div", { className: "text-center space-y-1", children: [jsxRuntime.jsx("p", { className: "text-sm font-semibold", style: { color: "var(--uni-secondary-color, #0a9983)" }, children: t("nfc_scan.qr_opened_title", "QR code scanné") }), jsxRuntime.jsx("p", { className: "text-xs text-gray-500 leading-relaxed", children: t("nfc_scan.qr_opened_description", "L'expérience NFC est ouverte sur votre smartphone. Continuez le scan sur votre téléphone.") }), jsxRuntime.jsxs("div", { className: "flex items-center justify-center gap-2 text-xs text-gray-500 pt-1", children: [jsxRuntime.jsx("span", { className: "h-2 w-2 rounded-full animate-pulse", style: { backgroundColor: "var(--uni-primary-color, #11e5c5)" } }), t("nfc_scan.waiting_completion", "En attente de la lecture NFC")] })] }))] })) })] }) }) }));
|
|
145
168
|
};
|
|
146
169
|
|
|
147
170
|
exports.default = NfcScanStep;
|
package/dist/cjs/i18n/en.json.js
CHANGED
|
@@ -1025,6 +1025,9 @@ var signature = {
|
|
|
1025
1025
|
token_error: "Error loading signature session."
|
|
1026
1026
|
};
|
|
1027
1027
|
var nfc_scan = {
|
|
1028
|
+
open_app_link: "Open the app",
|
|
1029
|
+
install_app_link: "Install the app",
|
|
1030
|
+
install_app_hint: "Once installed, come back to this page and tap “Open the app”.",
|
|
1028
1031
|
page_title: "NFC scan of your document",
|
|
1029
1032
|
page_description: "Scan the QR code below with your smartphone to read the electronic chip of your identity document.",
|
|
1030
1033
|
verifying: "Verifying…",
|
package/dist/cjs/i18n/es.json.js
CHANGED
|
@@ -1025,6 +1025,9 @@ var signature = {
|
|
|
1025
1025
|
token_error: "Error al cargar la sesión de firma."
|
|
1026
1026
|
};
|
|
1027
1027
|
var nfc_scan = {
|
|
1028
|
+
open_app_link: "Abrir la aplicación",
|
|
1029
|
+
install_app_link: "Instalar la aplicación",
|
|
1030
|
+
install_app_hint: "Después de instalarla, vuelve a esta página y pulsa «Abrir la aplicación».",
|
|
1028
1031
|
page_title: "Escaneo NFC de tu documento",
|
|
1029
1032
|
page_description: "Escanea el código QR siguiente con tu smartphone para leer el chip electrónico de tu documento de identidad.",
|
|
1030
1033
|
verifying: "Verificando…",
|
package/dist/cjs/i18n/fr.json.js
CHANGED
|
@@ -1025,6 +1025,9 @@ var signature = {
|
|
|
1025
1025
|
token_error: "Erreur lors du chargement de la session de signature."
|
|
1026
1026
|
};
|
|
1027
1027
|
var nfc_scan = {
|
|
1028
|
+
open_app_link: "Ouvrir l'application",
|
|
1029
|
+
install_app_link: "Installer l'application",
|
|
1030
|
+
install_app_hint: "Après l'installation, revenez sur cette page et appuyez sur « Ouvrir l'application ».",
|
|
1028
1031
|
page_title: "Scan NFC de votre document",
|
|
1029
1032
|
page_description: "Scannez le QR code ci-dessous avec votre smartphone pour lire la puce électronique de votre document d'identité.",
|
|
1030
1033
|
verifying: "Vérification en cours…",
|
|
@@ -12,5 +12,16 @@ var isMobileDevice = function () {
|
|
|
12
12
|
return false;
|
|
13
13
|
return /Android|iPhone|iPad|iPod|Opera Mini|IEMobile|WPDesktop/i.test(navigator.userAgent);
|
|
14
14
|
};
|
|
15
|
+
/**
|
|
16
|
+
* iPhone / iPad (UA historique) / iPod. Sur iOS, Safari n'ouvre pas l'app NFC via une redirection
|
|
17
|
+
* JS ni via un Universal Link du même domaine : l'étape NFC doit proposer un bouton (geste
|
|
18
|
+
* utilisateur) vers le schéma custom de l'app.
|
|
19
|
+
*/
|
|
20
|
+
var isIOSDevice = function () {
|
|
21
|
+
if (typeof navigator === "undefined")
|
|
22
|
+
return false;
|
|
23
|
+
return /iPhone|iPad|iPod/i.test(navigator.userAgent);
|
|
24
|
+
};
|
|
15
25
|
|
|
26
|
+
exports.isIOSDevice = isIOSDevice;
|
|
16
27
|
exports.isMobileDevice = isMobileDevice;
|
|
@@ -6,7 +6,7 @@ import { useI18n } from '../../hooks/useI18n.js';
|
|
|
6
6
|
import { useNfcSseStatus } from '../../hooks/useNfcSseStatus.js';
|
|
7
7
|
import { getBaseURL } from '../../services/api.js';
|
|
8
8
|
import { resetNfcScan } from '../../services/sessionService.js';
|
|
9
|
-
import { isMobileDevice } from '../../utils/isMobileDevice.js';
|
|
9
|
+
import { isMobileDevice, isIOSDevice } from '../../utils/isMobileDevice.js';
|
|
10
10
|
import MobilePageLayout from '../ui/MobilePageLayout.js';
|
|
11
11
|
import Button from '../ui/Button.js';
|
|
12
12
|
import PageActions from '../ui/PageActions.js';
|
|
@@ -14,6 +14,12 @@ import Title from '../ui/Title.js';
|
|
|
14
14
|
import Subtitle from '../ui/Subtitle.js';
|
|
15
15
|
import NfcSuccessAnimation from './NfcSuccessAnimation.js';
|
|
16
16
|
|
|
17
|
+
// App native NFC iOS « ID Scan ». Safari n'ouvre jamais l'app via une redirection JS ni via un
|
|
18
|
+
// Universal Link du même domaine que la page (Apple TN3155) : on passe par le schéma custom déclaré
|
|
19
|
+
// par l'app, sur un geste utilisateur. L'hôte du lien = backend Datakeen, que l'app utilise pour
|
|
20
|
+
// choisir l'environnement (même rôle que `intent://<host>/scan/<id>` sur Android).
|
|
21
|
+
var IOS_APP_SCHEME = "datakeenscannerswift";
|
|
22
|
+
var IOS_APP_STORE_URL = "https://apps.apple.com/app/id6762505375";
|
|
17
23
|
var NfcScanStep = function (_a) {
|
|
18
24
|
var sessionId = _a.sessionId, nodeId = _a.nodeId, stepObject = _a.stepObject, template = _a.template, pageTitle = _a.pageTitle, pageDescription = _a.pageDescription, onBack = _a.onBack, onContinueWithoutChip = _a.onContinueWithoutChip;
|
|
19
25
|
var t = useI18n().t;
|
|
@@ -23,11 +29,26 @@ var NfcScanStep = function (_a) {
|
|
|
23
29
|
var _d = useState(false), isResetting = _d[0], setIsResetting = _d[1];
|
|
24
30
|
// Sur mobile, on ouvre directement l'app de scan au lieu d'afficher un QR code inutile.
|
|
25
31
|
var isMobile = useMemo(function () { return isMobileDevice(); }, []);
|
|
32
|
+
var isIOS = useMemo(function () { return isIOSDevice(); }, []);
|
|
26
33
|
var nfcUrl = useMemo(function () {
|
|
27
34
|
var origin = typeof window !== "undefined" ? window.location.origin : "";
|
|
28
35
|
return "".concat(origin, "/scan/").concat(sessionId);
|
|
29
36
|
}, [sessionId]);
|
|
30
37
|
var apiBaseUrl = useMemo(function () { return getBaseURL(); }, []);
|
|
38
|
+
var iosAppLinks = useMemo(function () {
|
|
39
|
+
var host = new URL(apiBaseUrl, window.location.href).host;
|
|
40
|
+
return {
|
|
41
|
+
open: "".concat(IOS_APP_SCHEME, "://").concat(host, "/scan/").concat(sessionId),
|
|
42
|
+
// Lu par le bouton « Reprendre ma session » de l'app au premier lancement après installation.
|
|
43
|
+
resume: "https://".concat(host, "/scan/").concat(sessionId),
|
|
44
|
+
};
|
|
45
|
+
}, [apiBaseUrl, sessionId]);
|
|
46
|
+
// Best effort : l'App Store ne transmet aucun contexte à l'app installée (pas d'équivalent du
|
|
47
|
+
// Play Install Referrer), le presse-papier sert de relais. Échec silencieux (permission refusée).
|
|
48
|
+
var copyResumeLink = function () {
|
|
49
|
+
var _a;
|
|
50
|
+
(_a = navigator.clipboard) === null || _a === void 0 ? void 0 : _a.writeText(iosAppLinks.resume).catch(function () { return undefined; });
|
|
51
|
+
};
|
|
31
52
|
var status = useNfcSseStatus({
|
|
32
53
|
sessionId: sessionId,
|
|
33
54
|
apiBaseUrl: apiBaseUrl,
|
|
@@ -46,13 +67,15 @@ var NfcScanStep = function (_a) {
|
|
|
46
67
|
// Sur mobile : ouvrir directement l'application de scan (pas de QR à se scanner soi-même).
|
|
47
68
|
// Une seule fois, tant que le scan n'a pas progressé. Le SSE reste actif pour faire avancer
|
|
48
69
|
// le parcours quand la lecture est terminée.
|
|
70
|
+
// Pas sur iOS : la redirection resterait dans Safari et quitterait la page (SSE fermé, parcours
|
|
71
|
+
// bloqué). On y affiche des boutons à la place, et la page reste ouverte pendant le scan.
|
|
49
72
|
var hasRedirectedRef = useRef(false);
|
|
50
73
|
useEffect(function () {
|
|
51
|
-
if (!isMobile || status !== "pending" || hasRedirectedRef.current)
|
|
74
|
+
if (!isMobile || isIOS || status !== "pending" || hasRedirectedRef.current)
|
|
52
75
|
return;
|
|
53
76
|
hasRedirectedRef.current = true;
|
|
54
77
|
window.location.assign(nfcUrl);
|
|
55
|
-
}, [isMobile, status, nfcUrl]);
|
|
78
|
+
}, [isMobile, isIOS, status, nfcUrl]);
|
|
56
79
|
useEffect(function () {
|
|
57
80
|
if (isMobile)
|
|
58
81
|
return; // pas de QR sur mobile (redirection directe)
|
|
@@ -137,7 +160,7 @@ var NfcScanStep = function (_a) {
|
|
|
137
160
|
return (jsx(MobilePageLayout, { footer: footer, children: jsx("div", { className: "px-4 py-6 pt-11 md:px-8 md:py-8", children: jsxs("div", { className: "w-full max-w-md mx-auto space-y-6", children: [jsxs("div", { className: "text-center space-y-4 mt-16 md:mt-20", children: [jsx(Title, { className: "text-xl md:text-2xl lg:text-3xl", children: title }), jsx(Subtitle, { className: "text-sm md:text-base text-gray-600 leading-relaxed whitespace-pre-line", children: subtitle })] }), jsx("div", { className: "flex-1 flex flex-col justify-center items-center gap-4", children: status === "success" ? (jsx(NfcSuccessAnimation, {})) : status === "completed" ? (jsxs("div", { className: "flex flex-col items-center gap-4 p-8", children: [jsx("div", { className: "animate-spin w-10 h-10 border-2 border-gray-300 border-t-blue-500 rounded-full" }), jsx("p", { className: "text-sm text-gray-600", children: t("nfc_scan.verifying", "Vérification en cours…") })] })) : status === "failed" ? (jsxs("div", { className: "flex flex-col items-center gap-2 p-8 text-center", children: [jsx("p", { className: "text-base font-semibold text-red-600", children: t("nfc_scan.failed_title", "Le scan n'a pas pu être vérifié") }), jsx("p", { className: "text-sm text-gray-600 leading-relaxed", children: t("nfc_scan.failed_description", "Après plusieurs tentatives, la lecture de votre document n'a pas pu être validée.") }), resetError && (jsx("p", { className: "text-sm text-red-600", role: "alert", children: resetError }))] })) : (
|
|
138
161
|
// Contenu principal QR/mobile — reste monté pour "pending" ET "opened", pour ne
|
|
139
162
|
// jamais démonter le canvas déjà généré.
|
|
140
|
-
jsxs(Fragment, { children: [qrError ? (jsx("div", { className: "text-red-500 text-center p-4", children: qrError })) : isMobile ? (jsxs("div", { className: "flex flex-col items-center gap-4 p-8 text-center", children: [jsx("div", { className: "animate-spin w-10 h-10 border-2 border-gray-300 border-t-blue-500 rounded-full" }), jsx("p", { className: "text-sm text-gray-600", children: t("nfc_scan.opening_app", "Ouverture de l'application…") }), jsx("a", { href: nfcUrl, className: "text-sm font-medium text-blue-600 underline", children: t("nfc_scan.open_app_link", "Ouvrir l'application") })] })) : (jsx("div", { className: "bg-white p-4 rounded-lg shadow-lg border-2 border-gray-200", children: jsx("canvas", { ref: canvasRef }) })), status === "opened" && (jsxs("div", { className: "text-center space-y-1", children: [jsx("p", { className: "text-sm font-semibold", style: { color: "var(--uni-secondary-color, #0a9983)" }, children: t("nfc_scan.qr_opened_title", "QR code scanné") }), jsx("p", { className: "text-xs text-gray-500 leading-relaxed", children: t("nfc_scan.qr_opened_description", "L'expérience NFC est ouverte sur votre smartphone. Continuez le scan sur votre téléphone.") }), jsxs("div", { className: "flex items-center justify-center gap-2 text-xs text-gray-500 pt-1", children: [jsx("span", { className: "h-2 w-2 rounded-full animate-pulse", style: { backgroundColor: "var(--uni-primary-color, #11e5c5)" } }), t("nfc_scan.waiting_completion", "En attente de la lecture NFC")] })] }))] })) })] }) }) }));
|
|
163
|
+
jsxs(Fragment, { children: [qrError ? (jsx("div", { className: "text-red-500 text-center p-4", children: qrError })) : isIOS ? (jsxs("div", { className: "flex w-full flex-col items-center gap-3 p-4 text-center", children: [jsx("a", { href: iosAppLinks.open, className: "flex h-[48px] w-full items-center justify-center rounded-[12px] text-sm font-medium hover:brightness-110 active:brightness-90", style: { backgroundColor: "var(--dk-btn-bg)", color: "var(--dk-btn-text)" }, children: t("nfc_scan.open_app_link", "Ouvrir l'application") }), jsx("a", { href: IOS_APP_STORE_URL, onClick: copyResumeLink, className: "flex h-[48px] w-full items-center justify-center rounded-[12px] border border-gray-300 text-sm font-medium text-gray-600 hover:bg-black/5", children: t("nfc_scan.install_app_link", "Installer l'application") }), jsx("p", { className: "text-xs text-gray-500 leading-relaxed", children: t("nfc_scan.install_app_hint", "Après l'installation, revenez sur cette page et appuyez sur « Ouvrir l'application ».") })] })) : isMobile ? (jsxs("div", { className: "flex flex-col items-center gap-4 p-8 text-center", children: [jsx("div", { className: "animate-spin w-10 h-10 border-2 border-gray-300 border-t-blue-500 rounded-full" }), jsx("p", { className: "text-sm text-gray-600", children: t("nfc_scan.opening_app", "Ouverture de l'application…") }), jsx("a", { href: nfcUrl, className: "text-sm font-medium text-blue-600 underline", children: t("nfc_scan.open_app_link", "Ouvrir l'application") })] })) : (jsx("div", { className: "bg-white p-4 rounded-lg shadow-lg border-2 border-gray-200", children: jsx("canvas", { ref: canvasRef }) })), status === "opened" && (jsxs("div", { className: "text-center space-y-1", children: [jsx("p", { className: "text-sm font-semibold", style: { color: "var(--uni-secondary-color, #0a9983)" }, children: t("nfc_scan.qr_opened_title", "QR code scanné") }), jsx("p", { className: "text-xs text-gray-500 leading-relaxed", children: t("nfc_scan.qr_opened_description", "L'expérience NFC est ouverte sur votre smartphone. Continuez le scan sur votre téléphone.") }), jsxs("div", { className: "flex items-center justify-center gap-2 text-xs text-gray-500 pt-1", children: [jsx("span", { className: "h-2 w-2 rounded-full animate-pulse", style: { backgroundColor: "var(--uni-primary-color, #11e5c5)" } }), t("nfc_scan.waiting_completion", "En attente de la lecture NFC")] })] }))] })) })] }) }) }));
|
|
141
164
|
};
|
|
142
165
|
|
|
143
166
|
export { NfcScanStep as default };
|
package/dist/esm/i18n/en.json.js
CHANGED
|
@@ -1021,6 +1021,9 @@ var signature = {
|
|
|
1021
1021
|
token_error: "Error loading signature session."
|
|
1022
1022
|
};
|
|
1023
1023
|
var nfc_scan = {
|
|
1024
|
+
open_app_link: "Open the app",
|
|
1025
|
+
install_app_link: "Install the app",
|
|
1026
|
+
install_app_hint: "Once installed, come back to this page and tap “Open the app”.",
|
|
1024
1027
|
page_title: "NFC scan of your document",
|
|
1025
1028
|
page_description: "Scan the QR code below with your smartphone to read the electronic chip of your identity document.",
|
|
1026
1029
|
verifying: "Verifying…",
|
package/dist/esm/i18n/es.json.js
CHANGED
|
@@ -1021,6 +1021,9 @@ var signature = {
|
|
|
1021
1021
|
token_error: "Error al cargar la sesión de firma."
|
|
1022
1022
|
};
|
|
1023
1023
|
var nfc_scan = {
|
|
1024
|
+
open_app_link: "Abrir la aplicación",
|
|
1025
|
+
install_app_link: "Instalar la aplicación",
|
|
1026
|
+
install_app_hint: "Después de instalarla, vuelve a esta página y pulsa «Abrir la aplicación».",
|
|
1024
1027
|
page_title: "Escaneo NFC de tu documento",
|
|
1025
1028
|
page_description: "Escanea el código QR siguiente con tu smartphone para leer el chip electrónico de tu documento de identidad.",
|
|
1026
1029
|
verifying: "Verificando…",
|
package/dist/esm/i18n/fr.json.js
CHANGED
|
@@ -1021,6 +1021,9 @@ var signature = {
|
|
|
1021
1021
|
token_error: "Erreur lors du chargement de la session de signature."
|
|
1022
1022
|
};
|
|
1023
1023
|
var nfc_scan = {
|
|
1024
|
+
open_app_link: "Ouvrir l'application",
|
|
1025
|
+
install_app_link: "Installer l'application",
|
|
1026
|
+
install_app_hint: "Après l'installation, revenez sur cette page et appuyez sur « Ouvrir l'application ».",
|
|
1024
1027
|
page_title: "Scan NFC de votre document",
|
|
1025
1028
|
page_description: "Scannez le QR code ci-dessous avec votre smartphone pour lire la puce électronique de votre document d'identité.",
|
|
1026
1029
|
verifying: "Vérification en cours…",
|
|
@@ -10,5 +10,15 @@ var isMobileDevice = function () {
|
|
|
10
10
|
return false;
|
|
11
11
|
return /Android|iPhone|iPad|iPod|Opera Mini|IEMobile|WPDesktop/i.test(navigator.userAgent);
|
|
12
12
|
};
|
|
13
|
+
/**
|
|
14
|
+
* iPhone / iPad (UA historique) / iPod. Sur iOS, Safari n'ouvre pas l'app NFC via une redirection
|
|
15
|
+
* JS ni via un Universal Link du même domaine : l'étape NFC doit proposer un bouton (geste
|
|
16
|
+
* utilisateur) vers le schéma custom de l'app.
|
|
17
|
+
*/
|
|
18
|
+
var isIOSDevice = function () {
|
|
19
|
+
if (typeof navigator === "undefined")
|
|
20
|
+
return false;
|
|
21
|
+
return /iPhone|iPad|iPod/i.test(navigator.userAgent);
|
|
22
|
+
};
|
|
13
23
|
|
|
14
|
-
export { isMobileDevice };
|
|
24
|
+
export { isIOSDevice, isMobileDevice };
|