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