datakeen-session-react 1.1.195-dev.4 → 1.1.195-dev.6
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/jdi/JDIProcessing.js +3 -3
- package/dist/cjs/components/jdi/JDIProcessing.js.map +1 -1
- package/dist/cjs/components/selfie/Video.js +2 -2
- package/dist/cjs/components/selfie/Video.js.map +1 -1
- package/dist/cjs/components/selfie/selfie-flow/SelfieFlow.js +2 -2
- package/dist/cjs/components/selfie/selfie-flow/SelfieFlow.js.map +1 -1
- package/dist/cjs/components/selfie/selfie-flow/SelfieProcessing.js +5 -1
- package/dist/cjs/components/selfie/selfie-flow/SelfieProcessing.js.map +1 -1
- package/dist/cjs/components/selfie/selfie-flow/SelfieRecorder.js +123 -13
- package/dist/cjs/components/selfie/selfie-flow/SelfieRecorder.js.map +1 -1
- package/dist/cjs/components/session/Selfie.js +1 -1
- package/dist/cjs/components/session/Selfie.js.map +1 -1
- package/dist/cjs/i18n/en.json.js +2 -1
- package/dist/cjs/i18n/en.json.js.map +1 -1
- package/dist/cjs/i18n/es.json.js +2 -1
- package/dist/cjs/i18n/es.json.js.map +1 -1
- package/dist/cjs/i18n/fr.json.js +2 -1
- package/dist/cjs/i18n/fr.json.js.map +1 -1
- package/dist/cjs/services/analysis.js +40 -26
- package/dist/cjs/services/analysis.js.map +1 -1
- package/dist/cjs/services/iadService.js +30 -0
- package/dist/cjs/services/iadService.js.map +1 -0
- package/dist/cjs/types/session.js.map +1 -1
- package/dist/esm/components/jdi/JDIProcessing.js +3 -3
- package/dist/esm/components/jdi/JDIProcessing.js.map +1 -1
- package/dist/esm/components/selfie/Video.js +2 -2
- package/dist/esm/components/selfie/Video.js.map +1 -1
- package/dist/esm/components/selfie/selfie-flow/SelfieFlow.js +2 -2
- package/dist/esm/components/selfie/selfie-flow/SelfieFlow.js.map +1 -1
- package/dist/esm/components/selfie/selfie-flow/SelfieProcessing.js +5 -1
- package/dist/esm/components/selfie/selfie-flow/SelfieProcessing.js.map +1 -1
- package/dist/esm/components/selfie/selfie-flow/SelfieRecorder.js +124 -14
- package/dist/esm/components/selfie/selfie-flow/SelfieRecorder.js.map +1 -1
- package/dist/esm/components/session/Selfie.js +1 -1
- package/dist/esm/components/session/Selfie.js.map +1 -1
- package/dist/esm/i18n/en.json.js +2 -1
- package/dist/esm/i18n/en.json.js.map +1 -1
- package/dist/esm/i18n/es.json.js +2 -1
- package/dist/esm/i18n/es.json.js.map +1 -1
- package/dist/esm/i18n/fr.json.js +2 -1
- package/dist/esm/i18n/fr.json.js.map +1 -1
- package/dist/esm/services/analysis.js +40 -26
- package/dist/esm/services/analysis.js.map +1 -1
- package/dist/esm/services/iadService.js +28 -0
- package/dist/esm/services/iadService.js.map +1 -0
- package/dist/esm/types/session.js.map +1 -1
- package/docs/multi-runs.md +15 -8
- package/package.json +1 -1
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var tslib_es6 = require('../node_modules/tslib/tslib.es6.js');
|
|
4
|
+
var api = require('./api.js');
|
|
5
|
+
|
|
6
|
+
function prepareIadCapture(sessionId) {
|
|
7
|
+
return tslib_es6.__awaiter(this, void 0, void 0, function () {
|
|
8
|
+
var response, preparation;
|
|
9
|
+
var _a;
|
|
10
|
+
return tslib_es6.__generator(this, function (_b) {
|
|
11
|
+
switch (_b.label) {
|
|
12
|
+
case 0: return [4 /*yield*/, api.apiService.post("/session/sdk/".concat(sessionId, "/iad/prepare"))];
|
|
13
|
+
case 1:
|
|
14
|
+
response = _b.sent();
|
|
15
|
+
preparation = (_a = response.data) === null || _a === void 0 ? void 0 : _a.data;
|
|
16
|
+
if (!preparation ||
|
|
17
|
+
typeof preparation.data !== "string" ||
|
|
18
|
+
preparation.data.length === 0 ||
|
|
19
|
+
(preparation.mode !== "passive" &&
|
|
20
|
+
preparation.mode !== "active-fallback")) {
|
|
21
|
+
throw new Error("Invalid IAD preparation response");
|
|
22
|
+
}
|
|
23
|
+
return [2 /*return*/, preparation];
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
exports.prepareIadCapture = prepareIadCapture;
|
|
30
|
+
//# sourceMappingURL=iadService.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"iadService.js","sources":["../../../../src/services/iadService.ts"],"sourcesContent":["import type { IadMode } from \"@unissey-web/sdk-react\";\nimport { apiService } from \"./api\";\n\nexport interface IadPreparation {\n data: string;\n mode: IadMode;\n}\n\nexport async function prepareIadCapture(\n sessionId: string,\n): Promise<IadPreparation> {\n const response = await apiService.post<{\n status: number;\n message: string;\n data: IadPreparation;\n }>(`/session/sdk/${sessionId}/iad/prepare`);\n const preparation = response.data?.data;\n\n if (\n !preparation ||\n typeof preparation.data !== \"string\" ||\n preparation.data.length === 0 ||\n (preparation.mode !== \"passive\" &&\n preparation.mode !== \"active-fallback\")\n ) {\n throw new Error(\"Invalid IAD preparation response\");\n }\n\n return preparation;\n}\n"],"names":["apiService"],"mappings":";;;;;AAQM,SAAgB,iBAAiB,CACrC,SAAiB,EAAA;;;;;;wBAEA,OAAA,CAAA,CAAA,YAAMA,cAAU,CAAC,IAAI,CAInC,uBAAgB,SAAS,EAAA,cAAA,CAAc,CAAC,CAAA;;AAJrC,oBAAA,QAAQ,GAAG,EAAA,CAAA,IAAA,EAI0B;AACrC,oBAAA,WAAW,GAAG,CAAA,EAAA,GAAA,QAAQ,CAAC,IAAI,MAAA,IAAA,IAAA,EAAA,KAAA,MAAA,GAAA,MAAA,GAAA,EAAA,CAAE,IAAI;AAEvC,oBAAA,IACE,CAAC,WAAW;AACZ,wBAAA,OAAO,WAAW,CAAC,IAAI,KAAK,QAAQ;AACpC,wBAAA,WAAW,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC;AAC7B,yBAAC,WAAW,CAAC,IAAI,KAAK,SAAS;AAC7B,4BAAA,WAAW,CAAC,IAAI,KAAK,iBAAiB,CAAC,EACzC;AACA,wBAAA,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC;oBACrD;AAEA,oBAAA,OAAA,CAAA,CAAA,aAAO,WAAW,CAAA;;;;AACnB;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session.js","sources":["../../../../src/types/session.ts"],"sourcesContent":["import type React from \"react\";\n\nexport interface SessionConfig {\n sessionToken?: string;\n selfie?: boolean;\n requireMobile?: boolean;\n}\n\nexport interface DatakeenSessionProps {\n /** Session credential returned by server-side session creation. Required by secured backends. */\n sessionToken?: string;\n sessionId: string;\n sessionConfig?: SessionConfig;\n apiBaseUrl?: string; // Optional API base URL for dynamic environment configuration\n}\n\nexport interface UseSessionReturn {\n SessionComponent: React.ReactElement;\n}\n\nexport type stepObject = {\n setStep: (step: number, skipHistory?: boolean) => void;\n goBack: () => void;\n /** Retour arrière vers un nœud précis (ex: \"Corriger ma saisie\") :\n * tronque l'historique jusqu'à `targetStep` au lieu de l'empiler. */\n goBackToStep: (targetStep: number) => void;\n goToNextStep: (\n currentNodeId: string,\n template: SessionTemplate,\n handle?: string,\n ) => void;\n /** Avance via le graphe et tronque l'historique au nœud d'arrivée. */\n goToNextStepCommitted: (\n currentNodeId: string,\n template: SessionTemplate,\n handle?: string,\n ) => void;\n step: number;\n canGoBack: boolean;\n};\n\nexport interface ProcessingStep {\n title: string;\n subtitle: string;\n hasError?: boolean;\n}\n\nexport type ConditionTokenType = \"variable\" | \"control\" | \"operator\" | \"input\";\n\nexport interface ConditionToken {\n type: ConditionTokenType;\n value: string;\n label?: string;\n sourceNodeId?: string;\n}\n\n/**\n * Type for custom field value types\n */\nexport type CustomFieldValueType =\n | \"text\"\n | \"enum\"\n | \"number\"\n | \"boolean\"\n | \"date\"\n | \"email\"\n | \"address\"\n | \"list\";\n\n/**\n * Display formats supported for date fields (top-level and list columns).\n */\nexport type DateDisplayFormat = \"dd/mm/yyyy\" | \"mm/dd/yyyy\" | \"yyyy-mm-dd\";\n\nexport const DEFAULT_DATE_DISPLAY_FORMAT: DateDisplayFormat = \"dd/mm/yyyy\";\n\n/** Un cas de la règle : une option du pilote → un regex. */\nexport interface ListColumnRegexCase {\n value: string; // valeur exacte d'une option du pilote\n regex: string; // source JS sans slashes ; vide = pas de contrainte\n errorMessage?: string; // message spécifique à ce cas\n}\n\n/** Regex conditionnelle pilotée par une autre colonne enum de la même ligne. */\nexport interface ListColumnRegexRules {\n /** Builder-only explicit opt-out for uncovered text options. */\n allowUnconstrained?: boolean;\n sourceColumn: string; // label de la colonne enum pilote\n cases: ListColumnRegexCase[]; // une entrée par option couverte\n}\n\n/**\n * Column definition for a list-type custom field\n */\nexport interface ListColumn {\n label: string;\n type: \"text\" | \"enum\" | \"date\" | \"email\";\n options?: string[]; // required when type === 'enum'\n placeholder?: string; // text/email/date — shown to the end user\n regex?: string; // text/email — JS regex source (without slashes)\n regexErrorMessage?: string; // text/email — message displayed when regex fails\n regexRules?: ListColumnRegexRules; // text/email — conditional regex rules\n dateFormat?: DateDisplayFormat; // date — display format expected\n}\n\n/**\n * Interface for custom field definition\n */\nexport interface CustomField {\n id: string;\n label: string;\n placeholder?: string;\n description?: string;\n valueType: CustomFieldValueType;\n enumOptions?: string[];\n listColumns?: ListColumn[]; // for list type: column definitions\n minRows?: number; // for list type: minimum rows expected\n required?: boolean;\n /** Absent means personal data. Lists are classified as a whole, not per column. */\n containsPersonalData?: boolean;\n regex?: string; // text — JS regex source (without slashes)\n regexErrorMessage?: string; // text — message displayed when regex fails\n dateFormat?: DateDisplayFormat; // date — display format expected\n lockedFromApi?: boolean;\n editableIfMissing?: boolean; // soft lock — éditable si la valeur API est absente\n userInputKey?: string;\n}\n\n/**\n * Interface for session template node\n */\nexport interface SessionTemplateNode {\n id: string;\n type: string;\n title: string;\n description: string;\n informationType?:\n | \"identity\"\n | \"identity-legal\"\n | \"contact\"\n | \"address\"\n | \"nationality\"\n | \"custom\";\n position: {\n x: number;\n y: number;\n };\n options: unknown[];\n selectedOptions: string[];\n requiredDocumentType?: string;\n isRequired: boolean;\n order: number;\n optionalFields?: string[];\n requiredFields?: string[];\n pageTitle?: string;\n pageDescription?: string;\n // Properties for document-collection node type\n allowedDocumentTypes?: Array<{\n id: string;\n name: string;\n /**\n * Optional side information coming from the template.\n * When provided and equals to two (\"two\", 2, \"double\", \"recto-verso\"),\n * consumers should allow uploading two sides (front/back).\n */\n side?: string | number;\n }>;\n allowedAddingMethods?: string[];\n introductionPage?: {\n title?: string;\n description?: string;\n };\n documentSelection?: {\n title?: string;\n description?: string;\n };\n // Start node specific properties\n welcomeTitle?: string;\n welcomeSubtitle?: string;\n welcomeDescription?: string;\n welcomeImage?: string;\n qrCodeTitle?: string;\n qrCodeDescription?: string;\n\n // Legal consent node specific properties\n consentDescription?: string;\n consentDescription2?: string;\n cguUrl?: string;\n privacyPolicyUrl?: string;\n cguLinkLabel?: string;\n privacyLinkLabel?: string;\n checkboxText?: string;\n // Identity control specific properties\n automaticPhotoCapture?: boolean;\n nfcEnabled?: boolean;\n // \"nfcAndApi\" reste accepté pour rétrocompat (parcours legacy) ; à normaliser à la lecture.\n nfcMode?: \"nfcOnly\" | \"nfcOrPhoto\" | \"nfcAndApi\";\n acceptedCountries?: AcceptedCountry[];\n // End node specific properties\n callbackURL?: string | null;\n // Résultat forcé par le nœud `end` (configuré dans le builder). Sert au SDK à\n // afficher la variante « erreur conservée » de l'écran de fin quand la branche\n // fausse d'une condition pointe directement vers un end non_compliant.\n expectedResult?: string;\n // Condition node specific properties\n conditionExpression?: string;\n conditionTokens?: ConditionToken[];\n conditionFalseErrorMessage?: string;\n conditionMaxRetries?: number;\n conditionMaxRetryAction?: \"end-journey\" | \"force-true\";\n // Undefined is treated as \"loop\" by the SDK for legacy templates.\n conditionFalseMode?: \"retry\" | \"loop\";\n\n // External verification specific properties\n targetApi?: \"INSEE\" | \"INPI_RBE\";\n /** INPI_RBE only. Opt-in: retry against the RNA (associations) when the RNE finds nothing. */\n rnaFallbackEnabled?: boolean;\n /**\n * INPI_RBE only. Opt-in: retry against INSEE (Sirene) when the RNE finds\n * nothing. Tried before the RNA fallback when both are enabled.\n */\n enableInseeFallback?: boolean;\n referenceNodeId?: string;\n referenceNodeType?:\n | \"information-input\"\n | \"document-collection\"\n | \"identity-control\";\n referenceField?: \"siren\" | \"siret\";\n referenceVariable?: string;\n // Custom form fields (for information-input with type 'custom')\n customFields?: CustomField[];\n\n // Electronic signature specific properties\n templateId?: string;\n external_id?: string;\n /** Écran affiché après la signature. Valeurs vides : textes standard traduits. */\n signedScreenTitle?: string;\n signedScreenDescription?: string;\n signedScreenDownloadHint?: string;\n fieldMappings?: Array<{\n sourceFieldId: string;\n label: string;\n docusealType: string;\n readonly: boolean;\n role?: string;\n sourceNodeId?: string;\n }>;\n /** If set, the generated PDF from this upstream pdf-generation node will be used as the document to sign */\n sourcePdfNodeId?: string;\n\n // PDF generation node specific properties\n // Note: htmlTemplate is intentionally NOT included — it is server-side only and never sent to the client\n pdfMode?: \"upload\" | \"html-template\";\n sourceNodeIds?: string[];\n\n // retry properties\n allowResubmission: boolean;\n maxResubmissionAttempts?: number;\n\n /**\n * Paramétrable par nœud depuis le journey builder : autorise ou non le\n * bouton \"Poursuivre quand même\" en cas d'échec. S'applique aux nœuds\n * identity-control, document-collection, biometric-capture (selfie/video)\n * et external-verification. Absent/true = comportement actuel inchangé\n * (bouton proposé), false = masqué.\n *\n * Déprécié pour controle-jdi/identity-control quand une sortie \"false\" est\n * câblée : dans ce cas le routage automatique (blockingCodes +\n * maxResubmissionAction) prend le relais et ce bouton disparaît. Reste lu\n * tel quel pour les nœuds legacy sans sortie \"false\" (rétrocompat).\n */\n allowContinueOnFailure?: boolean;\n\n /**\n * Codes JDI exacts considérés comme bloquants pour ce nœud controle-jdi\n * (déclenchent la boucle de resoumission). Absent = DEFAULT_BLOCKING_CODES\n * (utils/jdiCodes.ts) — comportement legacy inchangé. Le code 8.0 est\n * toujours bloquant indépendamment de cette liste.\n */\n blockingCodes?: string[];\n\n /**\n * Action suivie quand les resoumissions sont épuisées sur un code bloquant\n * ET qu'une sortie \"false\" est câblée sur ce nœud controle-jdi (miroir de\n * conditionMaxRetryAction sur le nœud condition). Défaut \"end-journey\".\n */\n maxResubmissionAction?: \"end-journey\" | \"force-true\";\n}\n\n/**\n * Interface for accepted countries\n */\nexport interface AcceptedCountry {\n code: string;\n documents: {\n passport: string[];\n idCard: string[];\n driverLicense: string[];\n residencePermit: string[];\n pinkDriverLicense: string[];\n };\n}\n\n/**\n * Interface for session template edge\n */\nexport interface SessionTemplateEdge {\n id: string;\n source: string;\n target: string;\n sourceHandle?: string;\n targetHandle?: string;\n conditionValue?: string;\n}\n\n/**\n * Interface for platform information\n */\nexport interface PlatformInfo {\n mobile: boolean;\n desktop: boolean;\n backoffice: boolean;\n}\n\n/**\n * Interface for session template\n */\n/** Clé du catalogue d'icônes des écrans de fin (mappée vers lucide-react au rendu). */\nexport type EndScreenIcon =\n | \"thanks\"\n | \"send\"\n | \"mail\"\n | \"check\"\n | \"clock\"\n | \"shield\"\n | \"user\"\n | \"info\";\n\nexport interface EndScreenItem {\n icon: EndScreenIcon;\n text: string;\n}\n\nexport interface EndScreenCase {\n title?: string;\n items: EndScreenItem[];\n}\n\n/** Textes de fin personnalisés (config globale du journey). Vide → fallback standard. */\nexport interface EndScreenConfig {\n compliant?: EndScreenCase;\n nonCompliant?: EndScreenCase;\n}\n\nexport interface SessionTemplate {\n id: string;\n name: string;\n description: string;\n version: string;\n languages: string[];\n nodes: SessionTemplateNode[];\n edges: SessionTemplateEdge[];\n groupId: string;\n userId: string | null;\n created_at: string;\n updated_at: string;\n platforms?: PlatformInfo;\n logo?: string;\n showQRCode?: boolean;\n buttonBgColor?: string;\n buttonTextColor?: string;\n endScreenConfig?: EndScreenConfig;\n}\n\n/**\n * Interface for session data\n */\nexport interface SessionData {\n id: string;\n userId: string | null;\n token: string;\n templateId: string;\n templateKey: string;\n expireTime: number;\n status: string;\n result: Record<string, unknown>;\n landingPage: unknown;\n withSelfie: boolean | null;\n groupId: string | null;\n userInput: Record<string, unknown>;\n contactInfo?: {\n email: string;\n phoneNumber: string;\n };\n callbackURL?: string | null;\n webhookURL: string;\n analysisTemplateId: string | null;\n userAgent: unknown[];\n mobile: boolean;\n analysisId: string | null;\n currentStep?: number;\n nfcStatus?: \"pending\" | \"opened\" | \"completed\" | \"skipped\" | \"failed\";\n createdAt: string;\n updatedAt: string;\n auditTrail: unknown[];\n user: unknown | null;\n analysis: unknown[];\n documents: unknown[];\n template: SessionTemplate;\n retryCounts?: Record<string, number>; // nodeId -> retry count\n}\n\nexport interface ClientInfo {\n ip?: string;\n location?: string;\n device: string;\n browser: string;\n os: string;\n}\n\nexport type ComplementaryMandateOutcome = 'same_signer' | 'new_signer' | 'no_mandate';\nexport interface ComplementaryMandateNode extends SessionTemplateNode {\n type: 'complementary-mandate';\n sourceJourneyId?: string;\n maxAgeMonths?: number;\n excludedInheritedFields?: string[];\n}\n"],"names":[],"mappings":";;AA0EO,IAAM,2BAA2B,GAAsB;;;;"}
|
|
1
|
+
{"version":3,"file":"session.js","sources":["../../../../src/types/session.ts"],"sourcesContent":["import type React from \"react\";\n\nexport interface SessionConfig {\n sessionToken?: string;\n selfie?: boolean;\n requireMobile?: boolean;\n}\n\nexport interface DatakeenSessionProps {\n /** Session credential returned by server-side session creation. Required by secured backends. */\n sessionToken?: string;\n sessionId: string;\n sessionConfig?: SessionConfig;\n apiBaseUrl?: string; // Optional API base URL for dynamic environment configuration\n}\n\nexport interface UseSessionReturn {\n SessionComponent: React.ReactElement;\n}\n\nexport type stepObject = {\n setStep: (step: number, skipHistory?: boolean) => void;\n goBack: () => void;\n /** Retour arrière vers un nœud précis (ex: \"Corriger ma saisie\") :\n * tronque l'historique jusqu'à `targetStep` au lieu de l'empiler. */\n goBackToStep: (targetStep: number) => void;\n goToNextStep: (\n currentNodeId: string,\n template: SessionTemplate,\n handle?: string,\n ) => void;\n /** Avance via le graphe et tronque l'historique au nœud d'arrivée. */\n goToNextStepCommitted: (\n currentNodeId: string,\n template: SessionTemplate,\n handle?: string,\n ) => void;\n step: number;\n canGoBack: boolean;\n};\n\nexport interface ProcessingStep {\n title: string;\n subtitle: string;\n hasError?: boolean;\n}\n\nexport type ConditionTokenType = \"variable\" | \"control\" | \"operator\" | \"input\";\n\nexport interface ConditionToken {\n type: ConditionTokenType;\n value: string;\n label?: string;\n sourceNodeId?: string;\n}\n\n/**\n * Type for custom field value types\n */\nexport type CustomFieldValueType =\n | \"text\"\n | \"enum\"\n | \"number\"\n | \"boolean\"\n | \"date\"\n | \"email\"\n | \"address\"\n | \"list\";\n\n/**\n * Display formats supported for date fields (top-level and list columns).\n */\nexport type DateDisplayFormat = \"dd/mm/yyyy\" | \"mm/dd/yyyy\" | \"yyyy-mm-dd\";\n\nexport const DEFAULT_DATE_DISPLAY_FORMAT: DateDisplayFormat = \"dd/mm/yyyy\";\n\n/** Un cas de la règle : une option du pilote → un regex. */\nexport interface ListColumnRegexCase {\n value: string; // valeur exacte d'une option du pilote\n regex: string; // source JS sans slashes ; vide = pas de contrainte\n errorMessage?: string; // message spécifique à ce cas\n}\n\n/** Regex conditionnelle pilotée par une autre colonne enum de la même ligne. */\nexport interface ListColumnRegexRules {\n /** Builder-only explicit opt-out for uncovered text options. */\n allowUnconstrained?: boolean;\n sourceColumn: string; // label de la colonne enum pilote\n cases: ListColumnRegexCase[]; // une entrée par option couverte\n}\n\n/**\n * Column definition for a list-type custom field\n */\nexport interface ListColumn {\n label: string;\n type: \"text\" | \"enum\" | \"date\" | \"email\";\n options?: string[]; // required when type === 'enum'\n placeholder?: string; // text/email/date — shown to the end user\n regex?: string; // text/email — JS regex source (without slashes)\n regexErrorMessage?: string; // text/email — message displayed when regex fails\n regexRules?: ListColumnRegexRules; // text/email — conditional regex rules\n dateFormat?: DateDisplayFormat; // date — display format expected\n}\n\n/**\n * Interface for custom field definition\n */\nexport interface CustomField {\n id: string;\n label: string;\n placeholder?: string;\n description?: string;\n valueType: CustomFieldValueType;\n enumOptions?: string[];\n listColumns?: ListColumn[]; // for list type: column definitions\n minRows?: number; // for list type: minimum rows expected\n required?: boolean;\n /** Absent means personal data. Lists are classified as a whole, not per column. */\n containsPersonalData?: boolean;\n regex?: string; // text — JS regex source (without slashes)\n regexErrorMessage?: string; // text — message displayed when regex fails\n dateFormat?: DateDisplayFormat; // date — display format expected\n lockedFromApi?: boolean;\n editableIfMissing?: boolean; // soft lock — éditable si la valeur API est absente\n userInputKey?: string;\n}\n\n/**\n * Interface for session template node\n */\nexport interface SessionTemplateNode {\n id: string;\n type: string;\n title: string;\n description: string;\n informationType?:\n | \"identity\"\n | \"identity-legal\"\n | \"contact\"\n | \"address\"\n | \"nationality\"\n | \"custom\";\n position: {\n x: number;\n y: number;\n };\n options: unknown[];\n selectedOptions: string[];\n requiredDocumentType?: string;\n isRequired: boolean;\n order: number;\n optionalFields?: string[];\n requiredFields?: string[];\n pageTitle?: string;\n pageDescription?: string;\n // Properties for document-collection node type\n allowedDocumentTypes?: Array<{\n id: string;\n name: string;\n /**\n * Optional side information coming from the template.\n * When provided and equals to two (\"two\", 2, \"double\", \"recto-verso\"),\n * consumers should allow uploading two sides (front/back).\n */\n side?: string | number;\n }>;\n allowedAddingMethods?: string[];\n introductionPage?: {\n title?: string;\n description?: string;\n };\n documentSelection?: {\n title?: string;\n description?: string;\n };\n // Start node specific properties\n welcomeTitle?: string;\n welcomeSubtitle?: string;\n welcomeDescription?: string;\n welcomeImage?: string;\n qrCodeTitle?: string;\n qrCodeDescription?: string;\n\n // Legal consent node specific properties\n consentDescription?: string;\n consentDescription2?: string;\n cguUrl?: string;\n privacyPolicyUrl?: string;\n cguLinkLabel?: string;\n privacyLinkLabel?: string;\n checkboxText?: string;\n // Identity control specific properties\n automaticPhotoCapture?: boolean;\n nfcEnabled?: boolean;\n // \"nfcAndApi\" reste accepté pour rétrocompat (parcours legacy) ; à normaliser à la lecture.\n nfcMode?: \"nfcOnly\" | \"nfcOrPhoto\" | \"nfcAndApi\";\n iad?: {\n enabled: boolean;\n level?: \"basic\" | \"reinforced\";\n };\n acceptedCountries?: AcceptedCountry[];\n // End node specific properties\n callbackURL?: string | null;\n // Résultat forcé par le nœud `end` (configuré dans le builder). Sert au SDK à\n // afficher la variante « erreur conservée » de l'écran de fin quand la branche\n // fausse d'une condition pointe directement vers un end non_compliant.\n expectedResult?: string;\n // Condition node specific properties\n conditionExpression?: string;\n conditionTokens?: ConditionToken[];\n conditionFalseErrorMessage?: string;\n conditionMaxRetries?: number;\n conditionMaxRetryAction?: \"end-journey\" | \"force-true\";\n // Undefined is treated as \"loop\" by the SDK for legacy templates.\n conditionFalseMode?: \"retry\" | \"loop\";\n\n // External verification specific properties\n targetApi?: \"INSEE\" | \"INPI_RBE\";\n /** INPI_RBE only. Opt-in: retry against the RNA (associations) when the RNE finds nothing. */\n rnaFallbackEnabled?: boolean;\n /**\n * INPI_RBE only. Opt-in: retry against INSEE (Sirene) when the RNE finds\n * nothing. Tried before the RNA fallback when both are enabled.\n */\n enableInseeFallback?: boolean;\n referenceNodeId?: string;\n referenceNodeType?:\n | \"information-input\"\n | \"document-collection\"\n | \"identity-control\";\n referenceField?: \"siren\" | \"siret\";\n referenceVariable?: string;\n // Custom form fields (for information-input with type 'custom')\n customFields?: CustomField[];\n\n // Electronic signature specific properties\n templateId?: string;\n external_id?: string;\n /** Écran affiché après la signature. Valeurs vides : textes standard traduits. */\n signedScreenTitle?: string;\n signedScreenDescription?: string;\n signedScreenDownloadHint?: string;\n fieldMappings?: Array<{\n sourceFieldId: string;\n label: string;\n docusealType: string;\n readonly: boolean;\n role?: string;\n sourceNodeId?: string;\n }>;\n /** If set, the generated PDF from this upstream pdf-generation node will be used as the document to sign */\n sourcePdfNodeId?: string;\n\n // PDF generation node specific properties\n // Note: htmlTemplate is intentionally NOT included — it is server-side only and never sent to the client\n pdfMode?: \"upload\" | \"html-template\";\n sourceNodeIds?: string[];\n\n // retry properties\n allowResubmission: boolean;\n maxResubmissionAttempts?: number;\n\n /**\n * Paramétrable par nœud depuis le journey builder : autorise ou non le\n * bouton \"Poursuivre quand même\" en cas d'échec. S'applique aux nœuds\n * identity-control, document-collection, biometric-capture (selfie/video)\n * et external-verification. Absent/true = comportement actuel inchangé\n * (bouton proposé), false = masqué.\n *\n * Déprécié pour controle-jdi/identity-control quand une sortie \"false\" est\n * câblée : dans ce cas le routage automatique (blockingCodes +\n * maxResubmissionAction) prend le relais et ce bouton disparaît. Reste lu\n * tel quel pour les nœuds legacy sans sortie \"false\" (rétrocompat).\n */\n allowContinueOnFailure?: boolean;\n\n /**\n * Codes JDI exacts considérés comme bloquants pour ce nœud controle-jdi\n * (déclenchent la boucle de resoumission). Absent = DEFAULT_BLOCKING_CODES\n * (utils/jdiCodes.ts) — comportement legacy inchangé. Le code 8.0 est\n * toujours bloquant indépendamment de cette liste.\n */\n blockingCodes?: string[];\n\n /**\n * Action suivie quand les resoumissions sont épuisées sur un code bloquant\n * ET qu'une sortie \"false\" est câblée sur ce nœud controle-jdi (miroir de\n * conditionMaxRetryAction sur le nœud condition). Défaut \"end-journey\".\n */\n maxResubmissionAction?: \"end-journey\" | \"force-true\";\n}\n\n/**\n * Interface for accepted countries\n */\nexport interface AcceptedCountry {\n code: string;\n documents: {\n passport: string[];\n idCard: string[];\n driverLicense: string[];\n residencePermit: string[];\n pinkDriverLicense: string[];\n };\n}\n\n/**\n * Interface for session template edge\n */\nexport interface SessionTemplateEdge {\n id: string;\n source: string;\n target: string;\n sourceHandle?: string;\n targetHandle?: string;\n conditionValue?: string;\n}\n\n/**\n * Interface for platform information\n */\nexport interface PlatformInfo {\n mobile: boolean;\n desktop: boolean;\n backoffice: boolean;\n}\n\n/**\n * Interface for session template\n */\n/** Clé du catalogue d'icônes des écrans de fin (mappée vers lucide-react au rendu). */\nexport type EndScreenIcon =\n | \"thanks\"\n | \"send\"\n | \"mail\"\n | \"check\"\n | \"clock\"\n | \"shield\"\n | \"user\"\n | \"info\";\n\nexport interface EndScreenItem {\n icon: EndScreenIcon;\n text: string;\n}\n\nexport interface EndScreenCase {\n title?: string;\n items: EndScreenItem[];\n}\n\n/** Textes de fin personnalisés (config globale du journey). Vide → fallback standard. */\nexport interface EndScreenConfig {\n compliant?: EndScreenCase;\n nonCompliant?: EndScreenCase;\n}\n\nexport interface SessionTemplate {\n id: string;\n name: string;\n description: string;\n version: string;\n languages: string[];\n nodes: SessionTemplateNode[];\n edges: SessionTemplateEdge[];\n groupId: string;\n userId: string | null;\n created_at: string;\n updated_at: string;\n platforms?: PlatformInfo;\n logo?: string;\n showQRCode?: boolean;\n buttonBgColor?: string;\n buttonTextColor?: string;\n endScreenConfig?: EndScreenConfig;\n}\n\n/**\n * Interface for session data\n */\nexport interface SessionData {\n id: string;\n userId: string | null;\n token: string;\n templateId: string;\n templateKey: string;\n expireTime: number;\n status: string;\n result: Record<string, unknown>;\n landingPage: unknown;\n withSelfie: boolean | null;\n groupId: string | null;\n userInput: Record<string, unknown>;\n contactInfo?: {\n email: string;\n phoneNumber: string;\n };\n callbackURL?: string | null;\n webhookURL: string;\n analysisTemplateId: string | null;\n userAgent: unknown[];\n mobile: boolean;\n analysisId: string | null;\n currentStep?: number;\n nfcStatus?: \"pending\" | \"opened\" | \"completed\" | \"skipped\" | \"failed\";\n createdAt: string;\n updatedAt: string;\n auditTrail: unknown[];\n user: unknown | null;\n analysis: unknown[];\n documents: unknown[];\n template: SessionTemplate;\n retryCounts?: Record<string, number>; // nodeId -> retry count\n}\n\nexport interface ClientInfo {\n ip?: string;\n location?: string;\n device: string;\n browser: string;\n os: string;\n}\n\nexport type ComplementaryMandateOutcome = 'same_signer' | 'new_signer' | 'no_mandate';\nexport interface ComplementaryMandateNode extends SessionTemplateNode {\n type: 'complementary-mandate';\n sourceJourneyId?: string;\n maxAgeMonths?: number;\n excludedInheritedFields?: string[];\n}\n"],"names":[],"mappings":";;AA0EO,IAAM,2BAA2B,GAAsB;;;;"}
|
|
@@ -98,7 +98,7 @@ var JDIProcessing = memo(function (_a) {
|
|
|
98
98
|
return [4 /*yield*/, convertPdfToPng(frontImage)];
|
|
99
99
|
case 2:
|
|
100
100
|
convertedFile = _a.sent();
|
|
101
|
-
return [4 /*yield*/, uploadConvertedIdCardImage(sessionId, convertedFile)];
|
|
101
|
+
return [4 /*yield*/, uploadConvertedIdCardImage(sessionId, convertedFile, nodeId)];
|
|
102
102
|
case 3:
|
|
103
103
|
_a.sent();
|
|
104
104
|
return [3 /*break*/, 9];
|
|
@@ -107,14 +107,14 @@ var JDIProcessing = memo(function (_a) {
|
|
|
107
107
|
return [4 /*yield*/, convertJpegToPng(frontImage)];
|
|
108
108
|
case 5:
|
|
109
109
|
convertedFile = _a.sent();
|
|
110
|
-
return [4 /*yield*/, uploadConvertedIdCardImage(sessionId, convertedFile)];
|
|
110
|
+
return [4 /*yield*/, uploadConvertedIdCardImage(sessionId, convertedFile, nodeId)];
|
|
111
111
|
case 6:
|
|
112
112
|
_a.sent();
|
|
113
113
|
return [3 /*break*/, 9];
|
|
114
114
|
case 7:
|
|
115
115
|
if (!isPng(frontImage)) return [3 /*break*/, 9];
|
|
116
116
|
file = dataUrlToFile(frontImage, "converted_id_card.png");
|
|
117
|
-
return [4 /*yield*/, uploadConvertedIdCardImage(sessionId, file)];
|
|
117
|
+
return [4 /*yield*/, uploadConvertedIdCardImage(sessionId, file, nodeId)];
|
|
118
118
|
case 8:
|
|
119
119
|
_a.sent();
|
|
120
120
|
_a.label = 9;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"JDIProcessing.js","sources":["../../../../../src/components/jdi/JDIProcessing.tsx"],"sourcesContent":["import { useEffect, useRef, useState, useMemo, useCallback, memo } from \"react\";\nimport Title from \"../ui/Title\";\nimport Subtitle from \"../ui/Subtitle\";\nimport type { onUploadFiles } from \"../../types/uploadFiles\";\nimport type { ProcessingStep } from \"../../types/session\";\nimport type { Prediction } from \"../../utils/apiAnalysis\";\nimport type { JDIProcessingResult } from \"./types\";\nimport {\n analyzeFiles,\n uploadConvertedIdCardImage,\n} from \"../../services/analysis\";\nimport { getActiveSessionId } from \"../../services/sessionMemoryStore\";\nimport {\n convertPdfToPng,\n convertJpegToPng,\n dataUrlToFile,\n isPdf,\n isJpeg,\n isPng,\n} from \"../../utils/imageConverter\";\nimport { useI18n } from \"../../hooks/useI18n\";\nimport { requiresTwoSides } from \"../../utils/documentLabels\";\nimport {\n isS3UploadNotConfirmedError,\n isQuotaExceededError,\n QUOTA_EXCEEDED_CODE,\n} from \"../../utils/analysisErrors\";\nimport { isBlockingCode } from \"../../utils/jdiCodes\";\n\ninterface JDIProcessingProps {\n onProcessingComplete: (\n success: boolean,\n retryCount?: number,\n analysisData?: Prediction[] | null,\n blockContinue?: boolean,\n ) => void;\n documentType: string;\n fileUploaded: onUploadFiles | null; // Fichiers uploadés\n documentTypeId: string; // ID du type de document (jdd, income-proof, etc.)\n retryCount?: number; // Nombre de tentatives de retry déjà effectuées\n documentTemplateId?: string; // ID du modèle de document associé\n nodeId: string; // ID du nœud associé\n /** Codes JDI exacts considérés comme bloquants pour ce nœud (cf. node.blockingCodes). Absent = liste par défaut. */\n blockingCodes?: string[];\n}\n\ninterface AnalysisProgress {\n progress: number;\n currentStep: string;\n message: string;\n}\n\n// Fonction pour obtenir les étapes de traitement traduites\nconst getProcessingSteps = (t: (key: string) => string): ProcessingStep[] => [\n {\n title: t(\"jdi.processing.steps.document_reception.title\"),\n subtitle: t(\"jdi.processing.steps.document_reception.subtitle\"),\n hasError: false,\n },\n {\n title: t(\"jdi.processing.steps.quality_analysis.title\"),\n subtitle: t(\"jdi.processing.steps.quality_analysis.subtitle\"),\n hasError: false,\n },\n {\n title: t(\"jdi.processing.steps.data_extraction.title\"),\n subtitle: t(\"jdi.processing.steps.data_extraction.subtitle\"),\n hasError: false,\n },\n {\n title: t(\"jdi.processing.steps.final_verification.title\"),\n subtitle: t(\"jdi.processing.steps.final_verification.subtitle\"),\n hasError: false,\n },\n];\n\nconst JDIProcessing = memo(\n ({\n onProcessingComplete,\n documentType,\n fileUploaded,\n documentTypeId,\n retryCount = 0,\n documentTemplateId,\n nodeId,\n blockingCodes,\n }: JDIProcessingProps) => {\n const { t } = useI18n();\n const [isProcessing, setIsProcessing] = useState(false);\n const [currentStep, setCurrentStep] = useState(0);\n const [processingSteps, setProcessingSteps] = useState<ProcessingStep[]>(\n () => getProcessingSteps(t),\n );\n const [isComplete, setIsComplete] = useState(false);\n const [analysisResult, setAnalysisResult] =\n useState<JDIProcessingResult | null>(null);\n const [analysisProgress, setAnalysisProgress] = useState<AnalysisProgress>({\n progress: 0,\n currentStep: \"\",\n message: \"\",\n });\n\n const processingStartedRef = useRef(false);\n const processedFilesRef = useRef<string | null>(null);\n\n // Créer une clé stable pour les fichiers uploadés\n const filesKey = useMemo(() => {\n if (!fileUploaded) return null;\n return `${fileUploaded.front?.substring(0, 50) || \"no-front\"}-${\n fileUploaded.back?.substring(0, 50) || \"no-back\"\n }`;\n }, [fileUploaded]);\n\n // Callback stable pour onProcessingComplete\n const stableOnProcessingComplete = useCallback(\n (\n success: boolean,\n retryCount?: number,\n analysisData?: Prediction[] | null,\n blockContinue?: boolean,\n ) => {\n if (blockContinue === true) {\n onProcessingComplete(success, retryCount, analysisData, true);\n } else {\n onProcessingComplete(success, retryCount, analysisData);\n }\n },\n [onProcessingComplete],\n );\n\n useEffect(() => {\n // Empêcher les appels multiples\n if (\n !fileUploaded ||\n !filesKey ||\n isProcessing ||\n processingStartedRef.current\n ) {\n return;\n }\n\n const sessionId = getActiveSessionId();\n if (!sessionId) {\n stableOnProcessingComplete(false);\n return;\n }\n\n // Vérifier si on a déjà traité ces mêmes fichiers\n if (processedFilesRef.current === filesKey) {\n return;\n }\n\n // Fonction pour gérer la conversion et l'upload des fichiers\n const handleFileConversionAndUpload = async (\n sessionId: string,\n fileUploaded: onUploadFiles,\n ) => {\n const frontImage = fileUploaded.front;\n if (!frontImage) return;\n\n try {\n if (isPdf(frontImage)) {\n const convertedFile = await convertPdfToPng(frontImage);\n await uploadConvertedIdCardImage(sessionId, convertedFile);\n } else if (isJpeg(frontImage)) {\n const convertedFile = await convertJpegToPng(frontImage);\n await uploadConvertedIdCardImage(sessionId, convertedFile);\n } else if (isPng(frontImage)) {\n const file = dataUrlToFile(frontImage, \"converted_id_card.png\");\n await uploadConvertedIdCardImage(sessionId, file);\n }\n } catch (error) {\n console.error(\"Erreur lors de la conversion/upload:\", error);\n // Ne pas bloquer le processus, continuer avec l'analyse normale\n }\n };\n\n const processFiles = async () => {\n try {\n // Marquer le début du traitement\n setIsProcessing(true);\n processingStartedRef.current = true;\n processedFilesRef.current = filesKey;\n\n // Animation des étapes avec appel API réel à la fin\n for (let i = 0; i < processingSteps.length; i++) {\n setCurrentStep(i);\n\n if (i < processingSteps.length - 1) {\n // Délai entre les étapes (sauf la dernière)\n await new Promise((resolve) => setTimeout(resolve, 800));\n } else {\n // Dernière étape : conversion et upload si nécessaire, puis appel API réel\n await handleFileConversionAndUpload(sessionId, fileUploaded);\n\n const response = await analyzeFiles(\n sessionId,\n nodeId,\n fileUploaded,\n documentTemplateId || \"\",\n {\n save: false, // don't save to session yet\n incrementAnalysis: false, // don't auto-progress session\n documentTypeKey: documentType,\n requiresTwoSides: requiresTwoSides(documentType),\n enablePolling: true, // Enable polling for progress\n pollingOptions: {\n interval: 2000, // Poll every 2 seconds (backend optimized timing)\n maxAttempts: 30, // 30 * 2s = max 60s polling duration\n timeout: 600000,\n onProgress: (status) => {\n // Update analysis progress state for display\n setAnalysisProgress({\n progress: status.progress,\n currentStep: status.currentStep,\n message: status.message,\n });\n\n // Update UI based on progress percentage\n // 50% = Analyzing (steps 0-2)\n // 100% = Completed (step 3)\n if (status.progress === 50) {\n // Analysis in progress - show steps 0-2 progressively\n const elapsed =\n Date.now() -\n (Date.parse(status.startedAt || \"\") || Date.now());\n const elapsedSeconds = elapsed / 1000;\n\n // Progress through first 3 steps based on elapsed time\n if (elapsedSeconds < 3) {\n setCurrentStep((prev) => Math.max(prev, 0));\n } else if (elapsedSeconds < 6) {\n setCurrentStep((prev) => Math.max(prev, 1));\n } else {\n setCurrentStep((prev) => Math.max(prev, 2));\n }\n } else if (status.progress === 100) {\n // Analysis complete - move to final step\n setCurrentStep(processingSteps.length - 1);\n }\n },\n onComplete: (status) => {\n // Update final progress state\n setAnalysisProgress({\n progress: status.progress,\n currentStep: status.currentStep,\n message: status.message,\n });\n\n // Ensure we're at the final step\n setCurrentStep(processingSteps.length - 1);\n\n // Mark the final step based on analysis result\n const isFailed =\n status.currentStep === \"failed\" ||\n status.currentStep === \"error\";\n\n if (isFailed) {\n setProcessingSteps((prev) =>\n prev.map((step, index) =>\n index === processingSteps.length - 1\n ? { ...step, hasError: true }\n : step,\n ),\n );\n }\n },\n onFailed: (status, error) => {\n console.error(\n \"❌ [JDIProcessing] Analysis polling failed:\",\n error,\n );\n\n // Update error state\n setAnalysisProgress({\n progress: 100,\n currentStep: \"failed\",\n message: `Analysis failed: ${error}`,\n });\n\n // Mark current step as error\n setProcessingSteps((prev) =>\n prev.map((step, index) =>\n index === currentStep\n ? { ...step, hasError: true }\n : step,\n ),\n );\n },\n },\n },\n );\n\n const extractedCode = String(response.code);\n const codeName = response?.codeName;\n const codeDescription = response?.codeDescription;\n const mismatchDetails = response?.mismatchDetails;\n\n // Construct predictions array from the response\n const predictions: Prediction[] = [];\n if (extractedCode && codeName) {\n predictions.push({\n code: extractedCode,\n codeName: codeName,\n codeDescription: codeDescription || \"\",\n type: \"document\",\n ...(mismatchDetails ? { mismatchDetails } : {}),\n });\n }\n\n // Determine success based on the node's configured blocking codes\n // (blockingCodes absent → DEFAULT_BLOCKING_CODES, legacy behavior\n // unchanged). Code 8.x (specimen) is always blocking.\n const isSuccess = !isBlockingCode(extractedCode, blockingCodes);\n const canRetry = isSuccess === false;\n\n setAnalysisResult({\n success: isSuccess,\n code: extractedCode,\n canRetry,\n data: response,\n predictions: predictions,\n });\n\n // Mark the final step based on analysis result\n if (!isSuccess) {\n setProcessingSteps((prev) =>\n prev.map((step, index) =>\n index === processingSteps.length - 1\n ? { ...step, hasError: true }\n : step,\n ),\n );\n }\n\n // délai pour voir le résultat\n await new Promise((resolve) => setTimeout(resolve, 500));\n }\n }\n\n setCurrentStep(processingSteps.length);\n setIsComplete(true);\n } catch (error) {\n console.error(\"❌ Erreur lors de l'analyse des fichiers:\", error);\n\n // Determine which step failed\n let failedStepIndex = currentStep;\n\n // If error occurred during analysis, mark the final verification step as failed\n if (currentStep >= processingSteps.length - 1) {\n failedStepIndex = processingSteps.length - 1;\n }\n\n // Mark the failed step as error\n setProcessingSteps((prev) =>\n prev.map((step, index) =>\n index === failedStepIndex ? { ...step, hasError: true } : step,\n ),\n );\n\n // Move to the failed step to show error\n setCurrentStep(failedStepIndex);\n\n // Determine if retry is allowed based on error type\n const errorMessage =\n error instanceof Error ? error.message : String(error);\n const isNetworkError =\n errorMessage.includes(\"network\") ||\n errorMessage.includes(\"CORS\") ||\n errorMessage.includes(\"timeout\");\n const isUploadNotConfirmed = isS3UploadNotConfirmedError(error);\n const isQuotaExceeded = isQuotaExceededError(error);\n const apiError = error as { code?: string; message?: string };\n\n setAnalysisResult({\n success: false,\n data: null,\n // Propage le code/message QUOTA_EXCEEDED pour que l'écran\n // d'erreur puisse afficher un message dédié (limité au cas\n // quota : les autres erreurs gardent leur comportement existant).\n predictions: isQuotaExceeded\n ? [\n {\n code: QUOTA_EXCEEDED_CODE,\n codeName: QUOTA_EXCEEDED_CODE,\n codeDescription: apiError?.message || \"\",\n type: \"document\",\n },\n ]\n : undefined,\n canRetry: isNetworkError || isUploadNotConfirmed || isQuotaExceeded,\n blockContinue: isUploadNotConfirmed,\n });\n setIsComplete(true);\n } finally {\n setIsProcessing(false);\n }\n };\n\n processFiles();\n }, [\n fileUploaded,\n filesKey,\n documentTypeId,\n documentTemplateId,\n documentType,\n isProcessing,\n stableOnProcessingComplete,\n processingSteps.length,\n currentStep,\n blockingCodes,\n ]);\n\n // Auto-complete when analysis is done\n useEffect(() => {\n if (isComplete && analysisResult) {\n setTimeout(() => {\n const allowRetry =\n analysisResult.success || analysisResult.canRetry === true;\n // Pass predictions array instead of raw data\n stableOnProcessingComplete(\n analysisResult.success,\n allowRetry ? retryCount : undefined,\n analysisResult.predictions || null,\n analysisResult.blockContinue,\n );\n }, 1000);\n }\n }, [isComplete, analysisResult, stableOnProcessingComplete, retryCount]);\n\n return (\n <div className=\"flex flex-col justify-between h-full w-full\">\n {/* Main content area */}\n <div className=\"flex-1 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 {/* Header */}\n <div className=\"text-center space-y-4\">\n <Title className=\"text-xl md:text-2xl lg:text-3xl\">\n {t(\"jdi.processing.title\")}\n </Title>\n <Subtitle className=\"text-sm text-gray-600 leading-relaxed\">\n {t(\"jdi.processing.subtitle\", {\n document: t(\"documentTypes.\" + documentType),\n })}\n </Subtitle>\n </div>\n\n {/* Processing steps with status indicators */}\n <div className=\"w-full flex justify-center\">\n <div className=\"space-y-5\">\n {processingSteps.map((step, index: number) => (\n <div key={index} className=\"flex items-start\">\n {/* Status indicator */}\n <div className=\"mr-4 mt-1 flex-shrink-0\">\n {index < currentStep ? (\n step.hasError ? (\n // Error indicator - Red X\n <div className=\"flex items-center justify-center w-6 h-6 rounded-full bg-red-500 text-white text-xs\">\n ✕\n </div>\n ) : (\n // Success indicator - Green checkmark\n <div className=\"flex items-center justify-center w-6 h-6 rounded-full bg-[#11E5C5] text-white text-xs\">\n ✓\n </div>\n )\n ) : index === currentStep ? (\n // Loading spinner only for the current step\n <div className=\"w-6 h-6 rounded-full border-2 border-t-[#11E5C5] border-r-[#11E5C5] border-b-[#11E5C5] border-l-transparent animate-spin\"></div>\n ) : (\n // Empty circle for future steps\n <div className=\"w-6 h-6 rounded-full border-2 border-gray-300\"></div>\n )}\n </div>\n\n {/* Step content */}\n <div className=\"flex-1 min-w-0\">\n <p className=\"font-medium text-[#3C3C40] text-sm\">\n {step.title}\n </p>\n <p className=\"text-xs text-gray-500 mt-1\">\n {step.subtitle}\n </p>\n </div>\n </div>\n ))}\n </div>\n </div>\n </div>\n </div>\n </div>\n );\n },\n);\n\nJDIProcessing.displayName = \"JDIProcessing\";\n\nexport default JDIProcessing;\n"],"names":["_jsx","_jsxs"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"JDIProcessing.js","sources":["../../../../../src/components/jdi/JDIProcessing.tsx"],"sourcesContent":["import { useEffect, useRef, useState, useMemo, useCallback, memo } from \"react\";\nimport Title from \"../ui/Title\";\nimport Subtitle from \"../ui/Subtitle\";\nimport type { onUploadFiles } from \"../../types/uploadFiles\";\nimport type { ProcessingStep } from \"../../types/session\";\nimport type { Prediction } from \"../../utils/apiAnalysis\";\nimport type { JDIProcessingResult } from \"./types\";\nimport {\n analyzeFiles,\n uploadConvertedIdCardImage,\n} from \"../../services/analysis\";\nimport { getActiveSessionId } from \"../../services/sessionMemoryStore\";\nimport {\n convertPdfToPng,\n convertJpegToPng,\n dataUrlToFile,\n isPdf,\n isJpeg,\n isPng,\n} from \"../../utils/imageConverter\";\nimport { useI18n } from \"../../hooks/useI18n\";\nimport { requiresTwoSides } from \"../../utils/documentLabels\";\nimport {\n isS3UploadNotConfirmedError,\n isQuotaExceededError,\n QUOTA_EXCEEDED_CODE,\n} from \"../../utils/analysisErrors\";\nimport { isBlockingCode } from \"../../utils/jdiCodes\";\n\ninterface JDIProcessingProps {\n onProcessingComplete: (\n success: boolean,\n retryCount?: number,\n analysisData?: Prediction[] | null,\n blockContinue?: boolean,\n ) => void;\n documentType: string;\n fileUploaded: onUploadFiles | null; // Fichiers uploadés\n documentTypeId: string; // ID du type de document (jdd, income-proof, etc.)\n retryCount?: number; // Nombre de tentatives de retry déjà effectuées\n documentTemplateId?: string; // ID du modèle de document associé\n nodeId: string; // ID du nœud associé\n /** Codes JDI exacts considérés comme bloquants pour ce nœud (cf. node.blockingCodes). Absent = liste par défaut. */\n blockingCodes?: string[];\n}\n\ninterface AnalysisProgress {\n progress: number;\n currentStep: string;\n message: string;\n}\n\n// Fonction pour obtenir les étapes de traitement traduites\nconst getProcessingSteps = (t: (key: string) => string): ProcessingStep[] => [\n {\n title: t(\"jdi.processing.steps.document_reception.title\"),\n subtitle: t(\"jdi.processing.steps.document_reception.subtitle\"),\n hasError: false,\n },\n {\n title: t(\"jdi.processing.steps.quality_analysis.title\"),\n subtitle: t(\"jdi.processing.steps.quality_analysis.subtitle\"),\n hasError: false,\n },\n {\n title: t(\"jdi.processing.steps.data_extraction.title\"),\n subtitle: t(\"jdi.processing.steps.data_extraction.subtitle\"),\n hasError: false,\n },\n {\n title: t(\"jdi.processing.steps.final_verification.title\"),\n subtitle: t(\"jdi.processing.steps.final_verification.subtitle\"),\n hasError: false,\n },\n];\n\nconst JDIProcessing = memo(\n ({\n onProcessingComplete,\n documentType,\n fileUploaded,\n documentTypeId,\n retryCount = 0,\n documentTemplateId,\n nodeId,\n blockingCodes,\n }: JDIProcessingProps) => {\n const { t } = useI18n();\n const [isProcessing, setIsProcessing] = useState(false);\n const [currentStep, setCurrentStep] = useState(0);\n const [processingSteps, setProcessingSteps] = useState<ProcessingStep[]>(\n () => getProcessingSteps(t),\n );\n const [isComplete, setIsComplete] = useState(false);\n const [analysisResult, setAnalysisResult] =\n useState<JDIProcessingResult | null>(null);\n const [analysisProgress, setAnalysisProgress] = useState<AnalysisProgress>({\n progress: 0,\n currentStep: \"\",\n message: \"\",\n });\n\n const processingStartedRef = useRef(false);\n const processedFilesRef = useRef<string | null>(null);\n\n // Créer une clé stable pour les fichiers uploadés\n const filesKey = useMemo(() => {\n if (!fileUploaded) return null;\n return `${fileUploaded.front?.substring(0, 50) || \"no-front\"}-${\n fileUploaded.back?.substring(0, 50) || \"no-back\"\n }`;\n }, [fileUploaded]);\n\n // Callback stable pour onProcessingComplete\n const stableOnProcessingComplete = useCallback(\n (\n success: boolean,\n retryCount?: number,\n analysisData?: Prediction[] | null,\n blockContinue?: boolean,\n ) => {\n if (blockContinue === true) {\n onProcessingComplete(success, retryCount, analysisData, true);\n } else {\n onProcessingComplete(success, retryCount, analysisData);\n }\n },\n [onProcessingComplete],\n );\n\n useEffect(() => {\n // Empêcher les appels multiples\n if (\n !fileUploaded ||\n !filesKey ||\n isProcessing ||\n processingStartedRef.current\n ) {\n return;\n }\n\n const sessionId = getActiveSessionId();\n if (!sessionId) {\n stableOnProcessingComplete(false);\n return;\n }\n\n // Vérifier si on a déjà traité ces mêmes fichiers\n if (processedFilesRef.current === filesKey) {\n return;\n }\n\n // Fonction pour gérer la conversion et l'upload des fichiers\n const handleFileConversionAndUpload = async (\n sessionId: string,\n fileUploaded: onUploadFiles,\n ) => {\n const frontImage = fileUploaded.front;\n if (!frontImage) return;\n\n try {\n if (isPdf(frontImage)) {\n const convertedFile = await convertPdfToPng(frontImage);\n await uploadConvertedIdCardImage(sessionId, convertedFile, nodeId);\n } else if (isJpeg(frontImage)) {\n const convertedFile = await convertJpegToPng(frontImage);\n await uploadConvertedIdCardImage(sessionId, convertedFile, nodeId);\n } else if (isPng(frontImage)) {\n const file = dataUrlToFile(frontImage, \"converted_id_card.png\");\n await uploadConvertedIdCardImage(sessionId, file, nodeId);\n }\n } catch (error) {\n console.error(\"Erreur lors de la conversion/upload:\", error);\n // Ne pas bloquer le processus, continuer avec l'analyse normale\n }\n };\n\n const processFiles = async () => {\n try {\n // Marquer le début du traitement\n setIsProcessing(true);\n processingStartedRef.current = true;\n processedFilesRef.current = filesKey;\n\n // Animation des étapes avec appel API réel à la fin\n for (let i = 0; i < processingSteps.length; i++) {\n setCurrentStep(i);\n\n if (i < processingSteps.length - 1) {\n // Délai entre les étapes (sauf la dernière)\n await new Promise((resolve) => setTimeout(resolve, 800));\n } else {\n // Dernière étape : conversion et upload si nécessaire, puis appel API réel\n await handleFileConversionAndUpload(sessionId, fileUploaded);\n\n const response = await analyzeFiles(\n sessionId,\n nodeId,\n fileUploaded,\n documentTemplateId || \"\",\n {\n save: false, // don't save to session yet\n incrementAnalysis: false, // don't auto-progress session\n documentTypeKey: documentType,\n requiresTwoSides: requiresTwoSides(documentType),\n enablePolling: true, // Enable polling for progress\n pollingOptions: {\n interval: 2000, // Poll every 2 seconds (backend optimized timing)\n maxAttempts: 30, // 30 * 2s = max 60s polling duration\n timeout: 600000,\n onProgress: (status) => {\n // Update analysis progress state for display\n setAnalysisProgress({\n progress: status.progress,\n currentStep: status.currentStep,\n message: status.message,\n });\n\n // Update UI based on progress percentage\n // 50% = Analyzing (steps 0-2)\n // 100% = Completed (step 3)\n if (status.progress === 50) {\n // Analysis in progress - show steps 0-2 progressively\n const elapsed =\n Date.now() -\n (Date.parse(status.startedAt || \"\") || Date.now());\n const elapsedSeconds = elapsed / 1000;\n\n // Progress through first 3 steps based on elapsed time\n if (elapsedSeconds < 3) {\n setCurrentStep((prev) => Math.max(prev, 0));\n } else if (elapsedSeconds < 6) {\n setCurrentStep((prev) => Math.max(prev, 1));\n } else {\n setCurrentStep((prev) => Math.max(prev, 2));\n }\n } else if (status.progress === 100) {\n // Analysis complete - move to final step\n setCurrentStep(processingSteps.length - 1);\n }\n },\n onComplete: (status) => {\n // Update final progress state\n setAnalysisProgress({\n progress: status.progress,\n currentStep: status.currentStep,\n message: status.message,\n });\n\n // Ensure we're at the final step\n setCurrentStep(processingSteps.length - 1);\n\n // Mark the final step based on analysis result\n const isFailed =\n status.currentStep === \"failed\" ||\n status.currentStep === \"error\";\n\n if (isFailed) {\n setProcessingSteps((prev) =>\n prev.map((step, index) =>\n index === processingSteps.length - 1\n ? { ...step, hasError: true }\n : step,\n ),\n );\n }\n },\n onFailed: (status, error) => {\n console.error(\n \"❌ [JDIProcessing] Analysis polling failed:\",\n error,\n );\n\n // Update error state\n setAnalysisProgress({\n progress: 100,\n currentStep: \"failed\",\n message: `Analysis failed: ${error}`,\n });\n\n // Mark current step as error\n setProcessingSteps((prev) =>\n prev.map((step, index) =>\n index === currentStep\n ? { ...step, hasError: true }\n : step,\n ),\n );\n },\n },\n },\n );\n\n const extractedCode = String(response.code);\n const codeName = response?.codeName;\n const codeDescription = response?.codeDescription;\n const mismatchDetails = response?.mismatchDetails;\n\n // Construct predictions array from the response\n const predictions: Prediction[] = [];\n if (extractedCode && codeName) {\n predictions.push({\n code: extractedCode,\n codeName: codeName,\n codeDescription: codeDescription || \"\",\n type: \"document\",\n ...(mismatchDetails ? { mismatchDetails } : {}),\n });\n }\n\n // Determine success based on the node's configured blocking codes\n // (blockingCodes absent → DEFAULT_BLOCKING_CODES, legacy behavior\n // unchanged). Code 8.x (specimen) is always blocking.\n const isSuccess = !isBlockingCode(extractedCode, blockingCodes);\n const canRetry = isSuccess === false;\n\n setAnalysisResult({\n success: isSuccess,\n code: extractedCode,\n canRetry,\n data: response,\n predictions: predictions,\n });\n\n // Mark the final step based on analysis result\n if (!isSuccess) {\n setProcessingSteps((prev) =>\n prev.map((step, index) =>\n index === processingSteps.length - 1\n ? { ...step, hasError: true }\n : step,\n ),\n );\n }\n\n // délai pour voir le résultat\n await new Promise((resolve) => setTimeout(resolve, 500));\n }\n }\n\n setCurrentStep(processingSteps.length);\n setIsComplete(true);\n } catch (error) {\n console.error(\"❌ Erreur lors de l'analyse des fichiers:\", error);\n\n // Determine which step failed\n let failedStepIndex = currentStep;\n\n // If error occurred during analysis, mark the final verification step as failed\n if (currentStep >= processingSteps.length - 1) {\n failedStepIndex = processingSteps.length - 1;\n }\n\n // Mark the failed step as error\n setProcessingSteps((prev) =>\n prev.map((step, index) =>\n index === failedStepIndex ? { ...step, hasError: true } : step,\n ),\n );\n\n // Move to the failed step to show error\n setCurrentStep(failedStepIndex);\n\n // Determine if retry is allowed based on error type\n const errorMessage =\n error instanceof Error ? error.message : String(error);\n const isNetworkError =\n errorMessage.includes(\"network\") ||\n errorMessage.includes(\"CORS\") ||\n errorMessage.includes(\"timeout\");\n const isUploadNotConfirmed = isS3UploadNotConfirmedError(error);\n const isQuotaExceeded = isQuotaExceededError(error);\n const apiError = error as { code?: string; message?: string };\n\n setAnalysisResult({\n success: false,\n data: null,\n // Propage le code/message QUOTA_EXCEEDED pour que l'écran\n // d'erreur puisse afficher un message dédié (limité au cas\n // quota : les autres erreurs gardent leur comportement existant).\n predictions: isQuotaExceeded\n ? [\n {\n code: QUOTA_EXCEEDED_CODE,\n codeName: QUOTA_EXCEEDED_CODE,\n codeDescription: apiError?.message || \"\",\n type: \"document\",\n },\n ]\n : undefined,\n canRetry: isNetworkError || isUploadNotConfirmed || isQuotaExceeded,\n blockContinue: isUploadNotConfirmed,\n });\n setIsComplete(true);\n } finally {\n setIsProcessing(false);\n }\n };\n\n processFiles();\n }, [\n fileUploaded,\n filesKey,\n documentTypeId,\n documentTemplateId,\n documentType,\n isProcessing,\n stableOnProcessingComplete,\n processingSteps.length,\n currentStep,\n blockingCodes,\n ]);\n\n // Auto-complete when analysis is done\n useEffect(() => {\n if (isComplete && analysisResult) {\n setTimeout(() => {\n const allowRetry =\n analysisResult.success || analysisResult.canRetry === true;\n // Pass predictions array instead of raw data\n stableOnProcessingComplete(\n analysisResult.success,\n allowRetry ? retryCount : undefined,\n analysisResult.predictions || null,\n analysisResult.blockContinue,\n );\n }, 1000);\n }\n }, [isComplete, analysisResult, stableOnProcessingComplete, retryCount]);\n\n return (\n <div className=\"flex flex-col justify-between h-full w-full\">\n {/* Main content area */}\n <div className=\"flex-1 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 {/* Header */}\n <div className=\"text-center space-y-4\">\n <Title className=\"text-xl md:text-2xl lg:text-3xl\">\n {t(\"jdi.processing.title\")}\n </Title>\n <Subtitle className=\"text-sm text-gray-600 leading-relaxed\">\n {t(\"jdi.processing.subtitle\", {\n document: t(\"documentTypes.\" + documentType),\n })}\n </Subtitle>\n </div>\n\n {/* Processing steps with status indicators */}\n <div className=\"w-full flex justify-center\">\n <div className=\"space-y-5\">\n {processingSteps.map((step, index: number) => (\n <div key={index} className=\"flex items-start\">\n {/* Status indicator */}\n <div className=\"mr-4 mt-1 flex-shrink-0\">\n {index < currentStep ? (\n step.hasError ? (\n // Error indicator - Red X\n <div className=\"flex items-center justify-center w-6 h-6 rounded-full bg-red-500 text-white text-xs\">\n ✕\n </div>\n ) : (\n // Success indicator - Green checkmark\n <div className=\"flex items-center justify-center w-6 h-6 rounded-full bg-[#11E5C5] text-white text-xs\">\n ✓\n </div>\n )\n ) : index === currentStep ? (\n // Loading spinner only for the current step\n <div className=\"w-6 h-6 rounded-full border-2 border-t-[#11E5C5] border-r-[#11E5C5] border-b-[#11E5C5] border-l-transparent animate-spin\"></div>\n ) : (\n // Empty circle for future steps\n <div className=\"w-6 h-6 rounded-full border-2 border-gray-300\"></div>\n )}\n </div>\n\n {/* Step content */}\n <div className=\"flex-1 min-w-0\">\n <p className=\"font-medium text-[#3C3C40] text-sm\">\n {step.title}\n </p>\n <p className=\"text-xs text-gray-500 mt-1\">\n {step.subtitle}\n </p>\n </div>\n </div>\n ))}\n </div>\n </div>\n </div>\n </div>\n </div>\n );\n },\n);\n\nJDIProcessing.displayName = \"JDIProcessing\";\n\nexport default JDIProcessing;\n"],"names":["_jsx","_jsxs"],"mappings":"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"}
|
|
@@ -6,7 +6,7 @@ import SelfieFlow from './selfie-flow/SelfieFlow.js';
|
|
|
6
6
|
import VideoResetStyles from './VideoResetStyles.js';
|
|
7
7
|
|
|
8
8
|
var Video = function (_a) {
|
|
9
|
-
var setSelfieData = _a.setSelfieData, setStep = _a.setStep, btnBg = _a.btnBg, btnText = _a.btnText;
|
|
9
|
+
var setSelfieData = _a.setSelfieData, setStep = _a.setStep, sessionId = _a.sessionId, iad = _a.iad, btnBg = _a.btnBg, btnText = _a.btnText;
|
|
10
10
|
// Effet pour ajouter la classe au body lorsque le composant est monté
|
|
11
11
|
useEffect(function () {
|
|
12
12
|
// Empêcher le scroll sur le body lorsque la capture est active
|
|
@@ -28,7 +28,7 @@ var Video = function (_a) {
|
|
|
28
28
|
setStep(1); // Move to the next step after selfie capture
|
|
29
29
|
}, 300);
|
|
30
30
|
};
|
|
31
|
-
return (jsxs("div", { className: "w-full h-full overflow-hidden flex flex-col", children: [jsx(VideoResetStyles, {}), jsx(SelfieFlow, { handleSelfie: handleSelfie, btnBg: btnBg, btnText: btnText })] }));
|
|
31
|
+
return (jsxs("div", { className: "w-full h-full overflow-hidden flex flex-col", children: [jsx(VideoResetStyles, {}), jsx(SelfieFlow, { handleSelfie: handleSelfie, sessionId: sessionId, iad: iad, btnBg: btnBg, btnText: btnText })] }));
|
|
32
32
|
};
|
|
33
33
|
|
|
34
34
|
export { Video as default };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Video.js","sources":["../../../../../src/components/selfie/Video.tsx"],"sourcesContent":["import { useEffect } from \"react\";\nimport type { SelfieCaptureData } from \"../../types/selfie\";\nimport \"./Video.css\";\nimport \"./VideoFixes.css\";\nimport SelfieFlow from \"./selfie-flow/SelfieFlow\";\nimport VideoResetStyles from \"./VideoResetStyles\";\n\ninterface VideoProps {\n setSelfieData: (selfieData: SelfieCaptureData) => void;\n setStep: (step: number) => void;\n btnBg?: string;\n btnText?: string;\n}\n\nconst Video = ({ setSelfieData, setStep, btnBg, btnText }: VideoProps) => {\n // Effet pour ajouter la classe au body lorsque le composant est monté\n useEffect(() => {\n // Empêcher le scroll sur le body lorsque la capture est active\n document.body.classList.add(\"selfie-active\");\n\n // Ajouter une classe pour gérer le plein écran sur mobile\n document.documentElement.classList.add(\"selfie-fullscreen\");\n\n return () => {\n // Nettoyer en enlevant les classes lors du démontage\n document.body.classList.remove(\"selfie-active\");\n document.documentElement.classList.remove(\"selfie-fullscreen\");\n };\n }, []);\n\n const handleSelfie = (e: Event) => {\n const data = (e as CustomEvent<SelfieCaptureData>).detail;\n\n // Attendre un court instant avant de passer à l'écran de confirmation\n // pour donner le temps à l'utilisateur de voir que la capture est terminée\n setTimeout(() => {\n setSelfieData(data);\n setStep(1); // Move to the next step after selfie capture\n }, 300);\n };\n\n return (\n <div className=\"w-full h-full overflow-hidden flex flex-col\">\n <VideoResetStyles />\n <SelfieFlow
|
|
1
|
+
{"version":3,"file":"Video.js","sources":["../../../../../src/components/selfie/Video.tsx"],"sourcesContent":["import { useEffect } from \"react\";\nimport type { SelfieCaptureData } from \"../../types/selfie\";\nimport \"./Video.css\";\nimport \"./VideoFixes.css\";\nimport SelfieFlow from \"./selfie-flow/SelfieFlow\";\nimport VideoResetStyles from \"./VideoResetStyles\";\n\ninterface VideoProps {\n setSelfieData: (selfieData: SelfieCaptureData) => void;\n setStep: (step: number) => void;\n sessionId?: string;\n iad?: { enabled: boolean; level?: \"basic\" | \"reinforced\" };\n btnBg?: string;\n btnText?: string;\n}\n\nconst Video = ({ setSelfieData, setStep, sessionId, iad, btnBg, btnText }: VideoProps) => {\n // Effet pour ajouter la classe au body lorsque le composant est monté\n useEffect(() => {\n // Empêcher le scroll sur le body lorsque la capture est active\n document.body.classList.add(\"selfie-active\");\n\n // Ajouter une classe pour gérer le plein écran sur mobile\n document.documentElement.classList.add(\"selfie-fullscreen\");\n\n return () => {\n // Nettoyer en enlevant les classes lors du démontage\n document.body.classList.remove(\"selfie-active\");\n document.documentElement.classList.remove(\"selfie-fullscreen\");\n };\n }, []);\n\n const handleSelfie = (e: Event) => {\n const data = (e as CustomEvent<SelfieCaptureData>).detail;\n\n // Attendre un court instant avant de passer à l'écran de confirmation\n // pour donner le temps à l'utilisateur de voir que la capture est terminée\n setTimeout(() => {\n setSelfieData(data);\n setStep(1); // Move to the next step after selfie capture\n }, 300);\n };\n\n return (\n <div className=\"w-full h-full overflow-hidden flex flex-col\">\n <VideoResetStyles />\n <SelfieFlow\n handleSelfie={handleSelfie}\n sessionId={sessionId}\n iad={iad}\n btnBg={btnBg}\n btnText={btnText}\n />\n </div>\n );\n};\n\nexport default Video;\n"],"names":["_jsxs","_jsx"],"mappings":";;;;;;;AAgBA,IAAM,KAAK,GAAG,UAAC,EAAsE,EAAA;AAApE,IAAA,IAAA,aAAa,GAAA,EAAA,CAAA,aAAA,EAAE,OAAO,GAAA,EAAA,CAAA,OAAA,EAAE,SAAS,GAAA,EAAA,CAAA,SAAA,EAAE,GAAG,SAAA,EAAE,KAAK,GAAA,EAAA,CAAA,KAAA,EAAE,OAAO,GAAA,EAAA,CAAA,OAAA;;AAErE,IAAA,SAAS,CAAC,YAAA;;QAER,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,eAAe,CAAC;;QAG5C,QAAQ,CAAC,eAAe,CAAC,SAAS,CAAC,GAAG,CAAC,mBAAmB,CAAC;QAE3D,OAAO,YAAA;;YAEL,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,eAAe,CAAC;YAC/C,QAAQ,CAAC,eAAe,CAAC,SAAS,CAAC,MAAM,CAAC,mBAAmB,CAAC;AAChE,QAAA,CAAC;IACH,CAAC,EAAE,EAAE,CAAC;IAEN,IAAM,YAAY,GAAG,UAAC,CAAQ,EAAA;AAC5B,QAAA,IAAM,IAAI,GAAI,CAAoC,CAAC,MAAM;;;AAIzD,QAAA,UAAU,CAAC,YAAA;YACT,aAAa,CAAC,IAAI,CAAC;AACnB,YAAA,OAAO,CAAC,CAAC,CAAC,CAAC;QACb,CAAC,EAAE,GAAG,CAAC;AACT,IAAA,CAAC;AAED,IAAA,QACEA,IAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAC,6CAA6C,EAAA,QAAA,EAAA,CAC1DC,GAAA,CAAC,gBAAgB,EAAA,EAAA,CAAG,EACpBA,GAAA,CAAC,UAAU,EAAA,EACT,YAAY,EAAE,YAAY,EAC1B,SAAS,EAAE,SAAS,EACpB,GAAG,EAAE,GAAG,EACR,KAAK,EAAE,KAAK,EACZ,OAAO,EAAE,OAAO,EAAA,CAChB,CAAA,EAAA,CACE;AAEV;;;;"}
|
|
@@ -7,12 +7,12 @@ import LoadingState from '../../states/LoadingState.js';
|
|
|
7
7
|
var SelfieRecorder = lazy(function () { return import('./SelfieRecorder.js'); });
|
|
8
8
|
var SelfieFlow = function (_a) {
|
|
9
9
|
var _b;
|
|
10
|
-
var handleSelfie = _a.handleSelfie, btnBg = _a.btnBg, btnText = _a.btnText;
|
|
10
|
+
var handleSelfie = _a.handleSelfie, sessionId = _a.sessionId, iad = _a.iad, btnBg = _a.btnBg, btnText = _a.btnText;
|
|
11
11
|
var _c = useState(-1), internalStep = _c[0], setInternalStep = _c[1]; // Commencer à -1 pour la pré-introduction
|
|
12
12
|
return (jsxs("div", { className: "h-full w-full flex flex-col", style: (_b = {},
|
|
13
13
|
_b["--dk-btn-bg"] = btnBg !== null && btnBg !== void 0 ? btnBg : "#11E5C5",
|
|
14
14
|
_b["--dk-btn-text"] = btnText !== null && btnText !== void 0 ? btnText : "#3C3C40",
|
|
15
|
-
_b), children: [internalStep === -1 && (jsx("div", { className: "flex-1 flex flex-col h-full", children: jsx(SelfiePreIntroduction, { onContinue: function () { return setInternalStep(0); } }) })), internalStep === 0 && (jsx("div", { className: "flex-1 flex flex-col h-full", children: jsx(InstructionsSelfie, { setStep: setInternalStep, onBack: function () { return setInternalStep(-1); } }) })), internalStep === 1 && (jsx("div", { className: "flex-1 flex flex-col h-full overflow-hidden", children: jsx(Suspense, { fallback: jsx(LoadingState, {}), children: jsx(SelfieRecorder, { handleSelfie: handleSelfie, btnBg: btnBg, btnText: btnText }) }) }))] }));
|
|
15
|
+
_b), children: [internalStep === -1 && (jsx("div", { className: "flex-1 flex flex-col h-full", children: jsx(SelfiePreIntroduction, { onContinue: function () { return setInternalStep(0); } }) })), internalStep === 0 && (jsx("div", { className: "flex-1 flex flex-col h-full", children: jsx(InstructionsSelfie, { setStep: setInternalStep, onBack: function () { return setInternalStep(-1); } }) })), internalStep === 1 && (jsx("div", { className: "flex-1 flex flex-col h-full overflow-hidden", children: jsx(Suspense, { fallback: jsx(LoadingState, {}), children: jsx(SelfieRecorder, { handleSelfie: handleSelfie, sessionId: sessionId, iad: iad, btnBg: btnBg, btnText: btnText }) }) }))] }));
|
|
16
16
|
};
|
|
17
17
|
|
|
18
18
|
export { SelfieFlow as default };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SelfieFlow.js","sources":["../../../../../../src/components/selfie/selfie-flow/SelfieFlow.tsx"],"sourcesContent":["import { lazy, Suspense, useState } from \"react\";\nimport SelfiePreIntroduction from \"./SelfiePreIntroduction\";\nimport InstructionsSelfie from \"./InstructionsSelfie\";\nimport LoadingState from \"../../states/LoadingState\";\n\nconst SelfieRecorder = lazy(() => import(\"./SelfieRecorder\"));\n\ninterface SelfieFlowProps {\n handleSelfie: (e: Event) => void;\n btnBg?: string;\n btnText?: string;\n}\n\nconst SelfieFlow = ({ handleSelfie, btnBg, btnText }: SelfieFlowProps) => {\n const [internalStep, setInternalStep] = useState(-1); // Commencer à -1 pour la pré-introduction\n\n return (\n <div\n className=\"h-full w-full flex flex-col\"\n style={{\n [\"--dk-btn-bg\" as string]: btnBg ?? \"#11E5C5\",\n [\"--dk-btn-text\" as string]: btnText ?? \"#3C3C40\",\n }}\n >\n {internalStep === -1 && (\n <div className=\"flex-1 flex flex-col h-full\">\n <SelfiePreIntroduction\n onContinue={() => setInternalStep(0)}\n />\n </div>\n )}\n {internalStep === 0 && (\n <div className=\"flex-1 flex flex-col h-full\">\n <InstructionsSelfie\n setStep={setInternalStep}\n onBack={() => setInternalStep(-1)}\n />\n </div>\n )}\n {internalStep === 1 && (\n <div className=\"flex-1 flex flex-col h-full overflow-hidden\">\n <Suspense fallback={<LoadingState />}>\n <SelfieRecorder
|
|
1
|
+
{"version":3,"file":"SelfieFlow.js","sources":["../../../../../../src/components/selfie/selfie-flow/SelfieFlow.tsx"],"sourcesContent":["import { lazy, Suspense, useState } from \"react\";\nimport SelfiePreIntroduction from \"./SelfiePreIntroduction\";\nimport InstructionsSelfie from \"./InstructionsSelfie\";\nimport LoadingState from \"../../states/LoadingState\";\n\nconst SelfieRecorder = lazy(() => import(\"./SelfieRecorder\"));\n\ninterface SelfieFlowProps {\n handleSelfie: (e: Event) => void;\n sessionId?: string;\n iad?: { enabled: boolean; level?: \"basic\" | \"reinforced\" };\n btnBg?: string;\n btnText?: string;\n}\n\nconst SelfieFlow = ({ handleSelfie, sessionId, iad, btnBg, btnText }: SelfieFlowProps) => {\n const [internalStep, setInternalStep] = useState(-1); // Commencer à -1 pour la pré-introduction\n\n return (\n <div\n className=\"h-full w-full flex flex-col\"\n style={{\n [\"--dk-btn-bg\" as string]: btnBg ?? \"#11E5C5\",\n [\"--dk-btn-text\" as string]: btnText ?? \"#3C3C40\",\n }}\n >\n {internalStep === -1 && (\n <div className=\"flex-1 flex flex-col h-full\">\n <SelfiePreIntroduction\n onContinue={() => setInternalStep(0)}\n />\n </div>\n )}\n {internalStep === 0 && (\n <div className=\"flex-1 flex flex-col h-full\">\n <InstructionsSelfie\n setStep={setInternalStep}\n onBack={() => setInternalStep(-1)}\n />\n </div>\n )}\n {internalStep === 1 && (\n <div className=\"flex-1 flex flex-col h-full overflow-hidden\">\n <Suspense fallback={<LoadingState />}>\n <SelfieRecorder\n handleSelfie={handleSelfie}\n sessionId={sessionId}\n iad={iad}\n btnBg={btnBg}\n btnText={btnText}\n />\n </Suspense>\n </div>\n )}\n </div>\n );\n};\n\nexport default SelfieFlow;\n"],"names":["_jsxs","_jsx"],"mappings":";;;;;;AAKA,IAAM,cAAc,GAAG,IAAI,CAAC,YAAA,EAAM,OAAA,OAAO,qBAAkB,CAAC,CAAA,CAA1B,CAA0B,CAAC;AAU7D,IAAM,UAAU,GAAG,UAAC,EAAiE,EAAA;;AAA/D,IAAA,IAAA,YAAY,GAAA,EAAA,CAAA,YAAA,EAAE,SAAS,GAAA,EAAA,CAAA,SAAA,EAAE,GAAG,GAAA,EAAA,CAAA,GAAA,EAAE,KAAK,GAAA,EAAA,CAAA,KAAA,EAAE,OAAO,GAAA,EAAA,CAAA,OAAA;AAC1D,IAAA,IAAA,EAAA,GAAkC,QAAQ,CAAC,EAAE,CAAC,EAA7C,YAAY,GAAA,EAAA,CAAA,CAAA,CAAA,EAAE,eAAe,GAAA,EAAA,CAAA,CAAA,CAAgB,CAAC;AAErD,IAAA,QACEA,IAAA,CAAA,KAAA,EAAA,EACE,SAAS,EAAC,6BAA6B,EACvC,KAAK,GAAA,EAAA,GAAA,EAAA;YACH,EAAA,CAAC,aAAuB,IAAG,KAAK,KAAA,IAAA,IAAL,KAAK,KAAA,MAAA,GAAL,KAAK,GAAI,SAAS;YAC7C,EAAA,CAAC,eAAyB,IAAG,OAAO,KAAA,IAAA,IAAP,OAAO,KAAA,MAAA,GAAP,OAAO,GAAI,SAAS;4BAGlD,YAAY,KAAK,EAAE,KAClBC,GAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAC,6BAA6B,EAAA,QAAA,EAC1CA,GAAA,CAAC,qBAAqB,EAAA,EACpB,UAAU,EAAE,YAAA,EAAM,OAAA,eAAe,CAAC,CAAC,CAAC,CAAA,CAAlB,CAAkB,EAAA,CACpC,EAAA,CACE,CACP,EACA,YAAY,KAAK,CAAC,KACjBA,aAAK,SAAS,EAAC,6BAA6B,EAAA,QAAA,EAC1CA,GAAA,CAAC,kBAAkB,IACjB,OAAO,EAAE,eAAe,EACxB,MAAM,EAAE,cAAM,OAAA,eAAe,CAAC,EAAE,CAAC,EAAnB,CAAmB,EAAA,CACjC,GACE,CACP,EACA,YAAY,KAAK,CAAC,KACjBA,GAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAC,6CAA6C,EAAA,QAAA,EAC1DA,GAAA,CAAC,QAAQ,EAAA,EAAC,QAAQ,EAAEA,GAAA,CAAC,YAAY,EAAA,EAAA,CAAG,EAAA,QAAA,EAClCA,GAAA,CAAC,cAAc,IACb,YAAY,EAAE,YAAY,EAC1B,SAAS,EAAE,SAAS,EACpB,GAAG,EAAE,GAAG,EACR,KAAK,EAAE,KAAK,EACZ,OAAO,EAAE,OAAO,EAAA,CAChB,GACO,EAAA,CACP,CACP,CAAA,EAAA,CACG;AAEV;;;;"}
|
|
@@ -81,7 +81,11 @@ var SelfieProcessing = function (_a) {
|
|
|
81
81
|
details = data.details;
|
|
82
82
|
faceComparison = details === null || details === void 0 ? void 0 : details.face_comparison;
|
|
83
83
|
// Success: face match with high confidence
|
|
84
|
-
if (data.
|
|
84
|
+
if (data.face_comparison_disabled === true) {
|
|
85
|
+
isSuccess = true;
|
|
86
|
+
conformityCodeToSet = "1.0";
|
|
87
|
+
}
|
|
88
|
+
else if (data.is_match &&
|
|
85
89
|
(faceComparison === null || faceComparison === void 0 ? void 0 : faceComparison.result) === "match"
|
|
86
90
|
// faceComparison?.confidence_level === "high" Pas assez explicit
|
|
87
91
|
) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SelfieProcessing.js","sources":["../../../../../../src/components/selfie/selfie-flow/SelfieProcessing.tsx"],"sourcesContent":["import { useState, useEffect, useRef } from \"react\";\nimport Title from \"../../ui/Title\";\nimport Subtitle from \"../../ui/Subtitle\";\nimport { useI18n } from \"../../../hooks/useI18n\";\nimport { codeToStep } from \"../../../services/utils\";\nimport type { SelfieCaptureData } from \"../../../types/selfie\";\nimport { analyzeSelfie } from \"../../../services/analysis\";\nimport { getActiveSessionId } from \"../../../services/sessionMemoryStore\";\nimport ButtonDesktop from \"../../ui/ButtonDesktop\";\nimport { reportSelfieFailure } from \"../../../services/sessionService\";\n\ninterface SelfieProcessingProps {\n onProcessingComplete: (success: boolean) => void;\n selfieVideo: SelfieCaptureData | null;\n selfiePhoto: string | null;\n onRetake: () => void;\n onContinueAnyway?: () => void;\n nodeId: string;\n}\n\nconst processingSteps = [\n { key: \"analysis\" },\n { key: \"face_detection\" },\n { key: \"liveness\" },\n { key: \"finalization\" },\n];\nconst SelfieProcessing = ({\n onProcessingComplete,\n selfieVideo,\n selfiePhoto,\n onRetake,\n onContinueAnyway,\n nodeId,\n}: SelfieProcessingProps) => {\n const { t } = useI18n();\n const [currentStep, setCurrentStep] = useState(0);\n const [hasError, setHasError] = useState(false);\n const [isDone, setIsDone] = useState(false);\n const [conformityCode, setConformityCode] = useState<string | null>(null);\n\n const analysisStartedRef = useRef(false);\n useEffect(() => {\n // Prevent multiple analysis runs\n if (analysisStartedRef.current) return;\n if (!selfieVideo || !selfiePhoto) return;\n\n analysisStartedRef.current = true;\n\n // Timeout simple : 60 secondes pour tous\n const timeoutId = setTimeout(() => {\n if (!isDone) {\n console.error(\"⏰ Selfie analysis timeout after 60 seconds\");\n const sessionId = getActiveSessionId();\n if (sessionId) {\n void reportSelfieFailure(sessionId, {\n nodeId,\n reason: \"timeout\",\n }).catch(() => undefined);\n }\n setHasError(true);\n setIsDone(true);\n onProcessingComplete(false);\n }\n }, 60000);\n\n const processFiles = async () => {\n const sessionId = getActiveSessionId();\n if (!sessionId) {\n console.error(\"❌ No session ID found\");\n setHasError(true);\n onProcessingComplete(false);\n setIsDone(true);\n clearTimeout(timeoutId);\n return;\n }\n\n console.log(\"🚀 Starting selfie analysis...\");\n\n try {\n // Délai minimum simple : 2 secondes\n const [response] = await Promise.all([\n analyzeSelfie(sessionId, selfieVideo, selfiePhoto, nodeId),\n new Promise((resolve) => setTimeout(resolve, 2000)),\n ]);\n\n console.log(\"✅ Analysis response:\", response);\n clearTimeout(timeoutId);\n\n // Handle Unissey response format\n let isSuccess = false;\n let conformityCodeToSet = \"4\"; // Default to error\n\n if (response && response.data) {\n // Check if analysis was successful based on real Unissey response structure\n const data = response.data;\n const details = data.details;\n const faceComparison = details?.face_comparison;\n\n // Success: face match with high confidence\n if (\n data.is_match &&\n faceComparison?.result === \"match\"\n // faceComparison?.confidence_level === \"high\" Pas assez explicit\n ) {\n isSuccess = true;\n conformityCodeToSet = \"1.0\"; // Success code\n } else if (details) {\n // Check specific failure reasons\n if (faceComparison?.result !== \"match\") {\n conformityCodeToSet = \"2.0\"; // Face comparison failed\n } else if (faceComparison?.confidence_level !== \"high\") {\n conformityCodeToSet = \"3.0\"; // Low confidence\n } else {\n conformityCodeToSet = \"4.0\"; // Generic error\n }\n }\n }\n\n console.log(\"📊 Selfie analysis result:\", {\n isSuccess,\n conformityCode: conformityCodeToSet,\n isMatch: response?.data?.is_match,\n confidenceLevel:\n response?.data?.details?.face_comparison?.confidence_level,\n comparisonResult: response?.data?.details?.face_comparison?.result,\n });\n\n setConformityCode(conformityCodeToSet);\n setIsDone(true);\n\n // Don't call onProcessingComplete here - let the animation effect handle it\n } catch (error) {\n console.error(\"💥 Selfie analysis failed:\", error);\n void reportSelfieFailure(sessionId, {\n nodeId,\n reason: \"network_error\",\n }).catch(() => undefined);\n clearTimeout(timeoutId);\n setHasError(true);\n setIsDone(true);\n onProcessingComplete(false);\n }\n };\n\n processFiles();\n\n return () => {\n clearTimeout(timeoutId);\n };\n }, [onProcessingComplete, selfieVideo, selfiePhoto, isDone, nodeId]);\n\n useEffect(() => {\n // While analysis is not finished, stay at step 0\n if (!isDone && !hasError) {\n setCurrentStep(0);\n return;\n }\n // We want stepToStop to be the step in error (the one corresponding to conformityCode)\n let stepToStop = codeToStep(conformityCode || \"4\");\n // If codeToStep returns 0 (generic error), stop at the first step\n if (stepToStop === 0) stepToStop = 1;\n console.log(\"Step to stop (error):\", stepToStop);\n\n // When analysis is finished (success or error), start the animation\n const interval = setInterval(() => {\n setCurrentStep((prev) => {\n if (prev < stepToStop - 1) {\n return prev + 1;\n } else {\n clearInterval(interval);\n if (stepToStop < 4) setHasError(true);\n onProcessingComplete(stepToStop === 4);\n return prev; // Stop at the step in error\n }\n });\n }, 500); // Adjust the speed of the animation\n return () => clearInterval(interval);\n }, [onProcessingComplete, hasError, isDone, conformityCode]);\n\n return (\n <div className=\"flex flex-col justify-between h-full w-full\">\n <div className=\"flex-1 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\">\n <Title className=\"text-xl md:text-2xl lg:text-3xl\">\n {hasError\n ? t(\"selfie.processing.error_title\", \"Échec de l'analyse\")\n : t(\"selfie.processing.title\", \"Analyse en cours\")}\n </Title>\n <Subtitle className=\"text-sm text-gray-600 leading-relaxed\">\n {hasError\n ? t(\n \"selfie.processing.error_subtitle\",\n \"Une erreur est survenue lors de l'analyse du selfie. Veuillez réessayer.\",\n )\n : t(\n \"selfie.processing.subtitle\",\n \"Nous analysons votre selfie. Cela peut prendre quelques instants.\",\n )}\n </Subtitle>\n </div>\n\n <div className=\"w-full\">\n <div className=\"space-y-5\">\n {processingSteps.map(\n (step, index) =>\n step.key && (\n <div key={index} className=\"flex items-start\">\n <div className=\"mr-4 mt-1 flex-shrink-0\">\n {hasError && index === currentStep ? (\n // Step in error - red cross\n <div className=\"flex items-center justify-center w-6 h-6 rounded-full bg-red-500 text-white text-xs font-bold\">\n ×\n </div>\n ) : index < currentStep ? (\n // Completed step - green check\n <div className=\"flex items-center justify-center w-6 h-6 rounded-full bg-[#11E5C5] text-white text-xs\">\n ✓\n </div>\n ) : index === currentStep ? (\n // Current step - spinner\n <div className=\"w-6 h-6 rounded-full border-2 border-t-[#11E5C5] border-r-[#11E5C5] border-b-[#11E5C5] border-l-transparent animate-spin\"></div>\n ) : (\n // Upcoming step - gray circle\n <div className=\"w-6 h-6 rounded-full border-2 border-gray-300\"></div>\n )}\n </div>\n <div className=\"flex-1 min-w-0\">\n <p className=\"font-medium text-[#3C3C40] text-sm\">\n {t(`selfie.processing.steps.${step.key}.title`)}\n </p>\n <p className=\"text-xs text-gray-500 mt-1\">\n {t(`selfie.processing.steps.${step.key}.subtitle`)}\n </p>\n </div>\n </div>\n ),\n )}\n </div>\n </div>\n\n <div className=\"w-full\">\n <div className=\"bg-gray-200 rounded-full h-2\">\n <div\n className={\n hasError\n ? \"bg-red-500 h-2 rounded-full transition-all duration-500 ease-out\"\n : \"bg-[#11E5C5] h-2 rounded-full transition-all duration-500 ease-out\"\n }\n style={{\n width: `${\n ((currentStep + 1) / processingSteps.length) * 100\n }%`,\n }}\n ></div>\n </div>\n <p className=\"text-xs text-gray-500 mt-2 text-center\">\n {t(\"selfie.processing.step_of\", {\n current: currentStep + 1,\n total: processingSteps.length,\n })}\n </p>\n </div>\n\n {/* Footer with buttons */}\n {hasError && (\n <div className=\"sticky bottom-0 bg-white border-t border-gray-100 p-4 md:p-6\">\n <div className=\"w-full max-w-md mx-auto\">\n {/* Mobile layout - stacked buttons */}\n <div className=\"flex flex-col space-y-3 md:hidden\">\n {onContinueAnyway && (\n <ButtonDesktop type=\"back\" onClick={onContinueAnyway}>\n {t(\"errors.continue_anyway\", \"Poursuivre tout de même\")}\n </ButtonDesktop>\n )}\n <ButtonDesktop type=\"continue\" onClick={onRetake}>\n {t(\"selfie.confirmation.retake\", \"Reprendre le selfie\")}\n </ButtonDesktop>\n </div>\n\n {/* Desktop layout - horizontal buttons */}\n <div className=\"hidden md:flex gap-3 justify-between items-center\">\n {onContinueAnyway && (\n <ButtonDesktop type=\"back\" onClick={onContinueAnyway}>\n {t(\"errors.continue_anyway\", \"Poursuivre tout de même\")}\n </ButtonDesktop>\n )}\n <ButtonDesktop type=\"continue\" onClick={onRetake}>\n {t(\"selfie.confirmation.retake\", \"Reprendre le selfie\")}\n </ButtonDesktop>\n </div>\n </div>\n </div>\n )}\n </div>\n </div>\n </div>\n );\n};\n\nexport default SelfieProcessing;\n"],"names":["_jsx","_jsxs"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"SelfieProcessing.js","sources":["../../../../../../src/components/selfie/selfie-flow/SelfieProcessing.tsx"],"sourcesContent":["import { useState, useEffect, useRef } from \"react\";\nimport Title from \"../../ui/Title\";\nimport Subtitle from \"../../ui/Subtitle\";\nimport { useI18n } from \"../../../hooks/useI18n\";\nimport { codeToStep } from \"../../../services/utils\";\nimport type { SelfieCaptureData } from \"../../../types/selfie\";\nimport { analyzeSelfie } from \"../../../services/analysis\";\nimport { getActiveSessionId } from \"../../../services/sessionMemoryStore\";\nimport ButtonDesktop from \"../../ui/ButtonDesktop\";\nimport { reportSelfieFailure } from \"../../../services/sessionService\";\n\ninterface SelfieProcessingProps {\n onProcessingComplete: (success: boolean) => void;\n selfieVideo: SelfieCaptureData | null;\n selfiePhoto: string | null;\n onRetake: () => void;\n onContinueAnyway?: () => void;\n nodeId: string;\n}\n\nconst processingSteps = [\n { key: \"analysis\" },\n { key: \"face_detection\" },\n { key: \"liveness\" },\n { key: \"finalization\" },\n];\nconst SelfieProcessing = ({\n onProcessingComplete,\n selfieVideo,\n selfiePhoto,\n onRetake,\n onContinueAnyway,\n nodeId,\n}: SelfieProcessingProps) => {\n const { t } = useI18n();\n const [currentStep, setCurrentStep] = useState(0);\n const [hasError, setHasError] = useState(false);\n const [isDone, setIsDone] = useState(false);\n const [conformityCode, setConformityCode] = useState<string | null>(null);\n\n const analysisStartedRef = useRef(false);\n useEffect(() => {\n // Prevent multiple analysis runs\n if (analysisStartedRef.current) return;\n if (!selfieVideo || !selfiePhoto) return;\n\n analysisStartedRef.current = true;\n\n // Timeout simple : 60 secondes pour tous\n const timeoutId = setTimeout(() => {\n if (!isDone) {\n console.error(\"⏰ Selfie analysis timeout after 60 seconds\");\n const sessionId = getActiveSessionId();\n if (sessionId) {\n void reportSelfieFailure(sessionId, {\n nodeId,\n reason: \"timeout\",\n }).catch(() => undefined);\n }\n setHasError(true);\n setIsDone(true);\n onProcessingComplete(false);\n }\n }, 60000);\n\n const processFiles = async () => {\n const sessionId = getActiveSessionId();\n if (!sessionId) {\n console.error(\"❌ No session ID found\");\n setHasError(true);\n onProcessingComplete(false);\n setIsDone(true);\n clearTimeout(timeoutId);\n return;\n }\n\n console.log(\"🚀 Starting selfie analysis...\");\n\n try {\n // Délai minimum simple : 2 secondes\n const [response] = await Promise.all([\n analyzeSelfie(sessionId, selfieVideo, selfiePhoto, nodeId),\n new Promise((resolve) => setTimeout(resolve, 2000)),\n ]);\n\n console.log(\"✅ Analysis response:\", response);\n clearTimeout(timeoutId);\n\n // Handle Unissey response format\n let isSuccess = false;\n let conformityCodeToSet = \"4\"; // Default to error\n\n if (response && response.data) {\n // Check if analysis was successful based on real Unissey response structure\n const data = response.data;\n const details = data.details;\n const faceComparison = details?.face_comparison;\n\n // Success: face match with high confidence\n if (data.face_comparison_disabled === true) {\n isSuccess = true;\n conformityCodeToSet = \"1.0\";\n } else if (\n data.is_match &&\n faceComparison?.result === \"match\"\n // faceComparison?.confidence_level === \"high\" Pas assez explicit\n ) {\n isSuccess = true;\n conformityCodeToSet = \"1.0\"; // Success code\n } else if (details) {\n // Check specific failure reasons\n if (faceComparison?.result !== \"match\") {\n conformityCodeToSet = \"2.0\"; // Face comparison failed\n } else if (faceComparison?.confidence_level !== \"high\") {\n conformityCodeToSet = \"3.0\"; // Low confidence\n } else {\n conformityCodeToSet = \"4.0\"; // Generic error\n }\n }\n }\n\n console.log(\"📊 Selfie analysis result:\", {\n isSuccess,\n conformityCode: conformityCodeToSet,\n isMatch: response?.data?.is_match,\n confidenceLevel:\n response?.data?.details?.face_comparison?.confidence_level,\n comparisonResult: response?.data?.details?.face_comparison?.result,\n });\n\n setConformityCode(conformityCodeToSet);\n setIsDone(true);\n\n // Don't call onProcessingComplete here - let the animation effect handle it\n } catch (error) {\n console.error(\"💥 Selfie analysis failed:\", error);\n void reportSelfieFailure(sessionId, {\n nodeId,\n reason: \"network_error\",\n }).catch(() => undefined);\n clearTimeout(timeoutId);\n setHasError(true);\n setIsDone(true);\n onProcessingComplete(false);\n }\n };\n\n processFiles();\n\n return () => {\n clearTimeout(timeoutId);\n };\n }, [onProcessingComplete, selfieVideo, selfiePhoto, isDone, nodeId]);\n\n useEffect(() => {\n // While analysis is not finished, stay at step 0\n if (!isDone && !hasError) {\n setCurrentStep(0);\n return;\n }\n // We want stepToStop to be the step in error (the one corresponding to conformityCode)\n let stepToStop = codeToStep(conformityCode || \"4\");\n // If codeToStep returns 0 (generic error), stop at the first step\n if (stepToStop === 0) stepToStop = 1;\n console.log(\"Step to stop (error):\", stepToStop);\n\n // When analysis is finished (success or error), start the animation\n const interval = setInterval(() => {\n setCurrentStep((prev) => {\n if (prev < stepToStop - 1) {\n return prev + 1;\n } else {\n clearInterval(interval);\n if (stepToStop < 4) setHasError(true);\n onProcessingComplete(stepToStop === 4);\n return prev; // Stop at the step in error\n }\n });\n }, 500); // Adjust the speed of the animation\n return () => clearInterval(interval);\n }, [onProcessingComplete, hasError, isDone, conformityCode]);\n\n return (\n <div className=\"flex flex-col justify-between h-full w-full\">\n <div className=\"flex-1 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\">\n <Title className=\"text-xl md:text-2xl lg:text-3xl\">\n {hasError\n ? t(\"selfie.processing.error_title\", \"Échec de l'analyse\")\n : t(\"selfie.processing.title\", \"Analyse en cours\")}\n </Title>\n <Subtitle className=\"text-sm text-gray-600 leading-relaxed\">\n {hasError\n ? t(\n \"selfie.processing.error_subtitle\",\n \"Une erreur est survenue lors de l'analyse du selfie. Veuillez réessayer.\",\n )\n : t(\n \"selfie.processing.subtitle\",\n \"Nous analysons votre selfie. Cela peut prendre quelques instants.\",\n )}\n </Subtitle>\n </div>\n\n <div className=\"w-full\">\n <div className=\"space-y-5\">\n {processingSteps.map(\n (step, index) =>\n step.key && (\n <div key={index} className=\"flex items-start\">\n <div className=\"mr-4 mt-1 flex-shrink-0\">\n {hasError && index === currentStep ? (\n // Step in error - red cross\n <div className=\"flex items-center justify-center w-6 h-6 rounded-full bg-red-500 text-white text-xs font-bold\">\n ×\n </div>\n ) : index < currentStep ? (\n // Completed step - green check\n <div className=\"flex items-center justify-center w-6 h-6 rounded-full bg-[#11E5C5] text-white text-xs\">\n ✓\n </div>\n ) : index === currentStep ? (\n // Current step - spinner\n <div className=\"w-6 h-6 rounded-full border-2 border-t-[#11E5C5] border-r-[#11E5C5] border-b-[#11E5C5] border-l-transparent animate-spin\"></div>\n ) : (\n // Upcoming step - gray circle\n <div className=\"w-6 h-6 rounded-full border-2 border-gray-300\"></div>\n )}\n </div>\n <div className=\"flex-1 min-w-0\">\n <p className=\"font-medium text-[#3C3C40] text-sm\">\n {t(`selfie.processing.steps.${step.key}.title`)}\n </p>\n <p className=\"text-xs text-gray-500 mt-1\">\n {t(`selfie.processing.steps.${step.key}.subtitle`)}\n </p>\n </div>\n </div>\n ),\n )}\n </div>\n </div>\n\n <div className=\"w-full\">\n <div className=\"bg-gray-200 rounded-full h-2\">\n <div\n className={\n hasError\n ? \"bg-red-500 h-2 rounded-full transition-all duration-500 ease-out\"\n : \"bg-[#11E5C5] h-2 rounded-full transition-all duration-500 ease-out\"\n }\n style={{\n width: `${\n ((currentStep + 1) / processingSteps.length) * 100\n }%`,\n }}\n ></div>\n </div>\n <p className=\"text-xs text-gray-500 mt-2 text-center\">\n {t(\"selfie.processing.step_of\", {\n current: currentStep + 1,\n total: processingSteps.length,\n })}\n </p>\n </div>\n\n {/* Footer with buttons */}\n {hasError && (\n <div className=\"sticky bottom-0 bg-white border-t border-gray-100 p-4 md:p-6\">\n <div className=\"w-full max-w-md mx-auto\">\n {/* Mobile layout - stacked buttons */}\n <div className=\"flex flex-col space-y-3 md:hidden\">\n {onContinueAnyway && (\n <ButtonDesktop type=\"back\" onClick={onContinueAnyway}>\n {t(\"errors.continue_anyway\", \"Poursuivre tout de même\")}\n </ButtonDesktop>\n )}\n <ButtonDesktop type=\"continue\" onClick={onRetake}>\n {t(\"selfie.confirmation.retake\", \"Reprendre le selfie\")}\n </ButtonDesktop>\n </div>\n\n {/* Desktop layout - horizontal buttons */}\n <div className=\"hidden md:flex gap-3 justify-between items-center\">\n {onContinueAnyway && (\n <ButtonDesktop type=\"back\" onClick={onContinueAnyway}>\n {t(\"errors.continue_anyway\", \"Poursuivre tout de même\")}\n </ButtonDesktop>\n )}\n <ButtonDesktop type=\"continue\" onClick={onRetake}>\n {t(\"selfie.confirmation.retake\", \"Reprendre le selfie\")}\n </ButtonDesktop>\n </div>\n </div>\n </div>\n )}\n </div>\n </div>\n </div>\n );\n};\n\nexport default SelfieProcessing;\n"],"names":["_jsx","_jsxs"],"mappings":"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"}
|