@hexar/biometric-identity-sdk-react-native 1.0.2 → 1.0.4

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.
@@ -3,6 +3,7 @@
3
3
  * Main UI component for identity verification with backend AI support
4
4
  */
5
5
  import React from 'react';
6
+ import { ViewStyle } from 'react-native';
6
7
  import { ValidationResult, ThemeConfig, BiometricError, SupportedLanguage } from '@hexar/biometric-identity-sdk-core';
7
8
  export interface BiometricIdentityFlowProps {
8
9
  onValidationComplete: (result: ValidationResult) => void;
@@ -11,6 +12,10 @@ export interface BiometricIdentityFlowProps {
11
12
  language?: SupportedLanguage;
12
13
  customTranslations?: Record<string, string>;
13
14
  smartLivenessMode?: boolean;
15
+ styles?: {
16
+ container?: ViewStyle;
17
+ content?: ViewStyle;
18
+ };
14
19
  }
15
20
  export declare const BiometricIdentityFlow: React.FC<BiometricIdentityFlowProps>;
16
21
  export default BiometricIdentityFlow;
@@ -1 +1 @@
1
- {"version":3,"file":"BiometricIdentityFlow.d.ts","sourceRoot":"","sources":["../../src/components/BiometricIdentityFlow.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAA2C,MAAM,OAAO,CAAC;AAShE,OAAO,EACL,gBAAgB,EAChB,WAAW,EACX,cAAc,EAId,iBAAiB,EAClB,MAAM,oCAAoC,CAAC;AAU5C,MAAM,WAAW,0BAA0B;IACzC,oBAAoB,EAAE,CAAC,MAAM,EAAE,gBAAgB,KAAK,IAAI,CAAC;IACzD,OAAO,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,CAAC;IACzC,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,QAAQ,CAAC,EAAE,iBAAiB,CAAC;IAC7B,kBAAkB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5C,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED,eAAO,MAAM,qBAAqB,EAAE,KAAK,CAAC,EAAE,CAAC,0BAA0B,CAqStE,CAAC;AAiOF,eAAe,qBAAqB,CAAC"}
1
+ {"version":3,"file":"BiometricIdentityFlow.d.ts","sourceRoot":"","sources":["../../src/components/BiometricIdentityFlow.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAA2C,MAAM,OAAO,CAAC;AAChE,OAAO,EAOL,SAAS,EACV,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,gBAAgB,EAChB,WAAW,EACX,cAAc,EAId,iBAAiB,EAClB,MAAM,oCAAoC,CAAC;AAU5C,MAAM,WAAW,0BAA0B;IACzC,oBAAoB,EAAE,CAAC,MAAM,EAAE,gBAAgB,KAAK,IAAI,CAAC;IACzD,OAAO,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,CAAC;IACzC,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,QAAQ,CAAC,EAAE,iBAAiB,CAAC;IAC7B,kBAAkB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5C,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,MAAM,CAAC,EAAE;QACP,SAAS,CAAC,EAAE,SAAS,CAAC;QACtB,OAAO,CAAC,EAAE,SAAS,CAAC;KACrB,CAAC;CACH;AAED,eAAO,MAAM,qBAAqB,EAAE,KAAK,CAAC,EAAE,CAAC,0BAA0B,CAuStE,CAAC;AAiOF,eAAe,qBAAqB,CAAC"}
@@ -48,7 +48,7 @@ const ValidationProgress_1 = require("./ValidationProgress");
48
48
  const ResultScreen_1 = require("./ResultScreen");
49
49
  const ErrorScreen_1 = require("./ErrorScreen");
50
50
  const InstructionsScreen_1 = require("./InstructionsScreen");
51
- const BiometricIdentityFlow = ({ onValidationComplete, onError, theme, language, customTranslations, smartLivenessMode = true, }) => {
51
+ const BiometricIdentityFlow = ({ onValidationComplete, onError, theme, language, customTranslations, smartLivenessMode = true, styles: customStyles, }) => {
52
52
  const { sdk, state, isInitialized, isUsingBackend, challenges, uploadFrontID, uploadBackID, storeVideoRecording, fetchChallenges, validateIdentity, reset, } = (0, useBiometricSDK_1.useBiometricSDK)();
53
53
  const [showCamera, setShowCamera] = (0, react_1.useState)(false);
54
54
  const [cameraMode, setCameraMode] = (0, react_1.useState)('front');
@@ -145,14 +145,14 @@ const BiometricIdentityFlow = ({ onValidationComplete, onError, theme, language,
145
145
  }, [reset]);
146
146
  // Show loading while initializing
147
147
  if (!isInitialized) {
148
- return (react_1.default.createElement(react_native_1.SafeAreaView, { style: styles.container },
148
+ return (react_1.default.createElement(react_native_1.SafeAreaView, { style: [styles.container, customStyles?.container] },
149
149
  react_1.default.createElement(react_native_1.View, { style: styles.loadingFullScreen },
150
150
  react_1.default.createElement(react_native_1.ActivityIndicator, { size: "large", color: theme?.primaryColor || '#6366F1' }),
151
151
  react_1.default.createElement(react_native_1.Text, { style: styles.loadingText }, strings.initialization.initializing))));
152
152
  }
153
153
  // Show instructions on first load
154
154
  if (showInstructions) {
155
- return (react_1.default.createElement(InstructionsScreen_1.InstructionsScreen, { theme: theme, language: language, onStart: () => setShowInstructions(false) }));
155
+ return (react_1.default.createElement(InstructionsScreen_1.InstructionsScreen, { theme: theme, language: language, onStart: () => setShowInstructions(false), styles: customStyles }));
156
156
  }
157
157
  // Show camera/video recorder
158
158
  if (showCamera) {
@@ -176,8 +176,8 @@ const BiometricIdentityFlow = ({ onValidationComplete, onError, theme, language,
176
176
  if (state.currentStep === biometric_identity_sdk_core_1.SDKStep.ERROR && state.error) {
177
177
  return (react_1.default.createElement(ErrorScreen_1.ErrorScreen, { error: state.error, theme: theme, language: language, onRetry: handleRetry, onClose: () => onError(state.error) }));
178
178
  }
179
- return (react_1.default.createElement(react_native_1.SafeAreaView, { style: styles.container },
180
- react_1.default.createElement(react_native_1.View, { style: styles.content },
179
+ return (react_1.default.createElement(react_native_1.SafeAreaView, { style: [styles.container, customStyles?.container] },
180
+ react_1.default.createElement(react_native_1.View, { style: [styles.content, customStyles?.content] },
181
181
  react_1.default.createElement(react_native_1.Text, { style: styles.title }, strings.instructions.title),
182
182
  react_1.default.createElement(react_native_1.Text, { style: styles.subtitle }, strings.instructions.subtitle),
183
183
  isUsingBackend && (react_1.default.createElement(react_native_1.View, { style: styles.backendBadge },
@@ -3,11 +3,16 @@
3
3
  * Shows initial instructions before starting verification
4
4
  */
5
5
  import React from 'react';
6
+ import { ViewStyle } from 'react-native';
6
7
  import { ThemeConfig, SupportedLanguage } from '@hexar/biometric-identity-sdk-core';
7
8
  export interface InstructionsScreenProps {
8
9
  theme?: ThemeConfig;
9
10
  language?: SupportedLanguage;
10
11
  onStart: () => void;
12
+ styles?: {
13
+ container?: ViewStyle;
14
+ content?: ViewStyle;
15
+ };
11
16
  }
12
17
  export declare const InstructionsScreen: React.FC<InstructionsScreenProps>;
13
18
  export default InstructionsScreen;
@@ -1 +1 @@
1
- {"version":3,"file":"InstructionsScreen.d.ts","sourceRoot":"","sources":["../../src/components/InstructionsScreen.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAQ1B,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAc,MAAM,oCAAoC,CAAC;AAEhG,MAAM,WAAW,uBAAuB;IACtC,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,QAAQ,CAAC,EAAE,iBAAiB,CAAC;IAC7B,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED,eAAO,MAAM,kBAAkB,EAAE,KAAK,CAAC,EAAE,CAAC,uBAAuB,CAwEhE,CAAC;AA6KF,eAAe,kBAAkB,CAAC"}
1
+ {"version":3,"file":"InstructionsScreen.d.ts","sourceRoot":"","sources":["../../src/components/InstructionsScreen.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAoB,MAAM,OAAO,CAAC;AACzC,OAAO,EAML,SAAS,EACV,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAA2B,MAAM,oCAAoC,CAAC;AAE7G,MAAM,WAAW,uBAAuB;IACtC,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,QAAQ,CAAC,EAAE,iBAAiB,CAAC;IAC7B,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,MAAM,CAAC,EAAE;QACP,SAAS,CAAC,EAAE,SAAS,CAAC;QACtB,OAAO,CAAC,EAAE,SAAS,CAAC;KACrB,CAAC;CACH;AAED,eAAO,MAAM,kBAAkB,EAAE,KAAK,CAAC,EAAE,CAAC,uBAAuB,CAoFhE,CAAC;AAuLF,eAAe,kBAAkB,CAAC"}
@@ -3,36 +3,76 @@
3
3
  * Instructions Screen Component
4
4
  * Shows initial instructions before starting verification
5
5
  */
6
- var __importDefault = (this && this.__importDefault) || function (mod) {
7
- return (mod && mod.__esModule) ? mod : { "default": mod };
8
- };
6
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
7
+ if (k2 === undefined) k2 = k;
8
+ var desc = Object.getOwnPropertyDescriptor(m, k);
9
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
10
+ desc = { enumerable: true, get: function() { return m[k]; } };
11
+ }
12
+ Object.defineProperty(o, k2, desc);
13
+ }) : (function(o, m, k, k2) {
14
+ if (k2 === undefined) k2 = k;
15
+ o[k2] = m[k];
16
+ }));
17
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
18
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
19
+ }) : function(o, v) {
20
+ o["default"] = v;
21
+ });
22
+ var __importStar = (this && this.__importStar) || (function () {
23
+ var ownKeys = function(o) {
24
+ ownKeys = Object.getOwnPropertyNames || function (o) {
25
+ var ar = [];
26
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
27
+ return ar;
28
+ };
29
+ return ownKeys(o);
30
+ };
31
+ return function (mod) {
32
+ if (mod && mod.__esModule) return mod;
33
+ var result = {};
34
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
35
+ __setModuleDefault(result, mod);
36
+ return result;
37
+ };
38
+ })();
9
39
  Object.defineProperty(exports, "__esModule", { value: true });
10
40
  exports.InstructionsScreen = void 0;
11
- const react_1 = __importDefault(require("react"));
41
+ const react_1 = __importStar(require("react"));
12
42
  const react_native_1 = require("react-native");
13
- const InstructionsScreen = ({ theme, language = 'en', onStart, }) => {
14
- const content = language === 'es' ? spanishContent : englishContent;
15
- return (react_1.default.createElement(react_native_1.View, { style: styles.container },
16
- react_1.default.createElement(react_native_1.ScrollView, { contentContainerStyle: styles.content },
17
- react_1.default.createElement(react_native_1.Text, { style: [styles.title, { color: theme?.textColor || '#000000' }] }, content.title),
18
- react_1.default.createElement(react_native_1.Text, { style: [styles.subtitle, { color: theme?.secondaryTextColor || '#6B7280' }] }, content.subtitle),
43
+ const biometric_identity_sdk_core_1 = require("@hexar/biometric-identity-sdk-core");
44
+ const InstructionsScreen = ({ theme, language = 'en', onStart, styles: customStyles, }) => {
45
+ // Set language when prop changes
46
+ (0, react_1.useEffect)(() => {
47
+ if (language) {
48
+ (0, biometric_identity_sdk_core_1.setLanguage)(language);
49
+ }
50
+ }, [language]);
51
+ const strings = (0, biometric_identity_sdk_core_1.getStrings)();
52
+ // Get tips and privacy message based on language
53
+ const tipsContent = getTipsContent(language);
54
+ const privacyContent = getPrivacyContent(language);
55
+ return (react_1.default.createElement(react_native_1.View, { style: [styles.container, customStyles?.container] },
56
+ react_1.default.createElement(react_native_1.ScrollView, { contentContainerStyle: [styles.content, customStyles?.content] },
57
+ react_1.default.createElement(react_native_1.Text, { style: [styles.title, { color: theme?.textColor || '#000000' }] }, strings.instructions.title),
58
+ react_1.default.createElement(react_native_1.Text, { style: [styles.subtitle, { color: theme?.secondaryTextColor || '#6B7280' }] }, strings.instructions.subtitle),
19
59
  react_1.default.createElement(react_native_1.View, { style: styles.stepsContainer },
20
- react_1.default.createElement(InstructionStep, { number: 1, title: content.step1Title, description: content.step1Description, theme: theme }),
21
- react_1.default.createElement(InstructionStep, { number: 2, title: content.step2Title, description: content.step2Description, theme: theme }),
22
- react_1.default.createElement(InstructionStep, { number: 3, title: content.step3Title, description: content.step3Description, theme: theme })),
60
+ react_1.default.createElement(InstructionStep, { number: 1, title: strings.capture.frontId.title, description: strings.capture.frontId.instruction, theme: theme }),
61
+ react_1.default.createElement(InstructionStep, { number: 2, title: strings.capture.backId.title, description: strings.capture.backId.instruction, theme: theme }),
62
+ react_1.default.createElement(InstructionStep, { number: 3, title: strings.liveness.title, description: strings.liveness.instructions.stayStill, theme: theme })),
23
63
  react_1.default.createElement(react_native_1.View, { style: styles.tipsContainer },
24
- react_1.default.createElement(react_native_1.Text, { style: [styles.tipsTitle, { color: theme?.textColor || '#000000' }] }, content.tipsTitle),
25
- content.tips.map((tip, index) => (react_1.default.createElement(react_native_1.Text, { key: index, style: styles.tipText },
64
+ react_1.default.createElement(react_native_1.Text, { style: [styles.tipsTitle, { color: theme?.textColor || '#000000' }] }, tipsContent.title),
65
+ tipsContent.tips.map((tip, index) => (react_1.default.createElement(react_native_1.Text, { key: index, style: styles.tipText },
26
66
  "\u2022 ",
27
67
  tip)))),
28
68
  react_1.default.createElement(react_native_1.View, { style: styles.privacyContainer },
29
- react_1.default.createElement(react_native_1.Text, { style: styles.privacyText }, content.privacy))),
69
+ react_1.default.createElement(react_native_1.Text, { style: styles.privacyText }, privacyContent))),
30
70
  react_1.default.createElement(react_native_1.View, { style: styles.footer },
31
71
  react_1.default.createElement(react_native_1.TouchableOpacity, { style: [
32
72
  styles.button,
33
73
  { backgroundColor: theme?.primaryColor || '#6366F1' },
34
74
  ], onPress: onStart },
35
- react_1.default.createElement(react_native_1.Text, { style: styles.buttonText }, content.startButton)))));
75
+ react_1.default.createElement(react_native_1.Text, { style: styles.buttonText }, strings.instructions.startButton)))));
36
76
  };
37
77
  exports.InstructionsScreen = InstructionsScreen;
38
78
  const InstructionStep = ({ number, title, description, theme, }) => (react_1.default.createElement(react_native_1.View, { style: stepStyles.container },
@@ -140,42 +180,52 @@ const styles = react_native_1.StyleSheet.create({
140
180
  fontWeight: '600',
141
181
  },
142
182
  });
143
- const englishContent = {
144
- title: 'Identity Verification',
145
- subtitle: 'We need to verify your identity to continue. This process takes about 2 minutes.',
146
- step1Title: 'Capture ID Front',
147
- step1Description: 'Take a clear photo of the front of your ID document.',
148
- step2Title: 'Capture ID Back',
149
- step2Description: 'Take a clear photo of the back of your ID document.',
150
- step3Title: 'Record Face Video',
151
- step3Description: 'Record a short video of your face while following on-screen instructions.',
152
- tipsTitle: 'Tips for Success',
153
- tips: [
154
- 'Ensure good lighting without glare or shadows',
155
- 'Keep your ID flat and all edges visible',
156
- 'Remove glasses and face coverings',
157
- 'Find a quiet place without distractions',
158
- ],
159
- privacy: '🔒 Your data is encrypted and processed securely. We do not store your biometric data locally.',
160
- startButton: 'Start Verification',
183
+ // Helper function to get tips content based on language
184
+ const getTipsContent = (language) => {
185
+ switch (language) {
186
+ case 'es':
187
+ case 'es-AR':
188
+ return {
189
+ title: 'Consejos para el Éxito',
190
+ tips: [
191
+ 'Asegura buena iluminación sin brillos o sombras',
192
+ 'Mantén tu documento plano y todos los bordes visibles',
193
+ 'Quítate los lentes y cubiertas faciales',
194
+ 'Encuentra un lugar tranquilo sin distracciones',
195
+ ],
196
+ };
197
+ case 'pt-BR':
198
+ return {
199
+ title: 'Dicas para o Sucesso',
200
+ tips: [
201
+ 'Garanta boa iluminação sem brilhos ou sombras',
202
+ 'Mantenha seu documento plano e todas as bordas visíveis',
203
+ 'Remova óculos e coberturas faciais',
204
+ 'Encontre um lugar tranquilo sem distrações',
205
+ ],
206
+ };
207
+ default:
208
+ return {
209
+ title: 'Tips for Success',
210
+ tips: [
211
+ 'Ensure good lighting without glare or shadows',
212
+ 'Keep your ID flat and all edges visible',
213
+ 'Remove glasses and face coverings',
214
+ 'Find a quiet place without distractions',
215
+ ],
216
+ };
217
+ }
161
218
  };
162
- const spanishContent = {
163
- title: 'Verificación de Identidad',
164
- subtitle: 'Necesitamos verificar tu identidad para continuar. Este proceso toma aproximadamente 2 minutos.',
165
- step1Title: 'Captura Frente del Documento',
166
- step1Description: 'Toma una foto clara del frente de tu documento de identidad.',
167
- step2Title: 'Captura Reverso del Documento',
168
- step2Description: 'Toma una foto clara del reverso de tu documento de identidad.',
169
- step3Title: 'Graba Video Facial',
170
- step3Description: 'Graba un video corto de tu rostro siguiendo las instrucciones en pantalla.',
171
- tipsTitle: 'Consejos para el Éxito',
172
- tips: [
173
- 'Asegura buena iluminación sin brillos o sombras',
174
- 'Mantén tu documento plano y todos los bordes visibles',
175
- 'Quítate los lentes y cubiertas faciales',
176
- 'Encuentra un lugar tranquilo sin distracciones',
177
- ],
178
- privacy: '🔒 Tus datos están encriptados y procesados de forma segura. No almacenamos tus datos biométricos localmente.',
179
- startButton: 'Iniciar Verificación',
219
+ // Helper function to get privacy message based on language
220
+ const getPrivacyContent = (language) => {
221
+ switch (language) {
222
+ case 'es':
223
+ case 'es-AR':
224
+ return '🔒 Tus datos están encriptados y procesados de forma segura. No almacenamos tus datos biométricos localmente.';
225
+ case 'pt-BR':
226
+ return '🔒 Seus dados estão criptografados e processados com segurança. Não armazenamos seus dados biométricos localmente.';
227
+ default:
228
+ return '🔒 Your data is encrypted and processed securely. We do not store your biometric data locally.';
229
+ }
180
230
  };
181
231
  exports.default = exports.InstructionsScreen;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hexar/biometric-identity-sdk-react-native",
3
- "version": "1.0.2",
3
+ "version": "1.0.4",
4
4
  "description": "React Native wrapper for Biometric Identity SDK",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -11,6 +11,7 @@ import {
11
11
  TouchableOpacity,
12
12
  ActivityIndicator,
13
13
  SafeAreaView,
14
+ ViewStyle,
14
15
  } from 'react-native';
15
16
  import {
16
17
  ValidationResult,
@@ -37,6 +38,10 @@ export interface BiometricIdentityFlowProps {
37
38
  language?: SupportedLanguage;
38
39
  customTranslations?: Record<string, string>;
39
40
  smartLivenessMode?: boolean;
41
+ styles?: {
42
+ container?: ViewStyle;
43
+ content?: ViewStyle;
44
+ };
40
45
  }
41
46
 
42
47
  export const BiometricIdentityFlow: React.FC<BiometricIdentityFlowProps> = ({
@@ -46,6 +51,7 @@ export const BiometricIdentityFlow: React.FC<BiometricIdentityFlowProps> = ({
46
51
  language,
47
52
  customTranslations,
48
53
  smartLivenessMode = true,
54
+ styles: customStyles,
49
55
  }) => {
50
56
  const {
51
57
  sdk,
@@ -165,7 +171,7 @@ export const BiometricIdentityFlow: React.FC<BiometricIdentityFlowProps> = ({
165
171
  // Show loading while initializing
166
172
  if (!isInitialized) {
167
173
  return (
168
- <SafeAreaView style={styles.container}>
174
+ <SafeAreaView style={[styles.container, customStyles?.container]}>
169
175
  <View style={styles.loadingFullScreen}>
170
176
  <ActivityIndicator size="large" color={theme?.primaryColor || '#6366F1'} />
171
177
  <Text style={styles.loadingText}>{strings.initialization.initializing}</Text>
@@ -181,6 +187,7 @@ export const BiometricIdentityFlow: React.FC<BiometricIdentityFlowProps> = ({
181
187
  theme={theme}
182
188
  language={language}
183
189
  onStart={() => setShowInstructions(false)}
190
+ styles={customStyles}
184
191
  />
185
192
  );
186
193
  }
@@ -251,8 +258,8 @@ export const BiometricIdentityFlow: React.FC<BiometricIdentityFlowProps> = ({
251
258
  }
252
259
 
253
260
  return (
254
- <SafeAreaView style={styles.container}>
255
- <View style={styles.content}>
261
+ <SafeAreaView style={[styles.container, customStyles?.container]}>
262
+ <View style={[styles.content, customStyles?.content]}>
256
263
  <Text style={styles.title}>{strings.instructions.title}</Text>
257
264
  <Text style={styles.subtitle}>{strings.instructions.subtitle}</Text>
258
265
 
@@ -3,58 +3,75 @@
3
3
  * Shows initial instructions before starting verification
4
4
  */
5
5
 
6
- import React from 'react';
6
+ import React, { useEffect } from 'react';
7
7
  import {
8
8
  View,
9
9
  Text,
10
10
  StyleSheet,
11
11
  TouchableOpacity,
12
12
  ScrollView,
13
+ ViewStyle,
13
14
  } from 'react-native';
14
- import { ThemeConfig, SupportedLanguage, getStrings } from '@hexar/biometric-identity-sdk-core';
15
+ import { ThemeConfig, SupportedLanguage, getStrings, setLanguage } from '@hexar/biometric-identity-sdk-core';
15
16
 
16
17
  export interface InstructionsScreenProps {
17
18
  theme?: ThemeConfig;
18
19
  language?: SupportedLanguage;
19
20
  onStart: () => void;
21
+ styles?: {
22
+ container?: ViewStyle;
23
+ content?: ViewStyle;
24
+ };
20
25
  }
21
26
 
22
27
  export const InstructionsScreen: React.FC<InstructionsScreenProps> = ({
23
28
  theme,
24
29
  language = 'en',
25
30
  onStart,
31
+ styles: customStyles,
26
32
  }) => {
27
- const content = language === 'es' ? spanishContent : englishContent;
33
+ // Set language when prop changes
34
+ useEffect(() => {
35
+ if (language) {
36
+ setLanguage(language);
37
+ }
38
+ }, [language]);
39
+
40
+ const strings = getStrings();
41
+
42
+ // Get tips and privacy message based on language
43
+ const tipsContent = getTipsContent(language);
44
+ const privacyContent = getPrivacyContent(language);
28
45
 
29
46
  return (
30
- <View style={styles.container}>
31
- <ScrollView contentContainerStyle={styles.content}>
47
+ <View style={[styles.container, customStyles?.container]}>
48
+ <ScrollView contentContainerStyle={[styles.content, customStyles?.content]}>
32
49
  <Text style={[styles.title, { color: theme?.textColor || '#000000' }]}>
33
- {content.title}
50
+ {strings.instructions.title}
34
51
  </Text>
35
52
 
36
53
  <Text style={[styles.subtitle, { color: theme?.secondaryTextColor || '#6B7280' }]}>
37
- {content.subtitle}
54
+ {strings.instructions.subtitle}
38
55
  </Text>
39
56
 
40
57
  {/* Steps */}
41
58
  <View style={styles.stepsContainer}>
42
59
  <InstructionStep
43
60
  number={1}
44
- title={content.step1Title}
45
- description={content.step1Description}
61
+ title={strings.capture.frontId.title}
62
+ description={strings.capture.frontId.instruction}
46
63
  theme={theme}
47
64
  />
48
65
  <InstructionStep
49
66
  number={2}
50
- title={content.step2Title}
51
- description={content.step2Description}
67
+ title={strings.capture.backId.title}
68
+ description={strings.capture.backId.instruction}
52
69
  theme={theme}
53
70
  />
54
71
  <InstructionStep
55
72
  number={3}
56
- title={content.step3Title}
57
- description={content.step3Description}
73
+ title={strings.liveness.title}
74
+ description={strings.liveness.instructions.stayStill}
58
75
  theme={theme}
59
76
  />
60
77
  </View>
@@ -62,9 +79,9 @@ export const InstructionsScreen: React.FC<InstructionsScreenProps> = ({
62
79
  {/* Tips */}
63
80
  <View style={styles.tipsContainer}>
64
81
  <Text style={[styles.tipsTitle, { color: theme?.textColor || '#000000' }]}>
65
- {content.tipsTitle}
82
+ {tipsContent.title}
66
83
  </Text>
67
- {content.tips.map((tip, index) => (
84
+ {tipsContent.tips.map((tip, index) => (
68
85
  <Text key={index} style={styles.tipText}>
69
86
  • {tip}
70
87
  </Text>
@@ -73,7 +90,7 @@ export const InstructionsScreen: React.FC<InstructionsScreenProps> = ({
73
90
 
74
91
  {/* Privacy Notice */}
75
92
  <View style={styles.privacyContainer}>
76
- <Text style={styles.privacyText}>{content.privacy}</Text>
93
+ <Text style={styles.privacyText}>{privacyContent}</Text>
77
94
  </View>
78
95
  </ScrollView>
79
96
 
@@ -86,7 +103,7 @@ export const InstructionsScreen: React.FC<InstructionsScreenProps> = ({
86
103
  ]}
87
104
  onPress={onStart}
88
105
  >
89
- <Text style={styles.buttonText}>{content.startButton}</Text>
106
+ <Text style={styles.buttonText}>{strings.instructions.startButton}</Text>
90
107
  </TouchableOpacity>
91
108
  </View>
92
109
  </View>
@@ -224,44 +241,54 @@ const styles = StyleSheet.create({
224
241
  },
225
242
  });
226
243
 
227
- const englishContent = {
228
- title: 'Identity Verification',
229
- subtitle: 'We need to verify your identity to continue. This process takes about 2 minutes.',
230
- step1Title: 'Capture ID Front',
231
- step1Description: 'Take a clear photo of the front of your ID document.',
232
- step2Title: 'Capture ID Back',
233
- step2Description: 'Take a clear photo of the back of your ID document.',
234
- step3Title: 'Record Face Video',
235
- step3Description: 'Record a short video of your face while following on-screen instructions.',
236
- tipsTitle: 'Tips for Success',
237
- tips: [
238
- 'Ensure good lighting without glare or shadows',
239
- 'Keep your ID flat and all edges visible',
240
- 'Remove glasses and face coverings',
241
- 'Find a quiet place without distractions',
242
- ],
243
- privacy: '🔒 Your data is encrypted and processed securely. We do not store your biometric data locally.',
244
- startButton: 'Start Verification',
244
+ // Helper function to get tips content based on language
245
+ const getTipsContent = (language?: SupportedLanguage) => {
246
+ switch (language) {
247
+ case 'es':
248
+ case 'es-AR':
249
+ return {
250
+ title: 'Consejos para el Éxito',
251
+ tips: [
252
+ 'Asegura buena iluminación sin brillos o sombras',
253
+ 'Mantén tu documento plano y todos los bordes visibles',
254
+ 'Quítate los lentes y cubiertas faciales',
255
+ 'Encuentra un lugar tranquilo sin distracciones',
256
+ ],
257
+ };
258
+ case 'pt-BR':
259
+ return {
260
+ title: 'Dicas para o Sucesso',
261
+ tips: [
262
+ 'Garanta boa iluminação sem brilhos ou sombras',
263
+ 'Mantenha seu documento plano e todas as bordas visíveis',
264
+ 'Remova óculos e coberturas faciais',
265
+ 'Encontre um lugar tranquilo sem distrações',
266
+ ],
267
+ };
268
+ default:
269
+ return {
270
+ title: 'Tips for Success',
271
+ tips: [
272
+ 'Ensure good lighting without glare or shadows',
273
+ 'Keep your ID flat and all edges visible',
274
+ 'Remove glasses and face coverings',
275
+ 'Find a quiet place without distractions',
276
+ ],
277
+ };
278
+ }
245
279
  };
246
280
 
247
- const spanishContent = {
248
- title: 'Verificación de Identidad',
249
- subtitle: 'Necesitamos verificar tu identidad para continuar. Este proceso toma aproximadamente 2 minutos.',
250
- step1Title: 'Captura Frente del Documento',
251
- step1Description: 'Toma una foto clara del frente de tu documento de identidad.',
252
- step2Title: 'Captura Reverso del Documento',
253
- step2Description: 'Toma una foto clara del reverso de tu documento de identidad.',
254
- step3Title: 'Graba Video Facial',
255
- step3Description: 'Graba un video corto de tu rostro siguiendo las instrucciones en pantalla.',
256
- tipsTitle: 'Consejos para el Éxito',
257
- tips: [
258
- 'Asegura buena iluminación sin brillos o sombras',
259
- 'Mantén tu documento plano y todos los bordes visibles',
260
- 'Quítate los lentes y cubiertas faciales',
261
- 'Encuentra un lugar tranquilo sin distracciones',
262
- ],
263
- privacy: '🔒 Tus datos están encriptados y procesados de forma segura. No almacenamos tus datos biométricos localmente.',
264
- startButton: 'Iniciar Verificación',
281
+ // Helper function to get privacy message based on language
282
+ const getPrivacyContent = (language?: SupportedLanguage): string => {
283
+ switch (language) {
284
+ case 'es':
285
+ case 'es-AR':
286
+ return '🔒 Tus datos están encriptados y procesados de forma segura. No almacenamos tus datos biométricos localmente.';
287
+ case 'pt-BR':
288
+ return '🔒 Seus dados estão criptografados e processados com segurança. Não armazenamos seus dados biométricos localmente.';
289
+ default:
290
+ return '🔒 Your data is encrypted and processed securely. We do not store your biometric data locally.';
291
+ }
265
292
  };
266
293
 
267
294
  export default InstructionsScreen;