@redacto.io/consent-sdk-react 4.0.0 → 5.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +13 -1
- package/LICENSE +176 -0
- package/dist/index.js +231 -96
- package/dist/index.mjs +231 -96
- package/dist/privacy-center.d.mts +649 -0
- package/dist/privacy-center.d.ts +649 -0
- package/dist/privacy-center.js +20824 -0
- package/dist/privacy-center.mjs +20789 -0
- package/package.json +47 -3
- package/src/RedactoNoticeConsent/RedactoNoticeConsent.tsx +6 -4
- package/src/RedactoNoticeConsent/api/index.ts +2 -0
- package/src/RedactoNoticeConsent/api/types.ts +2 -0
- package/src/RedactoNoticeConsent/components/DigiLockerCallback.tsx +128 -62
- package/src/RedactoNoticeConsent/language-codes.ts +97 -0
- package/src/RedactoNoticeConsentInline/RedactoNoticeConsentInline.tsx +0 -3
- package/src/RedactoNoticeConsentInline/api/index.ts +0 -1
- package/src/RedactoPrivacyCenter/PrivacyCenterActivityPage.tsx +19 -0
- package/src/RedactoPrivacyCenter/PrivacyCenterCaseDetailsPage.tsx +154 -0
- package/src/RedactoPrivacyCenter/PrivacyCenterConsentManagerPage.tsx +17 -0
- package/src/RedactoPrivacyCenter/PrivacyCenterFormPage.tsx +79 -0
- package/src/RedactoPrivacyCenter/PrivacyCenterHomePage.tsx +30 -0
- package/src/RedactoPrivacyCenter/PrivacyCenterLayout.tsx +173 -0
- package/src/RedactoPrivacyCenter/RedactoPrivacyCenter.tsx +55 -0
- package/src/RedactoPrivacyCenter/api/actions.ts +476 -0
- package/src/RedactoPrivacyCenter/api/client.ts +524 -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/CaseDetails/AttachmentCard.tsx +38 -0
- package/src/RedactoPrivacyCenter/components/CaseDetails/ChatBubble.tsx +31 -0
- package/src/RedactoPrivacyCenter/components/CaseDetails/DocumentRequestCard.tsx +73 -0
- package/src/RedactoPrivacyCenter/components/CaseDetails/MessageComposer.tsx +87 -0
- package/src/RedactoPrivacyCenter/components/CaseDetails/MessageItem.tsx +95 -0
- package/src/RedactoPrivacyCenter/components/CaseDetails/MessagesTab.tsx +147 -0
- package/src/RedactoPrivacyCenter/components/CaseDetails/RequestDetailsTab.tsx +171 -0
- package/src/RedactoPrivacyCenter/components/CaseDetails/StatusEvent.tsx +23 -0
- package/src/RedactoPrivacyCenter/components/CaseDetails/useFileUpload.ts +116 -0
- package/src/RedactoPrivacyCenter/components/CaseDetails/useMessagePolling.ts +36 -0
- package/src/RedactoPrivacyCenter/components/CaseDetails/utils.ts +56 -0
- package/src/RedactoPrivacyCenter/components/CaseDetailsModal.tsx +469 -0
- package/src/RedactoPrivacyCenter/components/CaseHistory.tsx +426 -0
- package/src/RedactoPrivacyCenter/components/ConsentManager.tsx +732 -0
- package/src/RedactoPrivacyCenter/components/ConsentManagerColumns.tsx +238 -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 +304 -0
- package/src/RedactoPrivacyCenter/components/Form.tsx +1596 -0
- package/src/RedactoPrivacyCenter/components/GrievanceTable.tsx +174 -0
- package/src/RedactoPrivacyCenter/components/GrievanceTablePagination.tsx +337 -0
- package/src/RedactoPrivacyCenter/components/ModifyConsentModal.tsx +330 -0
- package/src/RedactoPrivacyCenter/components/Pagination.tsx +140 -0
- package/src/RedactoPrivacyCenter/components/PrivacyCenterLayout.tsx +304 -0
- package/src/RedactoPrivacyCenter/components/RequestSubmit.tsx +232 -0
- package/src/RedactoPrivacyCenter/components/SideMenuBarPC/SideBarPC.tsx +475 -0
- package/src/RedactoPrivacyCenter/components/SideMenuBarPC/SideMenuPC.tsx +408 -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 +159 -0
- package/src/RedactoPrivacyCenter/components/constant.ts +16 -0
- package/src/RedactoPrivacyCenter/components/types.ts +76 -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 +137 -0
- package/src/RedactoPrivacyCenter/context/BaseUrlContext.tsx +41 -0
- package/src/RedactoPrivacyCenter/context/LocaleContext.tsx +11 -0
- package/src/RedactoPrivacyCenter/context/NavigationContext.tsx +96 -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/context/types.ts +14 -0
- package/src/RedactoPrivacyCenter/lib/api.ts +566 -0
- package/src/RedactoPrivacyCenter/lib/consent-manager/utils.tsx +63 -0
- package/src/RedactoPrivacyCenter/lib/constants.ts +161 -0
- package/src/RedactoPrivacyCenter/lib/i18n.ts +81 -0
- package/src/RedactoPrivacyCenter/lib/locales.ts +105 -0
- package/src/RedactoPrivacyCenter/lib/queries.ts +134 -0
- package/src/RedactoPrivacyCenter/lib/types.ts +531 -0
- package/src/RedactoPrivacyCenter/lib/useCurrentLanguage.ts +37 -0
- package/src/RedactoPrivacyCenter/lib/utils.ts +626 -0
- package/src/RedactoPrivacyCenter/locales/as/translation.json +280 -0
- package/src/RedactoPrivacyCenter/locales/bho/translation.json +280 -0
- package/src/RedactoPrivacyCenter/locales/bn/translation.json +280 -0
- package/src/RedactoPrivacyCenter/locales/brx/translation.json +280 -0
- package/src/RedactoPrivacyCenter/locales/doi/translation.json +280 -0
- package/src/RedactoPrivacyCenter/locales/en/translation.json +255 -0
- package/src/RedactoPrivacyCenter/locales/gom/translation.json +280 -0
- package/src/RedactoPrivacyCenter/locales/gu/translation.json +280 -0
- package/src/RedactoPrivacyCenter/locales/hi/translation.json +280 -0
- package/src/RedactoPrivacyCenter/locales/kn/translation.json +280 -0
- package/src/RedactoPrivacyCenter/locales/ks/translation.json +280 -0
- package/src/RedactoPrivacyCenter/locales/mai/translation.json +280 -0
- package/src/RedactoPrivacyCenter/locales/ml/translation.json +280 -0
- package/src/RedactoPrivacyCenter/locales/mni-Mtei/translation.json +280 -0
- package/src/RedactoPrivacyCenter/locales/mr/translation.json +280 -0
- package/src/RedactoPrivacyCenter/locales/ne/translation.json +280 -0
- package/src/RedactoPrivacyCenter/locales/or/translation.json +280 -0
- package/src/RedactoPrivacyCenter/locales/pa/translation.json +280 -0
- package/src/RedactoPrivacyCenter/locales/sa/translation.json +280 -0
- package/src/RedactoPrivacyCenter/locales/sat/translation.json +280 -0
- package/src/RedactoPrivacyCenter/locales/sd/translation.json +280 -0
- package/src/RedactoPrivacyCenter/locales/ta/translation.json +280 -0
- package/src/RedactoPrivacyCenter/locales/te/translation.json +280 -0
- package/src/RedactoPrivacyCenter/locales/ur/translation.json +280 -0
- package/src/RedactoPrivacyCenter/styles/base.css +117 -0
- package/src/RedactoPrivacyCenter/styles/injectStyles.ts +1725 -0
- package/src/RedactoPrivacyCenter/styles/pcStyles.ts +813 -0
- package/src/RedactoPrivacyCenter/styles/responsive.ts +138 -0
- package/src/RedactoPrivacyCenter/styles/variables.css +133 -0
- package/src/RedactoPrivacyCenter/table/AdvancedTable.tsx +367 -0
- package/src/RedactoPrivacyCenter/table/AdvancedTablePagination.tsx +476 -0
- package/src/RedactoPrivacyCenter/table/index.ts +2 -0
- package/src/RedactoPrivacyCenter/types/images.d.ts +29 -0
- package/src/RedactoPrivacyCenter/ui/Footer.tsx +75 -0
- package/src/RedactoPrivacyCenter/ui/FormBlockWrapper.tsx +54 -0
- package/src/RedactoPrivacyCenter/ui/PCAccordion.tsx +93 -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 +107 -0
- package/src/RedactoPrivacyCenter/ui/PCEmpty.tsx +35 -0
- package/src/RedactoPrivacyCenter/ui/PCInput.tsx +132 -0
- package/src/RedactoPrivacyCenter/ui/PCLoader.tsx +31 -0
- package/src/RedactoPrivacyCenter/ui/PCModal.tsx +106 -0
- package/src/RedactoPrivacyCenter/ui/PCPopover.tsx +173 -0
- package/src/RedactoPrivacyCenter/ui/PCSelect.tsx +387 -0
- package/src/RedactoPrivacyCenter/ui/PCTable.tsx +149 -0
- package/src/RedactoPrivacyCenter/ui/PCText.tsx +41 -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 +53 -0
- package/src/RedactoPrivacyCenter/ui/ThemeToggle.tsx +72 -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/privacy-center.ts +108 -0
- package/tsconfig.json +2 -0
- package/tsup.config.ts +16 -1
- package/.turbo/turbo-build.log +0 -21
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@redacto.io/consent-sdk-react",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "5.0.0",
|
|
4
4
|
"main": "dist/index.cjs",
|
|
5
5
|
"module": "dist/index.mjs",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -9,12 +9,17 @@
|
|
|
9
9
|
"types": "./dist/index.d.ts",
|
|
10
10
|
"require": "./dist/index.cjs",
|
|
11
11
|
"import": "./dist/index.mjs"
|
|
12
|
+
},
|
|
13
|
+
"./privacy-center": {
|
|
14
|
+
"types": "./dist/privacy-center.d.ts",
|
|
15
|
+
"require": "./dist/privacy-center.cjs",
|
|
16
|
+
"import": "./dist/privacy-center.mjs"
|
|
12
17
|
}
|
|
13
18
|
},
|
|
14
19
|
"keywords": [],
|
|
15
20
|
"author": "",
|
|
16
21
|
"license": "Apache-2.0",
|
|
17
|
-
"description": "",
|
|
22
|
+
"description": "React SDK for Redacto consent notices and privacy center",
|
|
18
23
|
"publishConfig": {
|
|
19
24
|
"access": "public"
|
|
20
25
|
},
|
|
@@ -24,6 +29,7 @@
|
|
|
24
29
|
"devDependencies": {
|
|
25
30
|
"@testing-library/jest-dom": "^6.6.3",
|
|
26
31
|
"@testing-library/react": "^16.3.0",
|
|
32
|
+
"@types/lodash": "^4.17.0",
|
|
27
33
|
"@types/react": "^19.1.3",
|
|
28
34
|
"@types/react-dom": "^19.1.3",
|
|
29
35
|
"@vitest/coverage-v8": "3.1.3",
|
|
@@ -34,7 +40,45 @@
|
|
|
34
40
|
},
|
|
35
41
|
"peerDependencies": {
|
|
36
42
|
"react": "^16.8.0 || ^17 || ^18 || ^19",
|
|
37
|
-
"react-dom": "^16.8.0 || ^17 || ^18 || ^19"
|
|
43
|
+
"react-dom": "^16.8.0 || ^17 || ^18 || ^19",
|
|
44
|
+
"@tanstack/react-query": "^5.0.0",
|
|
45
|
+
"@tanstack/react-table": "^8.0.0",
|
|
46
|
+
"i18next": "^23.0.0",
|
|
47
|
+
"i18next-browser-languagedetector": "^7.0.0",
|
|
48
|
+
"react-i18next": "^13.0.0",
|
|
49
|
+
"lucide-react": ">=0.300.0",
|
|
50
|
+
"react-icons": "^5.0.0",
|
|
51
|
+
"dayjs": "^1.11.0",
|
|
52
|
+
"lodash": "^4.17.0"
|
|
53
|
+
},
|
|
54
|
+
"peerDependenciesMeta": {
|
|
55
|
+
"@tanstack/react-query": {
|
|
56
|
+
"optional": true
|
|
57
|
+
},
|
|
58
|
+
"@tanstack/react-table": {
|
|
59
|
+
"optional": true
|
|
60
|
+
},
|
|
61
|
+
"i18next": {
|
|
62
|
+
"optional": true
|
|
63
|
+
},
|
|
64
|
+
"i18next-browser-languagedetector": {
|
|
65
|
+
"optional": true
|
|
66
|
+
},
|
|
67
|
+
"react-i18next": {
|
|
68
|
+
"optional": true
|
|
69
|
+
},
|
|
70
|
+
"lucide-react": {
|
|
71
|
+
"optional": true
|
|
72
|
+
},
|
|
73
|
+
"react-icons": {
|
|
74
|
+
"optional": true
|
|
75
|
+
},
|
|
76
|
+
"dayjs": {
|
|
77
|
+
"optional": true
|
|
78
|
+
},
|
|
79
|
+
"lodash": {
|
|
80
|
+
"optional": true
|
|
81
|
+
}
|
|
38
82
|
},
|
|
39
83
|
"scripts": {
|
|
40
84
|
"build": "tsup",
|
|
@@ -32,6 +32,7 @@ import logo from "./assets/redacto-logo.png";
|
|
|
32
32
|
|
|
33
33
|
// Constants
|
|
34
34
|
import { DPO_AUDIO_ELEMENT_MAP } from "./constants";
|
|
35
|
+
import { toBcp47Code, toNativeLabel } from "./language-codes";
|
|
35
36
|
|
|
36
37
|
// Utility imports
|
|
37
38
|
import { injectCheckboxStyles } from "./injectStyles";
|
|
@@ -2151,6 +2152,7 @@ export const RedactoNoticeConsent = ({
|
|
|
2151
2152
|
};
|
|
2152
2153
|
}),
|
|
2153
2154
|
declined: false,
|
|
2155
|
+
language: toBcp47Code(selectedLanguage),
|
|
2154
2156
|
meta_data: applicationId
|
|
2155
2157
|
? { specific_uuid: applicationId }
|
|
2156
2158
|
: undefined,
|
|
@@ -3778,9 +3780,9 @@ export const RedactoNoticeConsent = ({
|
|
|
3778
3780
|
aria-expanded={isLanguageDropdownOpen}
|
|
3779
3781
|
aria-haspopup="listbox"
|
|
3780
3782
|
aria-controls="language-listbox"
|
|
3781
|
-
aria-label={`Select language. Current language: ${selectedLanguage}`}
|
|
3783
|
+
aria-label={`Select language. Current language: ${toNativeLabel(selectedLanguage)}`}
|
|
3782
3784
|
>
|
|
3783
|
-
{selectedLanguage}
|
|
3785
|
+
{toNativeLabel(selectedLanguage)}
|
|
3784
3786
|
<svg
|
|
3785
3787
|
xmlns="http://www.w3.org/2000/svg"
|
|
3786
3788
|
width="16"
|
|
@@ -3827,9 +3829,9 @@ export const RedactoNoticeConsent = ({
|
|
|
3827
3829
|
role="option"
|
|
3828
3830
|
aria-selected={selectedLanguage === lang}
|
|
3829
3831
|
tabIndex={0}
|
|
3830
|
-
aria-label={`Select ${lang} language`}
|
|
3832
|
+
aria-label={`Select ${toNativeLabel(lang)} language`}
|
|
3831
3833
|
>
|
|
3832
|
-
{lang}
|
|
3834
|
+
{toNativeLabel(lang)}
|
|
3833
3835
|
</li>
|
|
3834
3836
|
))}
|
|
3835
3837
|
</ul>
|
|
@@ -143,6 +143,7 @@ export const submitConsentEvent = async ({
|
|
|
143
143
|
noticeUuid,
|
|
144
144
|
purposes,
|
|
145
145
|
declined,
|
|
146
|
+
language,
|
|
146
147
|
meta_data,
|
|
147
148
|
guardianVerificationReference,
|
|
148
149
|
selfDeclaredAdult,
|
|
@@ -190,6 +191,7 @@ export const submitConsentEvent = async ({
|
|
|
190
191
|
select_all_mandatory: false,
|
|
191
192
|
source: "WEB",
|
|
192
193
|
declined: Boolean(declined),
|
|
194
|
+
language: language || undefined,
|
|
193
195
|
meta_data: meta_data ? { specific_uuid: meta_data.specific_uuid, minor_age: meta_data.minor_age } : undefined,
|
|
194
196
|
guardian_verification_reference: guardianVerificationReference,
|
|
195
197
|
self_declared_adult: selfDeclaredAdult,
|
|
@@ -170,6 +170,7 @@ export type ConsentEventPayload = {
|
|
|
170
170
|
select_all_mandatory: boolean;
|
|
171
171
|
source?: string;
|
|
172
172
|
declined?: boolean;
|
|
173
|
+
language?: string;
|
|
173
174
|
meta_data?: {
|
|
174
175
|
specific_uuid?: string;
|
|
175
176
|
minor_age?: number;
|
|
@@ -201,6 +202,7 @@ export type SubmitConsentEventParams = {
|
|
|
201
202
|
noticeUuid: string;
|
|
202
203
|
purposes: Array<Purpose>;
|
|
203
204
|
declined: boolean;
|
|
205
|
+
language?: string;
|
|
204
206
|
meta_data?: {
|
|
205
207
|
specific_uuid?: string;
|
|
206
208
|
minor_age?: number;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* DigiLockerCallback Component
|
|
3
|
-
*
|
|
3
|
+
*
|
|
4
4
|
* Standalone component for handling DigiLocker redirect callbacks.
|
|
5
5
|
* Clients should add this to their routing (e.g., /digilocker-callback page).
|
|
6
|
-
*
|
|
6
|
+
*
|
|
7
7
|
* Usage in Next.js:
|
|
8
8
|
* ```tsx
|
|
9
9
|
* // pages/digilocker-callback.tsx
|
|
@@ -18,10 +18,10 @@
|
|
|
18
18
|
* ```tsx
|
|
19
19
|
* <Route path="/digilocker-callback" element={<DigiLockerCallback accessToken={"<token>"} />} />
|
|
20
20
|
* ```
|
|
21
|
-
*
|
|
21
|
+
*
|
|
22
22
|
* URL Parameters expected from redirect:
|
|
23
23
|
* - session_token: The verification session token
|
|
24
|
-
* - status: "verified" | "failed" | "expired"
|
|
24
|
+
* - status: "verified" | "failed" | "expired"
|
|
25
25
|
* - verification_reference: (if verified) Reference for consent submission
|
|
26
26
|
* - error_code: (if failed) Error code like GUARDIAN_UNDER_18, SESSION_EXPIRED, etc.
|
|
27
27
|
*/
|
|
@@ -131,7 +131,7 @@ export const DigiLockerCallback: React.FC<DigiLockerCallbackProps> = ({
|
|
|
131
131
|
setStatus("success");
|
|
132
132
|
setMessage("Guardian verified successfully! Redirecting...");
|
|
133
133
|
onSuccess?.(verificationReference);
|
|
134
|
-
|
|
134
|
+
|
|
135
135
|
// If in iframe, postMessage to parent instead of redirecting
|
|
136
136
|
if (isInIframe && window.parent) {
|
|
137
137
|
window.parent.postMessage(
|
|
@@ -144,7 +144,7 @@ export const DigiLockerCallback: React.FC<DigiLockerCallbackProps> = ({
|
|
|
144
144
|
);
|
|
145
145
|
return;
|
|
146
146
|
}
|
|
147
|
-
|
|
147
|
+
|
|
148
148
|
redirectToOriginalPage(originalUrl, "verified", verificationReference);
|
|
149
149
|
return;
|
|
150
150
|
}
|
|
@@ -170,16 +170,16 @@ export const DigiLockerCallback: React.FC<DigiLockerCallbackProps> = ({
|
|
|
170
170
|
);
|
|
171
171
|
return;
|
|
172
172
|
}
|
|
173
|
-
|
|
173
|
+
|
|
174
174
|
redirectToOriginalPage(originalUrl, urlStatus);
|
|
175
175
|
return;
|
|
176
176
|
}
|
|
177
177
|
|
|
178
178
|
// 4. If no status in URL, poll the backend for verification status
|
|
179
179
|
setMessage("Processing verification...");
|
|
180
|
-
|
|
180
|
+
|
|
181
181
|
const apiBaseUrl = baseUrl || storedBaseUrl;
|
|
182
|
-
|
|
182
|
+
|
|
183
183
|
const response = await verifyGuardianStatus({
|
|
184
184
|
accessToken,
|
|
185
185
|
baseUrl: apiBaseUrl,
|
|
@@ -336,11 +336,11 @@ export const DigiLockerCallback: React.FC<DigiLockerCallbackProps> = ({
|
|
|
336
336
|
} catch (error) {
|
|
337
337
|
console.error("DigiLocker callback error:", error);
|
|
338
338
|
setStatus("error");
|
|
339
|
-
|
|
339
|
+
|
|
340
340
|
const err = error as Error;
|
|
341
341
|
setMessage("Verification failed");
|
|
342
342
|
setErrorDetail(err.message || "An error occurred during verification");
|
|
343
|
-
|
|
343
|
+
|
|
344
344
|
onError?.(err);
|
|
345
345
|
|
|
346
346
|
// Try to redirect back even on error
|
|
@@ -373,106 +373,157 @@ export const DigiLockerCallback: React.FC<DigiLockerCallbackProps> = ({
|
|
|
373
373
|
}
|
|
374
374
|
}, []);
|
|
375
375
|
|
|
376
|
-
//
|
|
376
|
+
// --- Styles ---
|
|
377
|
+
|
|
377
378
|
const containerStyle: React.CSSProperties = {
|
|
378
379
|
display: "flex",
|
|
379
380
|
alignItems: "center",
|
|
380
381
|
justifyContent: "center",
|
|
381
382
|
minHeight: "100vh",
|
|
382
|
-
backgroundColor: "#
|
|
383
|
+
backgroundColor: "#f8fafc",
|
|
383
384
|
fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif',
|
|
384
|
-
padding: "
|
|
385
|
+
padding: "24px",
|
|
385
386
|
boxSizing: "border-box",
|
|
386
387
|
};
|
|
387
388
|
|
|
388
389
|
const cardStyle: React.CSSProperties = {
|
|
389
390
|
backgroundColor: "#ffffff",
|
|
390
|
-
borderRadius: "
|
|
391
|
-
boxShadow: "0
|
|
392
|
-
padding: "40px",
|
|
391
|
+
borderRadius: "16px",
|
|
392
|
+
boxShadow: "0 1px 3px rgba(0, 0, 0, 0.08), 0 8px 30px rgba(0, 0, 0, 0.06)",
|
|
393
|
+
padding: "48px 40px 40px",
|
|
393
394
|
textAlign: "center",
|
|
394
|
-
maxWidth: "
|
|
395
|
+
maxWidth: "420px",
|
|
395
396
|
width: "100%",
|
|
396
397
|
};
|
|
397
398
|
|
|
399
|
+
const spinnerContainerStyle: React.CSSProperties = {
|
|
400
|
+
width: "72px",
|
|
401
|
+
height: "72px",
|
|
402
|
+
margin: "0 auto 28px",
|
|
403
|
+
position: "relative",
|
|
404
|
+
};
|
|
405
|
+
|
|
398
406
|
const spinnerStyle: React.CSSProperties = {
|
|
399
|
-
width: "
|
|
400
|
-
height: "
|
|
401
|
-
border: "
|
|
402
|
-
borderTopColor: "#
|
|
407
|
+
width: "72px",
|
|
408
|
+
height: "72px",
|
|
409
|
+
border: "3px solid #e5e7eb",
|
|
410
|
+
borderTopColor: "#4f87ff",
|
|
403
411
|
borderRadius: "50%",
|
|
404
|
-
animation: "spin
|
|
405
|
-
|
|
412
|
+
animation: "redacto-dl-spin 0.8s linear infinite",
|
|
413
|
+
boxSizing: "border-box",
|
|
406
414
|
};
|
|
407
415
|
|
|
408
|
-
const
|
|
409
|
-
width: "
|
|
410
|
-
height: "
|
|
416
|
+
const iconContainerStyle: React.CSSProperties = {
|
|
417
|
+
width: "72px",
|
|
418
|
+
height: "72px",
|
|
411
419
|
borderRadius: "50%",
|
|
412
420
|
display: "flex",
|
|
413
421
|
alignItems: "center",
|
|
414
422
|
justifyContent: "center",
|
|
415
|
-
margin: "0 auto
|
|
423
|
+
margin: "0 auto 28px",
|
|
424
|
+
animation: "redacto-dl-pop 0.4s cubic-bezier(0.34, 1.56, 0.64, 1) forwards",
|
|
425
|
+
position: "relative",
|
|
416
426
|
};
|
|
417
427
|
|
|
418
428
|
const successIconStyle: React.CSSProperties = {
|
|
419
|
-
...
|
|
429
|
+
...iconContainerStyle,
|
|
420
430
|
backgroundColor: "#d1fae5",
|
|
421
431
|
color: "#059669",
|
|
422
432
|
};
|
|
423
433
|
|
|
424
434
|
const errorIconStyle: React.CSSProperties = {
|
|
425
|
-
...
|
|
435
|
+
...iconContainerStyle,
|
|
426
436
|
backgroundColor: "#fee2e2",
|
|
427
437
|
color: "#dc2626",
|
|
428
438
|
};
|
|
429
439
|
|
|
430
440
|
const titleStyle: React.CSSProperties = {
|
|
431
|
-
fontSize: "
|
|
432
|
-
fontWeight:
|
|
441
|
+
fontSize: "22px",
|
|
442
|
+
fontWeight: 700,
|
|
433
443
|
color: "#111827",
|
|
434
|
-
margin: "0 0
|
|
444
|
+
margin: "0 0 8px 0",
|
|
445
|
+
letterSpacing: "-0.01em",
|
|
435
446
|
};
|
|
436
447
|
|
|
437
448
|
const messageStyle: React.CSSProperties = {
|
|
438
449
|
fontSize: "14px",
|
|
439
450
|
color: "#6b7280",
|
|
440
|
-
marginBottom: "
|
|
451
|
+
marginBottom: "0",
|
|
452
|
+
lineHeight: 1.6,
|
|
453
|
+
};
|
|
454
|
+
|
|
455
|
+
const subtextStyle: React.CSSProperties = {
|
|
456
|
+
fontSize: "13px",
|
|
457
|
+
color: "#9ca3af",
|
|
458
|
+
marginTop: "16px",
|
|
441
459
|
lineHeight: 1.5,
|
|
442
460
|
};
|
|
443
461
|
|
|
444
462
|
const errorDetailStyle: React.CSSProperties = {
|
|
445
463
|
fontSize: "13px",
|
|
446
464
|
color: "#dc2626",
|
|
447
|
-
marginTop: "
|
|
448
|
-
padding: "12px",
|
|
465
|
+
marginTop: "16px",
|
|
466
|
+
padding: "12px 16px",
|
|
449
467
|
backgroundColor: "#fef2f2",
|
|
450
|
-
borderRadius: "
|
|
468
|
+
borderRadius: "10px",
|
|
451
469
|
border: "1px solid #fecaca",
|
|
470
|
+
lineHeight: 1.5,
|
|
471
|
+
textAlign: "left",
|
|
452
472
|
};
|
|
453
473
|
|
|
454
474
|
const buttonStyle: React.CSSProperties = {
|
|
455
|
-
marginTop: "
|
|
456
|
-
padding: "
|
|
457
|
-
backgroundColor: "#
|
|
475
|
+
marginTop: "24px",
|
|
476
|
+
padding: "12px 28px",
|
|
477
|
+
backgroundColor: "#4f87ff",
|
|
458
478
|
color: "#ffffff",
|
|
459
479
|
border: "none",
|
|
460
|
-
borderRadius: "
|
|
461
|
-
fontSize: "
|
|
462
|
-
fontWeight:
|
|
480
|
+
borderRadius: "10px",
|
|
481
|
+
fontSize: "15px",
|
|
482
|
+
fontWeight: 600,
|
|
463
483
|
cursor: "pointer",
|
|
464
|
-
transition: "background-color 0.2s",
|
|
484
|
+
transition: "background-color 0.2s, transform 0.15s",
|
|
485
|
+
width: "100%",
|
|
465
486
|
};
|
|
466
487
|
|
|
488
|
+
const keyframesStyle = `
|
|
489
|
+
@keyframes redacto-dl-spin {
|
|
490
|
+
to { transform: rotate(360deg); }
|
|
491
|
+
}
|
|
492
|
+
@keyframes redacto-dl-pop {
|
|
493
|
+
0% { transform: scale(0.3); opacity: 0; }
|
|
494
|
+
60% { transform: scale(1.08); opacity: 1; }
|
|
495
|
+
100% { transform: scale(1); opacity: 1; }
|
|
496
|
+
}
|
|
497
|
+
@keyframes redacto-dl-check {
|
|
498
|
+
0% { stroke-dashoffset: 24; }
|
|
499
|
+
100% { stroke-dashoffset: 0; }
|
|
500
|
+
}
|
|
501
|
+
@keyframes redacto-dl-pulse {
|
|
502
|
+
0%, 100% { transform: scale(1); opacity: 0.6; }
|
|
503
|
+
50% { transform: scale(1.15); opacity: 0; }
|
|
504
|
+
}
|
|
505
|
+
.redacto-dl-retry-btn:hover {
|
|
506
|
+
background-color: #3d6fdb !important;
|
|
507
|
+
transform: translateY(-1px);
|
|
508
|
+
}
|
|
509
|
+
.redacto-dl-retry-btn:active {
|
|
510
|
+
transform: translateY(0);
|
|
511
|
+
}
|
|
512
|
+
`;
|
|
513
|
+
|
|
467
514
|
return (
|
|
515
|
+
<>
|
|
516
|
+
<style dangerouslySetInnerHTML={{ __html: keyframesStyle }} />
|
|
468
517
|
<div style={containerStyle}>
|
|
469
518
|
<div style={cardStyle}>
|
|
470
519
|
{status === "processing" && (
|
|
471
520
|
<>
|
|
472
|
-
<div style={
|
|
521
|
+
<div style={spinnerContainerStyle}>
|
|
522
|
+
<div style={spinnerStyle} />
|
|
523
|
+
</div>
|
|
473
524
|
<h2 style={titleStyle}>Processing Verification</h2>
|
|
474
525
|
<p style={messageStyle}>{message}</p>
|
|
475
|
-
<p style={
|
|
526
|
+
<p style={subtextStyle}>
|
|
476
527
|
Please wait while we verify your guardian's identity...
|
|
477
528
|
</p>
|
|
478
529
|
</>
|
|
@@ -480,22 +531,36 @@ export const DigiLockerCallback: React.FC<DigiLockerCallbackProps> = ({
|
|
|
480
531
|
|
|
481
532
|
{status === "success" && (
|
|
482
533
|
<>
|
|
483
|
-
<div style={
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
534
|
+
<div style={{ position: "relative", width: "72px", height: "72px", margin: "0 auto 28px" }}>
|
|
535
|
+
{/* Pulse ring */}
|
|
536
|
+
<div style={{
|
|
537
|
+
position: "absolute",
|
|
538
|
+
inset: "-8px",
|
|
539
|
+
borderRadius: "50%",
|
|
540
|
+
border: "2px solid #d1fae5",
|
|
541
|
+
animation: "redacto-dl-pulse 1.5s ease-out infinite",
|
|
542
|
+
}} />
|
|
543
|
+
<div style={successIconStyle}>
|
|
544
|
+
<svg
|
|
545
|
+
width="30"
|
|
546
|
+
height="30"
|
|
547
|
+
viewBox="0 0 24 24"
|
|
548
|
+
fill="none"
|
|
549
|
+
stroke="currentColor"
|
|
550
|
+
strokeWidth="2.5"
|
|
551
|
+
strokeLinecap="round"
|
|
552
|
+
strokeLinejoin="round"
|
|
553
|
+
style={{ strokeDasharray: 24, animation: "redacto-dl-check 0.4s ease-out 0.3s forwards", strokeDashoffset: 24 }}
|
|
554
|
+
>
|
|
555
|
+
<polyline points="20 6 9 17 4 12" />
|
|
556
|
+
</svg>
|
|
557
|
+
</div>
|
|
496
558
|
</div>
|
|
497
559
|
<h2 style={titleStyle}>Verification Successful</h2>
|
|
498
560
|
<p style={messageStyle}>{message}</p>
|
|
561
|
+
<p style={subtextStyle}>
|
|
562
|
+
You will be redirected automatically.
|
|
563
|
+
</p>
|
|
499
564
|
</>
|
|
500
565
|
)}
|
|
501
566
|
|
|
@@ -503,12 +568,12 @@ export const DigiLockerCallback: React.FC<DigiLockerCallbackProps> = ({
|
|
|
503
568
|
<>
|
|
504
569
|
<div style={errorIconStyle}>
|
|
505
570
|
<svg
|
|
506
|
-
width="
|
|
507
|
-
height="
|
|
571
|
+
width="30"
|
|
572
|
+
height="30"
|
|
508
573
|
viewBox="0 0 24 24"
|
|
509
574
|
fill="none"
|
|
510
575
|
stroke="currentColor"
|
|
511
|
-
strokeWidth="2"
|
|
576
|
+
strokeWidth="2.5"
|
|
512
577
|
strokeLinecap="round"
|
|
513
578
|
strokeLinejoin="round"
|
|
514
579
|
>
|
|
@@ -530,6 +595,7 @@ export const DigiLockerCallback: React.FC<DigiLockerCallbackProps> = ({
|
|
|
530
595
|
)}
|
|
531
596
|
</div>
|
|
532
597
|
</div>
|
|
598
|
+
</>
|
|
533
599
|
);
|
|
534
600
|
};
|
|
535
601
|
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Maps English language names to "Native script (English)" display labels.
|
|
3
|
+
* English itself is kept as-is; all others show the native script first.
|
|
4
|
+
*/
|
|
5
|
+
export const LANGUAGE_NATIVE_LABELS: Record<string, string> = {
|
|
6
|
+
English: "English",
|
|
7
|
+
Assamese: "অসমীয়া (Assamese)",
|
|
8
|
+
Bengali: "বাংলা (Bengali)",
|
|
9
|
+
Bhojpuri: "भोजपुरी (Bhojpuri)",
|
|
10
|
+
Bodo: "बड़ो (Bodo)",
|
|
11
|
+
Dogri: "डोगरी (Dogri)",
|
|
12
|
+
Gujarati: "ગુજરાતી (Gujarati)",
|
|
13
|
+
Hindi: "हिन्दी (Hindi)",
|
|
14
|
+
Kannada: "ಕನ್ನಡ (Kannada)",
|
|
15
|
+
Kashmiri: "كٲشُر (Kashmiri)",
|
|
16
|
+
"Goan Konkani": "कोंकणी (Goan Konkani)",
|
|
17
|
+
Maithili: "मैथिली (Maithili)",
|
|
18
|
+
Malayalam: "മലയാളം (Malayalam)",
|
|
19
|
+
Manipuri: "ꯃꯩꯇꯩꯂꯣꯟ (Manipuri)",
|
|
20
|
+
Marathi: "मराठी (Marathi)",
|
|
21
|
+
Nepali: "नेपाली (Nepali)",
|
|
22
|
+
Odia: "ଓଡ଼ିଆ (Odia)",
|
|
23
|
+
Punjabi: "ਪੰਜਾਬੀ (Punjabi)",
|
|
24
|
+
Sanskrit: "संस्कृतम् (Sanskrit)",
|
|
25
|
+
Santali: "ᱥᱟᱱᱛᱟᱲᱤ (Santali)",
|
|
26
|
+
Sindhi: "سنڌي (Sindhi)",
|
|
27
|
+
Tamil: "தமிழ் (Tamil)",
|
|
28
|
+
Telugu: "తెలుగు (Telugu)",
|
|
29
|
+
Urdu: "اردو (Urdu)",
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
/** Returns the "Native (English)" display label for a language name, falling back to the name itself. */
|
|
33
|
+
export const toNativeLabel = (name: string): string =>
|
|
34
|
+
LANGUAGE_NATIVE_LABELS[name] ?? name;
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Maps display language names (as used in supported_languages_and_translations
|
|
38
|
+
* keys and the language dropdown) to BCP-47 codes for the submit-consent payload.
|
|
39
|
+
*
|
|
40
|
+
* Covers English + the 22 languages in the 8th Schedule of the Indian Constitution
|
|
41
|
+
* (DPDP Act 2023, Sections 5 & 6).
|
|
42
|
+
*/
|
|
43
|
+
const LANGUAGE_NAME_TO_BCP47: Record<string, string> = {
|
|
44
|
+
English: "en",
|
|
45
|
+
Assamese: "as",
|
|
46
|
+
Bengali: "bn",
|
|
47
|
+
Bhojpuri: "bho",
|
|
48
|
+
Bodo: "brx",
|
|
49
|
+
Dogri: "doi",
|
|
50
|
+
Gujarati: "gu",
|
|
51
|
+
Hindi: "hi",
|
|
52
|
+
Kannada: "kn",
|
|
53
|
+
Kashmiri: "ks",
|
|
54
|
+
"Goan Konkani": "gom",
|
|
55
|
+
Maithili: "mai",
|
|
56
|
+
Malayalam: "ml",
|
|
57
|
+
Manipuri: "mni-Mtei",
|
|
58
|
+
Marathi: "mr",
|
|
59
|
+
Nepali: "ne",
|
|
60
|
+
Odia: "or",
|
|
61
|
+
Punjabi: "pa",
|
|
62
|
+
Sanskrit: "sa",
|
|
63
|
+
Santali: "sat",
|
|
64
|
+
Sindhi: "sd",
|
|
65
|
+
Tamil: "ta",
|
|
66
|
+
Telugu: "te",
|
|
67
|
+
Urdu: "ur",
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
const KNOWN_BCP47_CODES = new Set(Object.values(LANGUAGE_NAME_TO_BCP47));
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Convert a language display name or code to a BCP-47 code.
|
|
74
|
+
* Handles these cases:
|
|
75
|
+
* 1. Display name ("Punjabi") → BCP-47 ("pa")
|
|
76
|
+
* 2. Already a BCP-47 tag, including region/script subtags ("pa", "en-US", "zh-Hans") → returned as-is
|
|
77
|
+
* 3. Unknown value → falls back to "en"
|
|
78
|
+
*/
|
|
79
|
+
export const toBcp47Code = (language: string): string => {
|
|
80
|
+
if (LANGUAGE_NAME_TO_BCP47[language]) {
|
|
81
|
+
return LANGUAGE_NAME_TO_BCP47[language];
|
|
82
|
+
}
|
|
83
|
+
if (KNOWN_BCP47_CODES.has(language)) {
|
|
84
|
+
return language;
|
|
85
|
+
}
|
|
86
|
+
const lower = language.toLowerCase();
|
|
87
|
+
for (const [name, code] of Object.entries(LANGUAGE_NAME_TO_BCP47)) {
|
|
88
|
+
if (name.toLowerCase() === lower) {
|
|
89
|
+
return code;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
// Pass through well-formed BCP-47 tags with subtags (e.g. en-US, pa-IN, zh-Hans).
|
|
93
|
+
if (/^[A-Za-z]{2,3}(?:-[A-Za-z0-9]{2,8})*$/.test(language)) {
|
|
94
|
+
return language;
|
|
95
|
+
}
|
|
96
|
+
return "en";
|
|
97
|
+
};
|
|
@@ -87,9 +87,6 @@ const RedactoConsentInlineComponent = ({
|
|
|
87
87
|
onValidationChange?.(areAllRequiredElementsChecked);
|
|
88
88
|
}, [areAllRequiredElementsChecked, onValidationChange]);
|
|
89
89
|
|
|
90
|
-
const acceptDisabled =
|
|
91
|
-
isSubmitting || !areAllRequiredElementsChecked || !accessToken;
|
|
92
|
-
|
|
93
90
|
useEffect(() => {
|
|
94
91
|
if (hasAlreadyConsented) {
|
|
95
92
|
onAccept?.();
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { useEffect } from 'react';
|
|
2
|
+
import i18n from './lib/i18n';
|
|
3
|
+
import ActivitiesList from './components/ActivitiesList';
|
|
4
|
+
|
|
5
|
+
export function PrivacyCenterActivityPage() {
|
|
6
|
+
useEffect(() => {
|
|
7
|
+
if (!i18n.language) {
|
|
8
|
+
i18n.changeLanguage('en');
|
|
9
|
+
}
|
|
10
|
+
}, []);
|
|
11
|
+
|
|
12
|
+
return (
|
|
13
|
+
<div style={{ width: '100%' }}>
|
|
14
|
+
<div style={{ paddingTop: '0.5rem' }}>
|
|
15
|
+
<ActivitiesList />
|
|
16
|
+
</div>
|
|
17
|
+
</div>
|
|
18
|
+
);
|
|
19
|
+
}
|