datakeen-session-react 1.1.140-dev.33 → 1.1.140-dev.35
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/DatakeenSession.js +2 -2
- package/dist/cjs/components/DatakeenSession.js.map +1 -1
- package/dist/cjs/components/selfie/SelfieConfirmation.js +1 -1
- package/dist/cjs/components/selfie/SelfieConfirmation.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/SelfieRecorder.js +10 -6
- package/dist/cjs/components/selfie/selfie-flow/SelfieRecorder.js.map +1 -1
- package/dist/cjs/components/session/Selfie.js +6 -5
- package/dist/cjs/components/session/Selfie.js.map +1 -1
- package/dist/cjs/components/session/SessionContent.js +2 -2
- package/dist/cjs/components/session/SessionContent.js.map +1 -1
- package/dist/cjs/components/template/ConditionNodeHandler.js +4 -0
- package/dist/cjs/components/template/ConditionNodeHandler.js.map +1 -1
- package/dist/cjs/components/template/TemplateNodeRenderer.js +25 -2
- package/dist/cjs/components/template/TemplateNodeRenderer.js.map +1 -1
- package/dist/cjs/hooks/useStepNavigation.js +1 -0
- package/dist/cjs/hooks/useStepNavigation.js.map +1 -1
- package/dist/cjs/index.css.js +1 -1
- package/dist/cjs/services/sessionService.js +20 -0
- package/dist/cjs/services/sessionService.js.map +1 -1
- package/dist/esm/components/DatakeenSession.js +2 -2
- package/dist/esm/components/DatakeenSession.js.map +1 -1
- package/dist/esm/components/selfie/SelfieConfirmation.js +1 -1
- package/dist/esm/components/selfie/SelfieConfirmation.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/SelfieRecorder.js +10 -6
- package/dist/esm/components/selfie/selfie-flow/SelfieRecorder.js.map +1 -1
- package/dist/esm/components/session/Selfie.js +6 -5
- package/dist/esm/components/session/Selfie.js.map +1 -1
- package/dist/esm/components/session/SessionContent.js +2 -2
- package/dist/esm/components/session/SessionContent.js.map +1 -1
- package/dist/esm/components/template/ConditionNodeHandler.js +4 -0
- package/dist/esm/components/template/ConditionNodeHandler.js.map +1 -1
- package/dist/esm/components/template/TemplateNodeRenderer.js +26 -3
- package/dist/esm/components/template/TemplateNodeRenderer.js.map +1 -1
- package/dist/esm/hooks/useStepNavigation.js +1 -0
- package/dist/esm/hooks/useStepNavigation.js.map +1 -1
- package/dist/esm/index.css.js +1 -1
- package/dist/esm/services/sessionService.js +20 -1
- package/dist/esm/services/sessionService.js.map +1 -1
- package/docs/multi-runs.md +100 -0
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sessionService.js","sources":["../../../../src/services/sessionService.ts"],"sourcesContent":["/**\n * Session Service\n *\n * Service for interacting with the Datakeen Session API.\n * Handles fetching session data by ID.\n */\n\nimport type {\n ClientInfo,\n SessionData,\n SessionTemplate,\n SessionTemplateNode,\n} from \"../types/session\";\nimport { apiService } from \"./api\";\nimport { logStatusModified } from \"./auditTrailService\";\nimport { clearSessionMemory } from \"./sessionMemoryStore\";\n\n/**\n * Fetches session data by ID from the Datakeen backend\n *\n * @param sessionId - The unique identifier of the session\n * @returns The session data\n */\nexport const fetchSessionById = async (\n sessionId: string,\n): Promise<SessionData> => {\n try {\n const response = await apiService.get(`/session/sdk/${sessionId}`);\n return response.data;\n } catch (error) {\n console.error(\"Error fetching session data:\", error);\n throw error;\n }\n};\n\n/** Sends client information (IP, device, browser, OS) to the backend for a specific session\n *\n * @param sessionId - The unique identifier of the session\n * @param clientInfo - The client information to send\n */\nexport const sendClientInfo = async (\n sessionId: string,\n clientInfo: ClientInfo,\n): Promise<void> => {\n try {\n await apiService.post(`/session/sdk/${sessionId}/client-info`, clientInfo);\n } catch (error) {\n console.error(\"Error sending client info:\", error);\n throw error;\n }\n};\n\n/**\n * Determines if the session template has a specific type of node\n *\n * @param template - The session template\n * @param nodeType - The type of node to check for\n * @returns true if the template has a node of the specified type, false otherwise\n */\nexport const hasNodeType = (\n template: SessionTemplate,\n nodeType: string,\n): boolean => {\n return template.nodes.some((node) => node.type === nodeType);\n};\n\n/**\n * Determines if the session template has a node with a specific requiredDocumentType\n *\n * @param template - The session template\n * @param requiredDocumentType - The requiredDocumentType to check for\n * @returns true if the template has a node with the specified requiredDocumentType, false otherwise\n */\nexport const hasDocumentTypeNode = (\n template: SessionTemplate,\n requiredDocumentType: string,\n): boolean => {\n return template.nodes.some(\n (node) => node.requiredDocumentType === requiredDocumentType,\n );\n};\n\n/**\n * Gets all nodes of a specific type\n *\n * @param template - The session template\n * @param nodeType - The type of node to get\n * @returns Array of nodes matching the type\n */\nexport const getNodesByType = (\n template: SessionTemplate,\n nodeType: string,\n): SessionTemplateNode[] => {\n return template.nodes.filter((node) => node.type === nodeType);\n};\n\n/**\n * Gets all nodes with a specific requiredDocumentType\n *\n * @param template - The session template\n * @param requiredDocumentType - The requiredDocumentType to get\n * @returns Array of nodes matching the requiredDocumentType\n */\nexport const getNodesByDocumentType = (\n template: SessionTemplate,\n requiredDocumentType: string,\n): SessionTemplateNode[] => {\n return template.nodes.filter(\n (node) => node.requiredDocumentType === requiredDocumentType,\n );\n};\n\n/**\n * Get document options for a specific document type\n *\n * @param template - The session template\n * @param requiredDocumentType - The document type to get options for\n * @returns Array of document options (empty if none found)\n */\nexport const getDocumentOptions = (\n template: SessionTemplate,\n requiredDocumentType: string,\n): string[] => {\n const node = template.nodes.find(\n (node) => node.requiredDocumentType === requiredDocumentType,\n );\n return node?.selectedOptions || [];\n};\n\n/**\n * Determines if the session template has a selfie step\n *\n * @param template - The session template\n * @returns true if the template has a selfie step, false otherwise\n */\nexport const hasSelfieCaptureStep = (template: SessionTemplate): boolean => {\n return hasNodeType(template, \"selfie-capture\");\n};\n\n/**\n * Determines if the session template has an ID document step\n *\n * @param template - The session template\n * @returns true if the template has an ID document step, false otherwise\n */\nexport const hasDocumentStep = (template: SessionTemplate): boolean => {\n // Check if there's any document-selection node with requiredDocumentType \"id-card\"\n // or if none specified, just check for document-selection nodes\n const hasIDCard = hasDocumentTypeNode(template, \"id-card\");\n return hasIDCard || hasNodeType(template, \"document-selection\");\n};\n\n/**\n * Determines if the session template has a JDD (proof of address) step\n *\n * @param template - The session template\n * @returns true if the template has a JDD step, false otherwise\n */\nexport const hasJDDStep = (template: SessionTemplate): boolean => {\n return hasDocumentTypeNode(template, \"jdd\");\n};\n\n/**\n * Determines if the session template has a proof of funds step\n *\n * @param template - The session template\n * @returns true if the template has a proof of funds step, false otherwise\n */\nexport const hasProofOfFundsStep = (template: SessionTemplate): boolean => {\n return hasDocumentTypeNode(template, \"income-proof\");\n};\n\n/**\n * Determines if the session template has a document collection step\n *\n * @param template - The session template\n * @returns true if the template has a document collection step, false otherwise\n */\nexport const hasDocumentCollectionStep = (\n template: SessionTemplate,\n): boolean => {\n return hasNodeType(template, \"document-collection\");\n};\n\n/**\n * Gets all node types in the template\n *\n * @param template - The session template\n * @returns Array of node types in the template\n */\nexport const getNodeTypes = (template: SessionTemplate): string[] => {\n return Array.from(new Set(template.nodes.map((node) => node.type)));\n};\n\n/**\n * Gets all document types required in the template\n *\n * @param template - The session template\n * @returns Array of document types required in the template\n */\nexport const getRequiredDocumentTypes = (\n template: SessionTemplate,\n): string[] => {\n return Array.from(\n new Set(\n template.nodes\n .filter((node) => node.requiredDocumentType)\n .map((node) => node.requiredDocumentType!),\n ),\n );\n};\n\n/**\n * Converts template document type to internal document type\n * This helps standardize document types between the template and the application\n *\n * @param templateDocType - The document type as defined in the template\n * @returns The internal document type used by the application\n */\nexport const convertTemplateDocTypeToInternal = (\n templateDocType: string,\n): string => {\n if (!templateDocType) return \"\";\n\n // Mapping between template document types and internal document types\n const typeMap: Record<string, string> = {\n \"id-card\": \"id-card\",\n jdd: \"jdd\",\n \"income-proof\": \"income-proof\", // Using consistent naming\n };\n\n return typeMap[templateDocType] || templateDocType;\n};\n\n/**\n * Converts internal document type to template document type\n *\n * @param internalDocType - The document type used internally by the application\n * @returns The document type as expected in the template\n */\nexport const convertInternalDocTypeToTemplate = (\n internalDocType: string,\n): string => {\n if (!internalDocType) return \"\";\n\n // Mapping between internal document types and template document types\n const typeMap: Record<string, string> = {\n \"id-card\": \"id-card\",\n jdd: \"jdd\",\n funds: \"income-proof\", // Map funds to income-proof for backwards compatibility\n \"income-proof\": \"income-proof\",\n };\n\n return typeMap[internalDocType] || internalDocType;\n};\n\n/**\n * Updates session data with user input information\n *\n * @param sessionId - The unique identifier of the session\n * @param userInput - The user input data (firstName, lastName, birthDate)\n * @returns The updated session data\n */\nexport const updateSessionUserInput = async (\n sessionId: string,\n userInput: {\n firstName?: string;\n lastName?: string;\n birthDate?: string;\n [key: string]: unknown;\n },\n): Promise<SessionData> => {\n try {\n const response = await apiService.patch(`/session/sdk/${sessionId}`, {\n userInput,\n });\n return response.data;\n } catch (error) {\n console.error(\"Error updating session data:\", error);\n throw error;\n }\n};\n\n/**\n * Updates session data with contact information\n *\n * @param sessionId - The unique identifier of the session\n * @param contactInfo - The contact information data (email, phoneNumber)\n * @returns The updated session data\n */\nexport const updateSessionContactInfo = async (\n sessionId: string,\n contactInfo: {\n email: string;\n phoneNumber: string;\n [key: string]: unknown;\n },\n): Promise<SessionData> => {\n try {\n const response = await apiService.patch(`/session/sdk/${sessionId}`, {\n contactInfo,\n });\n return response.data;\n } catch (error) {\n console.error(\"Error updating contact information:\", error);\n throw error;\n }\n};\n\n/**\n * Updates session status\n *\n * @param sessionId - The unique identifier of the session\n * @param status - The new status for the session\n * @returns The updated session data\n */\nexport const updateSessionStatus = async (\n sessionId: string,\n status: string,\n): Promise<SessionData> => {\n try {\n const response = await apiService.patch(`/session/sdk/${sessionId}`, {\n status,\n });\n\n // Log status modification in audit trail\n if (response.data && response.data.analysisId) {\n try {\n await logStatusModified(\n sessionId,\n status,\n response.data.clientInfoId || undefined,\n );\n } catch (err) {\n console.error(\"Failed to log status modification in audit trail:\", err);\n // Non-blocking error - continue session\n }\n }\n\n return response.data;\n } catch (error) {\n console.error(\"Error updating session status:\", error);\n throw error;\n }\n};\n\n/**\n * Updates the current step in the session\n *\n * @param sessionId - The unique identifier of the session\n * @param currentStep - The current step index in the workflow\n * @returns The updated session data\n */\nexport const updateSessionCurrentStep = async (\n sessionId: string,\n currentStep: number,\n): Promise<SessionData> => {\n try {\n const response = await apiService.patch(`/session/sdk/${sessionId}`, {\n currentStep,\n });\n return response.data;\n } catch (error) {\n console.error(\"Error updating session current step:\", error);\n throw error;\n }\n};\n\n/**\n * Gets the journey steps from the template in order\n *\n * @param template - The session template\n * @returns Array of ordered steps\n */\nexport const getOrderedJourneySteps = (\n template: SessionTemplate,\n): SessionTemplateNode[] => {\n // Filter out only start nodes, keep end nodes for proper journey completion, then sort by order\n return template.nodes\n .filter((node) => node.type !== \"start\")\n .sort((a, b) => a.order - b.order);\n};\n\nconst normalizeHandle = (value?: string): string => {\n return (value || \"\").trim().toLowerCase();\n};\n\n/**\n * Finds the outgoing edge to follow from a node.\n *\n * Resolution order:\n * 1. Exact handle match via sourceHandle/conditionValue.\n * 2. For condition:false loops, fallback to targetHandle=right.\n * 3. First outgoing edge as final fallback.\n */\nexport const findOutgoingEdge = (\n currentNodeId: string,\n template: SessionTemplate,\n handle?: string,\n): SessionTemplate[\"edges\"][number] | null => {\n const outgoingEdges = (template.edges || []).filter(\n (edge) => edge.source === currentNodeId,\n );\n\n if (outgoingEdges.length === 0) {\n return null;\n }\n\n if (!handle) {\n return outgoingEdges[0];\n }\n\n const normalizedHandle = normalizeHandle(handle);\n const edgeByHandle = outgoingEdges.find((edge) => {\n return (\n normalizeHandle(edge.sourceHandle) === normalizedHandle ||\n normalizeHandle(edge.conditionValue) === normalizedHandle\n );\n });\n\n if (edgeByHandle) {\n return edgeByHandle;\n }\n\n const currentNode = template.nodes.find((node) => node.id === currentNodeId);\n if (currentNode?.type === \"condition\" && normalizedHandle === \"false\") {\n const rightHandleLoopEdge = outgoingEdges.find(\n (edge) => normalizeHandle(edge.targetHandle) === \"right\",\n );\n if (rightHandleLoopEdge) {\n return rightHandleLoopEdge;\n }\n }\n\n return outgoingEdges[0];\n};\n\n/**\n * Gets the next step index by following the graph edge from the current node\n *\n * @param currentNodeId - The ID of the current node\n * @param template - The session template\n * @returns The next step index (1-based) or null if no edge found\n */\nexport const getNextStepIndex = (\n currentNodeId: string,\n template: SessionTemplate,\n handle?: string,\n): number | null => {\n const orderedNodes = getOrderedJourneySteps(template);\n const edge = findOutgoingEdge(currentNodeId, template, handle);\n\n if (!edge) {\n console.debug(\n `[sessionService] No outgoing edge found for node ${currentNodeId}${handle ? ` with handle ${handle}` : \"\"}`,\n );\n return null;\n }\n\n const targetId = edge.target;\n const targetIndex = orderedNodes.findIndex((n) => n.id === targetId);\n\n if (targetIndex === -1) {\n console.debug(\n `[sessionService] Target node ${targetId} not found in ordered steps`,\n );\n return null;\n }\n\n // steps are 1-indexed in the SDK (0 is StartSession)\n return 1 + targetIndex;\n};\n\n/**\n * Reconstructs the navigation history by following the graph from step 0\n * up to (and including) targetStep. Returns [0, ...stepIndices].\n * If the graph path cannot reach targetStep, falls back to [0, targetStep].\n */\nexport const reconstructHistoryToStep = (\n targetStep: number,\n template: SessionTemplate,\n): number[] => {\n if (targetStep <= 0) return [0];\n\n const orderedNodes = getOrderedJourneySteps(template);\n const history: number[] = [0];\n let currentStep = 1; // first node is step 1\n\n // Follow the default (first) edge from each node in sequence\n for (let safetyLimit = 0; safetyLimit < orderedNodes.length + 1; safetyLimit++) {\n if (currentStep === targetStep) {\n history.push(currentStep);\n break;\n }\n if (currentStep > targetStep) break;\n\n const nodeIndex = currentStep - 1;\n const currentNode = orderedNodes[nodeIndex];\n if (!currentNode) break;\n\n history.push(currentStep);\n\n const nextStep = getNextStepIndex(currentNode.id, template);\n if (nextStep === null) break;\n currentStep = nextStep;\n }\n\n // Fallback: if we couldn't reach targetStep via graph, use simple seed\n if (history[history.length - 1] !== targetStep) {\n return [0, targetStep];\n }\n\n return history;\n};\n\n/**\n * Maps a template node type to a step component type\n *\n * @param node - The session template node\n * @returns The step component type\n */\nexport const getStepComponentType = (node: SessionTemplateNode): string => {\n // Map from template node types to component types\n const typeMap: Record<string, string> = {\n \"document-selection\": \"document\",\n \"document-collection\": \"document-collection\",\n \"selfie-capture\": \"selfie\",\n \"contact-info\": \"contact-info\",\n \"user-input\": \"user-input\",\n \"otp-verification\": \"otp\",\n };\n\n // First check the node type\n if (node.type in typeMap) {\n return typeMap[node.type];\n }\n\n // Then check the requiredDocumentType\n if (node.requiredDocumentType) {\n return node.requiredDocumentType;\n }\n\n // Default fallback\n return node.type;\n};\n\n/**\n * Checks if a session has expired\n *\n * @param session - The session data to check\n * @returns true if the session has expired, false otherwise\n */\nexport const isSessionExpired = (session: SessionData): boolean => {\n if (!session.expireTime) {\n return false;\n }\n\n const currentTime = Date.now();\n return currentTime > session.expireTime;\n};\n\n/**\n * Stores document options in localStorage for a specific document type\n *\n * @param sessionId - The session ID\n * @param documentTypeId - The document type ID (e.g., 'jdd', 'income-proof')\n * @param options - The options to store\n */\nexport const storeDocumentOptions = (\n sessionId: string,\n documentTypeId: string,\n options: string[],\n): void => {\n if (!sessionId || !documentTypeId || !options || options.length === 0) {\n console.warn(\"Missing data for storeDocumentOptions:\", {\n sessionId,\n documentTypeId,\n options,\n });\n return;\n }\n\n // Create a consistent key format based on document type\n let storageKey = \"\";\n\n switch (documentTypeId) {\n case \"jdd\":\n storageKey = `jddOptions_${sessionId}`;\n break;\n case \"income-proof\":\n storageKey = `fundsOptions_${sessionId}`;\n break;\n case \"id-card\":\n storageKey = `idOptions_${sessionId}`;\n break;\n case \"document-collection\":\n storageKey = `documentCollectionOptions_${sessionId}`;\n break;\n default:\n storageKey = `${documentTypeId}Options_${sessionId}`;\n }\n\n localStorage.setItem(storageKey, JSON.stringify(options));\n};\n\n/**\n * Retrieves document options from localStorage for a specific document type\n *\n * @param sessionId - The session ID\n * @param documentTypeId - The document type ID (e.g., 'jdd', 'income-proof')\n * @returns Array of options or default options if none found\n */\nexport const retrieveDocumentOptions = (\n sessionId: string,\n documentTypeId: string,\n): string[] => {\n if (!sessionId || !documentTypeId) {\n console.warn(\"Missing data for retrieveDocumentOptions:\", {\n sessionId,\n documentTypeId,\n });\n return [];\n }\n\n // Create consistent key formats to check\n const possibleKeys = [\n `${documentTypeId}Options_${sessionId}`,\n documentTypeId === \"jdd\" ? `jddOptions_${sessionId}` : \"\",\n documentTypeId === \"income-proof\" ? `fundsOptions_${sessionId}` : \"\",\n documentTypeId === \"id-card\" ? `idOptions_${sessionId}` : \"\",\n documentTypeId === \"document-collection\"\n ? `documentCollectionOptions_${sessionId}`\n : \"\",\n ].filter(Boolean);\n\n // Try each possible key\n for (const key of possibleKeys) {\n const savedOptions = localStorage.getItem(key);\n if (savedOptions) {\n try {\n const parsedOptions = JSON.parse(savedOptions);\n\n return parsedOptions;\n } catch (e) {\n console.error(\n `Error parsing options for ${documentTypeId} with key ${key}:`,\n e,\n );\n }\n }\n }\n\n // Return default options if none found\n console.warn(`No options found for ${documentTypeId}, using defaults`);\n if (documentTypeId === \"jdd\") {\n return [\n \"Facture d'électricité (< 3 mois)\",\n \"Facture de gaz (< 3 mois)\",\n \"Facture d'eau (< 3 mois)\",\n \"Quittance de loyer (< 3 mois)\",\n \"Facture téléphone/internet (< 3 mois)\",\n \"Attestation d'assurance habitation (< 3 mois)\",\n ];\n } else if (documentTypeId === \"income-proof\") {\n return [\n \"Bulletin de salaire\",\n \"Avis d'imposition\",\n \"Relevé de compte bancaire\",\n \"Attestation de revenus\",\n \"Contrat de travail\",\n ];\n } else if (documentTypeId === \"id-card\") {\n return [\"Carte nationale d'identité\", \"Passeport\", \"Permis de conduire\"];\n } else if (documentTypeId === \"document-collection\") {\n return [\"Document administratif\", \"Justificatif\", \"Attestation\"];\n }\n\n return [];\n};\n\nconst clearStorageBySessionId = (sessionId: string): void => {\n const scopedKeys = [\n `userInput_${sessionId}`,\n `contactInfo_${sessionId}`,\n `sessionData_${sessionId}`,\n ];\n\n scopedKeys.forEach((key) => {\n localStorage.removeItem(key);\n sessionStorage.removeItem(key);\n });\n\n for (let i = localStorage.length - 1; i >= 0; i -= 1) {\n const key = localStorage.key(i);\n if (!key) {\n continue;\n }\n if (key.endsWith(`_${sessionId}`)) {\n localStorage.removeItem(key);\n }\n }\n\n for (let i = sessionStorage.length - 1; i >= 0; i -= 1) {\n const key = sessionStorage.key(i);\n if (!key) {\n continue;\n }\n if (key.endsWith(`_${sessionId}`)) {\n sessionStorage.removeItem(key);\n }\n }\n\n if (localStorage.getItem(\"sessionId\") === sessionId) {\n localStorage.removeItem(\"sessionId\");\n }\n if (sessionStorage.getItem(\"sessionId\") === sessionId) {\n sessionStorage.removeItem(\"sessionId\");\n }\n};\n\n/**\n * Clears all client-side session traces (memory + browser storage)\n * for a given session. This is intentionally aggressive for security.\n */\nexport const clearSessionSensitiveData = (sessionId?: string): void => {\n clearSessionMemory(sessionId);\n\n if (sessionId) {\n clearStorageBySessionId(sessionId);\n return;\n }\n\n localStorage.removeItem(\"sessionId\");\n sessionStorage.removeItem(\"sessionId\");\n\n for (let i = localStorage.length - 1; i >= 0; i -= 1) {\n const key = localStorage.key(i);\n if (!key) {\n continue;\n }\n if (\n key.startsWith(\"userInput_\") ||\n key.startsWith(\"contactInfo_\") ||\n key.includes(\"Options_\")\n ) {\n localStorage.removeItem(key);\n }\n }\n\n for (let i = sessionStorage.length - 1; i >= 0; i -= 1) {\n const key = sessionStorage.key(i);\n if (!key) {\n continue;\n }\n if (\n key.startsWith(\"userInput_\") ||\n key.startsWith(\"contactInfo_\") ||\n key.includes(\"Options_\")\n ) {\n sessionStorage.removeItem(key);\n }\n }\n};\n"],"names":["__awaiter","apiService","logStatusModified","clearSessionMemory"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"sessionService.js","sources":["../../../../src/services/sessionService.ts"],"sourcesContent":["/**\n * Session Service\n *\n * Service for interacting with the Datakeen Session API.\n * Handles fetching session data by ID.\n */\n\nimport type {\n ClientInfo,\n SessionData,\n SessionTemplate,\n SessionTemplateNode,\n} from \"../types/session\";\nimport { apiService } from \"./api\";\nimport { logStatusModified } from \"./auditTrailService\";\nimport { clearSessionMemory } from \"./sessionMemoryStore\";\n\n/**\n * Fetches session data by ID from the Datakeen backend\n *\n * @param sessionId - The unique identifier of the session\n * @returns The session data\n */\nexport const fetchSessionById = async (\n sessionId: string,\n): Promise<SessionData> => {\n try {\n const response = await apiService.get(`/session/sdk/${sessionId}`);\n return response.data;\n } catch (error) {\n console.error(\"Error fetching session data:\", error);\n throw error;\n }\n};\n\n/** Sends client information (IP, device, browser, OS) to the backend for a specific session\n *\n * @param sessionId - The unique identifier of the session\n * @param clientInfo - The client information to send\n */\nexport const sendClientInfo = async (\n sessionId: string,\n clientInfo: ClientInfo,\n): Promise<void> => {\n try {\n await apiService.post(`/session/sdk/${sessionId}/client-info`, clientInfo);\n } catch (error) {\n console.error(\"Error sending client info:\", error);\n throw error;\n }\n};\n\n/**\n * Determines if the session template has a specific type of node\n *\n * @param template - The session template\n * @param nodeType - The type of node to check for\n * @returns true if the template has a node of the specified type, false otherwise\n */\nexport const hasNodeType = (\n template: SessionTemplate,\n nodeType: string,\n): boolean => {\n return template.nodes.some((node) => node.type === nodeType);\n};\n\n/**\n * Determines if the session template has a node with a specific requiredDocumentType\n *\n * @param template - The session template\n * @param requiredDocumentType - The requiredDocumentType to check for\n * @returns true if the template has a node with the specified requiredDocumentType, false otherwise\n */\nexport const hasDocumentTypeNode = (\n template: SessionTemplate,\n requiredDocumentType: string,\n): boolean => {\n return template.nodes.some(\n (node) => node.requiredDocumentType === requiredDocumentType,\n );\n};\n\n/**\n * Gets all nodes of a specific type\n *\n * @param template - The session template\n * @param nodeType - The type of node to get\n * @returns Array of nodes matching the type\n */\nexport const getNodesByType = (\n template: SessionTemplate,\n nodeType: string,\n): SessionTemplateNode[] => {\n return template.nodes.filter((node) => node.type === nodeType);\n};\n\n/**\n * Gets all nodes with a specific requiredDocumentType\n *\n * @param template - The session template\n * @param requiredDocumentType - The requiredDocumentType to get\n * @returns Array of nodes matching the requiredDocumentType\n */\nexport const getNodesByDocumentType = (\n template: SessionTemplate,\n requiredDocumentType: string,\n): SessionTemplateNode[] => {\n return template.nodes.filter(\n (node) => node.requiredDocumentType === requiredDocumentType,\n );\n};\n\n/**\n * Get document options for a specific document type\n *\n * @param template - The session template\n * @param requiredDocumentType - The document type to get options for\n * @returns Array of document options (empty if none found)\n */\nexport const getDocumentOptions = (\n template: SessionTemplate,\n requiredDocumentType: string,\n): string[] => {\n const node = template.nodes.find(\n (node) => node.requiredDocumentType === requiredDocumentType,\n );\n return node?.selectedOptions || [];\n};\n\n/**\n * Determines if the session template has a selfie step\n *\n * @param template - The session template\n * @returns true if the template has a selfie step, false otherwise\n */\nexport const hasSelfieCaptureStep = (template: SessionTemplate): boolean => {\n return hasNodeType(template, \"selfie-capture\");\n};\n\n/**\n * Determines if the session template has an ID document step\n *\n * @param template - The session template\n * @returns true if the template has an ID document step, false otherwise\n */\nexport const hasDocumentStep = (template: SessionTemplate): boolean => {\n // Check if there's any document-selection node with requiredDocumentType \"id-card\"\n // or if none specified, just check for document-selection nodes\n const hasIDCard = hasDocumentTypeNode(template, \"id-card\");\n return hasIDCard || hasNodeType(template, \"document-selection\");\n};\n\n/**\n * Determines if the session template has a JDD (proof of address) step\n *\n * @param template - The session template\n * @returns true if the template has a JDD step, false otherwise\n */\nexport const hasJDDStep = (template: SessionTemplate): boolean => {\n return hasDocumentTypeNode(template, \"jdd\");\n};\n\n/**\n * Determines if the session template has a proof of funds step\n *\n * @param template - The session template\n * @returns true if the template has a proof of funds step, false otherwise\n */\nexport const hasProofOfFundsStep = (template: SessionTemplate): boolean => {\n return hasDocumentTypeNode(template, \"income-proof\");\n};\n\n/**\n * Determines if the session template has a document collection step\n *\n * @param template - The session template\n * @returns true if the template has a document collection step, false otherwise\n */\nexport const hasDocumentCollectionStep = (\n template: SessionTemplate,\n): boolean => {\n return hasNodeType(template, \"document-collection\");\n};\n\n/**\n * Gets all node types in the template\n *\n * @param template - The session template\n * @returns Array of node types in the template\n */\nexport const getNodeTypes = (template: SessionTemplate): string[] => {\n return Array.from(new Set(template.nodes.map((node) => node.type)));\n};\n\n/**\n * Gets all document types required in the template\n *\n * @param template - The session template\n * @returns Array of document types required in the template\n */\nexport const getRequiredDocumentTypes = (\n template: SessionTemplate,\n): string[] => {\n return Array.from(\n new Set(\n template.nodes\n .filter((node) => node.requiredDocumentType)\n .map((node) => node.requiredDocumentType!),\n ),\n );\n};\n\n/**\n * Converts template document type to internal document type\n * This helps standardize document types between the template and the application\n *\n * @param templateDocType - The document type as defined in the template\n * @returns The internal document type used by the application\n */\nexport const convertTemplateDocTypeToInternal = (\n templateDocType: string,\n): string => {\n if (!templateDocType) return \"\";\n\n // Mapping between template document types and internal document types\n const typeMap: Record<string, string> = {\n \"id-card\": \"id-card\",\n jdd: \"jdd\",\n \"income-proof\": \"income-proof\", // Using consistent naming\n };\n\n return typeMap[templateDocType] || templateDocType;\n};\n\n/**\n * Converts internal document type to template document type\n *\n * @param internalDocType - The document type used internally by the application\n * @returns The document type as expected in the template\n */\nexport const convertInternalDocTypeToTemplate = (\n internalDocType: string,\n): string => {\n if (!internalDocType) return \"\";\n\n // Mapping between internal document types and template document types\n const typeMap: Record<string, string> = {\n \"id-card\": \"id-card\",\n jdd: \"jdd\",\n funds: \"income-proof\", // Map funds to income-proof for backwards compatibility\n \"income-proof\": \"income-proof\",\n };\n\n return typeMap[internalDocType] || internalDocType;\n};\n\n/**\n * Updates session data with user input information\n *\n * @param sessionId - The unique identifier of the session\n * @param userInput - The user input data (firstName, lastName, birthDate)\n * @returns The updated session data\n */\nexport const updateSessionUserInput = async (\n sessionId: string,\n userInput: {\n firstName?: string;\n lastName?: string;\n birthDate?: string;\n [key: string]: unknown;\n },\n): Promise<SessionData> => {\n try {\n const response = await apiService.patch(`/session/sdk/${sessionId}`, {\n userInput,\n });\n return response.data;\n } catch (error) {\n console.error(\"Error updating session data:\", error);\n throw error;\n }\n};\n\n/**\n * Updates session data with contact information\n *\n * @param sessionId - The unique identifier of the session\n * @param contactInfo - The contact information data (email, phoneNumber)\n * @returns The updated session data\n */\nexport const updateSessionContactInfo = async (\n sessionId: string,\n contactInfo: {\n email: string;\n phoneNumber: string;\n [key: string]: unknown;\n },\n): Promise<SessionData> => {\n try {\n const response = await apiService.patch(`/session/sdk/${sessionId}`, {\n contactInfo,\n });\n return response.data;\n } catch (error) {\n console.error(\"Error updating contact information:\", error);\n throw error;\n }\n};\n\n/**\n * Updates session status\n *\n * @param sessionId - The unique identifier of the session\n * @param status - The new status for the session\n * @returns The updated session data\n */\nexport const updateSessionStatus = async (\n sessionId: string,\n status: string,\n): Promise<SessionData> => {\n try {\n const response = await apiService.patch(`/session/sdk/${sessionId}`, {\n status,\n });\n\n // Log status modification in audit trail\n if (response.data && response.data.analysisId) {\n try {\n await logStatusModified(\n sessionId,\n status,\n response.data.clientInfoId || undefined,\n );\n } catch (err) {\n console.error(\"Failed to log status modification in audit trail:\", err);\n // Non-blocking error - continue session\n }\n }\n\n return response.data;\n } catch (error) {\n console.error(\"Error updating session status:\", error);\n throw error;\n }\n};\n\n/**\n * Updates the current step in the session\n *\n * @param sessionId - The unique identifier of the session\n * @param currentStep - The current step index in the workflow\n * @returns The updated session data\n */\nexport const updateSessionCurrentStep = async (\n sessionId: string,\n currentStep: number,\n): Promise<SessionData> => {\n try {\n const response = await apiService.patch(`/session/sdk/${sessionId}`, {\n currentStep,\n });\n return response.data;\n } catch (error) {\n console.error(\"Error updating session current step:\", error);\n throw error;\n }\n};\n\n/**\n * Gets the journey steps from the template in order\n *\n * @param template - The session template\n * @returns Array of ordered steps\n */\nexport const getOrderedJourneySteps = (\n template: SessionTemplate,\n): SessionTemplateNode[] => {\n // Filter out only start nodes, keep end nodes for proper journey completion, then sort by order\n return template.nodes\n .filter((node) => node.type !== \"start\")\n .sort((a, b) => a.order - b.order);\n};\n\nconst normalizeHandle = (value?: string): string => {\n return (value || \"\").trim().toLowerCase();\n};\n\n/**\n * Finds the outgoing edge to follow from a node.\n *\n * Resolution order:\n * 1. Exact handle match via sourceHandle/conditionValue.\n * 2. For condition:false loops, fallback to targetHandle=right.\n * 3. First outgoing edge as final fallback.\n */\nexport const findOutgoingEdge = (\n currentNodeId: string,\n template: SessionTemplate,\n handle?: string,\n): SessionTemplate[\"edges\"][number] | null => {\n const outgoingEdges = (template.edges || []).filter(\n (edge) => edge.source === currentNodeId,\n );\n\n if (outgoingEdges.length === 0) {\n return null;\n }\n\n if (!handle) {\n return outgoingEdges[0];\n }\n\n const normalizedHandle = normalizeHandle(handle);\n const edgeByHandle = outgoingEdges.find((edge) => {\n return (\n normalizeHandle(edge.sourceHandle) === normalizedHandle ||\n normalizeHandle(edge.conditionValue) === normalizedHandle\n );\n });\n\n if (edgeByHandle) {\n return edgeByHandle;\n }\n\n const currentNode = template.nodes.find((node) => node.id === currentNodeId);\n if (currentNode?.type === \"condition\" && normalizedHandle === \"false\") {\n const rightHandleLoopEdge = outgoingEdges.find(\n (edge) => normalizeHandle(edge.targetHandle) === \"right\",\n );\n if (rightHandleLoopEdge) {\n return rightHandleLoopEdge;\n }\n }\n\n return outgoingEdges[0];\n};\n\n/**\n * Gets the next step index by following the graph edge from the current node\n *\n * @param currentNodeId - The ID of the current node\n * @param template - The session template\n * @returns The next step index (1-based) or null if no edge found\n */\nexport const getNextStepIndex = (\n currentNodeId: string,\n template: SessionTemplate,\n handle?: string,\n): number | null => {\n const orderedNodes = getOrderedJourneySteps(template);\n const edge = findOutgoingEdge(currentNodeId, template, handle);\n\n if (!edge) {\n console.debug(\n `[sessionService] No outgoing edge found for node ${currentNodeId}${handle ? ` with handle ${handle}` : \"\"}`,\n );\n return null;\n }\n\n const targetId = edge.target;\n const targetIndex = orderedNodes.findIndex((n) => n.id === targetId);\n\n if (targetIndex === -1) {\n console.debug(\n `[sessionService] Target node ${targetId} not found in ordered steps`,\n );\n return null;\n }\n\n // steps are 1-indexed in the SDK (0 is StartSession)\n return 1 + targetIndex;\n};\n\n/**\n * Reconstructs the navigation history by following the graph from step 0\n * up to (and including) targetStep. Returns [0, ...stepIndices].\n * If the graph path cannot reach targetStep, falls back to [0, targetStep].\n */\nexport const reconstructHistoryToStep = (\n targetStep: number,\n template: SessionTemplate,\n): number[] => {\n if (targetStep <= 0) return [0];\n\n const orderedNodes = getOrderedJourneySteps(template);\n const history: number[] = [0];\n let currentStep = 1; // first node is step 1\n\n // Follow the default (first) edge from each node in sequence\n for (let safetyLimit = 0; safetyLimit < orderedNodes.length + 1; safetyLimit++) {\n if (currentStep === targetStep) {\n history.push(currentStep);\n break;\n }\n if (currentStep > targetStep) break;\n\n const nodeIndex = currentStep - 1;\n const currentNode = orderedNodes[nodeIndex];\n if (!currentNode) break;\n\n history.push(currentStep);\n\n const nextStep = getNextStepIndex(currentNode.id, template);\n if (nextStep === null) break;\n currentStep = nextStep;\n }\n\n // Fallback: if we couldn't reach targetStep via graph, use simple seed\n if (history[history.length - 1] !== targetStep) {\n return [0, targetStep];\n }\n\n return history;\n};\n\n/**\n * Maps a template node type to a step component type\n *\n * @param node - The session template node\n * @returns The step component type\n */\nexport const getStepComponentType = (node: SessionTemplateNode): string => {\n // Map from template node types to component types\n const typeMap: Record<string, string> = {\n \"document-selection\": \"document\",\n \"document-collection\": \"document-collection\",\n \"selfie-capture\": \"selfie\",\n \"contact-info\": \"contact-info\",\n \"user-input\": \"user-input\",\n \"otp-verification\": \"otp\",\n };\n\n // First check the node type\n if (node.type in typeMap) {\n return typeMap[node.type];\n }\n\n // Then check the requiredDocumentType\n if (node.requiredDocumentType) {\n return node.requiredDocumentType;\n }\n\n // Default fallback\n return node.type;\n};\n\n/**\n * Checks if a session has expired\n *\n * @param session - The session data to check\n * @returns true if the session has expired, false otherwise\n */\nexport const isSessionExpired = (session: SessionData): boolean => {\n if (!session.expireTime) {\n return false;\n }\n\n const currentTime = Date.now();\n return currentTime > session.expireTime;\n};\n\n/**\n * Stores document options in localStorage for a specific document type\n *\n * @param sessionId - The session ID\n * @param documentTypeId - The document type ID (e.g., 'jdd', 'income-proof')\n * @param options - The options to store\n */\nexport const storeDocumentOptions = (\n sessionId: string,\n documentTypeId: string,\n options: string[],\n): void => {\n if (!sessionId || !documentTypeId || !options || options.length === 0) {\n console.warn(\"Missing data for storeDocumentOptions:\", {\n sessionId,\n documentTypeId,\n options,\n });\n return;\n }\n\n // Create a consistent key format based on document type\n let storageKey = \"\";\n\n switch (documentTypeId) {\n case \"jdd\":\n storageKey = `jddOptions_${sessionId}`;\n break;\n case \"income-proof\":\n storageKey = `fundsOptions_${sessionId}`;\n break;\n case \"id-card\":\n storageKey = `idOptions_${sessionId}`;\n break;\n case \"document-collection\":\n storageKey = `documentCollectionOptions_${sessionId}`;\n break;\n default:\n storageKey = `${documentTypeId}Options_${sessionId}`;\n }\n\n localStorage.setItem(storageKey, JSON.stringify(options));\n};\n\n/**\n * Retrieves document options from localStorage for a specific document type\n *\n * @param sessionId - The session ID\n * @param documentTypeId - The document type ID (e.g., 'jdd', 'income-proof')\n * @returns Array of options or default options if none found\n */\nexport const retrieveDocumentOptions = (\n sessionId: string,\n documentTypeId: string,\n): string[] => {\n if (!sessionId || !documentTypeId) {\n console.warn(\"Missing data for retrieveDocumentOptions:\", {\n sessionId,\n documentTypeId,\n });\n return [];\n }\n\n // Create consistent key formats to check\n const possibleKeys = [\n `${documentTypeId}Options_${sessionId}`,\n documentTypeId === \"jdd\" ? `jddOptions_${sessionId}` : \"\",\n documentTypeId === \"income-proof\" ? `fundsOptions_${sessionId}` : \"\",\n documentTypeId === \"id-card\" ? `idOptions_${sessionId}` : \"\",\n documentTypeId === \"document-collection\"\n ? `documentCollectionOptions_${sessionId}`\n : \"\",\n ].filter(Boolean);\n\n // Try each possible key\n for (const key of possibleKeys) {\n const savedOptions = localStorage.getItem(key);\n if (savedOptions) {\n try {\n const parsedOptions = JSON.parse(savedOptions);\n\n return parsedOptions;\n } catch (e) {\n console.error(\n `Error parsing options for ${documentTypeId} with key ${key}:`,\n e,\n );\n }\n }\n }\n\n // Return default options if none found\n console.warn(`No options found for ${documentTypeId}, using defaults`);\n if (documentTypeId === \"jdd\") {\n return [\n \"Facture d'électricité (< 3 mois)\",\n \"Facture de gaz (< 3 mois)\",\n \"Facture d'eau (< 3 mois)\",\n \"Quittance de loyer (< 3 mois)\",\n \"Facture téléphone/internet (< 3 mois)\",\n \"Attestation d'assurance habitation (< 3 mois)\",\n ];\n } else if (documentTypeId === \"income-proof\") {\n return [\n \"Bulletin de salaire\",\n \"Avis d'imposition\",\n \"Relevé de compte bancaire\",\n \"Attestation de revenus\",\n \"Contrat de travail\",\n ];\n } else if (documentTypeId === \"id-card\") {\n return [\"Carte nationale d'identité\", \"Passeport\", \"Permis de conduire\"];\n } else if (documentTypeId === \"document-collection\") {\n return [\"Document administratif\", \"Justificatif\", \"Attestation\"];\n }\n\n return [];\n};\n\nconst clearStorageBySessionId = (sessionId: string): void => {\n const scopedKeys = [\n `userInput_${sessionId}`,\n `contactInfo_${sessionId}`,\n `sessionData_${sessionId}`,\n ];\n\n scopedKeys.forEach((key) => {\n localStorage.removeItem(key);\n sessionStorage.removeItem(key);\n });\n\n for (let i = localStorage.length - 1; i >= 0; i -= 1) {\n const key = localStorage.key(i);\n if (!key) {\n continue;\n }\n if (key.endsWith(`_${sessionId}`)) {\n localStorage.removeItem(key);\n }\n }\n\n for (let i = sessionStorage.length - 1; i >= 0; i -= 1) {\n const key = sessionStorage.key(i);\n if (!key) {\n continue;\n }\n if (key.endsWith(`_${sessionId}`)) {\n sessionStorage.removeItem(key);\n }\n }\n\n if (localStorage.getItem(\"sessionId\") === sessionId) {\n localStorage.removeItem(\"sessionId\");\n }\n if (sessionStorage.getItem(\"sessionId\") === sessionId) {\n sessionStorage.removeItem(\"sessionId\");\n }\n};\n\n/**\n * Clears all client-side session traces (memory + browser storage)\n * for a given session. This is intentionally aggressive for security.\n */\nexport const clearSessionSensitiveData = (sessionId?: string): void => {\n clearSessionMemory(sessionId);\n\n if (sessionId) {\n clearStorageBySessionId(sessionId);\n return;\n }\n\n localStorage.removeItem(\"sessionId\");\n sessionStorage.removeItem(\"sessionId\");\n\n for (let i = localStorage.length - 1; i >= 0; i -= 1) {\n const key = localStorage.key(i);\n if (!key) {\n continue;\n }\n if (\n key.startsWith(\"userInput_\") ||\n key.startsWith(\"contactInfo_\") ||\n key.includes(\"Options_\")\n ) {\n localStorage.removeItem(key);\n }\n }\n\n for (let i = sessionStorage.length - 1; i >= 0; i -= 1) {\n const key = sessionStorage.key(i);\n if (!key) {\n continue;\n }\n if (\n key.startsWith(\"userInput_\") ||\n key.startsWith(\"contactInfo_\") ||\n key.includes(\"Options_\")\n ) {\n sessionStorage.removeItem(key);\n }\n }\n};\n\n/**\n * Returns the pre-fill data for a given run index from a `userInput` object\n * that contains a `_list` array.\n *\n * Convention: when the integrator wants to pre-fill different data per run\n * (e.g. multiple persons in a loop), they pass `userInput: { _list: [...] }`\n * at session creation. Each element in `_list` corresponds to a run (0-indexed).\n *\n * @param userInput - The session's userInput object\n * @param runIndex - The current run index (0 = first pass, 1 = second pass, …)\n * @returns The pre-fill data for that run, or null if not defined\n */\nexport const getRunPrefillData = (\n userInput: Record<string, unknown>,\n runIndex: number,\n): Record<string, unknown> | null => {\n const list = userInput?._list;\n if (!Array.isArray(list)) return null;\n return (list[runIndex] as Record<string, unknown>) ?? null;\n};\n"],"names":["__awaiter","apiService","logStatusModified","clearSessionMemory"],"mappings":"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"}
|
|
@@ -50,7 +50,7 @@ var DatakeenSession = function (_a) {
|
|
|
50
50
|
// Session data management
|
|
51
51
|
var _p = useSessionData(sessionId, clientInfo, clientInfoLoaded), session = _p.session, setSession = _p.setSession, loading = _p.loading, setLoading = _p.setLoading, error = _p.error, isExpired = _p.isExpired, userInput = _p.userInput, setUserInput = _p.setUserInput, contactInfo = _p.contactInfo, setContactInfo = _p.setContactInfo, loadSession = _p.loadSession, handleRetrySession = _p.handleRetrySession;
|
|
52
52
|
// Step navigation management
|
|
53
|
-
var _q = useStepNavigation(sessionId, session === null || session === void 0 ? void 0 : session.status, session === null || session === void 0 ? void 0 : session.currentStep, session === null || session === void 0 ? void 0 : session.template), step = _q.step, stepObject = _q.stepObject;
|
|
53
|
+
var _q = useStepNavigation(sessionId, session === null || session === void 0 ? void 0 : session.status, session === null || session === void 0 ? void 0 : session.currentStep, session === null || session === void 0 ? void 0 : session.template), step = _q.step, stepObject = _q.stepObject, history = _q.history;
|
|
54
54
|
// Load route-specific CSS based on current step
|
|
55
55
|
useStepCSS(step, session);
|
|
56
56
|
// Template loading logic
|
|
@@ -125,7 +125,7 @@ var DatakeenSession = function (_a) {
|
|
|
125
125
|
if (isExpired) {
|
|
126
126
|
return jsx(SessionExpired, { onRetry: handleRetrySession });
|
|
127
127
|
}
|
|
128
|
-
return (jsx(SessionContent, { step: step, loading: loading, session: session, sessionId: sessionId, stepObject: stepObject, userInput: userInput, setUserInput: setUserInput, contactInfo: contactInfo, setContactInfo: setContactInfo }));
|
|
128
|
+
return (jsx(SessionContent, { step: step, loading: loading, session: session, sessionId: sessionId, stepObject: stepObject, stepHistory: history, userInput: userInput, setUserInput: setUserInput, contactInfo: contactInfo, setContactInfo: setContactInfo }));
|
|
129
129
|
};
|
|
130
130
|
var mobileScrollPadding = showMobilePoweredBy
|
|
131
131
|
? "calc(".concat(poweredByHeight, "px + env(safe-area-inset-bottom, 0px))")
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DatakeenSession.js","sources":["../../../../src/components/DatakeenSession.tsx"],"sourcesContent":["import { useEffect, useLayoutEffect, useMemo, useRef, useState } from \"react\";\nimport type { CSSProperties } from \"react\";\nimport type { DatakeenSessionProps } from \"../types/session\";\nimport Paper from \"./ui/Paper\";\nimport useIsMobile from \"../hooks/useIsMobile\";\nimport PoweredBy from \"./ui/PoweredBy\";\nimport SessionExpired from \"./session/SessionExpired\";\nimport { useRouteCSS } from \"../hooks/useRouteCSS\";\nimport { DocumentProvider } from \"../context/DocumentContext\";\nimport { ConfigProvider } from \"../context/ConfigContext\";\nimport { setSessionStore } from \"../context/SessionContext\";\n\n// Hooks\nimport { useSessionData } from \"../hooks/useSessionData\";\nimport { useStepNavigation } from \"../hooks/useStepNavigation\";\nimport { useStepCSS } from \"../hooks/useStepCSS\";\nimport { useTemplateLoader } from \"../hooks/useTemplateLoader\";\nimport { useClientInfo } from \"../hooks/useClientInfo\";\nimport { getOrderedJourneySteps } from \"../services/sessionService\";\n\n// Components\nimport NoSessionIdState from \"./states/NoSessionIdState\";\nimport LoadingState from \"./states/LoadingState\";\nimport ErrorState from \"./states/ErrorState\";\nimport SessionContent from \"./session/SessionContent\";\n\n/**\n * DatakeenSession Component\n *\n * The main component of the Datakeen SDK that manages the multi-step verification flow.\n * This component handles the different steps of the session process, including:\n * - Initial welcome screen\n * - User information collection\n * - Country selection for JDI verification\n * - Mobile redirect when selfie is required\n *\n * The component maintains internal state for the current step and user input data,\n * progressing through the verification journey as the user completes each step.\n *\n * @param {DatakeenSessionProps} props - Component props\n * @param {string} props.sessionId - Unique identifier for the verification session\n * @param {SessionConfig} props.sessionConfig - Configuration for the session (e.g., selfie: true)\n * @param {string} props.apiBaseUrl - Optional API base URL for dynamic environment configuration\n * @returns {JSX.Element} A Paper-wrapped container with the appropriate step component based on current state\n */\nconst DatakeenSession = ({\n sessionId,\n sessionConfig,\n apiBaseUrl,\n}: DatakeenSessionProps) => {\n const isMobile = useIsMobile();\n const { info: clientInfo, isLoaded: clientInfoLoaded } = useClientInfo();\n\n // Load base CSS and UI components CSS that are always needed\n useRouteCSS(\"ui-components\");\n\n // Session data management\n const {\n session,\n setSession,\n loading,\n setLoading,\n error,\n isExpired,\n userInput,\n setUserInput,\n contactInfo,\n setContactInfo,\n loadSession,\n handleRetrySession,\n } = useSessionData(sessionId, clientInfo, clientInfoLoaded);\n\n // Step navigation management\n const { step, stepObject } = useStepNavigation(\n sessionId,\n session?.status,\n session?.currentStep,\n session?.template,\n );\n\n // Load route-specific CSS based on current step\n useStepCSS(step, session);\n\n // Template loading logic\n useTemplateLoader(step, sessionId, session, loading, setSession, setLoading);\n\n // Load session data on component mount\n useEffect(() => {\n loadSession();\n }, [sessionId, sessionConfig]);\n\n // Update global session store whenever session data changes\n useEffect(() => {\n const sanitizedSessionForGlobalStore = session\n ? {\n ...session,\n token: \"\",\n userInput: {},\n contactInfo: undefined,\n }\n : null;\n\n setSessionStore({\n session: sanitizedSessionForGlobalStore,\n loading,\n error,\n isExpired,\n userInput: {},\n contactInfo: { email: \"\", phoneNumber: \"\" },\n });\n }, [session, loading, error, isExpired]);\n\n // Handle initial step setting when session loads\n useEffect(() => {\n if (session && session.status === \"ended\") {\n // If session is ended, find the appropriate end step\n const templateNodes = session.template?.nodes || [];\n const endNodeIndex = templateNodes.findIndex(\n (node) => node.type === \"end\",\n );\n\n if (endNodeIndex !== -1) {\n stepObject.setStep(1 + endNodeIndex);\n } else {\n stepObject.setStep(1 + templateNodes.length);\n }\n }\n }, [session, stepObject]);\n\n if (!sessionId) {\n return <NoSessionIdState />;\n }\n\n // PoweredBy de DatakeenSession : uniquement pour les états spéciaux (loading/error/expired)\n // Les pages normales utilisent MobilePageLayout qui gère son propre PoweredBy\n const showMobilePoweredBy = isMobile && (loading || !!error || isExpired);\n const showDesktopPoweredBy = !isMobile && !loading && !error && !isExpired;\n const poweredByRef = useRef<HTMLDivElement | null>(null);\n const [poweredByHeight, setPoweredByHeight] = useState(0);\n\n useLayoutEffect(() => {\n if (typeof window === \"undefined\" || !showMobilePoweredBy) {\n setPoweredByHeight(0);\n return;\n }\n\n const updateHeight = () => {\n if (poweredByRef.current) {\n setPoweredByHeight(poweredByRef.current.offsetHeight);\n }\n };\n\n updateHeight();\n window.addEventListener(\"resize\", updateHeight);\n\n return () => {\n window.removeEventListener(\"resize\", updateHeight);\n };\n }, [showMobilePoweredBy]);\n\n const mobileRootStyle: CSSProperties = {\n [\"--dk-mobile-footer-offset\" as any]: `${poweredByHeight}px`,\n };\n\n const renderSessionContent = () => {\n if (loading) {\n return <LoadingState />;\n }\n\n if (error) {\n return <ErrorState error={error} />;\n }\n\n if (isExpired) {\n return <SessionExpired onRetry={handleRetrySession} />;\n }\n\n return (\n <SessionContent\n step={step}\n loading={loading}\n session={session}\n sessionId={sessionId}\n stepObject={stepObject}\n userInput={userInput}\n setUserInput={setUserInput}\n contactInfo={contactInfo}\n setContactInfo={setContactInfo}\n />\n );\n };\n\n const mobileScrollPadding = showMobilePoweredBy\n ? `calc(${poweredByHeight}px + env(safe-area-inset-bottom, 0px))`\n : \"env(safe-area-inset-bottom, 0px)\";\n\n const currentTemplateNode = useMemo(() => {\n if (!session?.template || step < 1) {\n return null;\n }\n\n const templateIndex = Math.floor(step - 1);\n const orderedSteps = getOrderedJourneySteps(session.template);\n return orderedSteps[templateIndex] || null;\n }, [session?.template, step]);\n\n const shouldUseWideDesktopLayout =\n currentTemplateNode?.type === \"information-input\" &&\n currentTemplateNode.informationType === \"custom\" &&\n (currentTemplateNode.customFields || []).some(\n (field) => field.valueType === \"list\",\n );\n\n const isCaptureStep =\n currentTemplateNode?.type === \"biometric-capture\" ||\n currentTemplateNode?.type === \"selfie-capture\" ||\n currentTemplateNode?.type === \"document-collection\" || // Could be upload, but safer to allow full height\n currentTemplateNode?.type === \"controle-jdi\";\n\n const btnBg = session?.template?.buttonBgColor ?? \"#11E5C5\";\n const btnText = session?.template?.buttonTextColor ?? \"#3C3C40\";\n\n return (\n <ConfigProvider apiBaseUrl={apiBaseUrl}>\n <DocumentProvider>\n <div\n className=\"sdk-session flex-1 flex flex-col\"\n style={\n {\n [\"--dk-btn-bg\" as string]: btnBg,\n [\"--dk-btn-text\" as string]: btnText,\n ...(isMobile\n ? {\n [\"--dk-mobile-scroll-padding\" as string]:\n mobileScrollPadding,\n }\n : undefined),\n } as CSSProperties\n }\n >\n {isMobile ? (\n <div\n className=\"flex h-full w-full flex-col bg-white\"\n style={mobileRootStyle}\n >\n <div\n className={`flex flex-1 min-h-0 flex-col ${isCaptureStep ? \"\" : \"overflow-y-auto\"}`}\n style={{\n paddingBottom: isCaptureStep\n ? \"0\"\n : \"var(--dk-mobile-scroll-padding, env(safe-area-inset-bottom, 0px))\",\n }}\n >\n <div className=\"flex flex-1 flex-col min-h-0\">\n {renderSessionContent()}\n </div>\n </div>\n {showMobilePoweredBy && (\n <div\n className=\"bg-white px-4 pt-3 pb-4 sm:px-6 sm:pt-6 sm:pb-6\"\n style={{\n paddingBottom:\n \"calc(env(safe-area-inset-bottom, 0px) + 0.5rem)\",\n }}\n ref={poweredByRef}\n >\n <PoweredBy\n logo={session?.template?.logo}\n text={session?.template?.logo ? \"par\" : undefined}\n />\n </div>\n )}\n </div>\n ) : (\n <div className=\"flex items-center justify-center w-full min-h-screen bg-gray-100 py-12\">\n <div className=\"flex flex-col items-center justify-center\">\n <Paper\n className={`flex flex-col h-[800px] px-8 py-10 bg-white rounded-2xl shadow-xl z-10 ${shouldUseWideDesktopLayout\n ? \"w-[98vw] max-w-[1500px]\"\n : \"w-[600px]\"\n }`}\n >\n <div className=\"flex-1 w-full h-full overflow-y-auto\">\n {renderSessionContent()}\n </div>\n </Paper>\n {showDesktopPoweredBy && (\n <div className=\"pt-6 text-center\">\n <PoweredBy\n logo={session?.template?.logo}\n text={session?.template?.logo ? \"par\" : undefined}\n />\n </div>\n )}\n </div>\n </div>\n )}\n </div>\n </DocumentProvider>\n </ConfigProvider>\n );\n};\n\nexport default DatakeenSession;\n"],"names":["_jsx","_jsxs"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"DatakeenSession.js","sources":["../../../../src/components/DatakeenSession.tsx"],"sourcesContent":["import { useEffect, useLayoutEffect, useMemo, useRef, useState } from \"react\";\nimport type { CSSProperties } from \"react\";\nimport type { DatakeenSessionProps } from \"../types/session\";\nimport Paper from \"./ui/Paper\";\nimport useIsMobile from \"../hooks/useIsMobile\";\nimport PoweredBy from \"./ui/PoweredBy\";\nimport SessionExpired from \"./session/SessionExpired\";\nimport { useRouteCSS } from \"../hooks/useRouteCSS\";\nimport { DocumentProvider } from \"../context/DocumentContext\";\nimport { ConfigProvider } from \"../context/ConfigContext\";\nimport { setSessionStore } from \"../context/SessionContext\";\n\n// Hooks\nimport { useSessionData } from \"../hooks/useSessionData\";\nimport { useStepNavigation } from \"../hooks/useStepNavigation\";\nimport { useStepCSS } from \"../hooks/useStepCSS\";\nimport { useTemplateLoader } from \"../hooks/useTemplateLoader\";\nimport { useClientInfo } from \"../hooks/useClientInfo\";\nimport { getOrderedJourneySteps } from \"../services/sessionService\";\n\n// Components\nimport NoSessionIdState from \"./states/NoSessionIdState\";\nimport LoadingState from \"./states/LoadingState\";\nimport ErrorState from \"./states/ErrorState\";\nimport SessionContent from \"./session/SessionContent\";\n\n/**\n * DatakeenSession Component\n *\n * The main component of the Datakeen SDK that manages the multi-step verification flow.\n * This component handles the different steps of the session process, including:\n * - Initial welcome screen\n * - User information collection\n * - Country selection for JDI verification\n * - Mobile redirect when selfie is required\n *\n * The component maintains internal state for the current step and user input data,\n * progressing through the verification journey as the user completes each step.\n *\n * @param {DatakeenSessionProps} props - Component props\n * @param {string} props.sessionId - Unique identifier for the verification session\n * @param {SessionConfig} props.sessionConfig - Configuration for the session (e.g., selfie: true)\n * @param {string} props.apiBaseUrl - Optional API base URL for dynamic environment configuration\n * @returns {JSX.Element} A Paper-wrapped container with the appropriate step component based on current state\n */\nconst DatakeenSession = ({\n sessionId,\n sessionConfig,\n apiBaseUrl,\n}: DatakeenSessionProps) => {\n const isMobile = useIsMobile();\n const { info: clientInfo, isLoaded: clientInfoLoaded } = useClientInfo();\n\n // Load base CSS and UI components CSS that are always needed\n useRouteCSS(\"ui-components\");\n\n // Session data management\n const {\n session,\n setSession,\n loading,\n setLoading,\n error,\n isExpired,\n userInput,\n setUserInput,\n contactInfo,\n setContactInfo,\n loadSession,\n handleRetrySession,\n } = useSessionData(sessionId, clientInfo, clientInfoLoaded);\n\n // Step navigation management\n const { step, stepObject, history } = useStepNavigation(\n sessionId,\n session?.status,\n session?.currentStep,\n session?.template,\n );\n\n // Load route-specific CSS based on current step\n useStepCSS(step, session);\n\n // Template loading logic\n useTemplateLoader(step, sessionId, session, loading, setSession, setLoading);\n\n // Load session data on component mount\n useEffect(() => {\n loadSession();\n }, [sessionId, sessionConfig]);\n\n // Update global session store whenever session data changes\n useEffect(() => {\n const sanitizedSessionForGlobalStore = session\n ? {\n ...session,\n token: \"\",\n userInput: {},\n contactInfo: undefined,\n }\n : null;\n\n setSessionStore({\n session: sanitizedSessionForGlobalStore,\n loading,\n error,\n isExpired,\n userInput: {},\n contactInfo: { email: \"\", phoneNumber: \"\" },\n });\n }, [session, loading, error, isExpired]);\n\n // Handle initial step setting when session loads\n useEffect(() => {\n if (session && session.status === \"ended\") {\n // If session is ended, find the appropriate end step\n const templateNodes = session.template?.nodes || [];\n const endNodeIndex = templateNodes.findIndex(\n (node) => node.type === \"end\",\n );\n\n if (endNodeIndex !== -1) {\n stepObject.setStep(1 + endNodeIndex);\n } else {\n stepObject.setStep(1 + templateNodes.length);\n }\n }\n }, [session, stepObject]);\n\n if (!sessionId) {\n return <NoSessionIdState />;\n }\n\n // PoweredBy de DatakeenSession : uniquement pour les états spéciaux (loading/error/expired)\n // Les pages normales utilisent MobilePageLayout qui gère son propre PoweredBy\n const showMobilePoweredBy = isMobile && (loading || !!error || isExpired);\n const showDesktopPoweredBy = !isMobile && !loading && !error && !isExpired;\n const poweredByRef = useRef<HTMLDivElement | null>(null);\n const [poweredByHeight, setPoweredByHeight] = useState(0);\n\n useLayoutEffect(() => {\n if (typeof window === \"undefined\" || !showMobilePoweredBy) {\n setPoweredByHeight(0);\n return;\n }\n\n const updateHeight = () => {\n if (poweredByRef.current) {\n setPoweredByHeight(poweredByRef.current.offsetHeight);\n }\n };\n\n updateHeight();\n window.addEventListener(\"resize\", updateHeight);\n\n return () => {\n window.removeEventListener(\"resize\", updateHeight);\n };\n }, [showMobilePoweredBy]);\n\n const mobileRootStyle: CSSProperties = {\n [\"--dk-mobile-footer-offset\" as any]: `${poweredByHeight}px`,\n };\n\n const renderSessionContent = () => {\n if (loading) {\n return <LoadingState />;\n }\n\n if (error) {\n return <ErrorState error={error} />;\n }\n\n if (isExpired) {\n return <SessionExpired onRetry={handleRetrySession} />;\n }\n\n return (\n <SessionContent\n step={step}\n loading={loading}\n session={session}\n sessionId={sessionId}\n stepObject={stepObject}\n stepHistory={history}\n userInput={userInput}\n setUserInput={setUserInput}\n contactInfo={contactInfo}\n setContactInfo={setContactInfo}\n />\n );\n };\n\n const mobileScrollPadding = showMobilePoweredBy\n ? `calc(${poweredByHeight}px + env(safe-area-inset-bottom, 0px))`\n : \"env(safe-area-inset-bottom, 0px)\";\n\n const currentTemplateNode = useMemo(() => {\n if (!session?.template || step < 1) {\n return null;\n }\n\n const templateIndex = Math.floor(step - 1);\n const orderedSteps = getOrderedJourneySteps(session.template);\n return orderedSteps[templateIndex] || null;\n }, [session?.template, step]);\n\n const shouldUseWideDesktopLayout =\n currentTemplateNode?.type === \"information-input\" &&\n currentTemplateNode.informationType === \"custom\" &&\n (currentTemplateNode.customFields || []).some(\n (field) => field.valueType === \"list\",\n );\n\n const isCaptureStep =\n currentTemplateNode?.type === \"biometric-capture\" ||\n currentTemplateNode?.type === \"selfie-capture\" ||\n currentTemplateNode?.type === \"document-collection\" || // Could be upload, but safer to allow full height\n currentTemplateNode?.type === \"controle-jdi\";\n\n const btnBg = session?.template?.buttonBgColor ?? \"#11E5C5\";\n const btnText = session?.template?.buttonTextColor ?? \"#3C3C40\";\n\n return (\n <ConfigProvider apiBaseUrl={apiBaseUrl}>\n <DocumentProvider>\n <div\n className=\"sdk-session flex-1 flex flex-col\"\n style={\n {\n [\"--dk-btn-bg\" as string]: btnBg,\n [\"--dk-btn-text\" as string]: btnText,\n ...(isMobile\n ? {\n [\"--dk-mobile-scroll-padding\" as string]:\n mobileScrollPadding,\n }\n : undefined),\n } as CSSProperties\n }\n >\n {isMobile ? (\n <div\n className=\"flex h-full w-full flex-col bg-white\"\n style={mobileRootStyle}\n >\n <div\n className={`flex flex-1 min-h-0 flex-col ${isCaptureStep ? \"\" : \"overflow-y-auto\"}`}\n style={{\n paddingBottom: isCaptureStep\n ? \"0\"\n : \"var(--dk-mobile-scroll-padding, env(safe-area-inset-bottom, 0px))\",\n }}\n >\n <div className=\"flex flex-1 flex-col min-h-0\">\n {renderSessionContent()}\n </div>\n </div>\n {showMobilePoweredBy && (\n <div\n className=\"bg-white px-4 pt-3 pb-4 sm:px-6 sm:pt-6 sm:pb-6\"\n style={{\n paddingBottom:\n \"calc(env(safe-area-inset-bottom, 0px) + 0.5rem)\",\n }}\n ref={poweredByRef}\n >\n <PoweredBy\n logo={session?.template?.logo}\n text={session?.template?.logo ? \"par\" : undefined}\n />\n </div>\n )}\n </div>\n ) : (\n <div className=\"flex items-center justify-center w-full min-h-screen bg-gray-100 py-12\">\n <div className=\"flex flex-col items-center justify-center\">\n <Paper\n className={`flex flex-col h-[800px] px-8 py-10 bg-white rounded-2xl shadow-xl z-10 ${shouldUseWideDesktopLayout\n ? \"w-[98vw] max-w-[1500px]\"\n : \"w-[600px]\"\n }`}\n >\n <div className=\"flex-1 w-full h-full overflow-y-auto\">\n {renderSessionContent()}\n </div>\n </Paper>\n {showDesktopPoweredBy && (\n <div className=\"pt-6 text-center\">\n <PoweredBy\n logo={session?.template?.logo}\n text={session?.template?.logo ? \"par\" : undefined}\n />\n </div>\n )}\n </div>\n </div>\n )}\n </div>\n </DocumentProvider>\n </ConfigProvider>\n );\n};\n\nexport default DatakeenSession;\n"],"names":["_jsx","_jsxs"],"mappings":"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"}
|
|
@@ -42,7 +42,7 @@ var SelfieConfirmation = function (_a) {
|
|
|
42
42
|
if (!imageUrl) {
|
|
43
43
|
return (jsx("div", { className: "flex flex-col items-center justify-center h-full bg-white", children: jsxs("div", { className: "text-center p-6 max-w-md mx-auto", children: [jsx("div", { className: "w-16 h-16 mx-auto mb-4 text-yellow-500", children: jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [jsx("circle", { cx: "12", cy: "12", r: "10" }), jsx("line", { x1: "12", y1: "8", x2: "12", y2: "12" }), jsx("line", { x1: "12", y1: "16", x2: "12.01", y2: "16" })] }) }), jsx(Title, { className: "text-xl mb-2", children: t("selfie.confirmation.no_display_title", "Impossible d'afficher le selfie") }), jsx("p", { className: "mb-6 text-sm text-gray-600", children: t("selfie.confirmation.no_display_desc", "Nous n'avons pas pu traiter correctement votre selfie.") }), jsx(Button, { variant: "secondary", onClick: onRetake, className: "md:max-w-xs mx-auto", children: t("selfie.confirmation.retake", "Reprendre le selfie") })] }) }));
|
|
44
44
|
}
|
|
45
|
-
return (jsx(MobilePageLayout, { header: jsxs("div", { className: "p-4 text-center bg-white border-b border-gray-100", children: [jsx(Title, { className: "text-xl md:text-2xl", children: t("selfie.confirmation.title", "Confirmez votre selfie") }), jsx(Subtitle, { className: "text-xs text-gray-600 mt-2 md:text-sm", children: t("selfie.confirmation.subtitle", "Vérifiez que votre visage est clairement visible") })] }), footer: jsx(PageActions, { primary: jsx(Button, { onClick: onConfirm, children: t("selfie.confirmation.confirm", "Confirmer") }), secondary: jsx(Button, { variant: "secondary", onClick: onRetake, children: t("selfie.confirmation.retake", "Reprendre le selfie") }) }), className: "bg-white", children: jsx("div", { className: "px-4 py-6 md:px-8 md:py-8", children: jsxs("div", { className: "w-full max-w-md mx-auto space-y-6", children: [jsx("div", { className: "w-full bg-white rounded-lg overflow-hidden shadow-md", children: jsxs("div", { className: "relative rounded-lg overflow-hidden border-2 border-[#11E5C5]", children: [jsx("img", { src: imageUrl, alt: "Selfie captur\u00E9", className: "w-full
|
|
45
|
+
return (jsx(MobilePageLayout, { header: jsxs("div", { className: "p-4 text-center bg-white border-b border-gray-100", children: [jsx(Title, { className: "text-xl md:text-2xl", children: t("selfie.confirmation.title", "Confirmez votre selfie") }), jsx(Subtitle, { className: "text-xs text-gray-600 mt-2 md:text-sm", children: t("selfie.confirmation.subtitle", "Vérifiez que votre visage est clairement visible") })] }), footer: jsx(PageActions, { primary: jsx(Button, { onClick: onConfirm, children: t("selfie.confirmation.confirm", "Confirmer") }), secondary: jsx(Button, { variant: "secondary", onClick: onRetake, children: t("selfie.confirmation.retake", "Reprendre le selfie") }) }), className: "bg-white", children: jsx("div", { className: "px-4 py-6 md:px-8 md:py-8", children: jsxs("div", { className: "w-full max-w-md mx-auto space-y-6", children: [jsx("div", { className: "w-full bg-white rounded-lg overflow-hidden shadow-md", children: jsxs("div", { className: "relative rounded-lg overflow-hidden border-2 border-[#11E5C5]", children: [jsx("img", { src: imageUrl, alt: "Selfie captur\u00E9", className: "w-full max-h-[50vh] object-contain bg-white", onError: function () {
|
|
46
46
|
setError("Impossible d'afficher l'image du selfie");
|
|
47
47
|
} }), jsx("div", { className: "absolute bottom-0 left-0 right-0 bg-gradient-to-t from-black/30 to-transparent p-3", children: jsx("p", { className: "text-white text-xs text-center", children: t("selfie.confirmation.overlay_success", "Selfie capturé avec succès") }) })] }) }), jsxs("div", { className: "bg-gray-50 p-4 rounded-lg", children: [jsx("h3", { className: "font-medium text-sm mb-3", children: t("selfie.confirmation.checklist_title", "Vérifiez que :") }), jsxs("ul", { className: "space-y-2 text-xs text-gray-700", children: [jsxs("li", { className: "flex items-start", children: [jsx("svg", { className: "w-4 h-4 text-green-500 mr-2 mt-0.5", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", xmlns: "http://www.w3.org/2000/svg", children: jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M5 13l4 4L19 7" }) }), t("selfie.confirmation.check_visible", "Votre visage est bien visible et occupe la majeure partie de l'image")] }), jsxs("li", { className: "flex items-start", children: [jsx("svg", { className: "w-4 h-4 text-green-500 mr-2 mt-0.5", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", xmlns: "http://www.w3.org/2000/svg", children: jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M5 13l4 4L19 7" }) }), t("selfie.confirmation.check_well_lit", "L'image est nette et bien éclairée")] }), jsxs("li", { className: "flex items-start", children: [jsx("svg", { className: "w-4 h-4 text-green-500 mr-2 mt-0.5", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", xmlns: "http://www.w3.org/2000/svg", children: jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M5 13l4 4L19 7" }) }), t("selfie.confirmation.check_no_object", "Aucun objet ne cache votre visage (lunettes de soleil, masque, etc.)")] })] })] }), jsx("canvas", { ref: canvasRef, style: { display: "none" } })] }) }) }));
|
|
48
48
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SelfieConfirmation.js","sources":["../../../../../src/components/selfie/SelfieConfirmation.tsx"],"sourcesContent":["/**\n * SelfieConfirmation component\n *\n * Displays the captured selfie and allows the user to confirm or retake it.\n *\n * @param {Object} props - Component props\n * @param {SelfieCaptureData} props.selfieData - The captured selfie data containing media blob and metadata\n * @param {Function} props.onConfirm - Function called when user confirms the selfie\n * @param {Function} props.onRetake - Function called when user wants to retake the selfie\n * @returns {JSX.Element} The selfie confirmation UI component\n */\n\nimport { useEffect, useRef, useState } from \"react\";\nimport type { SelfieCaptureData } from \"../../types/selfie\";\nimport Button from \"../ui/Button\";\nimport PageActions from \"../ui/PageActions\";\nimport Title from \"../ui/Title\";\nimport Subtitle from \"../ui/Subtitle\";\nimport MobilePageLayout from \"../ui/MobilePageLayout\";\nimport { useI18n } from \"../../hooks/useI18n\";\n\ninterface SelfieConfirmationProps {\n selfieData: SelfieCaptureData;\n setSelfiePhoto: (photo: string) => void;\n onConfirm: () => void;\n onRetake: () => void;\n}\n\nconst SelfieConfirmation = ({\n selfieData,\n setSelfiePhoto,\n onConfirm,\n onRetake,\n}: SelfieConfirmationProps) => {\n const { t } = useI18n();\n const [isLoading, setIsLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n const [imageUrl, setImageUrl] = useState<string | null>(null);\n const canvasRef = useRef<HTMLCanvasElement>(null);\n\n useEffect(() => {\n setIsLoading(true);\n setError(null);\n\n if (!selfieData?.media) {\n setError(t(\"selfie.confirmation.errors.no_data\", \"Aucune donnée de selfie disponible\"));\n setIsLoading(false);\n return;\n }\n\n // Use pre-captured thumbnail from live video stream\n if (selfieData.thumbnail) {\n setImageUrl(selfieData.thumbnail);\n setSelfiePhoto(selfieData.thumbnail);\n setIsLoading(false);\n return;\n }\n\n // No thumbnail available (should not happen)\n setError(t(\"selfie.confirmation.errors.no_preview\", \"Aucune preview disponible\"));\n setIsLoading(false);\n }, [selfieData, setSelfiePhoto]);\n\n if (isLoading) {\n return (\n <div className=\"flex flex-col items-center justify-center h-full bg-white\">\n <div className=\"text-center p-6\">\n <div className=\"mb-4 text-gray-700\">\n {t(\"selfie.confirmation.loading\", \"Traitement de votre selfie...\")}\n </div>\n <div className=\"w-12 h-12 border-4 border-[#11E5C5] border-t-transparent rounded-full animate-spin mx-auto\"></div>\n </div>\n </div>\n );\n }\n\n if (error) {\n return (\n <div className=\"flex flex-col items-center justify-center h-full bg-white\">\n <div className=\"text-center p-6 max-w-md mx-auto\">\n <div className=\"w-16 h-16 mx-auto mb-4 text-red-500\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <circle cx=\"12\" cy=\"12\" r=\"10\"></circle>\n <line x1=\"15\" y1=\"9\" x2=\"9\" y2=\"15\"></line>\n <line x1=\"9\" y1=\"9\" x2=\"15\" y2=\"15\"></line>\n </svg>\n </div>\n <Title className=\"text-xl mb-2\">{t(\"selfie.confirmation.error_title\", \"Une erreur est survenue\")}</Title>\n <p className=\"mb-6 text-sm text-gray-600\">{error}</p>\n <Button variant=\"secondary\" onClick={onRetake} className=\"md:max-w-xs mx-auto\">\n {t(\"selfie.confirmation.retake\", \"Reprendre le selfie\")}\n </Button>\n </div>\n </div>\n );\n }\n\n if (!imageUrl) {\n return (\n <div className=\"flex flex-col items-center justify-center h-full bg-white\">\n <div className=\"text-center p-6 max-w-md mx-auto\">\n <div className=\"w-16 h-16 mx-auto mb-4 text-yellow-500\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <circle cx=\"12\" cy=\"12\" r=\"10\"></circle>\n <line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"12\"></line>\n <line x1=\"12\" y1=\"16\" x2=\"12.01\" y2=\"16\"></line>\n </svg>\n </div>\n <Title className=\"text-xl mb-2\">{t(\"selfie.confirmation.no_display_title\", \"Impossible d'afficher le selfie\")}</Title>\n <p className=\"mb-6 text-sm text-gray-600\">{t(\"selfie.confirmation.no_display_desc\", \"Nous n'avons pas pu traiter correctement votre selfie.\")}</p>\n <Button variant=\"secondary\" onClick={onRetake} className=\"md:max-w-xs mx-auto\">\n {t(\"selfie.confirmation.retake\", \"Reprendre le selfie\")}\n </Button>\n </div>\n </div>\n );\n }\n\n return (\n <MobilePageLayout\n header={\n <div className=\"p-4 text-center bg-white border-b border-gray-100\">\n <Title className=\"text-xl md:text-2xl\">{t(\"selfie.confirmation.title\", \"Confirmez votre selfie\")}</Title>\n <Subtitle className=\"text-xs text-gray-600 mt-2 md:text-sm\">{t(\"selfie.confirmation.subtitle\", \"Vérifiez que votre visage est clairement visible\")}</Subtitle>\n </div>\n }\n footer={\n <PageActions\n primary={\n <Button onClick={onConfirm}>\n {t(\"selfie.confirmation.confirm\", \"Confirmer\")}\n </Button>\n }\n secondary={\n <Button variant=\"secondary\" onClick={onRetake}>\n {t(\"selfie.confirmation.retake\", \"Reprendre le selfie\")}\n </Button>\n }\n />\n }\n className=\"bg-white\"\n >\n <div className=\"px-4 py-6 md:px-8 md:py-8\">\n <div className=\"w-full max-w-md mx-auto space-y-6\">\n {/* Selfie display with frame */}\n <div className=\"w-full bg-white rounded-lg overflow-hidden shadow-md\">\n <div className=\"relative rounded-lg overflow-hidden border-2 border-[#11E5C5]\">\n <img\n src={imageUrl}\n alt=\"Selfie capturé\"\n className=\"w-full h-64 md:h-80 object-cover bg-white\"\n onError={() => {\n setError(\"Impossible d'afficher l'image du selfie\");\n }}\n />\n {/* Overlay pour améliorer la lisibilité */}\n <div className=\"absolute bottom-0 left-0 right-0 bg-gradient-to-t from-black/30 to-transparent p-3\">\n <p className=\"text-white text-xs text-center\">{t(\"selfie.confirmation.overlay_success\", \"Selfie capturé avec succès\")}</p>\n </div>\n </div>\n </div>\n\n {/* Checklist de confirmation */}\n <div className=\"bg-gray-50 p-4 rounded-lg\">\n <h3 className=\"font-medium text-sm mb-3\">{t(\"selfie.confirmation.checklist_title\", \"Vérifiez que :\")}</h3>\n <ul className=\"space-y-2 text-xs text-gray-700\">\n <li className=\"flex items-start\">\n <svg\n className=\"w-4 h-4 text-green-500 mr-2 mt-0.5\"\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth=\"2\"\n d=\"M5 13l4 4L19 7\"\n ></path>\n </svg>\n {t(\"selfie.confirmation.check_visible\", \"Votre visage est bien visible et occupe la majeure partie de l'image\")}\n </li>\n <li className=\"flex items-start\">\n <svg\n className=\"w-4 h-4 text-green-500 mr-2 mt-0.5\"\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth=\"2\"\n d=\"M5 13l4 4L19 7\"\n ></path>\n </svg>\n {t(\"selfie.confirmation.check_well_lit\", \"L'image est nette et bien éclairée\")}\n </li>\n <li className=\"flex items-start\">\n <svg\n className=\"w-4 h-4 text-green-500 mr-2 mt-0.5\"\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth=\"2\"\n d=\"M5 13l4 4L19 7\"\n ></path>\n </svg>\n {t(\"selfie.confirmation.check_no_object\", \"Aucun objet ne cache votre visage (lunettes de soleil, masque, etc.)\")}\n </li>\n </ul>\n </div>\n\n {/* Canvas caché utilisé pour le traitement des images */}\n <canvas ref={canvasRef} style={{ display: \"none\" }} />\n </div>\n </div>\n </MobilePageLayout>\n );\n};\n\nexport default SelfieConfirmation;\n"],"names":["_jsx","_jsxs"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"SelfieConfirmation.js","sources":["../../../../../src/components/selfie/SelfieConfirmation.tsx"],"sourcesContent":["/**\n * SelfieConfirmation component\n *\n * Displays the captured selfie and allows the user to confirm or retake it.\n *\n * @param {Object} props - Component props\n * @param {SelfieCaptureData} props.selfieData - The captured selfie data containing media blob and metadata\n * @param {Function} props.onConfirm - Function called when user confirms the selfie\n * @param {Function} props.onRetake - Function called when user wants to retake the selfie\n * @returns {JSX.Element} The selfie confirmation UI component\n */\n\nimport { useEffect, useRef, useState } from \"react\";\nimport type { SelfieCaptureData } from \"../../types/selfie\";\nimport Button from \"../ui/Button\";\nimport PageActions from \"../ui/PageActions\";\nimport Title from \"../ui/Title\";\nimport Subtitle from \"../ui/Subtitle\";\nimport MobilePageLayout from \"../ui/MobilePageLayout\";\nimport { useI18n } from \"../../hooks/useI18n\";\n\ninterface SelfieConfirmationProps {\n selfieData: SelfieCaptureData;\n setSelfiePhoto: (photo: string) => void;\n onConfirm: () => void;\n onRetake: () => void;\n}\n\nconst SelfieConfirmation = ({\n selfieData,\n setSelfiePhoto,\n onConfirm,\n onRetake,\n}: SelfieConfirmationProps) => {\n const { t } = useI18n();\n const [isLoading, setIsLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n const [imageUrl, setImageUrl] = useState<string | null>(null);\n const canvasRef = useRef<HTMLCanvasElement>(null);\n\n useEffect(() => {\n setIsLoading(true);\n setError(null);\n\n if (!selfieData?.media) {\n setError(t(\"selfie.confirmation.errors.no_data\", \"Aucune donnée de selfie disponible\"));\n setIsLoading(false);\n return;\n }\n\n // Use pre-captured thumbnail from live video stream\n if (selfieData.thumbnail) {\n setImageUrl(selfieData.thumbnail);\n setSelfiePhoto(selfieData.thumbnail);\n setIsLoading(false);\n return;\n }\n\n // No thumbnail available (should not happen)\n setError(t(\"selfie.confirmation.errors.no_preview\", \"Aucune preview disponible\"));\n setIsLoading(false);\n }, [selfieData, setSelfiePhoto]);\n\n if (isLoading) {\n return (\n <div className=\"flex flex-col items-center justify-center h-full bg-white\">\n <div className=\"text-center p-6\">\n <div className=\"mb-4 text-gray-700\">\n {t(\"selfie.confirmation.loading\", \"Traitement de votre selfie...\")}\n </div>\n <div className=\"w-12 h-12 border-4 border-[#11E5C5] border-t-transparent rounded-full animate-spin mx-auto\"></div>\n </div>\n </div>\n );\n }\n\n if (error) {\n return (\n <div className=\"flex flex-col items-center justify-center h-full bg-white\">\n <div className=\"text-center p-6 max-w-md mx-auto\">\n <div className=\"w-16 h-16 mx-auto mb-4 text-red-500\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <circle cx=\"12\" cy=\"12\" r=\"10\"></circle>\n <line x1=\"15\" y1=\"9\" x2=\"9\" y2=\"15\"></line>\n <line x1=\"9\" y1=\"9\" x2=\"15\" y2=\"15\"></line>\n </svg>\n </div>\n <Title className=\"text-xl mb-2\">{t(\"selfie.confirmation.error_title\", \"Une erreur est survenue\")}</Title>\n <p className=\"mb-6 text-sm text-gray-600\">{error}</p>\n <Button variant=\"secondary\" onClick={onRetake} className=\"md:max-w-xs mx-auto\">\n {t(\"selfie.confirmation.retake\", \"Reprendre le selfie\")}\n </Button>\n </div>\n </div>\n );\n }\n\n if (!imageUrl) {\n return (\n <div className=\"flex flex-col items-center justify-center h-full bg-white\">\n <div className=\"text-center p-6 max-w-md mx-auto\">\n <div className=\"w-16 h-16 mx-auto mb-4 text-yellow-500\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <circle cx=\"12\" cy=\"12\" r=\"10\"></circle>\n <line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"12\"></line>\n <line x1=\"12\" y1=\"16\" x2=\"12.01\" y2=\"16\"></line>\n </svg>\n </div>\n <Title className=\"text-xl mb-2\">{t(\"selfie.confirmation.no_display_title\", \"Impossible d'afficher le selfie\")}</Title>\n <p className=\"mb-6 text-sm text-gray-600\">{t(\"selfie.confirmation.no_display_desc\", \"Nous n'avons pas pu traiter correctement votre selfie.\")}</p>\n <Button variant=\"secondary\" onClick={onRetake} className=\"md:max-w-xs mx-auto\">\n {t(\"selfie.confirmation.retake\", \"Reprendre le selfie\")}\n </Button>\n </div>\n </div>\n );\n }\n\n return (\n <MobilePageLayout\n header={\n <div className=\"p-4 text-center bg-white border-b border-gray-100\">\n <Title className=\"text-xl md:text-2xl\">{t(\"selfie.confirmation.title\", \"Confirmez votre selfie\")}</Title>\n <Subtitle className=\"text-xs text-gray-600 mt-2 md:text-sm\">{t(\"selfie.confirmation.subtitle\", \"Vérifiez que votre visage est clairement visible\")}</Subtitle>\n </div>\n }\n footer={\n <PageActions\n primary={\n <Button onClick={onConfirm}>\n {t(\"selfie.confirmation.confirm\", \"Confirmer\")}\n </Button>\n }\n secondary={\n <Button variant=\"secondary\" onClick={onRetake}>\n {t(\"selfie.confirmation.retake\", \"Reprendre le selfie\")}\n </Button>\n }\n />\n }\n className=\"bg-white\"\n >\n <div className=\"px-4 py-6 md:px-8 md:py-8\">\n <div className=\"w-full max-w-md mx-auto space-y-6\">\n {/* Selfie display with frame */}\n <div className=\"w-full bg-white rounded-lg overflow-hidden shadow-md\">\n <div className=\"relative rounded-lg overflow-hidden border-2 border-[#11E5C5]\">\n <img\n src={imageUrl}\n alt=\"Selfie capturé\"\n className=\"w-full max-h-[50vh] object-contain bg-white\"\n onError={() => {\n setError(\"Impossible d'afficher l'image du selfie\");\n }}\n />\n {/* Overlay pour améliorer la lisibilité */}\n <div className=\"absolute bottom-0 left-0 right-0 bg-gradient-to-t from-black/30 to-transparent p-3\">\n <p className=\"text-white text-xs text-center\">{t(\"selfie.confirmation.overlay_success\", \"Selfie capturé avec succès\")}</p>\n </div>\n </div>\n </div>\n\n {/* Checklist de confirmation */}\n <div className=\"bg-gray-50 p-4 rounded-lg\">\n <h3 className=\"font-medium text-sm mb-3\">{t(\"selfie.confirmation.checklist_title\", \"Vérifiez que :\")}</h3>\n <ul className=\"space-y-2 text-xs text-gray-700\">\n <li className=\"flex items-start\">\n <svg\n className=\"w-4 h-4 text-green-500 mr-2 mt-0.5\"\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth=\"2\"\n d=\"M5 13l4 4L19 7\"\n ></path>\n </svg>\n {t(\"selfie.confirmation.check_visible\", \"Votre visage est bien visible et occupe la majeure partie de l'image\")}\n </li>\n <li className=\"flex items-start\">\n <svg\n className=\"w-4 h-4 text-green-500 mr-2 mt-0.5\"\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth=\"2\"\n d=\"M5 13l4 4L19 7\"\n ></path>\n </svg>\n {t(\"selfie.confirmation.check_well_lit\", \"L'image est nette et bien éclairée\")}\n </li>\n <li className=\"flex items-start\">\n <svg\n className=\"w-4 h-4 text-green-500 mr-2 mt-0.5\"\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth=\"2\"\n d=\"M5 13l4 4L19 7\"\n ></path>\n </svg>\n {t(\"selfie.confirmation.check_no_object\", \"Aucun objet ne cache votre visage (lunettes de soleil, masque, etc.)\")}\n </li>\n </ul>\n </div>\n\n {/* Canvas caché utilisé pour le traitement des images */}\n <canvas ref={canvasRef} style={{ display: \"none\" }} />\n </div>\n </div>\n </MobilePageLayout>\n );\n};\n\nexport default SelfieConfirmation;\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, onBack = _a.onBack;
|
|
9
|
+
var setSelfieData = _a.setSelfieData, setStep = _a.setStep, onBack = _a.onBack, 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, onBack: onBack })] }));
|
|
31
|
+
return (jsxs("div", { className: "w-full h-full overflow-hidden flex flex-col", children: [jsx(VideoResetStyles, {}), jsx(SelfieFlow, { handleSelfie: handleSelfie, onBack: onBack, 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 onBack?: () => void;\n}\n\nconst Video = ({ setSelfieData, setStep, onBack }: 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 handleSelfie={handleSelfie} onBack={onBack} />\n </div>\n );\n};\n\nexport default Video;\n"],"names":["_jsxs","_jsx"],"mappings":";;;;;;;
|
|
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 onBack?: () => void;\n btnBg?: string;\n btnText?: string;\n}\n\nconst Video = ({ setSelfieData, setStep, onBack, 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 handleSelfie={handleSelfie} onBack={onBack} btnBg={btnBg} btnText={btnText} />\n </div>\n );\n};\n\nexport default Video;\n"],"names":["_jsxs","_jsx"],"mappings":";;;;;;;AAeA,IAAM,KAAK,GAAG,UAAC,EAA8D,EAAA;AAA5D,IAAA,IAAA,aAAa,GAAA,EAAA,CAAA,aAAA,EAAE,OAAO,GAAA,EAAA,CAAA,OAAA,EAAE,MAAM,GAAA,EAAA,CAAA,MAAA,EAAE,KAAK,GAAA,EAAA,CAAA,KAAA,EAAE,OAAO,GAAA,EAAA,CAAA,OAAA;;AAE7D,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,IAAC,YAAY,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAA,CAAI,CAAA,EAAA,CACtF;AAEV;;;;"}
|
|
@@ -5,7 +5,7 @@ import InstructionsSelfie from './InstructionsSelfie.js';
|
|
|
5
5
|
import SelfieRecorder from './SelfieRecorder.js';
|
|
6
6
|
|
|
7
7
|
var SelfieFlow = function (_a) {
|
|
8
|
-
var handleSelfie = _a.handleSelfie, onBack = _a.onBack;
|
|
8
|
+
var handleSelfie = _a.handleSelfie, onBack = _a.onBack, btnBg = _a.btnBg, btnText = _a.btnText;
|
|
9
9
|
var _b = useState(-1), internalStep = _b[0], setInternalStep = _b[1]; // Commencer à -1 pour la pré-introduction
|
|
10
10
|
var handleBack = function () {
|
|
11
11
|
if (internalStep > -1) {
|
|
@@ -16,7 +16,7 @@ var SelfieFlow = function (_a) {
|
|
|
16
16
|
onBack();
|
|
17
17
|
}
|
|
18
18
|
};
|
|
19
|
-
return (jsxs("div", { className: "h-full w-full flex flex-col", children: [internalStep === -1 && (jsx("div", { className: "flex-1 flex flex-col h-full", children: jsx(SelfiePreIntroduction, { onContinue: function () { return setInternalStep(0); }, onBack: handleBack }) })), 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(SelfieRecorder, { handleSelfie: handleSelfie }) }))] }));
|
|
19
|
+
return (jsxs("div", { className: "h-full w-full flex flex-col", children: [internalStep === -1 && (jsx("div", { className: "flex-1 flex flex-col h-full", children: jsx(SelfiePreIntroduction, { onContinue: function () { return setInternalStep(0); }, onBack: handleBack }) })), 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(SelfieRecorder, { handleSelfie: handleSelfie, btnBg: btnBg, btnText: btnText }) }))] }));
|
|
20
20
|
};
|
|
21
21
|
|
|
22
22
|
export { SelfieFlow as default };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SelfieFlow.js","sources":["../../../../../../src/components/selfie/selfie-flow/SelfieFlow.tsx"],"sourcesContent":["import { useState } from \"react\";\nimport SelfiePreIntroduction from \"./SelfiePreIntroduction\";\nimport InstructionsSelfie from \"./InstructionsSelfie\";\nimport SelfieRecorder from \"./SelfieRecorder\";\n\ninterface SelfieFlowProps {\n handleSelfie: (e: Event) => void;\n onBack?: () => void;\n}\n\nconst SelfieFlow = ({ handleSelfie, onBack }: SelfieFlowProps) => {\n const [internalStep, setInternalStep] = useState(-1); // Commencer à -1 pour la pré-introduction\n\n const handleBack = () => {\n if (internalStep > -1) {\n setInternalStep(internalStep - 1);\n } else if (internalStep === -1 && onBack) {\n // Si on est à la première étape et qu'on a une fonction de retour parent, l'utiliser\n onBack();\n }\n };\n\n return (\n <div className=\"h-full w-full flex flex-col\">\n {internalStep === -1 && (\n <div className=\"flex-1 flex flex-col h-full\">\n <SelfiePreIntroduction\n onContinue={() => setInternalStep(0)}\n onBack={handleBack}\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 <SelfieRecorder handleSelfie={handleSelfie} />\n </div>\n )}\n </div>\n );\n};\n\nexport default SelfieFlow;\n"],"names":["_jsxs","_jsx"],"mappings":";;;;;;
|
|
1
|
+
{"version":3,"file":"SelfieFlow.js","sources":["../../../../../../src/components/selfie/selfie-flow/SelfieFlow.tsx"],"sourcesContent":["import { useState } from \"react\";\nimport SelfiePreIntroduction from \"./SelfiePreIntroduction\";\nimport InstructionsSelfie from \"./InstructionsSelfie\";\nimport SelfieRecorder from \"./SelfieRecorder\";\n\ninterface SelfieFlowProps {\n handleSelfie: (e: Event) => void;\n onBack?: () => void;\n btnBg?: string;\n btnText?: string;\n}\n\nconst SelfieFlow = ({ handleSelfie, onBack, btnBg, btnText }: SelfieFlowProps) => {\n const [internalStep, setInternalStep] = useState(-1); // Commencer à -1 pour la pré-introduction\n\n const handleBack = () => {\n if (internalStep > -1) {\n setInternalStep(internalStep - 1);\n } else if (internalStep === -1 && onBack) {\n // Si on est à la première étape et qu'on a une fonction de retour parent, l'utiliser\n onBack();\n }\n };\n\n return (\n <div className=\"h-full w-full flex flex-col\">\n {internalStep === -1 && (\n <div className=\"flex-1 flex flex-col h-full\">\n <SelfiePreIntroduction\n onContinue={() => setInternalStep(0)}\n onBack={handleBack}\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 <SelfieRecorder handleSelfie={handleSelfie} btnBg={btnBg} btnText={btnText} />\n </div>\n )}\n </div>\n );\n};\n\nexport default SelfieFlow;\n"],"names":["_jsxs","_jsx"],"mappings":";;;;;;AAYA,IAAM,UAAU,GAAG,UAAC,EAAyD,EAAA;QAAvD,YAAY,GAAA,EAAA,CAAA,YAAA,EAAE,MAAM,GAAA,EAAA,CAAA,MAAA,EAAE,KAAK,GAAA,EAAA,CAAA,KAAA,EAAE,OAAO,GAAA,EAAA,CAAA,OAAA;AAClD,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,IAAM,UAAU,GAAG,YAAA;AACjB,QAAA,IAAI,YAAY,GAAG,EAAE,EAAE;AACrB,YAAA,eAAe,CAAC,YAAY,GAAG,CAAC,CAAC;QACnC;AAAO,aAAA,IAAI,YAAY,KAAK,EAAE,IAAI,MAAM,EAAE;;AAExC,YAAA,MAAM,EAAE;QACV;AACF,IAAA,CAAC;IAED,QACEA,cAAK,SAAS,EAAC,6BAA6B,EAAA,QAAA,EAAA,CACzC,YAAY,KAAK,EAAE,KAClBC,GAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAC,6BAA6B,YAC1CA,GAAA,CAAC,qBAAqB,EAAA,EACpB,UAAU,EAAE,YAAA,EAAM,OAAA,eAAe,CAAC,CAAC,CAAC,CAAA,CAAlB,CAAkB,EACpC,MAAM,EAAE,UAAU,EAAA,CAClB,EAAA,CACE,CACP,EACA,YAAY,KAAK,CAAC,KACjBA,GAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAC,6BAA6B,EAAA,QAAA,EAC1CA,GAAA,CAAC,kBAAkB,EAAA,EACjB,OAAO,EAAE,eAAe,EACxB,MAAM,EAAE,YAAA,EAAM,OAAA,eAAe,CAAC,EAAE,CAAC,CAAA,CAAnB,CAAmB,EAAA,CACjC,EAAA,CACE,CACP,EACA,YAAY,KAAK,CAAC,KACjBA,aAAK,SAAS,EAAC,6CAA6C,EAAA,QAAA,EAC1DA,GAAA,CAAC,cAAc,EAAA,EAAC,YAAY,EAAE,YAAY,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,GAAI,EAAA,CAC1E,CACP,CAAA,EAAA,CACG;AAEV;;;;"}
|
|
@@ -13,14 +13,15 @@ import { useI18n } from '../../../hooks/useI18n.js';
|
|
|
13
13
|
import { getUnisseyStrings } from '../utils/unisseyStrings.js';
|
|
14
14
|
|
|
15
15
|
var SelfieRecorder = function (_a) {
|
|
16
|
-
var
|
|
16
|
+
var _b;
|
|
17
|
+
var handleSelfie = _a.handleSelfie, _c = _a.onBeginCapture, onBeginCapture = _c === void 0 ? function () { } : _c; _a.isCapturing; var btnBg = _a.btnBg, btnText = _a.btnText;
|
|
17
18
|
var t = useI18n().t;
|
|
18
19
|
var recorderRef = useRef(null);
|
|
19
|
-
var
|
|
20
|
-
var
|
|
21
|
-
var
|
|
20
|
+
var _e = useState(false), disableButton = _e[0], setDisableButton = _e[1];
|
|
21
|
+
var _f = useState(false), recorderReady = _f[0], setRecorderReady = _f[1];
|
|
22
|
+
var _g = useState("idle"), recordingState = _g[0], setRecordingState = _g[1];
|
|
22
23
|
var capturedThumbnailRef = useRef(null);
|
|
23
|
-
var
|
|
24
|
+
var _h = useLiveFrameCapture(), captureFrame = _h.captureFrame, cleanup = _h.cleanup;
|
|
24
25
|
useVideoRecorderStyles();
|
|
25
26
|
useEffect(function () {
|
|
26
27
|
document.body.classList.add("recording-selfie");
|
|
@@ -148,7 +149,10 @@ var SelfieRecorder = function (_a) {
|
|
|
148
149
|
setRecordingState("processing");
|
|
149
150
|
handleSelfie(enhancedEvent);
|
|
150
151
|
};
|
|
151
|
-
return (jsxs("div", { className: "selfie fixed inset-0 z-50 flex flex-col",
|
|
152
|
+
return (jsxs("div", { className: "selfie fixed inset-0 z-50 flex flex-col", style: (_b = {},
|
|
153
|
+
_b["--dk-btn-bg"] = btnBg !== null && btnBg !== void 0 ? btnBg : "var(--dk-btn-bg)",
|
|
154
|
+
_b["--dk-btn-text"] = btnText !== null && btnText !== void 0 ? btnText : "var(--dk-btn-text)",
|
|
155
|
+
_b), children: [jsxs("div", { className: "p-4 text-center bg-white shrink-0", children: [jsx(Title, { className: "text-lg md:text-xl mb-1", children: t("selfie.recorder.title") }), jsx(Subtitle, { className: "text-xs text-gray-600 md:text-sm", children: t("selfie.recorder.subtitle") })] }), jsx("div", { className: "video-container flex-1 relative overflow-hidden", children: jsx(VideoRecorder, __assign({ ref: recorderRef, preset: AcquisitionPreset.SELFIE_OPTIMIZED, hideCaptureBtn: true, faceChecker: "enabled", disableDebugMode: true, onRecorderReady: handleRecorderReady, onRecordCompleted: handleRecordCompleted, onRecord: recordStarting, style: { width: "100%", height: "100%" }, className: "video-recorder-no-radius w-full h-full" }, (isIOS() && {
|
|
152
156
|
"data-playsinline": "true",
|
|
153
157
|
"data-autoplay": "true",
|
|
154
158
|
"data-muted": "true"
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SelfieRecorder.js","sources":["../../../../../../src/components/selfie/selfie-flow/SelfieRecorder.tsx"],"sourcesContent":["import { useRef, useState, useEffect } from \"react\";\nimport { AcquisitionPreset, VideoRecorder } from \"@unissey-web/sdk-react\";\nimport Button from \"../../ui/Button\";\nimport Title from \"../../ui/Title\";\nimport Subtitle from \"../../ui/Subtitle\";\nimport useVideoRecorderStyles from \"../hooks/useVideoRecorderStyles\";\nimport { setupVideoElementsObserver } from \"../utils/videoElementStyles\";\nimport { delay, isIOS, waitForVideoFrame, getRecorderVideoElement } from \"../utils/selfieCaptureUtils\";\nimport { useLiveFrameCapture } from \"../hooks/useLiveFrameCapture\";\nimport { useI18n } from \"../../../hooks/useI18n\";\nimport { getUnisseyStrings } from \"../utils/unisseyStrings\";\n\ninterface SelfieRecorderProps {\n handleSelfie: (e: Event) => void;\n onBeginCapture?: () => void;\n isCapturing?: boolean;\n}\n\ninterface VideoRecorderRef extends HTMLElement {\n capture: () => void;\n}\n\nconst SelfieRecorder = ({\n handleSelfie,\n onBeginCapture = () => { },\n isCapturing = false,\n}: SelfieRecorderProps) => {\n const { t } = useI18n();\n const recorderRef = useRef<VideoRecorderRef | null>(null);\n const [disableButton, setDisableButton] = useState(false);\n const [recorderReady, setRecorderReady] = useState(false);\n const [recordingState, setRecordingState] = useState<\n \"idle\" | \"preparing\" | \"recording\" | \"processing\"\n >(\"idle\");\n const capturedThumbnailRef = useRef<string | null>(null);\n const { captureFrame, cleanup } = useLiveFrameCapture();\n\n useVideoRecorderStyles();\n\n useEffect(() => {\n document.body.classList.add(\"recording-selfie\");\n const cleanupObserver = setupVideoElementsObserver();\n\n // iOS-specific fix: Add required attributes to video elements after mount\n if (isIOS()) {\n const addIOSVideoAttributes = () => {\n const videoRecorders = document.querySelectorAll(\"uni-video-recorder\");\n videoRecorders.forEach((recorder) => {\n // Try to access shadow DOM and video elements\n try {\n const shadowRoot = (recorder as any).shadowRoot;\n if (shadowRoot) {\n const videoElements = shadowRoot.querySelectorAll(\"video\");\n videoElements.forEach((video: HTMLVideoElement) => {\n video.setAttribute(\"playsinline\", \"true\");\n video.setAttribute(\"autoplay\", \"true\");\n video.setAttribute(\"muted\", \"true\");\n // Ensure video plays inline and autoplays\n video.playsInline = true;\n video.autoplay = true;\n video.muted = true;\n });\n }\n } catch (error) {\n console.log(\"Could not access shadow DOM:\", error);\n }\n\n // Also set attributes on the component itself\n recorder.setAttribute(\"playsinline\", \"true\");\n recorder.setAttribute(\"autoplay\", \"true\");\n recorder.setAttribute(\"muted\", \"true\");\n });\n };\n\n // Apply immediately and also after a delay to catch dynamically created elements\n addIOSVideoAttributes();\n const iosTimeout = setTimeout(addIOSVideoAttributes, 500);\n const iosInterval = setInterval(addIOSVideoAttributes, 1000);\n\n return () => {\n document.body.classList.remove(\"recording-selfie\");\n cleanupObserver();\n cleanup();\n clearTimeout(iosTimeout);\n clearInterval(iosInterval);\n };\n }\n\n return () => {\n document.body.classList.remove(\"recording-selfie\");\n cleanupObserver();\n cleanup();\n };\n }, [cleanup]);\n\n const recordStarting = () => {\n if (!recorderReady || recordingState !== \"idle\") return;\n onBeginCapture();\n setRecordingState(\"preparing\");\n setDisableButton(true);\n\n const triggerCapture = async () => {\n try {\n await waitForVideoFrame(recorderRef.current);\n await delay(200);\n setRecordingState(\"recording\");\n\n // Capture a frame from the live video during recording (after a short delay)\n setTimeout(() => {\n const videoElement = getRecorderVideoElement(recorderRef.current);\n if (videoElement) {\n const thumbnail = captureFrame(videoElement);\n capturedThumbnailRef.current = thumbnail;\n }\n }, 1000); // Capture frame 1 second into recording\n\n recorderRef.current?.capture();\n } catch (error) {\n console.error(\"SelfieRecorder: failed to capture frame\", error);\n setRecordingState(\"idle\");\n setDisableButton(false);\n }\n };\n\n void triggerCapture();\n };\n\n const handleRecorderReady = () => setRecorderReady(true);\n\n const handleRecordCompleted = (e: Event) => {\n const customEvent = e as CustomEvent<{ media?: Blob; metadata?: string }>;\n if (!customEvent.detail?.media || customEvent.detail.media.size === 0) {\n console.error(\"❌ No valid media captured\");\n\n // iOS-specific debugging\n if (isIOS()) {\n console.log(\"🍎 iOS detected - checking video elements for proper attributes\");\n const videoRecorders = document.querySelectorAll(\"uni-video-recorder\");\n videoRecorders.forEach((recorder, index) => {\n console.log(`VideoRecorder ${index}:`, {\n playsinline: recorder.getAttribute(\"playsinline\"),\n autoplay: recorder.getAttribute(\"autoplay\"),\n muted: recorder.getAttribute(\"muted\")\n });\n });\n }\n\n setRecordingState(\"idle\");\n setDisableButton(false);\n return;\n }\n\n // Attach the captured thumbnail to the event\n const enhancedEvent = new CustomEvent('record-completed', {\n detail: {\n media: customEvent.detail.media,\n metadata: customEvent.detail.metadata || '',\n thumbnail: capturedThumbnailRef.current || undefined,\n }\n });\n\n setRecordingState(\"processing\");\n handleSelfie(enhancedEvent);\n };\n\n return (\n <div className=\"selfie fixed inset-0 z-50 flex flex-col\">\n <div className=\"p-4 text-center bg-white shrink-0\">\n <Title className=\"text-lg md:text-xl mb-1\">{t(\"selfie.recorder.title\")}</Title>\n <Subtitle className=\"text-xs text-gray-600 md:text-sm\">{t(\"selfie.recorder.subtitle\")}</Subtitle>\n </div>\n\n <div className=\"video-container flex-1 relative overflow-hidden\">\n <VideoRecorder\n ref={recorderRef as any}\n preset={AcquisitionPreset.SELFIE_OPTIMIZED}\n hideCaptureBtn\n faceChecker=\"enabled\"\n disableDebugMode\n onRecorderReady={handleRecorderReady}\n onRecordCompleted={handleRecordCompleted}\n onRecord={recordStarting}\n style={{ width: \"100%\", height: \"100%\" }}\n className=\"video-recorder-no-radius w-full h-full\"\n {...(isIOS() && {\n \"data-playsinline\": \"true\",\n \"data-autoplay\": \"true\",\n \"data-muted\": \"true\"\n })}\n strings={getUnisseyStrings(t)}\n />\n </div>\n\n <div className=\"shrink-0 bg-white border-t border-gray-200 p-4 md:p-6 relative\" style={{ zIndex: 9999 }}>\n <div className=\"max-w-md mx-auto\">\n <div className=\"text-center text-xs text-gray-400 mt-3\">\n {t(\"selfie.recorder.note\")}\n </div>\n\n <Button\n onClick={recordStarting}\n className=\"w-full py-3 md:py-4 relative selfie-button\"\n disabled={disableButton || !recorderReady}\n >\n {recordingState === \"idle\" && t(\"selfie.recorder.start\")}\n {recordingState === \"preparing\" && t(\"selfie.recorder.preparing\")}\n {recordingState === \"recording\" && (\n <span className=\"flex items-center justify-center\">\n <span className=\"mr-2\">{t(\"selfie.recorder.recording_label\")}</span>\n <span className=\"flex space-x-1 loading-dots\">\n <span className=\"h-1 w-1 bg-white rounded-full\"></span>\n <span className=\"h-1 w-1 bg-white rounded-full\"></span>\n <span className=\"h-1 w-1 bg-white rounded-full\"></span>\n </span>\n </span>\n )}\n {recordingState === \"processing\" && t(\"selfie.recorder.processing\")}\n </Button>\n </div>\n </div>\n </div>\n );\n};\n\nexport default SelfieRecorder;\n"],"names":["_jsxs","_jsx"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"SelfieRecorder.js","sources":["../../../../../../src/components/selfie/selfie-flow/SelfieRecorder.tsx"],"sourcesContent":["import { useRef, useState, useEffect } from \"react\";\nimport { AcquisitionPreset, VideoRecorder } from \"@unissey-web/sdk-react\";\nimport Button from \"../../ui/Button\";\nimport Title from \"../../ui/Title\";\nimport Subtitle from \"../../ui/Subtitle\";\nimport useVideoRecorderStyles from \"../hooks/useVideoRecorderStyles\";\nimport { setupVideoElementsObserver } from \"../utils/videoElementStyles\";\nimport { delay, isIOS, waitForVideoFrame, getRecorderVideoElement } from \"../utils/selfieCaptureUtils\";\nimport { useLiveFrameCapture } from \"../hooks/useLiveFrameCapture\";\nimport { useI18n } from \"../../../hooks/useI18n\";\nimport { getUnisseyStrings } from \"../utils/unisseyStrings\";\n\ninterface SelfieRecorderProps {\n handleSelfie: (e: Event) => void;\n onBeginCapture?: () => void;\n isCapturing?: boolean;\n btnBg?: string;\n btnText?: string;\n}\n\ninterface VideoRecorderRef extends HTMLElement {\n capture: () => void;\n}\n\nconst SelfieRecorder = ({\n handleSelfie,\n onBeginCapture = () => { },\n isCapturing = false,\n btnBg,\n btnText,\n}: SelfieRecorderProps) => {\n const { t } = useI18n();\n const recorderRef = useRef<VideoRecorderRef | null>(null);\n const [disableButton, setDisableButton] = useState(false);\n const [recorderReady, setRecorderReady] = useState(false);\n const [recordingState, setRecordingState] = useState<\n \"idle\" | \"preparing\" | \"recording\" | \"processing\"\n >(\"idle\");\n const capturedThumbnailRef = useRef<string | null>(null);\n const { captureFrame, cleanup } = useLiveFrameCapture();\n\n useVideoRecorderStyles();\n\n useEffect(() => {\n document.body.classList.add(\"recording-selfie\");\n const cleanupObserver = setupVideoElementsObserver();\n\n // iOS-specific fix: Add required attributes to video elements after mount\n if (isIOS()) {\n const addIOSVideoAttributes = () => {\n const videoRecorders = document.querySelectorAll(\"uni-video-recorder\");\n videoRecorders.forEach((recorder) => {\n // Try to access shadow DOM and video elements\n try {\n const shadowRoot = (recorder as any).shadowRoot;\n if (shadowRoot) {\n const videoElements = shadowRoot.querySelectorAll(\"video\");\n videoElements.forEach((video: HTMLVideoElement) => {\n video.setAttribute(\"playsinline\", \"true\");\n video.setAttribute(\"autoplay\", \"true\");\n video.setAttribute(\"muted\", \"true\");\n // Ensure video plays inline and autoplays\n video.playsInline = true;\n video.autoplay = true;\n video.muted = true;\n });\n }\n } catch (error) {\n console.log(\"Could not access shadow DOM:\", error);\n }\n\n // Also set attributes on the component itself\n recorder.setAttribute(\"playsinline\", \"true\");\n recorder.setAttribute(\"autoplay\", \"true\");\n recorder.setAttribute(\"muted\", \"true\");\n });\n };\n\n // Apply immediately and also after a delay to catch dynamically created elements\n addIOSVideoAttributes();\n const iosTimeout = setTimeout(addIOSVideoAttributes, 500);\n const iosInterval = setInterval(addIOSVideoAttributes, 1000);\n\n return () => {\n document.body.classList.remove(\"recording-selfie\");\n cleanupObserver();\n cleanup();\n clearTimeout(iosTimeout);\n clearInterval(iosInterval);\n };\n }\n\n return () => {\n document.body.classList.remove(\"recording-selfie\");\n cleanupObserver();\n cleanup();\n };\n }, [cleanup]);\n\n const recordStarting = () => {\n if (!recorderReady || recordingState !== \"idle\") return;\n onBeginCapture();\n setRecordingState(\"preparing\");\n setDisableButton(true);\n\n const triggerCapture = async () => {\n try {\n await waitForVideoFrame(recorderRef.current);\n await delay(200);\n setRecordingState(\"recording\");\n\n // Capture a frame from the live video during recording (after a short delay)\n setTimeout(() => {\n const videoElement = getRecorderVideoElement(recorderRef.current);\n if (videoElement) {\n const thumbnail = captureFrame(videoElement);\n capturedThumbnailRef.current = thumbnail;\n }\n }, 1000); // Capture frame 1 second into recording\n\n recorderRef.current?.capture();\n } catch (error) {\n console.error(\"SelfieRecorder: failed to capture frame\", error);\n setRecordingState(\"idle\");\n setDisableButton(false);\n }\n };\n\n void triggerCapture();\n };\n\n const handleRecorderReady = () => setRecorderReady(true);\n\n const handleRecordCompleted = (e: Event) => {\n const customEvent = e as CustomEvent<{ media?: Blob; metadata?: string }>;\n if (!customEvent.detail?.media || customEvent.detail.media.size === 0) {\n console.error(\"❌ No valid media captured\");\n\n // iOS-specific debugging\n if (isIOS()) {\n console.log(\"🍎 iOS detected - checking video elements for proper attributes\");\n const videoRecorders = document.querySelectorAll(\"uni-video-recorder\");\n videoRecorders.forEach((recorder, index) => {\n console.log(`VideoRecorder ${index}:`, {\n playsinline: recorder.getAttribute(\"playsinline\"),\n autoplay: recorder.getAttribute(\"autoplay\"),\n muted: recorder.getAttribute(\"muted\")\n });\n });\n }\n\n setRecordingState(\"idle\");\n setDisableButton(false);\n return;\n }\n\n // Attach the captured thumbnail to the event\n const enhancedEvent = new CustomEvent('record-completed', {\n detail: {\n media: customEvent.detail.media,\n metadata: customEvent.detail.metadata || '',\n thumbnail: capturedThumbnailRef.current || undefined,\n }\n });\n\n setRecordingState(\"processing\");\n handleSelfie(enhancedEvent);\n };\n\n return (\n <div\n className=\"selfie fixed inset-0 z-50 flex flex-col\"\n style={{\n [\"--dk-btn-bg\" as string]: btnBg ?? \"var(--dk-btn-bg)\",\n [\"--dk-btn-text\" as string]: btnText ?? \"var(--dk-btn-text)\",\n }}\n >\n <div className=\"p-4 text-center bg-white shrink-0\">\n <Title className=\"text-lg md:text-xl mb-1\">{t(\"selfie.recorder.title\")}</Title>\n <Subtitle className=\"text-xs text-gray-600 md:text-sm\">{t(\"selfie.recorder.subtitle\")}</Subtitle>\n </div>\n\n <div className=\"video-container flex-1 relative overflow-hidden\">\n <VideoRecorder\n ref={recorderRef as any}\n preset={AcquisitionPreset.SELFIE_OPTIMIZED}\n hideCaptureBtn\n faceChecker=\"enabled\"\n disableDebugMode\n onRecorderReady={handleRecorderReady}\n onRecordCompleted={handleRecordCompleted}\n onRecord={recordStarting}\n style={{ width: \"100%\", height: \"100%\" }}\n className=\"video-recorder-no-radius w-full h-full\"\n {...(isIOS() && {\n \"data-playsinline\": \"true\",\n \"data-autoplay\": \"true\",\n \"data-muted\": \"true\"\n })}\n strings={getUnisseyStrings(t)}\n />\n </div>\n\n <div className=\"shrink-0 bg-white border-t border-gray-200 p-4 md:p-6 relative\" style={{ zIndex: 9999 }}>\n <div className=\"max-w-md mx-auto\">\n <div className=\"text-center text-xs text-gray-400 mt-3\">\n {t(\"selfie.recorder.note\")}\n </div>\n\n <Button\n onClick={recordStarting}\n className=\"w-full py-3 md:py-4 relative selfie-button\"\n disabled={disableButton || !recorderReady}\n >\n {recordingState === \"idle\" && t(\"selfie.recorder.start\")}\n {recordingState === \"preparing\" && t(\"selfie.recorder.preparing\")}\n {recordingState === \"recording\" && (\n <span className=\"flex items-center justify-center\">\n <span className=\"mr-2\">{t(\"selfie.recorder.recording_label\")}</span>\n <span className=\"flex space-x-1 loading-dots\">\n <span className=\"h-1 w-1 bg-white rounded-full\"></span>\n <span className=\"h-1 w-1 bg-white rounded-full\"></span>\n <span className=\"h-1 w-1 bg-white rounded-full\"></span>\n </span>\n </span>\n )}\n {recordingState === \"processing\" && t(\"selfie.recorder.processing\")}\n </Button>\n </div>\n </div>\n </div>\n );\n};\n\nexport default SelfieRecorder;\n"],"names":["_jsxs","_jsx"],"mappings":"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"}
|