@redacto.io/consent-sdk-react 10.2.2-beta.2 → 10.2.2-beta.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -792,6 +792,15 @@ var CONFIRM_DIALOG_COPY = {
792
792
  confirm: "Yes",
793
793
  cancel: "No"
794
794
  };
795
+ var OTP_GATE_LENGTH = 6;
796
+ var OTP_GATE_COPY = {
797
+ title: "Enter the verification code",
798
+ description: "Ask the customer to read out the code they were sent. Your selections are locked until it is confirmed.",
799
+ submit: "Confirm code",
800
+ verifying: "Verifying...",
801
+ failed: "Could not verify that code."
802
+ };
803
+ var PRODUCT_POLICIES_LABEL = "Privacy policies:";
795
804
 
796
805
  // src/RedactoNoticeConsent/styles.ts
797
806
  var styles = {
@@ -1186,6 +1195,65 @@ var styles = {
1186
1195
  textAlign: "center",
1187
1196
  fontFamily: "inherit"
1188
1197
  },
1198
+ otpGateLocked: {
1199
+ pointerEvents: "none",
1200
+ opacity: 0.55
1201
+ },
1202
+ otpGatePanel: {
1203
+ margin: "8px 0 4px",
1204
+ padding: "12px",
1205
+ border: "1px solid #e5e7eb",
1206
+ borderRadius: "8px",
1207
+ background: "#f9fafb"
1208
+ },
1209
+ otpGateTitle: {
1210
+ margin: 0,
1211
+ fontSize: "13px",
1212
+ fontWeight: 600,
1213
+ color: "#111827"
1214
+ },
1215
+ otpGateDescription: {
1216
+ margin: "4px 0 10px",
1217
+ fontSize: "12px",
1218
+ lineHeight: 1.4,
1219
+ color: "#6b7280"
1220
+ },
1221
+ otpGateDigits: {
1222
+ display: "flex",
1223
+ gap: "8px",
1224
+ justifyContent: "space-between"
1225
+ },
1226
+ otpGateDigit: {
1227
+ width: "100%",
1228
+ minWidth: 0,
1229
+ boxSizing: "border-box",
1230
+ padding: "10px 0",
1231
+ fontSize: "18px",
1232
+ fontWeight: 600,
1233
+ textAlign: "center",
1234
+ border: "1px solid #d1d5db",
1235
+ borderRadius: "8px",
1236
+ background: "#ffffff"
1237
+ },
1238
+ otpGateInput: {
1239
+ width: "100%",
1240
+ boxSizing: "border-box",
1241
+ padding: "8px 10px",
1242
+ fontSize: "16px",
1243
+ letterSpacing: "0.3em",
1244
+ textAlign: "center",
1245
+ border: "1px solid #d1d5db",
1246
+ borderRadius: "6px"
1247
+ },
1248
+ otpGateError: {
1249
+ margin: "8px 0 0",
1250
+ fontSize: "12px",
1251
+ color: "#dc2626"
1252
+ },
1253
+ otpGateButton: {
1254
+ width: "100%",
1255
+ marginTop: "10px"
1256
+ },
1189
1257
  acceptButton: {
1190
1258
  backgroundColor: "#4f87ff",
1191
1259
  border: "none",
@@ -3759,6 +3827,7 @@ var RedactoNoticeConsent = ({
3759
3827
  onAccept,
3760
3828
  onDecline,
3761
3829
  onError,
3830
+ otpGate,
3762
3831
  settings,
3763
3832
  applicationId,
3764
3833
  validateAgainst = "all",
@@ -3770,7 +3839,7 @@ var RedactoNoticeConsent = ({
3770
3839
  reviewModeButtonText = "Continue",
3771
3840
  defaultOpenProducts
3772
3841
  }) => {
3773
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y;
3842
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B;
3774
3843
  const sandboxParams = (0, import_react5.useMemo)(
3775
3844
  () => ({
3776
3845
  token,
@@ -3864,6 +3933,19 @@ var RedactoNoticeConsent = ({
3864
3933
  const [selfDeclaredAdult, setSelfDeclaredAdult] = (0, import_react5.useState)(false);
3865
3934
  const [showGuardianForm, setShowGuardianForm] = (0, import_react5.useState)(false);
3866
3935
  const [isSubmittingGuardian, setIsSubmittingGuardian] = (0, import_react5.useState)(false);
3936
+ const [otpPendingMode, setOtpPendingMode] = (0, import_react5.useState)(null);
3937
+ const otpVerifiedRef = (0, import_react5.useRef)(false);
3938
+ const otpTokenAtVerifyRef = (0, import_react5.useRef)(void 0);
3939
+ const [otpAcceptAfterToken, setOtpAcceptAfterToken] = (0, import_react5.useState)(null);
3940
+ const [otpCode, setOtpCode] = (0, import_react5.useState)("");
3941
+ const [otpError, setOtpError] = (0, import_react5.useState)(null);
3942
+ const [otpBusy, setOtpBusy] = (0, import_react5.useState)(false);
3943
+ const otpLocked = otpPendingMode !== null;
3944
+ const focusOtpDigit = (index) => {
3945
+ var _a2;
3946
+ if (index < 0 || index >= OTP_GATE_LENGTH) return;
3947
+ (_a2 = document.getElementById(`notice-otp-digit-${index}`)) == null ? void 0 : _a2.focus();
3948
+ };
3867
3949
  const [guardianFormData, setGuardianFormData] = (0, import_react5.useState)({
3868
3950
  guardianName: "",
3869
3951
  guardianContact: "",
@@ -4691,6 +4773,11 @@ var RedactoNoticeConsent = ({
4691
4773
  };
4692
4774
  const handleAccept = async (mode = "selected") => {
4693
4775
  const submitController = new AbortController();
4776
+ if ((otpGate == null ? void 0 : otpGate.required) && !otpVerifiedRef.current) {
4777
+ setOtpPendingMode(mode);
4778
+ setOtpError(null);
4779
+ return;
4780
+ }
4694
4781
  try {
4695
4782
  if (isMinorFlow && !verificationReference) {
4696
4783
  setErrorMessage(
@@ -5614,6 +5701,58 @@ var RedactoNoticeConsent = ({
5614
5701
  (content == null ? void 0 : content.decline_button_text) || DEFAULT_DECLINE_BUTTON_TEXT
5615
5702
  )
5616
5703
  };
5704
+ const handleOtpConfirm = async () => {
5705
+ var _a2;
5706
+ if (!otpGate || otpCode.length !== OTP_GATE_LENGTH) {
5707
+ return;
5708
+ }
5709
+ setOtpBusy(true);
5710
+ setOtpError(null);
5711
+ const result = await otpGate.onVerify(otpCode);
5712
+ if (!result.ok) {
5713
+ setOtpError((_a2 = result.message) != null ? _a2 : OTP_GATE_COPY.failed);
5714
+ setOtpCode("");
5715
+ setOtpBusy(false);
5716
+ return;
5717
+ }
5718
+ const mode = otpPendingMode != null ? otpPendingMode : "selected";
5719
+ otpVerifiedRef.current = true;
5720
+ setOtpPendingMode(null);
5721
+ setOtpBusy(false);
5722
+ otpTokenAtVerifyRef.current = accessToken;
5723
+ setOtpAcceptAfterToken(mode);
5724
+ };
5725
+ (0, import_react5.useEffect)(() => {
5726
+ if (!otpAcceptAfterToken) {
5727
+ return;
5728
+ }
5729
+ if (accessToken === otpTokenAtVerifyRef.current) {
5730
+ return;
5731
+ }
5732
+ const mode = otpAcceptAfterToken;
5733
+ setOtpAcceptAfterToken(null);
5734
+ void handleAccept(mode);
5735
+ }, [accessToken, otpAcceptAfterToken]);
5736
+ const productPolicyLinks = (0, import_react5.useMemo)(() => {
5737
+ var _a2;
5738
+ const policies = content == null ? void 0 : content.product_privacy_policies;
5739
+ if (!policies) {
5740
+ return [];
5741
+ }
5742
+ return ((_a2 = content == null ? void 0 : content.products) != null ? _a2 : []).filter((product) => Boolean(policies[product.uuid])).map((product) => ({
5743
+ uuid: product.uuid,
5744
+ name: product.name,
5745
+ url: policies[product.uuid]
5746
+ }));
5747
+ }, [content]);
5748
+ const showNoticePolicyLink = (0, import_react5.useMemo)(() => {
5749
+ var _a2;
5750
+ const products = (_a2 = content == null ? void 0 : content.products) != null ? _a2 : [];
5751
+ if (productPolicyLinks.length === 0 || products.length === 0) {
5752
+ return true;
5753
+ }
5754
+ return productPolicyLinks.length < products.length;
5755
+ }, [content, productPolicyLinks]);
5617
5756
  const handleAcceptAll = () => handleAccept("all");
5618
5757
  const handleAcceptSelected = () => handleAccept("selected");
5619
5758
  const linkStyle = {
@@ -6224,8 +6363,8 @@ var RedactoNoticeConsent = ({
6224
6363
  },
6225
6364
  `privacy-notice-text-${selectedLanguage}`
6226
6365
  ),
6227
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("br", {}),
6228
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
6366
+ showNoticePolicyLink && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("br", {}),
6367
+ showNoticePolicyLink && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
6229
6368
  "span",
6230
6369
  {
6231
6370
  id: "privacy-policy-text",
@@ -6274,10 +6413,33 @@ var RedactoNoticeConsent = ({
6274
6413
  },
6275
6414
  `purpose-section-heading-${selectedLanguage}`
6276
6415
  ),
6277
- categorizedPurposes && !isMultiProduct(content == null ? void 0 : content.products) ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: styles.optionsContainer, children: soleProductSection(
6278
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
6279
- categorizedPurposes.alreadyConsented.map(
6280
- (purpose) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
6416
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { style: otpLocked ? styles.otpGateLocked : void 0, children: [
6417
+ categorizedPurposes && !isMultiProduct(content == null ? void 0 : content.products) ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: styles.optionsContainer, children: soleProductSection(
6418
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
6419
+ categorizedPurposes.alreadyConsented.map(
6420
+ (purpose) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
6421
+ PurposeItem,
6422
+ {
6423
+ purpose,
6424
+ selectedPurposes,
6425
+ collapsedPurposes,
6426
+ selectedDataElements,
6427
+ recordedAnswers,
6428
+ settings,
6429
+ styles,
6430
+ responsiveStyles,
6431
+ onPurposeToggle: handlePurposeCheckboxChange,
6432
+ onPurposeCollapse: togglePurposeCollapse,
6433
+ onDataElementToggle: handleDataElementCheckboxChange,
6434
+ getTranslatedText,
6435
+ isAlreadyConsented: true,
6436
+ selectedLanguage,
6437
+ initialDataElementSelections
6438
+ },
6439
+ `${purpose.uuid}-${selectedLanguage}`
6440
+ )
6441
+ ),
6442
+ categorizedPurposes.needsConsent.map((purpose) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
6281
6443
  PurposeItem,
6282
6444
  {
6283
6445
  purpose,
@@ -6292,246 +6454,247 @@ var RedactoNoticeConsent = ({
6292
6454
  onPurposeCollapse: togglePurposeCollapse,
6293
6455
  onDataElementToggle: handleDataElementCheckboxChange,
6294
6456
  getTranslatedText,
6295
- isAlreadyConsented: true,
6296
- selectedLanguage,
6297
- initialDataElementSelections
6457
+ isAlreadyConsented: false,
6458
+ selectedLanguage
6298
6459
  },
6299
6460
  `${purpose.uuid}-${selectedLanguage}`
6300
- )
6301
- ),
6302
- categorizedPurposes.needsConsent.map((purpose) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
6303
- PurposeItem,
6304
- {
6305
- purpose,
6306
- selectedPurposes,
6307
- collapsedPurposes,
6308
- selectedDataElements,
6309
- recordedAnswers,
6310
- settings,
6311
- styles,
6312
- responsiveStyles,
6313
- onPurposeToggle: handlePurposeCheckboxChange,
6314
- onPurposeCollapse: togglePurposeCollapse,
6315
- onDataElementToggle: handleDataElementCheckboxChange,
6316
- getTranslatedText,
6317
- isAlreadyConsented: false,
6318
- selectedLanguage
6319
- },
6320
- `${purpose.uuid}-${selectedLanguage}`
6321
- ))
6322
- ] })
6323
- ) }) : (
6324
- /* Regular consent UI */
6325
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: styles.optionsContainer, children: isMultiProduct(content == null ? void 0 : content.products) ? productGroups.map((group) => {
6326
- var _a2;
6327
- const boxPurposes = productBoxPurposes(
6328
- group.purposes
6329
- );
6330
- const selectedInGroup = boxPurposes.filter(
6331
- (purpose) => selectedPurposes[productPurposeKey(
6332
- group.product.uuid,
6333
- purpose.uuid
6334
- )]
6335
- ).length;
6336
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { children: [
6337
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
6338
- ProductSectionHeader,
6339
- {
6340
- product: group.product,
6341
- isRequired: productIsRequiredFor(
6342
- group.product.uuid
6343
- ),
6344
- purposeCount: boxPurposes.length,
6345
- requiredOnly: boxPurposes.length < group.purposes.length,
6346
- allSelected: selectedInGroup === boxPurposes.length,
6347
- someSelected: selectedInGroup > 0,
6348
- collapsed: collapsedProducts[group.product.uuid] || false,
6349
- locked: (_a2 = consentedProducts[group.product.uuid]) != null ? _a2 : false,
6350
- settings,
6351
- styles,
6352
- responsiveStyles,
6353
- onToggleCollapse: toggleProductCollapse,
6354
- onToggleSelect: handleProductCheckboxChange,
6355
- getTranslatedText
6356
- }
6357
- ),
6358
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
6359
- "div",
6360
- {
6361
- id: `product-${group.product.uuid}`,
6362
- style: styles.sectionBody,
6363
- hidden: collapsedProducts[group.product.uuid] || false,
6364
- children: group.purposes.map((purpose) => {
6365
- var _a3;
6366
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
6367
- PurposeItem,
6368
- {
6369
- purpose,
6370
- productUuid: group.product.uuid,
6371
- selectedPurposes,
6372
- collapsedPurposes,
6373
- selectedDataElements,
6374
- recordedAnswers,
6375
- settings,
6376
- styles,
6377
- responsiveStyles,
6378
- onPurposeToggle: handlePurposeCheckboxChange,
6379
- onPurposeCollapse: togglePurposeCollapse,
6380
- onDataElementToggle: handleDataElementCheckboxChange,
6381
- getTranslatedText,
6382
- isAlreadyConsented: (_a3 = consentedPurposes[productPurposeKey(
6383
- group.product.uuid,
6384
- purpose.uuid
6385
- )]) != null ? _a3 : false,
6386
- selectedLanguage,
6387
- initialDataElementSelections
6388
- },
6389
- `${group.product.uuid}-${purpose.uuid}-${selectedLanguage}`
6390
- );
6391
- })
6392
- }
6393
- )
6394
- ] }, group.product.uuid);
6395
- }) : soleProductSection(
6396
- (_y = content == null ? void 0 : content.purposes) == null ? void 0 : _y.map((purpose) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
6397
- PurposeItem,
6398
- {
6399
- purpose,
6400
- selectedPurposes,
6401
- collapsedPurposes,
6402
- selectedDataElements,
6403
- recordedAnswers,
6404
- settings,
6405
- styles,
6406
- responsiveStyles,
6407
- onPurposeToggle: handlePurposeCheckboxChange,
6408
- onPurposeCollapse: togglePurposeCollapse,
6409
- onDataElementToggle: handleDataElementCheckboxChange,
6410
- getTranslatedText,
6411
- isAlreadyConsented: isFullyConsentedReviewMode,
6412
- selectedLanguage,
6413
- initialDataElementSelections
6414
- },
6415
- `${purpose.uuid}-${selectedLanguage}`
6416
- ))
6417
- ) })
6418
- ),
6419
- ((content == null ? void 0 : content.privacy_center_url) || (content == null ? void 0 : content.dpo_info)) && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
6420
- "div",
6421
- {
6422
- style: {
6423
- ...styles.privacyText,
6424
- ...responsiveStyles.privacyText,
6425
- ...componentTextStyle,
6426
- fontSize: isMobile ? "13px" : "14px",
6427
- lineHeight: "1.4",
6428
- borderTop: "1px solid rgba(152, 162, 179, 0.3)",
6429
- paddingTop: "12px",
6430
- marginTop: "12px"
6431
- },
6432
- children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("p", { style: { margin: 0, opacity: 0.6 }, children: [
6433
- content.privacy_center_url && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
6434
- content.additional_text && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { id: "additional-text", children: getTranslatedText(
6435
- "additional_text",
6436
- content.additional_text
6437
- ) }),
6438
- " ",
6461
+ ))
6462
+ ] })
6463
+ ) }) : (
6464
+ /* Regular consent UI */
6465
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: styles.optionsContainer, children: isMultiProduct(content == null ? void 0 : content.products) ? productGroups.map((group) => {
6466
+ var _a2;
6467
+ const boxPurposes = productBoxPurposes(
6468
+ group.purposes
6469
+ );
6470
+ const selectedInGroup = boxPurposes.filter(
6471
+ (purpose) => selectedPurposes[productPurposeKey(
6472
+ group.product.uuid,
6473
+ purpose.uuid
6474
+ )]
6475
+ ).length;
6476
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { children: [
6439
6477
  /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
6440
- "a",
6478
+ ProductSectionHeader,
6441
6479
  {
6442
- id: "privacy-center-link",
6443
- style: { ...styles.link, ...linkStyle },
6444
- href: content.privacy_center_url,
6445
- target: "_blank",
6446
- rel: "noopener noreferrer",
6447
- children: getTranslatedText(
6448
- "privacy_center_anchor_text",
6449
- content.privacy_center_anchor_text || "Privacy Center"
6450
- )
6480
+ product: group.product,
6481
+ isRequired: productIsRequiredFor(
6482
+ group.product.uuid
6483
+ ),
6484
+ purposeCount: boxPurposes.length,
6485
+ requiredOnly: boxPurposes.length < group.purposes.length,
6486
+ allSelected: selectedInGroup === boxPurposes.length,
6487
+ someSelected: selectedInGroup > 0,
6488
+ collapsed: collapsedProducts[group.product.uuid] || false,
6489
+ locked: (_a2 = consentedProducts[group.product.uuid]) != null ? _a2 : false,
6490
+ settings,
6491
+ styles,
6492
+ responsiveStyles,
6493
+ onToggleCollapse: toggleProductCollapse,
6494
+ onToggleSelect: handleProductCheckboxChange,
6495
+ getTranslatedText
6451
6496
  }
6452
6497
  ),
6453
- "."
6454
- ] }),
6455
- content.dpo_info && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
6456
- content.privacy_center_url && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("br", {}),
6457
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { id: "dpo-grievance-text", children: getTranslatedDpoText(
6458
- "grievance_text",
6459
- content.dpo_info.grievance_text || ""
6460
- ) }),
6461
- " ",
6462
- content.dpo_info.grievance_url && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
6463
- "a",
6498
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
6499
+ "div",
6464
6500
  {
6465
- id: "dpo-grievance-link",
6466
- style: { ...styles.link, ...linkStyle },
6467
- href: content.dpo_info.grievance_url,
6468
- target: "_blank",
6469
- rel: "noopener noreferrer",
6470
- children: getTranslatedDpoText(
6471
- "grievance_anchor_text",
6472
- content.dpo_info.grievance_anchor_text || "click here"
6473
- )
6501
+ id: `product-${group.product.uuid}`,
6502
+ style: styles.sectionBody,
6503
+ hidden: collapsedProducts[group.product.uuid] || false,
6504
+ children: group.purposes.map((purpose) => {
6505
+ var _a3;
6506
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
6507
+ PurposeItem,
6508
+ {
6509
+ purpose,
6510
+ productUuid: group.product.uuid,
6511
+ selectedPurposes,
6512
+ collapsedPurposes,
6513
+ selectedDataElements,
6514
+ recordedAnswers,
6515
+ settings,
6516
+ styles,
6517
+ responsiveStyles,
6518
+ onPurposeToggle: handlePurposeCheckboxChange,
6519
+ onPurposeCollapse: togglePurposeCollapse,
6520
+ onDataElementToggle: handleDataElementCheckboxChange,
6521
+ getTranslatedText,
6522
+ isAlreadyConsented: (_a3 = consentedPurposes[productPurposeKey(
6523
+ group.product.uuid,
6524
+ purpose.uuid
6525
+ )]) != null ? _a3 : false,
6526
+ selectedLanguage,
6527
+ initialDataElementSelections
6528
+ },
6529
+ `${group.product.uuid}-${purpose.uuid}-${selectedLanguage}`
6530
+ );
6531
+ })
6474
6532
  }
6475
- ),
6476
- content.dpo_info.grievance_email && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
6477
- " ",
6478
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { id: "dpo-grievance-email-connector", children: getTranslatedDpoText(
6479
- "grievance_email_connector_text",
6480
- content.dpo_info.grievance_email_connector_text || "or email to"
6533
+ )
6534
+ ] }, group.product.uuid);
6535
+ }) : soleProductSection(
6536
+ (_y = content == null ? void 0 : content.purposes) == null ? void 0 : _y.map((purpose) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
6537
+ PurposeItem,
6538
+ {
6539
+ purpose,
6540
+ selectedPurposes,
6541
+ collapsedPurposes,
6542
+ selectedDataElements,
6543
+ recordedAnswers,
6544
+ settings,
6545
+ styles,
6546
+ responsiveStyles,
6547
+ onPurposeToggle: handlePurposeCheckboxChange,
6548
+ onPurposeCollapse: togglePurposeCollapse,
6549
+ onDataElementToggle: handleDataElementCheckboxChange,
6550
+ getTranslatedText,
6551
+ isAlreadyConsented: isFullyConsentedReviewMode,
6552
+ selectedLanguage,
6553
+ initialDataElementSelections
6554
+ },
6555
+ `${purpose.uuid}-${selectedLanguage}`
6556
+ ))
6557
+ ) })
6558
+ ),
6559
+ ((content == null ? void 0 : content.privacy_center_url) || (content == null ? void 0 : content.dpo_info)) && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
6560
+ "div",
6561
+ {
6562
+ style: {
6563
+ ...styles.privacyText,
6564
+ ...responsiveStyles.privacyText,
6565
+ ...componentTextStyle,
6566
+ fontSize: isMobile ? "13px" : "14px",
6567
+ lineHeight: "1.4",
6568
+ borderTop: "1px solid rgba(152, 162, 179, 0.3)",
6569
+ paddingTop: "12px",
6570
+ marginTop: "12px"
6571
+ },
6572
+ children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("p", { style: { margin: 0, opacity: 0.6 }, children: [
6573
+ content.privacy_center_url && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
6574
+ content.additional_text && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { id: "additional-text", children: getTranslatedText(
6575
+ "additional_text",
6576
+ content.additional_text
6481
6577
  ) }),
6482
6578
  " ",
6483
6579
  /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
6484
6580
  "a",
6485
6581
  {
6486
- id: "dpo-grievance-email",
6582
+ id: "privacy-center-link",
6487
6583
  style: { ...styles.link, ...linkStyle },
6488
- href: `mailto:${content.dpo_info.grievance_email}`,
6489
- children: content.dpo_info.grievance_email
6584
+ href: content.privacy_center_url,
6585
+ target: "_blank",
6586
+ rel: "noopener noreferrer",
6587
+ children: getTranslatedText(
6588
+ "privacy_center_anchor_text",
6589
+ content.privacy_center_anchor_text || "Privacy Center"
6590
+ )
6490
6591
  }
6491
- )
6592
+ ),
6593
+ "."
6492
6594
  ] }),
6493
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("br", {}),
6494
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { id: "dpo-dp-board-text", children: getTranslatedDpoText(
6495
- "dp_board_text",
6496
- content.dpo_info.dp_board_text || ""
6497
- ) }),
6498
- " ",
6499
- content.dpo_info.dp_board_url && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
6500
- "a",
6501
- {
6502
- id: "dpo-dp-board-link",
6503
- style: { ...styles.link, ...linkStyle },
6504
- href: content.dpo_info.dp_board_url,
6505
- target: "_blank",
6506
- rel: "noopener noreferrer",
6507
- children: getTranslatedDpoText(
6508
- "dp_board_anchor_text",
6509
- content.dpo_info.dp_board_anchor_text || "here"
6595
+ productPolicyLinks.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
6596
+ content.privacy_center_url && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("br", {}),
6597
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { id: "product-privacy-policies-label", children: getTranslatedText(
6598
+ "product_privacy_policies_label",
6599
+ PRODUCT_POLICIES_LABEL
6600
+ ) }),
6601
+ " ",
6602
+ productPolicyLinks.map((entry, index) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { children: [
6603
+ index > 0 && ", ",
6604
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
6605
+ "a",
6606
+ {
6607
+ id: `product-privacy-policy-${entry.uuid}`,
6608
+ style: { ...styles.link, ...linkStyle },
6609
+ href: entry.url,
6610
+ target: "_blank",
6611
+ rel: "noopener noreferrer",
6612
+ children: entry.name
6613
+ }
6510
6614
  )
6511
- }
6512
- ),
6513
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("br", {}),
6514
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { id: "dpo-dpo-text", children: getTranslatedDpoText(
6515
- "dpo_text",
6516
- content.dpo_info.dpo_text || ""
6517
- ) }),
6518
- " ",
6519
- content.dpo_info.dpo_email && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
6520
- "a",
6521
- {
6522
- id: "dpo-dpo-link",
6523
- style: { ...styles.link, ...linkStyle },
6524
- href: `mailto:${content.dpo_info.dpo_email}`,
6525
- children: getTranslatedDpoText(
6526
- "dpo_anchor_text",
6527
- content.dpo_info.dpo_anchor_text || "Click here"
6615
+ ] }, entry.uuid))
6616
+ ] }),
6617
+ content.dpo_info && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
6618
+ (content.privacy_center_url || productPolicyLinks.length > 0) && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("br", {}),
6619
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { id: "dpo-grievance-text", children: getTranslatedDpoText(
6620
+ "grievance_text",
6621
+ content.dpo_info.grievance_text || ""
6622
+ ) }),
6623
+ " ",
6624
+ content.dpo_info.grievance_url && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
6625
+ "a",
6626
+ {
6627
+ id: "dpo-grievance-link",
6628
+ style: { ...styles.link, ...linkStyle },
6629
+ href: content.dpo_info.grievance_url,
6630
+ target: "_blank",
6631
+ rel: "noopener noreferrer",
6632
+ children: getTranslatedDpoText(
6633
+ "grievance_anchor_text",
6634
+ content.dpo_info.grievance_anchor_text || "click here"
6635
+ )
6636
+ }
6637
+ ),
6638
+ content.dpo_info.grievance_email && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
6639
+ " ",
6640
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { id: "dpo-grievance-email-connector", children: getTranslatedDpoText(
6641
+ "grievance_email_connector_text",
6642
+ content.dpo_info.grievance_email_connector_text || "or email to"
6643
+ ) }),
6644
+ " ",
6645
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
6646
+ "a",
6647
+ {
6648
+ id: "dpo-grievance-email",
6649
+ style: { ...styles.link, ...linkStyle },
6650
+ href: `mailto:${content.dpo_info.grievance_email}`,
6651
+ children: content.dpo_info.grievance_email
6652
+ }
6528
6653
  )
6529
- }
6530
- )
6654
+ ] }),
6655
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("br", {}),
6656
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { id: "dpo-dp-board-text", children: getTranslatedDpoText(
6657
+ "dp_board_text",
6658
+ content.dpo_info.dp_board_text || ""
6659
+ ) }),
6660
+ " ",
6661
+ content.dpo_info.dp_board_url && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
6662
+ "a",
6663
+ {
6664
+ id: "dpo-dp-board-link",
6665
+ style: { ...styles.link, ...linkStyle },
6666
+ href: content.dpo_info.dp_board_url,
6667
+ target: "_blank",
6668
+ rel: "noopener noreferrer",
6669
+ children: getTranslatedDpoText(
6670
+ "dp_board_anchor_text",
6671
+ content.dpo_info.dp_board_anchor_text || "here"
6672
+ )
6673
+ }
6674
+ ),
6675
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("br", {}),
6676
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { id: "dpo-dpo-text", children: getTranslatedDpoText(
6677
+ "dpo_text",
6678
+ content.dpo_info.dpo_text || ""
6679
+ ) }),
6680
+ " ",
6681
+ content.dpo_info.dpo_email && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
6682
+ "a",
6683
+ {
6684
+ id: "dpo-dpo-link",
6685
+ style: { ...styles.link, ...linkStyle },
6686
+ href: `mailto:${content.dpo_info.dpo_email}`,
6687
+ children: getTranslatedDpoText(
6688
+ "dpo_anchor_text",
6689
+ content.dpo_info.dpo_anchor_text || "Click here"
6690
+ )
6691
+ }
6692
+ )
6693
+ ] })
6531
6694
  ] })
6532
- ] })
6533
- }
6534
- )
6695
+ }
6696
+ )
6697
+ ] })
6535
6698
  ]
6536
6699
  }
6537
6700
  ),
@@ -6544,6 +6707,72 @@ var RedactoNoticeConsent = ({
6544
6707
  children: confirmHint
6545
6708
  }
6546
6709
  ),
6710
+ otpLocked && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { style: styles.otpGatePanel, children: [
6711
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { style: styles.otpGateTitle, children: (_z = otpGate == null ? void 0 : otpGate.title) != null ? _z : OTP_GATE_COPY.title }),
6712
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { style: styles.otpGateDescription, children: (_A = otpGate == null ? void 0 : otpGate.description) != null ? _A : OTP_GATE_COPY.description }),
6713
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: styles.otpGateDigits, children: Array.from({ length: OTP_GATE_LENGTH }).map((_, i) => {
6714
+ var _a2;
6715
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
6716
+ "input",
6717
+ {
6718
+ id: `notice-otp-digit-${i}`,
6719
+ style: styles.otpGateDigit,
6720
+ inputMode: "numeric",
6721
+ autoComplete: i === 0 ? "one-time-code" : "off",
6722
+ maxLength: 1,
6723
+ value: (_a2 = otpCode[i]) != null ? _a2 : "",
6724
+ disabled: otpBusy,
6725
+ "aria-label": `Digit ${i + 1}`,
6726
+ onChange: (e) => {
6727
+ const digit = e.target.value.replace(/[^0-9]/g, "");
6728
+ if (!digit) return;
6729
+ const next = otpCode.split("");
6730
+ next[i] = digit[digit.length - 1];
6731
+ setOtpCode(next.join("").slice(0, OTP_GATE_LENGTH));
6732
+ focusOtpDigit(i + 1);
6733
+ },
6734
+ onKeyDown: (e) => {
6735
+ if (e.key !== "Backspace") return;
6736
+ e.preventDefault();
6737
+ const next = otpCode.split("");
6738
+ if (next[i]) {
6739
+ next[i] = "";
6740
+ setOtpCode(next.join(""));
6741
+ return;
6742
+ }
6743
+ next[i - 1] = "";
6744
+ setOtpCode(next.join(""));
6745
+ focusOtpDigit(i - 1);
6746
+ },
6747
+ onPaste: (e) => {
6748
+ e.preventDefault();
6749
+ const pasted = e.clipboardData.getData("text").replace(/[^0-9]/g, "").slice(0, OTP_GATE_LENGTH);
6750
+ if (!pasted) return;
6751
+ setOtpCode(pasted);
6752
+ focusOtpDigit(pasted.length - 1);
6753
+ }
6754
+ },
6755
+ `notice-otp-digit-${i}`
6756
+ );
6757
+ }) }),
6758
+ otpError && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { style: styles.otpGateError, children: otpError }),
6759
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
6760
+ "button",
6761
+ {
6762
+ type: "button",
6763
+ style: {
6764
+ ...styles.button,
6765
+ ...responsiveStyles.button,
6766
+ ...styles.acceptButton,
6767
+ ...acceptAllButtonStyle,
6768
+ ...styles.otpGateButton
6769
+ },
6770
+ onClick: handleOtpConfirm,
6771
+ disabled: otpBusy || otpCode.length !== OTP_GATE_LENGTH,
6772
+ children: otpBusy ? OTP_GATE_COPY.verifying : (_B = otpGate == null ? void 0 : otpGate.submitLabel) != null ? _B : OTP_GATE_COPY.submit
6773
+ }
6774
+ )
6775
+ ] }),
6547
6776
  /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
6548
6777
  "div",
6549
6778
  {