@redacto.io/consent-sdk-react 0.0.3 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -1,54 +1,114 @@
1
1
  // src/RedactoNoticeConsent/RedactoNoticeConsent.tsx
2
- import { useEffect as useEffect2, useMemo, useState as useState2, useRef } from "react";
2
+ import { useCallback, useEffect as useEffect2, useMemo, useRef, useState as useState2 } from "react";
3
3
 
4
4
  // src/RedactoNoticeConsent/api/index.ts
5
5
  import { jwtDecode } from "jwt-decode";
6
- var BASE_URL = "https://api.redacto.tech/consent";
6
+ var BASE_URL = "https://api.redacto.io/consent";
7
+ var apiCache = /* @__PURE__ */ new Map();
8
+ var CACHE_TTL = 5 * 60 * 1e3;
9
+ function getCachedData(key) {
10
+ const cached = apiCache.get(key);
11
+ if (cached && Date.now() - cached.timestamp < cached.ttl) {
12
+ return cached.data;
13
+ }
14
+ if (cached) {
15
+ apiCache.delete(key);
16
+ }
17
+ return null;
18
+ }
19
+ function setCachedData(key, data, ttl = CACHE_TTL) {
20
+ apiCache.set(key, { data, timestamp: Date.now(), ttl });
21
+ }
22
+ function decodeTokenSafely(token) {
23
+ try {
24
+ return jwtDecode(token);
25
+ } catch (error) {
26
+ console.warn("Failed to decode JWT token:", error);
27
+ return null;
28
+ }
29
+ }
30
+ var storage = {
31
+ getItem: (key) => {
32
+ if (typeof window !== "undefined") {
33
+ return localStorage.getItem(key);
34
+ }
35
+ return null;
36
+ }
37
+ };
38
+ var clearApiCache = () => {
39
+ apiCache.clear();
40
+ };
7
41
  var fetchConsentContent = async ({
8
42
  noticeId,
9
43
  accessToken,
10
44
  baseUrl,
11
45
  language = "en",
12
- specific_uuid
46
+ specific_uuid,
47
+ check_mode = "all",
48
+ signal
49
+ // AbortSignal for request cancellation
13
50
  }) => {
14
51
  try {
15
- const decodedToken = jwtDecode(accessToken);
16
- const ORGANISATION_UUID = decodedToken == null ? void 0 : decodedToken.organisation_uuid;
17
- const WORKSPACE_UUID = decodedToken == null ? void 0 : decodedToken.workspace_uuid;
52
+ if (!noticeId || !accessToken) {
53
+ throw new Error("noticeId and accessToken are required");
54
+ }
55
+ const decodedToken = decodeTokenSafely(accessToken);
56
+ if (!decodedToken) {
57
+ throw new Error("Invalid access token");
58
+ }
59
+ const { organisation_uuid: ORGANISATION_UUID, workspace_uuid: WORKSPACE_UUID } = decodedToken;
60
+ if (!ORGANISATION_UUID || !WORKSPACE_UUID) {
61
+ throw new Error("Invalid token: missing organization or workspace UUID");
62
+ }
18
63
  const apiBaseUrl = baseUrl || BASE_URL;
64
+ const cacheKey = `${accessToken}-${noticeId}-${check_mode}-${language}-${specific_uuid || ""}`;
65
+ if (check_mode === "all" && !specific_uuid) {
66
+ const cachedData = getCachedData(cacheKey);
67
+ if (cachedData) {
68
+ return cachedData;
69
+ }
70
+ }
19
71
  const url = new URL(
20
72
  `${apiBaseUrl}/public/organisations/${ORGANISATION_UUID}/workspaces/${WORKSPACE_UUID}/notices/${noticeId}`
21
73
  );
22
74
  if (specific_uuid) {
23
75
  url.searchParams.append("specific_uuid", specific_uuid);
24
76
  }
77
+ url.searchParams.append("check_mode", check_mode);
25
78
  const response = await fetch(url.toString(), {
26
79
  method: "GET",
27
80
  headers: {
28
81
  Authorization: `Bearer ${accessToken}`,
29
82
  "Accept-Language": language,
30
83
  "Content-Type": "application/json"
31
- }
84
+ },
85
+ signal
86
+ // Add abort signal for request cancellation
32
87
  });
33
- if (response.status === 401) {
34
- const error = new Error("Unauthorized");
35
- error.status = 401;
36
- throw error;
37
- }
38
- if (response.status === 409) {
39
- const error = new Error("User has already provided consent");
40
- error.status = 409;
41
- throw error;
42
- }
43
88
  if (!response.ok) {
44
- throw new Error(
45
- `Failed to fetch consent content: ${response.statusText}`
46
- );
89
+ let errorMessage = `Failed to fetch consent content: ${response.status} ${response.statusText}`;
90
+ if (response.status === 401) {
91
+ errorMessage = "Unauthorized: Invalid or expired token";
92
+ } else if (response.status === 403) {
93
+ errorMessage = "Forbidden: Access denied";
94
+ } else if (response.status === 404) {
95
+ errorMessage = "Notice not found";
96
+ } else if (response.status === 409) {
97
+ errorMessage = "User has already provided consent";
98
+ } else if (response.status >= 500) {
99
+ errorMessage = "Server error: Please try again later";
100
+ }
101
+ const error = new Error(errorMessage);
102
+ error.status = response.status;
103
+ throw error;
47
104
  }
48
105
  const data = await response.json();
106
+ if (check_mode === "all" && !specific_uuid) {
107
+ setCachedData(cacheKey, data);
108
+ }
49
109
  return data;
50
110
  } catch (error) {
51
- console.error("Error fetching consent content:", error);
111
+ console.error("Error fetching consent content:", error instanceof Error ? error.message : error);
52
112
  throw error;
53
113
  }
54
114
  };
@@ -58,35 +118,56 @@ var submitConsentEvent = async ({
58
118
  noticeUuid,
59
119
  purposes,
60
120
  declined,
61
- meta_data
121
+ meta_data,
122
+ signal
123
+ // AbortSignal for request cancellation
62
124
  }) => {
63
125
  try {
64
- const primaryEmail = localStorage.getItem("userEmail");
65
- const decodedToken = jwtDecode(accessToken);
66
- const ORGANISATION_UUID = decodedToken.organisation_uuid;
67
- const WORKSPACE_UUID = decodedToken.workspace_uuid;
126
+ if (!noticeUuid || !accessToken || !Array.isArray(purposes)) {
127
+ throw new Error("noticeUuid, accessToken, and purposes array are required");
128
+ }
129
+ const decodedToken = decodeTokenSafely(accessToken);
130
+ if (!decodedToken) {
131
+ throw new Error("Invalid access token");
132
+ }
133
+ const { organisation_uuid: ORGANISATION_UUID, workspace_uuid: WORKSPACE_UUID } = decodedToken;
134
+ if (!ORGANISATION_UUID || !WORKSPACE_UUID) {
135
+ throw new Error("Invalid token: missing organization or workspace UUID");
136
+ }
137
+ const primaryEmail = storage.getItem("userEmail");
138
+ const validatedPurposes = purposes.map((purpose) => {
139
+ if (!purpose.uuid || !purpose.name) {
140
+ throw new Error(`Invalid purpose data: missing uuid or name`);
141
+ }
142
+ return {
143
+ uuid: purpose.uuid,
144
+ name: purpose.name,
145
+ description: purpose.description || "",
146
+ industries: purpose.industries || "",
147
+ selected: Boolean(purpose.selected),
148
+ data_elements: (purpose.data_elements || []).map((element) => {
149
+ if (!element.uuid || !element.name) {
150
+ throw new Error(`Invalid data element: missing uuid or name`);
151
+ }
152
+ return {
153
+ uuid: element.uuid,
154
+ name: element.name,
155
+ enabled: Boolean(element.enabled),
156
+ required: Boolean(element.required),
157
+ selected: element.required ? true : Boolean(element.selected)
158
+ };
159
+ })
160
+ };
161
+ });
68
162
  const payload = {
69
163
  primary_email: primaryEmail || void 0,
70
164
  notice_uuid: noticeUuid,
71
165
  source: "WEB",
72
- declined,
166
+ declined: Boolean(declined),
73
167
  consents: {
74
- purposes: purposes.map((purpose) => ({
75
- uuid: purpose.uuid,
76
- name: purpose.name,
77
- description: purpose.description,
78
- industries: purpose.industries || "",
79
- selected: purpose.selected,
80
- data_elements: purpose.data_elements.map((element) => ({
81
- uuid: element.uuid,
82
- name: element.name,
83
- enabled: element.enabled,
84
- required: element.required,
85
- selected: element.required ? true : element.selected
86
- }))
87
- }))
168
+ purposes: validatedPurposes
88
169
  },
89
- meta_data
170
+ meta_data: meta_data ? { specific_uuid: meta_data.specific_uuid } : void 0
90
171
  };
91
172
  const apiBaseUrl = baseUrl || BASE_URL;
92
173
  const response = await fetch(
@@ -97,18 +178,213 @@ var submitConsentEvent = async ({
97
178
  Authorization: `Bearer ${accessToken}`,
98
179
  "Content-Type": "application/json"
99
180
  },
100
- body: JSON.stringify(payload)
181
+ body: JSON.stringify(payload),
182
+ signal
183
+ // Add abort signal for request cancellation
101
184
  }
102
185
  );
103
186
  if (!response.ok) {
104
- throw new Error(`Failed to submit consent event: ${response.statusText}`);
187
+ let errorMessage = `Failed to submit consent: ${response.status} ${response.statusText}`;
188
+ if (response.status === 400) {
189
+ errorMessage = "Invalid request data";
190
+ } else if (response.status === 401) {
191
+ errorMessage = "Unauthorized: Invalid or expired token";
192
+ } else if (response.status === 403) {
193
+ errorMessage = "Forbidden: Access denied";
194
+ } else if (response.status === 404) {
195
+ errorMessage = "Notice not found";
196
+ } else if (response.status >= 500) {
197
+ errorMessage = "Server error: Please try again later";
198
+ }
199
+ const error = new Error(errorMessage);
200
+ error.status = response.status;
201
+ throw error;
105
202
  }
203
+ apiCache.clear();
106
204
  } catch (error) {
107
- console.error("Error submitting consent event:", error);
205
+ console.error("Error submitting consent event:", error instanceof Error ? error.message : error);
206
+ throw error;
207
+ }
208
+ };
209
+ var submitGuardianInfo = async ({
210
+ accessToken,
211
+ baseUrl,
212
+ guardianName,
213
+ guardianContact,
214
+ guardianRelationship,
215
+ signal
216
+ // AbortSignal for request cancellation
217
+ }) => {
218
+ try {
219
+ if (!accessToken) {
220
+ throw new Error("accessToken is required");
221
+ }
222
+ if (!(guardianName == null ? void 0 : guardianName.trim())) {
223
+ throw new Error("guardianName is required and cannot be empty");
224
+ }
225
+ if (!(guardianContact == null ? void 0 : guardianContact.trim())) {
226
+ throw new Error("guardianContact is required and cannot be empty");
227
+ }
228
+ if (!(guardianRelationship == null ? void 0 : guardianRelationship.trim())) {
229
+ throw new Error("guardianRelationship is required and cannot be empty");
230
+ }
231
+ const decodedToken = decodeTokenSafely(accessToken);
232
+ if (!decodedToken) {
233
+ throw new Error("Invalid access token");
234
+ }
235
+ const { organisation_uuid: ORGANISATION_UUID, workspace_uuid: WORKSPACE_UUID } = decodedToken;
236
+ if (!ORGANISATION_UUID || !WORKSPACE_UUID) {
237
+ throw new Error("Invalid token: missing organization or workspace UUID");
238
+ }
239
+ const payload = {
240
+ guardian_name: guardianName.trim(),
241
+ guardian_contact: guardianContact.trim(),
242
+ guardian_relationship: guardianRelationship.trim()
243
+ };
244
+ const apiBaseUrl = baseUrl || BASE_URL;
245
+ const response = await fetch(
246
+ `${apiBaseUrl}/public/organisations/${ORGANISATION_UUID}/workspaces/${WORKSPACE_UUID}/guardian-info`,
247
+ {
248
+ method: "POST",
249
+ headers: {
250
+ Authorization: `Bearer ${accessToken}`,
251
+ "Content-Type": "application/json"
252
+ },
253
+ body: JSON.stringify(payload),
254
+ signal
255
+ // Add abort signal for request cancellation
256
+ }
257
+ );
258
+ if (!response.ok) {
259
+ let errorMessage = `Failed to submit guardian info: ${response.status} ${response.statusText}`;
260
+ if (response.status === 400) {
261
+ errorMessage = "Invalid request data";
262
+ } else if (response.status === 401) {
263
+ errorMessage = "Unauthorized: Invalid or expired token";
264
+ } else if (response.status === 403) {
265
+ errorMessage = "Forbidden: Access denied";
266
+ } else if (response.status === 404) {
267
+ errorMessage = "Organization or workspace not found";
268
+ } else if (response.status === 422) {
269
+ try {
270
+ const errorData = await response.json();
271
+ errorMessage = errorData.message || "Validation error";
272
+ } catch (parseError) {
273
+ errorMessage = "Validation error: Please check your input";
274
+ }
275
+ } else if (response.status >= 500) {
276
+ errorMessage = "Server error: Please try again later";
277
+ }
278
+ const error = new Error(errorMessage);
279
+ error.status = response.status;
280
+ throw error;
281
+ }
282
+ } catch (error) {
283
+ console.error("Error submitting guardian info:", error instanceof Error ? error.message : error);
108
284
  throw error;
109
285
  }
110
286
  };
111
287
 
288
+ // src/RedactoNoticeConsent/assets/redacto-logo.png
289
+ var redacto_logo_default = "data:image/png;base64,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";
290
+
291
+ // src/RedactoNoticeConsent/injectStyles.ts
292
+ var stylesInjected = false;
293
+ var injectCheckboxStyles = () => {
294
+ if (stylesInjected || typeof document === "undefined") {
295
+ return;
296
+ }
297
+ const STYLE_ID = "redacto-consent-checkbox-styles";
298
+ if (document.getElementById(STYLE_ID)) {
299
+ stylesInjected = true;
300
+ return;
301
+ }
302
+ const style = document.createElement("style");
303
+ style.id = STYLE_ID;
304
+ style.textContent = `
305
+ /* Redacto Consent SDK Checkbox Styles */
306
+ .redacto-checkbox-large {
307
+ appearance: none !important;
308
+ -webkit-appearance: none !important;
309
+ -moz-appearance: none !important;
310
+ height: 20px !important;
311
+ width: 20px !important;
312
+ border: 2px solid #d0d5dd !important;
313
+ border-radius: 5px !important;
314
+ background-color: transparent !important;
315
+ cursor: pointer !important;
316
+ position: relative !important;
317
+ box-sizing: border-box !important;
318
+ margin: 0 !important;
319
+ padding: 4px !important;
320
+ }
321
+
322
+ .redacto-checkbox-small {
323
+ appearance: none !important;
324
+ -webkit-appearance: none !important;
325
+ -moz-appearance: none !important;
326
+ height: 16px !important;
327
+ width: 16px !important;
328
+ border: 2px solid #d0d5dd !important;
329
+ border-radius: 5px !important;
330
+ background-color: transparent !important;
331
+ cursor: pointer !important;
332
+ position: relative !important;
333
+ box-sizing: border-box !important;
334
+ margin: 0 !important;
335
+ padding: 4px !important;
336
+ }
337
+
338
+ .redacto-checkbox-large:checked {
339
+ background-color: #4f87ff !important;
340
+ border-color: #4f87ff !important;
341
+ }
342
+
343
+ .redacto-checkbox-small:checked {
344
+ background-color: #4f87ff !important;
345
+ border-color: #4f87ff !important;
346
+ }
347
+
348
+ .redacto-checkbox-large:checked::after {
349
+ content: '' !important;
350
+ position: absolute !important;
351
+ left: 50% !important;
352
+ top: 50% !important;
353
+ transform: translate(-50%, -50%) rotate(45deg) !important;
354
+ width: 4px !important;
355
+ height: 8px !important;
356
+ border: solid white !important;
357
+ border-width: 0 2px 2px 0 !important;
358
+ box-sizing: border-box !important;
359
+ }
360
+
361
+ .redacto-checkbox-small:checked::after {
362
+ content: '' !important;
363
+ position: absolute !important;
364
+ left: 50% !important;
365
+ top: 50% !important;
366
+ transform: translate(-50%, -50%) rotate(45deg) !important;
367
+ width: 3px !important;
368
+ height: 6px !important;
369
+ border: solid white !important;
370
+ border-width: 0 1.5px 1.5px 0 !important;
371
+ box-sizing: border-box !important;
372
+ }
373
+
374
+ .redacto-checkbox-large:focus {
375
+ outline: 2px solid #4f87ff !important;
376
+ outline-offset: 2px !important;
377
+ }
378
+
379
+ .redacto-checkbox-small:focus {
380
+ outline: 2px solid #4f87ff !important;
381
+ outline-offset: 2px !important;
382
+ }
383
+ `;
384
+ document.head.appendChild(style);
385
+ stylesInjected = true;
386
+ };
387
+
112
388
  // src/RedactoNoticeConsent/styles.ts
113
389
  var styles = {
114
390
  overlay: {
@@ -259,7 +535,7 @@ var styles = {
259
535
  optionsContainer: {
260
536
  display: "flex",
261
537
  flexDirection: "column",
262
- gap: "14px",
538
+ gap: "10px",
263
539
  margin: 0,
264
540
  padding: 0,
265
541
  boxSizing: "border-box"
@@ -460,9 +736,6 @@ var styles = {
460
736
  }
461
737
  };
462
738
 
463
- // src/RedactoNoticeConsent/assets/redacto-logo.png
464
- var redacto_logo_default = "data:image/png;base64,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";
465
-
466
739
  // src/RedactoNoticeConsent/useMediaQuery.ts
467
740
  import { useState, useEffect } from "react";
468
741
  var useMediaQuery = (query) => {
@@ -490,1116 +763,2850 @@ var useMediaQuery = (query) => {
490
763
  return matches;
491
764
  };
492
765
 
493
- // src/RedactoNoticeConsent/injectStyles.ts
494
- var stylesInjected = false;
495
- var injectCheckboxStyles = () => {
496
- if (stylesInjected || typeof document === "undefined") {
497
- return;
498
- }
499
- const STYLE_ID = "redacto-consent-checkbox-styles";
500
- if (document.getElementById(STYLE_ID)) {
501
- stylesInjected = true;
502
- return;
503
- }
504
- const style = document.createElement("style");
505
- style.id = STYLE_ID;
506
- style.textContent = `
507
- /* Redacto Consent SDK Checkbox Styles */
508
- .redacto-checkbox-large {
509
- appearance: none !important;
510
- -webkit-appearance: none !important;
511
- -moz-appearance: none !important;
512
- height: 20px !important;
513
- width: 20px !important;
514
- border: 2px solid #d0d5dd !important;
515
- border-radius: 5px !important;
516
- background-color: transparent !important;
517
- cursor: pointer !important;
518
- position: relative !important;
519
- box-sizing: border-box !important;
520
- margin: 0 !important;
521
- padding: 4px !important;
522
- }
523
-
524
- .redacto-checkbox-small {
525
- appearance: none !important;
526
- -webkit-appearance: none !important;
527
- -moz-appearance: none !important;
528
- height: 16px !important;
529
- width: 16px !important;
530
- border: 2px solid #d0d5dd !important;
531
- border-radius: 5px !important;
532
- background-color: transparent !important;
533
- cursor: pointer !important;
534
- position: relative !important;
535
- box-sizing: border-box !important;
536
- margin: 0 !important;
537
- padding: 4px !important;
538
- }
539
-
540
- .redacto-checkbox-large:checked {
541
- background-color: #4f87ff !important;
542
- border-color: #4f87ff !important;
543
- }
544
-
545
- .redacto-checkbox-small:checked {
546
- background-color: #4f87ff !important;
547
- border-color: #4f87ff !important;
548
- }
549
-
550
- .redacto-checkbox-large:checked::after {
551
- content: '' !important;
552
- position: absolute !important;
553
- left: 50% !important;
554
- top: 50% !important;
555
- transform: translate(-50%, -50%) rotate(45deg) !important;
556
- width: 4px !important;
557
- height: 8px !important;
558
- border: solid white !important;
559
- border-width: 0 2px 2px 0 !important;
560
- box-sizing: border-box !important;
561
- }
562
-
563
- .redacto-checkbox-small:checked::after {
564
- content: '' !important;
565
- position: absolute !important;
566
- left: 50% !important;
567
- top: 50% !important;
568
- transform: translate(-50%, -50%) rotate(45deg) !important;
569
- width: 3px !important;
570
- height: 6px !important;
571
- border: solid white !important;
572
- border-width: 0 1.5px 1.5px 0 !important;
573
- box-sizing: border-box !important;
574
- }
575
-
576
- .redacto-checkbox-large:focus {
577
- outline: 2px solid #4f87ff !important;
578
- outline-offset: 2px !important;
579
- }
580
-
581
- .redacto-checkbox-small:focus {
582
- outline: 2px solid #4f87ff !important;
583
- outline-offset: 2px !important;
584
- }
585
- `;
586
- document.head.appendChild(style);
587
- stylesInjected = true;
588
- };
589
-
590
766
  // src/RedactoNoticeConsent/RedactoNoticeConsent.tsx
591
767
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
592
- var RedactoNoticeConsent = ({
593
- noticeId,
594
- accessToken,
595
- refreshToken,
596
- baseUrl,
597
- language = "en",
598
- blockUI = true,
599
- onAccept,
600
- onDecline,
601
- onError,
768
+ var PurposeItem = ({
769
+ purpose,
770
+ selectedPurposes,
771
+ collapsedPurposes,
772
+ selectedDataElements,
602
773
  settings,
603
- applicationId
774
+ styles: styles3,
775
+ responsiveStyles,
776
+ onPurposeToggle,
777
+ onPurposeCollapse,
778
+ onDataElementToggle,
779
+ getTranslatedText,
780
+ isAlreadyConsented
604
781
  }) => {
605
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s;
606
- const [content, setContent] = useState2(null);
607
- const [isLoading, setIsLoading] = useState2(true);
608
- const [isSubmitting, setIsSubmitting] = useState2(false);
609
- const [isRefreshingToken, setIsRefreshingToken] = useState2(false);
610
- const [isLanguageDropdownOpen, setIsLanguageDropdownOpen] = useState2(false);
611
- const [selectedLanguage, setSelectedLanguage] = useState2(language);
612
- const [collapsedPurposes, setCollapsedPurposes] = useState2({});
613
- const [selectedPurposes, setSelectedPurposes] = useState2({});
614
- const [selectedDataElements, setSelectedDataElements] = useState2({});
615
- const [hasAlreadyConsented, setHasAlreadyConsented] = useState2(false);
616
- const [errorMessage, setErrorMessage] = useState2(null);
617
- const [fetchError, setFetchError] = useState2(null);
618
- const modalRef = useRef(null);
619
- const firstFocusableRef = useRef(null);
620
- const lastFocusableRef = useRef(null);
621
- const MAX_REFRESH_ATTEMPTS = 1;
622
- const [refreshAttempts, setRefreshAttempts] = useState2(0);
623
- const isMobile = useMediaQuery("(max-width: 768px)");
624
- const responsiveStyles = useMemo(
782
+ const headingStyle = useMemo(
625
783
  () => ({
626
- modal: {
627
- width: isMobile ? "90%" : "700px"
628
- },
629
- content: {
630
- margin: isMobile ? "20px" : "22px"
631
- },
632
- title: {
633
- fontSize: isMobile ? "16px" : "18px"
634
- },
635
- subTitle: {
636
- fontSize: isMobile ? "14px" : "16px"
637
- },
638
- privacyText: {
639
- fontSize: isMobile ? "14px" : "16px"
640
- },
641
- optionTitle: {
642
- fontSize: isMobile ? "14px" : "16px"
643
- },
644
- optionDescription: {
645
- fontSize: isMobile ? "11px" : "12px"
646
- },
647
- dataElementText: {
648
- fontSize: isMobile ? "12px" : "14px"
649
- },
650
- topRight: {
651
- fontSize: isMobile ? "11px" : "12px",
652
- padding: isMobile ? "3px 6px" : "3px 9px",
653
- height: isMobile ? "auto" : void 0,
654
- width: isMobile ? "auto" : void 0
655
- },
656
- languageItem: {
657
- fontSize: isMobile ? "11px" : "12px",
658
- padding: isMobile ? "6px 10px" : "8px 12px"
659
- },
660
- bottomSection: {
661
- flexDirection: isMobile ? "column" : "row",
662
- gap: isMobile ? "12px" : "29px"
663
- },
664
- button: {
665
- fontSize: isMobile ? "14px" : "16px",
666
- padding: isMobile ? "10px 20px" : "9px 45px"
667
- },
668
- middleSection: {
669
- paddingRight: isMobile ? "10px" : "15px"
670
- },
671
- errorDialog: {
672
- padding: isMobile ? "12px" : "16px",
673
- maxWidth: isMobile ? "100%" : "400px",
674
- marginBottom: isMobile ? "16px" : "20px"
675
- },
676
- errorTitle: {
677
- fontSize: isMobile ? "16px" : "18px",
678
- margin: isMobile ? "0 0 8px 0" : "0 0 12px 0"
679
- },
680
- errorMessage: {
681
- fontSize: isMobile ? "12px" : "14px",
682
- margin: isMobile ? "0 0 12px 0" : "0 0 16px 0"
683
- },
684
- errorButton: {
685
- padding: isMobile ? "6px 12px" : "8px 16px",
686
- fontSize: isMobile ? "12px" : "14px"
687
- },
688
- closeButton: {
689
- top: isMobile ? "4px" : "8px",
690
- right: isMobile ? "4px" : "8px",
691
- padding: isMobile ? "2px" : "4px"
692
- }
784
+ color: (settings == null ? void 0 : settings.headingColor) || "#323B4B",
785
+ fontFamily: (settings == null ? void 0 : settings.font) || "inherit"
693
786
  }),
694
- [isMobile]
787
+ [settings]
695
788
  );
696
- const areAllRequiredElementsChecked = useMemo(() => {
697
- if (!content) return false;
698
- return content.purposes.every((purpose) => {
699
- const requiredElements = purpose.data_elements.filter(
700
- (element) => element.required
701
- );
702
- return requiredElements.every(
703
- (element) => selectedDataElements[`${purpose.uuid}-${element.uuid}`]
704
- );
705
- });
706
- }, [content, selectedDataElements]);
707
- const acceptDisabled = isSubmitting || !areAllRequiredElementsChecked;
708
- useEffect2(() => {
709
- if (hasAlreadyConsented) {
710
- onAccept == null ? void 0 : onAccept();
711
- }
712
- }, [hasAlreadyConsented, onAccept]);
713
- const getTranslatedText = (key, defaultText, itemId) => {
714
- var _a2, _b2;
715
- if (!content) return defaultText;
716
- if (selectedLanguage === content.default_language) {
717
- if (key === "privacy_policy_anchor_text" && content.privacy_policy_anchor_text) {
718
- return content.privacy_policy_anchor_text;
719
- }
720
- return defaultText;
721
- }
722
- if (!content.supported_languages_and_translations) {
723
- return defaultText;
724
- }
725
- const translationMap = content.supported_languages_and_translations[selectedLanguage];
726
- if (!translationMap) {
727
- return defaultText;
728
- }
729
- if (itemId) {
730
- if (key === "purposes.name" || key === "purposes.description") {
731
- return ((_a2 = translationMap.purposes) == null ? void 0 : _a2[itemId]) || defaultText;
732
- }
733
- if (key.startsWith("data_elements.")) {
734
- return ((_b2 = translationMap.data_elements) == null ? void 0 : _b2[itemId]) || defaultText;
789
+ const textStyle = useMemo(
790
+ () => ({
791
+ color: (settings == null ? void 0 : settings.textColor) || "#344054",
792
+ fontFamily: (settings == null ? void 0 : settings.font) || "inherit"
793
+ }),
794
+ [settings]
795
+ );
796
+ return /* @__PURE__ */ jsxs("div", { children: [
797
+ /* @__PURE__ */ jsxs("div", { style: styles3.optionItem, children: [
798
+ /* @__PURE__ */ jsxs(
799
+ "div",
800
+ {
801
+ style: styles3.optionLeft,
802
+ onClick: () => onPurposeCollapse(purpose.uuid),
803
+ role: "button",
804
+ tabIndex: 0,
805
+ "aria-expanded": !collapsedPurposes[purpose.uuid],
806
+ "aria-controls": `purpose-${purpose.uuid}`,
807
+ onKeyDown: (e) => {
808
+ if (e.key === "Enter" || e.key === " ") {
809
+ e.preventDefault();
810
+ onPurposeCollapse(purpose.uuid);
811
+ }
812
+ },
813
+ children: [
814
+ /* @__PURE__ */ jsx(
815
+ "div",
816
+ {
817
+ style: {
818
+ display: "flex",
819
+ alignItems: "center",
820
+ justifyContent: "center",
821
+ marginLeft: "5px"
822
+ },
823
+ children: /* @__PURE__ */ jsx(
824
+ "svg",
825
+ {
826
+ width: "7",
827
+ height: "12",
828
+ viewBox: "0 0 7 12",
829
+ fill: "none",
830
+ xmlns: "http://www.w3.org/2000/svg",
831
+ stroke: (settings == null ? void 0 : settings.headingColor) || "#323B4B",
832
+ strokeWidth: "2",
833
+ strokeLinecap: "round",
834
+ strokeLinejoin: "round",
835
+ style: {
836
+ transform: !collapsedPurposes[purpose.uuid] ? "rotate(90deg)" : "rotate(0deg)",
837
+ transition: "transform 0.3s ease"
838
+ },
839
+ "aria-hidden": "true",
840
+ children: /* @__PURE__ */ jsx("path", { d: "M1 1L6 6L1 11" })
841
+ }
842
+ )
843
+ }
844
+ ),
845
+ /* @__PURE__ */ jsxs("div", { style: styles3.optionTextContainer, children: [
846
+ /* @__PURE__ */ jsx(
847
+ "h2",
848
+ {
849
+ style: {
850
+ ...styles3.optionTitle,
851
+ ...responsiveStyles.optionTitle,
852
+ ...headingStyle
853
+ },
854
+ children: getTranslatedText(`purposes.name`, purpose.name, purpose.uuid)
855
+ }
856
+ ),
857
+ /* @__PURE__ */ jsx(
858
+ "h3",
859
+ {
860
+ style: {
861
+ ...styles3.optionDescription,
862
+ ...responsiveStyles.optionDescription,
863
+ ...textStyle
864
+ },
865
+ children: getTranslatedText(
866
+ `purposes.description`,
867
+ purpose.description,
868
+ purpose.uuid
869
+ )
870
+ }
871
+ )
872
+ ] })
873
+ ]
874
+ }
875
+ ),
876
+ !isAlreadyConsented && /* @__PURE__ */ jsx(
877
+ "input",
878
+ {
879
+ className: "redacto-checkbox-large",
880
+ type: "checkbox",
881
+ checked: selectedPurposes[purpose.uuid] || false,
882
+ onChange: () => onPurposeToggle(purpose.uuid),
883
+ "aria-label": `Select all data elements for ${getTranslatedText(
884
+ `purposes.name`,
885
+ purpose.name,
886
+ purpose.uuid
887
+ )}`
888
+ }
889
+ ),
890
+ isAlreadyConsented && /* @__PURE__ */ jsx(
891
+ "div",
892
+ {
893
+ style: {
894
+ display: "flex",
895
+ alignItems: "center",
896
+ justifyContent: "center",
897
+ width: "20px",
898
+ height: "20px",
899
+ borderRadius: "50%",
900
+ backgroundColor: "#10B981",
901
+ marginLeft: "12px"
902
+ },
903
+ children: /* @__PURE__ */ jsx(
904
+ "svg",
905
+ {
906
+ width: "12",
907
+ height: "12",
908
+ viewBox: "0 0 12 12",
909
+ fill: "none",
910
+ xmlns: "http://www.w3.org/2000/svg",
911
+ children: /* @__PURE__ */ jsx(
912
+ "path",
913
+ {
914
+ d: "M4 6L5.5 7.5L8.5 4.5",
915
+ stroke: "white",
916
+ strokeWidth: "2",
917
+ strokeLinecap: "round",
918
+ strokeLinejoin: "round"
919
+ }
920
+ )
921
+ }
922
+ )
923
+ }
924
+ )
925
+ ] }),
926
+ !collapsedPurposes[purpose.uuid] && purpose.data_elements && purpose.data_elements.length > 0 && /* @__PURE__ */ jsx(
927
+ "div",
928
+ {
929
+ id: `purpose-${purpose.uuid}`,
930
+ style: styles3.dataElementsContainer,
931
+ children: purpose.data_elements.map((dataElement) => /* @__PURE__ */ jsxs("div", { style: styles3.dataElementItem, children: [
932
+ /* @__PURE__ */ jsxs(
933
+ "span",
934
+ {
935
+ style: {
936
+ ...styles3.dataElementText,
937
+ ...responsiveStyles.dataElementText,
938
+ ...textStyle
939
+ },
940
+ children: [
941
+ getTranslatedText(
942
+ `data_elements.name`,
943
+ dataElement.name,
944
+ dataElement.uuid
945
+ ),
946
+ dataElement.required && /* @__PURE__ */ jsx(
947
+ "span",
948
+ {
949
+ style: {
950
+ color: "red",
951
+ marginLeft: "4px"
952
+ },
953
+ "aria-label": "required",
954
+ children: "*"
955
+ }
956
+ )
957
+ ]
958
+ }
959
+ ),
960
+ !isAlreadyConsented && /* @__PURE__ */ jsx(
961
+ "input",
962
+ {
963
+ className: "redacto-checkbox-small",
964
+ type: "checkbox",
965
+ checked: selectedDataElements[`${purpose.uuid}-${dataElement.uuid}`] || false,
966
+ onChange: () => onDataElementToggle(dataElement.uuid, purpose.uuid),
967
+ "aria-label": `Select ${getTranslatedText(
968
+ `data_elements.name`,
969
+ dataElement.name,
970
+ dataElement.uuid
971
+ )}${dataElement.required ? " (required)" : ""}`
972
+ }
973
+ ),
974
+ isAlreadyConsented && /* @__PURE__ */ jsx(
975
+ "div",
976
+ {
977
+ style: {
978
+ display: "flex",
979
+ alignItems: "center",
980
+ justifyContent: "center",
981
+ width: "16px",
982
+ height: "16px",
983
+ borderRadius: "50%",
984
+ backgroundColor: "#10B981"
985
+ },
986
+ children: /* @__PURE__ */ jsx(
987
+ "svg",
988
+ {
989
+ width: "10",
990
+ height: "10",
991
+ viewBox: "0 0 10 10",
992
+ fill: "none",
993
+ xmlns: "http://www.w3.org/2000/svg",
994
+ children: /* @__PURE__ */ jsx(
995
+ "path",
996
+ {
997
+ d: "M3 5L4.5 6.5L7.5 3.5",
998
+ stroke: "white",
999
+ strokeWidth: "1.5",
1000
+ strokeLinecap: "round",
1001
+ strokeLinejoin: "round"
1002
+ }
1003
+ )
1004
+ }
1005
+ )
1006
+ }
1007
+ )
1008
+ ] }, dataElement.uuid))
735
1009
  }
736
- }
737
- const value = translationMap[key];
738
- if (typeof value === "string") {
739
- return value;
740
- }
741
- return defaultText;
742
- };
743
- const fetchNotice = async () => {
744
- setIsLoading(true);
745
- setFetchError(null);
746
- try {
747
- const consentContentData = await fetchConsentContent({
748
- noticeId,
749
- accessToken,
750
- refreshToken,
751
- baseUrl,
752
- language,
753
- specific_uuid: applicationId
754
- });
755
- setContent(consentContentData.detail.active_config);
756
- if (consentContentData.detail.active_config.default_language) {
757
- setSelectedLanguage(
758
- consentContentData.detail.active_config.default_language
759
- );
760
- }
761
- const initialCollapsedState = consentContentData.detail.active_config.purposes.reduce(
762
- (acc, purpose) => ({
763
- ...acc,
764
- [purpose.uuid]: true
765
- }),
766
- {}
767
- );
768
- setCollapsedPurposes(initialCollapsedState);
769
- const initialPurposeState = consentContentData.detail.active_config.purposes.reduce(
770
- (acc, purpose) => {
771
- return {
772
- ...acc,
773
- [purpose.uuid]: false
774
- };
775
- },
776
- {}
777
- );
778
- setSelectedPurposes(initialPurposeState);
779
- const initialDataElementState = consentContentData.detail.active_config.purposes.reduce(
780
- (acc, purpose) => {
781
- purpose.data_elements.forEach((element) => {
782
- const combinedId = `${purpose.uuid}-${element.uuid}`;
783
- acc[combinedId] = false;
784
- });
785
- return acc;
786
- },
787
- {}
788
- );
789
- setSelectedDataElements(initialDataElementState);
790
- } catch (err) {
791
- console.error(err);
792
- const error = err;
793
- setFetchError(error);
794
- if (error.status === 401 && refreshAttempts < MAX_REFRESH_ATTEMPTS) {
795
- setRefreshAttempts((c) => c + 1);
796
- setIsRefreshingToken(true);
797
- onError == null ? void 0 : onError(error);
798
- } else if (error.status === 409) {
799
- setHasAlreadyConsented(true);
800
- } else {
801
- onError == null ? void 0 : onError(error);
802
- }
803
- } finally {
804
- setIsLoading(false);
805
- setIsRefreshingToken(false);
806
- }
807
- };
808
- useEffect2(() => {
809
- injectCheckboxStyles();
810
- fetchNotice();
811
- }, [
812
- noticeId,
813
- accessToken,
814
- refreshToken,
815
- language,
816
- onError,
817
- applicationId,
818
- isRefreshingToken
819
- ]);
820
- const togglePurposeCollapse = (purposeUuid) => {
821
- setCollapsedPurposes((prev) => ({
822
- ...prev,
823
- [purposeUuid]: !prev[purposeUuid]
824
- }));
825
- };
826
- const toggleLanguageDropdown = () => {
827
- setIsLanguageDropdownOpen(!isLanguageDropdownOpen);
828
- };
829
- const handleLanguageSelect = (lang) => {
830
- setSelectedLanguage(lang);
831
- setIsLanguageDropdownOpen(false);
832
- };
833
- const handlePurposeCheckboxChange = (purposeUuid) => {
834
- if (content) {
835
- const purpose = content.purposes.find((p) => p.uuid === purposeUuid);
836
- if (purpose) {
837
- const newPurposeState = !selectedPurposes[purposeUuid];
838
- setSelectedPurposes((prev) => ({
839
- ...prev,
840
- [purposeUuid]: newPurposeState
841
- }));
842
- setSelectedDataElements((prev) => {
843
- const updated = { ...prev };
844
- purpose.data_elements.forEach((el) => {
845
- updated[`${purposeUuid}-${el.uuid}`] = newPurposeState;
846
- });
847
- return updated;
848
- });
849
- }
850
- }
851
- };
852
- const handleDataElementCheckboxChange = (elementUuid, purposeUuid) => {
853
- const combinedId = `${purposeUuid}-${elementUuid}`;
854
- setSelectedDataElements((prev) => {
855
- const newState = {
856
- ...prev,
857
- [combinedId]: !prev[combinedId]
858
- };
859
- if (content) {
860
- const purpose = content.purposes.find((p) => p.uuid === purposeUuid);
861
- if (purpose) {
862
- const requiredElements = purpose.data_elements.filter(
863
- (el) => el.required
864
- );
865
- const allRequiredElementsChecked = requiredElements.every(
866
- (el) => newState[`${purposeUuid}-${el.uuid}`]
867
- );
868
- setSelectedPurposes((prevPurposes) => ({
869
- ...prevPurposes,
870
- [purposeUuid]: allRequiredElementsChecked
871
- }));
872
- }
873
- }
874
- return newState;
875
- });
876
- };
877
- const handleAccept = async () => {
878
- try {
879
- setIsSubmitting(true);
880
- setErrorMessage(null);
881
- if (content) {
882
- await submitConsentEvent({
883
- accessToken,
884
- baseUrl,
885
- noticeUuid: content.notice_uuid,
886
- purposes: content.purposes.map((purpose) => ({
887
- ...purpose,
888
- selected: selectedPurposes[purpose.uuid] || false,
889
- data_elements: purpose.data_elements.map((element) => ({
890
- ...element,
891
- selected: element.required ? true : selectedDataElements[`${purpose.uuid}-${element.uuid}`] || false
892
- }))
893
- })),
894
- declined: false,
895
- meta_data: applicationId ? { specific_uuid: applicationId } : void 0
896
- });
897
- }
898
- onAccept == null ? void 0 : onAccept();
899
- } catch (error) {
900
- console.error("Error submitting consent:", error);
901
- const err = error;
902
- if (err.status === 500) {
903
- setErrorMessage(
904
- "An error occurred while submitting your consent. Please try again later."
905
- );
906
- }
907
- onError == null ? void 0 : onError(error);
908
- } finally {
909
- setIsSubmitting(false);
910
- }
911
- };
912
- const handleDecline = async () => {
913
- onDecline == null ? void 0 : onDecline();
914
- };
915
- const availableLanguages = useMemo(
916
- () => content ? [
917
- content.default_language,
918
- ...Object.keys(content.supported_languages_and_translations || {})
919
- ].filter((value, index, self) => self.indexOf(value) === index) : [language],
920
- [content, language]
921
- );
922
- const modalStyle = {
923
- borderRadius: (settings == null ? void 0 : settings.borderRadius) || "8px",
924
- backgroundColor: (settings == null ? void 0 : settings.backgroundColor) || "#ffffff"
925
- };
926
- const buttonStyle = {
927
- borderRadius: (settings == null ? void 0 : settings.borderRadius) || "8px"
928
- };
929
- const acceptButtonStyle = {
930
- ...buttonStyle,
931
- backgroundColor: ((_b = (_a = settings == null ? void 0 : settings.button) == null ? void 0 : _a.accept) == null ? void 0 : _b.backgroundColor) || (content == null ? void 0 : content.primary_color) || "#4f87ff",
932
- color: ((_d = (_c = settings == null ? void 0 : settings.button) == null ? void 0 : _c.accept) == null ? void 0 : _d.textColor) || "#ffffff"
933
- };
934
- const declineButtonStyle = {
935
- ...buttonStyle,
936
- backgroundColor: ((_f = (_e = settings == null ? void 0 : settings.button) == null ? void 0 : _e.decline) == null ? void 0 : _f.backgroundColor) || "#ffffff",
937
- color: ((_h = (_g = settings == null ? void 0 : settings.button) == null ? void 0 : _g.decline) == null ? void 0 : _h.textColor) || "#000000",
938
- borderColor: (settings == null ? void 0 : settings.borderColor) || "#d0d5dd"
939
- };
940
- const linkStyle = {
941
- color: (settings == null ? void 0 : settings.link) || (content == null ? void 0 : content.secondary_color) || "#4f87ff"
942
- };
943
- const languageSelectorStyle = {
1010
+ )
1011
+ ] }, purpose.uuid);
1012
+ };
1013
+ var GuardianForm = ({
1014
+ formData,
1015
+ errors,
1016
+ isSubmitting,
1017
+ onChange,
1018
+ onNext,
1019
+ onDecline,
1020
+ styles: styles3,
1021
+ responsiveStyles,
1022
+ settings,
1023
+ componentHeadingStyle,
1024
+ componentTextStyle,
1025
+ acceptButtonStyle,
1026
+ declineButtonStyle,
1027
+ logoUrl
1028
+ }) => {
1029
+ const inputStyle = {
1030
+ width: "100%",
1031
+ padding: "10px 12px",
1032
+ border: `1px solid ${(settings == null ? void 0 : settings.borderColor) || "#d0d5dd"}`,
944
1033
  borderRadius: (settings == null ? void 0 : settings.borderRadius) || "8px",
945
- borderColor: (settings == null ? void 0 : settings.borderColor) || "#d0d5dd",
946
- backgroundColor: ((_j = (_i = settings == null ? void 0 : settings.button) == null ? void 0 : _i.language) == null ? void 0 : _j.backgroundColor) || "#ffffff",
947
- color: ((_l = (_k = settings == null ? void 0 : settings.button) == null ? void 0 : _k.language) == null ? void 0 : _l.textColor) || "#344054"
948
- };
949
- const selectedLanguageItemStyle = {
950
- ...languageSelectorStyle,
951
- backgroundColor: ((_n = (_m = settings == null ? void 0 : settings.button) == null ? void 0 : _m.language) == null ? void 0 : _n.selectedBackgroundColor) || "#f3f4f6",
952
- color: ((_p = (_o = settings == null ? void 0 : settings.button) == null ? void 0 : _o.language) == null ? void 0 : _p.selectedTextColor) || "#344054",
953
- fontWeight: 600
954
- };
955
- const headingStyle = {
956
- color: (settings == null ? void 0 : settings.headingColor) || "#101828"
957
- };
958
- const textStyle = {
959
- color: (settings == null ? void 0 : settings.textColor) || "#344054"
1034
+ fontSize: "13px",
1035
+ fontFamily: (settings == null ? void 0 : settings.font) || "inherit",
1036
+ color: (settings == null ? void 0 : settings.textColor) || "#344054",
1037
+ backgroundColor: (settings == null ? void 0 : settings.backgroundColor) || "#ffffff",
1038
+ marginBottom: "4px",
1039
+ boxSizing: "border-box"
960
1040
  };
961
- const sectionStyle = {
962
- backgroundColor: (settings == null ? void 0 : settings.backgroundColor) || "#ffffff"
1041
+ const errorStyle = {
1042
+ color: "#DC2626",
1043
+ fontSize: "12px",
1044
+ marginTop: "4px",
1045
+ marginBottom: "16px"
963
1046
  };
964
- const handleCloseError = () => {
965
- setErrorMessage(null);
1047
+ const labelStyle = {
1048
+ ...componentTextStyle,
1049
+ fontSize: "13px",
1050
+ fontWeight: "500",
1051
+ marginBottom: "6px",
1052
+ display: "block"
966
1053
  };
967
- useEffect2(() => {
968
- const handleKeyDown = (event) => {
969
- if (!modalRef.current) return;
970
- const focusableElements = modalRef.current.querySelectorAll(
971
- 'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
972
- );
973
- if (!focusableElements.length) return;
974
- if (event.key === "Escape") {
975
- handleDecline();
976
- }
977
- if (event.key === "Tab") {
978
- const firstElement = focusableElements[0];
979
- const lastElement = focusableElements[focusableElements.length - 1];
980
- if (event.shiftKey) {
981
- if (document.activeElement === firstElement) {
982
- event.preventDefault();
983
- lastElement.focus();
984
- }
985
- } else {
986
- if (document.activeElement === lastElement) {
987
- event.preventDefault();
988
- firstElement.focus();
989
- }
1054
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
1055
+ /* @__PURE__ */ jsx("div", { style: { ...styles3.topSection, ...componentTextStyle }, children: /* @__PURE__ */ jsxs("div", { style: styles3.topLeft, children: [
1056
+ /* @__PURE__ */ jsx("img", { style: styles3.logo, src: logoUrl, alt: "Redacto Logo" }),
1057
+ /* @__PURE__ */ jsx(
1058
+ "h2",
1059
+ {
1060
+ id: "guardian-form-title",
1061
+ style: {
1062
+ ...styles3.title,
1063
+ ...responsiveStyles.title,
1064
+ ...componentHeadingStyle,
1065
+ fontSize: "16px",
1066
+ fontWeight: 600
1067
+ },
1068
+ children: "Guardian Information Required"
990
1069
  }
991
- }
992
- };
993
- const modal = modalRef.current;
994
- modal == null ? void 0 : modal.addEventListener("keydown", handleKeyDown);
995
- if (modal && !isLoading) {
996
- const focusableElements = modal.querySelectorAll(
997
- 'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
998
- );
999
- const firstElement = focusableElements[0];
1000
- firstElement == null ? void 0 : firstElement.focus();
1001
- }
1002
- return () => {
1003
- modal == null ? void 0 : modal.removeEventListener("keydown", handleKeyDown);
1004
- };
1005
- }, [isLoading, handleDecline]);
1006
- return /* @__PURE__ */ jsx(Fragment, { children: hasAlreadyConsented ? null : /* @__PURE__ */ jsxs(Fragment, { children: [
1007
- blockUI && /* @__PURE__ */ jsx(
1008
- "div",
1009
- {
1010
- style: styles.overlay,
1011
- "aria-hidden": "true",
1012
- role: "presentation"
1013
- }
1014
- ),
1015
- /* @__PURE__ */ jsx(
1070
+ )
1071
+ ] }) }),
1072
+ /* @__PURE__ */ jsxs(
1016
1073
  "div",
1017
1074
  {
1018
- ref: modalRef,
1019
1075
  style: {
1020
- ...styles.modal,
1021
- ...responsiveStyles.modal,
1022
- ...modalStyle
1076
+ ...styles3.middleSection,
1077
+ ...responsiveStyles.middleSection,
1078
+ ...componentTextStyle
1023
1079
  },
1024
- role: "dialog",
1025
- "aria-modal": "true",
1026
- "aria-labelledby": "privacy-notice-title",
1027
- "aria-describedby": "privacy-notice-description",
1028
- tabIndex: -1,
1029
- children: isLoading || isRefreshingToken ? /* @__PURE__ */ jsxs("div", { style: styles.loadingContainer, children: [
1030
- /* @__PURE__ */ jsx("div", { style: styles.loadingSpinner }),
1031
- /* @__PURE__ */ jsx("p", { style: { ...styles.privacyText, ...textStyle }, children: isRefreshingToken ? "Refreshing session..." : "Loading..." })
1032
- ] }) : fetchError ? /* @__PURE__ */ jsx(
1033
- "div",
1034
- {
1035
- style: {
1036
- ...styles.content,
1037
- ...responsiveStyles.content,
1038
- display: "flex",
1039
- flexDirection: "column",
1040
- alignItems: "center",
1041
- justifyContent: "center",
1042
- textAlign: "center",
1043
- padding: "40px 20px"
1044
- },
1045
- children: /* @__PURE__ */ jsxs(
1046
- "div",
1047
- {
1048
- style: {
1049
- color: "#DC2626",
1050
- padding: responsiveStyles.errorDialog.padding,
1051
- borderRadius: "8px",
1052
- marginBottom: responsiveStyles.errorDialog.marginBottom,
1053
- width: "100%",
1054
- maxWidth: responsiveStyles.errorDialog.maxWidth,
1055
- position: "relative"
1056
- },
1057
- children: [
1080
+ children: [
1081
+ /* @__PURE__ */ jsx(
1082
+ "p",
1083
+ {
1084
+ style: {
1085
+ ...styles3.privacyText,
1086
+ ...responsiveStyles.privacyText,
1087
+ ...componentTextStyle,
1088
+ fontSize: "14px",
1089
+ lineHeight: "1.4"
1090
+ },
1091
+ children: "As you are under the age of consent, we need to collect information about your legal guardian to proceed."
1092
+ }
1093
+ ),
1094
+ /* @__PURE__ */ jsxs(
1095
+ "div",
1096
+ {
1097
+ style: {
1098
+ display: "flex",
1099
+ flexDirection: "column",
1100
+ gap: "12px",
1101
+ marginTop: "16px"
1102
+ },
1103
+ children: [
1104
+ /* @__PURE__ */ jsxs("div", { children: [
1058
1105
  /* @__PURE__ */ jsx(
1059
- "button",
1106
+ "label",
1060
1107
  {
1061
- onClick: handleDecline,
1062
- style: {
1063
- position: "absolute",
1064
- top: responsiveStyles.closeButton.top,
1065
- right: responsiveStyles.closeButton.right,
1066
- background: "none",
1067
- border: "none",
1068
- color: "#DC2626",
1069
- cursor: "pointer",
1070
- padding: responsiveStyles.closeButton.padding,
1071
- display: "flex",
1072
- alignItems: "center",
1073
- justifyContent: "center"
1074
- },
1075
- "aria-label": "Close error message",
1076
- children: /* @__PURE__ */ jsx(
1077
- "svg",
1078
- {
1079
- width: isMobile ? "14" : "16",
1080
- height: isMobile ? "14" : "16",
1081
- viewBox: "0 0 16 16",
1082
- fill: "none",
1083
- xmlns: "http://www.w3.org/2000/svg",
1084
- "aria-hidden": "true",
1085
- children: /* @__PURE__ */ jsx(
1086
- "path",
1087
- {
1088
- d: "M12 4L4 12M4 4L12 12",
1089
- stroke: "currentColor",
1090
- strokeWidth: "2",
1091
- strokeLinecap: "round",
1092
- strokeLinejoin: "round"
1093
- }
1094
- )
1095
- }
1096
- )
1108
+ htmlFor: "guardianName",
1109
+ style: { ...labelStyle, marginBottom: "8px", display: "block" },
1110
+ children: "Name of Guardian *"
1097
1111
  }
1098
1112
  ),
1099
1113
  /* @__PURE__ */ jsx(
1100
- "h3",
1114
+ "input",
1101
1115
  {
1116
+ id: "guardianName",
1117
+ type: "text",
1118
+ value: formData.guardianName,
1119
+ onChange: (e) => onChange("guardianName", e.target.value),
1102
1120
  style: {
1103
- margin: responsiveStyles.errorTitle.margin,
1104
- fontSize: responsiveStyles.errorTitle.fontSize,
1105
- fontWeight: "600"
1121
+ ...inputStyle,
1122
+ borderColor: errors.guardianName ? "#DC2626" : inputStyle.border
1106
1123
  },
1107
- children: "Error Loading Consent Notice"
1124
+ placeholder: "Enter guardian's full name"
1108
1125
  }
1109
1126
  ),
1127
+ errors.guardianName && /* @__PURE__ */ jsx("div", { style: errorStyle, children: errors.guardianName })
1128
+ ] }),
1129
+ /* @__PURE__ */ jsxs("div", { children: [
1110
1130
  /* @__PURE__ */ jsx(
1111
- "p",
1131
+ "label",
1112
1132
  {
1133
+ htmlFor: "guardianContact",
1134
+ style: { ...labelStyle, marginBottom: "8px", display: "block" },
1135
+ children: "Contact of Guardian *"
1136
+ }
1137
+ ),
1138
+ /* @__PURE__ */ jsx(
1139
+ "input",
1140
+ {
1141
+ id: "guardianContact",
1142
+ type: "text",
1143
+ value: formData.guardianContact,
1144
+ onChange: (e) => onChange("guardianContact", e.target.value),
1113
1145
  style: {
1114
- margin: responsiveStyles.errorMessage.margin,
1115
- fontSize: responsiveStyles.errorMessage.fontSize,
1116
- lineHeight: "1.5"
1146
+ ...inputStyle,
1147
+ borderColor: errors.guardianContact ? "#DC2626" : inputStyle.border
1117
1148
  },
1118
- children: fetchError.message || "Failed to load consent notice. Please try again."
1149
+ placeholder: "Enter guardian's email or phone number"
1119
1150
  }
1120
1151
  ),
1152
+ errors.guardianContact && /* @__PURE__ */ jsx("div", { style: errorStyle, children: errors.guardianContact })
1153
+ ] }),
1154
+ /* @__PURE__ */ jsxs("div", { children: [
1121
1155
  /* @__PURE__ */ jsx(
1122
- "button",
1156
+ "label",
1123
1157
  {
1124
- onClick: fetchNotice,
1158
+ htmlFor: "guardianRelationship",
1159
+ style: { ...labelStyle, marginBottom: "8px", display: "block" },
1160
+ children: "Relationship to Guardian *"
1161
+ }
1162
+ ),
1163
+ /* @__PURE__ */ jsx(
1164
+ "input",
1165
+ {
1166
+ id: "guardianRelationship",
1167
+ type: "text",
1168
+ value: formData.guardianRelationship,
1169
+ onChange: (e) => onChange("guardianRelationship", e.target.value),
1125
1170
  style: {
1126
- backgroundColor: "#DC2626",
1127
- color: "#FFFFFF",
1128
- border: "none",
1129
- padding: responsiveStyles.errorButton.padding,
1130
- borderRadius: "6px",
1131
- cursor: "pointer",
1132
- fontSize: responsiveStyles.errorButton.fontSize,
1133
- fontWeight: "500",
1134
- transition: "background-color 0.2s"
1171
+ ...inputStyle,
1172
+ borderColor: errors.guardianRelationship ? "#DC2626" : inputStyle.border
1135
1173
  },
1136
- onMouseOver: (e) => e.currentTarget.style.backgroundColor = "#B91C1C",
1137
- onMouseOut: (e) => e.currentTarget.style.backgroundColor = "#DC2626",
1138
- children: "Refresh"
1174
+ placeholder: "e.g., Parent, Legal Guardian, etc."
1139
1175
  }
1140
- )
1141
- ]
1142
- }
1143
- )
1144
- }
1145
- ) : /* @__PURE__ */ jsxs("div", { style: { ...styles.content, ...responsiveStyles.content }, children: [
1146
- errorMessage && /* @__PURE__ */ jsxs(
1176
+ ),
1177
+ errors.guardianRelationship && /* @__PURE__ */ jsx("div", { style: errorStyle, children: errors.guardianRelationship })
1178
+ ] })
1179
+ ]
1180
+ }
1181
+ ),
1182
+ errors.general && /* @__PURE__ */ jsx(
1147
1183
  "div",
1148
1184
  {
1149
1185
  role: "alert",
1150
1186
  style: {
1151
- backgroundColor: "#FEE2E2",
1152
1187
  color: "#DC2626",
1188
+ fontSize: "14px",
1189
+ marginTop: "16px",
1153
1190
  padding: "12px",
1154
1191
  borderRadius: "6px",
1155
- marginBottom: "16px",
1156
- fontSize: "14px",
1157
1192
  border: "1px solid #FCA5A5",
1158
- position: "relative",
1159
- display: "flex",
1160
- alignItems: "center",
1161
- justifyContent: "space-between"
1193
+ backgroundColor: "#FEF2F2",
1194
+ textAlign: "center"
1162
1195
  },
1163
- children: [
1164
- /* @__PURE__ */ jsx("span", { children: errorMessage }),
1165
- /* @__PURE__ */ jsx(
1166
- "button",
1167
- {
1168
- type: "button",
1169
- onClick: handleCloseError,
1170
- style: {
1171
- background: "none",
1172
- border: "none",
1173
- color: "#DC2626",
1174
- cursor: "pointer",
1175
- padding: "4px",
1176
- marginLeft: "8px",
1177
- display: "flex",
1178
- alignItems: "center",
1179
- justifyContent: "center"
1180
- },
1181
- "aria-label": "Close error message",
1182
- children: /* @__PURE__ */ jsx(
1183
- "svg",
1184
- {
1185
- width: "16",
1186
- height: "16",
1187
- viewBox: "0 0 16 16",
1188
- fill: "none",
1189
- xmlns: "http://www.w3.org/2000/svg",
1190
- "aria-hidden": "true",
1191
- children: /* @__PURE__ */ jsx(
1192
- "path",
1193
- {
1194
- d: "M12 4L4 12M4 4L12 12",
1195
- stroke: "currentColor",
1196
- strokeWidth: "2",
1197
- strokeLinecap: "round",
1198
- strokeLinejoin: "round"
1199
- }
1200
- )
1201
- }
1202
- )
1203
- }
1204
- )
1205
- ]
1196
+ children: errors.general
1197
+ }
1198
+ )
1199
+ ]
1200
+ }
1201
+ ),
1202
+ /* @__PURE__ */ jsxs(
1203
+ "div",
1204
+ {
1205
+ style: {
1206
+ ...styles3.bottomSection,
1207
+ ...responsiveStyles.bottomSection,
1208
+ ...componentTextStyle,
1209
+ paddingTop: "12px"
1210
+ },
1211
+ children: [
1212
+ /* @__PURE__ */ jsx(
1213
+ "button",
1214
+ {
1215
+ style: {
1216
+ ...styles3.button,
1217
+ ...responsiveStyles.button,
1218
+ ...styles3.acceptButton,
1219
+ ...acceptButtonStyle
1220
+ },
1221
+ onClick: onNext,
1222
+ disabled: isSubmitting,
1223
+ type: "button",
1224
+ children: isSubmitting ? "Submitting..." : "Next"
1206
1225
  }
1207
1226
  ),
1208
- /* @__PURE__ */ jsxs("div", { style: { ...styles.topSection, ...sectionStyle }, children: [
1209
- /* @__PURE__ */ jsxs("div", { style: styles.topLeft, children: [
1210
- /* @__PURE__ */ jsx(
1211
- "img",
1227
+ /* @__PURE__ */ jsx(
1228
+ "button",
1229
+ {
1230
+ style: {
1231
+ ...styles3.button,
1232
+ ...responsiveStyles.button,
1233
+ ...styles3.cancelButton,
1234
+ ...declineButtonStyle
1235
+ },
1236
+ onClick: onDecline,
1237
+ type: "button",
1238
+ children: "Cancel"
1239
+ }
1240
+ )
1241
+ ]
1242
+ }
1243
+ )
1244
+ ] });
1245
+ };
1246
+ var AgeVerification = ({
1247
+ onYes,
1248
+ onNo,
1249
+ onClose,
1250
+ styles: styles3,
1251
+ responsiveStyles,
1252
+ componentHeadingStyle,
1253
+ componentTextStyle,
1254
+ acceptButtonStyle,
1255
+ declineButtonStyle,
1256
+ logoUrl,
1257
+ isMobile
1258
+ }) => {
1259
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
1260
+ /* @__PURE__ */ jsxs("div", { style: { ...styles3.topSection, ...componentTextStyle }, children: [
1261
+ /* @__PURE__ */ jsxs("div", { style: styles3.topLeft, children: [
1262
+ /* @__PURE__ */ jsx("img", { style: styles3.logo, src: logoUrl, alt: "Redacto Logo" }),
1263
+ /* @__PURE__ */ jsx(
1264
+ "h2",
1265
+ {
1266
+ id: "age-verification-title",
1267
+ style: {
1268
+ ...styles3.title,
1269
+ ...responsiveStyles.title,
1270
+ ...componentHeadingStyle
1271
+ },
1272
+ children: "Age Verification Required"
1273
+ }
1274
+ )
1275
+ ] }),
1276
+ /* @__PURE__ */ jsx(
1277
+ "button",
1278
+ {
1279
+ onClick: onClose,
1280
+ style: {
1281
+ background: "none",
1282
+ border: "none",
1283
+ color: (componentHeadingStyle == null ? void 0 : componentHeadingStyle.color) || "#323B4B",
1284
+ cursor: "pointer",
1285
+ padding: isMobile ? "2px" : "4px",
1286
+ display: "flex",
1287
+ alignItems: "center",
1288
+ justifyContent: "center"
1289
+ },
1290
+ "aria-label": "Close modal",
1291
+ children: /* @__PURE__ */ jsx(
1292
+ "svg",
1293
+ {
1294
+ width: isMobile ? "18" : "20",
1295
+ height: isMobile ? "18" : "20",
1296
+ viewBox: "0 0 20 20",
1297
+ fill: "none",
1298
+ xmlns: "http://www.w3.org/2000/svg",
1299
+ "aria-hidden": "true",
1300
+ children: /* @__PURE__ */ jsx(
1301
+ "path",
1212
1302
  {
1213
- style: styles.logo,
1214
- src: (content == null ? void 0 : content.logo_url) || redacto_logo_default,
1215
- alt: "Redacto Logo"
1303
+ d: "M15 5L5 15M5 5L15 15",
1304
+ stroke: "currentColor",
1305
+ strokeWidth: "2",
1306
+ strokeLinecap: "round",
1307
+ strokeLinejoin: "round"
1216
1308
  }
1217
- ),
1218
- /* @__PURE__ */ jsx(
1219
- "h2",
1220
- {
1221
- id: "privacy-notice-title",
1222
- style: {
1223
- ...styles.title,
1224
- ...responsiveStyles.title,
1225
- ...headingStyle
1226
- },
1227
- children: "Your Privacy Matters"
1309
+ )
1310
+ }
1311
+ )
1312
+ }
1313
+ )
1314
+ ] }),
1315
+ /* @__PURE__ */ jsxs(
1316
+ "div",
1317
+ {
1318
+ style: {
1319
+ ...styles3.middleSection,
1320
+ ...responsiveStyles.middleSection,
1321
+ ...componentTextStyle
1322
+ },
1323
+ children: [
1324
+ /* @__PURE__ */ jsx(
1325
+ "p",
1326
+ {
1327
+ style: {
1328
+ ...styles3.privacyText,
1329
+ ...responsiveStyles.privacyText,
1330
+ ...componentTextStyle,
1331
+ marginBottom: "16px"
1332
+ },
1333
+ children: "To proceed with this consent form, we need to verify your age."
1334
+ }
1335
+ ),
1336
+ /* @__PURE__ */ jsx(
1337
+ "p",
1338
+ {
1339
+ style: {
1340
+ ...styles3.subTitle,
1341
+ ...componentTextStyle,
1342
+ marginBottom: "24px",
1343
+ textAlign: "left"
1344
+ },
1345
+ children: "Are you 18 years of age or older?"
1346
+ }
1347
+ )
1348
+ ]
1349
+ }
1350
+ ),
1351
+ /* @__PURE__ */ jsxs(
1352
+ "div",
1353
+ {
1354
+ style: {
1355
+ ...styles3.bottomSection,
1356
+ ...responsiveStyles.bottomSection,
1357
+ ...componentTextStyle
1358
+ },
1359
+ children: [
1360
+ /* @__PURE__ */ jsx(
1361
+ "button",
1362
+ {
1363
+ style: {
1364
+ ...styles3.button,
1365
+ ...responsiveStyles.button,
1366
+ ...styles3.acceptButton,
1367
+ ...acceptButtonStyle
1368
+ },
1369
+ onClick: onYes,
1370
+ type: "button",
1371
+ children: "Yes, I am 18 or older"
1372
+ }
1373
+ ),
1374
+ /* @__PURE__ */ jsx(
1375
+ "button",
1376
+ {
1377
+ style: {
1378
+ ...styles3.button,
1379
+ ...responsiveStyles.button,
1380
+ ...styles3.cancelButton,
1381
+ ...declineButtonStyle
1382
+ },
1383
+ onClick: onNo,
1384
+ type: "button",
1385
+ children: "No, I am under 18"
1386
+ }
1387
+ )
1388
+ ]
1389
+ }
1390
+ )
1391
+ ] });
1392
+ };
1393
+ var RedactoNoticeConsent = ({
1394
+ noticeId,
1395
+ accessToken,
1396
+ refreshToken,
1397
+ baseUrl,
1398
+ language = "en",
1399
+ blockUI = true,
1400
+ onAccept,
1401
+ onDecline,
1402
+ onError,
1403
+ settings,
1404
+ applicationId,
1405
+ checkMode = "all"
1406
+ }) => {
1407
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u;
1408
+ const propValidationError = useMemo(() => {
1409
+ if (!(noticeId == null ? void 0 : noticeId.trim())) {
1410
+ return "RedactoNoticeConsent: 'noticeId' prop is required and cannot be empty";
1411
+ }
1412
+ if (!(accessToken == null ? void 0 : accessToken.trim())) {
1413
+ return "RedactoNoticeConsent: 'accessToken' prop is required and cannot be empty";
1414
+ }
1415
+ return null;
1416
+ }, [noticeId, accessToken]);
1417
+ if (propValidationError) {
1418
+ return /* @__PURE__ */ jsxs(
1419
+ "div",
1420
+ {
1421
+ style: {
1422
+ padding: "20px",
1423
+ backgroundColor: "#fee",
1424
+ border: "1px solid #fcc",
1425
+ borderRadius: "4px",
1426
+ color: "#c33"
1427
+ },
1428
+ children: [
1429
+ /* @__PURE__ */ jsx("h3", { children: "Configuration Error" }),
1430
+ /* @__PURE__ */ jsx("p", { children: propValidationError }),
1431
+ /* @__PURE__ */ jsx("p", { children: "Please check your component props and try again." })
1432
+ ]
1433
+ }
1434
+ );
1435
+ }
1436
+ const [isLoading, setIsLoading] = useState2(true);
1437
+ const [isSubmitting, setIsSubmitting] = useState2(false);
1438
+ const [content, setContent] = useState2(null);
1439
+ const [categorizedPurposes, setCategorizedPurposes] = useState2(null);
1440
+ const [selectedPurposes, setSelectedPurposes] = useState2({});
1441
+ const [selectedDataElements, setSelectedDataElements] = useState2({});
1442
+ const [collapsedPurposes, setCollapsedPurposes] = useState2({});
1443
+ const [hasAlreadyConsented, setHasAlreadyConsented] = useState2(false);
1444
+ const [isLanguageDropdownOpen, setIsLanguageDropdownOpen] = useState2(false);
1445
+ const [selectedLanguage, setSelectedLanguage] = useState2(language);
1446
+ const [errorMessage, setErrorMessage] = useState2(null);
1447
+ const [fetchError, setFetchError] = useState2(null);
1448
+ const [showAgeVerification, setShowAgeVerification] = useState2(false);
1449
+ const [showGuardianForm, setShowGuardianForm] = useState2(false);
1450
+ const [isSubmittingGuardian, setIsSubmittingGuardian] = useState2(false);
1451
+ const [guardianFormData, setGuardianFormData] = useState2({
1452
+ guardianName: "",
1453
+ guardianContact: "",
1454
+ guardianRelationship: ""
1455
+ });
1456
+ const [guardianFormErrors, setGuardianFormErrors] = useState2({});
1457
+ const modalRef = useRef(null);
1458
+ const firstFocusableRef = useRef(null);
1459
+ const lastFocusableRef = useRef(null);
1460
+ const abortControllerRef = useRef(null);
1461
+ const isRequestInProgressRef = useRef(false);
1462
+ const isMobile = useMediaQuery("(max-width: 768px)");
1463
+ const responsiveStyles = useMemo(
1464
+ () => ({
1465
+ modal: {
1466
+ width: isMobile ? "90%" : "700px"
1467
+ },
1468
+ content: {
1469
+ margin: isMobile ? "20px" : "22px"
1470
+ },
1471
+ title: {
1472
+ fontSize: isMobile ? "16px" : "18px"
1473
+ },
1474
+ subTitle: {
1475
+ fontSize: isMobile ? "14px" : "16px"
1476
+ },
1477
+ optionTitle: {
1478
+ fontSize: isMobile ? "14px" : "16px"
1479
+ },
1480
+ optionDescription: {
1481
+ fontSize: isMobile ? "12px" : "14px"
1482
+ },
1483
+ dataElementText: {
1484
+ fontSize: isMobile ? "12px" : "14px"
1485
+ },
1486
+ bottomSection: {
1487
+ flexDirection: isMobile ? "column" : "row",
1488
+ gap: isMobile ? "12px" : "16px"
1489
+ },
1490
+ privacyText: {
1491
+ fontSize: isMobile ? "14px" : "16px"
1492
+ },
1493
+ errorDialog: {
1494
+ padding: isMobile ? "12px" : "16px",
1495
+ maxWidth: isMobile ? "100%" : "400px",
1496
+ marginBottom: isMobile ? "16px" : "20px"
1497
+ },
1498
+ errorTitle: {
1499
+ fontSize: isMobile ? "16px" : "18px",
1500
+ margin: isMobile ? "0 0 8px 0" : "0 0 12px 0"
1501
+ },
1502
+ errorMessage: {
1503
+ fontSize: isMobile ? "12px" : "14px",
1504
+ margin: isMobile ? "0 0 12px 0" : "0 0 16px 0"
1505
+ },
1506
+ errorButton: {
1507
+ padding: isMobile ? "6px 12px" : "8px 16px",
1508
+ fontSize: isMobile ? "12px" : "14px"
1509
+ },
1510
+ closeButton: {
1511
+ top: isMobile ? "4px" : "8px",
1512
+ right: isMobile ? "4px" : "8px",
1513
+ padding: isMobile ? "2px" : "4px"
1514
+ },
1515
+ topRight: {
1516
+ fontSize: isMobile ? "11px" : "12px",
1517
+ padding: isMobile ? "3px 6px" : "3px 9px",
1518
+ height: isMobile ? "auto" : void 0,
1519
+ width: isMobile ? "auto" : void 0
1520
+ },
1521
+ languageItem: {
1522
+ fontSize: isMobile ? "11px" : "12px",
1523
+ padding: isMobile ? "6px 10px" : "8px 12px"
1524
+ },
1525
+ middleSection: {
1526
+ paddingRight: isMobile ? "10px" : "15px"
1527
+ },
1528
+ button: {
1529
+ fontSize: isMobile ? "14px" : "16px",
1530
+ padding: isMobile ? "10px 20px" : "9px 45px"
1531
+ }
1532
+ }),
1533
+ [isMobile]
1534
+ );
1535
+ const componentHeadingStyle = useMemo(
1536
+ () => ({
1537
+ color: (settings == null ? void 0 : settings.headingColor) || "#323B4B",
1538
+ fontFamily: (settings == null ? void 0 : settings.font) || "inherit"
1539
+ }),
1540
+ [settings == null ? void 0 : settings.headingColor, settings == null ? void 0 : settings.font]
1541
+ );
1542
+ const componentTextStyle = useMemo(
1543
+ () => ({
1544
+ color: (settings == null ? void 0 : settings.textColor) || "#344054",
1545
+ fontFamily: (settings == null ? void 0 : settings.font) || "inherit"
1546
+ }),
1547
+ [settings == null ? void 0 : settings.textColor, settings == null ? void 0 : settings.font]
1548
+ );
1549
+ const sectionStyle = useMemo(
1550
+ () => ({
1551
+ color: (settings == null ? void 0 : settings.textColor) || "#344054",
1552
+ fontFamily: (settings == null ? void 0 : settings.font) || "inherit"
1553
+ }),
1554
+ [settings == null ? void 0 : settings.textColor, settings == null ? void 0 : settings.font]
1555
+ );
1556
+ const areAllRequiredElementsChecked = useMemo(() => {
1557
+ if (!content) return false;
1558
+ return content.purposes.every((purpose) => {
1559
+ const requiredElements = purpose.data_elements.filter(
1560
+ (element) => element.required
1561
+ );
1562
+ return requiredElements.every(
1563
+ (element) => selectedDataElements[`${purpose.uuid}-${element.uuid}`]
1564
+ );
1565
+ });
1566
+ }, [content, selectedDataElements]);
1567
+ const acceptDisabled = isSubmitting || !areAllRequiredElementsChecked;
1568
+ useEffect2(() => {
1569
+ clearApiCache();
1570
+ isRequestInProgressRef.current = false;
1571
+ setContent(null);
1572
+ setCategorizedPurposes(null);
1573
+ setSelectedPurposes({});
1574
+ setSelectedDataElements({});
1575
+ setCollapsedPurposes({});
1576
+ setHasAlreadyConsented(false);
1577
+ setErrorMessage(null);
1578
+ setFetchError(null);
1579
+ setIsLoading(true);
1580
+ setShowAgeVerification(false);
1581
+ setShowGuardianForm(false);
1582
+ setIsSubmittingGuardian(false);
1583
+ setGuardianFormData({
1584
+ guardianName: "",
1585
+ guardianContact: "",
1586
+ guardianRelationship: ""
1587
+ });
1588
+ setGuardianFormErrors({});
1589
+ }, [accessToken]);
1590
+ useEffect2(() => {
1591
+ if (hasAlreadyConsented) {
1592
+ onAccept == null ? void 0 : onAccept();
1593
+ }
1594
+ }, [hasAlreadyConsented, onAccept]);
1595
+ const getTranslatedText = (key, defaultText, itemId) => {
1596
+ var _a2, _b2;
1597
+ if (!content) return defaultText;
1598
+ if (selectedLanguage === content.default_language) {
1599
+ if (key === "privacy_policy_anchor_text" && content.privacy_policy_anchor_text) {
1600
+ return content.privacy_policy_anchor_text;
1601
+ }
1602
+ return defaultText;
1603
+ }
1604
+ if (!content.supported_languages_and_translations) {
1605
+ return defaultText;
1606
+ }
1607
+ const translationMap = content.supported_languages_and_translations[selectedLanguage];
1608
+ if (!translationMap) {
1609
+ return defaultText;
1610
+ }
1611
+ if (itemId) {
1612
+ if (key === "purposes.name" || key === "purposes.description") {
1613
+ return ((_a2 = translationMap.purposes) == null ? void 0 : _a2[itemId]) || defaultText;
1614
+ }
1615
+ if (key.startsWith("data_elements.")) {
1616
+ return ((_b2 = translationMap.data_elements) == null ? void 0 : _b2[itemId]) || defaultText;
1617
+ }
1618
+ }
1619
+ const value = translationMap[key];
1620
+ if (typeof value === "string") {
1621
+ return value;
1622
+ }
1623
+ return defaultText;
1624
+ };
1625
+ const fetchNotice = async () => {
1626
+ var _a2;
1627
+ if (isRequestInProgressRef.current) {
1628
+ return;
1629
+ }
1630
+ isRequestInProgressRef.current = true;
1631
+ if (abortControllerRef.current) {
1632
+ abortControllerRef.current.abort();
1633
+ }
1634
+ abortControllerRef.current = new AbortController();
1635
+ setIsLoading(true);
1636
+ setFetchError(null);
1637
+ setShowAgeVerification(false);
1638
+ setShowGuardianForm(false);
1639
+ try {
1640
+ const consentContentData = await fetchConsentContent({
1641
+ noticeId,
1642
+ accessToken,
1643
+ refreshToken,
1644
+ baseUrl,
1645
+ language,
1646
+ specific_uuid: applicationId,
1647
+ check_mode: checkMode,
1648
+ signal: (_a2 = abortControllerRef.current) == null ? void 0 : _a2.signal
1649
+ });
1650
+ setContent(consentContentData.detail.active_config);
1651
+ if (consentContentData.detail.active_config.default_language) {
1652
+ setSelectedLanguage(
1653
+ consentContentData.detail.active_config.default_language
1654
+ );
1655
+ }
1656
+ const initialCollapsedState = consentContentData.detail.active_config.purposes.reduce(
1657
+ (acc, purpose) => ({
1658
+ ...acc,
1659
+ [purpose.uuid]: true
1660
+ }),
1661
+ {}
1662
+ );
1663
+ setCollapsedPurposes(initialCollapsedState);
1664
+ const isReconsentRequired = consentContentData.detail.reconsent_required;
1665
+ const purposeSelections = consentContentData.detail.purpose_selections;
1666
+ const newCategorizedPurposes = isReconsentRequired ? {
1667
+ alreadyConsented: consentContentData.detail.active_config.purposes.filter(
1668
+ (purpose) => {
1669
+ const selection = purposeSelections == null ? void 0 : purposeSelections[purpose.uuid];
1670
+ return selection && (selection.status === "ACTIVE" || selection.status === "EXPIRED") && !selection.needs_reconsent;
1671
+ }
1672
+ ),
1673
+ needsConsent: consentContentData.detail.active_config.purposes.filter(
1674
+ (purpose) => {
1675
+ const selection = purposeSelections == null ? void 0 : purposeSelections[purpose.uuid];
1676
+ return !selection || selection.status !== "ACTIVE" || selection.needs_reconsent;
1677
+ }
1678
+ )
1679
+ } : null;
1680
+ setCategorizedPurposes(newCategorizedPurposes);
1681
+ const initialPurposeState = consentContentData.detail.active_config.purposes.reduce(
1682
+ (acc, purpose) => {
1683
+ if (isReconsentRequired && (purposeSelections == null ? void 0 : purposeSelections[purpose.uuid])) {
1684
+ acc[purpose.uuid] = purposeSelections[purpose.uuid].selected;
1685
+ } else {
1686
+ acc[purpose.uuid] = false;
1687
+ }
1688
+ return acc;
1689
+ },
1690
+ {}
1691
+ );
1692
+ setSelectedPurposes(initialPurposeState);
1693
+ const initialDataElementState = consentContentData.detail.active_config.purposes.reduce(
1694
+ (acc, purpose) => {
1695
+ purpose.data_elements.forEach((element) => {
1696
+ var _a3, _b2;
1697
+ const combinedId = `${purpose.uuid}-${element.uuid}`;
1698
+ if (isReconsentRequired && ((_b2 = (_a3 = purposeSelections == null ? void 0 : purposeSelections[purpose.uuid]) == null ? void 0 : _a3.data_elements) == null ? void 0 : _b2[element.uuid])) {
1699
+ acc[combinedId] = purposeSelections[purpose.uuid].data_elements[element.uuid].selected;
1700
+ } else {
1701
+ acc[combinedId] = false;
1702
+ }
1703
+ });
1704
+ return acc;
1705
+ },
1706
+ {}
1707
+ );
1708
+ setSelectedDataElements(initialDataElementState);
1709
+ if (consentContentData.detail.is_minor) {
1710
+ setShowAgeVerification(true);
1711
+ }
1712
+ setIsLoading(false);
1713
+ } catch (err) {
1714
+ if (err instanceof Error && err.name === "AbortError") {
1715
+ console.log("Request was cancelled");
1716
+ return;
1717
+ }
1718
+ console.error(err);
1719
+ const error = err;
1720
+ setFetchError(error);
1721
+ if (error.status === 409) {
1722
+ setHasAlreadyConsented(true);
1723
+ } else {
1724
+ onError == null ? void 0 : onError(error);
1725
+ }
1726
+ setIsLoading(false);
1727
+ } finally {
1728
+ isRequestInProgressRef.current = false;
1729
+ }
1730
+ };
1731
+ useEffect2(() => {
1732
+ injectCheckboxStyles();
1733
+ fetchNotice();
1734
+ }, [
1735
+ noticeId,
1736
+ accessToken,
1737
+ refreshToken,
1738
+ language,
1739
+ applicationId,
1740
+ checkMode
1741
+ // Removed onError and isRefreshingToken from dependencies to prevent duplicate API calls
1742
+ // onError is only called on errors, not needed for initial data fetching
1743
+ ]);
1744
+ const togglePurposeCollapse = (purposeUuid) => {
1745
+ setCollapsedPurposes((prev) => ({
1746
+ ...prev,
1747
+ [purposeUuid]: !prev[purposeUuid]
1748
+ }));
1749
+ };
1750
+ const toggleLanguageDropdown = () => {
1751
+ setIsLanguageDropdownOpen(!isLanguageDropdownOpen);
1752
+ };
1753
+ const handleLanguageSelect = (lang) => {
1754
+ setSelectedLanguage(lang);
1755
+ setIsLanguageDropdownOpen(false);
1756
+ };
1757
+ const handlePurposeCheckboxChange = (purposeUuid) => {
1758
+ if (content) {
1759
+ const purpose = content.purposes.find((p) => p.uuid === purposeUuid);
1760
+ if (purpose) {
1761
+ const newPurposeState = !selectedPurposes[purposeUuid];
1762
+ setSelectedPurposes((prev) => ({
1763
+ ...prev,
1764
+ [purposeUuid]: newPurposeState
1765
+ }));
1766
+ setSelectedDataElements((prev) => {
1767
+ const updated = { ...prev };
1768
+ purpose.data_elements.forEach((el) => {
1769
+ updated[`${purposeUuid}-${el.uuid}`] = newPurposeState;
1770
+ });
1771
+ return updated;
1772
+ });
1773
+ }
1774
+ }
1775
+ };
1776
+ const handleDataElementCheckboxChange = (elementUuid, purposeUuid) => {
1777
+ if (!content) return;
1778
+ const combinedId = `${purposeUuid}-${elementUuid}`;
1779
+ setSelectedDataElements((prev) => {
1780
+ const newState = {
1781
+ ...prev,
1782
+ [combinedId]: !prev[combinedId]
1783
+ };
1784
+ const purpose = content.purposes.find((p) => p.uuid === purposeUuid);
1785
+ if (purpose) {
1786
+ const requiredElements = purpose.data_elements.filter(
1787
+ (el) => el.required
1788
+ );
1789
+ const allRequiredElementsChecked = requiredElements.every(
1790
+ (el) => newState[`${purposeUuid}-${el.uuid}`]
1791
+ );
1792
+ setSelectedPurposes((prevPurposes) => ({
1793
+ ...prevPurposes,
1794
+ [purposeUuid]: allRequiredElementsChecked
1795
+ }));
1796
+ }
1797
+ return newState;
1798
+ });
1799
+ };
1800
+ const handleAccept = async () => {
1801
+ const submitController = new AbortController();
1802
+ try {
1803
+ setIsSubmitting(true);
1804
+ setErrorMessage(null);
1805
+ if (content) {
1806
+ await submitConsentEvent({
1807
+ accessToken,
1808
+ baseUrl,
1809
+ noticeUuid: content.notice_uuid,
1810
+ purposes: content.purposes.map((purpose) => ({
1811
+ ...purpose,
1812
+ selected: selectedPurposes[purpose.uuid] || false,
1813
+ data_elements: purpose.data_elements.map((element) => ({
1814
+ ...element,
1815
+ selected: element.required ? true : selectedDataElements[`${purpose.uuid}-${element.uuid}`] || false
1816
+ }))
1817
+ })),
1818
+ declined: false,
1819
+ meta_data: applicationId ? { specific_uuid: applicationId } : void 0,
1820
+ signal: submitController.signal
1821
+ });
1822
+ }
1823
+ onAccept == null ? void 0 : onAccept();
1824
+ } catch (error) {
1825
+ if (error instanceof Error && error.name === "AbortError") {
1826
+ console.log("Consent submission was cancelled");
1827
+ return;
1828
+ }
1829
+ console.error("Error submitting consent:", error);
1830
+ const err = error;
1831
+ if (err.status === 500) {
1832
+ setErrorMessage(
1833
+ "An error occurred while submitting your consent. Please try again later."
1834
+ );
1835
+ }
1836
+ onError == null ? void 0 : onError(error);
1837
+ } finally {
1838
+ setIsSubmitting(false);
1839
+ }
1840
+ };
1841
+ const handleDecline = useCallback(async () => {
1842
+ onDecline == null ? void 0 : onDecline();
1843
+ }, [onDecline]);
1844
+ const handleGuardianFormChange = useCallback(
1845
+ (field, value) => {
1846
+ setGuardianFormData((prev) => ({
1847
+ ...prev,
1848
+ [field]: value
1849
+ }));
1850
+ if (guardianFormErrors[field]) {
1851
+ setGuardianFormErrors((prev) => ({
1852
+ ...prev,
1853
+ [field]: ""
1854
+ }));
1855
+ }
1856
+ },
1857
+ [guardianFormErrors]
1858
+ );
1859
+ const validateGuardianForm = () => {
1860
+ const errors = {};
1861
+ if (!guardianFormData.guardianName.trim()) {
1862
+ errors.guardianName = "Guardian name is required";
1863
+ }
1864
+ if (!guardianFormData.guardianContact.trim()) {
1865
+ errors.guardianContact = "Guardian contact is required";
1866
+ }
1867
+ if (!guardianFormData.guardianRelationship.trim()) {
1868
+ errors.guardianRelationship = "Relationship to guardian is required";
1869
+ }
1870
+ setGuardianFormErrors(errors);
1871
+ return Object.keys(errors).length === 0;
1872
+ };
1873
+ const handleGuardianFormNext = useCallback(async () => {
1874
+ if (!validateGuardianForm()) {
1875
+ return;
1876
+ }
1877
+ const guardianController = new AbortController();
1878
+ try {
1879
+ setIsSubmittingGuardian(true);
1880
+ setGuardianFormErrors({});
1881
+ await submitGuardianInfo({
1882
+ accessToken,
1883
+ baseUrl,
1884
+ guardianName: guardianFormData.guardianName,
1885
+ guardianContact: guardianFormData.guardianContact,
1886
+ guardianRelationship: guardianFormData.guardianRelationship,
1887
+ signal: guardianController.signal
1888
+ });
1889
+ setShowGuardianForm(false);
1890
+ } catch (error) {
1891
+ const err = error;
1892
+ if (err.status === 422) {
1893
+ if (err.message.includes("guardian_contact")) {
1894
+ setGuardianFormErrors({ guardianContact: err.message });
1895
+ } else if (err.message.includes("guardian_name")) {
1896
+ setGuardianFormErrors({ guardianName: err.message });
1897
+ } else if (err.message.includes("guardian_relationship")) {
1898
+ setGuardianFormErrors({ guardianRelationship: err.message });
1899
+ } else {
1900
+ setGuardianFormErrors({ general: err.message });
1901
+ }
1902
+ } else {
1903
+ setGuardianFormErrors({
1904
+ general: err.message || "Failed to submit guardian information. Please try again."
1905
+ });
1906
+ onError == null ? void 0 : onError(err);
1907
+ }
1908
+ } finally {
1909
+ setIsSubmittingGuardian(false);
1910
+ }
1911
+ }, [accessToken, baseUrl, guardianFormData, onError]);
1912
+ const handleAgeVerificationYes = useCallback(() => {
1913
+ setShowAgeVerification(false);
1914
+ }, []);
1915
+ const handleAgeVerificationNo = useCallback(() => {
1916
+ setShowAgeVerification(false);
1917
+ setShowGuardianForm(true);
1918
+ }, []);
1919
+ const availableLanguages = useMemo(
1920
+ () => content ? [
1921
+ content.default_language,
1922
+ ...Object.keys(content.supported_languages_and_translations || {})
1923
+ ].filter((value, index, self) => self.indexOf(value) === index) : [language],
1924
+ [content, language]
1925
+ );
1926
+ const modalStyle = {
1927
+ borderRadius: (settings == null ? void 0 : settings.borderRadius) || "8px",
1928
+ backgroundColor: (settings == null ? void 0 : settings.backgroundColor) || "#ffffff"
1929
+ };
1930
+ const buttonStyle = {
1931
+ borderRadius: (settings == null ? void 0 : settings.borderRadius) || "8px"
1932
+ };
1933
+ const acceptButtonStyle = {
1934
+ ...buttonStyle,
1935
+ backgroundColor: ((_b = (_a = settings == null ? void 0 : settings.button) == null ? void 0 : _a.accept) == null ? void 0 : _b.backgroundColor) || (content == null ? void 0 : content.primary_color) || "#4f87ff",
1936
+ color: ((_d = (_c = settings == null ? void 0 : settings.button) == null ? void 0 : _c.accept) == null ? void 0 : _d.textColor) || "#ffffff"
1937
+ };
1938
+ const declineButtonStyle = {
1939
+ ...buttonStyle,
1940
+ backgroundColor: ((_f = (_e = settings == null ? void 0 : settings.button) == null ? void 0 : _e.decline) == null ? void 0 : _f.backgroundColor) || "#ffffff",
1941
+ color: ((_h = (_g = settings == null ? void 0 : settings.button) == null ? void 0 : _g.decline) == null ? void 0 : _h.textColor) || "#000000",
1942
+ borderColor: (settings == null ? void 0 : settings.borderColor) || "#d0d5dd"
1943
+ };
1944
+ const linkStyle = {
1945
+ color: (settings == null ? void 0 : settings.link) || (content == null ? void 0 : content.secondary_color) || "#4f87ff"
1946
+ };
1947
+ const languageSelectorStyle = {
1948
+ borderRadius: (settings == null ? void 0 : settings.borderRadius) || "8px",
1949
+ borderColor: (settings == null ? void 0 : settings.borderColor) || "#d0d5dd",
1950
+ backgroundColor: ((_j = (_i = settings == null ? void 0 : settings.button) == null ? void 0 : _i.language) == null ? void 0 : _j.backgroundColor) || "#ffffff",
1951
+ color: ((_l = (_k = settings == null ? void 0 : settings.button) == null ? void 0 : _k.language) == null ? void 0 : _l.textColor) || "#344054"
1952
+ };
1953
+ const selectedLanguageItemStyle = {
1954
+ ...languageSelectorStyle,
1955
+ backgroundColor: ((_n = (_m = settings == null ? void 0 : settings.button) == null ? void 0 : _m.language) == null ? void 0 : _n.selectedBackgroundColor) || "#f3f4f6",
1956
+ color: ((_p = (_o = settings == null ? void 0 : settings.button) == null ? void 0 : _o.language) == null ? void 0 : _p.selectedTextColor) || "#344054",
1957
+ fontWeight: 600
1958
+ };
1959
+ const handleCloseError = () => {
1960
+ setErrorMessage(null);
1961
+ };
1962
+ useEffect2(() => {
1963
+ const handleKeyDown = (event) => {
1964
+ if (!modalRef.current) return;
1965
+ const focusableElements = modalRef.current.querySelectorAll(
1966
+ 'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
1967
+ );
1968
+ if (!focusableElements.length) return;
1969
+ if (event.key === "Escape") {
1970
+ handleDecline();
1971
+ }
1972
+ if (event.key === "Tab") {
1973
+ const firstElement = focusableElements[0];
1974
+ const lastElement = focusableElements[focusableElements.length - 1];
1975
+ if (event.shiftKey) {
1976
+ if (document.activeElement === firstElement) {
1977
+ event.preventDefault();
1978
+ lastElement.focus();
1979
+ }
1980
+ } else {
1981
+ if (document.activeElement === lastElement) {
1982
+ event.preventDefault();
1983
+ firstElement.focus();
1984
+ }
1985
+ }
1986
+ }
1987
+ };
1988
+ const modal = modalRef.current;
1989
+ modal == null ? void 0 : modal.addEventListener("keydown", handleKeyDown);
1990
+ if (modal && !isLoading) {
1991
+ const focusableElements = modal.querySelectorAll(
1992
+ 'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
1993
+ );
1994
+ const firstElement = focusableElements[0];
1995
+ firstElement == null ? void 0 : firstElement.focus();
1996
+ }
1997
+ return () => {
1998
+ modal == null ? void 0 : modal.removeEventListener("keydown", handleKeyDown);
1999
+ };
2000
+ }, [isLoading, handleDecline]);
2001
+ useEffect2(() => {
2002
+ return () => {
2003
+ if (abortControllerRef.current) {
2004
+ abortControllerRef.current.abort();
2005
+ }
2006
+ };
2007
+ }, []);
2008
+ return /* @__PURE__ */ jsx(Fragment, { children: hasAlreadyConsented ? null : /* @__PURE__ */ jsxs(Fragment, { children: [
2009
+ blockUI && /* @__PURE__ */ jsx(
2010
+ "div",
2011
+ {
2012
+ style: styles.overlay,
2013
+ "aria-hidden": "true",
2014
+ role: "presentation"
2015
+ }
2016
+ ),
2017
+ /* @__PURE__ */ jsx(
2018
+ "div",
2019
+ {
2020
+ ref: modalRef,
2021
+ style: {
2022
+ ...styles.modal,
2023
+ ...responsiveStyles.modal,
2024
+ ...modalStyle
2025
+ },
2026
+ role: "dialog",
2027
+ "aria-modal": "true",
2028
+ "aria-labelledby": "privacy-notice-title",
2029
+ "aria-describedby": "privacy-notice-description",
2030
+ tabIndex: -1,
2031
+ children: isLoading ? /* @__PURE__ */ jsxs(
2032
+ "div",
2033
+ {
2034
+ role: "status",
2035
+ "aria-live": "polite",
2036
+ "aria-label": "Loading consent notice",
2037
+ style: styles.loadingContainer,
2038
+ children: [
2039
+ /* @__PURE__ */ jsx("div", { style: styles.loadingSpinner, "aria-hidden": "true" }),
2040
+ /* @__PURE__ */ jsx("p", { style: { ...styles.privacyText, ...componentTextStyle }, children: "Loading..." })
2041
+ ]
2042
+ }
2043
+ ) : fetchError ? /* @__PURE__ */ jsx(
2044
+ "div",
2045
+ {
2046
+ role: "alert",
2047
+ "aria-live": "assertive",
2048
+ "aria-label": "Error loading consent notice",
2049
+ style: {
2050
+ ...styles.content,
2051
+ ...responsiveStyles.content,
2052
+ display: "flex",
2053
+ flexDirection: "column",
2054
+ alignItems: "center",
2055
+ justifyContent: "center",
2056
+ textAlign: "center",
2057
+ padding: "40px 20px"
2058
+ },
2059
+ children: /* @__PURE__ */ jsxs(
2060
+ "div",
2061
+ {
2062
+ style: {
2063
+ color: "#DC2626",
2064
+ padding: responsiveStyles.errorDialog.padding,
2065
+ borderRadius: "8px",
2066
+ marginBottom: responsiveStyles.errorDialog.marginBottom,
2067
+ width: "100%",
2068
+ maxWidth: responsiveStyles.errorDialog.maxWidth,
2069
+ position: "relative"
2070
+ },
2071
+ children: [
2072
+ /* @__PURE__ */ jsx(
2073
+ "button",
2074
+ {
2075
+ onClick: handleDecline,
2076
+ style: {
2077
+ position: "absolute",
2078
+ top: responsiveStyles.closeButton.top,
2079
+ right: responsiveStyles.closeButton.right,
2080
+ background: "none",
2081
+ border: "none",
2082
+ color: "#DC2626",
2083
+ cursor: "pointer",
2084
+ padding: responsiveStyles.closeButton.padding,
2085
+ display: "flex",
2086
+ alignItems: "center",
2087
+ justifyContent: "center"
2088
+ },
2089
+ "aria-label": "Close error message",
2090
+ children: /* @__PURE__ */ jsx(
2091
+ "svg",
2092
+ {
2093
+ width: isMobile ? "14" : "16",
2094
+ height: isMobile ? "14" : "16",
2095
+ viewBox: "0 0 16 16",
2096
+ fill: "none",
2097
+ xmlns: "http://www.w3.org/2000/svg",
2098
+ "aria-hidden": "true",
2099
+ children: /* @__PURE__ */ jsx(
2100
+ "path",
2101
+ {
2102
+ d: "M12 4L4 12M4 4L12 12",
2103
+ stroke: "currentColor",
2104
+ strokeWidth: "2",
2105
+ strokeLinecap: "round",
2106
+ strokeLinejoin: "round"
2107
+ }
2108
+ )
2109
+ }
2110
+ )
2111
+ }
2112
+ ),
2113
+ /* @__PURE__ */ jsx(
2114
+ "h3",
2115
+ {
2116
+ style: {
2117
+ margin: responsiveStyles.errorTitle.margin,
2118
+ fontSize: responsiveStyles.errorTitle.fontSize,
2119
+ fontWeight: "600"
2120
+ },
2121
+ children: "Error Loading Consent Notice"
2122
+ }
2123
+ ),
2124
+ /* @__PURE__ */ jsx(
2125
+ "p",
2126
+ {
2127
+ style: {
2128
+ margin: responsiveStyles.errorMessage.margin,
2129
+ fontSize: responsiveStyles.errorMessage.fontSize,
2130
+ lineHeight: "1.5"
2131
+ },
2132
+ children: fetchError.message || "Failed to load consent notice. Please try again."
2133
+ }
2134
+ ),
2135
+ /* @__PURE__ */ jsx(
2136
+ "button",
2137
+ {
2138
+ onClick: fetchNotice,
2139
+ style: {
2140
+ backgroundColor: "#DC2626",
2141
+ color: "#FFFFFF",
2142
+ border: "none",
2143
+ padding: responsiveStyles.errorButton.padding,
2144
+ borderRadius: "6px",
2145
+ cursor: "pointer",
2146
+ fontSize: responsiveStyles.errorButton.fontSize,
2147
+ fontWeight: "500",
2148
+ transition: "background-color 0.2s"
2149
+ },
2150
+ onMouseOver: (e) => e.currentTarget.style.backgroundColor = "#B91C1C",
2151
+ onMouseOut: (e) => e.currentTarget.style.backgroundColor = "#DC2626",
2152
+ children: "Refresh"
2153
+ }
2154
+ )
2155
+ ]
2156
+ }
2157
+ )
2158
+ }
2159
+ ) : showAgeVerification ? /* @__PURE__ */ jsx("div", { style: { ...styles.content, ...responsiveStyles.content }, children: /* @__PURE__ */ jsx(
2160
+ AgeVerification,
2161
+ {
2162
+ onYes: handleAgeVerificationYes,
2163
+ onNo: handleAgeVerificationNo,
2164
+ onClose: handleDecline,
2165
+ styles,
2166
+ responsiveStyles,
2167
+ componentHeadingStyle,
2168
+ componentTextStyle,
2169
+ acceptButtonStyle,
2170
+ declineButtonStyle,
2171
+ logoUrl: (content == null ? void 0 : content.logo_url) || redacto_logo_default,
2172
+ isMobile
2173
+ }
2174
+ ) }) : showGuardianForm ? /* @__PURE__ */ jsx("div", { style: { ...styles.content, ...responsiveStyles.content }, children: /* @__PURE__ */ jsx(
2175
+ GuardianForm,
2176
+ {
2177
+ formData: guardianFormData,
2178
+ errors: guardianFormErrors,
2179
+ isSubmitting: isSubmittingGuardian,
2180
+ onChange: handleGuardianFormChange,
2181
+ onNext: handleGuardianFormNext,
2182
+ onDecline: handleDecline,
2183
+ styles,
2184
+ responsiveStyles,
2185
+ settings,
2186
+ componentHeadingStyle,
2187
+ componentTextStyle,
2188
+ acceptButtonStyle,
2189
+ declineButtonStyle,
2190
+ logoUrl: (content == null ? void 0 : content.logo_url) || redacto_logo_default
2191
+ }
2192
+ ) }) : /* @__PURE__ */ jsxs("div", { style: { ...styles.content, ...responsiveStyles.content }, children: [
2193
+ errorMessage && /* @__PURE__ */ jsxs(
2194
+ "div",
2195
+ {
2196
+ role: "alert",
2197
+ style: {
2198
+ backgroundColor: "#FEE2E2",
2199
+ color: "#DC2626",
2200
+ padding: "12px",
2201
+ borderRadius: "6px",
2202
+ marginBottom: "16px",
2203
+ fontSize: "14px",
2204
+ border: "1px solid #FCA5A5",
2205
+ position: "relative",
2206
+ display: "flex",
2207
+ alignItems: "center",
2208
+ justifyContent: "space-between"
2209
+ },
2210
+ children: [
2211
+ /* @__PURE__ */ jsx("span", { children: errorMessage }),
2212
+ /* @__PURE__ */ jsx(
2213
+ "button",
2214
+ {
2215
+ type: "button",
2216
+ onClick: handleCloseError,
2217
+ style: {
2218
+ background: "none",
2219
+ border: "none",
2220
+ color: "#DC2626",
2221
+ cursor: "pointer",
2222
+ padding: "4px",
2223
+ marginLeft: "8px",
2224
+ display: "flex",
2225
+ alignItems: "center",
2226
+ justifyContent: "center"
2227
+ },
2228
+ "aria-label": "Close error message",
2229
+ children: /* @__PURE__ */ jsx(
2230
+ "svg",
2231
+ {
2232
+ width: "16",
2233
+ height: "16",
2234
+ viewBox: "0 0 16 16",
2235
+ fill: "none",
2236
+ xmlns: "http://www.w3.org/2000/svg",
2237
+ "aria-hidden": "true",
2238
+ children: /* @__PURE__ */ jsx(
2239
+ "path",
2240
+ {
2241
+ d: "M12 4L4 12M4 4L12 12",
2242
+ stroke: "currentColor",
2243
+ strokeWidth: "2",
2244
+ strokeLinecap: "round",
2245
+ strokeLinejoin: "round"
2246
+ }
2247
+ )
2248
+ }
2249
+ )
2250
+ }
2251
+ )
2252
+ ]
2253
+ }
2254
+ ),
2255
+ /* @__PURE__ */ jsxs("div", { style: { ...styles.topSection, ...sectionStyle }, children: [
2256
+ /* @__PURE__ */ jsxs("div", { style: styles.topLeft, children: [
2257
+ /* @__PURE__ */ jsx(
2258
+ "img",
2259
+ {
2260
+ style: styles.logo,
2261
+ src: (content == null ? void 0 : content.logo_url) || redacto_logo_default,
2262
+ alt: "Redacto Logo"
2263
+ }
2264
+ ),
2265
+ /* @__PURE__ */ jsx(
2266
+ "h2",
2267
+ {
2268
+ id: "privacy-notice-title",
2269
+ style: {
2270
+ ...styles.title,
2271
+ ...responsiveStyles.title,
2272
+ ...componentHeadingStyle
2273
+ },
2274
+ children: content == null ? void 0 : content.notice_banner_heading
2275
+ }
2276
+ )
2277
+ ] }),
2278
+ /* @__PURE__ */ jsxs("div", { style: styles.languageSelectorContainer, children: [
2279
+ /* @__PURE__ */ jsxs(
2280
+ "div",
2281
+ {
2282
+ style: {
2283
+ display: "flex",
2284
+ alignItems: "center",
2285
+ gap: "8px"
2286
+ },
2287
+ children: [
2288
+ /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsxs(
2289
+ "button",
2290
+ {
2291
+ ref: firstFocusableRef,
2292
+ style: {
2293
+ ...styles.topRight,
2294
+ ...responsiveStyles.topRight,
2295
+ ...languageSelectorStyle
2296
+ },
2297
+ onClick: toggleLanguageDropdown,
2298
+ "aria-expanded": isLanguageDropdownOpen,
2299
+ "aria-haspopup": "listbox",
2300
+ "aria-controls": "language-listbox",
2301
+ children: [
2302
+ selectedLanguage,
2303
+ /* @__PURE__ */ jsx(
2304
+ "svg",
2305
+ {
2306
+ xmlns: "http://www.w3.org/2000/svg",
2307
+ width: "16",
2308
+ height: "16",
2309
+ viewBox: "0 0 16 16",
2310
+ fill: "none",
2311
+ stroke: ((_r = (_q = settings == null ? void 0 : settings.button) == null ? void 0 : _q.language) == null ? void 0 : _r.textColor) || "currentColor",
2312
+ strokeWidth: "2",
2313
+ strokeLinecap: "round",
2314
+ strokeLinejoin: "round",
2315
+ style: { flexShrink: 0, marginLeft: "4px" },
2316
+ "aria-hidden": "true",
2317
+ children: /* @__PURE__ */ jsx("path", { d: "M4 6l4 4 4-4" })
2318
+ }
2319
+ )
2320
+ ]
2321
+ }
2322
+ ) }),
2323
+ /* @__PURE__ */ jsx(
2324
+ "button",
2325
+ {
2326
+ style: {
2327
+ ...styles.topRight,
2328
+ ...responsiveStyles.topRight,
2329
+ ...languageSelectorStyle,
2330
+ padding: "3px 9px"
2331
+ },
2332
+ "aria-label": "Talkback",
2333
+ title: "Talkback",
2334
+ children: /* @__PURE__ */ jsxs(
2335
+ "svg",
2336
+ {
2337
+ xmlns: "http://www.w3.org/2000/svg",
2338
+ width: "16",
2339
+ height: "16",
2340
+ viewBox: "0 0 24 24",
2341
+ fill: "none",
2342
+ stroke: ((_t = (_s = settings == null ? void 0 : settings.button) == null ? void 0 : _s.language) == null ? void 0 : _t.textColor) || "currentColor",
2343
+ strokeWidth: "2",
2344
+ strokeLinecap: "round",
2345
+ strokeLinejoin: "round",
2346
+ "aria-hidden": "true",
2347
+ children: [
2348
+ /* @__PURE__ */ jsx("path", { d: "M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z" }),
2349
+ /* @__PURE__ */ jsx("path", { d: "M19 10v2a7 7 0 0 1-14 0v-2" }),
2350
+ /* @__PURE__ */ jsx("line", { x1: "12", y1: "19", x2: "12", y2: "23" }),
2351
+ /* @__PURE__ */ jsx("line", { x1: "8", y1: "23", x2: "16", y2: "23" })
2352
+ ]
2353
+ }
2354
+ )
2355
+ }
2356
+ )
2357
+ ]
2358
+ }
2359
+ ),
2360
+ isLanguageDropdownOpen && /* @__PURE__ */ jsx(
2361
+ "ul",
2362
+ {
2363
+ id: "language-listbox",
2364
+ style: {
2365
+ ...styles.languageDropdown,
2366
+ ...languageSelectorStyle
2367
+ },
2368
+ role: "listbox",
2369
+ "aria-label": "Select language",
2370
+ children: availableLanguages.map((lang) => /* @__PURE__ */ jsx(
2371
+ "li",
2372
+ {
2373
+ style: {
2374
+ ...styles.languageItem,
2375
+ ...responsiveStyles.languageItem,
2376
+ ...selectedLanguage === lang ? selectedLanguageItemStyle : languageSelectorStyle,
2377
+ listStyle: "none"
2378
+ },
2379
+ onClick: () => handleLanguageSelect(lang),
2380
+ role: "option",
2381
+ "aria-selected": selectedLanguage === lang,
2382
+ tabIndex: 0,
2383
+ children: lang
2384
+ },
2385
+ lang
2386
+ ))
2387
+ }
2388
+ )
2389
+ ] })
2390
+ ] }),
2391
+ /* @__PURE__ */ jsxs(
2392
+ "div",
2393
+ {
2394
+ id: "privacy-notice-description",
2395
+ style: {
2396
+ ...styles.middleSection,
2397
+ ...responsiveStyles.middleSection,
2398
+ ...sectionStyle
2399
+ },
2400
+ children: [
2401
+ /* @__PURE__ */ jsxs(
2402
+ "p",
2403
+ {
2404
+ style: {
2405
+ ...styles.privacyText,
2406
+ ...responsiveStyles.privacyText,
2407
+ ...componentTextStyle
2408
+ },
2409
+ children: [
2410
+ content ? getTranslatedText("notice_text", content.notice_text) : "",
2411
+ /* @__PURE__ */ jsx("br", {}),
2412
+ "Learn more in our",
2413
+ " ",
2414
+ /* @__PURE__ */ jsxs(
2415
+ "a",
2416
+ {
2417
+ style: { ...styles.link, ...linkStyle },
2418
+ href: (content == null ? void 0 : content.privacy_policy_url) || "#",
2419
+ target: "_blank",
2420
+ rel: "noopener noreferrer",
2421
+ "aria-label": "Privacy Policy (opens in new tab)",
2422
+ children: [
2423
+ "[",
2424
+ getTranslatedText(
2425
+ "privacy_policy_anchor_text",
2426
+ (content == null ? void 0 : content.privacy_policy_anchor_text) || "Privacy Policy"
2427
+ ),
2428
+ "]"
2429
+ ]
2430
+ }
2431
+ ),
2432
+ " ",
2433
+ "and",
2434
+ " ",
2435
+ /* @__PURE__ */ jsxs(
2436
+ "a",
2437
+ {
2438
+ style: { ...styles.link, ...linkStyle },
2439
+ href: (content == null ? void 0 : content.sub_processors_url) || "#",
2440
+ target: "_blank",
2441
+ rel: "noopener noreferrer",
2442
+ "aria-label": "Vendors List (opens in new tab)",
2443
+ children: [
2444
+ "[",
2445
+ getTranslatedText(
2446
+ "vendors_list_anchor_text",
2447
+ (content == null ? void 0 : content.vendors_list_anchor_text) || "Vendors List"
2448
+ ),
2449
+ "]"
2450
+ ]
2451
+ }
2452
+ ),
2453
+ "."
2454
+ ]
2455
+ }
2456
+ ),
2457
+ /* @__PURE__ */ jsx(
2458
+ "h2",
2459
+ {
2460
+ style: {
2461
+ ...styles.subTitle,
2462
+ ...responsiveStyles.subTitle,
2463
+ ...componentHeadingStyle
2464
+ },
2465
+ children: getTranslatedText(
2466
+ "purpose_section_heading",
2467
+ "Manage What You Share"
2468
+ )
2469
+ }
2470
+ ),
2471
+ categorizedPurposes ? /* @__PURE__ */ jsxs("div", { style: styles.optionsContainer, children: [
2472
+ categorizedPurposes.alreadyConsented.map((purpose) => /* @__PURE__ */ jsx(
2473
+ PurposeItem,
2474
+ {
2475
+ purpose,
2476
+ selectedPurposes,
2477
+ collapsedPurposes,
2478
+ selectedDataElements,
2479
+ settings,
2480
+ styles,
2481
+ responsiveStyles,
2482
+ onPurposeToggle: handlePurposeCheckboxChange,
2483
+ onPurposeCollapse: togglePurposeCollapse,
2484
+ onDataElementToggle: handleDataElementCheckboxChange,
2485
+ getTranslatedText,
2486
+ isAlreadyConsented: true
2487
+ },
2488
+ purpose.uuid
2489
+ )),
2490
+ categorizedPurposes.needsConsent.map((purpose) => /* @__PURE__ */ jsx(
2491
+ PurposeItem,
2492
+ {
2493
+ purpose,
2494
+ selectedPurposes,
2495
+ collapsedPurposes,
2496
+ selectedDataElements,
2497
+ settings,
2498
+ styles,
2499
+ responsiveStyles,
2500
+ onPurposeToggle: handlePurposeCheckboxChange,
2501
+ onPurposeCollapse: togglePurposeCollapse,
2502
+ onDataElementToggle: handleDataElementCheckboxChange,
2503
+ getTranslatedText,
2504
+ isAlreadyConsented: false
2505
+ },
2506
+ purpose.uuid
2507
+ ))
2508
+ ] }) : (
2509
+ /* Regular consent UI */
2510
+ /* @__PURE__ */ jsx("div", { style: styles.optionsContainer, children: (_u = content == null ? void 0 : content.purposes) == null ? void 0 : _u.map((purpose) => /* @__PURE__ */ jsx(
2511
+ PurposeItem,
2512
+ {
2513
+ purpose,
2514
+ selectedPurposes,
2515
+ collapsedPurposes,
2516
+ selectedDataElements,
2517
+ settings,
2518
+ styles,
2519
+ responsiveStyles,
2520
+ onPurposeToggle: handlePurposeCheckboxChange,
2521
+ onPurposeCollapse: togglePurposeCollapse,
2522
+ onDataElementToggle: handleDataElementCheckboxChange,
2523
+ getTranslatedText,
2524
+ isAlreadyConsented: false
2525
+ },
2526
+ purpose.uuid
2527
+ )) })
2528
+ )
2529
+ ]
2530
+ }
2531
+ ),
2532
+ /* @__PURE__ */ jsxs(
2533
+ "div",
2534
+ {
2535
+ style: {
2536
+ ...styles.bottomSection,
2537
+ ...responsiveStyles.bottomSection,
2538
+ ...sectionStyle
2539
+ },
2540
+ children: [
2541
+ /* @__PURE__ */ jsx(
2542
+ "button",
2543
+ {
2544
+ ref: lastFocusableRef,
2545
+ style: {
2546
+ ...styles.button,
2547
+ ...responsiveStyles.button,
2548
+ ...styles.acceptButton,
2549
+ ...acceptButtonStyle,
2550
+ opacity: acceptDisabled ? 0.5 : 1
2551
+ },
2552
+ onClick: handleAccept,
2553
+ disabled: acceptDisabled,
2554
+ "aria-label": getTranslatedText(
2555
+ "confirm_button_text",
2556
+ (content == null ? void 0 : content.confirm_button_text) || "Accept"
2557
+ ),
2558
+ children: isSubmitting ? "Processing..." : getTranslatedText(
2559
+ "confirm_button_text",
2560
+ (content == null ? void 0 : content.confirm_button_text) || "Accept"
2561
+ )
2562
+ }
2563
+ ),
2564
+ /* @__PURE__ */ jsx(
2565
+ "button",
2566
+ {
2567
+ style: {
2568
+ ...styles.button,
2569
+ ...responsiveStyles.button,
2570
+ ...styles.cancelButton,
2571
+ ...declineButtonStyle
2572
+ },
2573
+ onClick: handleDecline,
2574
+ disabled: isSubmitting,
2575
+ "aria-label": getTranslatedText(
2576
+ "decline_button_text",
2577
+ (content == null ? void 0 : content.decline_button_text) || "Decline"
2578
+ ),
2579
+ children: isSubmitting ? "Processing..." : getTranslatedText(
2580
+ "decline_button_text",
2581
+ (content == null ? void 0 : content.decline_button_text) || "Decline"
2582
+ )
2583
+ }
2584
+ )
2585
+ ]
2586
+ }
2587
+ )
2588
+ ] })
2589
+ }
2590
+ )
2591
+ ] }) });
2592
+ };
2593
+
2594
+ // src/RedactoNoticeConsentInline/RedactoNoticeConsentInline.tsx
2595
+ import {
2596
+ useEffect as useEffect4,
2597
+ useMemo as useMemo2,
2598
+ useState as useState4,
2599
+ useImperativeHandle,
2600
+ forwardRef,
2601
+ memo
2602
+ } from "react";
2603
+
2604
+ // src/RedactoNoticeConsentInline/api/index.ts
2605
+ var BASE_URL2 = "https://api.redacto.tech/consent";
2606
+ var fetchConsentContent2 = async ({
2607
+ org_uuid,
2608
+ workspace_uuid,
2609
+ notice_uuid,
2610
+ baseUrl,
2611
+ language = "en",
2612
+ specific_uuid
2613
+ }) => {
2614
+ try {
2615
+ const apiBaseUrl = baseUrl || BASE_URL2;
2616
+ const url = new URL(
2617
+ `${apiBaseUrl}/public/organisations/${org_uuid}/workspaces/${workspace_uuid}/notices/get-notice/${notice_uuid}`
2618
+ );
2619
+ if (specific_uuid) {
2620
+ url.searchParams.append("specific_uuid", specific_uuid);
2621
+ }
2622
+ const response = await fetch(url.toString(), {
2623
+ method: "GET",
2624
+ headers: {
2625
+ "Content-Type": "application/json"
2626
+ }
2627
+ });
2628
+ if (response.status === 401) {
2629
+ const error = new Error("Unauthorized");
2630
+ error.status = 401;
2631
+ throw error;
2632
+ }
2633
+ if (response.status === 409) {
2634
+ const error = new Error("User has already provided consent");
2635
+ error.status = 409;
2636
+ throw error;
2637
+ }
2638
+ if (!response.ok) {
2639
+ throw new Error(
2640
+ `Failed to fetch consent content: ${response.statusText}`
2641
+ );
2642
+ }
2643
+ const data = await response.json();
2644
+ return data;
2645
+ } catch (error) {
2646
+ console.error("Error fetching consent content:", error);
2647
+ throw error;
2648
+ }
2649
+ };
2650
+ var submitConsentEvent2 = async ({
2651
+ org_uuid,
2652
+ workspace_uuid,
2653
+ accessToken,
2654
+ baseUrl,
2655
+ noticeUuid,
2656
+ purposes,
2657
+ declined,
2658
+ meta_data
2659
+ }) => {
2660
+ var _a, _b;
2661
+ try {
2662
+ const primaryEmail = localStorage.getItem("userEmail");
2663
+ const primaryMobile = localStorage.getItem("userMobile");
2664
+ const payload = {
2665
+ primary_email: primaryEmail || void 0,
2666
+ primary_mobile: primaryMobile || void 0,
2667
+ notice_uuid: noticeUuid,
2668
+ source: "WEB",
2669
+ declined,
2670
+ consents: {
2671
+ purposes: purposes.map((purpose) => ({
2672
+ uuid: purpose.uuid,
2673
+ name: purpose.name,
2674
+ description: purpose.description,
2675
+ industries: purpose.industries || "",
2676
+ selected: purpose.selected,
2677
+ data_elements: purpose.data_elements.map((element) => ({
2678
+ uuid: element.uuid,
2679
+ name: element.name,
2680
+ enabled: element.enabled,
2681
+ required: element.required,
2682
+ selected: element.required ? true : element.selected
2683
+ }))
2684
+ }))
2685
+ },
2686
+ meta_data
2687
+ };
2688
+ const apiBaseUrl = baseUrl || BASE_URL2;
2689
+ const response = await fetch(
2690
+ `${apiBaseUrl}/public/organisations/${org_uuid}/workspaces/${workspace_uuid}/by-token`,
2691
+ {
2692
+ method: "POST",
2693
+ headers: {
2694
+ Authorization: `Bearer ${accessToken}`,
2695
+ "Content-Type": "application/json"
2696
+ },
2697
+ body: JSON.stringify(payload)
2698
+ }
2699
+ );
2700
+ if (!response.ok) {
2701
+ let errorData;
2702
+ try {
2703
+ errorData = await response.json();
2704
+ } catch {
2705
+ errorData = { message: response.statusText };
2706
+ }
2707
+ if (response.status === 409) {
2708
+ const error2 = new Error(
2709
+ ((_a = errorData.detail) == null ? void 0 : _a.message) || errorData.message || "User has already provided consent"
2710
+ );
2711
+ error2.status = 409;
2712
+ error2.code = errorData.code || 409;
2713
+ error2.detail = errorData.detail;
2714
+ throw error2;
2715
+ }
2716
+ const error = new Error(
2717
+ ((_b = errorData.detail) == null ? void 0 : _b.message) || errorData.message || `Failed to submit consent event: ${response.statusText}`
2718
+ );
2719
+ error.status = response.status;
2720
+ error.code = errorData.code;
2721
+ error.detail = errorData.detail;
2722
+ throw error;
2723
+ }
2724
+ } catch (error) {
2725
+ console.error("Error submitting consent event:", error);
2726
+ throw error;
2727
+ }
2728
+ };
2729
+
2730
+ // src/RedactoNoticeConsentInline/styles.ts
2731
+ var styles2 = {
2732
+ overlay: {
2733
+ position: "fixed",
2734
+ top: 0,
2735
+ left: 0,
2736
+ width: "100%",
2737
+ height: "100%",
2738
+ backgroundColor: "rgba(0, 0, 0, 0.5)",
2739
+ display: "flex",
2740
+ alignItems: "center",
2741
+ justifyContent: "center",
2742
+ zIndex: 999,
2743
+ animation: "overlayFadeIn 0.2s cubic-bezier(0.16, 1, 0.3, 1)",
2744
+ pointerEvents: "all",
2745
+ margin: 0,
2746
+ padding: 0,
2747
+ boxSizing: "border-box"
2748
+ },
2749
+ container: {
2750
+ position: "relative",
2751
+ width: "100%",
2752
+ maxWidth: "700px",
2753
+ borderRadius: "8px",
2754
+ backgroundColor: "#ffffff",
2755
+ boxShadow: "0px 1px 3px rgba(0, 0, 0, 0.1)",
2756
+ border: "1px solid #e5e7eb",
2757
+ display: "flex",
2758
+ flexDirection: "column",
2759
+ margin: 0,
2760
+ padding: 0,
2761
+ boxSizing: "border-box",
2762
+ textAlign: "left",
2763
+ fontFamily: "inherit"
2764
+ },
2765
+ content: {
2766
+ margin: "22px",
2767
+ display: "flex",
2768
+ flexDirection: "column",
2769
+ flexGrow: 1,
2770
+ overflow: "hidden",
2771
+ minHeight: 0,
2772
+ boxSizing: "border-box",
2773
+ textAlign: "left"
2774
+ },
2775
+ topSection: {
2776
+ display: "flex",
2777
+ justifyContent: "space-between",
2778
+ alignItems: "center",
2779
+ paddingBottom: "15px",
2780
+ borderBottom: "1px solid #e5e7eb",
2781
+ boxShadow: "0 1px 2px rgba(0, 0, 0, 0.03)",
2782
+ backgroundColor: "#ffffff",
2783
+ margin: 0,
2784
+ boxSizing: "border-box",
2785
+ textAlign: "left"
2786
+ },
2787
+ topLeft: {
2788
+ display: "flex",
2789
+ alignItems: "center",
2790
+ gap: "10px",
2791
+ margin: 0,
2792
+ padding: 0,
2793
+ boxSizing: "border-box"
2794
+ },
2795
+ logo: {
2796
+ height: "32px",
2797
+ width: "auto",
2798
+ objectFit: "contain",
2799
+ margin: 0,
2800
+ padding: 0,
2801
+ display: "block"
2802
+ },
2803
+ title: {
2804
+ fontSize: "18px",
2805
+ fontWeight: 700,
2806
+ lineHeight: "150%",
2807
+ letterSpacing: "0.2px",
2808
+ verticalAlign: "middle",
2809
+ color: "#101828",
2810
+ margin: 0,
2811
+ padding: 0,
2812
+ textAlign: "left"
2813
+ },
2814
+ topRight: {
2815
+ borderRadius: "8px",
2816
+ padding: "3px 9px",
2817
+ border: "1px solid #d0d5dd",
2818
+ display: "flex",
2819
+ alignItems: "center",
2820
+ justifyContent: "center",
2821
+ fontWeight: 400,
2822
+ fontSize: "12px",
2823
+ lineHeight: "150%",
2824
+ letterSpacing: "0.2px",
2825
+ verticalAlign: "middle",
2826
+ color: "#344054",
2827
+ gap: "5px",
2828
+ margin: 0,
2829
+ boxSizing: "border-box",
2830
+ textAlign: "left",
2831
+ cursor: "pointer",
2832
+ backgroundColor: "#ffffff"
2833
+ },
2834
+ middleSection: {
2835
+ margin: "20px 0px",
2836
+ display: "flex",
2837
+ flexDirection: "column",
2838
+ gap: "12px",
2839
+ flexGrow: 1,
2840
+ overflowY: "auto",
2841
+ minHeight: 0,
2842
+ paddingRight: "15px",
2843
+ boxSizing: "border-box",
2844
+ textAlign: "left"
2845
+ },
2846
+ privacyText: {
2847
+ fontSize: "16px",
2848
+ fontWeight: 400,
2849
+ lineHeight: "150%",
2850
+ letterSpacing: "0.2px",
2851
+ color: "#344054",
2852
+ margin: 0,
2853
+ padding: 0,
2854
+ textAlign: "left"
2855
+ },
2856
+ link: {
2857
+ color: "#4f87ff",
2858
+ textDecoration: "none",
2859
+ margin: 0,
2860
+ padding: 0,
2861
+ boxSizing: "border-box"
2862
+ },
2863
+ subTitle: {
2864
+ fontWeight: 600,
2865
+ fontSize: "16px",
2866
+ lineHeight: "150%",
2867
+ letterSpacing: "0.2px",
2868
+ color: "#101828",
2869
+ margin: 0,
2870
+ padding: 0,
2871
+ textAlign: "left"
2872
+ },
2873
+ optionsContainer: {
2874
+ display: "flex",
2875
+ flexDirection: "column",
2876
+ gap: "14px",
2877
+ margin: 0,
2878
+ padding: 0,
2879
+ boxSizing: "border-box"
2880
+ },
2881
+ optionItem: {
2882
+ display: "flex",
2883
+ justifyContent: "space-between",
2884
+ alignItems: "center",
2885
+ margin: 0,
2886
+ padding: 0,
2887
+ boxSizing: "border-box"
2888
+ },
2889
+ optionLeft: {
2890
+ display: "flex",
2891
+ gap: "12px",
2892
+ alignItems: "center",
2893
+ cursor: "pointer",
2894
+ margin: 0,
2895
+ padding: 0,
2896
+ boxSizing: "border-box"
2897
+ },
2898
+ optionTextContainer: {
2899
+ display: "flex",
2900
+ flexDirection: "column",
2901
+ margin: 0,
2902
+ padding: 0,
2903
+ boxSizing: "border-box"
2904
+ },
2905
+ optionTitle: {
2906
+ fontWeight: 500,
2907
+ fontSize: "16px",
2908
+ lineHeight: "150%",
2909
+ letterSpacing: "0.2px",
2910
+ color: "#101828",
2911
+ margin: 0,
2912
+ padding: 0,
2913
+ textAlign: "left"
2914
+ },
2915
+ optionDescription: {
2916
+ fontWeight: 400,
2917
+ fontSize: "12px",
2918
+ lineHeight: "150%",
2919
+ letterSpacing: "0.2px",
2920
+ color: "#475467",
2921
+ verticalAlign: "middle",
2922
+ margin: 0,
2923
+ padding: 0,
2924
+ textAlign: "left"
2925
+ },
2926
+ checkboxLarge: {
2927
+ height: "20px",
2928
+ width: "20px",
2929
+ padding: "4px",
2930
+ borderRadius: "5px",
2931
+ border: "2px solid #d0d5dd",
2932
+ margin: 0,
2933
+ boxSizing: "border-box",
2934
+ appearance: "none",
2935
+ WebkitAppearance: "none",
2936
+ MozAppearance: "none",
2937
+ cursor: "pointer",
2938
+ position: "relative",
2939
+ backgroundColor: "transparent"
2940
+ },
2941
+ dataElementsContainer: {
2942
+ marginLeft: "27px",
2943
+ display: "flex",
2944
+ flexDirection: "column",
2945
+ margin: 0,
2946
+ padding: 0,
2947
+ boxSizing: "border-box",
2948
+ paddingLeft: "22px"
2949
+ },
2950
+ dataElementItem: {
2951
+ display: "flex",
2952
+ alignItems: "center",
2953
+ gap: "10px",
2954
+ justifyContent: "space-between",
2955
+ margin: 0,
2956
+ padding: 0,
2957
+ boxSizing: "border-box",
2958
+ minHeight: "24px"
2959
+ },
2960
+ dataElementText: {
2961
+ fontWeight: 400,
2962
+ fontSize: "14px",
2963
+ lineHeight: "150%",
2964
+ letterSpacing: "0.2px",
2965
+ color: "#344054",
2966
+ margin: 0,
2967
+ padding: 0,
2968
+ textAlign: "left"
2969
+ },
2970
+ checkboxSmall: {
2971
+ height: "16px",
2972
+ width: "16px",
2973
+ padding: "4px",
2974
+ borderRadius: "5px",
2975
+ border: "2px solid #d0d5dd",
2976
+ margin: 0,
2977
+ boxSizing: "border-box",
2978
+ appearance: "none",
2979
+ WebkitAppearance: "none",
2980
+ MozAppearance: "none",
2981
+ cursor: "pointer",
2982
+ position: "relative",
2983
+ backgroundColor: "transparent"
2984
+ },
2985
+ bottomSection: {
2986
+ display: "flex",
2987
+ justifyContent: "space-between",
2988
+ gap: "29px",
2989
+ paddingTop: "15px",
2990
+ borderTop: "1px solid #e5e7eb",
2991
+ boxShadow: "0 -1px 2px rgba(0, 0, 0, 0.03)",
2992
+ backgroundColor: "#ffffff",
2993
+ margin: 0,
2994
+ boxSizing: "border-box"
2995
+ },
2996
+ button: {
2997
+ width: "100%",
2998
+ borderRadius: "8px",
2999
+ padding: "9px 45px",
3000
+ fontWeight: 400,
3001
+ fontSize: "16px",
3002
+ lineHeight: "150%",
3003
+ letterSpacing: "0.2px",
3004
+ cursor: "pointer",
3005
+ margin: 0,
3006
+ boxSizing: "border-box",
3007
+ textAlign: "center"
3008
+ },
3009
+ acceptButton: {
3010
+ backgroundColor: "#4f87ff",
3011
+ border: "none",
3012
+ color: "#ffffff"
3013
+ },
3014
+ cancelButton: {
3015
+ border: "1px solid #d0d5dd",
3016
+ backgroundColor: "#ffffff",
3017
+ color: "#000000"
3018
+ },
3019
+ languageSelectorContainer: {
3020
+ position: "relative",
3021
+ margin: 0,
3022
+ padding: 0,
3023
+ boxSizing: "border-box"
3024
+ },
3025
+ languageDropdown: {
3026
+ position: "absolute",
3027
+ top: "100%",
3028
+ right: 0,
3029
+ backgroundColor: "#ffffff",
3030
+ border: "1px solid #d0d5dd",
3031
+ borderRadius: "4px",
3032
+ boxShadow: "0px 2px 4px rgba(0, 0, 0, 0.1)",
3033
+ zIndex: 10,
3034
+ width: "max-content",
3035
+ marginTop: "4px",
3036
+ padding: 0,
3037
+ boxSizing: "border-box",
3038
+ textAlign: "left"
3039
+ },
3040
+ languageItem: {
3041
+ padding: "8px 12px",
3042
+ cursor: "pointer",
3043
+ fontSize: "12px",
3044
+ color: "#344054",
3045
+ backgroundColor: "#ffffff",
3046
+ borderBottom: "1px solid #e5e7eb",
3047
+ margin: 0,
3048
+ boxSizing: "border-box",
3049
+ textAlign: "left"
3050
+ },
3051
+ selectedLanguageItem: {
3052
+ backgroundColor: "#f3f4f6",
3053
+ fontWeight: 600
3054
+ },
3055
+ loadingContainer: {
3056
+ display: "flex",
3057
+ flexDirection: "column",
3058
+ alignItems: "center",
3059
+ justifyContent: "center",
3060
+ padding: "2rem",
3061
+ minHeight: "200px",
3062
+ margin: 0,
3063
+ boxSizing: "border-box"
3064
+ },
3065
+ loadingSpinner: {
3066
+ width: "40px",
3067
+ height: "40px",
3068
+ border: "4px solid #f3f3f3",
3069
+ borderTop: "4px solid #3498db",
3070
+ borderRadius: "50%",
3071
+ animation: "spin 1s linear infinite",
3072
+ marginBottom: "1rem",
3073
+ boxSizing: "border-box"
3074
+ }
3075
+ };
3076
+
3077
+ // src/RedactoNoticeConsentInline/useMediaQuery.ts
3078
+ import { useState as useState3, useEffect as useEffect3 } from "react";
3079
+ var useMediaQuery2 = (query) => {
3080
+ const getMatches = () => typeof window !== "undefined" ? window.matchMedia(query).matches : false;
3081
+ const [matches, setMatches] = useState3(getMatches);
3082
+ useEffect3(() => {
3083
+ if (typeof window === "undefined") return;
3084
+ const media = window.matchMedia(query);
3085
+ const listener = (e) => {
3086
+ setMatches(e.matches);
3087
+ };
3088
+ if (media.addEventListener) {
3089
+ media.addEventListener("change", listener);
3090
+ } else {
3091
+ media.addListener(listener);
3092
+ }
3093
+ return () => {
3094
+ if (media.removeEventListener) {
3095
+ media.removeEventListener("change", listener);
3096
+ } else {
3097
+ media.removeListener(listener);
3098
+ }
3099
+ };
3100
+ }, [query]);
3101
+ return matches;
3102
+ };
3103
+
3104
+ // src/RedactoNoticeConsentInline/injectStyles.ts
3105
+ var spinnerAnimationInjected = false;
3106
+ var injectSpinnerAnimation = () => {
3107
+ if (spinnerAnimationInjected || typeof document === "undefined") {
3108
+ return;
3109
+ }
3110
+ const STYLE_ID = "redacto-consent-spinner-animation";
3111
+ if (document.getElementById(STYLE_ID)) {
3112
+ spinnerAnimationInjected = true;
3113
+ return;
3114
+ }
3115
+ const style = document.createElement("style");
3116
+ style.id = STYLE_ID;
3117
+ style.textContent = `
3118
+ /* Loading spinner animation */
3119
+ @keyframes spin {
3120
+ 0% {
3121
+ transform: rotate(0deg);
3122
+ }
3123
+ 100% {
3124
+ transform: rotate(360deg);
3125
+ }
3126
+ }
3127
+ `;
3128
+ document.head.appendChild(style);
3129
+ spinnerAnimationInjected = true;
3130
+ };
3131
+
3132
+ // src/RedactoNoticeConsentInline/RedactoNoticeConsentInline.tsx
3133
+ import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
3134
+ var RedactoConsentInlineComponent = forwardRef(
3135
+ ({
3136
+ org_uuid,
3137
+ workspace_uuid,
3138
+ notice_uuid,
3139
+ accessToken,
3140
+ baseUrl,
3141
+ language = "en",
3142
+ onAccept,
3143
+ onError,
3144
+ onValidationChange,
3145
+ settings,
3146
+ applicationId
3147
+ }, ref) => {
3148
+ var _a;
3149
+ const [content, setContent] = useState4(null);
3150
+ const [isLoading, setIsLoading] = useState4(true);
3151
+ const [isSubmitting, setIsSubmitting] = useState4(false);
3152
+ const [selectedLanguage, setSelectedLanguage] = useState4(language);
3153
+ const [collapsedPurposes, setCollapsedPurposes] = useState4({});
3154
+ const [selectedPurposes, setSelectedPurposes] = useState4({});
3155
+ const [selectedDataElements, setSelectedDataElements] = useState4({});
3156
+ const [hasAlreadyConsented, setHasAlreadyConsented] = useState4(false);
3157
+ const [fetchError, setFetchError] = useState4(null);
3158
+ const [errorMessage, setErrorMessage] = useState4(null);
3159
+ useEffect4(() => {
3160
+ injectSpinnerAnimation();
3161
+ }, []);
3162
+ const isMobile = useMediaQuery2("(max-width: 768px)");
3163
+ const responsiveStyles = useMemo2(
3164
+ () => ({
3165
+ optionTitle: {
3166
+ fontSize: isMobile ? "14px" : "16px"
3167
+ },
3168
+ optionDescription: {
3169
+ fontSize: isMobile ? "11px" : "12px"
3170
+ },
3171
+ dataElementText: {
3172
+ fontSize: isMobile ? "12px" : "14px"
3173
+ },
3174
+ button: {
3175
+ fontSize: isMobile ? "14px" : "16px",
3176
+ padding: isMobile ? "10px 20px" : "9px 45px"
3177
+ }
3178
+ }),
3179
+ [isMobile]
3180
+ );
3181
+ const areAllRequiredElementsChecked = useMemo2(() => {
3182
+ if (!content) return false;
3183
+ return content.purposes.every((purpose) => {
3184
+ const requiredElements = purpose.data_elements.filter(
3185
+ (element) => element.required
3186
+ );
3187
+ return requiredElements.every(
3188
+ (element) => selectedDataElements[`${purpose.uuid}-${element.uuid}`]
3189
+ );
3190
+ });
3191
+ }, [content, selectedDataElements]);
3192
+ useImperativeHandle(
3193
+ ref,
3194
+ () => ({
3195
+ submitConsent: async (accessTokenOverride) => {
3196
+ const tokenToUse = accessTokenOverride || accessToken;
3197
+ if (!tokenToUse || !content) {
3198
+ setErrorMessage("Unable to submit consent. Please try again.");
3199
+ throw new Error("Access token or content not available");
3200
+ }
3201
+ await handleAcceptWithToken(tokenToUse);
3202
+ },
3203
+ areAllRequiredElementsChecked
3204
+ }),
3205
+ [areAllRequiredElementsChecked, accessToken, content]
3206
+ );
3207
+ useEffect4(() => {
3208
+ onValidationChange == null ? void 0 : onValidationChange(areAllRequiredElementsChecked);
3209
+ }, [areAllRequiredElementsChecked, onValidationChange]);
3210
+ const acceptDisabled = isSubmitting || !areAllRequiredElementsChecked || !accessToken;
3211
+ useEffect4(() => {
3212
+ if (hasAlreadyConsented) {
3213
+ onAccept == null ? void 0 : onAccept();
3214
+ }
3215
+ }, [hasAlreadyConsented, onAccept]);
3216
+ const getTranslatedText = (key, defaultText, itemId) => {
3217
+ var _a2, _b;
3218
+ if (!content) return defaultText;
3219
+ if (selectedLanguage === content.default_language) {
3220
+ if (key === "privacy_policy_anchor_text" && content.privacy_policy_anchor_text) {
3221
+ return content.privacy_policy_anchor_text;
3222
+ }
3223
+ return defaultText;
3224
+ }
3225
+ if (!content.supported_languages_and_translations) {
3226
+ return defaultText;
3227
+ }
3228
+ const translationMap = content.supported_languages_and_translations[selectedLanguage];
3229
+ if (!translationMap) {
3230
+ return defaultText;
3231
+ }
3232
+ if (itemId) {
3233
+ if (key === "purposes.name" || key === "purposes.description") {
3234
+ return ((_a2 = translationMap.purposes) == null ? void 0 : _a2[itemId]) || defaultText;
3235
+ }
3236
+ if (key.startsWith("data_elements.")) {
3237
+ return ((_b = translationMap.data_elements) == null ? void 0 : _b[itemId]) || defaultText;
3238
+ }
3239
+ }
3240
+ const value = translationMap[key];
3241
+ if (typeof value === "string") {
3242
+ return value;
3243
+ }
3244
+ return defaultText;
3245
+ };
3246
+ const fetchNotice = async () => {
3247
+ setIsLoading(true);
3248
+ setFetchError(null);
3249
+ try {
3250
+ const consentContentData = await fetchConsentContent2({
3251
+ org_uuid,
3252
+ workspace_uuid,
3253
+ notice_uuid,
3254
+ baseUrl,
3255
+ language,
3256
+ specific_uuid: applicationId
3257
+ });
3258
+ setContent(consentContentData.detail.active_config);
3259
+ if (consentContentData.detail.active_config.default_language) {
3260
+ setSelectedLanguage(
3261
+ consentContentData.detail.active_config.default_language
3262
+ );
3263
+ }
3264
+ const initialCollapsedState = consentContentData.detail.active_config.purposes.reduce(
3265
+ (acc, purpose) => ({
3266
+ ...acc,
3267
+ [purpose.uuid]: true
3268
+ }),
3269
+ {}
3270
+ );
3271
+ setCollapsedPurposes(initialCollapsedState);
3272
+ const initialDataElementState = consentContentData.detail.active_config.purposes.reduce(
3273
+ (acc, purpose) => {
3274
+ purpose.data_elements.forEach((element) => {
3275
+ const combinedId = `${purpose.uuid}-${element.uuid}`;
3276
+ acc[combinedId] = false;
3277
+ });
3278
+ return acc;
3279
+ },
3280
+ {}
3281
+ );
3282
+ setSelectedDataElements(initialDataElementState);
3283
+ const initialPurposeState = consentContentData.detail.active_config.purposes.reduce(
3284
+ (acc, purpose) => {
3285
+ return {
3286
+ ...acc,
3287
+ [purpose.uuid]: false
3288
+ };
3289
+ },
3290
+ {}
3291
+ );
3292
+ setSelectedPurposes(initialPurposeState);
3293
+ } catch (err) {
3294
+ console.error(err);
3295
+ const error = err;
3296
+ setFetchError(error);
3297
+ if (error.status === 409) {
3298
+ setHasAlreadyConsented(true);
3299
+ } else {
3300
+ onError == null ? void 0 : onError(error);
3301
+ }
3302
+ } finally {
3303
+ setIsLoading(false);
3304
+ }
3305
+ };
3306
+ useEffect4(() => {
3307
+ fetchNotice();
3308
+ }, [
3309
+ org_uuid,
3310
+ workspace_uuid,
3311
+ notice_uuid,
3312
+ language,
3313
+ onError,
3314
+ applicationId
3315
+ ]);
3316
+ const togglePurposeCollapse = (purposeUuid) => {
3317
+ setCollapsedPurposes((prev) => ({
3318
+ ...prev,
3319
+ [purposeUuid]: !prev[purposeUuid]
3320
+ }));
3321
+ };
3322
+ const handlePurposeCheckboxChange = (purposeUuid) => {
3323
+ if (content) {
3324
+ const purpose = content.purposes.find((p) => p.uuid === purposeUuid);
3325
+ if (purpose) {
3326
+ const newPurposeState = !selectedPurposes[purposeUuid];
3327
+ setSelectedPurposes((prev) => ({
3328
+ ...prev,
3329
+ [purposeUuid]: newPurposeState
3330
+ }));
3331
+ setSelectedDataElements((prev) => {
3332
+ const updated = { ...prev };
3333
+ purpose.data_elements.forEach((el) => {
3334
+ const combinedId = `${purposeUuid}-${el.uuid}`;
3335
+ updated[combinedId] = newPurposeState;
3336
+ });
3337
+ return updated;
3338
+ });
3339
+ }
3340
+ }
3341
+ };
3342
+ const handleDataElementCheckboxChange = (elementUuid, purposeUuid) => {
3343
+ if (!content) return;
3344
+ const purpose = content.purposes.find((p) => p.uuid === purposeUuid);
3345
+ if (!purpose) return;
3346
+ const dataElement = purpose.data_elements.find(
3347
+ (el) => el.uuid === elementUuid
3348
+ );
3349
+ if (!dataElement) return;
3350
+ const combinedId = `${purposeUuid}-${elementUuid}`;
3351
+ const currentState = selectedDataElements[combinedId] || false;
3352
+ const newElementState = !currentState;
3353
+ setSelectedDataElements((prev) => {
3354
+ const newState = {
3355
+ ...prev,
3356
+ [combinedId]: newElementState
3357
+ };
3358
+ const requiredElements = purpose.data_elements.filter(
3359
+ (el) => el.required
3360
+ );
3361
+ const allRequiredElementsChecked = requiredElements.length === 0 || requiredElements.every((el) => newState[`${purposeUuid}-${el.uuid}`]);
3362
+ setSelectedPurposes((prevPurposes) => ({
3363
+ ...prevPurposes,
3364
+ [purposeUuid]: allRequiredElementsChecked
3365
+ }));
3366
+ return newState;
3367
+ });
3368
+ };
3369
+ const handleAcceptWithToken = async (tokenToUse) => {
3370
+ if (!tokenToUse || !content) {
3371
+ setErrorMessage("Unable to submit consent. Please try again.");
3372
+ throw new Error("Access token or content not available");
3373
+ }
3374
+ try {
3375
+ setIsSubmitting(true);
3376
+ setErrorMessage(null);
3377
+ await submitConsentEvent2({
3378
+ org_uuid,
3379
+ workspace_uuid,
3380
+ accessToken: tokenToUse,
3381
+ baseUrl,
3382
+ noticeUuid: content.notice_uuid,
3383
+ purposes: content.purposes.map((purpose) => {
3384
+ const hasSelectedRequiredElement = purpose.data_elements.some(
3385
+ (element) => element.required && (selectedDataElements[`${purpose.uuid}-${element.uuid}`] || false)
3386
+ );
3387
+ const hasSelectedDataElement = purpose.data_elements.some(
3388
+ (element) => selectedDataElements[`${purpose.uuid}-${element.uuid}`] || false
3389
+ );
3390
+ const purposeSelected = selectedPurposes[purpose.uuid] || hasSelectedRequiredElement || hasSelectedDataElement;
3391
+ return {
3392
+ ...purpose,
3393
+ selected: purposeSelected,
3394
+ data_elements: purpose.data_elements.map((element) => ({
3395
+ ...element,
3396
+ selected: selectedDataElements[`${purpose.uuid}-${element.uuid}`] || false
3397
+ }))
3398
+ };
3399
+ }),
3400
+ declined: false,
3401
+ meta_data: applicationId ? { specific_uuid: applicationId } : void 0
3402
+ });
3403
+ onAccept == null ? void 0 : onAccept();
3404
+ } catch (error) {
3405
+ console.error("Error submitting consent:", error);
3406
+ const err = error;
3407
+ if (err.status === 500) {
3408
+ setErrorMessage(
3409
+ "An error occurred while submitting your consent. Please try again later."
3410
+ );
3411
+ }
3412
+ onError == null ? void 0 : onError(error);
3413
+ throw error;
3414
+ } finally {
3415
+ setIsSubmitting(false);
3416
+ }
3417
+ };
3418
+ const headingStyle = {
3419
+ color: (settings == null ? void 0 : settings.headingColor) || "#101828"
3420
+ };
3421
+ const textStyle = {
3422
+ color: (settings == null ? void 0 : settings.textColor) || "#344054"
3423
+ };
3424
+ if (hasAlreadyConsented || fetchError) {
3425
+ return null;
3426
+ }
3427
+ if (isLoading) {
3428
+ return /* @__PURE__ */ jsxs2("div", { style: styles2.loadingContainer, children: [
3429
+ /* @__PURE__ */ jsx2("div", { style: styles2.loadingSpinner }),
3430
+ /* @__PURE__ */ jsx2("p", { style: { ...styles2.privacyText, ...textStyle }, children: "Loading..." })
3431
+ ] });
3432
+ }
3433
+ if (!content) {
3434
+ return null;
3435
+ }
3436
+ return /* @__PURE__ */ jsxs2("div", { style: { display: "flex", flexDirection: "column", gap: "16px" }, children: [
3437
+ errorMessage && /* @__PURE__ */ jsx2(
3438
+ "div",
3439
+ {
3440
+ role: "alert",
3441
+ style: {
3442
+ backgroundColor: "#FEE2E2",
3443
+ color: "#DC2626",
3444
+ padding: "12px",
3445
+ borderRadius: "6px",
3446
+ fontSize: "14px",
3447
+ border: "1px solid #FCA5A5"
3448
+ },
3449
+ children: errorMessage
3450
+ }
3451
+ ),
3452
+ (_a = content == null ? void 0 : content.purposes) == null ? void 0 : _a.map((purpose) => /* @__PURE__ */ jsxs2("div", { children: [
3453
+ /* @__PURE__ */ jsxs2("div", { style: styles2.optionItem, children: [
3454
+ /* @__PURE__ */ jsxs2(
3455
+ "div",
3456
+ {
3457
+ style: styles2.optionLeft,
3458
+ onClick: () => togglePurposeCollapse(purpose.uuid),
3459
+ role: "button",
3460
+ tabIndex: 0,
3461
+ "aria-expanded": !collapsedPurposes[purpose.uuid],
3462
+ "aria-controls": `purpose-${purpose.uuid}`,
3463
+ onKeyDown: (e) => {
3464
+ if (e.key === "Enter" || e.key === " ") {
3465
+ e.preventDefault();
3466
+ togglePurposeCollapse(purpose.uuid);
1228
3467
  }
1229
- )
1230
- ] }),
1231
- /* @__PURE__ */ jsxs("div", { style: styles.languageSelectorContainer, children: [
1232
- /* @__PURE__ */ jsxs(
1233
- "button",
1234
- {
1235
- ref: firstFocusableRef,
1236
- style: {
1237
- ...styles.topRight,
1238
- ...responsiveStyles.topRight,
1239
- ...languageSelectorStyle
1240
- },
1241
- onClick: toggleLanguageDropdown,
1242
- "aria-expanded": isLanguageDropdownOpen,
1243
- "aria-haspopup": "listbox",
1244
- "aria-controls": "language-listbox",
1245
- children: [
1246
- selectedLanguage,
1247
- /* @__PURE__ */ jsx(
3468
+ },
3469
+ children: [
3470
+ /* @__PURE__ */ jsx2(
3471
+ "div",
3472
+ {
3473
+ style: {
3474
+ display: "flex",
3475
+ alignItems: "center",
3476
+ justifyContent: "center",
3477
+ marginLeft: "5px"
3478
+ },
3479
+ children: /* @__PURE__ */ jsx2(
1248
3480
  "svg",
1249
3481
  {
1250
- xmlns: "http://www.w3.org/2000/svg",
1251
- width: "16",
1252
- height: "16",
1253
- viewBox: "0 0 16 16",
3482
+ width: "7",
3483
+ height: "12",
3484
+ viewBox: "0 0 7 12",
1254
3485
  fill: "none",
1255
- stroke: ((_r = (_q = settings == null ? void 0 : settings.button) == null ? void 0 : _q.language) == null ? void 0 : _r.textColor) || "currentColor",
3486
+ xmlns: "http://www.w3.org/2000/svg",
3487
+ stroke: (settings == null ? void 0 : settings.headingColor) || "#323B4B",
1256
3488
  strokeWidth: "2",
1257
3489
  strokeLinecap: "round",
1258
3490
  strokeLinejoin: "round",
1259
- style: { flexShrink: 0, marginLeft: "4px" },
3491
+ style: {
3492
+ transform: !collapsedPurposes[purpose.uuid] ? "rotate(90deg)" : "rotate(0deg)",
3493
+ transition: "transform 0.3s ease"
3494
+ },
1260
3495
  "aria-hidden": "true",
1261
- children: /* @__PURE__ */ jsx("path", { d: "M4 6l4 4 4-4" })
3496
+ children: /* @__PURE__ */ jsx2("path", { d: "M1 1L6 6L1 11" })
1262
3497
  }
1263
3498
  )
1264
- ]
1265
- }
1266
- ),
1267
- isLanguageDropdownOpen && /* @__PURE__ */ jsx(
1268
- "ul",
1269
- {
1270
- id: "language-listbox",
1271
- style: {
1272
- ...styles.languageDropdown,
1273
- ...languageSelectorStyle
1274
- },
1275
- role: "listbox",
1276
- "aria-label": "Select language",
1277
- children: availableLanguages.map((lang) => /* @__PURE__ */ jsx(
1278
- "li",
3499
+ }
3500
+ ),
3501
+ /* @__PURE__ */ jsxs2("div", { style: styles2.optionTextContainer, children: [
3502
+ /* @__PURE__ */ jsx2(
3503
+ "h2",
1279
3504
  {
1280
3505
  style: {
1281
- ...styles.languageItem,
1282
- ...responsiveStyles.languageItem,
1283
- ...selectedLanguage === lang ? selectedLanguageItemStyle : languageSelectorStyle,
1284
- listStyle: "none"
3506
+ ...styles2.optionTitle,
3507
+ ...responsiveStyles.optionTitle,
3508
+ ...headingStyle
1285
3509
  },
1286
- onClick: () => handleLanguageSelect(lang),
1287
- role: "option",
1288
- "aria-selected": selectedLanguage === lang,
1289
- tabIndex: 0,
1290
- children: lang
1291
- },
1292
- lang
1293
- ))
1294
- }
1295
- )
1296
- ] })
1297
- ] }),
1298
- /* @__PURE__ */ jsxs(
1299
- "div",
1300
- {
1301
- id: "privacy-notice-description",
1302
- style: {
1303
- ...styles.middleSection,
1304
- ...responsiveStyles.middleSection,
1305
- ...sectionStyle
1306
- },
1307
- children: [
1308
- /* @__PURE__ */ jsxs(
1309
- "p",
1310
- {
1311
- style: {
1312
- ...styles.privacyText,
1313
- ...responsiveStyles.privacyText,
1314
- ...textStyle
1315
- },
1316
- children: [
1317
- content ? getTranslatedText("notice_text", content.notice_text) : "",
1318
- /* @__PURE__ */ jsx("br", {}),
1319
- "Learn more in our",
1320
- " ",
1321
- /* @__PURE__ */ jsxs(
1322
- "a",
1323
- {
1324
- style: { ...styles.link, ...linkStyle },
1325
- href: (content == null ? void 0 : content.privacy_policy_url) || "#",
1326
- target: "_blank",
1327
- rel: "noopener noreferrer",
1328
- "aria-label": "Privacy Policy (opens in new tab)",
1329
- children: [
1330
- "[",
1331
- getTranslatedText(
1332
- "privacy_policy_anchor_text",
1333
- (content == null ? void 0 : content.privacy_policy_anchor_text) || "Privacy Policy"
1334
- ),
1335
- "]"
1336
- ]
1337
- }
1338
- ),
1339
- " ",
1340
- "and",
1341
- " ",
1342
- /* @__PURE__ */ jsxs(
1343
- "a",
1344
- {
1345
- style: { ...styles.link, ...linkStyle },
1346
- href: (content == null ? void 0 : content.sub_processors_url) || "#",
1347
- target: "_blank",
1348
- rel: "noopener noreferrer",
1349
- "aria-label": "Vendors List (opens in new tab)",
1350
- children: [
1351
- "[",
1352
- getTranslatedText(
1353
- "vendors_list_anchor_text",
1354
- (content == null ? void 0 : content.vendors_list_anchor_text) || "Vendors List"
1355
- ),
1356
- "]"
1357
- ]
1358
- }
1359
- ),
1360
- "."
1361
- ]
1362
- }
1363
- ),
1364
- /* @__PURE__ */ jsx(
1365
- "h2",
1366
- {
1367
- style: {
1368
- ...styles.subTitle,
1369
- ...responsiveStyles.subTitle,
1370
- ...headingStyle
1371
- },
1372
- children: getTranslatedText(
1373
- "purpose_section_heading",
1374
- "Manage What You Share"
1375
- )
1376
- }
1377
- ),
1378
- /* @__PURE__ */ jsx("div", { style: styles.optionsContainer, children: (_s = content == null ? void 0 : content.purposes) == null ? void 0 : _s.map((purpose) => /* @__PURE__ */ jsxs("div", { children: [
1379
- /* @__PURE__ */ jsxs("div", { style: styles.optionItem, children: [
1380
- /* @__PURE__ */ jsxs(
1381
- "div",
1382
- {
1383
- style: styles.optionLeft,
1384
- onClick: () => togglePurposeCollapse(purpose.uuid),
1385
- role: "button",
1386
- tabIndex: 0,
1387
- "aria-expanded": !collapsedPurposes[purpose.uuid],
1388
- "aria-controls": `purpose-${purpose.uuid}`,
1389
- onKeyDown: (e) => {
1390
- if (e.key === "Enter" || e.key === " ") {
1391
- e.preventDefault();
1392
- togglePurposeCollapse(purpose.uuid);
1393
- }
1394
- },
1395
- children: [
1396
- /* @__PURE__ */ jsx(
1397
- "div",
1398
- {
1399
- style: {
1400
- display: "flex",
1401
- alignItems: "center",
1402
- justifyContent: "center",
1403
- marginLeft: "5px"
1404
- },
1405
- children: /* @__PURE__ */ jsx(
1406
- "svg",
1407
- {
1408
- width: "7",
1409
- height: "12",
1410
- viewBox: "0 0 7 12",
1411
- fill: "none",
1412
- xmlns: "http://www.w3.org/2000/svg",
1413
- stroke: (settings == null ? void 0 : settings.headingColor) || "#323B4B",
1414
- strokeWidth: "2",
1415
- strokeLinecap: "round",
1416
- strokeLinejoin: "round",
1417
- style: {
1418
- transform: !collapsedPurposes[purpose.uuid] ? "rotate(90deg)" : "rotate(0deg)",
1419
- transition: "transform 0.3s ease"
1420
- },
1421
- "aria-hidden": "true",
1422
- children: /* @__PURE__ */ jsx("path", { d: "M1 1L6 6L1 11" })
1423
- }
1424
- )
1425
- }
1426
- ),
1427
- /* @__PURE__ */ jsxs("div", { style: styles.optionTextContainer, children: [
1428
- /* @__PURE__ */ jsx(
1429
- "h2",
1430
- {
1431
- style: {
1432
- ...styles.optionTitle,
1433
- ...responsiveStyles.optionTitle,
1434
- ...headingStyle
1435
- },
1436
- children: getTranslatedText(
1437
- `purposes.name`,
1438
- purpose.name,
1439
- purpose.uuid
1440
- )
1441
- }
1442
- ),
1443
- /* @__PURE__ */ jsx(
1444
- "h3",
1445
- {
1446
- style: {
1447
- ...styles.optionDescription,
1448
- ...responsiveStyles.optionDescription,
1449
- ...textStyle
1450
- },
1451
- children: getTranslatedText(
1452
- `purposes.description`,
1453
- purpose.description,
1454
- purpose.uuid
1455
- )
1456
- }
1457
- )
1458
- ] })
1459
- ]
1460
- }
1461
- ),
1462
- /* @__PURE__ */ jsx(
1463
- "input",
1464
- {
1465
- className: "redacto-checkbox-large",
1466
- type: "checkbox",
1467
- checked: selectedPurposes[purpose.uuid] || false,
1468
- onChange: () => handlePurposeCheckboxChange(purpose.uuid),
1469
- "aria-label": `Select all data elements for ${getTranslatedText(
1470
- `purposes.name`,
1471
- purpose.name,
1472
- purpose.uuid
1473
- )}`
1474
- }
1475
- )
1476
- ] }),
1477
- !collapsedPurposes[purpose.uuid] && purpose.data_elements && purpose.data_elements.length > 0 && /* @__PURE__ */ jsx(
1478
- "div",
3510
+ children: getTranslatedText(
3511
+ `purposes.name`,
3512
+ purpose.name,
3513
+ purpose.uuid
3514
+ )
3515
+ }
3516
+ ),
3517
+ /* @__PURE__ */ jsx2(
3518
+ "h3",
1479
3519
  {
1480
- id: `purpose-${purpose.uuid}`,
1481
- style: styles.dataElementsContainer,
1482
- children: purpose.data_elements.map((dataElement) => /* @__PURE__ */ jsxs(
1483
- "div",
1484
- {
1485
- style: styles.dataElementItem,
1486
- children: [
1487
- /* @__PURE__ */ jsxs(
1488
- "span",
1489
- {
1490
- style: {
1491
- ...styles.dataElementText,
1492
- ...responsiveStyles.dataElementText,
1493
- ...textStyle
1494
- },
1495
- children: [
1496
- getTranslatedText(
1497
- `data_elements.name`,
1498
- dataElement.name,
1499
- dataElement.uuid
1500
- ),
1501
- dataElement.required && /* @__PURE__ */ jsx(
1502
- "span",
1503
- {
1504
- style: {
1505
- color: "red",
1506
- marginLeft: "4px"
1507
- },
1508
- "aria-label": "required",
1509
- children: "*"
1510
- }
1511
- )
1512
- ]
1513
- }
1514
- ),
1515
- /* @__PURE__ */ jsx(
1516
- "input",
1517
- {
1518
- className: "redacto-checkbox-small",
1519
- type: "checkbox",
1520
- checked: selectedDataElements[`${purpose.uuid}-${dataElement.uuid}`] || false,
1521
- onChange: () => handleDataElementCheckboxChange(
1522
- dataElement.uuid,
1523
- purpose.uuid
1524
- ),
1525
- "aria-label": `Select ${getTranslatedText(
1526
- `data_elements.name`,
1527
- dataElement.name,
1528
- dataElement.uuid
1529
- )}${dataElement.required ? " (required)" : ""}`
1530
- }
1531
- )
1532
- ]
1533
- },
1534
- dataElement.uuid
1535
- ))
3520
+ style: {
3521
+ ...styles2.optionDescription,
3522
+ ...responsiveStyles.optionDescription,
3523
+ ...textStyle
3524
+ },
3525
+ children: getTranslatedText(
3526
+ `purposes.description`,
3527
+ purpose.description,
3528
+ purpose.uuid
3529
+ )
1536
3530
  }
1537
3531
  )
1538
- ] }, purpose.uuid)) })
3532
+ ] })
1539
3533
  ]
1540
3534
  }
1541
3535
  ),
1542
- /* @__PURE__ */ jsxs(
1543
- "div",
3536
+ /* @__PURE__ */ jsx2(
3537
+ "input",
1544
3538
  {
1545
- style: {
1546
- ...styles.bottomSection,
1547
- ...responsiveStyles.bottomSection,
1548
- ...sectionStyle
1549
- },
1550
- children: [
1551
- /* @__PURE__ */ jsx(
1552
- "button",
1553
- {
1554
- ref: lastFocusableRef,
1555
- style: {
1556
- ...styles.button,
1557
- ...responsiveStyles.button,
1558
- ...styles.acceptButton,
1559
- ...acceptButtonStyle,
1560
- opacity: acceptDisabled ? 0.5 : 1
1561
- },
1562
- onClick: handleAccept,
1563
- disabled: acceptDisabled,
1564
- "aria-label": getTranslatedText(
1565
- "confirm_button_text",
1566
- (content == null ? void 0 : content.confirm_button_text) || "Accept"
1567
- ),
1568
- children: isSubmitting ? "Processing..." : getTranslatedText(
1569
- "confirm_button_text",
1570
- (content == null ? void 0 : content.confirm_button_text) || "Accept"
1571
- )
1572
- }
1573
- ),
1574
- /* @__PURE__ */ jsx(
1575
- "button",
1576
- {
1577
- style: {
1578
- ...styles.button,
1579
- ...responsiveStyles.button,
1580
- ...styles.cancelButton,
1581
- ...declineButtonStyle
1582
- },
1583
- onClick: handleDecline,
1584
- disabled: isSubmitting,
1585
- "aria-label": getTranslatedText(
1586
- "decline_button_text",
1587
- (content == null ? void 0 : content.decline_button_text) || "Decline"
1588
- ),
1589
- children: isSubmitting ? "Processing..." : getTranslatedText(
1590
- "decline_button_text",
1591
- (content == null ? void 0 : content.decline_button_text) || "Decline"
1592
- )
1593
- }
1594
- )
1595
- ]
3539
+ type: "checkbox",
3540
+ checked: selectedPurposes[purpose.uuid] || false,
3541
+ onChange: () => handlePurposeCheckboxChange(purpose.uuid),
3542
+ "aria-label": `Select all data elements for ${getTranslatedText(
3543
+ `purposes.name`,
3544
+ purpose.name,
3545
+ purpose.uuid
3546
+ )}`
1596
3547
  }
1597
3548
  )
1598
- ] })
1599
- }
1600
- )
1601
- ] }) });
1602
- };
3549
+ ] }),
3550
+ !collapsedPurposes[purpose.uuid] && purpose.data_elements && purpose.data_elements.length > 0 && /* @__PURE__ */ jsx2(
3551
+ "div",
3552
+ {
3553
+ id: `purpose-${purpose.uuid}`,
3554
+ style: styles2.dataElementsContainer,
3555
+ children: purpose.data_elements.map((dataElement) => /* @__PURE__ */ jsxs2("div", { style: styles2.dataElementItem, children: [
3556
+ /* @__PURE__ */ jsxs2(
3557
+ "span",
3558
+ {
3559
+ style: {
3560
+ ...styles2.dataElementText,
3561
+ ...responsiveStyles.dataElementText,
3562
+ ...textStyle
3563
+ },
3564
+ children: [
3565
+ getTranslatedText(
3566
+ `data_elements.name`,
3567
+ dataElement.name,
3568
+ dataElement.uuid
3569
+ ),
3570
+ dataElement.required && /* @__PURE__ */ jsx2(
3571
+ "span",
3572
+ {
3573
+ style: {
3574
+ color: "red",
3575
+ marginLeft: "4px"
3576
+ },
3577
+ "aria-label": "required",
3578
+ children: "*"
3579
+ }
3580
+ )
3581
+ ]
3582
+ }
3583
+ ),
3584
+ /* @__PURE__ */ jsx2(
3585
+ "input",
3586
+ {
3587
+ type: "checkbox",
3588
+ checked: selectedDataElements[`${purpose.uuid}-${dataElement.uuid}`] || false,
3589
+ onChange: () => handleDataElementCheckboxChange(
3590
+ dataElement.uuid,
3591
+ purpose.uuid
3592
+ ),
3593
+ "aria-label": `Select ${getTranslatedText(
3594
+ `data_elements.name`,
3595
+ dataElement.name,
3596
+ dataElement.uuid
3597
+ )}${dataElement.required ? " (required)" : ""}`
3598
+ }
3599
+ )
3600
+ ] }, dataElement.uuid))
3601
+ }
3602
+ )
3603
+ ] }, purpose.uuid))
3604
+ ] });
3605
+ }
3606
+ );
3607
+ RedactoConsentInlineComponent.displayName = "RedactoConsentInline";
3608
+ var RedactoConsentInline = memo(RedactoConsentInlineComponent);
1603
3609
  export {
1604
- RedactoNoticeConsent
3610
+ RedactoNoticeConsent,
3611
+ RedactoConsentInline as RedactoNoticeConsentInline
1605
3612
  };