@redacto.io/consent-sdk-react 3.5.0 → 3.6.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/CHANGELOG.md +6 -0
- package/LICENSE +176 -0
- package/dist/index.d.mts +51 -4
- package/dist/index.d.ts +51 -4
- package/dist/index.js +1891 -243
- package/dist/index.mjs +1890 -243
- package/dist/privacy-center.d.mts +566 -0
- package/dist/privacy-center.d.ts +566 -0
- package/dist/privacy-center.js +17174 -0
- package/dist/privacy-center.mjs +17136 -0
- package/package.json +47 -3
- package/src/RedactoNoticeConsent/RedactoNoticeConsent.test.tsx +201 -118
- package/src/RedactoNoticeConsent/RedactoNoticeConsent.tsx +1194 -93
- package/src/RedactoNoticeConsent/api/index.ts +335 -206
- package/src/RedactoNoticeConsent/api/types.ts +140 -16
- package/src/RedactoNoticeConsent/components/DigiLockerCallback.tsx +602 -0
- package/src/RedactoNoticeConsent/components/index.ts +7 -0
- package/src/RedactoNoticeConsent/injectStyles.ts +11 -0
- package/src/RedactoNoticeConsent/language-codes.ts +61 -0
- package/src/RedactoNoticeConsent/services/storage.ts +122 -0
- package/src/RedactoNoticeConsent/types.ts +2 -0
- package/src/RedactoPrivacyCenter/PrivacyCenterActivityPage.tsx +19 -0
- package/src/RedactoPrivacyCenter/PrivacyCenterConsentManagerPage.tsx +17 -0
- package/src/RedactoPrivacyCenter/PrivacyCenterFormPage.tsx +79 -0
- package/src/RedactoPrivacyCenter/PrivacyCenterHomePage.tsx +27 -0
- package/src/RedactoPrivacyCenter/PrivacyCenterLayout.tsx +142 -0
- package/src/RedactoPrivacyCenter/RedactoPrivacyCenter.tsx +51 -0
- package/src/RedactoPrivacyCenter/api/actions.ts +444 -0
- package/src/RedactoPrivacyCenter/api/client.ts +413 -0
- package/src/RedactoPrivacyCenter/api/config.ts +33 -0
- package/src/RedactoPrivacyCenter/api/fetcher.ts +181 -0
- package/src/RedactoPrivacyCenter/api/upload.ts +93 -0
- package/src/RedactoPrivacyCenter/assets/character.svg +31 -0
- package/src/RedactoPrivacyCenter/assets/fileAttach.svg +9 -0
- package/src/RedactoPrivacyCenter/assets/greenTick.svg +4 -0
- package/src/RedactoPrivacyCenter/assets/mail.svg +3 -0
- package/src/RedactoPrivacyCenter/assets/poweredByRedacto.svg +9 -0
- package/src/RedactoPrivacyCenter/assets/sentImg.svg +9 -0
- package/src/RedactoPrivacyCenter/assets/uploadFileIcon.svg +9 -0
- package/src/RedactoPrivacyCenter/components/ActivitiesList.tsx +272 -0
- package/src/RedactoPrivacyCenter/components/CaseDetailsModal.tsx +468 -0
- package/src/RedactoPrivacyCenter/components/CaseHistory.tsx +433 -0
- package/src/RedactoPrivacyCenter/components/ConsentManager.tsx +726 -0
- package/src/RedactoPrivacyCenter/components/ConsentManagerColumns.tsx +239 -0
- package/src/RedactoPrivacyCenter/components/ConsentManagerConstants.ts +7 -0
- package/src/RedactoPrivacyCenter/components/ConsentManagerTableSkeleton.tsx +155 -0
- package/src/RedactoPrivacyCenter/components/DataRequest/CorrectionDataSection.tsx +189 -0
- package/src/RedactoPrivacyCenter/components/DataRequest/GrievanceDataSection.tsx +118 -0
- package/src/RedactoPrivacyCenter/components/DataRequest/NominationDataSection.tsx +66 -0
- package/src/RedactoPrivacyCenter/components/DataRequest/PurposeSelectionSection.tsx +305 -0
- package/src/RedactoPrivacyCenter/components/Form.tsx +1455 -0
- package/src/RedactoPrivacyCenter/components/GrievanceTable.tsx +176 -0
- package/src/RedactoPrivacyCenter/components/GrievanceTablePagination.tsx +330 -0
- package/src/RedactoPrivacyCenter/components/ModifyConsentModal.tsx +329 -0
- package/src/RedactoPrivacyCenter/components/Pagination.tsx +140 -0
- package/src/RedactoPrivacyCenter/components/PrivacyCenterLayout.tsx +302 -0
- package/src/RedactoPrivacyCenter/components/RequestSubmit.tsx +218 -0
- package/src/RedactoPrivacyCenter/components/SideMenuBarPC/SideBarPC.tsx +475 -0
- package/src/RedactoPrivacyCenter/components/SideMenuBarPC/SideMenuPC.tsx +412 -0
- package/src/RedactoPrivacyCenter/components/SideMenuBarPC/constants.tsx +42 -0
- package/src/RedactoPrivacyCenter/components/SideMenuBarPC/menuItemsPC.tsx +1 -0
- package/src/RedactoPrivacyCenter/components/SideMenuBarPC/types.ts +40 -0
- package/src/RedactoPrivacyCenter/components/SideMenuBarPC/utils.ts +38 -0
- package/src/RedactoPrivacyCenter/components/ThemeTransitionOverlay.tsx +85 -0
- package/src/RedactoPrivacyCenter/components/activitiesColumns.tsx +141 -0
- package/src/RedactoPrivacyCenter/components/caseHistoryColumns.tsx +179 -0
- package/src/RedactoPrivacyCenter/components/constant.ts +20 -0
- package/src/RedactoPrivacyCenter/components/types.ts +68 -0
- package/src/RedactoPrivacyCenter/components/utils.tsx +10 -0
- package/src/RedactoPrivacyCenter/config/routes.ts +9 -0
- package/src/RedactoPrivacyCenter/config/table.ts +25 -0
- package/src/RedactoPrivacyCenter/context/AuthContext.tsx +123 -0
- package/src/RedactoPrivacyCenter/context/BaseUrlContext.tsx +44 -0
- package/src/RedactoPrivacyCenter/context/LocaleContext.tsx +11 -0
- package/src/RedactoPrivacyCenter/context/NavigationContext.tsx +64 -0
- package/src/RedactoPrivacyCenter/context/OrganizationContext.tsx +30 -0
- package/src/RedactoPrivacyCenter/context/PageChromeContext.tsx +60 -0
- package/src/RedactoPrivacyCenter/context/theme.tsx +127 -0
- package/src/RedactoPrivacyCenter/lib/api.ts +468 -0
- package/src/RedactoPrivacyCenter/lib/consent-manager/utils.tsx +63 -0
- package/src/RedactoPrivacyCenter/lib/constants.ts +116 -0
- package/src/RedactoPrivacyCenter/lib/i18n.ts +81 -0
- package/src/RedactoPrivacyCenter/lib/locales.ts +105 -0
- package/src/RedactoPrivacyCenter/lib/queries.ts +30 -0
- package/src/RedactoPrivacyCenter/lib/types.ts +346 -0
- package/src/RedactoPrivacyCenter/lib/useCurrentLanguage.ts +37 -0
- package/src/RedactoPrivacyCenter/lib/utils.ts +625 -0
- package/src/RedactoPrivacyCenter/locales/as/translation.json +188 -0
- package/src/RedactoPrivacyCenter/locales/bho/translation.json +188 -0
- package/src/RedactoPrivacyCenter/locales/bn/translation.json +188 -0
- package/src/RedactoPrivacyCenter/locales/brx/translation.json +188 -0
- package/src/RedactoPrivacyCenter/locales/doi/translation.json +188 -0
- package/src/RedactoPrivacyCenter/locales/en/translation.json +188 -0
- package/src/RedactoPrivacyCenter/locales/gom/translation.json +188 -0
- package/src/RedactoPrivacyCenter/locales/gu/translation.json +188 -0
- package/src/RedactoPrivacyCenter/locales/hi/translation.json +188 -0
- package/src/RedactoPrivacyCenter/locales/kn/translation.json +188 -0
- package/src/RedactoPrivacyCenter/locales/ks/translation.json +188 -0
- package/src/RedactoPrivacyCenter/locales/mai/translation.json +188 -0
- package/src/RedactoPrivacyCenter/locales/ml/translation.json +188 -0
- package/src/RedactoPrivacyCenter/locales/mni-Mtei/translation.json +188 -0
- package/src/RedactoPrivacyCenter/locales/mr/translation.json +188 -0
- package/src/RedactoPrivacyCenter/locales/ne/translation.json +188 -0
- package/src/RedactoPrivacyCenter/locales/or/translation.json +188 -0
- package/src/RedactoPrivacyCenter/locales/pa/translation.json +188 -0
- package/src/RedactoPrivacyCenter/locales/sa/translation.json +188 -0
- package/src/RedactoPrivacyCenter/locales/sat/translation.json +188 -0
- package/src/RedactoPrivacyCenter/locales/sd/translation.json +188 -0
- package/src/RedactoPrivacyCenter/locales/ta/translation.json +188 -0
- package/src/RedactoPrivacyCenter/locales/te/translation.json +188 -0
- package/src/RedactoPrivacyCenter/locales/ur/translation.json +188 -0
- package/src/RedactoPrivacyCenter/styles/base.css +117 -0
- package/src/RedactoPrivacyCenter/styles/injectStyles.ts +1000 -0
- package/src/RedactoPrivacyCenter/styles/pcStyles.ts +819 -0
- package/src/RedactoPrivacyCenter/styles/responsive.ts +138 -0
- package/src/RedactoPrivacyCenter/styles/variables.css +133 -0
- package/src/RedactoPrivacyCenter/table/AdvancedTable.tsx +365 -0
- package/src/RedactoPrivacyCenter/table/AdvancedTablePagination.tsx +479 -0
- package/src/RedactoPrivacyCenter/table/index.ts +2 -0
- package/src/RedactoPrivacyCenter/types/images.d.ts +29 -0
- package/src/RedactoPrivacyCenter/ui/Footer.tsx +73 -0
- package/src/RedactoPrivacyCenter/ui/FormBlockWrapper.tsx +54 -0
- package/src/RedactoPrivacyCenter/ui/PCAccordion.tsx +87 -0
- package/src/RedactoPrivacyCenter/ui/PCActionIcon.tsx +47 -0
- package/src/RedactoPrivacyCenter/ui/PCAvatar.tsx +69 -0
- package/src/RedactoPrivacyCenter/ui/PCBadge.tsx +48 -0
- package/src/RedactoPrivacyCenter/ui/PCButton.tsx +77 -0
- package/src/RedactoPrivacyCenter/ui/PCCheckbox.tsx +55 -0
- package/src/RedactoPrivacyCenter/ui/PCCollapse.tsx +97 -0
- package/src/RedactoPrivacyCenter/ui/PCEmpty.tsx +35 -0
- package/src/RedactoPrivacyCenter/ui/PCInput.tsx +128 -0
- package/src/RedactoPrivacyCenter/ui/PCLoader.tsx +30 -0
- package/src/RedactoPrivacyCenter/ui/PCModal.tsx +104 -0
- package/src/RedactoPrivacyCenter/ui/PCPopover.tsx +175 -0
- package/src/RedactoPrivacyCenter/ui/PCSelect.tsx +381 -0
- package/src/RedactoPrivacyCenter/ui/PCTable.tsx +137 -0
- package/src/RedactoPrivacyCenter/ui/PCText.tsx +39 -0
- package/src/RedactoPrivacyCenter/ui/PCTextarea.tsx +43 -0
- package/src/RedactoPrivacyCenter/ui/PCTitle.tsx +37 -0
- package/src/RedactoPrivacyCenter/ui/PCTooltip.tsx +119 -0
- package/src/RedactoPrivacyCenter/ui/SimpleBar.tsx +25 -0
- package/src/RedactoPrivacyCenter/ui/StatusBadge.tsx +55 -0
- package/src/RedactoPrivacyCenter/ui/ThemeToggle.tsx +70 -0
- package/src/RedactoPrivacyCenter/ui/index.ts +18 -0
- package/src/RedactoPrivacyCenter/utils/cn.ts +28 -0
- package/src/RedactoPrivacyCenter/utils/date.ts +48 -0
- package/src/RedactoPrivacyCenter/utils/status.ts +111 -0
- package/src/RedactoPrivacyCenter/utils/toast.ts +130 -0
- package/src/index.ts +10 -0
- package/src/privacy-center.ts +107 -0
- package/tsconfig.json +2 -0
- package/tsup.config.ts +16 -1
package/dist/index.js
CHANGED
|
@@ -20,6 +20,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/index.ts
|
|
21
21
|
var src_exports = {};
|
|
22
22
|
__export(src_exports, {
|
|
23
|
+
DigiLockerCallback: () => DigiLockerCallback,
|
|
23
24
|
RedactoNoticeConsent: () => RedactoNoticeConsent,
|
|
24
25
|
RedactoNoticeConsentInline: () => RedactoConsentInline
|
|
25
26
|
});
|
|
@@ -66,73 +67,66 @@ var fetchConsentContent = async ({
|
|
|
66
67
|
validate_against = "all",
|
|
67
68
|
include_fully_consented_data = false,
|
|
68
69
|
signal
|
|
69
|
-
// AbortSignal for request cancellation
|
|
70
70
|
}) => {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
return cachedData;
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
const url = new URL(
|
|
92
|
-
`${apiBaseUrl}/public/organisations/${ORGANISATION_UUID}/workspaces/${WORKSPACE_UUID}/notices/${noticeId}`
|
|
93
|
-
);
|
|
94
|
-
if (specific_uuid) {
|
|
95
|
-
url.searchParams.append("specific_uuid", specific_uuid);
|
|
96
|
-
}
|
|
97
|
-
url.searchParams.append("validate_against", validate_against);
|
|
98
|
-
if (include_fully_consented_data) {
|
|
99
|
-
url.searchParams.append("include_fully_consented_data", "true");
|
|
100
|
-
}
|
|
101
|
-
const response = await fetch(url.toString(), {
|
|
102
|
-
method: "GET",
|
|
103
|
-
headers: {
|
|
104
|
-
Authorization: `Bearer ${accessToken}`,
|
|
105
|
-
"Accept-Language": language,
|
|
106
|
-
"Content-Type": "application/json"
|
|
107
|
-
},
|
|
108
|
-
signal
|
|
109
|
-
// Add abort signal for request cancellation
|
|
110
|
-
});
|
|
111
|
-
if (!response.ok) {
|
|
112
|
-
let errorMessage = `Failed to fetch consent content: ${response.status} ${response.statusText}`;
|
|
113
|
-
if (response.status === 401) {
|
|
114
|
-
errorMessage = "Unauthorized: Invalid or expired token";
|
|
115
|
-
} else if (response.status === 403) {
|
|
116
|
-
errorMessage = "Forbidden: Access denied";
|
|
117
|
-
} else if (response.status === 404) {
|
|
118
|
-
errorMessage = "Notice not found";
|
|
119
|
-
} else if (response.status === 409) {
|
|
120
|
-
errorMessage = "User has already provided consent";
|
|
121
|
-
} else if (response.status >= 500) {
|
|
122
|
-
errorMessage = "Server error: Please try again later";
|
|
123
|
-
}
|
|
124
|
-
const error = new Error(errorMessage);
|
|
125
|
-
error.status = response.status;
|
|
126
|
-
throw error;
|
|
71
|
+
if (!noticeId || !accessToken || !validate_against) {
|
|
72
|
+
throw new Error("noticeId and accessToken are required");
|
|
73
|
+
}
|
|
74
|
+
const decodedToken = decodeTokenSafely(accessToken);
|
|
75
|
+
if (!decodedToken) {
|
|
76
|
+
throw new Error("Invalid access token");
|
|
77
|
+
}
|
|
78
|
+
const { organisation_uuid: ORGANISATION_UUID, workspace_uuid: WORKSPACE_UUID } = decodedToken;
|
|
79
|
+
if (!ORGANISATION_UUID || !WORKSPACE_UUID) {
|
|
80
|
+
throw new Error("Invalid token: missing organization or workspace UUID");
|
|
81
|
+
}
|
|
82
|
+
const apiBaseUrl = baseUrl || BASE_URL;
|
|
83
|
+
const cacheKey = `${accessToken}-${noticeId}-${validate_against}-${language}-${specific_uuid || ""}-${include_fully_consented_data}`;
|
|
84
|
+
if (validate_against === "all" && !specific_uuid) {
|
|
85
|
+
const cachedData = getCachedData(cacheKey);
|
|
86
|
+
if (cachedData) {
|
|
87
|
+
return cachedData;
|
|
127
88
|
}
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
89
|
+
}
|
|
90
|
+
const url = new URL(
|
|
91
|
+
`${apiBaseUrl}/public/organisations/${ORGANISATION_UUID}/workspaces/${WORKSPACE_UUID}/notices/${noticeId}`
|
|
92
|
+
);
|
|
93
|
+
if (specific_uuid) {
|
|
94
|
+
url.searchParams.append("specific_uuid", specific_uuid);
|
|
95
|
+
}
|
|
96
|
+
url.searchParams.append("validate_against", validate_against);
|
|
97
|
+
if (include_fully_consented_data) {
|
|
98
|
+
url.searchParams.append("include_fully_consented_data", "true");
|
|
99
|
+
}
|
|
100
|
+
const response = await fetch(url.toString(), {
|
|
101
|
+
method: "GET",
|
|
102
|
+
headers: {
|
|
103
|
+
Authorization: `Bearer ${accessToken}`,
|
|
104
|
+
"Accept-Language": language
|
|
105
|
+
},
|
|
106
|
+
signal
|
|
107
|
+
});
|
|
108
|
+
if (!response.ok) {
|
|
109
|
+
let errorMessage = `Failed to fetch consent content: ${response.status} ${response.statusText}`;
|
|
110
|
+
if (response.status === 401) {
|
|
111
|
+
errorMessage = "Unauthorized: Invalid or expired token";
|
|
112
|
+
} else if (response.status === 403) {
|
|
113
|
+
errorMessage = "Forbidden: Access denied";
|
|
114
|
+
} else if (response.status === 404) {
|
|
115
|
+
errorMessage = "Notice not found";
|
|
116
|
+
} else if (response.status === 409) {
|
|
117
|
+
errorMessage = "User has already provided consent";
|
|
118
|
+
} else if (response.status >= 500) {
|
|
119
|
+
errorMessage = "Server error: Please try again later";
|
|
131
120
|
}
|
|
132
|
-
|
|
133
|
-
|
|
121
|
+
const error = new Error(errorMessage);
|
|
122
|
+
error.status = response.status;
|
|
134
123
|
throw error;
|
|
135
124
|
}
|
|
125
|
+
const data = await response.json();
|
|
126
|
+
if (validate_against === "all" && !specific_uuid) {
|
|
127
|
+
setCachedData(cacheKey, data);
|
|
128
|
+
}
|
|
129
|
+
return data;
|
|
136
130
|
};
|
|
137
131
|
var submitConsentEvent = async ({
|
|
138
132
|
accessToken,
|
|
@@ -140,101 +134,154 @@ var submitConsentEvent = async ({
|
|
|
140
134
|
noticeUuid,
|
|
141
135
|
purposes,
|
|
142
136
|
declined,
|
|
137
|
+
language,
|
|
143
138
|
meta_data,
|
|
139
|
+
guardianVerificationReference,
|
|
140
|
+
selfDeclaredAdult,
|
|
144
141
|
signal
|
|
145
|
-
// AbortSignal for request cancellation
|
|
146
142
|
}) => {
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
143
|
+
if (!noticeUuid || !accessToken || !Array.isArray(purposes)) {
|
|
144
|
+
throw new Error("noticeUuid, accessToken, and purposes array are required");
|
|
145
|
+
}
|
|
146
|
+
const decodedToken = decodeTokenSafely(accessToken);
|
|
147
|
+
if (!decodedToken) {
|
|
148
|
+
throw new Error("Invalid access token");
|
|
149
|
+
}
|
|
150
|
+
const { organisation_uuid: ORGANISATION_UUID, workspace_uuid: WORKSPACE_UUID } = decodedToken;
|
|
151
|
+
if (!ORGANISATION_UUID || !WORKSPACE_UUID) {
|
|
152
|
+
throw new Error("Invalid token: missing organization or workspace UUID");
|
|
153
|
+
}
|
|
154
|
+
const apiBaseUrl = baseUrl || BASE_URL;
|
|
155
|
+
const validatedPurposes = purposes.map((purpose) => {
|
|
156
|
+
if (!purpose.uuid) {
|
|
157
|
+
throw new Error(`Invalid purpose data: missing uuid`);
|
|
158
158
|
}
|
|
159
|
-
const
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
}));
|
|
168
|
-
return {
|
|
169
|
-
purpose_uuid: purpose.uuid,
|
|
170
|
-
selected: Boolean(purpose.selected),
|
|
171
|
-
data_elements: dataElements.length > 0 ? dataElements : void 0
|
|
172
|
-
};
|
|
173
|
-
});
|
|
174
|
-
const payload = {
|
|
175
|
-
notice_uuid: noticeUuid,
|
|
176
|
-
purposes: validatedPurposes,
|
|
177
|
-
select_all_mandatory: false,
|
|
178
|
-
source: "WEB",
|
|
179
|
-
declined: Boolean(declined),
|
|
180
|
-
meta_data: meta_data ? { specific_uuid: meta_data.specific_uuid } : void 0
|
|
159
|
+
const dataElements = (purpose.data_elements || []).filter((element) => element.enabled).map((element) => ({
|
|
160
|
+
uuid: element.uuid,
|
|
161
|
+
selected: element.required ? true : Boolean(element.selected)
|
|
162
|
+
}));
|
|
163
|
+
return {
|
|
164
|
+
purpose_uuid: purpose.uuid,
|
|
165
|
+
selected: Boolean(purpose.selected),
|
|
166
|
+
data_elements: dataElements.length > 0 ? dataElements : void 0
|
|
181
167
|
};
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
168
|
+
});
|
|
169
|
+
const payload = {
|
|
170
|
+
notice_uuid: noticeUuid,
|
|
171
|
+
purposes: validatedPurposes,
|
|
172
|
+
select_all_mandatory: false,
|
|
173
|
+
source: "WEB",
|
|
174
|
+
declined: Boolean(declined),
|
|
175
|
+
language: language || void 0,
|
|
176
|
+
meta_data: meta_data ? { specific_uuid: meta_data.specific_uuid, minor_age: meta_data.minor_age } : void 0,
|
|
177
|
+
guardian_verification_reference: guardianVerificationReference,
|
|
178
|
+
self_declared_adult: selfDeclaredAdult
|
|
179
|
+
};
|
|
180
|
+
const response = await fetch(
|
|
181
|
+
`${apiBaseUrl}/public/organisations/${ORGANISATION_UUID}/workspaces/${WORKSPACE_UUID}/submit-consent`,
|
|
182
|
+
{
|
|
183
|
+
method: "POST",
|
|
184
|
+
headers: {
|
|
185
|
+
Authorization: `Bearer ${accessToken}`,
|
|
186
|
+
"Content-Type": "application/json"
|
|
187
|
+
},
|
|
188
|
+
body: JSON.stringify(payload),
|
|
189
|
+
signal
|
|
190
|
+
}
|
|
191
|
+
);
|
|
192
|
+
if (!response.ok) {
|
|
193
|
+
let errorMessage = `Failed to submit consent: ${response.status} ${response.statusText}`;
|
|
194
|
+
if (response.status === 400) {
|
|
195
|
+
try {
|
|
196
|
+
const errorData = await response.json();
|
|
197
|
+
errorMessage = errorData.message || "Invalid request data";
|
|
198
|
+
} catch {
|
|
198
199
|
errorMessage = "Invalid request data";
|
|
199
|
-
} else if (response.status === 401) {
|
|
200
|
-
errorMessage = "Unauthorized: Invalid or expired token";
|
|
201
|
-
} else if (response.status === 403) {
|
|
202
|
-
errorMessage = "Forbidden: Access denied";
|
|
203
|
-
} else if (response.status === 404) {
|
|
204
|
-
errorMessage = "Notice not found";
|
|
205
|
-
} else if (response.status >= 500) {
|
|
206
|
-
errorMessage = "Server error: Please try again later";
|
|
207
200
|
}
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
201
|
+
} else if (response.status === 401) {
|
|
202
|
+
errorMessage = "Unauthorized: Invalid or expired token";
|
|
203
|
+
} else if (response.status === 403) {
|
|
204
|
+
errorMessage = "Forbidden: Access denied";
|
|
205
|
+
} else if (response.status === 404) {
|
|
206
|
+
errorMessage = "Notice not found";
|
|
207
|
+
} else if (response.status >= 500) {
|
|
208
|
+
errorMessage = "Server error: Please try again later";
|
|
211
209
|
}
|
|
212
|
-
|
|
213
|
-
|
|
210
|
+
const error = new Error(errorMessage);
|
|
211
|
+
error.status = response.status;
|
|
214
212
|
throw error;
|
|
215
213
|
}
|
|
214
|
+
apiCache.clear();
|
|
216
215
|
};
|
|
217
|
-
var
|
|
216
|
+
var fetchTTSAudioUrls = async ({
|
|
217
|
+
accessToken,
|
|
218
|
+
baseUrl,
|
|
219
|
+
noticeUuid,
|
|
220
|
+
language,
|
|
221
|
+
signal
|
|
222
|
+
}) => {
|
|
223
|
+
if (!accessToken || !noticeUuid || !language) {
|
|
224
|
+
throw new Error("accessToken, noticeUuid, and language are required");
|
|
225
|
+
}
|
|
226
|
+
const decodedToken = decodeTokenSafely(accessToken);
|
|
227
|
+
if (!decodedToken) {
|
|
228
|
+
throw new Error("Invalid access token");
|
|
229
|
+
}
|
|
230
|
+
const { organisation_uuid: ORGANISATION_UUID, workspace_uuid: WORKSPACE_UUID } = decodedToken;
|
|
231
|
+
if (!ORGANISATION_UUID || !WORKSPACE_UUID) {
|
|
232
|
+
throw new Error("Invalid token: missing organization or workspace UUID");
|
|
233
|
+
}
|
|
234
|
+
const apiBaseUrl = baseUrl || BASE_URL;
|
|
235
|
+
const url = `${apiBaseUrl}/public/organisations/${ORGANISATION_UUID}/workspaces/${WORKSPACE_UUID}/notices/${noticeUuid}/audio/${language}`;
|
|
236
|
+
const response = await fetch(url, {
|
|
237
|
+
method: "GET",
|
|
238
|
+
headers: {
|
|
239
|
+
Authorization: `Bearer ${accessToken}`,
|
|
240
|
+
Accept: "application/json"
|
|
241
|
+
},
|
|
242
|
+
signal
|
|
243
|
+
});
|
|
244
|
+
if (!response.ok) {
|
|
245
|
+
let errorMessage = `Failed to fetch TTS audio URLs: ${response.status} ${response.statusText}`;
|
|
246
|
+
if (response.status === 401) {
|
|
247
|
+
errorMessage = "Unauthorized: Invalid or expired token";
|
|
248
|
+
} else if (response.status === 403) {
|
|
249
|
+
errorMessage = "Forbidden: Access denied";
|
|
250
|
+
} else if (response.status === 404) {
|
|
251
|
+
errorMessage = "Notice or audio not found";
|
|
252
|
+
} else if (response.status >= 500) {
|
|
253
|
+
errorMessage = "Server error: Please try again later";
|
|
254
|
+
}
|
|
255
|
+
const error = new Error(errorMessage);
|
|
256
|
+
error.status = response.status;
|
|
257
|
+
throw error;
|
|
258
|
+
}
|
|
259
|
+
const data = await response.json();
|
|
260
|
+
return data;
|
|
261
|
+
};
|
|
262
|
+
var initiateGuardianVerification = async ({
|
|
218
263
|
accessToken,
|
|
219
264
|
baseUrl,
|
|
220
265
|
guardianName,
|
|
221
266
|
guardianContact,
|
|
222
267
|
guardianRelationship,
|
|
268
|
+
frontendCallbackUrl,
|
|
269
|
+
metadata,
|
|
223
270
|
signal
|
|
224
|
-
// AbortSignal for request cancellation
|
|
225
271
|
}) => {
|
|
272
|
+
var _a;
|
|
226
273
|
try {
|
|
227
274
|
if (!accessToken) {
|
|
228
275
|
throw new Error("accessToken is required");
|
|
229
276
|
}
|
|
230
277
|
if (!(guardianName == null ? void 0 : guardianName.trim())) {
|
|
231
|
-
throw new Error("
|
|
278
|
+
throw new Error("Guardian name is required");
|
|
232
279
|
}
|
|
233
280
|
if (!(guardianContact == null ? void 0 : guardianContact.trim())) {
|
|
234
|
-
throw new Error("
|
|
281
|
+
throw new Error("Guardian contact is required");
|
|
235
282
|
}
|
|
236
283
|
if (!(guardianRelationship == null ? void 0 : guardianRelationship.trim())) {
|
|
237
|
-
throw new Error("
|
|
284
|
+
throw new Error("Guardian relationship is required");
|
|
238
285
|
}
|
|
239
286
|
const decodedToken = decodeTokenSafely(accessToken);
|
|
240
287
|
if (!decodedToken) {
|
|
@@ -244,14 +291,20 @@ var submitGuardianInfo = async ({
|
|
|
244
291
|
if (!ORGANISATION_UUID || !WORKSPACE_UUID) {
|
|
245
292
|
throw new Error("Invalid token: missing organization or workspace UUID");
|
|
246
293
|
}
|
|
294
|
+
const apiBaseUrl = baseUrl || BASE_URL;
|
|
247
295
|
const payload = {
|
|
248
296
|
guardian_name: guardianName.trim(),
|
|
249
297
|
guardian_contact: guardianContact.trim(),
|
|
250
298
|
guardian_relationship: guardianRelationship.trim()
|
|
251
299
|
};
|
|
252
|
-
|
|
300
|
+
if (frontendCallbackUrl) {
|
|
301
|
+
payload.frontend_callback_url = frontendCallbackUrl;
|
|
302
|
+
}
|
|
303
|
+
if (metadata) {
|
|
304
|
+
payload.metadata = metadata;
|
|
305
|
+
}
|
|
253
306
|
const response = await fetch(
|
|
254
|
-
`${apiBaseUrl}/public/organisations/${ORGANISATION_UUID}/workspaces/${WORKSPACE_UUID}/guardian-
|
|
307
|
+
`${apiBaseUrl}/public/organisations/${ORGANISATION_UUID}/workspaces/${WORKSPACE_UUID}/guardian/initiate-verification`,
|
|
255
308
|
{
|
|
256
309
|
method: "POST",
|
|
257
310
|
headers: {
|
|
@@ -260,24 +313,26 @@ var submitGuardianInfo = async ({
|
|
|
260
313
|
},
|
|
261
314
|
body: JSON.stringify(payload),
|
|
262
315
|
signal
|
|
263
|
-
// Add abort signal for request cancellation
|
|
264
316
|
}
|
|
265
317
|
);
|
|
266
318
|
if (!response.ok) {
|
|
267
|
-
let errorMessage = `Failed to
|
|
319
|
+
let errorMessage = `Failed to initiate verification: ${response.status} ${response.statusText}`;
|
|
268
320
|
if (response.status === 400) {
|
|
269
|
-
|
|
321
|
+
try {
|
|
322
|
+
const errorData = await response.json();
|
|
323
|
+
errorMessage = errorData.message || "Invalid request data";
|
|
324
|
+
} catch {
|
|
325
|
+
errorMessage = "Invalid request data";
|
|
326
|
+
}
|
|
270
327
|
} else if (response.status === 401) {
|
|
271
328
|
errorMessage = "Unauthorized: Invalid or expired token";
|
|
272
|
-
} else if (response.status === 403) {
|
|
273
|
-
errorMessage = "Forbidden: Access denied";
|
|
274
329
|
} else if (response.status === 404) {
|
|
275
330
|
errorMessage = "Organization or workspace not found";
|
|
276
331
|
} else if (response.status === 422) {
|
|
277
332
|
try {
|
|
278
333
|
const errorData = await response.json();
|
|
279
|
-
errorMessage = errorData.message || "Validation error";
|
|
280
|
-
} catch
|
|
334
|
+
errorMessage = errorData.message || "Validation error: Please check your input";
|
|
335
|
+
} catch {
|
|
281
336
|
errorMessage = "Validation error: Please check your input";
|
|
282
337
|
}
|
|
283
338
|
} else if (response.status >= 500) {
|
|
@@ -287,63 +342,98 @@ var submitGuardianInfo = async ({
|
|
|
287
342
|
error.status = response.status;
|
|
288
343
|
throw error;
|
|
289
344
|
}
|
|
345
|
+
const responseData = await response.json();
|
|
346
|
+
const detail = responseData.detail || responseData;
|
|
347
|
+
if (detail.already_verified) {
|
|
348
|
+
return {
|
|
349
|
+
success: true,
|
|
350
|
+
guardian_info_uuid: detail.guardian_info_uuid,
|
|
351
|
+
already_verified: true,
|
|
352
|
+
verification_reference: detail.verification_reference
|
|
353
|
+
};
|
|
354
|
+
}
|
|
355
|
+
if (!detail.session_token || !detail.digilocker_redirect_url) {
|
|
356
|
+
throw new Error("Invalid response: missing session_token or digilocker_redirect_url");
|
|
357
|
+
}
|
|
358
|
+
return {
|
|
359
|
+
success: (_a = detail.success) != null ? _a : true,
|
|
360
|
+
guardian_info_uuid: detail.guardian_info_uuid,
|
|
361
|
+
already_verified: false,
|
|
362
|
+
session_token: detail.session_token,
|
|
363
|
+
digilocker_redirect_url: detail.digilocker_redirect_url,
|
|
364
|
+
expires_at: detail.expires_at
|
|
365
|
+
};
|
|
290
366
|
} catch (error) {
|
|
291
|
-
console.error("Error
|
|
367
|
+
console.error("Error initiating guardian verification:", error instanceof Error ? error.message : error);
|
|
292
368
|
throw error;
|
|
293
369
|
}
|
|
294
370
|
};
|
|
295
|
-
var
|
|
371
|
+
var verifyGuardianStatus = async ({
|
|
296
372
|
accessToken,
|
|
297
373
|
baseUrl,
|
|
298
|
-
|
|
299
|
-
language,
|
|
374
|
+
sessionToken,
|
|
300
375
|
signal
|
|
301
|
-
// AbortSignal for request cancellation
|
|
302
376
|
}) => {
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
377
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
378
|
+
if (!accessToken || !sessionToken) {
|
|
379
|
+
throw new Error("accessToken and sessionToken are required");
|
|
380
|
+
}
|
|
381
|
+
const decodedToken = decodeTokenSafely(accessToken);
|
|
382
|
+
if (!decodedToken) {
|
|
383
|
+
throw new Error("Invalid access token");
|
|
384
|
+
}
|
|
385
|
+
const { organisation_uuid: ORGANISATION_UUID, workspace_uuid: WORKSPACE_UUID } = decodedToken;
|
|
386
|
+
if (!ORGANISATION_UUID || !WORKSPACE_UUID) {
|
|
387
|
+
throw new Error("Invalid token: missing organization or workspace UUID");
|
|
388
|
+
}
|
|
389
|
+
const apiBaseUrl = baseUrl || BASE_URL;
|
|
390
|
+
const response = await fetch(
|
|
391
|
+
`${apiBaseUrl}/public/organisations/${ORGANISATION_UUID}/workspaces/${WORKSPACE_UUID}/guardian/verify-status`,
|
|
392
|
+
{
|
|
393
|
+
method: "POST",
|
|
319
394
|
headers: {
|
|
320
395
|
Authorization: `Bearer ${accessToken}`,
|
|
321
|
-
Accept: "application/json",
|
|
322
396
|
"Content-Type": "application/json"
|
|
323
397
|
},
|
|
398
|
+
body: JSON.stringify({
|
|
399
|
+
session_token: sessionToken
|
|
400
|
+
}),
|
|
324
401
|
signal
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
errorMessage =
|
|
333
|
-
}
|
|
334
|
-
errorMessage = "
|
|
335
|
-
} else if (response.status >= 500) {
|
|
336
|
-
errorMessage = "Server error: Please try again later";
|
|
402
|
+
}
|
|
403
|
+
);
|
|
404
|
+
if (!response.ok) {
|
|
405
|
+
let errorMessage = `Failed to check verification status: ${response.status} ${response.statusText}`;
|
|
406
|
+
if (response.status === 400) {
|
|
407
|
+
try {
|
|
408
|
+
const errorData = await response.json();
|
|
409
|
+
errorMessage = errorData.message || ((_a = errorData.detail) == null ? void 0 : _a.message) || "Invalid session token";
|
|
410
|
+
} catch {
|
|
411
|
+
errorMessage = "Invalid session token";
|
|
337
412
|
}
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
413
|
+
} else if (response.status === 401) {
|
|
414
|
+
errorMessage = "Unauthorized: Invalid or expired token";
|
|
415
|
+
} else if (response.status === 404) {
|
|
416
|
+
errorMessage = "Verification session not found or expired. Please restart the verification process.";
|
|
417
|
+
} else if (response.status === 410) {
|
|
418
|
+
errorMessage = "Verification session has expired. Please restart the verification process.";
|
|
419
|
+
} else if (response.status >= 500) {
|
|
420
|
+
errorMessage = "Server error: Please try again later";
|
|
341
421
|
}
|
|
342
|
-
const
|
|
343
|
-
|
|
344
|
-
} catch (error) {
|
|
422
|
+
const error = new Error(errorMessage);
|
|
423
|
+
error.status = response.status;
|
|
345
424
|
throw error;
|
|
346
425
|
}
|
|
426
|
+
const responseData = await response.json();
|
|
427
|
+
const detail = responseData.detail || responseData;
|
|
428
|
+
return {
|
|
429
|
+
status: (_b = detail.status) != null ? _b : "in_progress",
|
|
430
|
+
guardian_info_uuid: (_c = detail.guardian_info_uuid) != null ? _c : null,
|
|
431
|
+
verification_reference: (_d = detail.verification_reference) != null ? _d : null,
|
|
432
|
+
guardian_details: (_e = detail.guardian_details) != null ? _e : null,
|
|
433
|
+
error: (_f = detail.error) != null ? _f : null,
|
|
434
|
+
error_code: (_g = detail.error_code) != null ? _g : null,
|
|
435
|
+
can_retry: (_h = detail.can_retry) != null ? _h : true
|
|
436
|
+
};
|
|
347
437
|
};
|
|
348
438
|
|
|
349
439
|
// src/RedactoNoticeConsent/assets/redacto-logo.png
|
|
@@ -361,6 +451,52 @@ var DPO_AUDIO_ELEMENT_MAP = [
|
|
|
361
451
|
{ audioKey: "dpo_anchor_text_audio_url", elementId: "dpo-dpo-link" }
|
|
362
452
|
];
|
|
363
453
|
|
|
454
|
+
// src/RedactoNoticeConsent/language-codes.ts
|
|
455
|
+
var LANGUAGE_NAME_TO_BCP47 = {
|
|
456
|
+
English: "en",
|
|
457
|
+
Assamese: "as",
|
|
458
|
+
Bengali: "bn",
|
|
459
|
+
Bodo: "brx",
|
|
460
|
+
Dogri: "doi",
|
|
461
|
+
Gujarati: "gu",
|
|
462
|
+
Hindi: "hi",
|
|
463
|
+
Kannada: "kn",
|
|
464
|
+
Kashmiri: "ks",
|
|
465
|
+
Konkani: "gom",
|
|
466
|
+
Maithili: "mai",
|
|
467
|
+
Malayalam: "ml",
|
|
468
|
+
Manipuri: "mni-Mtei",
|
|
469
|
+
Marathi: "mr",
|
|
470
|
+
Nepali: "ne",
|
|
471
|
+
Odia: "or",
|
|
472
|
+
Punjabi: "pa",
|
|
473
|
+
Sanskrit: "sa",
|
|
474
|
+
Santali: "sat",
|
|
475
|
+
Sindhi: "sd",
|
|
476
|
+
Tamil: "ta",
|
|
477
|
+
Telugu: "te",
|
|
478
|
+
Urdu: "ur"
|
|
479
|
+
};
|
|
480
|
+
var KNOWN_BCP47_CODES = new Set(Object.values(LANGUAGE_NAME_TO_BCP47));
|
|
481
|
+
var toBcp47Code = (language) => {
|
|
482
|
+
if (LANGUAGE_NAME_TO_BCP47[language]) {
|
|
483
|
+
return LANGUAGE_NAME_TO_BCP47[language];
|
|
484
|
+
}
|
|
485
|
+
if (KNOWN_BCP47_CODES.has(language)) {
|
|
486
|
+
return language;
|
|
487
|
+
}
|
|
488
|
+
const lower = language.toLowerCase();
|
|
489
|
+
for (const [name, code] of Object.entries(LANGUAGE_NAME_TO_BCP47)) {
|
|
490
|
+
if (name.toLowerCase() === lower) {
|
|
491
|
+
return code;
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
if (/^[A-Za-z]{2,3}(?:-[A-Za-z0-9]{2,8})*$/.test(language)) {
|
|
495
|
+
return language;
|
|
496
|
+
}
|
|
497
|
+
return "en";
|
|
498
|
+
};
|
|
499
|
+
|
|
364
500
|
// src/RedactoNoticeConsent/injectStyles.ts
|
|
365
501
|
var stylesInjected = false;
|
|
366
502
|
var injectCheckboxStyles = () => {
|
|
@@ -491,6 +627,17 @@ var injectCheckboxStyles = () => {
|
|
|
491
627
|
outline: 3px solid #FFF9C4 !important;
|
|
492
628
|
outline-offset: 2px !important;
|
|
493
629
|
}
|
|
630
|
+
|
|
631
|
+
/* Spinner animation for verification screens */
|
|
632
|
+
@keyframes spin {
|
|
633
|
+
from { transform: rotate(0deg); }
|
|
634
|
+
to { transform: rotate(360deg); }
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
/* DigiLocker callback retry button hover */
|
|
638
|
+
.redacto-dl-retry-btn:hover {
|
|
639
|
+
background-color: #2563eb !important;
|
|
640
|
+
}
|
|
494
641
|
`;
|
|
495
642
|
document.head.appendChild(style);
|
|
496
643
|
stylesInjected = true;
|
|
@@ -873,6 +1020,69 @@ var useMediaQuery = (query) => {
|
|
|
873
1020
|
return matches;
|
|
874
1021
|
};
|
|
875
1022
|
|
|
1023
|
+
// src/RedactoNoticeConsent/services/storage.ts
|
|
1024
|
+
var STORAGE_KEY = "redacto_consent_sdk_state";
|
|
1025
|
+
var STATE_EXPIRY_MS = 30 * 60 * 1e3;
|
|
1026
|
+
var isBrowser = () => {
|
|
1027
|
+
return typeof window !== "undefined" && typeof window.sessionStorage !== "undefined";
|
|
1028
|
+
};
|
|
1029
|
+
var saveConsentState = (state) => {
|
|
1030
|
+
if (!isBrowser()) {
|
|
1031
|
+
console.warn("SessionStorage not available - state not persisted");
|
|
1032
|
+
return;
|
|
1033
|
+
}
|
|
1034
|
+
try {
|
|
1035
|
+
const stateWithTimestamp = {
|
|
1036
|
+
...state,
|
|
1037
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
1038
|
+
};
|
|
1039
|
+
sessionStorage.setItem(STORAGE_KEY, JSON.stringify(stateWithTimestamp));
|
|
1040
|
+
} catch (error) {
|
|
1041
|
+
console.error("Failed to save consent state:", error);
|
|
1042
|
+
}
|
|
1043
|
+
};
|
|
1044
|
+
var getConsentState = () => {
|
|
1045
|
+
if (!isBrowser()) {
|
|
1046
|
+
return null;
|
|
1047
|
+
}
|
|
1048
|
+
try {
|
|
1049
|
+
const savedState = sessionStorage.getItem(STORAGE_KEY);
|
|
1050
|
+
if (!savedState) {
|
|
1051
|
+
return null;
|
|
1052
|
+
}
|
|
1053
|
+
const parsed = JSON.parse(savedState);
|
|
1054
|
+
const stateAge = Date.now() - new Date(parsed.timestamp).getTime();
|
|
1055
|
+
if (stateAge > STATE_EXPIRY_MS) {
|
|
1056
|
+
clearConsentState();
|
|
1057
|
+
return null;
|
|
1058
|
+
}
|
|
1059
|
+
return parsed;
|
|
1060
|
+
} catch (error) {
|
|
1061
|
+
console.error("Failed to get consent state:", error);
|
|
1062
|
+
return null;
|
|
1063
|
+
}
|
|
1064
|
+
};
|
|
1065
|
+
var clearConsentState = () => {
|
|
1066
|
+
if (!isBrowser()) {
|
|
1067
|
+
return;
|
|
1068
|
+
}
|
|
1069
|
+
try {
|
|
1070
|
+
sessionStorage.removeItem(STORAGE_KEY);
|
|
1071
|
+
} catch (error) {
|
|
1072
|
+
console.error("Failed to clear consent state:", error);
|
|
1073
|
+
}
|
|
1074
|
+
};
|
|
1075
|
+
var updateConsentState = (updates) => {
|
|
1076
|
+
const currentState = getConsentState();
|
|
1077
|
+
if (currentState) {
|
|
1078
|
+
saveConsentState({
|
|
1079
|
+
...currentState,
|
|
1080
|
+
...updates,
|
|
1081
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
1082
|
+
});
|
|
1083
|
+
}
|
|
1084
|
+
};
|
|
1085
|
+
|
|
876
1086
|
// src/RedactoNoticeConsent/RedactoNoticeConsent.tsx
|
|
877
1087
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
878
1088
|
var PurposeItem = ({
|
|
@@ -1180,6 +1390,12 @@ var PurposeItem = ({
|
|
|
1180
1390
|
)
|
|
1181
1391
|
] }, purpose.uuid);
|
|
1182
1392
|
};
|
|
1393
|
+
var RELATIONSHIP_OPTIONS = [
|
|
1394
|
+
{ value: "Father", label: "Father" },
|
|
1395
|
+
{ value: "Mother", label: "Mother" },
|
|
1396
|
+
{ value: "Legal Guardian", label: "Legal Guardian" },
|
|
1397
|
+
{ value: "Grandparent", label: "Grandparent" }
|
|
1398
|
+
];
|
|
1183
1399
|
var GuardianForm = ({
|
|
1184
1400
|
formData,
|
|
1185
1401
|
errors,
|
|
@@ -1196,34 +1412,128 @@ var GuardianForm = ({
|
|
|
1196
1412
|
declineButtonStyle,
|
|
1197
1413
|
logoUrl
|
|
1198
1414
|
}) => {
|
|
1415
|
+
var _a, _b, _c, _d, _e;
|
|
1416
|
+
const [isDropdownOpen, setIsDropdownOpen] = (0, import_react2.useState)(false);
|
|
1417
|
+
const [focusedIndex, setFocusedIndex] = (0, import_react2.useState)(-1);
|
|
1418
|
+
const [openUpward, setOpenUpward] = (0, import_react2.useState)(false);
|
|
1419
|
+
const dropdownRef = (0, import_react2.useRef)(null);
|
|
1420
|
+
const optionsRef = (0, import_react2.useRef)(null);
|
|
1421
|
+
(0, import_react2.useEffect)(() => {
|
|
1422
|
+
if (!isDropdownOpen) return;
|
|
1423
|
+
const handleClickOutside = (e) => {
|
|
1424
|
+
if (dropdownRef.current && !dropdownRef.current.contains(e.target)) {
|
|
1425
|
+
setIsDropdownOpen(false);
|
|
1426
|
+
setFocusedIndex(-1);
|
|
1427
|
+
}
|
|
1428
|
+
};
|
|
1429
|
+
document.addEventListener("mousedown", handleClickOutside);
|
|
1430
|
+
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
1431
|
+
}, [isDropdownOpen]);
|
|
1432
|
+
(0, import_react2.useEffect)(() => {
|
|
1433
|
+
if (!isDropdownOpen || !dropdownRef.current) return;
|
|
1434
|
+
const rect = dropdownRef.current.getBoundingClientRect();
|
|
1435
|
+
const spaceBelow = window.innerHeight - rect.bottom;
|
|
1436
|
+
const dropdownHeight = 220;
|
|
1437
|
+
setOpenUpward(spaceBelow < dropdownHeight && rect.top > dropdownHeight);
|
|
1438
|
+
}, [isDropdownOpen]);
|
|
1439
|
+
const handleSelect = (value) => {
|
|
1440
|
+
onChange("guardianRelationship", value);
|
|
1441
|
+
setIsDropdownOpen(false);
|
|
1442
|
+
setFocusedIndex(-1);
|
|
1443
|
+
};
|
|
1444
|
+
const handleKeyDown = (e) => {
|
|
1445
|
+
if (!isDropdownOpen) {
|
|
1446
|
+
if (e.key === "Enter" || e.key === " " || e.key === "ArrowDown") {
|
|
1447
|
+
e.preventDefault();
|
|
1448
|
+
setIsDropdownOpen(true);
|
|
1449
|
+
setFocusedIndex(0);
|
|
1450
|
+
}
|
|
1451
|
+
return;
|
|
1452
|
+
}
|
|
1453
|
+
switch (e.key) {
|
|
1454
|
+
case "ArrowDown":
|
|
1455
|
+
e.preventDefault();
|
|
1456
|
+
setFocusedIndex((prev) => Math.min(prev + 1, RELATIONSHIP_OPTIONS.length - 1));
|
|
1457
|
+
break;
|
|
1458
|
+
case "ArrowUp":
|
|
1459
|
+
e.preventDefault();
|
|
1460
|
+
setFocusedIndex((prev) => Math.max(prev - 1, 0));
|
|
1461
|
+
break;
|
|
1462
|
+
case "Enter":
|
|
1463
|
+
case " ":
|
|
1464
|
+
e.preventDefault();
|
|
1465
|
+
if (focusedIndex >= 0) handleSelect(RELATIONSHIP_OPTIONS[focusedIndex].value);
|
|
1466
|
+
break;
|
|
1467
|
+
case "Escape":
|
|
1468
|
+
case "Tab":
|
|
1469
|
+
setIsDropdownOpen(false);
|
|
1470
|
+
setFocusedIndex(-1);
|
|
1471
|
+
break;
|
|
1472
|
+
}
|
|
1473
|
+
};
|
|
1474
|
+
(0, import_react2.useEffect)(() => {
|
|
1475
|
+
var _a2;
|
|
1476
|
+
if (focusedIndex >= 0 && optionsRef.current) {
|
|
1477
|
+
const option = optionsRef.current.children[focusedIndex];
|
|
1478
|
+
(_a2 = option == null ? void 0 : option.scrollIntoView) == null ? void 0 : _a2.call(option, { block: "nearest" });
|
|
1479
|
+
}
|
|
1480
|
+
}, [focusedIndex]);
|
|
1481
|
+
const borderColor = (settings == null ? void 0 : settings.borderColor) || "#d0d5dd";
|
|
1482
|
+
const textColor = (settings == null ? void 0 : settings.textColor) || "#344054";
|
|
1483
|
+
const bgColor = (settings == null ? void 0 : settings.backgroundColor) || "#ffffff";
|
|
1484
|
+
const radius = (settings == null ? void 0 : settings.borderRadius) || "8px";
|
|
1485
|
+
const font = (settings == null ? void 0 : settings.font) || "inherit";
|
|
1199
1486
|
const inputStyle = {
|
|
1200
1487
|
width: "100%",
|
|
1201
1488
|
padding: "10px 12px",
|
|
1202
|
-
border: `1px solid ${
|
|
1203
|
-
borderRadius:
|
|
1489
|
+
border: `1px solid ${borderColor}`,
|
|
1490
|
+
borderRadius: radius,
|
|
1204
1491
|
fontSize: "13px",
|
|
1205
|
-
fontFamily:
|
|
1206
|
-
color:
|
|
1207
|
-
backgroundColor:
|
|
1208
|
-
marginBottom: "
|
|
1209
|
-
boxSizing: "border-box"
|
|
1492
|
+
fontFamily: font,
|
|
1493
|
+
color: textColor,
|
|
1494
|
+
backgroundColor: bgColor,
|
|
1495
|
+
marginBottom: "2px",
|
|
1496
|
+
boxSizing: "border-box",
|
|
1497
|
+
outline: "none"
|
|
1210
1498
|
};
|
|
1211
1499
|
const errorStyle = {
|
|
1212
1500
|
color: "#DC2626",
|
|
1213
|
-
fontSize: "
|
|
1501
|
+
fontSize: "11px",
|
|
1214
1502
|
marginTop: "4px",
|
|
1215
|
-
marginBottom: "
|
|
1503
|
+
marginBottom: "0px"
|
|
1216
1504
|
};
|
|
1217
1505
|
const labelStyle = {
|
|
1218
1506
|
...componentTextStyle,
|
|
1219
1507
|
fontSize: "13px",
|
|
1220
1508
|
fontWeight: "500",
|
|
1221
|
-
marginBottom: "
|
|
1509
|
+
marginBottom: "4px",
|
|
1222
1510
|
display: "block"
|
|
1223
1511
|
};
|
|
1512
|
+
const hintStyle = {
|
|
1513
|
+
fontSize: "11px",
|
|
1514
|
+
color: "#667085",
|
|
1515
|
+
marginTop: "2px",
|
|
1516
|
+
marginBottom: "0px",
|
|
1517
|
+
lineHeight: "1.4"
|
|
1518
|
+
};
|
|
1519
|
+
const infoBannerStyle = {
|
|
1520
|
+
display: "flex",
|
|
1521
|
+
alignItems: "flex-start",
|
|
1522
|
+
gap: "8px",
|
|
1523
|
+
padding: "10px 12px",
|
|
1524
|
+
backgroundColor: "#EFF6FF",
|
|
1525
|
+
border: "1px solid #BFDBFE",
|
|
1526
|
+
borderRadius: radius,
|
|
1527
|
+
marginBottom: "16px",
|
|
1528
|
+
fontSize: "12px",
|
|
1529
|
+
lineHeight: "1.5",
|
|
1530
|
+
color: "#1E40AF"
|
|
1531
|
+
};
|
|
1532
|
+
const selectedLabel = (_a = RELATIONSHIP_OPTIONS.find((o) => o.value === formData.guardianRelationship)) == null ? void 0 : _a.label;
|
|
1533
|
+
const hasError = Boolean(errors.guardianRelationship);
|
|
1224
1534
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
1225
1535
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { ...styles3.topSection, ...componentTextStyle }, children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: styles3.topLeft, children: [
|
|
1226
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("img", { style: styles3.logo, src: logoUrl, alt: "
|
|
1536
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("img", { style: styles3.logo, src: logoUrl, alt: "Logo" }),
|
|
1227
1537
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1228
1538
|
"h2",
|
|
1229
1539
|
{
|
|
@@ -1235,7 +1545,7 @@ var GuardianForm = ({
|
|
|
1235
1545
|
fontSize: "16px",
|
|
1236
1546
|
fontWeight: 600
|
|
1237
1547
|
},
|
|
1238
|
-
children: "Guardian
|
|
1548
|
+
children: "Guardian Verification"
|
|
1239
1549
|
}
|
|
1240
1550
|
)
|
|
1241
1551
|
] }) }),
|
|
@@ -1255,31 +1565,49 @@ var GuardianForm = ({
|
|
|
1255
1565
|
...styles3.privacyText,
|
|
1256
1566
|
...responsiveStyles.privacyText,
|
|
1257
1567
|
...componentTextStyle,
|
|
1258
|
-
fontSize: "
|
|
1259
|
-
lineHeight: "1.
|
|
1568
|
+
fontSize: "13px",
|
|
1569
|
+
lineHeight: "1.5",
|
|
1570
|
+
marginBottom: "12px"
|
|
1260
1571
|
},
|
|
1261
|
-
children: "
|
|
1572
|
+
children: "Since you are under the age of consent, a legal guardian must verify their identity via DigiLocker before you can proceed."
|
|
1262
1573
|
}
|
|
1263
1574
|
),
|
|
1575
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: infoBannerStyle, children: [
|
|
1576
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
1577
|
+
"svg",
|
|
1578
|
+
{
|
|
1579
|
+
width: "16",
|
|
1580
|
+
height: "16",
|
|
1581
|
+
viewBox: "0 0 24 24",
|
|
1582
|
+
fill: "none",
|
|
1583
|
+
stroke: "#2563EB",
|
|
1584
|
+
strokeWidth: "2",
|
|
1585
|
+
strokeLinecap: "round",
|
|
1586
|
+
strokeLinejoin: "round",
|
|
1587
|
+
style: { flexShrink: 0, marginTop: "1px" },
|
|
1588
|
+
children: [
|
|
1589
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: "12", cy: "12", r: "10" }),
|
|
1590
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "12", y1: "16", x2: "12", y2: "12" }),
|
|
1591
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "12", y1: "8", x2: "12.01", y2: "8" })
|
|
1592
|
+
]
|
|
1593
|
+
}
|
|
1594
|
+
),
|
|
1595
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: "The guardian's name will be matched against their DigiLocker identity document (e.g. Aadhaar). Please enter the name exactly as it appears on the document." })
|
|
1596
|
+
] }),
|
|
1264
1597
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
1265
1598
|
"div",
|
|
1266
1599
|
{
|
|
1267
1600
|
style: {
|
|
1268
1601
|
display: "flex",
|
|
1269
1602
|
flexDirection: "column",
|
|
1270
|
-
gap: "
|
|
1271
|
-
marginTop: "16px"
|
|
1603
|
+
gap: "14px"
|
|
1272
1604
|
},
|
|
1273
1605
|
children: [
|
|
1274
1606
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
|
|
1275
|
-
/* @__PURE__ */ (0, import_jsx_runtime.
|
|
1276
|
-
"
|
|
1277
|
-
{
|
|
1278
|
-
|
|
1279
|
-
style: { ...labelStyle, marginBottom: "8px", display: "block" },
|
|
1280
|
-
children: "Name of Guardian *"
|
|
1281
|
-
}
|
|
1282
|
-
),
|
|
1607
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { htmlFor: "guardianName", style: labelStyle, children: [
|
|
1608
|
+
"Guardian's Full Name ",
|
|
1609
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { color: "#DC2626" }, children: "*" })
|
|
1610
|
+
] }),
|
|
1283
1611
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1284
1612
|
"input",
|
|
1285
1613
|
{
|
|
@@ -1289,62 +1617,170 @@ var GuardianForm = ({
|
|
|
1289
1617
|
onChange: (e) => onChange("guardianName", e.target.value),
|
|
1290
1618
|
style: {
|
|
1291
1619
|
...inputStyle,
|
|
1292
|
-
borderColor: errors.guardianName ? "#DC2626" :
|
|
1620
|
+
borderColor: errors.guardianName ? "#DC2626" : borderColor
|
|
1293
1621
|
},
|
|
1294
|
-
placeholder: "
|
|
1622
|
+
placeholder: "e.g. Rajesh Kumar",
|
|
1623
|
+
autoComplete: "name",
|
|
1624
|
+
"aria-describedby": "guardianName-hint"
|
|
1295
1625
|
}
|
|
1296
1626
|
),
|
|
1297
|
-
|
|
1627
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { id: "guardianName-hint", style: hintStyle, children: "Enter the full name as per government ID (Aadhaar, PAN, etc.)" }),
|
|
1628
|
+
errors.guardianName && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: errorStyle, role: "alert", children: errors.guardianName })
|
|
1298
1629
|
] }),
|
|
1299
1630
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
|
|
1300
|
-
/* @__PURE__ */ (0, import_jsx_runtime.
|
|
1301
|
-
"
|
|
1302
|
-
{
|
|
1303
|
-
|
|
1304
|
-
style: { ...labelStyle, marginBottom: "8px", display: "block" },
|
|
1305
|
-
children: "Contact of Guardian *"
|
|
1306
|
-
}
|
|
1307
|
-
),
|
|
1631
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { htmlFor: "guardianContact", style: labelStyle, children: [
|
|
1632
|
+
"Guardian's Phone Number ",
|
|
1633
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { color: "#DC2626" }, children: "*" })
|
|
1634
|
+
] }),
|
|
1308
1635
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1309
1636
|
"input",
|
|
1310
1637
|
{
|
|
1311
1638
|
id: "guardianContact",
|
|
1312
|
-
type: "
|
|
1639
|
+
type: "tel",
|
|
1640
|
+
inputMode: "tel",
|
|
1313
1641
|
value: formData.guardianContact,
|
|
1314
1642
|
onChange: (e) => onChange("guardianContact", e.target.value),
|
|
1315
1643
|
style: {
|
|
1316
1644
|
...inputStyle,
|
|
1317
|
-
borderColor: errors.guardianContact ? "#DC2626" :
|
|
1645
|
+
borderColor: errors.guardianContact ? "#DC2626" : borderColor
|
|
1318
1646
|
},
|
|
1319
|
-
placeholder: "
|
|
1647
|
+
placeholder: "e.g. 9876543210",
|
|
1648
|
+
autoComplete: "tel",
|
|
1649
|
+
"aria-describedby": "guardianContact-hint"
|
|
1320
1650
|
}
|
|
1321
1651
|
),
|
|
1322
|
-
|
|
1652
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { id: "guardianContact-hint", style: hintStyle, children: "Mobile number linked to guardian's Aadhaar" }),
|
|
1653
|
+
errors.guardianContact && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: errorStyle, role: "alert", children: errors.guardianContact })
|
|
1323
1654
|
] }),
|
|
1324
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
|
|
1325
|
-
/* @__PURE__ */ (0, import_jsx_runtime.
|
|
1326
|
-
"
|
|
1655
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { ref: dropdownRef, style: { position: "relative" }, children: [
|
|
1656
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { id: "guardianRelationship-label", style: labelStyle, children: [
|
|
1657
|
+
"Relationship ",
|
|
1658
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { color: "#DC2626" }, children: "*" })
|
|
1659
|
+
] }),
|
|
1660
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
1661
|
+
"div",
|
|
1327
1662
|
{
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1663
|
+
role: "combobox",
|
|
1664
|
+
"aria-expanded": isDropdownOpen,
|
|
1665
|
+
"aria-haspopup": "listbox",
|
|
1666
|
+
"aria-labelledby": "guardianRelationship-label",
|
|
1667
|
+
"aria-controls": "guardianRelationship-listbox",
|
|
1668
|
+
"aria-activedescendant": focusedIndex >= 0 ? `guardianRelationship-option-${focusedIndex}` : void 0,
|
|
1669
|
+
tabIndex: 0,
|
|
1670
|
+
onClick: () => {
|
|
1671
|
+
setIsDropdownOpen((prev) => !prev);
|
|
1672
|
+
setFocusedIndex(-1);
|
|
1673
|
+
},
|
|
1674
|
+
onKeyDown: handleKeyDown,
|
|
1675
|
+
style: {
|
|
1676
|
+
...inputStyle,
|
|
1677
|
+
borderColor: hasError ? "#DC2626" : isDropdownOpen ? ((_c = (_b = settings == null ? void 0 : settings.button) == null ? void 0 : _b.accept) == null ? void 0 : _c.backgroundColor) || "#3b82f6" : borderColor,
|
|
1678
|
+
boxShadow: isDropdownOpen ? `0 0 0 1px ${((_e = (_d = settings == null ? void 0 : settings.button) == null ? void 0 : _d.accept) == null ? void 0 : _e.backgroundColor) || "#3b82f6"}` : "none",
|
|
1679
|
+
color: selectedLabel ? textColor : "#9CA3AF",
|
|
1680
|
+
cursor: "pointer",
|
|
1681
|
+
display: "flex",
|
|
1682
|
+
alignItems: "center",
|
|
1683
|
+
justifyContent: "space-between",
|
|
1684
|
+
userSelect: "none",
|
|
1685
|
+
transition: "border-color 0.15s, box-shadow 0.15s"
|
|
1686
|
+
},
|
|
1687
|
+
children: [
|
|
1688
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }, children: selectedLabel || "Select relationship" }),
|
|
1689
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1690
|
+
"svg",
|
|
1691
|
+
{
|
|
1692
|
+
width: "14",
|
|
1693
|
+
height: "14",
|
|
1694
|
+
viewBox: "0 0 24 24",
|
|
1695
|
+
fill: "none",
|
|
1696
|
+
stroke: "#667085",
|
|
1697
|
+
strokeWidth: "2",
|
|
1698
|
+
strokeLinecap: "round",
|
|
1699
|
+
strokeLinejoin: "round",
|
|
1700
|
+
style: {
|
|
1701
|
+
flexShrink: 0,
|
|
1702
|
+
marginLeft: "8px",
|
|
1703
|
+
transform: isDropdownOpen ? "rotate(180deg)" : "rotate(0deg)",
|
|
1704
|
+
transition: "transform 0.2s"
|
|
1705
|
+
},
|
|
1706
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("polyline", { points: "6 9 12 15 18 9" })
|
|
1707
|
+
}
|
|
1708
|
+
)
|
|
1709
|
+
]
|
|
1331
1710
|
}
|
|
1332
1711
|
),
|
|
1333
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1334
|
-
"
|
|
1712
|
+
isDropdownOpen && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1713
|
+
"div",
|
|
1335
1714
|
{
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1715
|
+
ref: optionsRef,
|
|
1716
|
+
id: "guardianRelationship-listbox",
|
|
1717
|
+
role: "listbox",
|
|
1718
|
+
"aria-labelledby": "guardianRelationship-label",
|
|
1340
1719
|
style: {
|
|
1341
|
-
|
|
1342
|
-
|
|
1720
|
+
position: "absolute",
|
|
1721
|
+
...openUpward ? { bottom: "calc(100% + 4px)" } : { top: "calc(100% + 4px)" },
|
|
1722
|
+
left: 0,
|
|
1723
|
+
right: 0,
|
|
1724
|
+
backgroundColor: bgColor,
|
|
1725
|
+
border: `1px solid ${borderColor}`,
|
|
1726
|
+
borderRadius: radius,
|
|
1727
|
+
boxShadow: openUpward ? "0 -4px 12px rgba(0, 0, 0, 0.1), 0 -1px 3px rgba(0, 0, 0, 0.06)" : "0 4px 12px rgba(0, 0, 0, 0.1), 0 1px 3px rgba(0, 0, 0, 0.06)",
|
|
1728
|
+
zIndex: 50,
|
|
1729
|
+
overflow: "hidden",
|
|
1730
|
+
padding: "4px 0",
|
|
1731
|
+
maxHeight: "220px",
|
|
1732
|
+
overflowY: "auto"
|
|
1343
1733
|
},
|
|
1344
|
-
|
|
1734
|
+
children: RELATIONSHIP_OPTIONS.map((option, index) => {
|
|
1735
|
+
var _a2, _b2;
|
|
1736
|
+
const isSelected = formData.guardianRelationship === option.value;
|
|
1737
|
+
const isFocused = focusedIndex === index;
|
|
1738
|
+
const accentColor = ((_b2 = (_a2 = settings == null ? void 0 : settings.button) == null ? void 0 : _a2.accept) == null ? void 0 : _b2.backgroundColor) || "#3b82f6";
|
|
1739
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
1740
|
+
"div",
|
|
1741
|
+
{
|
|
1742
|
+
id: `guardianRelationship-option-${index}`,
|
|
1743
|
+
role: "option",
|
|
1744
|
+
"aria-selected": isSelected,
|
|
1745
|
+
onClick: () => handleSelect(option.value),
|
|
1746
|
+
onMouseEnter: () => setFocusedIndex(index),
|
|
1747
|
+
style: {
|
|
1748
|
+
padding: "9px 12px",
|
|
1749
|
+
fontSize: "13px",
|
|
1750
|
+
fontFamily: font,
|
|
1751
|
+
color: isSelected ? accentColor : textColor,
|
|
1752
|
+
backgroundColor: isFocused ? "#F3F4F6" : "transparent",
|
|
1753
|
+
cursor: "pointer",
|
|
1754
|
+
display: "flex",
|
|
1755
|
+
alignItems: "center",
|
|
1756
|
+
justifyContent: "space-between",
|
|
1757
|
+
transition: "background-color 0.1s"
|
|
1758
|
+
},
|
|
1759
|
+
children: [
|
|
1760
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: option.label }),
|
|
1761
|
+
isSelected && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1762
|
+
"svg",
|
|
1763
|
+
{
|
|
1764
|
+
width: "14",
|
|
1765
|
+
height: "14",
|
|
1766
|
+
viewBox: "0 0 24 24",
|
|
1767
|
+
fill: "none",
|
|
1768
|
+
stroke: accentColor,
|
|
1769
|
+
strokeWidth: "2.5",
|
|
1770
|
+
strokeLinecap: "round",
|
|
1771
|
+
strokeLinejoin: "round",
|
|
1772
|
+
style: { flexShrink: 0 },
|
|
1773
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("polyline", { points: "20 6 9 17 4 12" })
|
|
1774
|
+
}
|
|
1775
|
+
)
|
|
1776
|
+
]
|
|
1777
|
+
},
|
|
1778
|
+
option.value
|
|
1779
|
+
);
|
|
1780
|
+
})
|
|
1345
1781
|
}
|
|
1346
1782
|
),
|
|
1347
|
-
errors.guardianRelationship && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: errorStyle, children: errors.guardianRelationship })
|
|
1783
|
+
errors.guardianRelationship && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: errorStyle, role: "alert", children: errors.guardianRelationship })
|
|
1348
1784
|
] })
|
|
1349
1785
|
]
|
|
1350
1786
|
}
|
|
@@ -1355,7 +1791,7 @@ var GuardianForm = ({
|
|
|
1355
1791
|
role: "alert",
|
|
1356
1792
|
style: {
|
|
1357
1793
|
color: "#DC2626",
|
|
1358
|
-
fontSize: "
|
|
1794
|
+
fontSize: "13px",
|
|
1359
1795
|
marginTop: "16px",
|
|
1360
1796
|
padding: "12px",
|
|
1361
1797
|
borderRadius: "6px",
|
|
@@ -1391,8 +1827,8 @@ var GuardianForm = ({
|
|
|
1391
1827
|
onClick: onNext,
|
|
1392
1828
|
disabled: isSubmitting,
|
|
1393
1829
|
type: "button",
|
|
1394
|
-
"aria-label": isSubmitting ? "
|
|
1395
|
-
children: isSubmitting ? "
|
|
1830
|
+
"aria-label": isSubmitting ? "Verifying guardian identity" : "Proceed to guardian verification",
|
|
1831
|
+
children: isSubmitting ? "Verifying..." : "Verify via DigiLocker"
|
|
1396
1832
|
}
|
|
1397
1833
|
),
|
|
1398
1834
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
@@ -1406,7 +1842,7 @@ var GuardianForm = ({
|
|
|
1406
1842
|
},
|
|
1407
1843
|
onClick: onDecline,
|
|
1408
1844
|
type: "button",
|
|
1409
|
-
"aria-label": "Cancel
|
|
1845
|
+
"aria-label": "Cancel",
|
|
1410
1846
|
children: "Cancel"
|
|
1411
1847
|
}
|
|
1412
1848
|
)
|
|
@@ -1415,6 +1851,266 @@ var GuardianForm = ({
|
|
|
1415
1851
|
)
|
|
1416
1852
|
] });
|
|
1417
1853
|
};
|
|
1854
|
+
var VerificationScreen = ({
|
|
1855
|
+
onBack,
|
|
1856
|
+
onContinue,
|
|
1857
|
+
isInitiating,
|
|
1858
|
+
isPolling,
|
|
1859
|
+
isVerificationComplete,
|
|
1860
|
+
isAutoTransitioning,
|
|
1861
|
+
error,
|
|
1862
|
+
errorCode,
|
|
1863
|
+
canRetry,
|
|
1864
|
+
styles: styles3,
|
|
1865
|
+
responsiveStyles,
|
|
1866
|
+
settings,
|
|
1867
|
+
componentHeadingStyle,
|
|
1868
|
+
componentTextStyle,
|
|
1869
|
+
acceptButtonStyle,
|
|
1870
|
+
declineButtonStyle,
|
|
1871
|
+
logoUrl
|
|
1872
|
+
}) => {
|
|
1873
|
+
var _a, _b;
|
|
1874
|
+
const errorStyle = {
|
|
1875
|
+
color: "#DC2626",
|
|
1876
|
+
fontSize: "14px",
|
|
1877
|
+
marginTop: "16px",
|
|
1878
|
+
padding: "12px",
|
|
1879
|
+
borderRadius: "6px",
|
|
1880
|
+
border: "1px solid #FCA5A5",
|
|
1881
|
+
backgroundColor: "#FEF2F2",
|
|
1882
|
+
textAlign: "center"
|
|
1883
|
+
};
|
|
1884
|
+
const statusStyle = {
|
|
1885
|
+
color: "#059669",
|
|
1886
|
+
fontSize: "14px",
|
|
1887
|
+
marginTop: "16px",
|
|
1888
|
+
padding: "12px",
|
|
1889
|
+
borderRadius: "6px",
|
|
1890
|
+
border: "1px solid #A7F3D0",
|
|
1891
|
+
backgroundColor: "#D1FAE5",
|
|
1892
|
+
textAlign: "center"
|
|
1893
|
+
};
|
|
1894
|
+
const spinnerStyle = {
|
|
1895
|
+
width: "48px",
|
|
1896
|
+
height: "48px",
|
|
1897
|
+
border: "4px solid #e5e7eb",
|
|
1898
|
+
borderTopColor: ((_b = (_a = settings == null ? void 0 : settings.button) == null ? void 0 : _a.accept) == null ? void 0 : _b.backgroundColor) || "#3b82f6",
|
|
1899
|
+
borderRadius: "50%",
|
|
1900
|
+
animation: "spin 1s linear infinite",
|
|
1901
|
+
margin: "24px auto"
|
|
1902
|
+
};
|
|
1903
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
1904
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { ...styles3.topSection, ...componentTextStyle }, children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: styles3.topLeft, children: [
|
|
1905
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("img", { style: styles3.logo, src: logoUrl, alt: "Logo" }),
|
|
1906
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1907
|
+
"h2",
|
|
1908
|
+
{
|
|
1909
|
+
id: "verification-title",
|
|
1910
|
+
style: {
|
|
1911
|
+
...styles3.title,
|
|
1912
|
+
...responsiveStyles.title,
|
|
1913
|
+
...componentHeadingStyle,
|
|
1914
|
+
fontSize: "16px",
|
|
1915
|
+
fontWeight: 600
|
|
1916
|
+
},
|
|
1917
|
+
children: "Guardian Verification"
|
|
1918
|
+
}
|
|
1919
|
+
)
|
|
1920
|
+
] }) }),
|
|
1921
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
1922
|
+
"div",
|
|
1923
|
+
{
|
|
1924
|
+
style: {
|
|
1925
|
+
...styles3.middleSection,
|
|
1926
|
+
...responsiveStyles.middleSection,
|
|
1927
|
+
...componentTextStyle,
|
|
1928
|
+
textAlign: "center"
|
|
1929
|
+
},
|
|
1930
|
+
children: [
|
|
1931
|
+
isVerificationComplete && !error ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
1932
|
+
"div",
|
|
1933
|
+
{
|
|
1934
|
+
style: {
|
|
1935
|
+
display: "flex",
|
|
1936
|
+
flexDirection: "column",
|
|
1937
|
+
alignItems: "center",
|
|
1938
|
+
justifyContent: "center",
|
|
1939
|
+
flex: 1
|
|
1940
|
+
},
|
|
1941
|
+
children: [
|
|
1942
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1943
|
+
"div",
|
|
1944
|
+
{
|
|
1945
|
+
style: {
|
|
1946
|
+
width: "64px",
|
|
1947
|
+
height: "64px",
|
|
1948
|
+
borderRadius: "50%",
|
|
1949
|
+
backgroundColor: "#D1FAE5",
|
|
1950
|
+
display: "flex",
|
|
1951
|
+
alignItems: "center",
|
|
1952
|
+
justifyContent: "center"
|
|
1953
|
+
},
|
|
1954
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1955
|
+
"svg",
|
|
1956
|
+
{
|
|
1957
|
+
width: "32",
|
|
1958
|
+
height: "32",
|
|
1959
|
+
viewBox: "0 0 24 24",
|
|
1960
|
+
fill: "none",
|
|
1961
|
+
stroke: "#059669",
|
|
1962
|
+
strokeWidth: "2",
|
|
1963
|
+
strokeLinecap: "round",
|
|
1964
|
+
strokeLinejoin: "round",
|
|
1965
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("polyline", { points: "20 6 9 17 4 12" })
|
|
1966
|
+
}
|
|
1967
|
+
)
|
|
1968
|
+
}
|
|
1969
|
+
),
|
|
1970
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1971
|
+
"p",
|
|
1972
|
+
{
|
|
1973
|
+
style: {
|
|
1974
|
+
...componentHeadingStyle,
|
|
1975
|
+
fontSize: "16px",
|
|
1976
|
+
fontWeight: 600,
|
|
1977
|
+
lineHeight: "1.5",
|
|
1978
|
+
marginTop: "12px",
|
|
1979
|
+
marginBottom: "24px"
|
|
1980
|
+
},
|
|
1981
|
+
children: "Verification Completed"
|
|
1982
|
+
}
|
|
1983
|
+
)
|
|
1984
|
+
]
|
|
1985
|
+
}
|
|
1986
|
+
) : (isInitiating || isPolling) && !error ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
1987
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: spinnerStyle }),
|
|
1988
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: statusStyle, children: isInitiating ? "Opening DigiLocker in a new tab..." : "Please complete the verification in the DigiLocker tab. This page will update automatically when verification is complete." })
|
|
1989
|
+
] }) : null,
|
|
1990
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
1991
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1992
|
+
"div",
|
|
1993
|
+
{
|
|
1994
|
+
style: {
|
|
1995
|
+
width: "64px",
|
|
1996
|
+
height: "64px",
|
|
1997
|
+
borderRadius: "50%",
|
|
1998
|
+
backgroundColor: "#fee2e2",
|
|
1999
|
+
display: "flex",
|
|
2000
|
+
alignItems: "center",
|
|
2001
|
+
justifyContent: "center",
|
|
2002
|
+
margin: "24px auto"
|
|
2003
|
+
},
|
|
2004
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
2005
|
+
"svg",
|
|
2006
|
+
{
|
|
2007
|
+
width: "32",
|
|
2008
|
+
height: "32",
|
|
2009
|
+
viewBox: "0 0 24 24",
|
|
2010
|
+
fill: "none",
|
|
2011
|
+
stroke: "#dc2626",
|
|
2012
|
+
strokeWidth: "2",
|
|
2013
|
+
strokeLinecap: "round",
|
|
2014
|
+
strokeLinejoin: "round",
|
|
2015
|
+
children: [
|
|
2016
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
|
|
2017
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
|
|
2018
|
+
]
|
|
2019
|
+
}
|
|
2020
|
+
)
|
|
2021
|
+
}
|
|
2022
|
+
),
|
|
2023
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
2024
|
+
"p",
|
|
2025
|
+
{
|
|
2026
|
+
style: {
|
|
2027
|
+
...styles3.privacyText,
|
|
2028
|
+
...responsiveStyles.privacyText,
|
|
2029
|
+
...componentTextStyle,
|
|
2030
|
+
fontSize: "14px",
|
|
2031
|
+
lineHeight: "1.5",
|
|
2032
|
+
marginBottom: "12px"
|
|
2033
|
+
},
|
|
2034
|
+
children: "Verification failed"
|
|
2035
|
+
}
|
|
2036
|
+
),
|
|
2037
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: errorStyle, children: error })
|
|
2038
|
+
] })
|
|
2039
|
+
]
|
|
2040
|
+
}
|
|
2041
|
+
),
|
|
2042
|
+
isAutoTransitioning ? null : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
2043
|
+
"div",
|
|
2044
|
+
{
|
|
2045
|
+
style: {
|
|
2046
|
+
...styles3.bottomSection,
|
|
2047
|
+
...responsiveStyles.bottomSection,
|
|
2048
|
+
...componentTextStyle,
|
|
2049
|
+
paddingTop: "12px",
|
|
2050
|
+
display: "flex",
|
|
2051
|
+
gap: "12px",
|
|
2052
|
+
justifyContent: "center"
|
|
2053
|
+
},
|
|
2054
|
+
children: isVerificationComplete && !error ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
2055
|
+
"button",
|
|
2056
|
+
{
|
|
2057
|
+
style: {
|
|
2058
|
+
...styles3.button,
|
|
2059
|
+
...responsiveStyles.button,
|
|
2060
|
+
...acceptButtonStyle
|
|
2061
|
+
},
|
|
2062
|
+
onClick: onContinue,
|
|
2063
|
+
type: "button",
|
|
2064
|
+
"aria-label": "Continue to consent form",
|
|
2065
|
+
children: "Continue"
|
|
2066
|
+
}
|
|
2067
|
+
) : error && canRetry ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
2068
|
+
"button",
|
|
2069
|
+
{
|
|
2070
|
+
style: {
|
|
2071
|
+
...styles3.button,
|
|
2072
|
+
...responsiveStyles.button,
|
|
2073
|
+
...styles3.acceptButton,
|
|
2074
|
+
...acceptButtonStyle
|
|
2075
|
+
},
|
|
2076
|
+
onClick: () => onBack(errorCode === "GUARDIAN_UNDER_18"),
|
|
2077
|
+
type: "button",
|
|
2078
|
+
"aria-label": errorCode === "GUARDIAN_UNDER_18" ? "Change guardian details" : "Try verification again",
|
|
2079
|
+
children: errorCode === "GUARDIAN_UNDER_18" ? "Change Guardian" : "Try Again"
|
|
2080
|
+
}
|
|
2081
|
+
) : error ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
2082
|
+
"button",
|
|
2083
|
+
{
|
|
2084
|
+
style: {
|
|
2085
|
+
...styles3.button,
|
|
2086
|
+
...responsiveStyles.button,
|
|
2087
|
+
...styles3.cancelButton,
|
|
2088
|
+
...declineButtonStyle
|
|
2089
|
+
},
|
|
2090
|
+
onClick: () => onBack(false),
|
|
2091
|
+
type: "button",
|
|
2092
|
+
"aria-label": "Go back",
|
|
2093
|
+
children: "Go Back"
|
|
2094
|
+
}
|
|
2095
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
2096
|
+
"button",
|
|
2097
|
+
{
|
|
2098
|
+
style: {
|
|
2099
|
+
...styles3.button,
|
|
2100
|
+
...responsiveStyles.button,
|
|
2101
|
+
...styles3.cancelButton,
|
|
2102
|
+
...declineButtonStyle
|
|
2103
|
+
},
|
|
2104
|
+
onClick: () => onBack(false),
|
|
2105
|
+
type: "button",
|
|
2106
|
+
"aria-label": "Cancel verification",
|
|
2107
|
+
children: "Cancel"
|
|
2108
|
+
}
|
|
2109
|
+
)
|
|
2110
|
+
}
|
|
2111
|
+
)
|
|
2112
|
+
] });
|
|
2113
|
+
};
|
|
1418
2114
|
var AgeVerification = ({
|
|
1419
2115
|
onYes,
|
|
1420
2116
|
onNo,
|
|
@@ -1577,6 +2273,10 @@ var RedactoNoticeConsent = ({
|
|
|
1577
2273
|
settings,
|
|
1578
2274
|
applicationId,
|
|
1579
2275
|
validateAgainst = "all",
|
|
2276
|
+
digilockerMode = "redirect",
|
|
2277
|
+
// Default to full page redirect (DigiLocker blocks iframe embedding)
|
|
2278
|
+
digilockerCallbackUrl = "/digilocker-callback",
|
|
2279
|
+
// Default callback path
|
|
1580
2280
|
includeFullyConsentedData = false,
|
|
1581
2281
|
reviewModeButtonText = "Continue"
|
|
1582
2282
|
}) => {
|
|
@@ -1632,6 +2332,8 @@ var RedactoNoticeConsent = ({
|
|
|
1632
2332
|
const [currentAudioIndex, setCurrentAudioIndex] = (0, import_react2.useState)(0);
|
|
1633
2333
|
const [highlightedElementId, setHighlightedElementId] = (0, import_react2.useState)(null);
|
|
1634
2334
|
const [showAgeVerification, setShowAgeVerification] = (0, import_react2.useState)(false);
|
|
2335
|
+
const [isMinorFlow, setIsMinorFlow] = (0, import_react2.useState)(false);
|
|
2336
|
+
const [selfDeclaredAdult, setSelfDeclaredAdult] = (0, import_react2.useState)(false);
|
|
1635
2337
|
const [showGuardianForm, setShowGuardianForm] = (0, import_react2.useState)(false);
|
|
1636
2338
|
const [isSubmittingGuardian, setIsSubmittingGuardian] = (0, import_react2.useState)(false);
|
|
1637
2339
|
const [guardianFormData, setGuardianFormData] = (0, import_react2.useState)({
|
|
@@ -1640,12 +2342,32 @@ var RedactoNoticeConsent = ({
|
|
|
1640
2342
|
guardianRelationship: ""
|
|
1641
2343
|
});
|
|
1642
2344
|
const [guardianFormErrors, setGuardianFormErrors] = (0, import_react2.useState)({});
|
|
2345
|
+
const [showVerificationScreen, setShowVerificationScreen] = (0, import_react2.useState)(false);
|
|
2346
|
+
const [verificationReference, setVerificationReference] = (0, import_react2.useState)(null);
|
|
2347
|
+
const [isInitiatingVerification, setIsInitiatingVerification] = (0, import_react2.useState)(false);
|
|
2348
|
+
const [verificationError, setVerificationError] = (0, import_react2.useState)(
|
|
2349
|
+
null
|
|
2350
|
+
);
|
|
2351
|
+
const [verificationErrorCode, setVerificationErrorCode] = (0, import_react2.useState)(null);
|
|
2352
|
+
const [canRetryVerification, setCanRetryVerification] = (0, import_react2.useState)(false);
|
|
2353
|
+
const [isPollingStatus, setIsPollingStatus] = (0, import_react2.useState)(false);
|
|
2354
|
+
const [isVerificationComplete, setIsVerificationComplete] = (0, import_react2.useState)(false);
|
|
2355
|
+
const [isAutoTransitioning, setIsAutoTransitioning] = (0, import_react2.useState)(false);
|
|
1643
2356
|
const modalRef = (0, import_react2.useRef)(null);
|
|
1644
2357
|
const firstFocusableRef = (0, import_react2.useRef)(null);
|
|
1645
2358
|
const lastFocusableRef = (0, import_react2.useRef)(null);
|
|
1646
2359
|
const abortControllerRef = (0, import_react2.useRef)(null);
|
|
1647
2360
|
const isRequestInProgressRef = (0, import_react2.useRef)(false);
|
|
1648
2361
|
const currentAudioRef = (0, import_react2.useRef)(null);
|
|
2362
|
+
const popupCheckIntervalRef = (0, import_react2.useRef)(null);
|
|
2363
|
+
const statusPollIntervalRef = (0, import_react2.useRef)(null);
|
|
2364
|
+
const verificationPopupRef = (0, import_react2.useRef)(null);
|
|
2365
|
+
const pollingCleanupRef = (0, import_react2.useRef)(null);
|
|
2366
|
+
const autoTransitionTimerRef = (0, import_react2.useRef)(null);
|
|
2367
|
+
const digilockerRedirectTimeoutRef = (0, import_react2.useRef)(null);
|
|
2368
|
+
const isInitialMountRef = (0, import_react2.useRef)(true);
|
|
2369
|
+
const isPollingStatusRef = (0, import_react2.useRef)(false);
|
|
2370
|
+
const verificationSessionTokenRef = (0, import_react2.useRef)(null);
|
|
1649
2371
|
const isMobile = useMediaQuery("(max-width: 768px)");
|
|
1650
2372
|
const responsiveStyles = (0, import_react2.useMemo)(
|
|
1651
2373
|
() => ({
|
|
@@ -1753,6 +2475,7 @@ var RedactoNoticeConsent = ({
|
|
|
1753
2475
|
}, [content, selectedDataElements]);
|
|
1754
2476
|
const acceptDisabled = isSubmitting || !areAllRequiredElementsChecked;
|
|
1755
2477
|
(0, import_react2.useEffect)(() => {
|
|
2478
|
+
var _a2, _b2;
|
|
1756
2479
|
clearApiCache();
|
|
1757
2480
|
isRequestInProgressRef.current = false;
|
|
1758
2481
|
setContent(null);
|
|
@@ -1768,6 +2491,8 @@ var RedactoNoticeConsent = ({
|
|
|
1768
2491
|
setIsSubmittingAccept(false);
|
|
1769
2492
|
setIsSubmittingDecline(false);
|
|
1770
2493
|
setShowAgeVerification(false);
|
|
2494
|
+
setIsMinorFlow(false);
|
|
2495
|
+
setSelfDeclaredAdult(false);
|
|
1771
2496
|
setShowGuardianForm(false);
|
|
1772
2497
|
setIsSubmittingGuardian(false);
|
|
1773
2498
|
setGuardianFormData({
|
|
@@ -1776,6 +2501,41 @@ var RedactoNoticeConsent = ({
|
|
|
1776
2501
|
guardianRelationship: ""
|
|
1777
2502
|
});
|
|
1778
2503
|
setGuardianFormErrors({});
|
|
2504
|
+
setShowVerificationScreen(false);
|
|
2505
|
+
setVerificationReference(null);
|
|
2506
|
+
setIsInitiatingVerification(false);
|
|
2507
|
+
setVerificationError(null);
|
|
2508
|
+
setVerificationErrorCode(null);
|
|
2509
|
+
setCanRetryVerification(false);
|
|
2510
|
+
setIsVerificationComplete(false);
|
|
2511
|
+
setIsAutoTransitioning(false);
|
|
2512
|
+
setIsPollingStatus(false);
|
|
2513
|
+
isPollingStatusRef.current = false;
|
|
2514
|
+
verificationSessionTokenRef.current = null;
|
|
2515
|
+
if (popupCheckIntervalRef.current) {
|
|
2516
|
+
clearInterval(popupCheckIntervalRef.current);
|
|
2517
|
+
popupCheckIntervalRef.current = null;
|
|
2518
|
+
}
|
|
2519
|
+
if (statusPollIntervalRef.current) {
|
|
2520
|
+
clearTimeout(statusPollIntervalRef.current);
|
|
2521
|
+
statusPollIntervalRef.current = null;
|
|
2522
|
+
}
|
|
2523
|
+
(_a2 = pollingCleanupRef.current) == null ? void 0 : _a2.call(pollingCleanupRef);
|
|
2524
|
+
pollingCleanupRef.current = null;
|
|
2525
|
+
(_b2 = verificationPopupRef.current) == null ? void 0 : _b2.close();
|
|
2526
|
+
verificationPopupRef.current = null;
|
|
2527
|
+
if (autoTransitionTimerRef.current) {
|
|
2528
|
+
clearTimeout(autoTransitionTimerRef.current);
|
|
2529
|
+
autoTransitionTimerRef.current = null;
|
|
2530
|
+
}
|
|
2531
|
+
if (digilockerRedirectTimeoutRef.current) {
|
|
2532
|
+
clearTimeout(digilockerRedirectTimeoutRef.current);
|
|
2533
|
+
digilockerRedirectTimeoutRef.current = null;
|
|
2534
|
+
}
|
|
2535
|
+
if (!isInitialMountRef.current) {
|
|
2536
|
+
clearConsentState();
|
|
2537
|
+
}
|
|
2538
|
+
isInitialMountRef.current = false;
|
|
1779
2539
|
}, [accessToken]);
|
|
1780
2540
|
(0, import_react2.useEffect)(() => {
|
|
1781
2541
|
if (hasAlreadyConsented) {
|
|
@@ -1984,7 +2744,11 @@ var RedactoNoticeConsent = ({
|
|
|
1984
2744
|
setInitialDataElementSelections({});
|
|
1985
2745
|
}
|
|
1986
2746
|
if (consentContentData.detail.is_minor) {
|
|
1987
|
-
|
|
2747
|
+
setIsMinorFlow(true);
|
|
2748
|
+
const persistedState = getConsentState();
|
|
2749
|
+
if (!(persistedState == null ? void 0 : persistedState.sessionToken) && !(persistedState == null ? void 0 : persistedState.verificationReference)) {
|
|
2750
|
+
setShowAgeVerification(true);
|
|
2751
|
+
}
|
|
1988
2752
|
}
|
|
1989
2753
|
setIsLoading(false);
|
|
1990
2754
|
} catch (err) {
|
|
@@ -2083,6 +2847,10 @@ var RedactoNoticeConsent = ({
|
|
|
2083
2847
|
const handleAccept = async () => {
|
|
2084
2848
|
const submitController = new AbortController();
|
|
2085
2849
|
try {
|
|
2850
|
+
if (isMinorFlow && !verificationReference) {
|
|
2851
|
+
setErrorMessage("Guardian verification is required before consent can be submitted.");
|
|
2852
|
+
return;
|
|
2853
|
+
}
|
|
2086
2854
|
setIsSubmittingAccept(true);
|
|
2087
2855
|
setIsSubmitting(true);
|
|
2088
2856
|
setErrorMessage(null);
|
|
@@ -2117,7 +2885,10 @@ var RedactoNoticeConsent = ({
|
|
|
2117
2885
|
};
|
|
2118
2886
|
}),
|
|
2119
2887
|
declined: false,
|
|
2888
|
+
language: toBcp47Code(selectedLanguage),
|
|
2120
2889
|
meta_data: applicationId ? { specific_uuid: applicationId } : void 0,
|
|
2890
|
+
guardianVerificationReference: verificationReference || void 0,
|
|
2891
|
+
selfDeclaredAdult: selfDeclaredAdult || void 0,
|
|
2121
2892
|
signal: submitController.signal
|
|
2122
2893
|
});
|
|
2123
2894
|
}
|
|
@@ -2182,17 +2953,102 @@ var RedactoNoticeConsent = ({
|
|
|
2182
2953
|
try {
|
|
2183
2954
|
setIsSubmittingGuardian(true);
|
|
2184
2955
|
setGuardianFormErrors({});
|
|
2185
|
-
|
|
2956
|
+
setVerificationError(null);
|
|
2957
|
+
const callbackUrl = digilockerMode === "popup" ? new URL(digilockerCallbackUrl, window.location.origin).href : void 0;
|
|
2958
|
+
const response = await initiateGuardianVerification({
|
|
2186
2959
|
accessToken,
|
|
2187
2960
|
baseUrl,
|
|
2188
2961
|
guardianName: guardianFormData.guardianName,
|
|
2189
2962
|
guardianContact: guardianFormData.guardianContact,
|
|
2190
2963
|
guardianRelationship: guardianFormData.guardianRelationship,
|
|
2964
|
+
frontendCallbackUrl: callbackUrl,
|
|
2965
|
+
// Only for popup mode
|
|
2191
2966
|
signal: guardianController.signal
|
|
2192
2967
|
});
|
|
2968
|
+
setIsSubmittingGuardian(false);
|
|
2969
|
+
if (response.already_verified && response.verification_reference) {
|
|
2970
|
+
setVerificationReference(response.verification_reference);
|
|
2971
|
+
setShowGuardianForm(false);
|
|
2972
|
+
setShowVerificationScreen(true);
|
|
2973
|
+
setIsInitiatingVerification(false);
|
|
2974
|
+
setIsVerificationComplete(true);
|
|
2975
|
+
setIsAutoTransitioning(true);
|
|
2976
|
+
autoTransitionTimerRef.current = setTimeout(() => {
|
|
2977
|
+
setShowVerificationScreen(false);
|
|
2978
|
+
setIsVerificationComplete(false);
|
|
2979
|
+
setIsAutoTransitioning(false);
|
|
2980
|
+
autoTransitionTimerRef.current = null;
|
|
2981
|
+
}, 1e3);
|
|
2982
|
+
return;
|
|
2983
|
+
}
|
|
2984
|
+
if (!response.session_token || !response.digilocker_redirect_url) {
|
|
2985
|
+
throw new Error("Invalid response from server: missing required fields");
|
|
2986
|
+
}
|
|
2193
2987
|
setShowGuardianForm(false);
|
|
2988
|
+
setShowVerificationScreen(true);
|
|
2989
|
+
setIsInitiatingVerification(true);
|
|
2990
|
+
if (digilockerMode === "redirect") {
|
|
2991
|
+
saveConsentState({
|
|
2992
|
+
flowState: "digilocker-pending",
|
|
2993
|
+
sessionToken: response.session_token,
|
|
2994
|
+
guardianInfoUuid: response.guardian_info_uuid,
|
|
2995
|
+
selectedPurposes,
|
|
2996
|
+
selectedDataElements,
|
|
2997
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2998
|
+
originalUrl: window.location.href,
|
|
2999
|
+
noticeId,
|
|
3000
|
+
baseUrl
|
|
3001
|
+
});
|
|
3002
|
+
try {
|
|
3003
|
+
const openedWindow = window.open(
|
|
3004
|
+
response.digilocker_redirect_url,
|
|
3005
|
+
"_blank"
|
|
3006
|
+
);
|
|
3007
|
+
if (!openedWindow) {
|
|
3008
|
+
console.warn("Popup blocked \u2014 cannot open DigiLocker in new tab");
|
|
3009
|
+
setIsInitiatingVerification(false);
|
|
3010
|
+
setVerificationError(
|
|
3011
|
+
"Unable to open DigiLocker in a new tab. Please allow popups for this site and try again."
|
|
3012
|
+
);
|
|
3013
|
+
return;
|
|
3014
|
+
}
|
|
3015
|
+
try {
|
|
3016
|
+
openedWindow.opener = null;
|
|
3017
|
+
} catch {
|
|
3018
|
+
}
|
|
3019
|
+
} catch (error) {
|
|
3020
|
+
console.error("Failed to open DigiLocker in new tab:", error);
|
|
3021
|
+
setIsInitiatingVerification(false);
|
|
3022
|
+
setVerificationError(
|
|
3023
|
+
"Unable to open DigiLocker. Please allow popups for this site and try again."
|
|
3024
|
+
);
|
|
3025
|
+
return;
|
|
3026
|
+
}
|
|
3027
|
+
setIsInitiatingVerification(false);
|
|
3028
|
+
setIsPollingStatus(true);
|
|
3029
|
+
isPollingStatusRef.current = true;
|
|
3030
|
+
startStatusPolling(response.session_token);
|
|
3031
|
+
} else {
|
|
3032
|
+
setIsInitiatingVerification(true);
|
|
3033
|
+
const popup = window.open(
|
|
3034
|
+
response.digilocker_redirect_url,
|
|
3035
|
+
"digilocker_verification",
|
|
3036
|
+
"width=600,height=700,scrollbars=yes,resizable=yes"
|
|
3037
|
+
);
|
|
3038
|
+
if (popup) {
|
|
3039
|
+
verificationPopupRef.current = popup;
|
|
3040
|
+
startPopupMonitoring(popup);
|
|
3041
|
+
startStatusPolling(response.session_token);
|
|
3042
|
+
} else {
|
|
3043
|
+
setIsInitiatingVerification(false);
|
|
3044
|
+
setVerificationError(
|
|
3045
|
+
"Popup blocked. Please allow popups for this site or use redirect mode."
|
|
3046
|
+
);
|
|
3047
|
+
}
|
|
3048
|
+
}
|
|
2194
3049
|
} catch (error) {
|
|
2195
3050
|
const err = error;
|
|
3051
|
+
setIsInitiatingVerification(false);
|
|
2196
3052
|
if (err.status === 422) {
|
|
2197
3053
|
if (err.message.includes("guardian_contact")) {
|
|
2198
3054
|
setGuardianFormErrors({ guardianContact: err.message });
|
|
@@ -2203,23 +3059,265 @@ var RedactoNoticeConsent = ({
|
|
|
2203
3059
|
} else {
|
|
2204
3060
|
setGuardianFormErrors({ general: err.message });
|
|
2205
3061
|
}
|
|
3062
|
+
setShowVerificationScreen(false);
|
|
3063
|
+
setShowGuardianForm(true);
|
|
2206
3064
|
} else {
|
|
2207
3065
|
setGuardianFormErrors({
|
|
2208
|
-
general: err.message || "Failed to
|
|
3066
|
+
general: err.message || "Failed to initiate verification. Please try again."
|
|
2209
3067
|
});
|
|
3068
|
+
setShowVerificationScreen(false);
|
|
3069
|
+
setShowGuardianForm(true);
|
|
2210
3070
|
onError == null ? void 0 : onError(err);
|
|
2211
3071
|
}
|
|
2212
3072
|
} finally {
|
|
2213
3073
|
setIsSubmittingGuardian(false);
|
|
2214
3074
|
}
|
|
2215
|
-
}, [accessToken, baseUrl, guardianFormData, onError]);
|
|
3075
|
+
}, [accessToken, baseUrl, guardianFormData, digilockerMode, digilockerCallbackUrl, selectedPurposes, selectedDataElements, noticeId, onError]);
|
|
2216
3076
|
const handleAgeVerificationYes = (0, import_react2.useCallback)(() => {
|
|
2217
3077
|
setShowAgeVerification(false);
|
|
3078
|
+
setIsMinorFlow(false);
|
|
3079
|
+
setSelfDeclaredAdult(true);
|
|
2218
3080
|
}, []);
|
|
2219
3081
|
const handleAgeVerificationNo = (0, import_react2.useCallback)(() => {
|
|
2220
3082
|
setShowAgeVerification(false);
|
|
2221
3083
|
setShowGuardianForm(true);
|
|
2222
3084
|
}, []);
|
|
3085
|
+
const handleVerificationContinue = (0, import_react2.useCallback)(() => {
|
|
3086
|
+
setShowVerificationScreen(false);
|
|
3087
|
+
setIsVerificationComplete(false);
|
|
3088
|
+
}, []);
|
|
3089
|
+
const handlePopupClosed = (0, import_react2.useCallback)(async () => {
|
|
3090
|
+
var _a2, _b2;
|
|
3091
|
+
if (popupCheckIntervalRef.current) {
|
|
3092
|
+
clearInterval(popupCheckIntervalRef.current);
|
|
3093
|
+
popupCheckIntervalRef.current = null;
|
|
3094
|
+
}
|
|
3095
|
+
if (statusPollIntervalRef.current) {
|
|
3096
|
+
clearTimeout(statusPollIntervalRef.current);
|
|
3097
|
+
statusPollIntervalRef.current = null;
|
|
3098
|
+
}
|
|
3099
|
+
(_a2 = pollingCleanupRef.current) == null ? void 0 : _a2.call(pollingCleanupRef);
|
|
3100
|
+
pollingCleanupRef.current = null;
|
|
3101
|
+
verificationPopupRef.current = null;
|
|
3102
|
+
if (!isPollingStatusRef.current) return;
|
|
3103
|
+
const sessionToken = verificationSessionTokenRef.current;
|
|
3104
|
+
if (sessionToken) {
|
|
3105
|
+
try {
|
|
3106
|
+
const response = await verifyGuardianStatus({
|
|
3107
|
+
accessToken,
|
|
3108
|
+
baseUrl,
|
|
3109
|
+
sessionToken
|
|
3110
|
+
});
|
|
3111
|
+
if (response.status === "verified") {
|
|
3112
|
+
const ref = response.verification_reference || ((_b2 = response.guardian_details) == null ? void 0 : _b2.verification_reference);
|
|
3113
|
+
if (ref) {
|
|
3114
|
+
setVerificationReference(ref);
|
|
3115
|
+
setIsVerificationComplete(true);
|
|
3116
|
+
setIsPollingStatus(false);
|
|
3117
|
+
isPollingStatusRef.current = false;
|
|
3118
|
+
setIsInitiatingVerification(false);
|
|
3119
|
+
clearConsentState();
|
|
3120
|
+
return;
|
|
3121
|
+
}
|
|
3122
|
+
}
|
|
3123
|
+
} catch {
|
|
3124
|
+
}
|
|
3125
|
+
}
|
|
3126
|
+
setVerificationError(
|
|
3127
|
+
"Verification window was closed. Please try again."
|
|
3128
|
+
);
|
|
3129
|
+
setIsPollingStatus(false);
|
|
3130
|
+
isPollingStatusRef.current = false;
|
|
3131
|
+
setIsInitiatingVerification(false);
|
|
3132
|
+
}, [accessToken, baseUrl]);
|
|
3133
|
+
const startPopupMonitoring = (0, import_react2.useCallback)((popup) => {
|
|
3134
|
+
popupCheckIntervalRef.current = window.setInterval(() => {
|
|
3135
|
+
if (popup.closed) {
|
|
3136
|
+
handlePopupClosed();
|
|
3137
|
+
}
|
|
3138
|
+
}, 500);
|
|
3139
|
+
}, [handlePopupClosed]);
|
|
3140
|
+
const getVerificationErrorMessage = (0, import_react2.useCallback)(
|
|
3141
|
+
(errorCode, fallbackError) => {
|
|
3142
|
+
switch (errorCode) {
|
|
3143
|
+
case "GUARDIAN_UNDER_18":
|
|
3144
|
+
return "The guardian must be 18 years or older. Please provide details of a different guardian.";
|
|
3145
|
+
case "TOKEN_FAILED":
|
|
3146
|
+
return "DigiLocker verification could not be completed. Please try again.";
|
|
3147
|
+
case "DIGILOCKER_AUTH_FAILED":
|
|
3148
|
+
return "DigiLocker authorization was cancelled or failed. Please try again.";
|
|
3149
|
+
case "NO_AUTH_CODE":
|
|
3150
|
+
return "DigiLocker did not return an authorization code. Please try again.";
|
|
3151
|
+
case "SESSION_EXPIRED":
|
|
3152
|
+
return "Verification session has expired. Please try again.";
|
|
3153
|
+
default:
|
|
3154
|
+
return fallbackError || "Verification failed. Please try again.";
|
|
3155
|
+
}
|
|
3156
|
+
},
|
|
3157
|
+
[]
|
|
3158
|
+
);
|
|
3159
|
+
const startStatusPolling = (0, import_react2.useCallback)(
|
|
3160
|
+
(token) => {
|
|
3161
|
+
verificationSessionTokenRef.current = token;
|
|
3162
|
+
setIsPollingStatus(true);
|
|
3163
|
+
isPollingStatusRef.current = true;
|
|
3164
|
+
setVerificationError(null);
|
|
3165
|
+
setVerificationErrorCode(null);
|
|
3166
|
+
setCanRetryVerification(false);
|
|
3167
|
+
let attempts = 0;
|
|
3168
|
+
let consecutiveErrors = 0;
|
|
3169
|
+
let paused = false;
|
|
3170
|
+
const MAX_ATTEMPTS = 40;
|
|
3171
|
+
const MAX_CONSECUTIVE_ERRORS = 3;
|
|
3172
|
+
const POLL_INTERVAL = 3e3;
|
|
3173
|
+
const stopPolling = () => {
|
|
3174
|
+
var _a2;
|
|
3175
|
+
if (statusPollIntervalRef.current) {
|
|
3176
|
+
clearTimeout(statusPollIntervalRef.current);
|
|
3177
|
+
statusPollIntervalRef.current = null;
|
|
3178
|
+
}
|
|
3179
|
+
if (popupCheckIntervalRef.current) {
|
|
3180
|
+
clearInterval(popupCheckIntervalRef.current);
|
|
3181
|
+
popupCheckIntervalRef.current = null;
|
|
3182
|
+
}
|
|
3183
|
+
(_a2 = verificationPopupRef.current) == null ? void 0 : _a2.close();
|
|
3184
|
+
verificationPopupRef.current = null;
|
|
3185
|
+
document.removeEventListener("visibilitychange", onVisibilityChange);
|
|
3186
|
+
pollingCleanupRef.current = null;
|
|
3187
|
+
setIsPollingStatus(false);
|
|
3188
|
+
isPollingStatusRef.current = false;
|
|
3189
|
+
setIsInitiatingVerification(false);
|
|
3190
|
+
};
|
|
3191
|
+
const setError = (message, errorCode, canRetry) => {
|
|
3192
|
+
stopPolling();
|
|
3193
|
+
setVerificationError(message);
|
|
3194
|
+
setVerificationErrorCode(errorCode);
|
|
3195
|
+
setCanRetryVerification(canRetry);
|
|
3196
|
+
};
|
|
3197
|
+
const poll = async () => {
|
|
3198
|
+
var _a2;
|
|
3199
|
+
if (paused) return;
|
|
3200
|
+
attempts++;
|
|
3201
|
+
if (attempts > MAX_ATTEMPTS) {
|
|
3202
|
+
setError(
|
|
3203
|
+
"Verification is taking longer than expected. Please try again.",
|
|
3204
|
+
"SESSION_EXPIRED",
|
|
3205
|
+
true
|
|
3206
|
+
);
|
|
3207
|
+
return;
|
|
3208
|
+
}
|
|
3209
|
+
try {
|
|
3210
|
+
const response = await verifyGuardianStatus({
|
|
3211
|
+
accessToken,
|
|
3212
|
+
baseUrl,
|
|
3213
|
+
sessionToken: token
|
|
3214
|
+
});
|
|
3215
|
+
consecutiveErrors = 0;
|
|
3216
|
+
if (response.status === "verified") {
|
|
3217
|
+
stopPolling();
|
|
3218
|
+
const ref = response.verification_reference || ((_a2 = response.guardian_details) == null ? void 0 : _a2.verification_reference);
|
|
3219
|
+
if (!ref) {
|
|
3220
|
+
setError(
|
|
3221
|
+
"Verification completed but no reference received. Please try again.",
|
|
3222
|
+
null,
|
|
3223
|
+
true
|
|
3224
|
+
);
|
|
3225
|
+
return;
|
|
3226
|
+
}
|
|
3227
|
+
setVerificationReference(ref);
|
|
3228
|
+
setIsVerificationComplete(true);
|
|
3229
|
+
clearConsentState();
|
|
3230
|
+
return;
|
|
3231
|
+
}
|
|
3232
|
+
if (response.status === "failed" || response.status === "expired") {
|
|
3233
|
+
setError(
|
|
3234
|
+
getVerificationErrorMessage(response.error_code, response.error),
|
|
3235
|
+
response.error_code,
|
|
3236
|
+
response.can_retry
|
|
3237
|
+
);
|
|
3238
|
+
return;
|
|
3239
|
+
}
|
|
3240
|
+
if (!paused) {
|
|
3241
|
+
statusPollIntervalRef.current = window.setTimeout(poll, POLL_INTERVAL);
|
|
3242
|
+
}
|
|
3243
|
+
} catch (error) {
|
|
3244
|
+
const err = error;
|
|
3245
|
+
if (err.status === 404 || err.status === 410) {
|
|
3246
|
+
setError(
|
|
3247
|
+
"Verification session not found or expired. Please try again.",
|
|
3248
|
+
"SESSION_EXPIRED",
|
|
3249
|
+
true
|
|
3250
|
+
);
|
|
3251
|
+
return;
|
|
3252
|
+
}
|
|
3253
|
+
consecutiveErrors++;
|
|
3254
|
+
if (consecutiveErrors >= MAX_CONSECUTIVE_ERRORS) {
|
|
3255
|
+
setError(
|
|
3256
|
+
err.message || "Unable to check verification status. Please try again.",
|
|
3257
|
+
null,
|
|
3258
|
+
true
|
|
3259
|
+
);
|
|
3260
|
+
return;
|
|
3261
|
+
}
|
|
3262
|
+
statusPollIntervalRef.current = window.setTimeout(poll, POLL_INTERVAL);
|
|
3263
|
+
}
|
|
3264
|
+
};
|
|
3265
|
+
const onVisibilityChange = () => {
|
|
3266
|
+
if (document.hidden) {
|
|
3267
|
+
paused = true;
|
|
3268
|
+
if (statusPollIntervalRef.current) {
|
|
3269
|
+
clearTimeout(statusPollIntervalRef.current);
|
|
3270
|
+
statusPollIntervalRef.current = null;
|
|
3271
|
+
}
|
|
3272
|
+
} else {
|
|
3273
|
+
paused = false;
|
|
3274
|
+
poll();
|
|
3275
|
+
}
|
|
3276
|
+
};
|
|
3277
|
+
document.addEventListener("visibilitychange", onVisibilityChange);
|
|
3278
|
+
pollingCleanupRef.current = () => {
|
|
3279
|
+
document.removeEventListener("visibilitychange", onVisibilityChange);
|
|
3280
|
+
};
|
|
3281
|
+
statusPollIntervalRef.current = window.setTimeout(poll, POLL_INTERVAL);
|
|
3282
|
+
},
|
|
3283
|
+
[accessToken, baseUrl, getVerificationErrorMessage]
|
|
3284
|
+
);
|
|
3285
|
+
const handleBackToGuardianForm = (0, import_react2.useCallback)((clearName = false) => {
|
|
3286
|
+
var _a2, _b2;
|
|
3287
|
+
(_a2 = verificationPopupRef.current) == null ? void 0 : _a2.close();
|
|
3288
|
+
verificationPopupRef.current = null;
|
|
3289
|
+
if (popupCheckIntervalRef.current) {
|
|
3290
|
+
clearInterval(popupCheckIntervalRef.current);
|
|
3291
|
+
popupCheckIntervalRef.current = null;
|
|
3292
|
+
}
|
|
3293
|
+
if (statusPollIntervalRef.current) {
|
|
3294
|
+
clearTimeout(statusPollIntervalRef.current);
|
|
3295
|
+
statusPollIntervalRef.current = null;
|
|
3296
|
+
}
|
|
3297
|
+
if (autoTransitionTimerRef.current) {
|
|
3298
|
+
clearTimeout(autoTransitionTimerRef.current);
|
|
3299
|
+
autoTransitionTimerRef.current = null;
|
|
3300
|
+
}
|
|
3301
|
+
if (digilockerRedirectTimeoutRef.current) {
|
|
3302
|
+
clearTimeout(digilockerRedirectTimeoutRef.current);
|
|
3303
|
+
digilockerRedirectTimeoutRef.current = null;
|
|
3304
|
+
}
|
|
3305
|
+
(_b2 = pollingCleanupRef.current) == null ? void 0 : _b2.call(pollingCleanupRef);
|
|
3306
|
+
pollingCleanupRef.current = null;
|
|
3307
|
+
setShowVerificationScreen(false);
|
|
3308
|
+
setShowGuardianForm(true);
|
|
3309
|
+
setVerificationError(null);
|
|
3310
|
+
setVerificationErrorCode(null);
|
|
3311
|
+
setCanRetryVerification(false);
|
|
3312
|
+
setIsInitiatingVerification(false);
|
|
3313
|
+
setIsPollingStatus(false);
|
|
3314
|
+
isPollingStatusRef.current = false;
|
|
3315
|
+
setIsVerificationComplete(false);
|
|
3316
|
+
if (clearName) {
|
|
3317
|
+
setGuardianFormData((prev) => ({ ...prev, guardianName: "" }));
|
|
3318
|
+
}
|
|
3319
|
+
clearConsentState();
|
|
3320
|
+
}, []);
|
|
2223
3321
|
const availableLanguages = (0, import_react2.useMemo)(() => {
|
|
2224
3322
|
if (!content) return [language];
|
|
2225
3323
|
const languages = ["English"];
|
|
@@ -2629,12 +3727,67 @@ var RedactoNoticeConsent = ({
|
|
|
2629
3727
|
}, [content, stopAudio]);
|
|
2630
3728
|
(0, import_react2.useEffect)(() => {
|
|
2631
3729
|
return () => {
|
|
3730
|
+
var _a2, _b2;
|
|
2632
3731
|
if (abortControllerRef.current) {
|
|
2633
3732
|
abortControllerRef.current.abort();
|
|
2634
3733
|
}
|
|
2635
3734
|
stopAudio();
|
|
3735
|
+
if (popupCheckIntervalRef.current) {
|
|
3736
|
+
clearInterval(popupCheckIntervalRef.current);
|
|
3737
|
+
}
|
|
3738
|
+
if (statusPollIntervalRef.current) {
|
|
3739
|
+
clearTimeout(statusPollIntervalRef.current);
|
|
3740
|
+
}
|
|
3741
|
+
(_a2 = pollingCleanupRef.current) == null ? void 0 : _a2.call(pollingCleanupRef);
|
|
3742
|
+
pollingCleanupRef.current = null;
|
|
3743
|
+
(_b2 = verificationPopupRef.current) == null ? void 0 : _b2.close();
|
|
3744
|
+
if (autoTransitionTimerRef.current) {
|
|
3745
|
+
clearTimeout(autoTransitionTimerRef.current);
|
|
3746
|
+
autoTransitionTimerRef.current = null;
|
|
3747
|
+
}
|
|
3748
|
+
if (digilockerRedirectTimeoutRef.current) {
|
|
3749
|
+
clearTimeout(digilockerRedirectTimeoutRef.current);
|
|
3750
|
+
digilockerRedirectTimeoutRef.current = null;
|
|
3751
|
+
}
|
|
2636
3752
|
};
|
|
2637
3753
|
}, [stopAudio]);
|
|
3754
|
+
(0, import_react2.useEffect)(() => {
|
|
3755
|
+
const persistedState = getConsentState();
|
|
3756
|
+
if (!persistedState) return;
|
|
3757
|
+
if (persistedState.noticeId && persistedState.noticeId !== noticeId) {
|
|
3758
|
+
clearConsentState();
|
|
3759
|
+
return;
|
|
3760
|
+
}
|
|
3761
|
+
const REDIRECT_STATE_MAX_AGE_MS = 15 * 60 * 1e3;
|
|
3762
|
+
if (persistedState.timestamp) {
|
|
3763
|
+
const stateAge = Date.now() - new Date(persistedState.timestamp).getTime();
|
|
3764
|
+
if (stateAge > REDIRECT_STATE_MAX_AGE_MS) {
|
|
3765
|
+
clearConsentState();
|
|
3766
|
+
return;
|
|
3767
|
+
}
|
|
3768
|
+
}
|
|
3769
|
+
if (persistedState.flowState === "digilocker-pending" && persistedState.sessionToken) {
|
|
3770
|
+
setShowVerificationScreen(true);
|
|
3771
|
+
setShowGuardianForm(false);
|
|
3772
|
+
setShowAgeVerification(false);
|
|
3773
|
+
startStatusPolling(persistedState.sessionToken);
|
|
3774
|
+
} else if (persistedState.verificationResult === "verified" && persistedState.verificationReference) {
|
|
3775
|
+
setVerificationReference(persistedState.verificationReference);
|
|
3776
|
+
setShowVerificationScreen(true);
|
|
3777
|
+
setIsVerificationComplete(true);
|
|
3778
|
+
setShowGuardianForm(false);
|
|
3779
|
+
setShowAgeVerification(false);
|
|
3780
|
+
clearConsentState();
|
|
3781
|
+
} else if (persistedState.verificationResult === "failed" || persistedState.verificationResult === "expired") {
|
|
3782
|
+
setShowVerificationScreen(true);
|
|
3783
|
+
setShowGuardianForm(false);
|
|
3784
|
+
setShowAgeVerification(false);
|
|
3785
|
+
setVerificationError(
|
|
3786
|
+
persistedState.verificationResult === "expired" ? "Verification session has expired. Please try again." : "Verification failed. Please try again."
|
|
3787
|
+
);
|
|
3788
|
+
clearConsentState();
|
|
3789
|
+
}
|
|
3790
|
+
}, [startStatusPolling, noticeId]);
|
|
2638
3791
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children: hasAlreadyConsented ? null : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
2639
3792
|
blockUI && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
2640
3793
|
"div",
|
|
@@ -2820,6 +3973,27 @@ var RedactoNoticeConsent = ({
|
|
|
2820
3973
|
declineButtonStyle,
|
|
2821
3974
|
logoUrl: (content == null ? void 0 : content.logo_url) || redacto_logo_default
|
|
2822
3975
|
}
|
|
3976
|
+
) }) : showVerificationScreen ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { ...styles.content, ...responsiveStyles.content }, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
3977
|
+
VerificationScreen,
|
|
3978
|
+
{
|
|
3979
|
+
onBack: handleBackToGuardianForm,
|
|
3980
|
+
onContinue: handleVerificationContinue,
|
|
3981
|
+
isInitiating: isInitiatingVerification,
|
|
3982
|
+
isPolling: isPollingStatus,
|
|
3983
|
+
isVerificationComplete,
|
|
3984
|
+
isAutoTransitioning,
|
|
3985
|
+
error: verificationError,
|
|
3986
|
+
errorCode: verificationErrorCode,
|
|
3987
|
+
canRetry: canRetryVerification,
|
|
3988
|
+
styles,
|
|
3989
|
+
responsiveStyles,
|
|
3990
|
+
settings,
|
|
3991
|
+
componentHeadingStyle,
|
|
3992
|
+
componentTextStyle,
|
|
3993
|
+
acceptButtonStyle,
|
|
3994
|
+
declineButtonStyle,
|
|
3995
|
+
logoUrl: (content == null ? void 0 : content.logo_url) || redacto_logo_default
|
|
3996
|
+
}
|
|
2823
3997
|
) }) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { ...styles.content, ...responsiveStyles.content }, children: [
|
|
2824
3998
|
errorMessage && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
2825
3999
|
"div",
|
|
@@ -4423,8 +5597,482 @@ var RedactoConsentInlineComponent = ({
|
|
|
4423
5597
|
};
|
|
4424
5598
|
RedactoConsentInlineComponent.displayName = "RedactoConsentInline";
|
|
4425
5599
|
var RedactoConsentInline = (0, import_react4.memo)(RedactoConsentInlineComponent);
|
|
5600
|
+
|
|
5601
|
+
// src/RedactoNoticeConsent/components/DigiLockerCallback.tsx
|
|
5602
|
+
var import_react5 = require("react");
|
|
5603
|
+
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
5604
|
+
var DigiLockerCallback = ({
|
|
5605
|
+
accessToken: propAccessToken,
|
|
5606
|
+
baseUrl,
|
|
5607
|
+
onSuccess,
|
|
5608
|
+
onError
|
|
5609
|
+
}) => {
|
|
5610
|
+
const [status, setStatus] = (0, import_react5.useState)("processing");
|
|
5611
|
+
const [message, setMessage] = (0, import_react5.useState)("Verifying your guardian...");
|
|
5612
|
+
const [errorDetail, setErrorDetail] = (0, import_react5.useState)(null);
|
|
5613
|
+
const retryTimeoutRef = (0, import_react5.useRef)(null);
|
|
5614
|
+
const redirectTimeoutRef = (0, import_react5.useRef)(null);
|
|
5615
|
+
const isMountedRef = (0, import_react5.useRef)(true);
|
|
5616
|
+
const getErrorMessage = (errorCode) => {
|
|
5617
|
+
switch (errorCode) {
|
|
5618
|
+
case "GUARDIAN_UNDER_18":
|
|
5619
|
+
return "Guardian verification failed: The guardian must be 18 years or older.";
|
|
5620
|
+
case "SESSION_EXPIRED":
|
|
5621
|
+
return "Verification session has expired. Please restart the verification process.";
|
|
5622
|
+
case "TOKEN_FAILED":
|
|
5623
|
+
return "DigiLocker authentication failed. Please try again.";
|
|
5624
|
+
case "DIGILOCKER_AUTH_FAILED":
|
|
5625
|
+
return "DigiLocker authorization was cancelled or failed. Please try again.";
|
|
5626
|
+
case "NO_AUTH_CODE":
|
|
5627
|
+
return "Missing authorization code from DigiLocker. Please try again.";
|
|
5628
|
+
default:
|
|
5629
|
+
return "Verification failed. Please try again.";
|
|
5630
|
+
}
|
|
5631
|
+
};
|
|
5632
|
+
const redirectToOriginalPage = (0, import_react5.useCallback)(
|
|
5633
|
+
(originalUrl, verificationResult, verificationReference) => {
|
|
5634
|
+
updateConsentState({
|
|
5635
|
+
verificationResult,
|
|
5636
|
+
verificationReference,
|
|
5637
|
+
flowState: verificationResult === "verified" ? "consent-form" : "error"
|
|
5638
|
+
});
|
|
5639
|
+
redirectTimeoutRef.current = setTimeout(() => {
|
|
5640
|
+
window.location.href = originalUrl;
|
|
5641
|
+
}, 1500);
|
|
5642
|
+
},
|
|
5643
|
+
[]
|
|
5644
|
+
);
|
|
5645
|
+
const handleCallback = (0, import_react5.useCallback)(async () => {
|
|
5646
|
+
var _a, _b;
|
|
5647
|
+
try {
|
|
5648
|
+
const params = new URLSearchParams(window.location.search);
|
|
5649
|
+
const sessionToken = params.get("session_token");
|
|
5650
|
+
const urlStatus = params.get("status");
|
|
5651
|
+
const verificationReference = params.get("verification_reference");
|
|
5652
|
+
const errorCode = params.get("error_code");
|
|
5653
|
+
const persistedState = getConsentState();
|
|
5654
|
+
const originalUrl = (persistedState == null ? void 0 : persistedState.originalUrl) || "/";
|
|
5655
|
+
const storedBaseUrl = persistedState == null ? void 0 : persistedState.baseUrl;
|
|
5656
|
+
const storedSessionToken = persistedState == null ? void 0 : persistedState.sessionToken;
|
|
5657
|
+
const accessToken = propAccessToken;
|
|
5658
|
+
if (!accessToken) {
|
|
5659
|
+
throw new Error("Access token not provided. Please pass accessToken as a prop.");
|
|
5660
|
+
}
|
|
5661
|
+
const activeSessionToken = sessionToken || storedSessionToken;
|
|
5662
|
+
if (!activeSessionToken) {
|
|
5663
|
+
throw new Error("Session token not found. Please restart the verification process.");
|
|
5664
|
+
}
|
|
5665
|
+
let isInIframe = false;
|
|
5666
|
+
try {
|
|
5667
|
+
isInIframe = window.self !== window.top;
|
|
5668
|
+
} catch {
|
|
5669
|
+
isInIframe = true;
|
|
5670
|
+
}
|
|
5671
|
+
if (urlStatus === "verified" && verificationReference) {
|
|
5672
|
+
setStatus("success");
|
|
5673
|
+
setMessage("Guardian verified successfully! Redirecting...");
|
|
5674
|
+
onSuccess == null ? void 0 : onSuccess(verificationReference);
|
|
5675
|
+
if (isInIframe && window.parent) {
|
|
5676
|
+
window.parent.postMessage(
|
|
5677
|
+
{
|
|
5678
|
+
type: "DIGILOCKER_VERIFICATION_STATUS",
|
|
5679
|
+
status: "verified",
|
|
5680
|
+
verificationReference
|
|
5681
|
+
},
|
|
5682
|
+
window.location.origin
|
|
5683
|
+
);
|
|
5684
|
+
return;
|
|
5685
|
+
}
|
|
5686
|
+
redirectToOriginalPage(originalUrl, "verified", verificationReference);
|
|
5687
|
+
return;
|
|
5688
|
+
}
|
|
5689
|
+
if (urlStatus === "failed" || urlStatus === "expired") {
|
|
5690
|
+
const urlErrorCode = errorCode != null ? errorCode : void 0;
|
|
5691
|
+
const errorMessage = getErrorMessage(urlErrorCode);
|
|
5692
|
+
setStatus("error");
|
|
5693
|
+
setMessage("Verification failed");
|
|
5694
|
+
setErrorDetail(errorMessage);
|
|
5695
|
+
onError == null ? void 0 : onError(new Error(errorMessage), urlErrorCode);
|
|
5696
|
+
if (isInIframe && window.parent) {
|
|
5697
|
+
window.parent.postMessage(
|
|
5698
|
+
{
|
|
5699
|
+
type: "DIGILOCKER_VERIFICATION_STATUS",
|
|
5700
|
+
status: urlStatus,
|
|
5701
|
+
errorCode: urlErrorCode,
|
|
5702
|
+
error: errorMessage
|
|
5703
|
+
},
|
|
5704
|
+
window.location.origin
|
|
5705
|
+
);
|
|
5706
|
+
return;
|
|
5707
|
+
}
|
|
5708
|
+
redirectToOriginalPage(originalUrl, urlStatus);
|
|
5709
|
+
return;
|
|
5710
|
+
}
|
|
5711
|
+
setMessage("Processing verification...");
|
|
5712
|
+
const apiBaseUrl = baseUrl || storedBaseUrl;
|
|
5713
|
+
const response = await verifyGuardianStatus({
|
|
5714
|
+
accessToken,
|
|
5715
|
+
baseUrl: apiBaseUrl,
|
|
5716
|
+
sessionToken: activeSessionToken
|
|
5717
|
+
});
|
|
5718
|
+
if (!isMountedRef.current) return;
|
|
5719
|
+
if (response.status === "verified") {
|
|
5720
|
+
const verificationRef = response.verification_reference || ((_a = response.guardian_details) == null ? void 0 : _a.verification_reference) || void 0;
|
|
5721
|
+
if (!verificationRef) {
|
|
5722
|
+
setStatus("error");
|
|
5723
|
+
setMessage("Verification failed");
|
|
5724
|
+
setErrorDetail("Verification completed but no reference received. Please try again.");
|
|
5725
|
+
onError == null ? void 0 : onError(new Error("Verification completed but no reference received."));
|
|
5726
|
+
redirectToOriginalPage(originalUrl, "failed");
|
|
5727
|
+
return;
|
|
5728
|
+
}
|
|
5729
|
+
setStatus("success");
|
|
5730
|
+
setMessage("Guardian verified successfully! Redirecting...");
|
|
5731
|
+
onSuccess == null ? void 0 : onSuccess(verificationRef);
|
|
5732
|
+
if (isInIframe && window.parent) {
|
|
5733
|
+
window.parent.postMessage(
|
|
5734
|
+
{
|
|
5735
|
+
type: "DIGILOCKER_VERIFICATION_STATUS",
|
|
5736
|
+
status: "verified",
|
|
5737
|
+
verificationReference: verificationRef
|
|
5738
|
+
},
|
|
5739
|
+
window.location.origin
|
|
5740
|
+
);
|
|
5741
|
+
return;
|
|
5742
|
+
}
|
|
5743
|
+
redirectToOriginalPage(originalUrl, "verified", verificationRef);
|
|
5744
|
+
} else if (response.status === "failed" || response.status === "expired") {
|
|
5745
|
+
const responseErrorCode = (_b = response.error_code) != null ? _b : void 0;
|
|
5746
|
+
const errorMessage = response.error || getErrorMessage(responseErrorCode);
|
|
5747
|
+
setStatus("error");
|
|
5748
|
+
setMessage("Verification failed");
|
|
5749
|
+
setErrorDetail(errorMessage);
|
|
5750
|
+
onError == null ? void 0 : onError(new Error(errorMessage), responseErrorCode);
|
|
5751
|
+
if (isInIframe && window.parent) {
|
|
5752
|
+
window.parent.postMessage(
|
|
5753
|
+
{
|
|
5754
|
+
type: "DIGILOCKER_VERIFICATION_STATUS",
|
|
5755
|
+
status: response.status,
|
|
5756
|
+
errorCode: responseErrorCode,
|
|
5757
|
+
error: errorMessage
|
|
5758
|
+
},
|
|
5759
|
+
window.location.origin
|
|
5760
|
+
);
|
|
5761
|
+
return;
|
|
5762
|
+
}
|
|
5763
|
+
redirectToOriginalPage(originalUrl, response.status);
|
|
5764
|
+
} else {
|
|
5765
|
+
setMessage("Verification is still in progress. Please wait...");
|
|
5766
|
+
const MAX_RETRIES = 3;
|
|
5767
|
+
let retryCount = 0;
|
|
5768
|
+
const attemptRetry = () => {
|
|
5769
|
+
retryCount++;
|
|
5770
|
+
const delay = 3e3 * Math.pow(2, retryCount - 1);
|
|
5771
|
+
retryTimeoutRef.current = setTimeout(async () => {
|
|
5772
|
+
var _a2, _b2;
|
|
5773
|
+
if (!isMountedRef.current) return;
|
|
5774
|
+
try {
|
|
5775
|
+
const retryResponse = await verifyGuardianStatus({
|
|
5776
|
+
accessToken,
|
|
5777
|
+
baseUrl: apiBaseUrl,
|
|
5778
|
+
sessionToken: activeSessionToken
|
|
5779
|
+
});
|
|
5780
|
+
if (!isMountedRef.current) return;
|
|
5781
|
+
const retryRef = retryResponse.verification_reference || ((_a2 = retryResponse.guardian_details) == null ? void 0 : _a2.verification_reference) || void 0;
|
|
5782
|
+
if (retryResponse.status === "verified" && retryRef) {
|
|
5783
|
+
setStatus("success");
|
|
5784
|
+
setMessage("Guardian verified successfully! Redirecting...");
|
|
5785
|
+
onSuccess == null ? void 0 : onSuccess(retryRef);
|
|
5786
|
+
if (isInIframe && window.parent) {
|
|
5787
|
+
window.parent.postMessage(
|
|
5788
|
+
{
|
|
5789
|
+
type: "DIGILOCKER_VERIFICATION_STATUS",
|
|
5790
|
+
status: "verified",
|
|
5791
|
+
verificationReference: retryRef
|
|
5792
|
+
},
|
|
5793
|
+
window.location.origin
|
|
5794
|
+
);
|
|
5795
|
+
return;
|
|
5796
|
+
}
|
|
5797
|
+
redirectToOriginalPage(originalUrl, "verified", retryRef);
|
|
5798
|
+
} else if (retryResponse.status === "failed" || retryResponse.status === "expired") {
|
|
5799
|
+
const retryErrorCode = (_b2 = retryResponse.error_code) != null ? _b2 : void 0;
|
|
5800
|
+
const retryErrorMessage = retryResponse.error || getErrorMessage(retryErrorCode) || "Verification could not be completed. Please try again.";
|
|
5801
|
+
setStatus("error");
|
|
5802
|
+
setMessage("Verification failed");
|
|
5803
|
+
setErrorDetail(retryErrorMessage);
|
|
5804
|
+
onError == null ? void 0 : onError(new Error(retryErrorMessage), retryErrorCode);
|
|
5805
|
+
if (isInIframe && window.parent) {
|
|
5806
|
+
window.parent.postMessage(
|
|
5807
|
+
{
|
|
5808
|
+
type: "DIGILOCKER_VERIFICATION_STATUS",
|
|
5809
|
+
status: retryResponse.status,
|
|
5810
|
+
errorCode: retryErrorCode,
|
|
5811
|
+
error: retryErrorMessage
|
|
5812
|
+
},
|
|
5813
|
+
window.location.origin
|
|
5814
|
+
);
|
|
5815
|
+
return;
|
|
5816
|
+
}
|
|
5817
|
+
redirectToOriginalPage(originalUrl, retryResponse.status);
|
|
5818
|
+
} else if (retryCount < MAX_RETRIES) {
|
|
5819
|
+
setMessage("Verification taking longer than expected. Please wait...");
|
|
5820
|
+
attemptRetry();
|
|
5821
|
+
} else {
|
|
5822
|
+
const timeoutMessage = "Verification could not be completed in time. Please try again.";
|
|
5823
|
+
setStatus("error");
|
|
5824
|
+
setMessage("Verification failed");
|
|
5825
|
+
setErrorDetail(timeoutMessage);
|
|
5826
|
+
onError == null ? void 0 : onError(new Error(timeoutMessage));
|
|
5827
|
+
redirectToOriginalPage(originalUrl, "failed");
|
|
5828
|
+
}
|
|
5829
|
+
} catch (retryErr) {
|
|
5830
|
+
if (!isMountedRef.current) return;
|
|
5831
|
+
if (retryCount < MAX_RETRIES) {
|
|
5832
|
+
attemptRetry();
|
|
5833
|
+
} else {
|
|
5834
|
+
setStatus("error");
|
|
5835
|
+
setMessage("Verification failed");
|
|
5836
|
+
setErrorDetail(retryErr.message);
|
|
5837
|
+
onError == null ? void 0 : onError(retryErr);
|
|
5838
|
+
redirectToOriginalPage(originalUrl, "failed");
|
|
5839
|
+
}
|
|
5840
|
+
}
|
|
5841
|
+
}, delay);
|
|
5842
|
+
};
|
|
5843
|
+
attemptRetry();
|
|
5844
|
+
}
|
|
5845
|
+
} catch (error) {
|
|
5846
|
+
console.error("DigiLocker callback error:", error);
|
|
5847
|
+
setStatus("error");
|
|
5848
|
+
const err = error;
|
|
5849
|
+
setMessage("Verification failed");
|
|
5850
|
+
setErrorDetail(err.message || "An error occurred during verification");
|
|
5851
|
+
onError == null ? void 0 : onError(err);
|
|
5852
|
+
const persistedState = getConsentState();
|
|
5853
|
+
if (persistedState == null ? void 0 : persistedState.originalUrl) {
|
|
5854
|
+
redirectTimeoutRef.current = setTimeout(() => {
|
|
5855
|
+
redirectToOriginalPage(persistedState.originalUrl, "failed");
|
|
5856
|
+
}, 3e3);
|
|
5857
|
+
}
|
|
5858
|
+
}
|
|
5859
|
+
}, [propAccessToken, baseUrl, onSuccess, onError, redirectToOriginalPage]);
|
|
5860
|
+
(0, import_react5.useEffect)(() => {
|
|
5861
|
+
injectCheckboxStyles();
|
|
5862
|
+
handleCallback();
|
|
5863
|
+
return () => {
|
|
5864
|
+
isMountedRef.current = false;
|
|
5865
|
+
if (retryTimeoutRef.current) clearTimeout(retryTimeoutRef.current);
|
|
5866
|
+
if (redirectTimeoutRef.current) clearTimeout(redirectTimeoutRef.current);
|
|
5867
|
+
};
|
|
5868
|
+
}, [handleCallback]);
|
|
5869
|
+
const handleRetry = (0, import_react5.useCallback)(() => {
|
|
5870
|
+
const persistedState = getConsentState();
|
|
5871
|
+
if (persistedState == null ? void 0 : persistedState.originalUrl) {
|
|
5872
|
+
clearConsentState();
|
|
5873
|
+
window.location.href = persistedState.originalUrl;
|
|
5874
|
+
} else {
|
|
5875
|
+
window.location.href = "/";
|
|
5876
|
+
}
|
|
5877
|
+
}, []);
|
|
5878
|
+
const containerStyle = {
|
|
5879
|
+
display: "flex",
|
|
5880
|
+
alignItems: "center",
|
|
5881
|
+
justifyContent: "center",
|
|
5882
|
+
minHeight: "100vh",
|
|
5883
|
+
backgroundColor: "#f8fafc",
|
|
5884
|
+
fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif',
|
|
5885
|
+
padding: "24px",
|
|
5886
|
+
boxSizing: "border-box"
|
|
5887
|
+
};
|
|
5888
|
+
const cardStyle = {
|
|
5889
|
+
backgroundColor: "#ffffff",
|
|
5890
|
+
borderRadius: "16px",
|
|
5891
|
+
boxShadow: "0 1px 3px rgba(0, 0, 0, 0.08), 0 8px 30px rgba(0, 0, 0, 0.06)",
|
|
5892
|
+
padding: "48px 40px 40px",
|
|
5893
|
+
textAlign: "center",
|
|
5894
|
+
maxWidth: "420px",
|
|
5895
|
+
width: "100%"
|
|
5896
|
+
};
|
|
5897
|
+
const spinnerContainerStyle = {
|
|
5898
|
+
width: "72px",
|
|
5899
|
+
height: "72px",
|
|
5900
|
+
margin: "0 auto 28px",
|
|
5901
|
+
position: "relative"
|
|
5902
|
+
};
|
|
5903
|
+
const spinnerStyle = {
|
|
5904
|
+
width: "72px",
|
|
5905
|
+
height: "72px",
|
|
5906
|
+
border: "3px solid #e5e7eb",
|
|
5907
|
+
borderTopColor: "#4f87ff",
|
|
5908
|
+
borderRadius: "50%",
|
|
5909
|
+
animation: "redacto-dl-spin 0.8s linear infinite",
|
|
5910
|
+
boxSizing: "border-box"
|
|
5911
|
+
};
|
|
5912
|
+
const iconContainerStyle = {
|
|
5913
|
+
width: "72px",
|
|
5914
|
+
height: "72px",
|
|
5915
|
+
borderRadius: "50%",
|
|
5916
|
+
display: "flex",
|
|
5917
|
+
alignItems: "center",
|
|
5918
|
+
justifyContent: "center",
|
|
5919
|
+
margin: "0 auto 28px",
|
|
5920
|
+
animation: "redacto-dl-pop 0.4s cubic-bezier(0.34, 1.56, 0.64, 1) forwards",
|
|
5921
|
+
position: "relative"
|
|
5922
|
+
};
|
|
5923
|
+
const successIconStyle = {
|
|
5924
|
+
...iconContainerStyle,
|
|
5925
|
+
backgroundColor: "#d1fae5",
|
|
5926
|
+
color: "#059669"
|
|
5927
|
+
};
|
|
5928
|
+
const errorIconStyle = {
|
|
5929
|
+
...iconContainerStyle,
|
|
5930
|
+
backgroundColor: "#fee2e2",
|
|
5931
|
+
color: "#dc2626"
|
|
5932
|
+
};
|
|
5933
|
+
const titleStyle = {
|
|
5934
|
+
fontSize: "22px",
|
|
5935
|
+
fontWeight: 700,
|
|
5936
|
+
color: "#111827",
|
|
5937
|
+
margin: "0 0 8px 0",
|
|
5938
|
+
letterSpacing: "-0.01em"
|
|
5939
|
+
};
|
|
5940
|
+
const messageStyle = {
|
|
5941
|
+
fontSize: "14px",
|
|
5942
|
+
color: "#6b7280",
|
|
5943
|
+
marginBottom: "0",
|
|
5944
|
+
lineHeight: 1.6
|
|
5945
|
+
};
|
|
5946
|
+
const subtextStyle = {
|
|
5947
|
+
fontSize: "13px",
|
|
5948
|
+
color: "#9ca3af",
|
|
5949
|
+
marginTop: "16px",
|
|
5950
|
+
lineHeight: 1.5
|
|
5951
|
+
};
|
|
5952
|
+
const errorDetailStyle = {
|
|
5953
|
+
fontSize: "13px",
|
|
5954
|
+
color: "#dc2626",
|
|
5955
|
+
marginTop: "16px",
|
|
5956
|
+
padding: "12px 16px",
|
|
5957
|
+
backgroundColor: "#fef2f2",
|
|
5958
|
+
borderRadius: "10px",
|
|
5959
|
+
border: "1px solid #fecaca",
|
|
5960
|
+
lineHeight: 1.5,
|
|
5961
|
+
textAlign: "left"
|
|
5962
|
+
};
|
|
5963
|
+
const buttonStyle = {
|
|
5964
|
+
marginTop: "24px",
|
|
5965
|
+
padding: "12px 28px",
|
|
5966
|
+
backgroundColor: "#4f87ff",
|
|
5967
|
+
color: "#ffffff",
|
|
5968
|
+
border: "none",
|
|
5969
|
+
borderRadius: "10px",
|
|
5970
|
+
fontSize: "15px",
|
|
5971
|
+
fontWeight: 600,
|
|
5972
|
+
cursor: "pointer",
|
|
5973
|
+
transition: "background-color 0.2s, transform 0.15s",
|
|
5974
|
+
width: "100%"
|
|
5975
|
+
};
|
|
5976
|
+
const keyframesStyle = `
|
|
5977
|
+
@keyframes redacto-dl-spin {
|
|
5978
|
+
to { transform: rotate(360deg); }
|
|
5979
|
+
}
|
|
5980
|
+
@keyframes redacto-dl-pop {
|
|
5981
|
+
0% { transform: scale(0.3); opacity: 0; }
|
|
5982
|
+
60% { transform: scale(1.08); opacity: 1; }
|
|
5983
|
+
100% { transform: scale(1); opacity: 1; }
|
|
5984
|
+
}
|
|
5985
|
+
@keyframes redacto-dl-check {
|
|
5986
|
+
0% { stroke-dashoffset: 24; }
|
|
5987
|
+
100% { stroke-dashoffset: 0; }
|
|
5988
|
+
}
|
|
5989
|
+
@keyframes redacto-dl-pulse {
|
|
5990
|
+
0%, 100% { transform: scale(1); opacity: 0.6; }
|
|
5991
|
+
50% { transform: scale(1.15); opacity: 0; }
|
|
5992
|
+
}
|
|
5993
|
+
.redacto-dl-retry-btn:hover {
|
|
5994
|
+
background-color: #3d6fdb !important;
|
|
5995
|
+
transform: translateY(-1px);
|
|
5996
|
+
}
|
|
5997
|
+
.redacto-dl-retry-btn:active {
|
|
5998
|
+
transform: translateY(0);
|
|
5999
|
+
}
|
|
6000
|
+
`;
|
|
6001
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
|
|
6002
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("style", { dangerouslySetInnerHTML: { __html: keyframesStyle } }),
|
|
6003
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: containerStyle, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: cardStyle, children: [
|
|
6004
|
+
status === "processing" && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
|
|
6005
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: spinnerContainerStyle, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: spinnerStyle }) }),
|
|
6006
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h2", { style: titleStyle, children: "Processing Verification" }),
|
|
6007
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { style: messageStyle, children: message }),
|
|
6008
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { style: subtextStyle, children: "Please wait while we verify your guardian's identity..." })
|
|
6009
|
+
] }),
|
|
6010
|
+
status === "success" && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
|
|
6011
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: { position: "relative", width: "72px", height: "72px", margin: "0 auto 28px" }, children: [
|
|
6012
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: {
|
|
6013
|
+
position: "absolute",
|
|
6014
|
+
inset: "-8px",
|
|
6015
|
+
borderRadius: "50%",
|
|
6016
|
+
border: "2px solid #d1fae5",
|
|
6017
|
+
animation: "redacto-dl-pulse 1.5s ease-out infinite"
|
|
6018
|
+
} }),
|
|
6019
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: successIconStyle, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
6020
|
+
"svg",
|
|
6021
|
+
{
|
|
6022
|
+
width: "30",
|
|
6023
|
+
height: "30",
|
|
6024
|
+
viewBox: "0 0 24 24",
|
|
6025
|
+
fill: "none",
|
|
6026
|
+
stroke: "currentColor",
|
|
6027
|
+
strokeWidth: "2.5",
|
|
6028
|
+
strokeLinecap: "round",
|
|
6029
|
+
strokeLinejoin: "round",
|
|
6030
|
+
style: { strokeDasharray: 24, animation: "redacto-dl-check 0.4s ease-out 0.3s forwards", strokeDashoffset: 24 },
|
|
6031
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("polyline", { points: "20 6 9 17 4 12" })
|
|
6032
|
+
}
|
|
6033
|
+
) })
|
|
6034
|
+
] }),
|
|
6035
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h2", { style: titleStyle, children: "Verification Successful" }),
|
|
6036
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { style: messageStyle, children: message }),
|
|
6037
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { style: subtextStyle, children: "You will be redirected automatically." })
|
|
6038
|
+
] }),
|
|
6039
|
+
status === "error" && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
|
|
6040
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: errorIconStyle, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
6041
|
+
"svg",
|
|
6042
|
+
{
|
|
6043
|
+
width: "30",
|
|
6044
|
+
height: "30",
|
|
6045
|
+
viewBox: "0 0 24 24",
|
|
6046
|
+
fill: "none",
|
|
6047
|
+
stroke: "currentColor",
|
|
6048
|
+
strokeWidth: "2.5",
|
|
6049
|
+
strokeLinecap: "round",
|
|
6050
|
+
strokeLinejoin: "round",
|
|
6051
|
+
children: [
|
|
6052
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
|
|
6053
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
|
|
6054
|
+
]
|
|
6055
|
+
}
|
|
6056
|
+
) }),
|
|
6057
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h2", { style: titleStyle, children: "Verification Failed" }),
|
|
6058
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { style: messageStyle, children: message }),
|
|
6059
|
+
errorDetail && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { style: errorDetailStyle, children: errorDetail }),
|
|
6060
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
6061
|
+
"button",
|
|
6062
|
+
{
|
|
6063
|
+
className: "redacto-dl-retry-btn",
|
|
6064
|
+
style: buttonStyle,
|
|
6065
|
+
onClick: handleRetry,
|
|
6066
|
+
children: "Try Again"
|
|
6067
|
+
}
|
|
6068
|
+
)
|
|
6069
|
+
] })
|
|
6070
|
+
] }) })
|
|
6071
|
+
] });
|
|
6072
|
+
};
|
|
4426
6073
|
// Annotate the CommonJS export names for ESM import in node:
|
|
4427
6074
|
0 && (module.exports = {
|
|
6075
|
+
DigiLockerCallback,
|
|
4428
6076
|
RedactoNoticeConsent,
|
|
4429
6077
|
RedactoNoticeConsentInline
|
|
4430
6078
|
});
|