@redacto.io/consent-sdk-react-native 1.0.0 → 2.0.0

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/index.js CHANGED
@@ -36,9 +36,9 @@ __export(src_exports, {
36
36
  module.exports = __toCommonJS(src_exports);
37
37
 
38
38
  // src/RedactoNoticeConsent/RedactoNoticeConsent.tsx
39
- var import_react = require("react");
40
- var import_react_native4 = require("react-native");
41
- var import_react_native_svg2 = __toESM(require("react-native-svg"));
39
+ var import_react2 = require("react");
40
+ var import_react_native5 = require("react-native");
41
+ var import_react_native_svg3 = __toESM(require("react-native-svg"));
42
42
 
43
43
  // src/RedactoNoticeConsent/api/index.ts
44
44
  var import_jwt_decode = require("jwt-decode");
@@ -151,6 +151,8 @@ var submitConsentEvent = async ({
151
151
  purposes,
152
152
  declined,
153
153
  meta_data,
154
+ guardianVerificationReference,
155
+ selfDeclaredAdult,
154
156
  signal
155
157
  }) => {
156
158
  if (!noticeUuid || !accessToken || !Array.isArray(purposes)) {
@@ -185,7 +187,9 @@ var submitConsentEvent = async ({
185
187
  select_all_mandatory: false,
186
188
  source: "MOBILE",
187
189
  declined: Boolean(declined),
188
- meta_data: meta_data ? { specific_uuid: meta_data.specific_uuid } : void 0
190
+ meta_data: meta_data ? { specific_uuid: meta_data.specific_uuid } : void 0,
191
+ guardian_verification_reference: guardianVerificationReference,
192
+ self_declared_adult: selfDeclaredAdult
189
193
  };
190
194
  const response = await fetch(
191
195
  `${apiBaseUrl}/public/organisations/${ORGANISATION_UUID}/workspaces/${WORKSPACE_UUID}/submit-consent`,
@@ -218,25 +222,85 @@ var submitConsentEvent = async ({
218
222
  }
219
223
  apiCache.clear();
220
224
  };
221
- var submitGuardianInfo = async ({
225
+ var fetchTTSAudioUrls = async ({
226
+ accessToken,
227
+ baseUrl,
228
+ noticeUuid,
229
+ language,
230
+ signal
231
+ }) => {
232
+ if (!accessToken || !noticeUuid || !language) {
233
+ throw new Error("accessToken, noticeUuid, and language are required");
234
+ }
235
+ const decodedToken = decodeTokenSafely(accessToken);
236
+ if (!decodedToken) {
237
+ throw new Error("Invalid access token");
238
+ }
239
+ const { organisation_uuid: ORGANISATION_UUID, workspace_uuid: WORKSPACE_UUID } = decodedToken;
240
+ if (!ORGANISATION_UUID || !WORKSPACE_UUID) {
241
+ throw new Error("Invalid token: missing organization or workspace UUID");
242
+ }
243
+ const apiBaseUrl = baseUrl || DEFAULT_CONSENT_API_BASE_URL;
244
+ const normalizedLanguage = language === "en" || language === "EN" ? "English" : language;
245
+ const url = `${apiBaseUrl}/public/organisations/${ORGANISATION_UUID}/workspaces/${WORKSPACE_UUID}/notices/${noticeUuid}/audio/${encodeURIComponent(normalizedLanguage)}`;
246
+ const response = await fetch(url, {
247
+ method: "GET",
248
+ headers: {
249
+ Authorization: `Bearer ${accessToken}`,
250
+ Accept: "application/json",
251
+ "Content-Type": "application/json"
252
+ },
253
+ signal
254
+ });
255
+ if (!response.ok) {
256
+ let errorMessage = `Failed to fetch TTS audio URLs: ${response.status} ${response.statusText}`;
257
+ if (response.status === 401) {
258
+ errorMessage = "Unauthorized: Invalid or expired token";
259
+ } else if (response.status === 403) {
260
+ errorMessage = "Forbidden: Access denied";
261
+ } else if (response.status === 404) {
262
+ errorMessage = "Notice or audio not found";
263
+ } else if (response.status >= 500) {
264
+ errorMessage = "Server error: Please try again later";
265
+ }
266
+ let errorDetails = "";
267
+ try {
268
+ const bodyText = await response.text();
269
+ if (bodyText) {
270
+ errorDetails = bodyText.slice(0, 200);
271
+ }
272
+ } catch {
273
+ }
274
+ if (errorDetails) {
275
+ errorMessage = `${errorMessage}. Response: ${errorDetails}`;
276
+ }
277
+ const error = new Error(errorMessage);
278
+ error.status = response.status;
279
+ throw error;
280
+ }
281
+ return response.json();
282
+ };
283
+ var initiateGuardianVerification = async ({
222
284
  accessToken,
223
285
  baseUrl,
224
286
  guardianName,
225
287
  guardianContact,
226
288
  guardianRelationship,
289
+ frontendCallbackUrl,
227
290
  signal
228
291
  }) => {
292
+ var _a, _b, _c, _d, _e;
229
293
  if (!accessToken) {
230
294
  throw new Error("accessToken is required");
231
295
  }
232
296
  if (!(guardianName == null ? void 0 : guardianName.trim())) {
233
- throw new Error("guardianName is required and cannot be empty");
297
+ throw new Error("Guardian name is required");
234
298
  }
235
299
  if (!(guardianContact == null ? void 0 : guardianContact.trim())) {
236
- throw new Error("guardianContact is required and cannot be empty");
300
+ throw new Error("Guardian contact is required");
237
301
  }
238
302
  if (!(guardianRelationship == null ? void 0 : guardianRelationship.trim())) {
239
- throw new Error("guardianRelationship is required and cannot be empty");
303
+ throw new Error("Guardian relationship is required");
240
304
  }
241
305
  const decodedToken = decodeTokenSafely(accessToken);
242
306
  if (!decodedToken) {
@@ -246,14 +310,15 @@ var submitGuardianInfo = async ({
246
310
  if (!ORGANISATION_UUID || !WORKSPACE_UUID) {
247
311
  throw new Error("Invalid token: missing organization or workspace UUID");
248
312
  }
313
+ const apiBaseUrl = baseUrl || DEFAULT_CONSENT_API_BASE_URL;
249
314
  const payload = {
250
315
  guardian_name: guardianName.trim(),
251
316
  guardian_contact: guardianContact.trim(),
252
- guardian_relationship: guardianRelationship.trim()
317
+ guardian_relationship: guardianRelationship.trim(),
318
+ frontend_callback_url: frontendCallbackUrl
253
319
  };
254
- const apiBaseUrl = baseUrl || DEFAULT_CONSENT_API_BASE_URL;
255
320
  const response = await fetch(
256
- `${apiBaseUrl}/public/organisations/${ORGANISATION_UUID}/workspaces/${WORKSPACE_UUID}/guardian-info`,
321
+ `${apiBaseUrl}/public/organisations/${ORGANISATION_UUID}/workspaces/${WORKSPACE_UUID}/guardian/initiate-verification`,
257
322
  {
258
323
  method: "POST",
259
324
  headers: {
@@ -265,15 +330,13 @@ var submitGuardianInfo = async ({
265
330
  }
266
331
  );
267
332
  if (!response.ok) {
268
- let errorMessage = `Failed to submit guardian info: ${response.status} ${response.statusText}`;
333
+ let errorMessage = `Failed to initiate guardian verification: ${response.status} ${response.statusText}`;
269
334
  if (response.status === 400) {
270
335
  errorMessage = "Invalid request data";
271
336
  } else if (response.status === 401) {
272
337
  errorMessage = "Unauthorized: Invalid or expired token";
273
338
  } else if (response.status === 403) {
274
339
  errorMessage = "Forbidden: Access denied";
275
- } else if (response.status === 404) {
276
- errorMessage = "Organization or workspace not found";
277
340
  } else if (response.status === 422) {
278
341
  try {
279
342
  const errorData = await response.json();
@@ -288,16 +351,26 @@ var submitGuardianInfo = async ({
288
351
  error.status = response.status;
289
352
  throw error;
290
353
  }
354
+ const data = await response.json();
355
+ const raw = data.detail || data;
356
+ return {
357
+ sessionToken: (_a = raw.session_token) != null ? _a : raw.sessionToken,
358
+ digilockerRedirectUrl: (_b = raw.digilocker_redirect_url) != null ? _b : raw.digilockerRedirectUrl,
359
+ verificationReference: (_c = raw.verification_reference) != null ? _c : raw.verificationReference,
360
+ expiresAt: (_d = raw.expires_at) != null ? _d : raw.expiresAt,
361
+ status: raw.status,
362
+ alreadyVerified: (_e = raw.already_verified) != null ? _e : raw.alreadyVerified
363
+ };
291
364
  };
292
- var fetchTTSAudioUrls = async ({
365
+ var verifyGuardianStatus = async ({
293
366
  accessToken,
294
367
  baseUrl,
295
- noticeUuid,
296
- language,
368
+ sessionToken,
297
369
  signal
298
370
  }) => {
299
- if (!accessToken || !noticeUuid || !language) {
300
- throw new Error("accessToken, noticeUuid, and language are required");
371
+ var _a, _b, _c;
372
+ if (!accessToken || !sessionToken) {
373
+ throw new Error("accessToken and sessionToken are required");
301
374
  }
302
375
  const decodedToken = decodeTokenSafely(accessToken);
303
376
  if (!decodedToken) {
@@ -308,24 +381,22 @@ var fetchTTSAudioUrls = async ({
308
381
  throw new Error("Invalid token: missing organization or workspace UUID");
309
382
  }
310
383
  const apiBaseUrl = baseUrl || DEFAULT_CONSENT_API_BASE_URL;
311
- const url = `${apiBaseUrl}/public/organisations/${ORGANISATION_UUID}/workspaces/${WORKSPACE_UUID}/notices/${noticeUuid}/audio/${language}`;
312
- const response = await fetch(url, {
313
- method: "GET",
314
- headers: {
315
- Authorization: `Bearer ${accessToken}`,
316
- Accept: "application/json",
317
- "Content-Type": "application/json"
318
- },
319
- signal
320
- });
384
+ const response = await fetch(
385
+ `${apiBaseUrl}/public/organisations/${ORGANISATION_UUID}/workspaces/${WORKSPACE_UUID}/guardian/verify-status`,
386
+ {
387
+ method: "POST",
388
+ headers: {
389
+ Authorization: `Bearer ${accessToken}`,
390
+ "Content-Type": "application/json"
391
+ },
392
+ body: JSON.stringify({ session_token: sessionToken }),
393
+ signal
394
+ }
395
+ );
321
396
  if (!response.ok) {
322
- let errorMessage = `Failed to fetch TTS audio URLs: ${response.status} ${response.statusText}`;
397
+ let errorMessage = `Failed to verify guardian status: ${response.status} ${response.statusText}`;
323
398
  if (response.status === 401) {
324
399
  errorMessage = "Unauthorized: Invalid or expired token";
325
- } else if (response.status === 403) {
326
- errorMessage = "Forbidden: Access denied";
327
- } else if (response.status === 404) {
328
- errorMessage = "Notice or audio not found";
329
400
  } else if (response.status >= 500) {
330
401
  errorMessage = "Server error: Please try again later";
331
402
  }
@@ -333,7 +404,15 @@ var fetchTTSAudioUrls = async ({
333
404
  error.status = response.status;
334
405
  throw error;
335
406
  }
336
- return response.json();
407
+ const data = await response.json();
408
+ const raw = data.detail || data;
409
+ return {
410
+ status: raw.status,
411
+ verificationReference: (_a = raw.verification_reference) != null ? _a : raw.verificationReference,
412
+ error: raw.error,
413
+ errorCode: (_b = raw.error_code) != null ? _b : raw.errorCode,
414
+ canRetry: (_c = raw.can_retry) != null ? _c : raw.canRetry
415
+ };
337
416
  };
338
417
 
339
418
  // src/RedactoNoticeConsent/components/Checkbox.tsx
@@ -345,11 +424,13 @@ var Checkbox = ({
345
424
  onChange,
346
425
  size = "large",
347
426
  disabled = false,
348
- accessibilityLabel
427
+ accessibilityLabel,
428
+ accentColor
349
429
  }) => {
350
430
  const isLarge = size === "large";
351
431
  const boxSize = isLarge ? 20 : 16;
352
432
  const iconSize = isLarge ? 10 : 8;
433
+ const color = accentColor || "#4f87ff";
353
434
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
354
435
  import_react_native.TouchableOpacity,
355
436
  {
@@ -364,8 +445,8 @@ var Checkbox = ({
364
445
  {
365
446
  style: [
366
447
  styles.box,
367
- { width: boxSize, height: boxSize, borderRadius: 5 },
368
- checked ? styles.checked : styles.unchecked,
448
+ { width: boxSize, height: boxSize, borderRadius: 4 },
449
+ checked ? { backgroundColor: color, borderColor: color } : styles.unchecked,
369
450
  disabled && styles.disabled
370
451
  ],
371
452
  children: checked && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
@@ -378,9 +459,9 @@ var Checkbox = ({
378
459
  children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
379
460
  import_react_native_svg.Path,
380
461
  {
381
- d: "M1.5 5L4 7.5L8.5 2.5",
462
+ d: "M2.5 5L4.2 6.7L7.5 3.3",
382
463
  stroke: "white",
383
- strokeWidth: 1.8,
464
+ strokeWidth: isLarge ? 2 : 1.5,
384
465
  strokeLinecap: "round",
385
466
  strokeLinejoin: "round"
386
467
  }
@@ -396,11 +477,7 @@ var styles = import_react_native.StyleSheet.create({
396
477
  box: {
397
478
  alignItems: "center",
398
479
  justifyContent: "center",
399
- borderWidth: 2
400
- },
401
- checked: {
402
- backgroundColor: "#4f87ff",
403
- borderColor: "#4f87ff"
480
+ borderWidth: 1.5
404
481
  },
405
482
  unchecked: {
406
483
  backgroundColor: "transparent",
@@ -411,9 +488,393 @@ var styles = import_react_native.StyleSheet.create({
411
488
  }
412
489
  });
413
490
 
414
- // src/RedactoNoticeConsent/styles.ts
491
+ // src/RedactoNoticeConsent/components/VerificationScreen.tsx
492
+ var import_react = require("react");
415
493
  var import_react_native2 = require("react-native");
416
- var styles2 = import_react_native2.StyleSheet.create({
494
+ var import_react_native_svg2 = __toESM(require("react-native-svg"));
495
+ var import_jsx_runtime2 = require("react/jsx-runtime");
496
+ var VerificationScreen = ({
497
+ status,
498
+ errorMessage,
499
+ errorCode,
500
+ canRetry,
501
+ onRetry,
502
+ onBack,
503
+ onContinue,
504
+ onChangeGuardian,
505
+ settings
506
+ }) => {
507
+ var _a, _b, _c, _d, _e, _f, _g, _h;
508
+ const headingColor = (settings == null ? void 0 : settings.headingColor) || "#323B4B";
509
+ const textColor = (settings == null ? void 0 : settings.textColor) || "#344054";
510
+ const acceptBg = ((_b = (_a = settings == null ? void 0 : settings.button) == null ? void 0 : _a.accept) == null ? void 0 : _b.backgroundColor) || (settings == null ? void 0 : settings.primaryColor) || "#4f87ff";
511
+ const acceptText = ((_d = (_c = settings == null ? void 0 : settings.button) == null ? void 0 : _c.accept) == null ? void 0 : _d.textColor) || "#ffffff";
512
+ const declineBg = ((_f = (_e = settings == null ? void 0 : settings.button) == null ? void 0 : _e.decline) == null ? void 0 : _f.backgroundColor) || "#ffffff";
513
+ const declineText = ((_h = (_g = settings == null ? void 0 : settings.button) == null ? void 0 : _g.decline) == null ? void 0 : _h.textColor) || "#000000";
514
+ const borderColor = (settings == null ? void 0 : settings.borderColor) || "#d0d5dd";
515
+ const scaleAnim = (0, import_react.useRef)(new import_react_native2.Animated.Value(0.3)).current;
516
+ const contentAnim = (0, import_react.useRef)(new import_react_native2.Animated.Value(0)).current;
517
+ const pulseAnim = (0, import_react.useRef)(new import_react_native2.Animated.Value(0.6)).current;
518
+ (0, import_react.useEffect)(() => {
519
+ import_react_native2.Animated.spring(scaleAnim, {
520
+ toValue: 1,
521
+ friction: 5,
522
+ tension: 40,
523
+ delay: 100,
524
+ useNativeDriver: true
525
+ }).start();
526
+ import_react_native2.Animated.timing(contentAnim, {
527
+ toValue: 1,
528
+ duration: 400,
529
+ delay: 250,
530
+ useNativeDriver: true
531
+ }).start();
532
+ if (status === "verified") {
533
+ import_react_native2.Animated.loop(
534
+ import_react_native2.Animated.sequence([
535
+ import_react_native2.Animated.timing(pulseAnim, {
536
+ toValue: 0,
537
+ duration: 1200,
538
+ useNativeDriver: true
539
+ }),
540
+ import_react_native2.Animated.timing(pulseAnim, {
541
+ toValue: 0.6,
542
+ duration: 0,
543
+ useNativeDriver: true
544
+ })
545
+ ])
546
+ ).start();
547
+ }
548
+ }, [status, scaleAnim, contentAnim, pulseAnim]);
549
+ const getErrorGuidance = () => {
550
+ switch (errorCode) {
551
+ case "GUARDIAN_UNDER_18":
552
+ return "The guardian must be 18 years or older to provide consent.";
553
+ case "TOKEN_FAILED":
554
+ return "The verification session has expired. Please try again.";
555
+ case "DIGILOCKER_AUTH_FAILED":
556
+ return "DigiLocker authentication failed. Please try again and complete the verification in the browser.";
557
+ case "SESSION_EXPIRED":
558
+ return "Your verification session has expired. Please start a new verification.";
559
+ default:
560
+ return errorMessage || "An error occurred during verification. Please try again.";
561
+ }
562
+ };
563
+ const renderPendingContent = () => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native2.View, { style: s.centerContent, children: [
564
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.ActivityIndicator, { size: "large", color: acceptBg, style: s.pendingSpinner }),
565
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native2.View, { style: s.infoBanner, children: [
566
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native_svg2.default, { width: 16, height: 16, viewBox: "0 0 24 24", fill: "none", style: s.infoBannerIcon, children: [
567
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native_svg2.Circle, { cx: "12", cy: "12", r: "10", stroke: "#059669", strokeWidth: 2 }),
568
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native_svg2.Path, { d: "M12 16v-4M12 8h.01", stroke: "#059669", strokeWidth: 2, strokeLinecap: "round", strokeLinejoin: "round" })
569
+ ] }),
570
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.Text, { style: s.infoBannerText, children: "Please complete the verification in Safari. This screen will update automatically when verification is complete." })
571
+ ] })
572
+ ] });
573
+ const renderSuccessContent = () => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native2.View, { style: s.centerContent, children: [
574
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native2.View, { style: s.iconWrapper, children: [
575
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
576
+ import_react_native2.Animated.View,
577
+ {
578
+ style: [
579
+ s.pulseRing,
580
+ {
581
+ opacity: pulseAnim,
582
+ transform: [{
583
+ scale: pulseAnim.interpolate({
584
+ inputRange: [0, 0.6],
585
+ outputRange: [1.15, 1]
586
+ })
587
+ }]
588
+ }
589
+ ]
590
+ }
591
+ ),
592
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.Animated.View, { style: [s.successCircle, { transform: [{ scale: scaleAnim }] }], children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native_svg2.default, { width: 30, height: 30, viewBox: "0 0 24 24", fill: "none", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
593
+ import_react_native_svg2.Path,
594
+ {
595
+ d: "M5 13L9 17L19 7",
596
+ stroke: "#059669",
597
+ strokeWidth: 3,
598
+ strokeLinecap: "round",
599
+ strokeLinejoin: "round"
600
+ }
601
+ ) }) })
602
+ ] }),
603
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
604
+ import_react_native2.Animated.Text,
605
+ {
606
+ style: [
607
+ s.statusTitle,
608
+ { color: headingColor, opacity: contentAnim, transform: [{ translateY: contentAnim.interpolate({ inputRange: [0, 1], outputRange: [8, 0] }) }] }
609
+ ],
610
+ children: "Verification Completed"
611
+ }
612
+ ),
613
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
614
+ import_react_native2.Animated.Text,
615
+ {
616
+ style: [
617
+ s.statusSubtext,
618
+ { color: textColor, opacity: contentAnim, transform: [{ translateY: contentAnim.interpolate({ inputRange: [0, 1], outputRange: [8, 0] }) }] }
619
+ ],
620
+ children: "Your guardian's identity has been successfully verified. You can now proceed."
621
+ }
622
+ )
623
+ ] });
624
+ const renderErrorContent = () => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native2.View, { style: s.centerContent, children: [
625
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.View, { style: s.iconWrapper, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.Animated.View, { style: [s.errorCircle, { transform: [{ scale: scaleAnim }] }], children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native_svg2.default, { width: 30, height: 30, viewBox: "0 0 24 24", fill: "none", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
626
+ import_react_native_svg2.Path,
627
+ {
628
+ d: "M18 6L6 18M6 6L18 18",
629
+ stroke: "#DC2626",
630
+ strokeWidth: 3,
631
+ strokeLinecap: "round",
632
+ strokeLinejoin: "round"
633
+ }
634
+ ) }) }) }),
635
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
636
+ import_react_native2.Animated.Text,
637
+ {
638
+ style: [
639
+ s.statusTitle,
640
+ { color: headingColor, opacity: contentAnim }
641
+ ],
642
+ children: [
643
+ "Verification ",
644
+ status === "expired" ? "Expired" : "Failed"
645
+ ]
646
+ }
647
+ ),
648
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native2.Animated.View, { style: [s.errorBanner, { opacity: contentAnim }], children: [
649
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native_svg2.default, { width: 16, height: 16, viewBox: "0 0 24 24", fill: "none", style: s.infoBannerIcon, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
650
+ import_react_native_svg2.Path,
651
+ {
652
+ d: "M12 9v4M12 17h.01M10.29 3.86L1.82 18a2 2 0 001.71 3h16.94a2 2 0 001.71-3L13.71 3.86a2 2 0 00-3.42 0z",
653
+ stroke: "#DC2626",
654
+ strokeWidth: 2,
655
+ strokeLinecap: "round",
656
+ strokeLinejoin: "round"
657
+ }
658
+ ) }),
659
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.Text, { style: s.errorBannerText, children: getErrorGuidance() })
660
+ ] })
661
+ ] });
662
+ const renderBottomButtons = () => {
663
+ if (status === "verified") {
664
+ if (!onContinue) return null;
665
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.View, { style: [s.bottomSection, { borderTopColor: borderColor }], children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
666
+ import_react_native2.TouchableOpacity,
667
+ {
668
+ style: [s.primaryButton, { backgroundColor: acceptBg }],
669
+ onPress: onContinue,
670
+ activeOpacity: 0.8,
671
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.Text, { style: [s.primaryButtonText, { color: acceptText }], children: "Continue" })
672
+ }
673
+ ) });
674
+ }
675
+ if (status === "failed" || status === "expired") {
676
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native2.View, { style: [s.bottomSection, { borderTopColor: borderColor }], children: [
677
+ errorCode === "GUARDIAN_UNDER_18" && onChangeGuardian ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
678
+ import_react_native2.TouchableOpacity,
679
+ {
680
+ style: [s.primaryButton, { backgroundColor: acceptBg }],
681
+ onPress: onChangeGuardian,
682
+ activeOpacity: 0.8,
683
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.Text, { style: [s.primaryButtonText, { color: acceptText }], children: "Change Guardian" })
684
+ }
685
+ ) : canRetry !== false ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
686
+ import_react_native2.TouchableOpacity,
687
+ {
688
+ style: [s.primaryButton, { backgroundColor: acceptBg }],
689
+ onPress: onRetry,
690
+ activeOpacity: 0.8,
691
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.Text, { style: [s.primaryButtonText, { color: acceptText }], children: "Try Again" })
692
+ }
693
+ ) : null,
694
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
695
+ import_react_native2.TouchableOpacity,
696
+ {
697
+ style: [s.outlineButton, { backgroundColor: declineBg, borderColor }],
698
+ onPress: onBack,
699
+ activeOpacity: 0.8,
700
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.Text, { style: [s.outlineButtonText, { color: declineText }], children: "Go Back" })
701
+ }
702
+ )
703
+ ] });
704
+ }
705
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.View, { style: [s.bottomSection, { borderTopColor: borderColor }], children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
706
+ import_react_native2.TouchableOpacity,
707
+ {
708
+ style: [s.outlineButton, { backgroundColor: declineBg, borderColor }],
709
+ onPress: onBack,
710
+ activeOpacity: 0.8,
711
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.Text, { style: [s.outlineButtonText, { color: declineText }], children: "Cancel" })
712
+ }
713
+ ) });
714
+ };
715
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native2.View, { style: s.root, children: [
716
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.View, { style: [s.topSection, { borderBottomColor: borderColor }], children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.Text, { style: [s.topTitle, { color: headingColor }], children: "Guardian Verification" }) }),
717
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native2.View, { style: s.centerArea, children: status === "verified" ? renderSuccessContent() : status === "failed" || status === "expired" ? renderErrorContent() : renderPendingContent() }),
718
+ renderBottomButtons()
719
+ ] });
720
+ };
721
+ var s = import_react_native2.StyleSheet.create({
722
+ root: {
723
+ flex: 1
724
+ },
725
+ // -- Top --
726
+ topSection: {
727
+ flexDirection: "row",
728
+ alignItems: "center",
729
+ paddingHorizontal: 20,
730
+ paddingVertical: 16,
731
+ borderBottomWidth: import_react_native2.StyleSheet.hairlineWidth,
732
+ borderBottomColor: "#E5E7EB"
733
+ },
734
+ topTitle: {
735
+ fontSize: 18,
736
+ fontWeight: "700"
737
+ },
738
+ // -- Center --
739
+ centerArea: {
740
+ flex: 1,
741
+ justifyContent: "center",
742
+ alignItems: "center",
743
+ paddingHorizontal: 24
744
+ },
745
+ centerContent: {
746
+ alignItems: "center",
747
+ width: "100%",
748
+ maxWidth: 320
749
+ },
750
+ // -- Icon wrappers --
751
+ iconWrapper: {
752
+ width: 88,
753
+ height: 88,
754
+ alignItems: "center",
755
+ justifyContent: "center",
756
+ marginBottom: 20
757
+ },
758
+ pulseRing: {
759
+ position: "absolute",
760
+ width: 88,
761
+ height: 88,
762
+ borderRadius: 44,
763
+ borderWidth: 3,
764
+ borderColor: "#D1FAE5"
765
+ },
766
+ successCircle: {
767
+ width: 72,
768
+ height: 72,
769
+ borderRadius: 36,
770
+ backgroundColor: "#D1FAE5",
771
+ alignItems: "center",
772
+ justifyContent: "center"
773
+ },
774
+ errorCircle: {
775
+ width: 72,
776
+ height: 72,
777
+ borderRadius: 36,
778
+ backgroundColor: "#FEE2E2",
779
+ alignItems: "center",
780
+ justifyContent: "center"
781
+ },
782
+ // -- Text --
783
+ statusTitle: {
784
+ fontSize: 20,
785
+ fontWeight: "700",
786
+ textAlign: "center",
787
+ marginBottom: 8
788
+ },
789
+ statusSubtext: {
790
+ fontSize: 14,
791
+ textAlign: "center",
792
+ lineHeight: 20
793
+ },
794
+ // -- Pending --
795
+ pendingSpinner: {
796
+ marginBottom: 20
797
+ },
798
+ // -- Info banner (pending) --
799
+ infoBanner: {
800
+ flexDirection: "row",
801
+ alignItems: "flex-start",
802
+ backgroundColor: "#D1FAE5",
803
+ borderRadius: 8,
804
+ padding: 12,
805
+ width: "100%"
806
+ },
807
+ infoBannerIcon: {
808
+ marginRight: 8,
809
+ marginTop: 1
810
+ },
811
+ infoBannerText: {
812
+ flex: 1,
813
+ fontSize: 13,
814
+ color: "#059669",
815
+ lineHeight: 18
816
+ },
817
+ // -- Error banner --
818
+ errorBanner: {
819
+ flexDirection: "row",
820
+ alignItems: "flex-start",
821
+ backgroundColor: "#FEF2F2",
822
+ borderRadius: 8,
823
+ borderWidth: 1,
824
+ borderColor: "#FCA5A5",
825
+ padding: 12,
826
+ width: "100%",
827
+ marginTop: 4
828
+ },
829
+ errorBannerText: {
830
+ flex: 1,
831
+ fontSize: 13,
832
+ color: "#DC2626",
833
+ lineHeight: 18
834
+ },
835
+ // -- Bottom buttons --
836
+ bottomSection: {
837
+ padding: 20,
838
+ gap: 8,
839
+ borderTopWidth: import_react_native2.StyleSheet.hairlineWidth,
840
+ borderTopColor: "#E5E7EB"
841
+ },
842
+ primaryButton: {
843
+ borderRadius: 12,
844
+ paddingVertical: 14,
845
+ alignItems: "center"
846
+ },
847
+ primaryButtonText: {
848
+ fontSize: 16,
849
+ fontWeight: "600"
850
+ },
851
+ outlineButton: {
852
+ borderWidth: 1,
853
+ borderRadius: 12,
854
+ paddingVertical: 14,
855
+ alignItems: "center"
856
+ },
857
+ outlineButtonText: {
858
+ fontSize: 16,
859
+ fontWeight: "600"
860
+ }
861
+ });
862
+
863
+ // src/RedactoNoticeConsent/constants.ts
864
+ var DPO_AUDIO_ELEMENT_MAP = [
865
+ { audioKey: "grievance_text_audio_url", elementId: "dpo-grievance-text" },
866
+ { audioKey: "grievance_anchor_text_audio_url", elementId: "dpo-grievance-link" },
867
+ { audioKey: "grievance_email_connector_text_audio_url", elementId: "dpo-grievance-email-connector" },
868
+ { audioKey: "grievance_email_audio_url", elementId: "dpo-grievance-email" },
869
+ { audioKey: "dp_board_text_audio_url", elementId: "dpo-dp-board-text" },
870
+ { audioKey: "dp_board_anchor_text_audio_url", elementId: "dpo-dp-board-link" },
871
+ { audioKey: "dpo_text_audio_url", elementId: "dpo-dpo-text" },
872
+ { audioKey: "dpo_anchor_text_audio_url", elementId: "dpo-dpo-link" }
873
+ ];
874
+
875
+ // src/RedactoNoticeConsent/styles.ts
876
+ var import_react_native3 = require("react-native");
877
+ var styles2 = import_react_native3.StyleSheet.create({
417
878
  overlay: {
418
879
  flex: 1,
419
880
  backgroundColor: "rgba(0, 0, 0, 0.5)",
@@ -427,7 +888,7 @@ var styles2 = import_react_native2.StyleSheet.create({
427
888
  height: "90%",
428
889
  borderRadius: 8,
429
890
  backgroundColor: "#ffffff",
430
- ...import_react_native2.Platform.select({
891
+ ...import_react_native3.Platform.select({
431
892
  ios: {
432
893
  shadowColor: "#000",
433
894
  shadowOffset: { width: 0, height: 2 },
@@ -442,7 +903,9 @@ var styles2 = import_react_native2.StyleSheet.create({
442
903
  minHeight: 320
443
904
  },
444
905
  content: {
445
- padding: 22,
906
+ paddingHorizontal: 20,
907
+ paddingTop: 14,
908
+ paddingBottom: 0,
446
909
  flex: 1,
447
910
  minHeight: 0
448
911
  },
@@ -450,7 +913,7 @@ var styles2 = import_react_native2.StyleSheet.create({
450
913
  flexDirection: "row",
451
914
  justifyContent: "space-between",
452
915
  alignItems: "center",
453
- paddingBottom: 15,
916
+ paddingBottom: 12,
454
917
  backgroundColor: "#ffffff",
455
918
  flexShrink: 0
456
919
  },
@@ -470,13 +933,13 @@ var styles2 = import_react_native2.StyleSheet.create({
470
933
  fontWeight: "700",
471
934
  lineHeight: 27,
472
935
  letterSpacing: 0.2,
473
- color: "#101828",
936
+ color: "#323B4B",
474
937
  flexShrink: 1
475
938
  },
476
939
  topRight: {
477
- borderRadius: 8,
478
- paddingVertical: 3,
479
- paddingHorizontal: 9,
940
+ borderRadius: 6,
941
+ paddingVertical: 6,
942
+ paddingHorizontal: 10,
480
943
  borderWidth: 1,
481
944
  borderColor: "#d0d5dd",
482
945
  flexDirection: "row",
@@ -486,8 +949,8 @@ var styles2 = import_react_native2.StyleSheet.create({
486
949
  gap: 5
487
950
  },
488
951
  topRightText: {
489
- fontWeight: "400",
490
- fontSize: 12,
952
+ fontWeight: "500",
953
+ fontSize: 13,
491
954
  color: "#344054"
492
955
  },
493
956
  middleSection: {
@@ -503,14 +966,17 @@ var styles2 = import_react_native2.StyleSheet.create({
503
966
  },
504
967
  link: {
505
968
  color: "#4f87ff",
506
- textDecorationLine: "underline"
969
+ textDecorationLine: "none"
970
+ },
971
+ ttsHighlight: {
972
+ backgroundColor: "#FEF3C7"
507
973
  },
508
974
  subTitle: {
509
975
  fontWeight: "600",
510
976
  fontSize: 16,
511
977
  lineHeight: 24,
512
978
  letterSpacing: 0.2,
513
- color: "#101828"
979
+ color: "#323B4B"
514
980
  },
515
981
  optionsContainer: {
516
982
  gap: 10
@@ -522,7 +988,7 @@ var styles2 = import_react_native2.StyleSheet.create({
522
988
  },
523
989
  optionLeft: {
524
990
  flexDirection: "row",
525
- gap: 12,
991
+ gap: 8,
526
992
  alignItems: "center",
527
993
  flex: 1
528
994
  },
@@ -534,7 +1000,7 @@ var styles2 = import_react_native2.StyleSheet.create({
534
1000
  fontSize: 16,
535
1001
  lineHeight: 24,
536
1002
  letterSpacing: 0.2,
537
- color: "#101828"
1003
+ color: "#323B4B"
538
1004
  },
539
1005
  optionDescription: {
540
1006
  fontWeight: "400",
@@ -544,7 +1010,7 @@ var styles2 = import_react_native2.StyleSheet.create({
544
1010
  color: "#475467"
545
1011
  },
546
1012
  dataElementsContainer: {
547
- paddingLeft: 22
1013
+ paddingLeft: 26
548
1014
  },
549
1015
  dataElementItem: {
550
1016
  flexDirection: "row",
@@ -563,17 +1029,16 @@ var styles2 = import_react_native2.StyleSheet.create({
563
1029
  flex: 1
564
1030
  },
565
1031
  bottomSection: {
566
- flexDirection: "row",
567
- justifyContent: "space-between",
568
- gap: 12,
1032
+ flexDirection: "column",
1033
+ gap: 10,
569
1034
  paddingTop: 15,
1035
+ paddingBottom: 16,
570
1036
  backgroundColor: "#ffffff",
571
1037
  flexShrink: 0
572
1038
  },
573
1039
  button: {
574
- flex: 1,
575
1040
  borderRadius: 8,
576
- paddingVertical: 12,
1041
+ paddingVertical: 9,
577
1042
  paddingHorizontal: 20,
578
1043
  alignItems: "center",
579
1044
  justifyContent: "center"
@@ -613,7 +1078,7 @@ var styles2 = import_react_native2.StyleSheet.create({
613
1078
  minWidth: 120,
614
1079
  maxHeight: 200,
615
1080
  marginTop: 4,
616
- ...import_react_native2.Platform.select({
1081
+ ...import_react_native3.Platform.select({
617
1082
  ios: {
618
1083
  shadowColor: "#000",
619
1084
  shadowOffset: { width: 0, height: 2 },
@@ -659,7 +1124,7 @@ var styles2 = import_react_native2.StyleSheet.create({
659
1124
  padding: 12,
660
1125
  marginBottom: 16,
661
1126
  borderWidth: 1,
662
- borderColor: "#FCA5A5",
1127
+ borderColor: "#FECACA",
663
1128
  flexDirection: "row",
664
1129
  alignItems: "center",
665
1130
  justifyContent: "space-between"
@@ -689,7 +1154,7 @@ var styles2 = import_react_native2.StyleSheet.create({
689
1154
  textInput: {
690
1155
  borderWidth: 1,
691
1156
  borderColor: "#d0d5dd",
692
- borderRadius: 8,
1157
+ borderRadius: 6,
693
1158
  paddingVertical: 10,
694
1159
  paddingHorizontal: 12,
695
1160
  fontSize: 13,
@@ -725,7 +1190,7 @@ var styles2 = import_react_native2.StyleSheet.create({
725
1190
  width: 16,
726
1191
  height: 16,
727
1192
  borderRadius: 8,
728
- borderWidth: 2,
1193
+ borderWidth: 1.5,
729
1194
  borderColor: "#d0d5dd",
730
1195
  backgroundColor: "transparent"
731
1196
  },
@@ -737,9 +1202,9 @@ var styles2 = import_react_native2.StyleSheet.create({
737
1202
  });
738
1203
 
739
1204
  // src/RedactoNoticeConsent/useResponsive.ts
740
- var import_react_native3 = require("react-native");
1205
+ var import_react_native4 = require("react-native");
741
1206
  var useResponsive = () => {
742
- const { width, height } = (0, import_react_native3.useWindowDimensions)();
1207
+ const { width, height } = (0, import_react_native4.useWindowDimensions)();
743
1208
  return {
744
1209
  isMobile: width < 768,
745
1210
  width,
@@ -748,14 +1213,46 @@ var useResponsive = () => {
748
1213
  };
749
1214
 
750
1215
  // src/RedactoNoticeConsent/RedactoNoticeConsent.tsx
751
- var import_jsx_runtime2 = require("react/jsx-runtime");
1216
+ var import_jsx_runtime3 = require("react/jsx-runtime");
1217
+ function RemoteLogo({ uri }) {
1218
+ const isSvg = uri.toLowerCase().endsWith(".svg") || uri.toLowerCase().includes("image/svg");
1219
+ if (isSvg && import_react_native_svg3.SvgUri) {
1220
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native_svg3.SvgUri, { uri, width: 32, height: 32 });
1221
+ }
1222
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native5.Image, { style: styles2.logo, source: { uri } });
1223
+ }
752
1224
  function stripHtml(html) {
753
1225
  return html.replace(/<[^>]*>/g, "").replace(/&amp;/g, "&").replace(/&lt;/g, "<").replace(/&gt;/g, ">").replace(/&quot;/g, '"').replace(/&#39;/g, "'").replace(/&nbsp;/g, " ").trim();
754
1226
  }
755
- var expoAv = null;
756
- try {
757
- expoAv = require("expo-av");
758
- } catch {
1227
+ var expoAudioModule = null;
1228
+ var expoAudioModulePromise = null;
1229
+ async function getExpoAudioModuleAsync() {
1230
+ if (expoAudioModule) {
1231
+ return expoAudioModule;
1232
+ }
1233
+ if (expoAudioModulePromise) {
1234
+ return expoAudioModulePromise;
1235
+ }
1236
+ expoAudioModulePromise = (async () => {
1237
+ try {
1238
+ const moduleName = "expo-audio";
1239
+ const mod = await import(moduleName);
1240
+ const candidate = mod;
1241
+ if (typeof (candidate == null ? void 0 : candidate.createAudioPlayer) !== "function" || typeof (candidate == null ? void 0 : candidate.setAudioModeAsync) !== "function") {
1242
+ return null;
1243
+ }
1244
+ expoAudioModule = candidate;
1245
+ return candidate;
1246
+ } catch {
1247
+ return null;
1248
+ }
1249
+ })();
1250
+ const resolved = await expoAudioModulePromise;
1251
+ expoAudioModulePromise = null;
1252
+ return resolved;
1253
+ }
1254
+ function logTTS(stage, meta) {
1255
+ console.info("[RedactoConsentSDK][TTS]", stage, meta || {});
759
1256
  }
760
1257
  var PurposeItem = ({
761
1258
  purpose,
@@ -768,22 +1265,24 @@ var PurposeItem = ({
768
1265
  onDataElementToggle,
769
1266
  getTranslatedText,
770
1267
  isAlreadyConsented,
771
- initialDataElementSelections = {}
1268
+ initialDataElementSelections = {},
1269
+ accentColor: purposeAccentColor,
1270
+ activeTTSSegmentKey
772
1271
  }) => {
773
- const headingColor = (settings == null ? void 0 : settings.headingColor) || "#101828";
1272
+ const headingColor = (settings == null ? void 0 : settings.headingColor) || "#323B4B";
774
1273
  const textColor = (settings == null ? void 0 : settings.textColor) || "#344054";
775
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native4.View, { children: [
776
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native4.View, { style: styles2.optionItem, children: [
777
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
778
- import_react_native4.TouchableOpacity,
1274
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native5.View, { children: [
1275
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native5.View, { style: styles2.optionItem, children: [
1276
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
1277
+ import_react_native5.TouchableOpacity,
779
1278
  {
780
1279
  style: styles2.optionLeft,
781
1280
  onPress: () => onPurposeCollapse(purpose.uuid),
782
1281
  accessibilityRole: "button",
783
1282
  accessibilityLabel: `${collapsedPurposes[purpose.uuid] ? "Expand" : "Collapse"} ${getTranslatedText("purposes.name", purpose.name, purpose.uuid)} details`,
784
1283
  children: [
785
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.View, { style: styles2.purposeChevron, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native_svg2.default, { width: 7, height: 12, viewBox: "0 0 7 12", fill: "none", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
786
- import_react_native_svg2.Path,
1284
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native5.View, { style: styles2.purposeChevron, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native_svg3.default, { width: 7, height: 12, viewBox: "0 0 7 12", fill: "none", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1285
+ import_react_native_svg3.Path,
787
1286
  {
788
1287
  d: "M1 1L6 6L1 11",
789
1288
  stroke: (settings == null ? void 0 : settings.headingColor) || "#323B4B",
@@ -793,24 +1292,45 @@ var PurposeItem = ({
793
1292
  transform: !collapsedPurposes[purpose.uuid] ? "rotate(90 3.5 6)" : void 0
794
1293
  }
795
1294
  ) }) }),
796
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native4.View, { style: styles2.optionTextContainer, children: [
797
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.Text, { style: [styles2.optionTitle, { color: headingColor }], children: getTranslatedText("purposes.name", purpose.name, purpose.uuid) }),
798
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.Text, { style: [styles2.optionDescription, { color: textColor }], children: getTranslatedText("purposes.description", purpose.description, purpose.uuid) })
1295
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native5.View, { style: styles2.optionTextContainer, children: [
1296
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1297
+ import_react_native5.Text,
1298
+ {
1299
+ style: [
1300
+ styles2.optionTitle,
1301
+ { color: headingColor },
1302
+ activeTTSSegmentKey === `purpose_name_${purpose.uuid}` ? styles2.ttsHighlight : null
1303
+ ],
1304
+ children: getTranslatedText("purposes.name", purpose.name, purpose.uuid)
1305
+ }
1306
+ ),
1307
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1308
+ import_react_native5.Text,
1309
+ {
1310
+ style: [
1311
+ styles2.optionDescription,
1312
+ { color: textColor },
1313
+ activeTTSSegmentKey === `purpose_desc_${purpose.uuid}` ? styles2.ttsHighlight : null
1314
+ ],
1315
+ children: getTranslatedText("purposes.description", purpose.description, purpose.uuid)
1316
+ }
1317
+ )
799
1318
  ] })
800
1319
  ]
801
1320
  }
802
1321
  ),
803
- !isAlreadyConsented && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1322
+ !isAlreadyConsented && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
804
1323
  Checkbox,
805
1324
  {
806
1325
  checked: selectedPurposes[purpose.uuid] || false,
807
1326
  onChange: () => onPurposeToggle(purpose.uuid),
808
1327
  size: "large",
1328
+ accentColor: purposeAccentColor,
809
1329
  accessibilityLabel: `Select all data elements for ${getTranslatedText("purposes.name", purpose.name, purpose.uuid)}`
810
1330
  }
811
1331
  ),
812
- isAlreadyConsented && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.View, { style: styles2.consentedCheckmark, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native_svg2.default, { width: 12, height: 12, viewBox: "0 0 12 12", fill: "none", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
813
- import_react_native_svg2.Path,
1332
+ isAlreadyConsented && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native5.View, { style: styles2.consentedCheckmark, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native_svg3.default, { width: 12, height: 12, viewBox: "0 0 12 12", fill: "none", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1333
+ import_react_native_svg3.Path,
814
1334
  {
815
1335
  d: "M4 6L5.5 7.5L8.5 4.5",
816
1336
  stroke: "white",
@@ -820,24 +1340,35 @@ var PurposeItem = ({
820
1340
  }
821
1341
  ) }) })
822
1342
  ] }),
823
- !collapsedPurposes[purpose.uuid] && purpose.data_elements && purpose.data_elements.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.View, { style: styles2.dataElementsContainer, children: purpose.data_elements.map((dataElement) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native4.View, { style: styles2.dataElementItem, children: [
824
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native4.Text, { style: [styles2.dataElementText, { color: textColor }], children: [
825
- getTranslatedText("data_elements.name", dataElement.name, dataElement.uuid),
826
- dataElement.required && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.Text, { style: styles2.requiredAsterisk, children: " *" })
827
- ] }),
828
- !isAlreadyConsented && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1343
+ !collapsedPurposes[purpose.uuid] && purpose.data_elements && purpose.data_elements.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native5.View, { style: styles2.dataElementsContainer, children: purpose.data_elements.map((dataElement) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native5.View, { style: styles2.dataElementItem, children: [
1344
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
1345
+ import_react_native5.Text,
1346
+ {
1347
+ style: [
1348
+ styles2.dataElementText,
1349
+ { color: textColor },
1350
+ activeTTSSegmentKey === `element_${dataElement.uuid}` ? styles2.ttsHighlight : null
1351
+ ],
1352
+ children: [
1353
+ getTranslatedText("data_elements.name", dataElement.name, dataElement.uuid),
1354
+ dataElement.required && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native5.Text, { style: styles2.requiredAsterisk, children: " *" })
1355
+ ]
1356
+ }
1357
+ ),
1358
+ !isAlreadyConsented && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
829
1359
  Checkbox,
830
1360
  {
831
1361
  checked: selectedDataElements[`${purpose.uuid}-${dataElement.uuid}`] || false,
832
1362
  onChange: () => onDataElementToggle(dataElement.uuid, purpose.uuid),
833
1363
  size: "small",
1364
+ accentColor: purposeAccentColor,
834
1365
  accessibilityLabel: `Select ${getTranslatedText("data_elements.name", dataElement.name, dataElement.uuid)}${dataElement.required ? " (required)" : ""}`
835
1366
  }
836
1367
  ),
837
1368
  isAlreadyConsented && (() => {
838
1369
  const wasSelected = initialDataElementSelections[`${purpose.uuid}-${dataElement.uuid}`] || false;
839
- return wasSelected ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.View, { style: styles2.consentedCheckmarkSmall, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native_svg2.default, { width: 10, height: 10, viewBox: "0 0 10 10", fill: "none", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
840
- import_react_native_svg2.Path,
1370
+ return wasSelected ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native5.View, { style: styles2.consentedCheckmarkSmall, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native_svg3.default, { width: 10, height: 10, viewBox: "0 0 10 10", fill: "none", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1371
+ import_react_native_svg3.Path,
841
1372
  {
842
1373
  d: "M3 5L4.5 6.5L7.5 3.5",
843
1374
  stroke: "white",
@@ -845,27 +1376,34 @@ var PurposeItem = ({
845
1376
  strokeLinecap: "round",
846
1377
  strokeLinejoin: "round"
847
1378
  }
848
- ) }) }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.View, { style: styles2.notConsentedCircle });
1379
+ ) }) }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native5.View, { style: styles2.notConsentedCircle });
849
1380
  })()
850
1381
  ] }, dataElement.uuid)) })
851
1382
  ] });
852
1383
  };
1384
+ var RELATIONSHIP_OPTIONS = ["Father", "Mother", "Legal Guardian", "Grandparent"];
853
1385
  var GuardianForm = ({ formData, errors, isSubmitting, onChange, onNext, onDecline, settings, logoUrl }) => {
854
- var _a, _b, _c, _d;
1386
+ var _a, _b, _c, _d, _e, _f;
855
1387
  const borderColor = (settings == null ? void 0 : settings.borderColor) || "#d0d5dd";
856
1388
  const textColor = (settings == null ? void 0 : settings.textColor) || "#344054";
857
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
858
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.View, { style: styles2.topSection, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native4.View, { style: styles2.topLeft, children: [
859
- logoUrl ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.Image, { style: styles2.logo, source: { uri: logoUrl } }) : null,
860
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.Text, { style: [styles2.title, { color: (settings == null ? void 0 : settings.headingColor) || "#101828" }], children: "Guardian Information Required" })
1389
+ const [showRelationshipDropdown, setShowRelationshipDropdown] = (0, import_react2.useState)(false);
1390
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
1391
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native5.View, { style: styles2.topSection, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native5.View, { style: styles2.topLeft, children: [
1392
+ logoUrl ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(RemoteLogo, { uri: logoUrl, style: { height: 32, width: 80 } }) : null,
1393
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native5.Text, { style: [styles2.title, { color: (settings == null ? void 0 : settings.headingColor) || "#323B4B" }], children: "Guardian Verification" })
861
1394
  ] }) }),
862
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native4.ScrollView, { style: styles2.middleSection, showsVerticalScrollIndicator: false, children: [
863
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.Text, { style: [styles2.privacyText, { color: textColor, fontSize: 14, lineHeight: 20 }], children: "As you are under the age of consent, we need to collect information about your legal guardian to proceed." }),
864
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native4.View, { style: { marginTop: 16, gap: 12 }, children: [
865
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native4.View, { style: styles2.inputContainer, children: [
866
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.Text, { style: [styles2.inputLabel, { color: textColor }], children: "Name of Guardian *" }),
867
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
868
- import_react_native4.TextInput,
1395
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native5.View, { style: styles2.divider }),
1396
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native5.ScrollView, { style: styles2.middleSection, showsVerticalScrollIndicator: false, children: [
1397
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native5.Text, { style: [styles2.privacyText, { color: textColor, fontSize: 13, lineHeight: 20 }], children: "Since you are under the age of consent, a legal guardian must verify their identity via DigiLocker before consent can be provided on your behalf." }),
1398
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native5.View, { style: guardianStyles.infoBanner, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native5.Text, { style: guardianStyles.infoBannerText, children: "Please ensure the name and phone number entered below match the guardian's official Aadhaar-linked records for successful verification." }) }),
1399
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native5.View, { style: { marginTop: 16, gap: 12 }, children: [
1400
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native5.View, { style: styles2.inputContainer, children: [
1401
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native5.Text, { style: [styles2.inputLabel, { color: textColor }], children: [
1402
+ "Guardian's Full Name ",
1403
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native5.Text, { style: { color: "red" }, children: "*" })
1404
+ ] }),
1405
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1406
+ import_react_native5.TextInput,
869
1407
  {
870
1408
  value: formData.guardianName,
871
1409
  onChangeText: (v) => onChange("guardianName", v),
@@ -873,16 +1411,19 @@ var GuardianForm = ({ formData, errors, isSubmitting, onChange, onNext, onDeclin
873
1411
  styles2.textInput,
874
1412
  { borderColor: errors.guardianName ? "#DC2626" : borderColor, color: textColor }
875
1413
  ],
876
- placeholder: "Enter guardian's full name",
1414
+ placeholder: "e.g. Rajesh Kumar",
877
1415
  placeholderTextColor: "#9CA3AF"
878
1416
  }
879
1417
  ),
880
- errors.guardianName ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.Text, { style: styles2.inputError, children: errors.guardianName }) : null
1418
+ errors.guardianName ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native5.Text, { style: styles2.inputError, children: errors.guardianName }) : null
881
1419
  ] }),
882
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native4.View, { style: styles2.inputContainer, children: [
883
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.Text, { style: [styles2.inputLabel, { color: textColor }], children: "Contact of Guardian *" }),
884
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
885
- import_react_native4.TextInput,
1420
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native5.View, { style: styles2.inputContainer, children: [
1421
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native5.Text, { style: [styles2.inputLabel, { color: textColor }], children: [
1422
+ "Guardian's Phone Number ",
1423
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native5.Text, { style: { color: "red" }, children: "*" })
1424
+ ] }),
1425
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1426
+ import_react_native5.TextInput,
886
1427
  {
887
1428
  value: formData.guardianContact,
888
1429
  onChangeText: (v) => onChange("guardianContact", v),
@@ -890,37 +1431,72 @@ var GuardianForm = ({ formData, errors, isSubmitting, onChange, onNext, onDeclin
890
1431
  styles2.textInput,
891
1432
  { borderColor: errors.guardianContact ? "#DC2626" : borderColor, color: textColor }
892
1433
  ],
893
- placeholder: "Enter guardian's email or phone number",
1434
+ placeholder: "e.g. 9876543210",
894
1435
  placeholderTextColor: "#9CA3AF",
895
- keyboardType: "email-address",
896
- autoCapitalize: "none"
1436
+ keyboardType: "phone-pad"
897
1437
  }
898
1438
  ),
899
- errors.guardianContact ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.Text, { style: styles2.inputError, children: errors.guardianContact }) : null
1439
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native5.Text, { style: { fontSize: 11, color: "#667085", marginTop: 4 }, children: "Mobile number linked to guardian's Aadhaar" }),
1440
+ errors.guardianContact ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native5.Text, { style: styles2.inputError, children: errors.guardianContact }) : null
900
1441
  ] }),
901
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native4.View, { style: styles2.inputContainer, children: [
902
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.Text, { style: [styles2.inputLabel, { color: textColor }], children: "Relationship to Guardian *" }),
903
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
904
- import_react_native4.TextInput,
905
- {
906
- value: formData.guardianRelationship,
907
- onChangeText: (v) => onChange("guardianRelationship", v),
908
- style: [
909
- styles2.textInput,
910
- { borderColor: errors.guardianRelationship ? "#DC2626" : borderColor, color: textColor }
911
- ],
912
- placeholder: "e.g., Parent, Legal Guardian, etc.",
913
- placeholderTextColor: "#9CA3AF"
914
- }
915
- ),
916
- errors.guardianRelationship ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.Text, { style: styles2.inputError, children: errors.guardianRelationship }) : null
1442
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native5.View, { style: styles2.inputContainer, children: [
1443
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native5.Text, { style: [styles2.inputLabel, { color: textColor }], children: [
1444
+ "Relationship ",
1445
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native5.Text, { style: { color: "red" }, children: "*" })
1446
+ ] }),
1447
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native5.View, { style: { position: "relative" }, children: [
1448
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
1449
+ import_react_native5.TouchableOpacity,
1450
+ {
1451
+ style: [
1452
+ styles2.textInput,
1453
+ {
1454
+ borderColor: errors.guardianRelationship ? "#DC2626" : borderColor,
1455
+ flexDirection: "row",
1456
+ alignItems: "center",
1457
+ justifyContent: "space-between"
1458
+ }
1459
+ ],
1460
+ onPress: () => setShowRelationshipDropdown((v) => !v),
1461
+ children: [
1462
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native5.Text, { style: { color: formData.guardianRelationship ? textColor : "#9CA3AF", fontSize: 13 }, children: formData.guardianRelationship || "Select relationship" }),
1463
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native_svg3.default, { width: 12, height: 12, viewBox: "0 0 16 16", fill: "none", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1464
+ import_react_native_svg3.Path,
1465
+ {
1466
+ d: "M4 6L8 10L12 6",
1467
+ stroke: textColor,
1468
+ strokeWidth: 2,
1469
+ strokeLinecap: "round",
1470
+ strokeLinejoin: "round"
1471
+ }
1472
+ ) })
1473
+ ]
1474
+ }
1475
+ ),
1476
+ showRelationshipDropdown && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native5.View, { style: guardianStyles.relationshipDropdown, children: RELATIONSHIP_OPTIONS.map((option) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1477
+ import_react_native5.TouchableOpacity,
1478
+ {
1479
+ style: [
1480
+ guardianStyles.relationshipItem,
1481
+ formData.guardianRelationship === option ? guardianStyles.relationshipItemSelected : null
1482
+ ],
1483
+ onPress: () => {
1484
+ onChange("guardianRelationship", option);
1485
+ setShowRelationshipDropdown(false);
1486
+ },
1487
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native5.Text, { style: [guardianStyles.relationshipItemText, { color: textColor }], children: option })
1488
+ },
1489
+ option
1490
+ )) })
1491
+ ] }),
1492
+ errors.guardianRelationship ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native5.Text, { style: styles2.inputError, children: errors.guardianRelationship }) : null
917
1493
  ] }),
918
- errors.general ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.View, { style: styles2.errorContainer, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.Text, { style: styles2.errorText, children: errors.general }) }) : null
1494
+ errors.general ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native5.View, { style: styles2.errorContainer, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native5.Text, { style: styles2.errorText, children: errors.general }) }) : null
919
1495
  ] })
920
1496
  ] }),
921
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native4.View, { style: styles2.bottomSection, children: [
922
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
923
- import_react_native4.TouchableOpacity,
1497
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native5.View, { style: styles2.bottomSection, children: [
1498
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1499
+ import_react_native5.TouchableOpacity,
924
1500
  {
925
1501
  style: [
926
1502
  styles2.button,
@@ -930,47 +1506,95 @@ var GuardianForm = ({ formData, errors, isSubmitting, onChange, onNext, onDeclin
930
1506
  onPress: onNext,
931
1507
  disabled: isSubmitting,
932
1508
  accessibilityLabel: "Submit guardian information and proceed",
933
- children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.Text, { style: [
1509
+ children: isSubmitting ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native5.ActivityIndicator, { size: "small", color: ((_c = (_b = settings == null ? void 0 : settings.button) == null ? void 0 : _b.accept) == null ? void 0 : _c.textColor) || "#ffffff" }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native5.Text, { style: [
934
1510
  styles2.buttonText,
935
1511
  styles2.acceptButtonText,
936
- ((_b = settings == null ? void 0 : settings.button) == null ? void 0 : _b.accept) ? { color: settings.button.accept.textColor } : null
937
- ], children: isSubmitting ? "Submitting..." : "Next" })
1512
+ ((_d = settings == null ? void 0 : settings.button) == null ? void 0 : _d.accept) ? { color: settings.button.accept.textColor } : null
1513
+ ], children: "Verify via DigiLocker" })
938
1514
  }
939
1515
  ),
940
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
941
- import_react_native4.TouchableOpacity,
1516
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1517
+ import_react_native5.TouchableOpacity,
942
1518
  {
943
1519
  style: [
944
1520
  styles2.button,
945
1521
  styles2.cancelButton,
946
- ((_c = settings == null ? void 0 : settings.button) == null ? void 0 : _c.decline) ? { backgroundColor: settings.button.decline.backgroundColor, borderColor: settings.button.decline.backgroundColor } : null
1522
+ ((_e = settings == null ? void 0 : settings.button) == null ? void 0 : _e.decline) ? {
1523
+ backgroundColor: settings.button.decline.backgroundColor,
1524
+ borderColor: (settings == null ? void 0 : settings.borderColor) || "#d0d5dd"
1525
+ } : null
947
1526
  ],
948
1527
  onPress: onDecline,
1528
+ disabled: isSubmitting,
949
1529
  accessibilityLabel: "Cancel guardian information form",
950
- children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.Text, { style: [
1530
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native5.Text, { style: [
951
1531
  styles2.buttonText,
952
1532
  styles2.cancelButtonText,
953
- ((_d = settings == null ? void 0 : settings.button) == null ? void 0 : _d.decline) ? { color: settings.button.decline.textColor } : null
1533
+ ((_f = settings == null ? void 0 : settings.button) == null ? void 0 : _f.decline) ? { color: settings.button.decline.textColor } : null
954
1534
  ], children: "Cancel" })
955
1535
  }
956
1536
  )
957
1537
  ] })
958
1538
  ] });
959
1539
  };
960
- var AgeVerification = ({ onYes, onNo, settings, logoUrl }) => {
1540
+ var guardianStyles = import_react_native5.StyleSheet.create({
1541
+ infoBanner: {
1542
+ backgroundColor: "#EFF6FF",
1543
+ borderWidth: 1,
1544
+ borderColor: "#BFDBFE",
1545
+ borderRadius: 8,
1546
+ padding: 12,
1547
+ marginTop: 12
1548
+ },
1549
+ infoBannerText: {
1550
+ fontSize: 12,
1551
+ color: "#1D4ED8",
1552
+ lineHeight: 18
1553
+ },
1554
+ relationshipDropdown: {
1555
+ position: "absolute",
1556
+ top: "100%",
1557
+ left: 0,
1558
+ right: 0,
1559
+ backgroundColor: "#ffffff",
1560
+ borderWidth: 1,
1561
+ borderColor: "#d0d5dd",
1562
+ borderRadius: 8,
1563
+ zIndex: 10,
1564
+ marginTop: 4,
1565
+ overflow: "hidden"
1566
+ },
1567
+ relationshipItem: {
1568
+ paddingVertical: 10,
1569
+ paddingHorizontal: 12,
1570
+ borderBottomWidth: 1,
1571
+ borderBottomColor: "#e5e7eb"
1572
+ },
1573
+ relationshipItemSelected: {
1574
+ backgroundColor: "#f3f4f6"
1575
+ },
1576
+ relationshipItemText: {
1577
+ fontSize: 13
1578
+ }
1579
+ });
1580
+ var AgeVerification = ({ onYes, onNo, onClose, settings, logoUrl }) => {
961
1581
  var _a, _b, _c, _d;
962
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
963
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.View, { style: styles2.topSection, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native4.View, { style: styles2.topLeft, children: [
964
- logoUrl ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.Image, { style: styles2.logo, source: { uri: logoUrl } }) : null,
965
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.Text, { style: [styles2.title, { color: (settings == null ? void 0 : settings.headingColor) || "#101828" }], children: "Age Verification" })
966
- ] }) }),
967
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native4.ScrollView, { style: styles2.middleSection, showsVerticalScrollIndicator: false, children: [
968
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.Text, { style: [styles2.privacyText, { color: (settings == null ? void 0 : settings.textColor) || "#344054" }], children: "To proceed, we need to verify your age." }),
969
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.Text, { style: [styles2.privacyText, { color: (settings == null ? void 0 : settings.textColor) || "#344054", marginTop: 12, fontWeight: "600" }], children: "Are you 18 years of age or older?" })
1582
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
1583
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native5.View, { style: styles2.topSection, children: [
1584
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native5.View, { style: styles2.topLeft, children: [
1585
+ logoUrl ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(RemoteLogo, { uri: logoUrl, style: { height: 32, width: 80 } }) : null,
1586
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native5.Text, { style: [styles2.title, { color: (settings == null ? void 0 : settings.headingColor) || "#323B4B" }], children: "Age Verification Required" })
1587
+ ] }),
1588
+ onClose ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native5.TouchableOpacity, { onPress: onClose, hitSlop: { top: 8, bottom: 8, left: 8, right: 8 }, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native_svg3.default, { width: 18, height: 18, viewBox: "0 0 24 24", fill: "none", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native_svg3.Path, { d: "M18 6L6 18M6 6l12 12", stroke: "#9CA3AF", strokeWidth: 2, strokeLinecap: "round", strokeLinejoin: "round" }) }) }) : null
970
1589
  ] }),
971
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native4.View, { style: styles2.bottomSection, children: [
972
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
973
- import_react_native4.TouchableOpacity,
1590
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native5.View, { style: styles2.divider }),
1591
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native5.ScrollView, { style: styles2.middleSection, showsVerticalScrollIndicator: false, children: [
1592
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native5.Text, { style: [styles2.privacyText, { color: (settings == null ? void 0 : settings.textColor) || "#344054" }], children: "To proceed with this consent form, we need to verify your age." }),
1593
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native5.Text, { style: [styles2.privacyText, { color: (settings == null ? void 0 : settings.textColor) || "#344054", marginTop: 12, fontWeight: "600" }], children: "Are you 18 years of age or older?" })
1594
+ ] }),
1595
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native5.View, { style: styles2.bottomSection, children: [
1596
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1597
+ import_react_native5.TouchableOpacity,
974
1598
  {
975
1599
  style: [
976
1600
  styles2.button,
@@ -979,28 +1603,31 @@ var AgeVerification = ({ onYes, onNo, settings, logoUrl }) => {
979
1603
  ],
980
1604
  onPress: onYes,
981
1605
  accessibilityLabel: "Yes, I am 18 or older",
982
- children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.Text, { style: [
1606
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native5.Text, { style: [
983
1607
  styles2.buttonText,
984
1608
  styles2.acceptButtonText,
985
1609
  ((_b = settings == null ? void 0 : settings.button) == null ? void 0 : _b.accept) ? { color: settings.button.accept.textColor } : null
986
- ], children: "Yes" })
1610
+ ], children: "Yes, I am 18 or older" })
987
1611
  }
988
1612
  ),
989
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
990
- import_react_native4.TouchableOpacity,
1613
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1614
+ import_react_native5.TouchableOpacity,
991
1615
  {
992
1616
  style: [
993
1617
  styles2.button,
994
1618
  styles2.cancelButton,
995
- ((_c = settings == null ? void 0 : settings.button) == null ? void 0 : _c.decline) ? { backgroundColor: settings.button.decline.backgroundColor, borderColor: settings.button.decline.backgroundColor } : null
1619
+ ((_c = settings == null ? void 0 : settings.button) == null ? void 0 : _c.decline) ? {
1620
+ backgroundColor: settings.button.decline.backgroundColor,
1621
+ borderColor: (settings == null ? void 0 : settings.borderColor) || "#d0d5dd"
1622
+ } : null
996
1623
  ],
997
1624
  onPress: onNo,
998
1625
  accessibilityLabel: "No, I am under 18",
999
- children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.Text, { style: [
1626
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native5.Text, { style: [
1000
1627
  styles2.buttonText,
1001
1628
  styles2.cancelButtonText,
1002
1629
  ((_d = settings == null ? void 0 : settings.button) == null ? void 0 : _d.decline) ? { color: settings.button.decline.textColor } : null
1003
- ], children: "No" })
1630
+ ], children: "No, I am under 18" })
1004
1631
  }
1005
1632
  )
1006
1633
  ] })
@@ -1022,37 +1649,54 @@ var RedactoNoticeConsent = ({
1022
1649
  includeFullyConsentedData = false,
1023
1650
  reviewModeButtonText
1024
1651
  }) => {
1025
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s;
1652
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u;
1026
1653
  const { isMobile } = useResponsive();
1027
- const [content, setContent] = (0, import_react.useState)(null);
1028
- const [isLoading, setIsLoading] = (0, import_react.useState)(true);
1029
- const [isSubmitting, setIsSubmitting] = (0, import_react.useState)(false);
1030
- const [selectedLanguage, setSelectedLanguage] = (0, import_react.useState)(language);
1031
- const [collapsedPurposes, setCollapsedPurposes] = (0, import_react.useState)({});
1032
- const [selectedPurposes, setSelectedPurposes] = (0, import_react.useState)({});
1033
- const [selectedDataElements, setSelectedDataElements] = (0, import_react.useState)({});
1034
- const [initialDataElementSelections, setInitialDataElementSelections] = (0, import_react.useState)({});
1035
- const [errorMessage, setErrorMessage] = (0, import_react.useState)(null);
1036
- const [isLanguageDropdownOpen, setIsLanguageDropdownOpen] = (0, import_react.useState)(false);
1037
- const [isVisible, setIsVisible] = (0, import_react.useState)(false);
1038
- const [isReconsentMode, setIsReconsentMode] = (0, import_react.useState)(false);
1039
- const [isReviewMode, setIsReviewMode] = (0, import_react.useState)(false);
1040
- const [showAgeVerification, setShowAgeVerification] = (0, import_react.useState)(false);
1041
- const [showGuardianForm, setShowGuardianForm] = (0, import_react.useState)(false);
1042
- const [isMinor, setIsMinor] = (0, import_react.useState)(false);
1043
- const [guardianFormData, setGuardianFormData] = (0, import_react.useState)({ guardianName: "", guardianContact: "", guardianRelationship: "" });
1044
- const [guardianFormErrors, setGuardianFormErrors] = (0, import_react.useState)({});
1045
- const [isSubmittingGuardian, setIsSubmittingGuardian] = (0, import_react.useState)(false);
1046
- const [isTTSAvailable, setIsTTSAvailable] = (0, import_react.useState)(false);
1047
- const [ttsAudioUrls, setTtsAudioUrls] = (0, import_react.useState)({});
1048
- const [isPlaying, setIsPlaying] = (0, import_react.useState)(false);
1049
- const [isPaused, setIsPaused] = (0, import_react.useState)(false);
1050
- const soundRef = (0, import_react.useRef)(null);
1051
- const ttsQueueRef = (0, import_react.useRef)([]);
1052
- const ttsIndexRef = (0, import_react.useRef)(0);
1053
- const abortControllerRef = (0, import_react.useRef)(null);
1054
- const hasBootstrappedLanguageRef = (0, import_react.useRef)(false);
1055
- const fetchContent = (0, import_react.useCallback)(async () => {
1654
+ const [content, setContent] = (0, import_react2.useState)(null);
1655
+ const [isLoading, setIsLoading] = (0, import_react2.useState)(true);
1656
+ const [isSubmitting, setIsSubmitting] = (0, import_react2.useState)(false);
1657
+ const [selectedLanguage, setSelectedLanguage] = (0, import_react2.useState)(
1658
+ language === "en" || language === "EN" ? "English" : language
1659
+ );
1660
+ const [collapsedPurposes, setCollapsedPurposes] = (0, import_react2.useState)({});
1661
+ const [selectedPurposes, setSelectedPurposes] = (0, import_react2.useState)({});
1662
+ const [selectedDataElements, setSelectedDataElements] = (0, import_react2.useState)({});
1663
+ const [initialDataElementSelections, setInitialDataElementSelections] = (0, import_react2.useState)({});
1664
+ const [errorMessage, setErrorMessage] = (0, import_react2.useState)(null);
1665
+ const [isLanguageDropdownOpen, setIsLanguageDropdownOpen] = (0, import_react2.useState)(false);
1666
+ const [isVisible, setIsVisible] = (0, import_react2.useState)(false);
1667
+ const [isReconsentMode, setIsReconsentMode] = (0, import_react2.useState)(false);
1668
+ const [isReviewMode, setIsReviewMode] = (0, import_react2.useState)(false);
1669
+ const [showAgeVerification, setShowAgeVerification] = (0, import_react2.useState)(false);
1670
+ const [showGuardianForm, setShowGuardianForm] = (0, import_react2.useState)(false);
1671
+ const [isMinor, setIsMinor] = (0, import_react2.useState)(false);
1672
+ const [selfDeclaredAdult, setSelfDeclaredAdult] = (0, import_react2.useState)(false);
1673
+ const [guardianFormData, setGuardianFormData] = (0, import_react2.useState)({ guardianName: "", guardianContact: "", guardianRelationship: "" });
1674
+ const [guardianFormErrors, setGuardianFormErrors] = (0, import_react2.useState)({});
1675
+ const [isSubmittingGuardian, setIsSubmittingGuardian] = (0, import_react2.useState)(false);
1676
+ const [showVerificationScreen, setShowVerificationScreen] = (0, import_react2.useState)(false);
1677
+ const [verificationStatus, setVerificationStatus] = (0, import_react2.useState)("pending");
1678
+ const [verificationError, setVerificationError] = (0, import_react2.useState)();
1679
+ const [verificationErrorCode, setVerificationErrorCode] = (0, import_react2.useState)();
1680
+ const [canRetryVerification, setCanRetryVerification] = (0, import_react2.useState)(true);
1681
+ const verificationReferenceRef = (0, import_react2.useRef)(null);
1682
+ const verificationSessionTokenRef = (0, import_react2.useRef)(null);
1683
+ const pollingTimerRef = (0, import_react2.useRef)(null);
1684
+ const pollingCountRef = (0, import_react2.useRef)(0);
1685
+ const isAppActiveRef = (0, import_react2.useRef)(true);
1686
+ const [isTTSAvailable, setIsTTSAvailable] = (0, import_react2.useState)(false);
1687
+ const [ttsAudioUrls, setTtsAudioUrls] = (0, import_react2.useState)({});
1688
+ const [isPlaying, setIsPlaying] = (0, import_react2.useState)(false);
1689
+ const [isPaused, setIsPaused] = (0, import_react2.useState)(false);
1690
+ const [activeTTSSegmentKey, setActiveTTSSegmentKey] = (0, import_react2.useState)(null);
1691
+ const playerRef = (0, import_react2.useRef)(null);
1692
+ const playbackSubscriptionRef = (0, import_react2.useRef)(null);
1693
+ const playbackPollerRef = (0, import_react2.useRef)(null);
1694
+ const ttsQueueRef = (0, import_react2.useRef)([]);
1695
+ const ttsIndexRef = (0, import_react2.useRef)(0);
1696
+ const isAudioModeConfiguredRef = (0, import_react2.useRef)(false);
1697
+ const abortControllerRef = (0, import_react2.useRef)(null);
1698
+ const hasBootstrappedLanguageRef = (0, import_react2.useRef)(false);
1699
+ const fetchContent = (0, import_react2.useCallback)(async () => {
1056
1700
  if (abortControllerRef.current) {
1057
1701
  abortControllerRef.current.abort();
1058
1702
  }
@@ -1064,7 +1708,7 @@ var RedactoNoticeConsent = ({
1064
1708
  noticeId,
1065
1709
  accessToken,
1066
1710
  baseUrl,
1067
- language: selectedLanguage,
1711
+ language: "English",
1068
1712
  validate_against: validateAgainst,
1069
1713
  include_fully_consented_data: includeFullyConsentedData,
1070
1714
  specific_uuid: applicationId,
@@ -1098,12 +1742,23 @@ var RedactoNoticeConsent = ({
1098
1742
  setInitialDataElementSelections(initialDataElementSelectionsMap);
1099
1743
  if (!hasBootstrappedLanguageRef.current) {
1100
1744
  hasBootstrappedLanguageRef.current = true;
1101
- if (activeConfig2.default_language && activeConfig2.default_language !== selectedLanguage) {
1102
- setSelectedLanguage(activeConfig2.default_language);
1745
+ const defaultLang = activeConfig2.default_language;
1746
+ const mappedDefault = defaultLang === "en" || defaultLang === "EN" ? "English" : defaultLang;
1747
+ if (mappedDefault && mappedDefault !== selectedLanguage) {
1748
+ setSelectedLanguage(mappedDefault);
1103
1749
  }
1104
1750
  }
1105
1751
  setContent(data);
1106
1752
  setIsReconsentMode(reconsentRequired);
1753
+ if (includeFullyConsentedData && purposeSelections) {
1754
+ const allFullyConsented = activeConfig2.purposes.every((p) => {
1755
+ const sel = purposeSelections[p.uuid];
1756
+ return (sel == null ? void 0 : sel.selected) && !(sel == null ? void 0 : sel.needs_reconsent);
1757
+ });
1758
+ if (allFullyConsented) {
1759
+ setIsReviewMode(true);
1760
+ }
1761
+ }
1107
1762
  if (noticeIsMinor) {
1108
1763
  setShowAgeVerification(true);
1109
1764
  }
@@ -1124,19 +1779,23 @@ var RedactoNoticeConsent = ({
1124
1779
  } finally {
1125
1780
  setIsLoading(false);
1126
1781
  }
1127
- }, [noticeId, accessToken, baseUrl, selectedLanguage, validateAgainst, includeFullyConsentedData, applicationId, onAccept, onError]);
1128
- (0, import_react.useEffect)(() => {
1782
+ }, [noticeId, accessToken, baseUrl, validateAgainst, includeFullyConsentedData, applicationId, onAccept, onError]);
1783
+ (0, import_react2.useEffect)(() => {
1129
1784
  hasBootstrappedLanguageRef.current = false;
1130
1785
  }, [noticeId, accessToken]);
1131
- (0, import_react.useEffect)(() => {
1786
+ (0, import_react2.useEffect)(() => {
1132
1787
  fetchContent();
1133
1788
  return () => {
1134
1789
  var _a2;
1135
1790
  (_a2 = abortControllerRef.current) == null ? void 0 : _a2.abort();
1136
1791
  };
1137
1792
  }, [fetchContent]);
1138
- const fetchTTS = (0, import_react.useCallback)(async () => {
1139
- if (!expoAv || !content) return;
1793
+ const fetchTTS = (0, import_react2.useCallback)(async () => {
1794
+ if (!content) return;
1795
+ logTTS("tts_fetch_started", {
1796
+ language: selectedLanguage,
1797
+ baseUrl: baseUrl || "default"
1798
+ });
1140
1799
  try {
1141
1800
  const data = await fetchTTSAudioUrls({
1142
1801
  accessToken,
@@ -1148,8 +1807,15 @@ var RedactoNoticeConsent = ({
1148
1807
  notice_text: data.detail.notice_text_audio_url,
1149
1808
  additional_text: data.detail.additional_text_audio_url,
1150
1809
  notice_banner_heading: data.detail.notice_banner_heading_audio_url,
1151
- purpose_section_heading: data.detail.purpose_section_heading_audio_url
1810
+ purpose_section_heading: data.detail.purpose_section_heading_audio_url,
1811
+ privacy_policy_prefix_text: data.detail.privacy_policy_prefix_text_audio_url,
1812
+ privacy_policy_anchor_text: data.detail.privacy_policy_anchor_text_audio_url,
1813
+ confirm_button_text: data.detail.confirm_button_text_audio_url,
1814
+ decline_button_text: data.detail.decline_button_text_audio_url
1152
1815
  };
1816
+ if (data.detail.privacy_center_anchor_text_audio_url) {
1817
+ urls.privacy_center_anchor_text = data.detail.privacy_center_anchor_text_audio_url;
1818
+ }
1153
1819
  content.detail.active_config.purposes.forEach((p) => {
1154
1820
  var _a2;
1155
1821
  const pa = (_a2 = data.detail.purposes_audio) == null ? void 0 : _a2[p.uuid];
@@ -1163,90 +1829,293 @@ var RedactoNoticeConsent = ({
1163
1829
  if (ea) urls[`element_${el.uuid}`] = ea.name_audio_url;
1164
1830
  });
1165
1831
  });
1832
+ if (data.detail.dpo_info_audio) {
1833
+ const dpoAudio = data.detail.dpo_info_audio;
1834
+ DPO_AUDIO_ELEMENT_MAP.forEach(({ audioKey, elementId }) => {
1835
+ const url = dpoAudio[audioKey];
1836
+ if (url) urls[elementId] = url;
1837
+ });
1838
+ }
1839
+ const hasAtLeastOneAudio = Object.values(urls).some(Boolean);
1166
1840
  setTtsAudioUrls(urls);
1167
- setIsTTSAvailable(true);
1168
- } catch {
1841
+ setIsTTSAvailable(hasAtLeastOneAudio);
1842
+ logTTS("tts_fetch_success", {
1843
+ language: selectedLanguage,
1844
+ hasAtLeastOneAudio,
1845
+ audioKeyCount: Object.keys(urls).length
1846
+ });
1847
+ } catch (err) {
1848
+ const error = err;
1849
+ console.warn("[RedactoConsentSDK][TTS] tts_fetch_failed", {
1850
+ language: selectedLanguage,
1851
+ baseUrl: baseUrl || "default",
1852
+ status: error.status,
1853
+ message: error.message
1854
+ });
1855
+ setTtsAudioUrls({});
1169
1856
  setIsTTSAvailable(false);
1170
1857
  }
1171
1858
  }, [content, accessToken, baseUrl, selectedLanguage]);
1172
- (0, import_react.useEffect)(() => {
1173
- if (content && expoAv) {
1174
- fetchTTS();
1859
+ const clearPlaybackWatchers = (0, import_react2.useCallback)(() => {
1860
+ if (playbackSubscriptionRef.current) {
1861
+ playbackSubscriptionRef.current.remove();
1862
+ playbackSubscriptionRef.current = null;
1175
1863
  }
1176
- }, [content, fetchTTS]);
1177
- const stopAudio = (0, import_react.useCallback)(async () => {
1178
- if (soundRef.current) {
1179
- await soundRef.current.stopAsync();
1180
- await soundRef.current.unloadAsync();
1181
- soundRef.current = null;
1864
+ if (playbackPollerRef.current) {
1865
+ clearInterval(playbackPollerRef.current);
1866
+ playbackPollerRef.current = null;
1867
+ }
1868
+ }, []);
1869
+ const stopAudio = (0, import_react2.useCallback)(async () => {
1870
+ clearPlaybackWatchers();
1871
+ if (playerRef.current) {
1872
+ try {
1873
+ await playerRef.current.stop();
1874
+ } catch {
1875
+ }
1876
+ try {
1877
+ await playerRef.current.release();
1878
+ } catch {
1879
+ }
1880
+ playerRef.current = null;
1182
1881
  }
1183
1882
  setIsPlaying(false);
1184
1883
  setIsPaused(false);
1884
+ setActiveTTSSegmentKey(null);
1185
1885
  ttsIndexRef.current = 0;
1186
- }, []);
1187
- const playNextInQueue = (0, import_react.useCallback)(async () => {
1188
- if (!expoAv) return;
1886
+ }, [clearPlaybackWatchers]);
1887
+ (0, import_react2.useEffect)(() => {
1888
+ if (content) {
1889
+ void stopAudio();
1890
+ setIsTTSAvailable(false);
1891
+ setTtsAudioUrls({});
1892
+ void fetchTTS();
1893
+ }
1894
+ }, [content, fetchTTS, stopAudio]);
1895
+ (0, import_react2.useEffect)(() => {
1896
+ var _a2;
1897
+ if (!activeTTSSegmentKey || !content) return;
1898
+ if (!activeTTSSegmentKey.startsWith("purpose_name_") && !activeTTSSegmentKey.startsWith("purpose_desc_") && !activeTTSSegmentKey.startsWith("element_")) {
1899
+ return;
1900
+ }
1901
+ let matchedPurposeUuid = null;
1902
+ if (activeTTSSegmentKey.startsWith("purpose_name_")) {
1903
+ matchedPurposeUuid = activeTTSSegmentKey.replace("purpose_name_", "");
1904
+ } else if (activeTTSSegmentKey.startsWith("purpose_desc_")) {
1905
+ matchedPurposeUuid = activeTTSSegmentKey.replace("purpose_desc_", "");
1906
+ } else {
1907
+ const elementUuid = activeTTSSegmentKey.replace("element_", "");
1908
+ matchedPurposeUuid = ((_a2 = content.detail.active_config.purposes.find(
1909
+ (purpose) => purpose.data_elements.some((el) => el.uuid === elementUuid)
1910
+ )) == null ? void 0 : _a2.uuid) || null;
1911
+ }
1912
+ if (matchedPurposeUuid && collapsedPurposes[matchedPurposeUuid]) {
1913
+ setCollapsedPurposes((prev) => ({
1914
+ ...prev,
1915
+ [matchedPurposeUuid]: false
1916
+ }));
1917
+ }
1918
+ }, [activeTTSSegmentKey, collapsedPurposes, content]);
1919
+ const playNextInQueue = (0, import_react2.useCallback)(async () => {
1920
+ var _a2;
1921
+ const expoAudio = await getExpoAudioModuleAsync();
1922
+ if (!expoAudio) {
1923
+ console.warn("[RedactoConsentSDK][TTS] tts_playback_engine_missing", {
1924
+ reason: "expo-audio module not available"
1925
+ });
1926
+ await stopAudio();
1927
+ return;
1928
+ }
1189
1929
  const queue = ttsQueueRef.current;
1190
1930
  if (ttsIndexRef.current >= queue.length) {
1191
1931
  await stopAudio();
1192
1932
  return;
1193
1933
  }
1194
- const url = queue[ttsIndexRef.current];
1934
+ const segment = queue[ttsIndexRef.current];
1195
1935
  ttsIndexRef.current += 1;
1936
+ setActiveTTSSegmentKey(segment.segmentKey);
1196
1937
  try {
1197
- const { sound } = await expoAv.Audio.Sound.createAsync(
1198
- { uri: url },
1199
- { shouldPlay: true },
1200
- (status) => {
1201
- if (status.isLoaded && status.didJustFinish) {
1202
- playNextInQueue();
1203
- }
1938
+ clearPlaybackWatchers();
1939
+ if (playerRef.current) {
1940
+ await playerRef.current.release();
1941
+ playerRef.current = null;
1942
+ }
1943
+ const player = expoAudio.createAudioPlayer({ uri: segment.url });
1944
+ const maybeSubscription = (_a2 = player.addListener) == null ? void 0 : _a2.call(player, "playbackStatusUpdate", (status) => {
1945
+ if (status.didJustFinish) {
1946
+ clearPlaybackWatchers();
1947
+ void playNextInQueue();
1204
1948
  }
1205
- );
1206
- soundRef.current = sound;
1207
- } catch {
1208
- playNextInQueue();
1949
+ });
1950
+ if (typeof maybeSubscription === "function") {
1951
+ playbackSubscriptionRef.current = { remove: maybeSubscription };
1952
+ } else if (maybeSubscription && typeof maybeSubscription.remove === "function") {
1953
+ playbackSubscriptionRef.current = maybeSubscription;
1954
+ }
1955
+ if (!playbackSubscriptionRef.current) {
1956
+ playbackPollerRef.current = setInterval(() => {
1957
+ if (player.isLoaded && !player.playing && player.duration > 0 && player.currentTime >= player.duration - 0.05) {
1958
+ clearPlaybackWatchers();
1959
+ void playNextInQueue();
1960
+ }
1961
+ }, 200);
1962
+ }
1963
+ playerRef.current = {
1964
+ play: () => player.play(),
1965
+ pause: () => player.pause(),
1966
+ stop: () => player.pause(),
1967
+ release: () => player.remove()
1968
+ };
1969
+ player.play();
1970
+ } catch (err) {
1971
+ const error = err;
1972
+ logTTS("tts_playback_segment_failed", {
1973
+ segmentKey: segment.segmentKey,
1974
+ message: error.message
1975
+ });
1976
+ await playNextInQueue();
1977
+ }
1978
+ }, [clearPlaybackWatchers, stopAudio]);
1979
+ const startAudio = (0, import_react2.useCallback)(async () => {
1980
+ if (!content) return;
1981
+ const expoAudio = await getExpoAudioModuleAsync();
1982
+ if (!expoAudio) {
1983
+ console.warn("[RedactoConsentSDK][TTS] tts_playback_engine_missing", {
1984
+ reason: "expo-audio module not available"
1985
+ });
1986
+ return;
1987
+ }
1988
+ if (!isAudioModeConfiguredRef.current) {
1989
+ try {
1990
+ await expoAudio.setAudioModeAsync({
1991
+ playsInSilentMode: true
1992
+ });
1993
+ isAudioModeConfiguredRef.current = true;
1994
+ } catch (err) {
1995
+ const error = err;
1996
+ console.warn("[RedactoConsentSDK][TTS] tts_audio_mode_config_failed", {
1997
+ message: error.message
1998
+ });
1999
+ }
1209
2000
  }
1210
- }, [stopAudio]);
1211
- const startAudio = (0, import_react.useCallback)(async () => {
1212
- if (!expoAv || !content) return;
1213
2001
  const ac = content.detail.active_config;
1214
2002
  const queue = [];
1215
- if (ttsAudioUrls.notice_banner_heading) queue.push(ttsAudioUrls.notice_banner_heading);
1216
- if (ttsAudioUrls.notice_text) queue.push(ttsAudioUrls.notice_text);
1217
- if (ttsAudioUrls.additional_text) queue.push(ttsAudioUrls.additional_text);
1218
- if (ttsAudioUrls.purpose_section_heading) queue.push(ttsAudioUrls.purpose_section_heading);
2003
+ const pushSegment = (segmentKey, url) => {
2004
+ if (url) {
2005
+ queue.push({ segmentKey, url });
2006
+ }
2007
+ };
2008
+ pushSegment("notice_banner_heading", ttsAudioUrls.notice_banner_heading);
2009
+ pushSegment("notice_text", ttsAudioUrls.notice_text);
2010
+ pushSegment("privacy_policy_prefix_text", ttsAudioUrls.privacy_policy_prefix_text);
2011
+ pushSegment("privacy_policy_anchor_text", ttsAudioUrls.privacy_policy_anchor_text);
2012
+ pushSegment("purpose_section_heading", ttsAudioUrls.purpose_section_heading);
1219
2013
  ac.purposes.forEach((p) => {
1220
- if (ttsAudioUrls[`purpose_name_${p.uuid}`]) queue.push(ttsAudioUrls[`purpose_name_${p.uuid}`]);
1221
- if (ttsAudioUrls[`purpose_desc_${p.uuid}`]) queue.push(ttsAudioUrls[`purpose_desc_${p.uuid}`]);
2014
+ pushSegment(`purpose_name_${p.uuid}`, ttsAudioUrls[`purpose_name_${p.uuid}`]);
2015
+ pushSegment(`purpose_desc_${p.uuid}`, ttsAudioUrls[`purpose_desc_${p.uuid}`]);
1222
2016
  p.data_elements.forEach((el) => {
1223
- if (ttsAudioUrls[`element_${el.uuid}`]) queue.push(ttsAudioUrls[`element_${el.uuid}`]);
2017
+ pushSegment(`element_${el.uuid}`, ttsAudioUrls[`element_${el.uuid}`]);
1224
2018
  });
1225
2019
  });
2020
+ pushSegment("additional_text", ttsAudioUrls.additional_text);
2021
+ pushSegment("privacy_center_anchor_text", ttsAudioUrls.privacy_center_anchor_text);
2022
+ DPO_AUDIO_ELEMENT_MAP.forEach(({ elementId }) => {
2023
+ pushSegment(elementId, ttsAudioUrls[elementId]);
2024
+ });
2025
+ pushSegment("confirm_button_text", ttsAudioUrls.confirm_button_text);
2026
+ pushSegment("decline_button_text", ttsAudioUrls.decline_button_text);
2027
+ if (queue.length === 0) {
2028
+ logTTS("tts_playback_queue_empty", { language: selectedLanguage });
2029
+ return;
2030
+ }
1226
2031
  ttsQueueRef.current = queue;
1227
2032
  ttsIndexRef.current = 0;
1228
2033
  setIsPlaying(true);
1229
2034
  setIsPaused(false);
2035
+ logTTS("tts_playback_start", { queueLength: queue.length, language: selectedLanguage });
1230
2036
  await playNextInQueue();
1231
- }, [content, ttsAudioUrls, playNextInQueue]);
1232
- const toggleAudio = (0, import_react.useCallback)(async () => {
1233
- var _a2, _b2;
2037
+ }, [content, ttsAudioUrls, playNextInQueue, selectedLanguage]);
2038
+ const toggleAudio = (0, import_react2.useCallback)(async () => {
2039
+ var _a2;
1234
2040
  if (isPlaying && !isPaused) {
1235
- await ((_a2 = soundRef.current) == null ? void 0 : _a2.pauseAsync());
2041
+ await ((_a2 = playerRef.current) == null ? void 0 : _a2.pause());
1236
2042
  setIsPaused(true);
2043
+ setActiveTTSSegmentKey(null);
2044
+ logTTS("tts_playback_paused");
1237
2045
  } else if (isPaused) {
1238
- await ((_b2 = soundRef.current) == null ? void 0 : _b2.playAsync());
2046
+ if (!playerRef.current) {
2047
+ await startAudio();
2048
+ return;
2049
+ }
2050
+ await playerRef.current.play();
1239
2051
  setIsPaused(false);
2052
+ const currentQueueItem = ttsQueueRef.current[ttsIndexRef.current - 1];
2053
+ setActiveTTSSegmentKey((currentQueueItem == null ? void 0 : currentQueueItem.segmentKey) || null);
2054
+ logTTS("tts_playback_resumed");
1240
2055
  } else {
1241
2056
  await startAudio();
1242
2057
  }
1243
2058
  }, [isPlaying, isPaused, startAudio]);
1244
- (0, import_react.useEffect)(() => {
2059
+ (0, import_react2.useEffect)(() => {
1245
2060
  return () => {
1246
2061
  stopAudio();
1247
2062
  };
1248
2063
  }, [stopAudio]);
1249
- const getTranslatedText = (0, import_react.useCallback)(
2064
+ (0, import_react2.useEffect)(() => {
2065
+ const subscription = import_react_native5.AppState.addEventListener("change", (nextAppState) => {
2066
+ isAppActiveRef.current = nextAppState === "active";
2067
+ });
2068
+ return () => subscription.remove();
2069
+ }, []);
2070
+ const stopPolling = (0, import_react2.useCallback)(() => {
2071
+ if (pollingTimerRef.current) {
2072
+ clearTimeout(pollingTimerRef.current);
2073
+ pollingTimerRef.current = null;
2074
+ }
2075
+ }, []);
2076
+ const pollVerificationStatus = (0, import_react2.useCallback)(async () => {
2077
+ const sessionToken = verificationSessionTokenRef.current;
2078
+ if (!sessionToken) return;
2079
+ pollingCountRef.current += 1;
2080
+ if (pollingCountRef.current > 40) {
2081
+ stopPolling();
2082
+ setVerificationStatus("expired");
2083
+ setVerificationError("Verification timed out. Please try again.");
2084
+ return;
2085
+ }
2086
+ if (!isAppActiveRef.current) {
2087
+ pollingTimerRef.current = setTimeout(pollVerificationStatus, 3e3);
2088
+ return;
2089
+ }
2090
+ try {
2091
+ const result = await verifyGuardianStatus({
2092
+ accessToken,
2093
+ baseUrl,
2094
+ sessionToken
2095
+ });
2096
+ if (result.status === "verified") {
2097
+ stopPolling();
2098
+ verificationReferenceRef.current = result.verificationReference || null;
2099
+ setVerificationStatus("verified");
2100
+ } else if (result.status === "failed" || result.status === "expired") {
2101
+ stopPolling();
2102
+ setVerificationStatus(result.status);
2103
+ setVerificationError(result.error);
2104
+ setVerificationErrorCode(result.errorCode);
2105
+ setCanRetryVerification(result.canRetry !== false);
2106
+ } else {
2107
+ pollingTimerRef.current = setTimeout(pollVerificationStatus, 3e3);
2108
+ }
2109
+ } catch {
2110
+ pollingTimerRef.current = setTimeout(pollVerificationStatus, 3e3);
2111
+ }
2112
+ }, [accessToken, baseUrl, stopPolling]);
2113
+ (0, import_react2.useEffect)(() => {
2114
+ return () => {
2115
+ stopPolling();
2116
+ };
2117
+ }, [stopPolling]);
2118
+ const getTranslatedText = (0, import_react2.useCallback)(
1250
2119
  (key, defaultText, itemId) => {
1251
2120
  var _a2, _b2, _c2;
1252
2121
  if (!content) return defaultText;
@@ -1274,7 +2143,7 @@ var RedactoNoticeConsent = ({
1274
2143
  },
1275
2144
  [content, selectedLanguage]
1276
2145
  );
1277
- const handlePurposeToggle = (0, import_react.useCallback)((purposeUuid) => {
2146
+ const handlePurposeToggle = (0, import_react2.useCallback)((purposeUuid) => {
1278
2147
  setSelectedPurposes((prev) => {
1279
2148
  const newState = !prev[purposeUuid];
1280
2149
  setSelectedDataElements((prevEl) => {
@@ -1288,10 +2157,10 @@ var RedactoNoticeConsent = ({
1288
2157
  return { ...prev, [purposeUuid]: newState };
1289
2158
  });
1290
2159
  }, [content]);
1291
- const handlePurposeCollapse = (0, import_react.useCallback)((purposeUuid) => {
2160
+ const handlePurposeCollapse = (0, import_react2.useCallback)((purposeUuid) => {
1292
2161
  setCollapsedPurposes((prev) => ({ ...prev, [purposeUuid]: !prev[purposeUuid] }));
1293
2162
  }, []);
1294
- const handleDataElementToggle = (0, import_react.useCallback)((elementUuid, purposeUuid) => {
2163
+ const handleDataElementToggle = (0, import_react2.useCallback)((elementUuid, purposeUuid) => {
1295
2164
  if (!content) return;
1296
2165
  const purpose = content.detail.active_config.purposes.find((p) => p.uuid === purposeUuid);
1297
2166
  if (!purpose) return;
@@ -1304,7 +2173,7 @@ var RedactoNoticeConsent = ({
1304
2173
  return newState;
1305
2174
  });
1306
2175
  }, [content]);
1307
- const handleAccept = (0, import_react.useCallback)(async () => {
2176
+ const handleAccept = (0, import_react2.useCallback)(async () => {
1308
2177
  if (!content) return;
1309
2178
  try {
1310
2179
  setIsSubmitting(true);
@@ -1323,7 +2192,9 @@ var RedactoNoticeConsent = ({
1323
2192
  }))
1324
2193
  })),
1325
2194
  declined: false,
1326
- meta_data: applicationId ? { specific_uuid: applicationId } : void 0
2195
+ meta_data: applicationId ? { specific_uuid: applicationId } : void 0,
2196
+ guardianVerificationReference: verificationReferenceRef.current || void 0,
2197
+ selfDeclaredAdult: selfDeclaredAdult || void 0
1327
2198
  });
1328
2199
  await stopAudio();
1329
2200
  clearApiCache();
@@ -1339,40 +2210,17 @@ var RedactoNoticeConsent = ({
1339
2210
  setIsSubmitting(false);
1340
2211
  }
1341
2212
  }, [content, accessToken, baseUrl, applicationId, selectedPurposes, selectedDataElements, stopAudio, onAccept, onError]);
1342
- const handleDecline = (0, import_react.useCallback)(async () => {
1343
- if (!content) return;
1344
- if (blockUI) return;
1345
- try {
1346
- setIsSubmitting(true);
1347
- const activeConfig2 = content.detail.active_config;
1348
- await submitConsentEvent({
1349
- accessToken,
1350
- baseUrl,
1351
- noticeUuid: activeConfig2.notice_uuid,
1352
- purposes: activeConfig2.purposes.map((purpose) => ({
1353
- ...purpose,
1354
- selected: false,
1355
- data_elements: purpose.data_elements.map((el) => ({ ...el, selected: false }))
1356
- })),
1357
- declined: true
1358
- });
1359
- await stopAudio();
1360
- clearApiCache();
1361
- setIsVisible(false);
1362
- onDecline();
1363
- } catch (err) {
1364
- const error = err;
1365
- setErrorMessage(error.message || "Failed to decline consent.");
1366
- onError == null ? void 0 : onError(error);
1367
- } finally {
1368
- setIsSubmitting(false);
1369
- }
1370
- }, [content, accessToken, baseUrl, blockUI, stopAudio, onDecline, onError]);
1371
- const handleGuardianFormChange = (0, import_react.useCallback)((field, value) => {
2213
+ const handleDecline = (0, import_react2.useCallback)(() => {
2214
+ stopAudio();
2215
+ stopPolling();
2216
+ setIsVisible(false);
2217
+ onDecline();
2218
+ }, [stopAudio, stopPolling, onDecline]);
2219
+ const handleGuardianFormChange = (0, import_react2.useCallback)((field, value) => {
1372
2220
  setGuardianFormData((prev) => ({ ...prev, [field]: value }));
1373
2221
  setGuardianFormErrors((prev) => ({ ...prev, [field]: "" }));
1374
2222
  }, []);
1375
- const handleGuardianFormNext = (0, import_react.useCallback)(async () => {
2223
+ const handleGuardianFormNext = (0, import_react2.useCallback)(async () => {
1376
2224
  const errors = {};
1377
2225
  if (!guardianFormData.guardianName.trim()) errors.guardianName = "Guardian name is required";
1378
2226
  if (!guardianFormData.guardianContact.trim()) errors.guardianContact = "Guardian contact is required";
@@ -1383,53 +2231,114 @@ var RedactoNoticeConsent = ({
1383
2231
  }
1384
2232
  try {
1385
2233
  setIsSubmittingGuardian(true);
1386
- await submitGuardianInfo({
2234
+ setGuardianFormErrors({});
2235
+ const result = await initiateGuardianVerification({
1387
2236
  accessToken,
1388
2237
  baseUrl,
1389
2238
  guardianName: guardianFormData.guardianName,
1390
2239
  guardianContact: guardianFormData.guardianContact,
1391
2240
  guardianRelationship: guardianFormData.guardianRelationship
1392
2241
  });
1393
- setShowGuardianForm(false);
2242
+ if (result.alreadyVerified || result.verificationReference && result.status === "verified") {
2243
+ verificationReferenceRef.current = result.verificationReference || null;
2244
+ setVerificationStatus("verified");
2245
+ setShowVerificationScreen(true);
2246
+ return;
2247
+ }
2248
+ if (result.sessionToken && result.digilockerRedirectUrl) {
2249
+ verificationSessionTokenRef.current = result.sessionToken;
2250
+ setVerificationStatus("pending");
2251
+ setShowVerificationScreen(true);
2252
+ pollingCountRef.current = 0;
2253
+ try {
2254
+ const canOpen = await import_react_native5.Linking.canOpenURL(result.digilockerRedirectUrl);
2255
+ if (canOpen) {
2256
+ await import_react_native5.Linking.openURL(result.digilockerRedirectUrl);
2257
+ }
2258
+ } catch {
2259
+ }
2260
+ pollingTimerRef.current = setTimeout(pollVerificationStatus, 3e3);
2261
+ } else if (result.verificationReference) {
2262
+ verificationReferenceRef.current = result.verificationReference;
2263
+ setVerificationStatus("verified");
2264
+ setShowVerificationScreen(true);
2265
+ } else {
2266
+ setGuardianFormErrors({ general: "Invalid response from server: missing required fields" });
2267
+ }
1394
2268
  } catch (err) {
1395
2269
  const error = err;
1396
- setGuardianFormErrors({ general: error.message || "Failed to submit guardian info." });
2270
+ setGuardianFormErrors({ general: error.message || "Failed to initiate verification." });
1397
2271
  } finally {
1398
2272
  setIsSubmittingGuardian(false);
1399
2273
  }
1400
- }, [guardianFormData, accessToken, baseUrl]);
2274
+ }, [guardianFormData, accessToken, baseUrl, pollVerificationStatus]);
2275
+ const handleRetryVerification = (0, import_react2.useCallback)(() => {
2276
+ setVerificationStatus("pending");
2277
+ setVerificationError(void 0);
2278
+ setVerificationErrorCode(void 0);
2279
+ pollingCountRef.current = 0;
2280
+ setShowVerificationScreen(false);
2281
+ }, []);
1401
2282
  const activeConfig = content == null ? void 0 : content.detail.active_config;
1402
2283
  const logoUrl = activeConfig == null ? void 0 : activeConfig.logo_url;
1403
- const supportedLanguages = (0, import_react.useMemo)(
1404
- () => Object.keys((activeConfig == null ? void 0 : activeConfig.supported_languages_and_translations) || {}),
1405
- [activeConfig]
1406
- );
1407
- const acceptButtonStyle = ((_a = settings == null ? void 0 : settings.button) == null ? void 0 : _a.accept) ? { backgroundColor: settings.button.accept.backgroundColor } : {};
1408
- const acceptButtonTextStyle = ((_b = settings == null ? void 0 : settings.button) == null ? void 0 : _b.accept) ? { color: settings.button.accept.textColor } : {};
1409
- const declineButtonStyle = ((_c = settings == null ? void 0 : settings.button) == null ? void 0 : _c.decline) ? { backgroundColor: settings.button.decline.backgroundColor, borderColor: settings.button.decline.backgroundColor } : {};
1410
- const declineButtonTextStyle = ((_d = settings == null ? void 0 : settings.button) == null ? void 0 : _d.decline) ? { color: settings.button.decline.textColor } : {};
2284
+ const supportedLanguages = (0, import_react2.useMemo)(() => {
2285
+ if (!activeConfig) return [];
2286
+ const languages = ["English"];
2287
+ const defaultLang = activeConfig.default_language;
2288
+ if (defaultLang && defaultLang !== "English" && defaultLang !== "en" && defaultLang !== "EN") {
2289
+ languages.push(defaultLang);
2290
+ }
2291
+ for (const key of Object.keys(activeConfig.supported_languages_and_translations || {}).sort()) {
2292
+ if (!languages.includes(key)) {
2293
+ languages.push(key);
2294
+ }
2295
+ }
2296
+ return languages;
2297
+ }, [activeConfig]);
2298
+ const headingColor = (settings == null ? void 0 : settings.headingColor) || "#323B4B";
2299
+ const textColor = (settings == null ? void 0 : settings.textColor) || "#344054";
2300
+ const borderColor = (settings == null ? void 0 : settings.borderColor) || "#d0d5dd";
2301
+ const acceptBackgroundColor = ((_b = (_a = settings == null ? void 0 : settings.button) == null ? void 0 : _a.accept) == null ? void 0 : _b.backgroundColor) || (activeConfig == null ? void 0 : activeConfig.primary_color) || "#4f87ff";
2302
+ const acceptTextColor = ((_d = (_c = settings == null ? void 0 : settings.button) == null ? void 0 : _c.accept) == null ? void 0 : _d.textColor) || "#ffffff";
2303
+ const declineBackgroundColor = ((_f = (_e = settings == null ? void 0 : settings.button) == null ? void 0 : _e.decline) == null ? void 0 : _f.backgroundColor) || "#ffffff";
2304
+ const declineTextColor = ((_h = (_g = settings == null ? void 0 : settings.button) == null ? void 0 : _g.decline) == null ? void 0 : _h.textColor) || "#000000";
2305
+ const linkColor = (settings == null ? void 0 : settings.link) || (activeConfig == null ? void 0 : activeConfig.secondary_color) || "#4f87ff";
2306
+ const accentColor = (activeConfig == null ? void 0 : activeConfig.primary_color) || "#4f87ff";
2307
+ const areAllRequiredElementsChecked = (0, import_react2.useMemo)(() => {
2308
+ if (!activeConfig) return false;
2309
+ return activeConfig.purposes.every((purpose) => {
2310
+ const requiredElements = purpose.data_elements.filter((el) => el.required);
2311
+ return requiredElements.every(
2312
+ (el) => selectedDataElements[`${purpose.uuid}-${el.uuid}`]
2313
+ );
2314
+ });
2315
+ }, [activeConfig, selectedDataElements]);
2316
+ const acceptButtonStyle = { backgroundColor: acceptBackgroundColor };
2317
+ const acceptButtonTextStyle = { color: acceptTextColor };
2318
+ const declineButtonStyle = { backgroundColor: declineBackgroundColor, borderColor };
2319
+ const declineButtonTextStyle = { color: declineTextColor };
1411
2320
  const modalBg = (settings == null ? void 0 : settings.backgroundColor) ? { backgroundColor: settings.backgroundColor } : {};
1412
2321
  const translatedNoticeText = activeConfig ? stripHtml(getTranslatedText("notice_text", activeConfig.notice_text || "")) : "";
1413
2322
  const translatedAdditionalText = activeConfig ? stripHtml(getTranslatedText("additional_text", activeConfig.additional_text || "")) : "";
1414
2323
  if (!isVisible && !isLoading) return null;
1415
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1416
- import_react_native4.Modal,
2324
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2325
+ import_react_native5.Modal,
1417
2326
  {
1418
2327
  visible: isVisible || isLoading,
1419
2328
  transparent: true,
1420
2329
  animationType: "fade",
1421
2330
  onRequestClose: blockUI ? void 0 : handleDecline,
1422
2331
  accessibilityViewIsModal: true,
1423
- children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native4.View, { style: styles2.overlay, children: [
1424
- isLanguageDropdownOpen && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1425
- import_react_native4.Pressable,
2332
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native5.View, { style: styles2.overlay, children: [
2333
+ isLanguageDropdownOpen && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2334
+ import_react_native5.Pressable,
1426
2335
  {
1427
- style: [import_react_native4.StyleSheet.absoluteFillObject, { zIndex: 1 }],
2336
+ style: [import_react_native5.StyleSheet.absoluteFillObject, { zIndex: 1 }],
1428
2337
  onPress: () => setIsLanguageDropdownOpen(false)
1429
2338
  }
1430
2339
  ),
1431
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1432
- import_react_native4.View,
2340
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2341
+ import_react_native5.View,
1433
2342
  {
1434
2343
  style: [
1435
2344
  styles2.modal,
@@ -1437,10 +2346,47 @@ var RedactoNoticeConsent = ({
1437
2346
  { zIndex: 2 },
1438
2347
  (settings == null ? void 0 : settings.borderRadius) ? { borderRadius: parseInt(settings.borderRadius, 10) } : null
1439
2348
  ],
1440
- children: isLoading ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native4.View, { style: styles2.loadingContainer, children: [
1441
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.ActivityIndicator, { size: "large", color: "#4f87ff" }),
1442
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.Text, { style: styles2.loadingText, children: "Loading..." })
1443
- ] }) : showGuardianForm ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.View, { style: styles2.content, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
2349
+ children: isLoading ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native5.View, { style: styles2.loadingContainer, children: [
2350
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native5.ActivityIndicator, { size: "large", color: acceptBackgroundColor }),
2351
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native5.Text, { style: styles2.loadingText, children: "Loading..." })
2352
+ ] }) : showVerificationScreen ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native5.View, { style: styles2.content, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2353
+ VerificationScreen,
2354
+ {
2355
+ status: verificationStatus,
2356
+ errorMessage: verificationError,
2357
+ errorCode: verificationErrorCode,
2358
+ canRetry: canRetryVerification,
2359
+ onRetry: handleRetryVerification,
2360
+ onBack: () => {
2361
+ stopPolling();
2362
+ setShowVerificationScreen(false);
2363
+ },
2364
+ onContinue: () => {
2365
+ setShowVerificationScreen(false);
2366
+ setShowGuardianForm(false);
2367
+ },
2368
+ onChangeGuardian: () => {
2369
+ setShowVerificationScreen(false);
2370
+ },
2371
+ settings: {
2372
+ ...settings,
2373
+ headingColor,
2374
+ textColor,
2375
+ borderColor,
2376
+ primaryColor: acceptBackgroundColor,
2377
+ button: {
2378
+ accept: {
2379
+ backgroundColor: acceptBackgroundColor,
2380
+ textColor: acceptTextColor
2381
+ },
2382
+ decline: {
2383
+ backgroundColor: declineBackgroundColor,
2384
+ textColor: declineTextColor
2385
+ }
2386
+ }
2387
+ }
2388
+ }
2389
+ ) }) : showGuardianForm ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native5.View, { style: styles2.content, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1444
2390
  GuardianForm,
1445
2391
  {
1446
2392
  formData: guardianFormData,
@@ -1449,37 +2395,68 @@ var RedactoNoticeConsent = ({
1449
2395
  onChange: handleGuardianFormChange,
1450
2396
  onNext: handleGuardianFormNext,
1451
2397
  onDecline: handleDecline,
1452
- settings,
2398
+ settings: {
2399
+ ...settings,
2400
+ headingColor,
2401
+ textColor,
2402
+ borderColor,
2403
+ button: {
2404
+ accept: {
2405
+ backgroundColor: acceptBackgroundColor,
2406
+ textColor: acceptTextColor
2407
+ },
2408
+ decline: {
2409
+ backgroundColor: declineBackgroundColor,
2410
+ textColor: declineTextColor
2411
+ }
2412
+ }
2413
+ },
1453
2414
  logoUrl
1454
2415
  }
1455
- ) }) : showAgeVerification ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.View, { style: styles2.content, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
2416
+ ) }) : showAgeVerification ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native5.View, { style: styles2.content, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1456
2417
  AgeVerification,
1457
2418
  {
1458
2419
  onYes: () => {
1459
2420
  setShowAgeVerification(false);
2421
+ setSelfDeclaredAdult(true);
1460
2422
  },
1461
2423
  onNo: () => {
1462
2424
  setShowAgeVerification(false);
1463
2425
  if (isMinor) setShowGuardianForm(true);
1464
2426
  },
1465
- settings,
2427
+ settings: {
2428
+ ...settings,
2429
+ headingColor,
2430
+ textColor,
2431
+ button: {
2432
+ accept: {
2433
+ backgroundColor: acceptBackgroundColor,
2434
+ textColor: acceptTextColor
2435
+ },
2436
+ decline: {
2437
+ backgroundColor: declineBackgroundColor,
2438
+ textColor: declineTextColor
2439
+ }
2440
+ }
2441
+ },
1466
2442
  logoUrl
1467
2443
  }
1468
- ) }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native4.View, { style: styles2.content, children: [
1469
- errorMessage ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native4.View, { style: styles2.errorContainer, children: [
1470
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.Text, { style: styles2.errorText, children: errorMessage }),
1471
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.TouchableOpacity, { onPress: () => setErrorMessage(null), hitSlop: { top: 8, bottom: 8, left: 8, right: 8 }, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native_svg2.default, { width: 16, height: 16, viewBox: "0 0 16 16", fill: "none", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native_svg2.Path, { d: "M12 4L4 12M4 4L12 12", stroke: "#DC2626", strokeWidth: 2, strokeLinecap: "round", strokeLinejoin: "round" }) }) })
2444
+ ) }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native5.View, { style: styles2.content, children: [
2445
+ errorMessage ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native5.View, { style: styles2.errorContainer, children: [
2446
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native5.Text, { style: styles2.errorText, children: errorMessage }),
2447
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native5.TouchableOpacity, { onPress: () => setErrorMessage(null), hitSlop: { top: 8, bottom: 8, left: 8, right: 8 }, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native_svg3.default, { width: 16, height: 16, viewBox: "0 0 16 16", fill: "none", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native_svg3.Path, { d: "M12 4L4 12M4 4L12 12", stroke: "#DC2626", strokeWidth: 2, strokeLinecap: "round", strokeLinejoin: "round" }) }) })
1472
2448
  ] }) : null,
1473
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native4.View, { style: styles2.topSection, children: [
1474
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native4.View, { style: styles2.topLeft, children: [
1475
- logoUrl ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.Image, { style: styles2.logo, source: { uri: logoUrl } }) : null,
1476
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1477
- import_react_native4.Text,
2449
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native5.View, { style: styles2.topSection, children: [
2450
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native5.View, { style: styles2.topLeft, children: [
2451
+ logoUrl ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(RemoteLogo, { uri: logoUrl, style: { height: 32, width: 80 } }) : null,
2452
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2453
+ import_react_native5.Text,
1478
2454
  {
1479
2455
  style: [
1480
2456
  styles2.title,
1481
- { color: (settings == null ? void 0 : settings.headingColor) || "#101828" },
1482
- isMobile ? { fontSize: 16 } : null
2457
+ { color: headingColor },
2458
+ isMobile ? { fontSize: 16 } : null,
2459
+ activeTTSSegmentKey === "notice_banner_heading" ? styles2.ttsHighlight : null
1483
2460
  ],
1484
2461
  numberOfLines: 2,
1485
2462
  children: getTranslatedText(
@@ -1489,32 +2466,32 @@ var RedactoNoticeConsent = ({
1489
2466
  }
1490
2467
  )
1491
2468
  ] }),
1492
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native4.View, { style: { flexDirection: "row", gap: 8, alignItems: "center" }, children: [
1493
- isTTSAvailable && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1494
- import_react_native4.TouchableOpacity,
2469
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native5.View, { style: { flexDirection: "row", gap: 8, alignItems: "center" }, children: [
2470
+ isTTSAvailable && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2471
+ import_react_native5.TouchableOpacity,
1495
2472
  {
1496
- style: [styles2.topRight, ((_e = settings == null ? void 0 : settings.button) == null ? void 0 : _e.language) ? { backgroundColor: settings.button.language.backgroundColor, borderColor: settings.button.language.backgroundColor } : null],
2473
+ style: [styles2.topRight, ((_i = settings == null ? void 0 : settings.button) == null ? void 0 : _i.language) ? { backgroundColor: settings.button.language.backgroundColor, borderColor: settings.button.language.backgroundColor } : null],
1497
2474
  onPress: toggleAudio,
1498
2475
  accessibilityLabel: isPlaying && !isPaused ? "Pause audio" : isPaused ? "Resume audio" : "Start audio",
1499
- children: isPlaying && !isPaused ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native_svg2.default, { width: 16, height: 16, viewBox: "0 0 24 24", fill: "none", children: [
1500
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native_svg2.Rect, { x: "6", y: "4", width: "4", height: "16", fill: ((_g = (_f = settings == null ? void 0 : settings.button) == null ? void 0 : _f.language) == null ? void 0 : _g.textColor) || "#344054" }),
1501
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native_svg2.Rect, { x: "14", y: "4", width: "4", height: "16", fill: ((_i = (_h = settings == null ? void 0 : settings.button) == null ? void 0 : _h.language) == null ? void 0 : _i.textColor) || "#344054" })
1502
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native_svg2.default, { width: 16, height: 16, viewBox: "0 0 24 24", fill: "none", children: [
1503
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1504
- import_react_native_svg2.Path,
2476
+ children: isPlaying && !isPaused ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native_svg3.default, { width: 16, height: 16, viewBox: "0 0 24 24", fill: "none", children: [
2477
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native_svg3.Rect, { x: "6", y: "4", width: "4", height: "16", fill: ((_k = (_j = settings == null ? void 0 : settings.button) == null ? void 0 : _j.language) == null ? void 0 : _k.textColor) || "#344054" }),
2478
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native_svg3.Rect, { x: "14", y: "4", width: "4", height: "16", fill: ((_m = (_l = settings == null ? void 0 : settings.button) == null ? void 0 : _l.language) == null ? void 0 : _m.textColor) || "#344054" })
2479
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native_svg3.default, { width: 16, height: 16, viewBox: "0 0 24 24", fill: "none", children: [
2480
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2481
+ import_react_native_svg3.Path,
1505
2482
  {
1506
2483
  d: "M11 5L6 9H2V15H6L11 19V5Z",
1507
- stroke: ((_k = (_j = settings == null ? void 0 : settings.button) == null ? void 0 : _j.language) == null ? void 0 : _k.textColor) || "#344054",
2484
+ stroke: ((_o = (_n = settings == null ? void 0 : settings.button) == null ? void 0 : _n.language) == null ? void 0 : _o.textColor) || "#344054",
1508
2485
  strokeWidth: 2,
1509
2486
  strokeLinecap: "round",
1510
2487
  strokeLinejoin: "round"
1511
2488
  }
1512
2489
  ),
1513
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1514
- import_react_native_svg2.Path,
2490
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2491
+ import_react_native_svg3.Path,
1515
2492
  {
1516
2493
  d: "M19.07 4.93a10 10 0 0 1 0 14.14M15.54 8.46a5 5 0 0 1 0 7.07",
1517
- stroke: ((_m = (_l = settings == null ? void 0 : settings.button) == null ? void 0 : _l.language) == null ? void 0 : _m.textColor) || "#344054",
2494
+ stroke: ((_q = (_p = settings == null ? void 0 : settings.button) == null ? void 0 : _p.language) == null ? void 0 : _q.textColor) || "#344054",
1518
2495
  strokeWidth: 2,
1519
2496
  strokeLinecap: "round",
1520
2497
  strokeLinejoin: "round"
@@ -1523,23 +2500,23 @@ var RedactoNoticeConsent = ({
1523
2500
  ] })
1524
2501
  }
1525
2502
  ),
1526
- supportedLanguages.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native4.View, { style: styles2.languageSelectorContainer, children: [
1527
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
1528
- import_react_native4.TouchableOpacity,
2503
+ supportedLanguages.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native5.View, { style: styles2.languageSelectorContainer, children: [
2504
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
2505
+ import_react_native5.TouchableOpacity,
1529
2506
  {
1530
2507
  style: [
1531
2508
  styles2.topRight,
1532
- ((_n = settings == null ? void 0 : settings.button) == null ? void 0 : _n.language) ? { backgroundColor: settings.button.language.backgroundColor, borderColor: settings.button.language.backgroundColor } : null
2509
+ ((_r = settings == null ? void 0 : settings.button) == null ? void 0 : _r.language) ? { backgroundColor: settings.button.language.backgroundColor, borderColor: settings.button.language.backgroundColor } : null
1533
2510
  ],
1534
2511
  onPress: () => setIsLanguageDropdownOpen((v) => !v),
1535
2512
  accessibilityLabel: `Select language. Current: ${selectedLanguage}`,
1536
2513
  children: [
1537
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.Text, { style: [styles2.topRightText, ((_o = settings == null ? void 0 : settings.button) == null ? void 0 : _o.language) ? { color: settings.button.language.textColor } : null], children: selectedLanguage }),
1538
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native_svg2.default, { width: 12, height: 12, viewBox: "0 0 16 16", fill: "none", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1539
- import_react_native_svg2.Path,
2514
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native5.Text, { style: [styles2.topRightText, ((_s = settings == null ? void 0 : settings.button) == null ? void 0 : _s.language) ? { color: settings.button.language.textColor } : null], children: selectedLanguage }),
2515
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native_svg3.default, { width: 12, height: 12, viewBox: "0 0 16 16", fill: "none", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2516
+ import_react_native_svg3.Path,
1540
2517
  {
1541
2518
  d: "M4 6L8 10L12 6",
1542
- stroke: ((_q = (_p = settings == null ? void 0 : settings.button) == null ? void 0 : _p.language) == null ? void 0 : _q.textColor) || "#344054",
2519
+ stroke: ((_u = (_t = settings == null ? void 0 : settings.button) == null ? void 0 : _t.language) == null ? void 0 : _u.textColor) || "#344054",
1543
2520
  strokeWidth: 2,
1544
2521
  strokeLinecap: "round",
1545
2522
  strokeLinejoin: "round"
@@ -1548,8 +2525,8 @@ var RedactoNoticeConsent = ({
1548
2525
  ]
1549
2526
  }
1550
2527
  ),
1551
- isLanguageDropdownOpen && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.View, { style: styles2.languageDropdown, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.ScrollView, { children: supportedLanguages.map((lang) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1552
- import_react_native4.TouchableOpacity,
2528
+ isLanguageDropdownOpen && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native5.View, { style: styles2.languageDropdown, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native5.ScrollView, { children: supportedLanguages.map((lang) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2529
+ import_react_native5.TouchableOpacity,
1553
2530
  {
1554
2531
  style: [
1555
2532
  styles2.languageItem,
@@ -1559,8 +2536,8 @@ var RedactoNoticeConsent = ({
1559
2536
  setSelectedLanguage(lang);
1560
2537
  setIsLanguageDropdownOpen(false);
1561
2538
  },
1562
- children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1563
- import_react_native4.Text,
2539
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2540
+ import_react_native5.Text,
1564
2541
  {
1565
2542
  style: [
1566
2543
  styles2.languageItemText,
@@ -1575,27 +2552,63 @@ var RedactoNoticeConsent = ({
1575
2552
  ] })
1576
2553
  ] })
1577
2554
  ] }),
1578
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native4.ScrollView, { style: styles2.middleSection, showsVerticalScrollIndicator: false, children: [
1579
- translatedNoticeText ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.Text, { style: [styles2.privacyText, (settings == null ? void 0 : settings.textColor) ? { color: settings.textColor } : null], children: translatedNoticeText }) : null,
1580
- translatedAdditionalText ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.Text, { style: [styles2.privacyText, { marginTop: 8 }, (settings == null ? void 0 : settings.textColor) ? { color: settings.textColor } : null], children: translatedAdditionalText }) : null,
1581
- (activeConfig == null ? void 0 : activeConfig.privacy_policy_url) ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1582
- import_react_native4.TouchableOpacity,
2555
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native5.ScrollView, { style: styles2.middleSection, showsVerticalScrollIndicator: false, children: [
2556
+ translatedNoticeText ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2557
+ import_react_native5.Text,
2558
+ {
2559
+ style: [
2560
+ styles2.privacyText,
2561
+ { color: textColor },
2562
+ activeTTSSegmentKey === "notice_text" ? styles2.ttsHighlight : null
2563
+ ],
2564
+ children: translatedNoticeText
2565
+ }
2566
+ ) : null,
2567
+ (activeConfig == null ? void 0 : activeConfig.privacy_policy_url) ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
2568
+ import_react_native5.Text,
1583
2569
  {
1584
- onPress: () => import_react_native4.Linking.openURL(activeConfig.privacy_policy_url),
1585
- style: { marginTop: 8 },
1586
- children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native4.Text, { style: styles2.link, children: [
1587
- getTranslatedText("privacy_policy_prefix_text", activeConfig.privacy_policy_prefix_text || ""),
1588
- " ",
1589
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.Text, { style: styles2.link, children: getTranslatedText("privacy_policy_anchor_text", activeConfig.privacy_policy_anchor_text || "Privacy Policy") })
1590
- ] })
2570
+ style: [
2571
+ styles2.privacyText,
2572
+ { marginTop: 8 },
2573
+ { color: textColor }
2574
+ ],
2575
+ children: [
2576
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native5.Text, { style: activeTTSSegmentKey === "privacy_policy_prefix_text" ? styles2.ttsHighlight : null, children: [
2577
+ getTranslatedText("privacy_policy_prefix_text", activeConfig.privacy_policy_prefix_text || ""),
2578
+ " "
2579
+ ] }),
2580
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2581
+ import_react_native5.Text,
2582
+ {
2583
+ style: [
2584
+ styles2.link,
2585
+ { color: linkColor },
2586
+ activeTTSSegmentKey === "privacy_policy_anchor_text" ? styles2.ttsHighlight : null
2587
+ ],
2588
+ onPress: () => import_react_native5.Linking.openURL(activeConfig.privacy_policy_url),
2589
+ children: getTranslatedText("privacy_policy_anchor_text", activeConfig.privacy_policy_anchor_text || "Privacy Policy")
2590
+ }
2591
+ )
2592
+ ]
2593
+ }
2594
+ ) : null,
2595
+ (activeConfig == null ? void 0 : activeConfig.purposes) && activeConfig.purposes.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2596
+ import_react_native5.Text,
2597
+ {
2598
+ style: [
2599
+ styles2.subTitle,
2600
+ { marginTop: 16, marginBottom: 8 },
2601
+ { color: headingColor },
2602
+ activeTTSSegmentKey === "purpose_section_heading" ? styles2.ttsHighlight : null
2603
+ ],
2604
+ children: getTranslatedText("purpose_section_heading", activeConfig.purpose_section_heading || "Data Purposes")
1591
2605
  }
1592
2606
  ) : null,
1593
- (activeConfig == null ? void 0 : activeConfig.purposes) && activeConfig.purposes.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.Text, { style: [styles2.subTitle, { marginTop: 16, marginBottom: 8 }, (settings == null ? void 0 : settings.headingColor) ? { color: settings.headingColor } : null], children: getTranslatedText("purpose_section_heading", activeConfig.purpose_section_heading || "Data Purposes") }) : null,
1594
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.View, { style: styles2.optionsContainer, children: activeConfig == null ? void 0 : activeConfig.purposes.map((purpose) => {
2607
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native5.View, { style: styles2.optionsContainer, children: activeConfig == null ? void 0 : activeConfig.purposes.map((purpose) => {
1595
2608
  var _a2;
1596
2609
  const purposeSelection = (_a2 = content == null ? void 0 : content.detail.purpose_selections) == null ? void 0 : _a2[purpose.uuid];
1597
2610
  const isAlreadyConsented = !isReconsentMode && ((purposeSelection == null ? void 0 : purposeSelection.selected) || false) && !(purposeSelection == null ? void 0 : purposeSelection.needs_reconsent);
1598
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
2611
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1599
2612
  PurposeItem,
1600
2613
  {
1601
2614
  purpose,
@@ -1609,55 +2622,174 @@ var RedactoNoticeConsent = ({
1609
2622
  getTranslatedText,
1610
2623
  isAlreadyConsented,
1611
2624
  initialDataElementSelections,
1612
- selectedLanguage
2625
+ selectedLanguage,
2626
+ accentColor,
2627
+ activeTTSSegmentKey
1613
2628
  },
1614
2629
  purpose.uuid
1615
2630
  );
1616
2631
  }) }),
1617
- (activeConfig == null ? void 0 : activeConfig.dpo_info) ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.View, { style: { marginTop: 16, gap: 4 }, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native4.Text, { style: [styles2.privacyText, { fontSize: 13 }, (settings == null ? void 0 : settings.textColor) ? { color: settings.textColor } : null], children: [
1618
- activeConfig.dpo_info.grievance_text,
1619
- " ",
1620
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1621
- import_react_native4.Text,
1622
- {
1623
- style: styles2.link,
1624
- onPress: () => import_react_native4.Linking.openURL(activeConfig.dpo_info.grievance_url),
1625
- children: activeConfig.dpo_info.grievance_anchor_text
2632
+ (activeConfig == null ? void 0 : activeConfig.dpo_info) || (activeConfig == null ? void 0 : activeConfig.privacy_center_url) || translatedAdditionalText ? (() => {
2633
+ var _a2;
2634
+ const dpo = activeConfig == null ? void 0 : activeConfig.dpo_info;
2635
+ const translationMap = (_a2 = activeConfig == null ? void 0 : activeConfig.supported_languages_and_translations) == null ? void 0 : _a2[selectedLanguage];
2636
+ const dpoTranslation = translationMap == null ? void 0 : translationMap.dpo_info;
2637
+ const dpoTextColor = textColor;
2638
+ const getT = (key, fallback) => {
2639
+ if (dpoTranslation && key in dpoTranslation) {
2640
+ return dpoTranslation[key] || fallback;
1626
2641
  }
1627
- )
1628
- ] }) }) : null
2642
+ return fallback;
2643
+ };
2644
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native5.View, { style: { marginTop: 8, paddingTop: 8, borderTopWidth: 1, borderTopColor: "rgba(152, 162, 179, 0.3)", opacity: 0.6 }, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native5.Text, { style: [styles2.privacyText, { fontSize: 14, color: dpoTextColor }], children: [
2645
+ translatedAdditionalText ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native5.Text, { style: activeTTSSegmentKey === "additional_text" ? styles2.ttsHighlight : null, children: [
2646
+ translatedAdditionalText,
2647
+ " "
2648
+ ] }) : null,
2649
+ (activeConfig == null ? void 0 : activeConfig.privacy_center_url) ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
2650
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2651
+ import_react_native5.Text,
2652
+ {
2653
+ style: [
2654
+ styles2.link,
2655
+ { color: linkColor },
2656
+ activeTTSSegmentKey === "privacy_center_anchor_text" ? styles2.ttsHighlight : null
2657
+ ],
2658
+ onPress: () => import_react_native5.Linking.openURL(activeConfig.privacy_center_url),
2659
+ children: getTranslatedText("privacy_center_anchor_text", activeConfig.privacy_center_anchor_text || "Privacy Center")
2660
+ }
2661
+ ),
2662
+ ".\n"
2663
+ ] }) : null,
2664
+ (dpo == null ? void 0 : dpo.grievance_text) ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
2665
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native5.Text, { style: activeTTSSegmentKey === "dpo-grievance-text" ? styles2.ttsHighlight : null, children: [
2666
+ getT("grievance_text", dpo.grievance_text),
2667
+ " "
2668
+ ] }),
2669
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2670
+ import_react_native5.Text,
2671
+ {
2672
+ style: [
2673
+ styles2.link,
2674
+ { color: linkColor },
2675
+ activeTTSSegmentKey === "dpo-grievance-link" ? styles2.ttsHighlight : null
2676
+ ],
2677
+ onPress: () => import_react_native5.Linking.openURL(dpo.grievance_url),
2678
+ children: getT("grievance_anchor_text", dpo.grievance_anchor_text)
2679
+ }
2680
+ ),
2681
+ dpo.grievance_email ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
2682
+ " ",
2683
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native5.Text, { style: activeTTSSegmentKey === "dpo-grievance-email-connector" ? styles2.ttsHighlight : null, children: getT("grievance_email_connector_text", dpo.grievance_email_connector_text || "or email to") }),
2684
+ " ",
2685
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2686
+ import_react_native5.Text,
2687
+ {
2688
+ style: [
2689
+ styles2.link,
2690
+ { color: linkColor },
2691
+ activeTTSSegmentKey === "dpo-grievance-email" ? styles2.ttsHighlight : null
2692
+ ],
2693
+ onPress: () => import_react_native5.Linking.openURL(`mailto:${dpo.grievance_email}`),
2694
+ children: dpo.grievance_email
2695
+ }
2696
+ )
2697
+ ] }) : null,
2698
+ "\n"
2699
+ ] }) : null,
2700
+ (dpo == null ? void 0 : dpo.dp_board_text) ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
2701
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native5.Text, { style: activeTTSSegmentKey === "dpo-dp-board-text" ? styles2.ttsHighlight : null, children: [
2702
+ getT("dp_board_text", dpo.dp_board_text),
2703
+ " "
2704
+ ] }),
2705
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2706
+ import_react_native5.Text,
2707
+ {
2708
+ style: [
2709
+ styles2.link,
2710
+ { color: linkColor },
2711
+ activeTTSSegmentKey === "dpo-dp-board-link" ? styles2.ttsHighlight : null
2712
+ ],
2713
+ onPress: () => import_react_native5.Linking.openURL(dpo.dp_board_url),
2714
+ children: getT("dp_board_anchor_text", dpo.dp_board_anchor_text)
2715
+ }
2716
+ ),
2717
+ "\n"
2718
+ ] }) : null,
2719
+ (dpo == null ? void 0 : dpo.dpo_text) ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
2720
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native5.Text, { style: activeTTSSegmentKey === "dpo-dpo-text" ? styles2.ttsHighlight : null, children: [
2721
+ getT("dpo_text", dpo.dpo_text),
2722
+ " "
2723
+ ] }),
2724
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2725
+ import_react_native5.Text,
2726
+ {
2727
+ style: [
2728
+ styles2.link,
2729
+ { color: linkColor },
2730
+ activeTTSSegmentKey === "dpo-dpo-link" ? styles2.ttsHighlight : null
2731
+ ],
2732
+ onPress: () => import_react_native5.Linking.openURL(dpo.dpo_url),
2733
+ children: getT("dpo_anchor_text", dpo.dpo_anchor_text)
2734
+ }
2735
+ )
2736
+ ] }) : null
2737
+ ] }) });
2738
+ })() : null
1629
2739
  ] }),
1630
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.View, { style: styles2.bottomSection, children: isReviewMode ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1631
- import_react_native4.TouchableOpacity,
2740
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native5.View, { style: styles2.bottomSection, children: isReviewMode ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2741
+ import_react_native5.TouchableOpacity,
1632
2742
  {
1633
2743
  style: [styles2.button, styles2.acceptButton, acceptButtonStyle],
1634
2744
  onPress: () => setIsReviewMode(false),
1635
- children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.Text, { style: [styles2.buttonText, styles2.acceptButtonText, acceptButtonTextStyle], children: reviewModeButtonText || "Update Consent" })
2745
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native5.Text, { style: [styles2.buttonText, styles2.acceptButtonText, acceptButtonTextStyle], children: reviewModeButtonText || "Update Consent" })
1636
2746
  }
1637
- ) : /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
1638
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1639
- import_react_native4.TouchableOpacity,
2747
+ ) : /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
2748
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2749
+ import_react_native5.TouchableOpacity,
1640
2750
  {
1641
2751
  style: [
1642
2752
  styles2.button,
1643
2753
  styles2.acceptButton,
1644
2754
  acceptButtonStyle,
1645
- isSubmitting ? { opacity: 0.6 } : null
2755
+ isSubmitting || !areAllRequiredElementsChecked ? { opacity: 0.5 } : null
1646
2756
  ],
1647
2757
  onPress: handleAccept,
1648
- disabled: isSubmitting,
2758
+ disabled: isSubmitting || !areAllRequiredElementsChecked,
1649
2759
  accessibilityLabel: isSubmitting ? "Submitting consent" : getTranslatedText("confirm_button_text", (activeConfig == null ? void 0 : activeConfig.confirm_button_text) || "Accept"),
1650
- children: isSubmitting ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.ActivityIndicator, { size: "small", color: ((_s = (_r = settings == null ? void 0 : settings.button) == null ? void 0 : _r.accept) == null ? void 0 : _s.textColor) || "#ffffff" }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.Text, { style: [styles2.buttonText, styles2.acceptButtonText, acceptButtonTextStyle], children: getTranslatedText("confirm_button_text", (activeConfig == null ? void 0 : activeConfig.confirm_button_text) || "Accept") })
2760
+ children: isSubmitting ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native5.ActivityIndicator, { size: "small", color: acceptTextColor }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2761
+ import_react_native5.Text,
2762
+ {
2763
+ style: [
2764
+ styles2.buttonText,
2765
+ styles2.acceptButtonText,
2766
+ acceptButtonTextStyle,
2767
+ activeTTSSegmentKey === "confirm_button_text" ? styles2.ttsHighlight : null
2768
+ ],
2769
+ children: getTranslatedText("confirm_button_text", (activeConfig == null ? void 0 : activeConfig.confirm_button_text) || "Accept")
2770
+ }
2771
+ )
1651
2772
  }
1652
2773
  ),
1653
- !blockUI && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1654
- import_react_native4.TouchableOpacity,
2774
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2775
+ import_react_native5.TouchableOpacity,
1655
2776
  {
1656
- style: [styles2.button, styles2.cancelButton, declineButtonStyle],
2777
+ style: [styles2.button, styles2.cancelButton, declineButtonStyle, isSubmitting ? { opacity: 0.5 } : null],
1657
2778
  onPress: handleDecline,
1658
2779
  disabled: isSubmitting,
1659
2780
  accessibilityLabel: getTranslatedText("decline_button_text", (activeConfig == null ? void 0 : activeConfig.decline_button_text) || "Decline"),
1660
- children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native4.Text, { style: [styles2.buttonText, styles2.cancelButtonText, declineButtonTextStyle], children: getTranslatedText("decline_button_text", (activeConfig == null ? void 0 : activeConfig.decline_button_text) || "Decline") })
2781
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2782
+ import_react_native5.Text,
2783
+ {
2784
+ style: [
2785
+ styles2.buttonText,
2786
+ styles2.cancelButtonText,
2787
+ declineButtonTextStyle,
2788
+ activeTTSSegmentKey === "decline_button_text" ? styles2.ttsHighlight : null
2789
+ ],
2790
+ children: getTranslatedText("decline_button_text", (activeConfig == null ? void 0 : activeConfig.decline_button_text) || "Decline")
2791
+ }
2792
+ )
1661
2793
  }
1662
2794
  )
1663
2795
  ] }) })
@@ -1670,9 +2802,9 @@ var RedactoNoticeConsent = ({
1670
2802
  };
1671
2803
 
1672
2804
  // src/RedactoNoticeConsentInline/RedactoNoticeConsentInline.tsx
1673
- var import_react2 = require("react");
1674
- var import_react_native6 = require("react-native");
1675
- var import_react_native_svg3 = __toESM(require("react-native-svg"));
2805
+ var import_react3 = require("react");
2806
+ var import_react_native7 = require("react-native");
2807
+ var import_react_native_svg4 = __toESM(require("react-native-svg"));
1676
2808
 
1677
2809
  // src/RedactoNoticeConsentInline/api/index.ts
1678
2810
  var fetchConsentContent2 = async ({
@@ -1791,15 +2923,15 @@ var submitConsentEvent2 = async ({
1791
2923
  };
1792
2924
 
1793
2925
  // src/RedactoNoticeConsentInline/styles.ts
1794
- var import_react_native5 = require("react-native");
1795
- var styles3 = import_react_native5.StyleSheet.create({
2926
+ var import_react_native6 = require("react-native");
2927
+ var styles3 = import_react_native6.StyleSheet.create({
1796
2928
  container: {
1797
2929
  width: "100%",
1798
2930
  borderRadius: 8,
1799
2931
  backgroundColor: "#ffffff",
1800
2932
  borderWidth: 1,
1801
2933
  borderColor: "#e5e7eb",
1802
- ...import_react_native5.Platform.select({
2934
+ ...import_react_native6.Platform.select({
1803
2935
  ios: {
1804
2936
  shadowColor: "#000",
1805
2937
  shadowOffset: { width: 0, height: 1 },
@@ -1839,13 +2971,13 @@ var styles3 = import_react_native5.StyleSheet.create({
1839
2971
  fontWeight: "700",
1840
2972
  lineHeight: 27,
1841
2973
  letterSpacing: 0.2,
1842
- color: "#101828",
2974
+ color: "#323B4B",
1843
2975
  flexShrink: 1
1844
2976
  },
1845
2977
  topRight: {
1846
- borderRadius: 8,
1847
- paddingVertical: 3,
1848
- paddingHorizontal: 9,
2978
+ borderRadius: 6,
2979
+ paddingVertical: 6,
2980
+ paddingHorizontal: 10,
1849
2981
  borderWidth: 1,
1850
2982
  borderColor: "#d0d5dd",
1851
2983
  flexDirection: "row",
@@ -1854,8 +2986,8 @@ var styles3 = import_react_native5.StyleSheet.create({
1854
2986
  backgroundColor: "#ffffff"
1855
2987
  },
1856
2988
  topRightText: {
1857
- fontWeight: "400",
1858
- fontSize: 12,
2989
+ fontWeight: "500",
2990
+ fontSize: 13,
1859
2991
  color: "#344054"
1860
2992
  },
1861
2993
  middleSection: {
@@ -1878,7 +3010,7 @@ var styles3 = import_react_native5.StyleSheet.create({
1878
3010
  fontSize: 16,
1879
3011
  lineHeight: 24,
1880
3012
  letterSpacing: 0.2,
1881
- color: "#101828"
3013
+ color: "#323B4B"
1882
3014
  },
1883
3015
  optionsContainer: {
1884
3016
  gap: 14
@@ -1902,7 +3034,7 @@ var styles3 = import_react_native5.StyleSheet.create({
1902
3034
  fontSize: 16,
1903
3035
  lineHeight: 24,
1904
3036
  letterSpacing: 0.2,
1905
- color: "#101828"
3037
+ color: "#323B4B"
1906
3038
  },
1907
3039
  optionDescription: {
1908
3040
  fontWeight: "400",
@@ -1912,7 +3044,7 @@ var styles3 = import_react_native5.StyleSheet.create({
1912
3044
  color: "#475467"
1913
3045
  },
1914
3046
  dataElementsContainer: {
1915
- paddingLeft: 22,
3047
+ paddingLeft: 24,
1916
3048
  marginTop: 4
1917
3049
  },
1918
3050
  dataElementItem: {
@@ -1921,7 +3053,7 @@ var styles3 = import_react_native5.StyleSheet.create({
1921
3053
  gap: 10,
1922
3054
  justifyContent: "space-between",
1923
3055
  minHeight: 24,
1924
- paddingVertical: 2
3056
+ paddingVertical: 6
1925
3057
  },
1926
3058
  dataElementText: {
1927
3059
  fontWeight: "400",
@@ -2015,7 +3147,7 @@ var styles3 = import_react_native5.StyleSheet.create({
2015
3147
  minWidth: 120,
2016
3148
  maxHeight: 200,
2017
3149
  marginTop: 4,
2018
- ...import_react_native5.Platform.select({
3150
+ ...import_react_native6.Platform.select({
2019
3151
  ios: {
2020
3152
  shadowColor: "#000",
2021
3153
  shadowOffset: { width: 0, height: 2 },
@@ -2046,7 +3178,7 @@ var styles3 = import_react_native5.StyleSheet.create({
2046
3178
  });
2047
3179
 
2048
3180
  // src/RedactoNoticeConsentInline/RedactoNoticeConsentInline.tsx
2049
- var import_jsx_runtime3 = require("react/jsx-runtime");
3181
+ var import_jsx_runtime4 = require("react/jsx-runtime");
2050
3182
  var RedactoConsentInlineComponent = ({
2051
3183
  org_uuid,
2052
3184
  workspace_uuid,
@@ -2063,19 +3195,19 @@ var RedactoConsentInlineComponent = ({
2063
3195
  }) => {
2064
3196
  var _a, _b, _c, _d;
2065
3197
  const { isMobile } = useResponsive();
2066
- const [content, setContent] = (0, import_react2.useState)(null);
2067
- const [isLoading, setIsLoading] = (0, import_react2.useState)(true);
2068
- const [isSubmitting, setIsSubmitting] = (0, import_react2.useState)(false);
2069
- const [selectedLanguage, setSelectedLanguage] = (0, import_react2.useState)(language);
2070
- const [collapsedPurposes, setCollapsedPurposes] = (0, import_react2.useState)({});
2071
- const [selectedPurposes, setSelectedPurposes] = (0, import_react2.useState)({});
2072
- const [selectedDataElements, setSelectedDataElements] = (0, import_react2.useState)({});
2073
- const [hasAlreadyConsented, setHasAlreadyConsented] = (0, import_react2.useState)(false);
2074
- const [fetchError, setFetchError] = (0, import_react2.useState)(null);
2075
- const [errorMessage, setErrorMessage] = (0, import_react2.useState)(null);
2076
- const [isLanguageDropdownOpen, setIsLanguageDropdownOpen] = (0, import_react2.useState)(false);
2077
- const hasSubmittedRef = (0, import_react2.useRef)(false);
2078
- const getTranslatedText = (0, import_react2.useCallback)(
3198
+ const [content, setContent] = (0, import_react3.useState)(null);
3199
+ const [isLoading, setIsLoading] = (0, import_react3.useState)(true);
3200
+ const [isSubmitting, setIsSubmitting] = (0, import_react3.useState)(false);
3201
+ const [selectedLanguage, setSelectedLanguage] = (0, import_react3.useState)(language);
3202
+ const [collapsedPurposes, setCollapsedPurposes] = (0, import_react3.useState)({});
3203
+ const [selectedPurposes, setSelectedPurposes] = (0, import_react3.useState)({});
3204
+ const [selectedDataElements, setSelectedDataElements] = (0, import_react3.useState)({});
3205
+ const [hasAlreadyConsented, setHasAlreadyConsented] = (0, import_react3.useState)(false);
3206
+ const [fetchError, setFetchError] = (0, import_react3.useState)(null);
3207
+ const [errorMessage, setErrorMessage] = (0, import_react3.useState)(null);
3208
+ const [isLanguageDropdownOpen, setIsLanguageDropdownOpen] = (0, import_react3.useState)(false);
3209
+ const hasSubmittedRef = (0, import_react3.useRef)(false);
3210
+ const getTranslatedText = (0, import_react3.useCallback)(
2079
3211
  (key, defaultText, itemId) => {
2080
3212
  var _a2, _b2, _c2;
2081
3213
  if (!content) return defaultText;
@@ -2108,7 +3240,7 @@ var RedactoConsentInlineComponent = ({
2108
3240
  },
2109
3241
  [content, selectedLanguage]
2110
3242
  );
2111
- const areAllRequiredElementsChecked = (0, import_react2.useMemo)(() => {
3243
+ const areAllRequiredElementsChecked = (0, import_react3.useMemo)(() => {
2112
3244
  if (!content) return false;
2113
3245
  return content.purposes.every((purpose) => {
2114
3246
  const requiredElements = purpose.data_elements.filter((el) => el.required);
@@ -2117,16 +3249,16 @@ var RedactoConsentInlineComponent = ({
2117
3249
  );
2118
3250
  });
2119
3251
  }, [content, selectedDataElements]);
2120
- (0, import_react2.useEffect)(() => {
3252
+ (0, import_react3.useEffect)(() => {
2121
3253
  onValidationChange == null ? void 0 : onValidationChange(areAllRequiredElementsChecked);
2122
3254
  }, [areAllRequiredElementsChecked, onValidationChange]);
2123
3255
  const acceptDisabled = isSubmitting || !areAllRequiredElementsChecked || !accessToken;
2124
- (0, import_react2.useEffect)(() => {
3256
+ (0, import_react3.useEffect)(() => {
2125
3257
  if (hasAlreadyConsented) {
2126
3258
  onAccept == null ? void 0 : onAccept();
2127
3259
  }
2128
3260
  }, [hasAlreadyConsented, onAccept]);
2129
- const fetchNotice = (0, import_react2.useCallback)(async (signal) => {
3261
+ const fetchNotice = (0, import_react3.useCallback)(async (signal) => {
2130
3262
  setIsLoading(true);
2131
3263
  setFetchError(null);
2132
3264
  try {
@@ -2184,17 +3316,17 @@ var RedactoConsentInlineComponent = ({
2184
3316
  }
2185
3317
  }
2186
3318
  }, [org_uuid, workspace_uuid, notice_uuid, baseUrl, language, applicationId, onError]);
2187
- (0, import_react2.useEffect)(() => {
3319
+ (0, import_react3.useEffect)(() => {
2188
3320
  const controller = new AbortController();
2189
3321
  void fetchNotice(controller.signal);
2190
3322
  return () => {
2191
3323
  controller.abort();
2192
3324
  };
2193
3325
  }, [fetchNotice]);
2194
- const togglePurposeCollapse = (0, import_react2.useCallback)((purposeUuid) => {
3326
+ const togglePurposeCollapse = (0, import_react3.useCallback)((purposeUuid) => {
2195
3327
  setCollapsedPurposes((prev) => ({ ...prev, [purposeUuid]: !prev[purposeUuid] }));
2196
3328
  }, []);
2197
- const handlePurposeCheckboxChange = (0, import_react2.useCallback)(
3329
+ const handlePurposeCheckboxChange = (0, import_react3.useCallback)(
2198
3330
  (purposeUuid) => {
2199
3331
  if (!content) return;
2200
3332
  const purpose = content.purposes.find((p) => p.uuid === purposeUuid);
@@ -2211,7 +3343,7 @@ var RedactoConsentInlineComponent = ({
2211
3343
  },
2212
3344
  [content, selectedPurposes]
2213
3345
  );
2214
- const handleDataElementCheckboxChange = (0, import_react2.useCallback)(
3346
+ const handleDataElementCheckboxChange = (0, import_react3.useCallback)(
2215
3347
  (elementUuid, purposeUuid) => {
2216
3348
  if (!content) return;
2217
3349
  const purpose = content.purposes.find((p) => p.uuid === purposeUuid);
@@ -2227,7 +3359,7 @@ var RedactoConsentInlineComponent = ({
2227
3359
  },
2228
3360
  [content]
2229
3361
  );
2230
- const handleAcceptWithToken = (0, import_react2.useCallback)(
3362
+ const handleAcceptWithToken = (0, import_react3.useCallback)(
2231
3363
  async (tokenToUse) => {
2232
3364
  if (!tokenToUse || !content) {
2233
3365
  setErrorMessage("Unable to submit consent. Please try again.");
@@ -2285,7 +3417,7 @@ var RedactoConsentInlineComponent = ({
2285
3417
  onAccept
2286
3418
  ]
2287
3419
  );
2288
- (0, import_react2.useEffect)(() => {
3420
+ (0, import_react3.useEffect)(() => {
2289
3421
  if (accessToken && content && areAllRequiredElementsChecked && !isSubmitting && !hasSubmittedRef.current) {
2290
3422
  hasSubmittedRef.current = true;
2291
3423
  const autoSubmit = async () => {
@@ -2299,32 +3431,33 @@ var RedactoConsentInlineComponent = ({
2299
3431
  autoSubmit();
2300
3432
  }
2301
3433
  }, [accessToken, content, areAllRequiredElementsChecked, isSubmitting, handleAcceptWithToken, onError]);
2302
- (0, import_react2.useEffect)(() => {
3434
+ (0, import_react3.useEffect)(() => {
2303
3435
  if (!accessToken) {
2304
3436
  hasSubmittedRef.current = false;
2305
3437
  }
2306
3438
  }, [accessToken]);
2307
- const headingColor = (settings == null ? void 0 : settings.headingColor) || "#101828";
3439
+ const headingColor = (settings == null ? void 0 : settings.headingColor) || "#323B4B";
2308
3440
  const textColor = (settings == null ? void 0 : settings.textColor) || "#344054";
2309
- const supportedLanguages = (0, import_react2.useMemo)(
3441
+ const inlineAccentColor = (content == null ? void 0 : content.primary_color) || "#4f87ff";
3442
+ const supportedLanguages = (0, import_react3.useMemo)(
2310
3443
  () => Object.keys((content == null ? void 0 : content.supported_languages_and_translations) || {}),
2311
3444
  [content]
2312
3445
  );
2313
3446
  if (hasAlreadyConsented || fetchError) return null;
2314
3447
  if (isLoading) {
2315
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native6.View, { style: styles3.loadingContainer, children: [
2316
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native6.ActivityIndicator, { size: "large", color: "#4f87ff" }),
2317
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native6.Text, { style: [styles3.loadingText, { color: textColor }], children: "Loading..." })
3448
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react_native7.View, { style: styles3.loadingContainer, children: [
3449
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native7.ActivityIndicator, { size: "large", color: "#4f87ff" }),
3450
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native7.Text, { style: [styles3.loadingText, { color: textColor }], children: "Loading..." })
2318
3451
  ] });
2319
3452
  }
2320
3453
  if (!content) return null;
2321
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native6.View, { style: { gap: 16 }, children: [
2322
- errorMessage ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native6.View, { style: styles3.errorContainer, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native6.Text, { style: styles3.errorText, children: errorMessage }) }) : null,
2323
- supportedLanguages.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native6.View, { style: [styles3.topSection, { borderBottomWidth: 0, paddingBottom: 0 }], children: [
2324
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native6.View, {}),
2325
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native6.View, { style: styles3.languageSelectorContainer, children: [
2326
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
2327
- import_react_native6.TouchableOpacity,
3454
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react_native7.View, { style: { gap: 16 }, children: [
3455
+ errorMessage ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native7.View, { style: styles3.errorContainer, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native7.Text, { style: styles3.errorText, children: errorMessage }) }) : null,
3456
+ supportedLanguages.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react_native7.View, { style: [styles3.topSection, { borderBottomWidth: 0, paddingBottom: 0 }], children: [
3457
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native7.View, {}),
3458
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react_native7.View, { style: styles3.languageSelectorContainer, children: [
3459
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
3460
+ import_react_native7.TouchableOpacity,
2328
3461
  {
2329
3462
  style: [
2330
3463
  styles3.topRight,
@@ -2332,9 +3465,9 @@ var RedactoConsentInlineComponent = ({
2332
3465
  ],
2333
3466
  onPress: () => setIsLanguageDropdownOpen((v) => !v),
2334
3467
  children: [
2335
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native6.Text, { style: [styles3.topRightText, ((_b = settings == null ? void 0 : settings.button) == null ? void 0 : _b.language) ? { color: settings.button.language.textColor } : null], children: selectedLanguage }),
2336
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native_svg3.default, { width: 12, height: 12, viewBox: "0 0 16 16", fill: "none", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2337
- import_react_native_svg3.Path,
3468
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native7.Text, { style: [styles3.topRightText, ((_b = settings == null ? void 0 : settings.button) == null ? void 0 : _b.language) ? { color: settings.button.language.textColor } : null], children: selectedLanguage }),
3469
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native_svg4.default, { width: 12, height: 12, viewBox: "0 0 16 16", fill: "none", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
3470
+ import_react_native_svg4.Path,
2338
3471
  {
2339
3472
  d: "M4 6L8 10L12 6",
2340
3473
  stroke: ((_d = (_c = settings == null ? void 0 : settings.button) == null ? void 0 : _c.language) == null ? void 0 : _d.textColor) || "#344054",
@@ -2346,8 +3479,8 @@ var RedactoConsentInlineComponent = ({
2346
3479
  ]
2347
3480
  }
2348
3481
  ),
2349
- isLanguageDropdownOpen && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native6.View, { style: styles3.languageDropdown, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native6.ScrollView, { children: supportedLanguages.map((lang) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2350
- import_react_native6.TouchableOpacity,
3482
+ isLanguageDropdownOpen && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native7.View, { style: styles3.languageDropdown, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native7.ScrollView, { children: supportedLanguages.map((lang) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
3483
+ import_react_native7.TouchableOpacity,
2351
3484
  {
2352
3485
  style: [
2353
3486
  styles3.languageItem,
@@ -2357,24 +3490,24 @@ var RedactoConsentInlineComponent = ({
2357
3490
  setSelectedLanguage(lang);
2358
3491
  setIsLanguageDropdownOpen(false);
2359
3492
  },
2360
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native6.Text, { style: [styles3.languageItemText, lang === selectedLanguage ? styles3.selectedLanguageItemText : null], children: lang })
3493
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native7.Text, { style: [styles3.languageItemText, lang === selectedLanguage ? styles3.selectedLanguageItemText : null], children: lang })
2361
3494
  },
2362
3495
  lang
2363
3496
  )) }) })
2364
3497
  ] })
2365
3498
  ] }),
2366
- content.purposes.map((purpose) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native6.View, { children: [
2367
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native6.View, { style: styles3.optionItem, children: [
2368
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
2369
- import_react_native6.TouchableOpacity,
3499
+ content.purposes.map((purpose) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react_native7.View, { children: [
3500
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react_native7.View, { style: styles3.optionItem, children: [
3501
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
3502
+ import_react_native7.TouchableOpacity,
2370
3503
  {
2371
3504
  style: styles3.optionLeft,
2372
3505
  onPress: () => togglePurposeCollapse(purpose.uuid),
2373
3506
  accessibilityRole: "button",
2374
3507
  accessibilityLabel: `${collapsedPurposes[purpose.uuid] ? "Expand" : "Collapse"} ${getTranslatedText("purposes.name", purpose.name, purpose.uuid)}`,
2375
3508
  children: [
2376
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native6.View, { style: styles3.purposeChevron, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native_svg3.default, { width: 7, height: 12, viewBox: "0 0 7 12", fill: "none", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2377
- import_react_native_svg3.Path,
3509
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native7.View, { style: styles3.purposeChevron, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native_svg4.default, { width: 7, height: 12, viewBox: "0 0 7 12", fill: "none", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
3510
+ import_react_native_svg4.Path,
2378
3511
  {
2379
3512
  d: "M1 1L6 6L1 11",
2380
3513
  stroke: (settings == null ? void 0 : settings.headingColor) || "#323B4B",
@@ -2384,34 +3517,36 @@ var RedactoConsentInlineComponent = ({
2384
3517
  transform: !collapsedPurposes[purpose.uuid] ? "rotate(90 3.5 6)" : void 0
2385
3518
  }
2386
3519
  ) }) }),
2387
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native6.View, { style: styles3.optionTextContainer, children: [
2388
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native6.Text, { style: [styles3.optionTitle, { color: headingColor }, isMobile ? { fontSize: 14 } : null], children: getTranslatedText("purposes.name", purpose.name, purpose.uuid) }),
2389
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native6.Text, { style: [styles3.optionDescription, { color: textColor }, isMobile ? { fontSize: 11 } : null], children: getTranslatedText("purposes.description", purpose.description, purpose.uuid) })
3520
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react_native7.View, { style: styles3.optionTextContainer, children: [
3521
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native7.Text, { style: [styles3.optionTitle, { color: headingColor }, isMobile ? { fontSize: 14 } : null], children: getTranslatedText("purposes.name", purpose.name, purpose.uuid) }),
3522
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native7.Text, { style: [styles3.optionDescription, { color: textColor }, isMobile ? { fontSize: 11 } : null], children: getTranslatedText("purposes.description", purpose.description, purpose.uuid) })
2390
3523
  ] })
2391
3524
  ]
2392
3525
  }
2393
3526
  ),
2394
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3527
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2395
3528
  Checkbox,
2396
3529
  {
2397
3530
  checked: selectedPurposes[purpose.uuid] || false,
2398
3531
  onChange: () => handlePurposeCheckboxChange(purpose.uuid),
2399
3532
  size: "large",
3533
+ accentColor: inlineAccentColor,
2400
3534
  accessibilityLabel: `Select all data elements for ${getTranslatedText("purposes.name", purpose.name, purpose.uuid)}`
2401
3535
  }
2402
3536
  )
2403
3537
  ] }),
2404
- !collapsedPurposes[purpose.uuid] && purpose.data_elements && purpose.data_elements.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native6.View, { style: styles3.dataElementsContainer, children: purpose.data_elements.map((dataElement) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native6.View, { style: styles3.dataElementItem, children: [
2405
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native6.Text, { style: [styles3.dataElementText, { color: textColor }, isMobile ? { fontSize: 12 } : null], children: [
3538
+ !collapsedPurposes[purpose.uuid] && purpose.data_elements && purpose.data_elements.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native7.View, { style: styles3.dataElementsContainer, children: purpose.data_elements.map((dataElement) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react_native7.View, { style: styles3.dataElementItem, children: [
3539
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react_native7.Text, { style: [styles3.dataElementText, { color: textColor }, isMobile ? { fontSize: 12 } : null], children: [
2406
3540
  getTranslatedText("data_elements.name", dataElement.name, dataElement.uuid),
2407
- dataElement.required && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native6.Text, { style: styles3.requiredAsterisk, children: " *" })
3541
+ dataElement.required && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native7.Text, { style: styles3.requiredAsterisk, children: " *" })
2408
3542
  ] }),
2409
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3543
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
2410
3544
  Checkbox,
2411
3545
  {
2412
3546
  checked: selectedDataElements[`${purpose.uuid}-${dataElement.uuid}`] || false,
2413
3547
  onChange: () => handleDataElementCheckboxChange(dataElement.uuid, purpose.uuid),
2414
3548
  size: "small",
3549
+ accentColor: inlineAccentColor,
2415
3550
  accessibilityLabel: `Select ${getTranslatedText("data_elements.name", dataElement.name, dataElement.uuid)}${dataElement.required ? " (required)" : ""}`
2416
3551
  }
2417
3552
  )
@@ -2420,7 +3555,7 @@ var RedactoConsentInlineComponent = ({
2420
3555
  ] });
2421
3556
  };
2422
3557
  RedactoConsentInlineComponent.displayName = "RedactoConsentInline";
2423
- var RedactoConsentInline = (0, import_react2.memo)(RedactoConsentInlineComponent);
3558
+ var RedactoConsentInline = (0, import_react3.memo)(RedactoConsentInlineComponent);
2424
3559
  // Annotate the CommonJS export names for ESM import in node:
2425
3560
  0 && (module.exports = {
2426
3561
  RedactoNoticeConsent,