@redacto.io/consent-sdk-react 10.0.0-beta.9 → 10.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/NOTICE.md +17 -0
- package/README.md +141 -3
- package/dist/chunk-FEGTW73Q.mjs +182 -0
- package/dist/fonts.d.mts +35 -0
- package/dist/fonts.d.ts +35 -0
- package/dist/fonts.js +183 -0
- package/dist/fonts.mjs +10 -0
- package/dist/index.d.mts +12 -1
- package/dist/index.d.ts +12 -1
- package/dist/index.js +724 -365
- package/dist/index.mjs +346 -201
- package/dist/montserrat.generated-NBTECYRW.mjs +22 -0
- package/dist/privacy-center.d.mts +0 -1
- package/dist/privacy-center.d.ts +0 -1
- package/dist/privacy-center.js +2 -66
- package/dist/privacy-center.mjs +2 -66
- package/dist/types-6Aj7faxL.d.mts +57 -0
- package/dist/types-6Aj7faxL.d.ts +57 -0
- package/package.json +10 -1
- package/.turbo/turbo-build.log +0 -22
- package/.turbo/turbo-test.log +0 -203
- package/.turbo/turbo-verify-pack.log +0 -6
- package/CHANGELOG.md +0 -353
- package/src/RedactoNoticeAssisted/RedactoNoticeAssisted.test.tsx +0 -934
- package/src/RedactoNoticeAssisted/RedactoNoticeAssisted.tsx +0 -2160
- package/src/RedactoNoticeAssisted/api/index.ts +0 -275
- package/src/RedactoNoticeAssisted/api/types.ts +0 -182
- package/src/RedactoNoticeAssisted/assets/redacto-logo.png +0 -0
- package/src/RedactoNoticeAssisted/constants.ts +0 -51
- package/src/RedactoNoticeAssisted/i18n.ts +0 -1408
- package/src/RedactoNoticeAssisted/index.ts +0 -1
- package/src/RedactoNoticeAssisted/injectStyles.ts +0 -251
- package/src/RedactoNoticeAssisted/styles.ts +0 -730
- package/src/RedactoNoticeAssisted/types.ts +0 -26
- package/src/RedactoNoticeAssisted/useMediaQuery.ts +0 -36
- package/src/RedactoNoticeConsent/RedactoNoticeConsent.test.tsx +0 -1152
- package/src/RedactoNoticeConsent/RedactoNoticeConsent.tsx +0 -4308
- package/src/RedactoNoticeConsent/api/index.ts +0 -542
- package/src/RedactoNoticeConsent/api/sandbox.ts +0 -150
- package/src/RedactoNoticeConsent/api/types.ts +0 -515
- package/src/RedactoNoticeConsent/assets/redacto-logo.png +0 -0
- package/src/RedactoNoticeConsent/components/DigiLockerCallback.tsx +0 -602
- package/src/RedactoNoticeConsent/components/index.ts +0 -7
- package/src/RedactoNoticeConsent/constants.ts +0 -20
- package/src/RedactoNoticeConsent/index.ts +0 -1
- package/src/RedactoNoticeConsent/injectStyles.ts +0 -151
- package/src/RedactoNoticeConsent/language-codes.ts +0 -95
- package/src/RedactoNoticeConsent/services/storage.ts +0 -122
- package/src/RedactoNoticeConsent/styles.ts +0 -409
- package/src/RedactoNoticeConsent/types.ts +0 -80
- package/src/RedactoNoticeConsent/useMediaQuery.ts +0 -36
- package/src/RedactoNoticeConsentInline/RedactoNoticeConsentInline.test.tsx +0 -369
- package/src/RedactoNoticeConsentInline/RedactoNoticeConsentInline.tsx +0 -687
- package/src/RedactoNoticeConsentInline/api/index.ts +0 -106
- package/src/RedactoNoticeConsentInline/api/types.ts +0 -183
- package/src/RedactoNoticeConsentInline/assets/redacto-logo.png +0 -0
- package/src/RedactoNoticeConsentInline/index.ts +0 -1
- package/src/RedactoNoticeConsentInline/injectStyles.ts +0 -40
- package/src/RedactoNoticeConsentInline/styles.ts +0 -397
- package/src/RedactoNoticeConsentInline/types.ts +0 -51
- package/src/RedactoNoticeConsentInline/useMediaQuery.ts +0 -36
- package/src/RedactoPrivacyCenter/NotificationsPage.tsx +0 -182
- package/src/RedactoPrivacyCenter/PrivacyCenterActivityPage.tsx +0 -19
- package/src/RedactoPrivacyCenter/PrivacyCenterCaseDetailsPage.tsx +0 -156
- package/src/RedactoPrivacyCenter/PrivacyCenterConsentManagerPage.tsx +0 -17
- package/src/RedactoPrivacyCenter/PrivacyCenterFormPage.tsx +0 -79
- package/src/RedactoPrivacyCenter/PrivacyCenterHomePage.tsx +0 -36
- package/src/RedactoPrivacyCenter/PrivacyCenterLayout.tsx +0 -177
- package/src/RedactoPrivacyCenter/PrivacyCenterMyReceiptPage.tsx +0 -26
- package/src/RedactoPrivacyCenter/RedactoPrivacyCenter.tsx +0 -93
- package/src/RedactoPrivacyCenter/api/actions.ts +0 -695
- package/src/RedactoPrivacyCenter/api/client.ts +0 -1003
- package/src/RedactoPrivacyCenter/api/config.ts +0 -33
- package/src/RedactoPrivacyCenter/api/fetcher.ts +0 -275
- package/src/RedactoPrivacyCenter/api/orgBranding.ts +0 -16
- package/src/RedactoPrivacyCenter/api/upload.ts +0 -93
- package/src/RedactoPrivacyCenter/assets/character.svg +0 -31
- package/src/RedactoPrivacyCenter/assets/fileAttach.svg +0 -9
- package/src/RedactoPrivacyCenter/assets/greenTick.svg +0 -4
- package/src/RedactoPrivacyCenter/assets/mail.svg +0 -3
- package/src/RedactoPrivacyCenter/assets/poweredByRedacto.svg +0 -9
- package/src/RedactoPrivacyCenter/assets/sentImg.svg +0 -9
- package/src/RedactoPrivacyCenter/assets/uploadFileIcon.svg +0 -9
- package/src/RedactoPrivacyCenter/components/ActivitiesList.tsx +0 -252
- package/src/RedactoPrivacyCenter/components/ActivityTimeline.tsx +0 -239
- package/src/RedactoPrivacyCenter/components/AppShell/AppShell.tsx +0 -268
- package/src/RedactoPrivacyCenter/components/AppShell/MobileNavDrawer.tsx +0 -218
- package/src/RedactoPrivacyCenter/components/AppShell/NavItem.tsx +0 -205
- package/src/RedactoPrivacyCenter/components/AppShell/PageHeader.tsx +0 -107
- package/src/RedactoPrivacyCenter/components/AppShell/SidebarNav.tsx +0 -100
- package/src/RedactoPrivacyCenter/components/AppShell/TopAppBar.tsx +0 -339
- package/src/RedactoPrivacyCenter/components/AppShell/UserMenu.tsx +0 -245
- package/src/RedactoPrivacyCenter/components/AppShell/hooks/useIsTruncated.ts +0 -28
- package/src/RedactoPrivacyCenter/components/AppShell/hooks/useKeyboardShortcut.ts +0 -40
- package/src/RedactoPrivacyCenter/components/AppShell/hooks/useSidebarState.ts +0 -62
- package/src/RedactoPrivacyCenter/components/AppShell/usePrivacyCenterExitAction.ts +0 -36
- package/src/RedactoPrivacyCenter/components/CaseDetails/AttachmentCard.tsx +0 -38
- package/src/RedactoPrivacyCenter/components/CaseDetails/ChatBubble.tsx +0 -31
- package/src/RedactoPrivacyCenter/components/CaseDetails/DocumentRequestCard.tsx +0 -79
- package/src/RedactoPrivacyCenter/components/CaseDetails/FinalizedTooltipWrapper.tsx +0 -25
- package/src/RedactoPrivacyCenter/components/CaseDetails/MessageComposer.tsx +0 -96
- package/src/RedactoPrivacyCenter/components/CaseDetails/MessageItem.tsx +0 -97
- package/src/RedactoPrivacyCenter/components/CaseDetails/MessagesTab.tsx +0 -156
- package/src/RedactoPrivacyCenter/components/CaseDetails/RequestDetailsTab.tsx +0 -171
- package/src/RedactoPrivacyCenter/components/CaseDetails/StatusEvent.tsx +0 -23
- package/src/RedactoPrivacyCenter/components/CaseDetails/useFileUpload.ts +0 -116
- package/src/RedactoPrivacyCenter/components/CaseDetails/useMessagePolling.ts +0 -43
- package/src/RedactoPrivacyCenter/components/CaseDetails/utils.ts +0 -71
- package/src/RedactoPrivacyCenter/components/CaseDetailsModal.tsx +0 -469
- package/src/RedactoPrivacyCenter/components/CaseHistory.tsx +0 -426
- package/src/RedactoPrivacyCenter/components/ConsentManager.tsx +0 -1206
- package/src/RedactoPrivacyCenter/components/ConsentManagerCells.tsx +0 -218
- package/src/RedactoPrivacyCenter/components/ConsentManagerColumns.tsx +0 -138
- package/src/RedactoPrivacyCenter/components/ConsentManagerConstants.ts +0 -7
- package/src/RedactoPrivacyCenter/components/ConsentManagerExpandedRow.tsx +0 -179
- package/src/RedactoPrivacyCenter/components/ConsentManagerGroupedColumns.tsx +0 -318
- package/src/RedactoPrivacyCenter/components/ConsentManagerProductCards.tsx +0 -333
- package/src/RedactoPrivacyCenter/components/ConsentManagerPurposeCards.tsx +0 -102
- package/src/RedactoPrivacyCenter/components/ConsentManagerTableSkeleton.tsx +0 -159
- package/src/RedactoPrivacyCenter/components/DataRequest/CorrectionDataSection.tsx +0 -189
- package/src/RedactoPrivacyCenter/components/DataRequest/GrievanceDataSection.tsx +0 -118
- package/src/RedactoPrivacyCenter/components/DataRequest/NominationDataSection.tsx +0 -66
- package/src/RedactoPrivacyCenter/components/DataRequest/ProductSelectionSection.tsx +0 -222
- package/src/RedactoPrivacyCenter/components/DataRequest/PurposeSelectionSection.tsx +0 -331
- package/src/RedactoPrivacyCenter/components/Form.tsx +0 -1821
- package/src/RedactoPrivacyCenter/components/GrievanceTable.tsx +0 -174
- package/src/RedactoPrivacyCenter/components/GrievanceTablePagination.tsx +0 -337
- package/src/RedactoPrivacyCenter/components/ModifyConsentModal.tsx +0 -334
- package/src/RedactoPrivacyCenter/components/NotificationHub/NotificationBell.tsx +0 -173
- package/src/RedactoPrivacyCenter/components/NotificationHub/NotificationCTAButton.tsx +0 -18
- package/src/RedactoPrivacyCenter/components/NotificationHub/NotificationDropdown.tsx +0 -54
- package/src/RedactoPrivacyCenter/components/NotificationHub/NotificationDropdownItem.tsx +0 -57
- package/src/RedactoPrivacyCenter/components/NotificationHub/NotificationIcon.tsx +0 -19
- package/src/RedactoPrivacyCenter/components/NotificationHub/NotificationListPanel.tsx +0 -92
- package/src/RedactoPrivacyCenter/components/NotificationHub/NotificationRefreshButton.tsx +0 -20
- package/src/RedactoPrivacyCenter/components/NotificationHub/NotificationRow.tsx +0 -58
- package/src/RedactoPrivacyCenter/components/NotificationHub/StatCard.tsx +0 -10
- package/src/RedactoPrivacyCenter/components/NotificationHub/useNotificationActions.ts +0 -112
- package/src/RedactoPrivacyCenter/components/NotificationHub/utils.ts +0 -27
- package/src/RedactoPrivacyCenter/components/Pagination.tsx +0 -140
- package/src/RedactoPrivacyCenter/components/PrivacyCenterEmptyState.tsx +0 -76
- package/src/RedactoPrivacyCenter/components/PrivacyCenterSessionExpired.tsx +0 -97
- package/src/RedactoPrivacyCenter/components/ReceiptsList.tsx +0 -454
- package/src/RedactoPrivacyCenter/components/RequestSubmit.tsx +0 -270
- package/src/RedactoPrivacyCenter/components/SelectUser.tsx +0 -95
- package/src/RedactoPrivacyCenter/components/SelectUserGate.tsx +0 -195
- package/src/RedactoPrivacyCenter/components/SideMenuBarPC/constants.tsx +0 -25
- package/src/RedactoPrivacyCenter/components/SideMenuBarPC/types.ts +0 -21
- package/src/RedactoPrivacyCenter/components/caseHistoryColumns.tsx +0 -159
- package/src/RedactoPrivacyCenter/components/constant.ts +0 -52
- package/src/RedactoPrivacyCenter/components/groupHelpers.ts +0 -155
- package/src/RedactoPrivacyCenter/components/receiptColumns.tsx +0 -203
- package/src/RedactoPrivacyCenter/components/types.ts +0 -123
- package/src/RedactoPrivacyCenter/components/utils.tsx +0 -10
- package/src/RedactoPrivacyCenter/config/routes.ts +0 -9
- package/src/RedactoPrivacyCenter/config/table.ts +0 -25
- package/src/RedactoPrivacyCenter/context/AuthContext.tsx +0 -252
- package/src/RedactoPrivacyCenter/context/BaseUrlContext.tsx +0 -47
- package/src/RedactoPrivacyCenter/context/BrandingContext.tsx +0 -52
- package/src/RedactoPrivacyCenter/context/DataAvailabilityContext.session-expired.test.tsx +0 -92
- package/src/RedactoPrivacyCenter/context/DataAvailabilityContext.tsx +0 -181
- package/src/RedactoPrivacyCenter/context/LocaleContext.tsx +0 -11
- package/src/RedactoPrivacyCenter/context/NavigationContext.tsx +0 -96
- package/src/RedactoPrivacyCenter/context/OrganizationContext.tsx +0 -30
- package/src/RedactoPrivacyCenter/context/PageChromeContext.tsx +0 -80
- package/src/RedactoPrivacyCenter/context/ProfileSwitchContext.tsx +0 -15
- package/src/RedactoPrivacyCenter/context/types.ts +0 -57
- package/src/RedactoPrivacyCenter/lib/api.ts +0 -759
- package/src/RedactoPrivacyCenter/lib/consent-manager/utils.tsx +0 -67
- package/src/RedactoPrivacyCenter/lib/constants.ts +0 -283
- package/src/RedactoPrivacyCenter/lib/i18n.ts +0 -81
- package/src/RedactoPrivacyCenter/lib/locales.ts +0 -102
- package/src/RedactoPrivacyCenter/lib/queries.ts +0 -141
- package/src/RedactoPrivacyCenter/lib/sandbox.ts +0 -104
- package/src/RedactoPrivacyCenter/lib/types.ts +0 -896
- package/src/RedactoPrivacyCenter/lib/useCurrentLanguage.ts +0 -37
- package/src/RedactoPrivacyCenter/lib/utils.refresh-circuit.test.ts +0 -127
- package/src/RedactoPrivacyCenter/lib/utils.refresh-storage.test.ts +0 -85
- package/src/RedactoPrivacyCenter/lib/utils.session-expired.test.ts +0 -109
- package/src/RedactoPrivacyCenter/lib/utils.ts +0 -798
- package/src/RedactoPrivacyCenter/locales/as/translation.json +0 -342
- package/src/RedactoPrivacyCenter/locales/bn/translation.json +0 -342
- package/src/RedactoPrivacyCenter/locales/brx/translation.json +0 -342
- package/src/RedactoPrivacyCenter/locales/doi/translation.json +0 -342
- package/src/RedactoPrivacyCenter/locales/en/translation.json +0 -357
- package/src/RedactoPrivacyCenter/locales/gom/translation.json +0 -342
- package/src/RedactoPrivacyCenter/locales/gu/translation.json +0 -342
- package/src/RedactoPrivacyCenter/locales/hi/translation.json +0 -345
- package/src/RedactoPrivacyCenter/locales/kn/translation.json +0 -342
- package/src/RedactoPrivacyCenter/locales/ks/translation.json +0 -342
- package/src/RedactoPrivacyCenter/locales/mai/translation.json +0 -342
- package/src/RedactoPrivacyCenter/locales/ml/translation.json +0 -342
- package/src/RedactoPrivacyCenter/locales/mni-Mtei/translation.json +0 -342
- package/src/RedactoPrivacyCenter/locales/mr/translation.json +0 -342
- package/src/RedactoPrivacyCenter/locales/ne/translation.json +0 -342
- package/src/RedactoPrivacyCenter/locales/or/translation.json +0 -342
- package/src/RedactoPrivacyCenter/locales/pa/translation.json +0 -342
- package/src/RedactoPrivacyCenter/locales/sa/translation.json +0 -342
- package/src/RedactoPrivacyCenter/locales/sat/translation.json +0 -342
- package/src/RedactoPrivacyCenter/locales/sd/translation.json +0 -342
- package/src/RedactoPrivacyCenter/locales/ta/translation.json +0 -342
- package/src/RedactoPrivacyCenter/locales/te/translation.json +0 -342
- package/src/RedactoPrivacyCenter/locales/ur/translation.json +0 -342
- package/src/RedactoPrivacyCenter/styles/applyBrandingTheme.ts +0 -66
- package/src/RedactoPrivacyCenter/styles/base.css +0 -117
- package/src/RedactoPrivacyCenter/styles/injectStyles.ts +0 -3108
- package/src/RedactoPrivacyCenter/styles/pcStyles.ts +0 -831
- package/src/RedactoPrivacyCenter/styles/responsive.ts +0 -138
- package/src/RedactoPrivacyCenter/styles/variables.css +0 -96
- package/src/RedactoPrivacyCenter/table/AdvancedTable.tsx +0 -387
- package/src/RedactoPrivacyCenter/table/AdvancedTablePagination.tsx +0 -468
- package/src/RedactoPrivacyCenter/table/index.ts +0 -2
- package/src/RedactoPrivacyCenter/types/images.d.ts +0 -29
- package/src/RedactoPrivacyCenter/ui/Footer.tsx +0 -69
- package/src/RedactoPrivacyCenter/ui/FormBlockWrapper.tsx +0 -54
- package/src/RedactoPrivacyCenter/ui/PCAccordion.tsx +0 -93
- package/src/RedactoPrivacyCenter/ui/PCActionIcon.tsx +0 -47
- package/src/RedactoPrivacyCenter/ui/PCAvatar.test.tsx +0 -83
- package/src/RedactoPrivacyCenter/ui/PCAvatar.tsx +0 -93
- package/src/RedactoPrivacyCenter/ui/PCBadge.tsx +0 -48
- package/src/RedactoPrivacyCenter/ui/PCButton.tsx +0 -77
- package/src/RedactoPrivacyCenter/ui/PCCheckbox.tsx +0 -55
- package/src/RedactoPrivacyCenter/ui/PCCollapse.tsx +0 -107
- package/src/RedactoPrivacyCenter/ui/PCEmpty.tsx +0 -35
- package/src/RedactoPrivacyCenter/ui/PCInput.tsx +0 -132
- package/src/RedactoPrivacyCenter/ui/PCLoader.tsx +0 -31
- package/src/RedactoPrivacyCenter/ui/PCModal.tsx +0 -106
- package/src/RedactoPrivacyCenter/ui/PCPopover.tsx +0 -206
- package/src/RedactoPrivacyCenter/ui/PCSelect.tsx +0 -433
- package/src/RedactoPrivacyCenter/ui/PCTable.tsx +0 -149
- package/src/RedactoPrivacyCenter/ui/PCText.tsx +0 -41
- package/src/RedactoPrivacyCenter/ui/PCTextarea.tsx +0 -43
- package/src/RedactoPrivacyCenter/ui/PCTitle.tsx +0 -37
- package/src/RedactoPrivacyCenter/ui/PCTooltip.tsx +0 -121
- package/src/RedactoPrivacyCenter/ui/SimpleBar.tsx +0 -25
- package/src/RedactoPrivacyCenter/ui/StatusBadge.tsx +0 -53
- package/src/RedactoPrivacyCenter/ui/index.ts +0 -18
- package/src/RedactoPrivacyCenter/utils/cn.ts +0 -28
- package/src/RedactoPrivacyCenter/utils/date.ts +0 -48
- package/src/RedactoPrivacyCenter/utils/status.ts +0 -111
- package/src/RedactoPrivacyCenter/utils/toast.ts +0 -130
- package/src/index.ts +0 -19
- package/src/privacy-center.ts +0 -113
- package/src/shared/api-errors.ts +0 -180
- package/src/shared/notice-consent-status.ts +0 -190
- package/src/shared/sandbox.ts +0 -6
- package/src/types/css.d.ts +0 -4
- package/src/types/images.d.ts +0 -19
- package/src/types/react-jsx.d.ts +0 -26
- package/tests/DataAvailabilityContext.test.tsx +0 -123
- package/tests/Form.test.tsx +0 -1424
- package/tests/ManageConsentErrorMapping.test.tsx +0 -85
- package/tests/ProductSelectionSection.test.tsx +0 -328
- package/tests/RequestSubmit.test.tsx +0 -135
- package/tests/RevocablePurpose.test.tsx +0 -146
- package/tests/RevokeWarningMessage.test.tsx +0 -151
- package/tests/consentClient.test.ts +0 -217
- package/tests/manageConsentServer.test.ts +0 -38
- package/tests/mocks.ts +0 -257
- package/tests/resolveContactFromJwt.test.ts +0 -44
- package/tests/setup.ts +0 -16
- package/tsconfig.json +0 -16
- package/tsup.config.ts +0 -31
- package/vitest.config.ts +0 -16
|
@@ -1,156 +0,0 @@
|
|
|
1
|
-
import { useState, useEffect, useMemo } from 'react';
|
|
2
|
-
import { useTranslation } from 'react-i18next';
|
|
3
|
-
import { IoArrowBack } from 'react-icons/io5';
|
|
4
|
-
import { PCButton, PCBadge, PCLoader } from './ui';
|
|
5
|
-
import { useInternalNavigation } from './context/NavigationContext';
|
|
6
|
-
import { formatDate } from './components/utils';
|
|
7
|
-
import type { CaseDetailsTab, TabId } from './lib/types';
|
|
8
|
-
import { getCaseStatusVariant, formatCaseStatus } from './components/CaseDetails/utils';
|
|
9
|
-
import { MessagesTab } from './components/CaseDetails/MessagesTab';
|
|
10
|
-
import { RequestDetailsTab } from './components/CaseDetails/RequestDetailsTab';
|
|
11
|
-
import { useCaseHistory } from './lib/queries';
|
|
12
|
-
import { useOrganization } from './context/OrganizationContext';
|
|
13
|
-
import { useAuth } from './context/AuthContext';
|
|
14
|
-
|
|
15
|
-
// ─── Page shell ──────────────────────────────────────────────────────────────
|
|
16
|
-
|
|
17
|
-
export const PrivacyCenterCaseDetailsPage = () => {
|
|
18
|
-
const { t } = useTranslation();
|
|
19
|
-
const { navigateTo, selectedCase, setSelectedCase, pendingCaseUuid } = useInternalNavigation();
|
|
20
|
-
const [activeTab, setActiveTab] = useState<TabId>('request-details');
|
|
21
|
-
|
|
22
|
-
const { organization } = useOrganization();
|
|
23
|
-
const { accessToken, refreshToken, onError, updateTokens } = useAuth();
|
|
24
|
-
const organizationId = organization?.uuid;
|
|
25
|
-
const workspaceId = organization?.workspaces[0]?.uuid;
|
|
26
|
-
const contact = typeof window !== 'undefined' ? sessionStorage.getItem('email') || '' : '';
|
|
27
|
-
|
|
28
|
-
const authContext = useMemo(() => ({
|
|
29
|
-
accessToken, refreshToken, onError, updateTokens,
|
|
30
|
-
}), [accessToken, refreshToken, onError, updateTokens]);
|
|
31
|
-
|
|
32
|
-
// The target UUID comes from the in-memory case (normal navigation) or the
|
|
33
|
-
// persisted UUID (page-refresh). Always fetch so language changes re-hydrate
|
|
34
|
-
// selectedCase with fresh server-translated data.
|
|
35
|
-
const targetUuid = selectedCase?.uuid ?? pendingCaseUuid;
|
|
36
|
-
|
|
37
|
-
const { data: cases, isLoading } = useCaseHistory(
|
|
38
|
-
organizationId,
|
|
39
|
-
workspaceId,
|
|
40
|
-
contact,
|
|
41
|
-
authContext,
|
|
42
|
-
);
|
|
43
|
-
|
|
44
|
-
// Update selectedCase from fetched list (covers language-change re-hydration and page-refresh).
|
|
45
|
-
useEffect(() => {
|
|
46
|
-
if (!cases) return;
|
|
47
|
-
if (cases.length === 0) {
|
|
48
|
-
navigateTo('form');
|
|
49
|
-
return;
|
|
50
|
-
}
|
|
51
|
-
if (!targetUuid) return;
|
|
52
|
-
const found = cases.find((c) => c.uuid === targetUuid);
|
|
53
|
-
if (found) {
|
|
54
|
-
setSelectedCase(found);
|
|
55
|
-
} else {
|
|
56
|
-
navigateTo('form');
|
|
57
|
-
}
|
|
58
|
-
}, [cases, targetUuid, setSelectedCase, navigateTo]);
|
|
59
|
-
|
|
60
|
-
// If the query is disabled (missing org/workspace/contact), cases stays undefined
|
|
61
|
-
// and isLoading stays false — navigate away so the component does not stay blank.
|
|
62
|
-
useEffect(() => {
|
|
63
|
-
if (!targetUuid || isLoading || cases !== undefined) return;
|
|
64
|
-
if (!organizationId || !workspaceId || !contact) {
|
|
65
|
-
navigateTo('form');
|
|
66
|
-
}
|
|
67
|
-
}, [targetUuid, organizationId, workspaceId, contact, cases, isLoading, navigateTo]);
|
|
68
|
-
|
|
69
|
-
// Navigate away when there is no case and nothing to load — kept in an effect
|
|
70
|
-
// to avoid calling navigateTo during render.
|
|
71
|
-
useEffect(() => {
|
|
72
|
-
if (!selectedCase && !targetUuid && !isLoading) {
|
|
73
|
-
navigateTo('form');
|
|
74
|
-
}
|
|
75
|
-
}, [selectedCase, targetUuid, isLoading, navigateTo]);
|
|
76
|
-
|
|
77
|
-
if (!selectedCase) {
|
|
78
|
-
return isLoading ? (
|
|
79
|
-
<div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', minHeight: '200px' }}>
|
|
80
|
-
<PCLoader size="lg" />
|
|
81
|
-
</div>
|
|
82
|
-
) : null;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
const { request_details } = selectedCase;
|
|
86
|
-
const requestTypeLabel = selectedCase.request_type_display || selectedCase.request_type.replace('_', ' ');
|
|
87
|
-
const isDueDateOverdue = selectedCase.due_date && new Date(selectedCase.due_date) < new Date();
|
|
88
|
-
|
|
89
|
-
const tabs: CaseDetailsTab[] = [
|
|
90
|
-
{ id: 'request-details', label: t('requestDetails') },
|
|
91
|
-
{ id: 'messages', label: t('messages') },
|
|
92
|
-
];
|
|
93
|
-
|
|
94
|
-
return (
|
|
95
|
-
<div className="pc-case-page">
|
|
96
|
-
{/* Back */}
|
|
97
|
-
<div className="pc-case-back">
|
|
98
|
-
<PCButton
|
|
99
|
-
variant="text"
|
|
100
|
-
size="sm"
|
|
101
|
-
onClick={() => navigateTo('form')}
|
|
102
|
-
className="pc-case-back-btn"
|
|
103
|
-
>
|
|
104
|
-
<IoArrowBack size={16} className="pc-case-back-icon" />
|
|
105
|
-
{t('backToHome')}
|
|
106
|
-
</PCButton>
|
|
107
|
-
</div>
|
|
108
|
-
|
|
109
|
-
{/* Case header */}
|
|
110
|
-
<div className="pc-case-header">
|
|
111
|
-
<span className="pc-case-header-id">
|
|
112
|
-
{selectedCase.case_id}
|
|
113
|
-
</span>
|
|
114
|
-
<span>·</span>
|
|
115
|
-
<span>{requestTypeLabel}</span>
|
|
116
|
-
<span>·</span>
|
|
117
|
-
<span>{t('submitted')} {formatDate(selectedCase.created_at)}</span>
|
|
118
|
-
{selectedCase.due_date && (
|
|
119
|
-
<>
|
|
120
|
-
<span>·</span>
|
|
121
|
-
<span className={isDueDateOverdue ? 'pc-case-header-overdue' : undefined}>
|
|
122
|
-
{t('responseDue')} {formatDate(selectedCase.due_date)}
|
|
123
|
-
</span>
|
|
124
|
-
</>
|
|
125
|
-
)}
|
|
126
|
-
<span>·</span>
|
|
127
|
-
<PCBadge variant={getCaseStatusVariant(selectedCase.status)} size="sm" className="pc-status-badge">
|
|
128
|
-
{selectedCase.status_display || formatCaseStatus(selectedCase.status)}
|
|
129
|
-
</PCBadge>
|
|
130
|
-
</div>
|
|
131
|
-
|
|
132
|
-
{/* Tabs */}
|
|
133
|
-
<div className="pc-case-tabs">
|
|
134
|
-
{tabs.map((tab) => (
|
|
135
|
-
<button
|
|
136
|
-
key={tab.id}
|
|
137
|
-
onClick={() => setActiveTab(tab.id)}
|
|
138
|
-
className={`pc-case-tab ${activeTab === tab.id ? 'pc-case-tab--active' : ''}`}
|
|
139
|
-
>
|
|
140
|
-
{tab.label}
|
|
141
|
-
</button>
|
|
142
|
-
))}
|
|
143
|
-
</div>
|
|
144
|
-
|
|
145
|
-
{/* Tab content */}
|
|
146
|
-
<div className="pc-case-tab-content">
|
|
147
|
-
{activeTab === 'messages' && (
|
|
148
|
-
<MessagesTab caseUuid={selectedCase.uuid} caseStatus={selectedCase.status} />
|
|
149
|
-
)}
|
|
150
|
-
{activeTab === 'request-details' && (
|
|
151
|
-
<RequestDetailsTab selectedCase={selectedCase} request_details={request_details} requestTypeLabel={requestTypeLabel} />
|
|
152
|
-
)}
|
|
153
|
-
</div>
|
|
154
|
-
</div>
|
|
155
|
-
);
|
|
156
|
-
};
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { useEffect } from 'react';
|
|
2
|
-
import i18n from './lib/i18n';
|
|
3
|
-
import ConsentManager from './components/ConsentManager';
|
|
4
|
-
|
|
5
|
-
export function PrivacyCenterConsentManagerPage() {
|
|
6
|
-
useEffect(() => {
|
|
7
|
-
if (!i18n.language) {
|
|
8
|
-
i18n.changeLanguage('en');
|
|
9
|
-
}
|
|
10
|
-
}, []);
|
|
11
|
-
|
|
12
|
-
return (
|
|
13
|
-
<div style={{ width: '100%' }}>
|
|
14
|
-
<ConsentManager />
|
|
15
|
-
</div>
|
|
16
|
-
);
|
|
17
|
-
}
|
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
import { useEffect, useState } from 'react';
|
|
2
|
-
import { useTranslation } from 'react-i18next';
|
|
3
|
-
import { PCButton } from './ui';
|
|
4
|
-
import { pcStyles } from './styles/pcStyles';
|
|
5
|
-
import { IoArrowBack } from 'react-icons/io5';
|
|
6
|
-
import i18n from './lib/i18n';
|
|
7
|
-
import Form from './components/Form';
|
|
8
|
-
import CaseHistory from './components/CaseHistory';
|
|
9
|
-
import { usePageChrome } from './context/PageChromeContext';
|
|
10
|
-
|
|
11
|
-
const getVar = (varName: string): string => `var(${varName})`;
|
|
12
|
-
|
|
13
|
-
export function PrivacyCenterFormPage() {
|
|
14
|
-
const { t } = useTranslation();
|
|
15
|
-
const [showForm, setShowForm] = useState(() => {
|
|
16
|
-
try {
|
|
17
|
-
return sessionStorage.getItem('pc_grievance_view') === 'form';
|
|
18
|
-
} catch {
|
|
19
|
-
return false;
|
|
20
|
-
}
|
|
21
|
-
});
|
|
22
|
-
const { setPageChromeOverride, clearPageChromeOverride } = usePageChrome();
|
|
23
|
-
|
|
24
|
-
useEffect(() => {
|
|
25
|
-
if (!i18n.language) {
|
|
26
|
-
i18n.changeLanguage('en');
|
|
27
|
-
}
|
|
28
|
-
}, []);
|
|
29
|
-
|
|
30
|
-
useEffect(() => {
|
|
31
|
-
try {
|
|
32
|
-
sessionStorage.setItem('pc_grievance_view', showForm ? 'form' : 'list');
|
|
33
|
-
} catch {
|
|
34
|
-
// sessionStorage unavailable
|
|
35
|
-
}
|
|
36
|
-
}, [showForm]);
|
|
37
|
-
|
|
38
|
-
useEffect(() => {
|
|
39
|
-
if (showForm) {
|
|
40
|
-
setPageChromeOverride({
|
|
41
|
-
titleKey: 'yourPrivacyCenter',
|
|
42
|
-
descriptionKey: 'yourRightsOverDataSimplified',
|
|
43
|
-
});
|
|
44
|
-
} else {
|
|
45
|
-
clearPageChromeOverride();
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
return () => {
|
|
49
|
-
clearPageChromeOverride();
|
|
50
|
-
};
|
|
51
|
-
}, [showForm, setPageChromeOverride, clearPageChromeOverride]);
|
|
52
|
-
|
|
53
|
-
return (
|
|
54
|
-
<div style={{ ...pcStyles.wFull, ...pcStyles.flex, ...pcStyles.flexCol, gap: pcStyles.gapLg.gap }}>
|
|
55
|
-
{showForm ? (
|
|
56
|
-
<>
|
|
57
|
-
<div style={pcStyles.mbMd}>
|
|
58
|
-
<PCButton
|
|
59
|
-
variant="text"
|
|
60
|
-
size="sm"
|
|
61
|
-
onClick={() => setShowForm(false)}
|
|
62
|
-
style={{ paddingLeft: 0, color: getVar('--pc-text-secondary') }}
|
|
63
|
-
>
|
|
64
|
-
<IoArrowBack size={16} style={{ marginRight: '0.5rem' }} />
|
|
65
|
-
{t('backToHome')}
|
|
66
|
-
</PCButton>
|
|
67
|
-
</div>
|
|
68
|
-
<div style={{ width: '100%' }}>
|
|
69
|
-
<Form onCreateRequest={() => setShowForm(false)} />
|
|
70
|
-
</div>
|
|
71
|
-
</>
|
|
72
|
-
) : (
|
|
73
|
-
<div style={{ width: '100%' }}>
|
|
74
|
-
<CaseHistory onCreateRequest={() => setShowForm(true)} />
|
|
75
|
-
</div>
|
|
76
|
-
)}
|
|
77
|
-
</div>
|
|
78
|
-
);
|
|
79
|
-
}
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import { useEffect } from 'react';
|
|
2
|
-
import i18n from './lib/i18n';
|
|
3
|
-
import { useInternalNavigation } from './context/NavigationContext';
|
|
4
|
-
import { PrivacyCenterConsentManagerPage } from './PrivacyCenterConsentManagerPage';
|
|
5
|
-
import { PrivacyCenterFormPage } from './PrivacyCenterFormPage';
|
|
6
|
-
import { PrivacyCenterActivityPage } from './PrivacyCenterActivityPage';
|
|
7
|
-
import { PrivacyCenterMyReceiptPage } from './PrivacyCenterMyReceiptPage';
|
|
8
|
-
import { PrivacyCenterCaseDetailsPage } from './PrivacyCenterCaseDetailsPage';
|
|
9
|
-
import { NotificationsPage } from './NotificationsPage';
|
|
10
|
-
|
|
11
|
-
export function PrivacyCenterHomePage() {
|
|
12
|
-
const { currentPage } = useInternalNavigation();
|
|
13
|
-
|
|
14
|
-
useEffect(() => {
|
|
15
|
-
if (!i18n.language) {
|
|
16
|
-
i18n.changeLanguage('en');
|
|
17
|
-
}
|
|
18
|
-
}, []);
|
|
19
|
-
|
|
20
|
-
switch (currentPage) {
|
|
21
|
-
case 'consent-manager':
|
|
22
|
-
return <PrivacyCenterConsentManagerPage />;
|
|
23
|
-
case 'form':
|
|
24
|
-
return <PrivacyCenterFormPage />;
|
|
25
|
-
case 'activity':
|
|
26
|
-
return <PrivacyCenterActivityPage />;
|
|
27
|
-
case 'receipts':
|
|
28
|
-
return <PrivacyCenterMyReceiptPage />;
|
|
29
|
-
case 'case-details':
|
|
30
|
-
return <PrivacyCenterCaseDetailsPage />;
|
|
31
|
-
case 'notifications':
|
|
32
|
-
return <NotificationsPage />;
|
|
33
|
-
default:
|
|
34
|
-
return <PrivacyCenterConsentManagerPage />;
|
|
35
|
-
}
|
|
36
|
-
}
|
|
@@ -1,177 +0,0 @@
|
|
|
1
|
-
import { useEffect, useState, useRef, type ReactNode } from 'react';
|
|
2
|
-
import { OrganizationProvider } from './context/OrganizationContext';
|
|
3
|
-
import { DataAvailabilityProvider } from './context/DataAvailabilityContext';
|
|
4
|
-
import type { OrganizationDetail } from './lib/types';
|
|
5
|
-
import {
|
|
6
|
-
checkAndRefreshAuth,
|
|
7
|
-
decodeJwtToken,
|
|
8
|
-
resolveContactFromJwt,
|
|
9
|
-
} from './lib/utils';
|
|
10
|
-
import { useBaseUrl } from './context/BaseUrlContext';
|
|
11
|
-
import { useAuth } from './context/AuthContext';
|
|
12
|
-
import { PCLoader } from './ui';
|
|
13
|
-
import { pcStyles } from './styles/pcStyles';
|
|
14
|
-
import AppShell from './components/AppShell/AppShell';
|
|
15
|
-
import { SelectUserGate } from './components/SelectUserGate';
|
|
16
|
-
|
|
17
|
-
interface PrivacyCenterLayoutProps {
|
|
18
|
-
children: ReactNode;
|
|
19
|
-
slug: string;
|
|
20
|
-
onBack?: 'back' | 'signout';
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export function PrivacyCenterLayout({ children, slug, onBack }: PrivacyCenterLayoutProps) {
|
|
24
|
-
const { consentClient } = useBaseUrl();
|
|
25
|
-
// Read accessToken from AuthContext so this effect re-runs after AuthProvider
|
|
26
|
-
// syncs JWT data to sessionStorage (fixes race condition where child effects
|
|
27
|
-
// run before parent effects in React)
|
|
28
|
-
const { accessToken: authAccessToken } = useAuth();
|
|
29
|
-
const [organization, setOrganization] = useState<OrganizationDetail | null>(null);
|
|
30
|
-
const [isCheckingAuth, setIsCheckingAuth] = useState(true);
|
|
31
|
-
const [isLoadingOrg, setIsLoadingOrg] = useState(true);
|
|
32
|
-
const hasRedirectedRef = useRef(false);
|
|
33
|
-
const authCheckInProgressRef = useRef(false);
|
|
34
|
-
|
|
35
|
-
useEffect(() => {
|
|
36
|
-
if (typeof window === 'undefined') return;
|
|
37
|
-
|
|
38
|
-
// Try sessionStorage first
|
|
39
|
-
let accessToken = sessionStorage.getItem('access_token');
|
|
40
|
-
let orgId = sessionStorage.getItem('pc_org_id');
|
|
41
|
-
let workspaceId = sessionStorage.getItem('pc_workspace_id');
|
|
42
|
-
let orgSlug = sessionStorage.getItem('pc_org_slug');
|
|
43
|
-
|
|
44
|
-
// If sessionStorage is not yet populated (race condition: AuthProvider's
|
|
45
|
-
// effect hasn't run yet), fall back to decoding the JWT from AuthContext
|
|
46
|
-
if (authAccessToken && (!accessToken || !orgId || !workspaceId || !orgSlug)) {
|
|
47
|
-
const decoded = decodeJwtToken(authAccessToken);
|
|
48
|
-
if (decoded) {
|
|
49
|
-
accessToken = accessToken || authAccessToken;
|
|
50
|
-
orgId = orgId || (typeof decoded.organisation_uuid === 'string' ? decoded.organisation_uuid : null);
|
|
51
|
-
workspaceId = workspaceId || (typeof decoded.workspace_uuid === 'string' ? decoded.workspace_uuid : null);
|
|
52
|
-
orgSlug = orgSlug || (typeof decoded.organisation_slug === 'string' ? decoded.organisation_slug : null);
|
|
53
|
-
|
|
54
|
-
// Write to sessionStorage so child components (SideBarPC, ConsentManager)
|
|
55
|
-
// can read these values when they mount
|
|
56
|
-
if (accessToken) sessionStorage.setItem('access_token', accessToken);
|
|
57
|
-
if (orgId) sessionStorage.setItem('pc_org_id', orgId);
|
|
58
|
-
if (workspaceId) sessionStorage.setItem('pc_workspace_id', workspaceId);
|
|
59
|
-
if (orgSlug) sessionStorage.setItem('pc_org_slug', orgSlug);
|
|
60
|
-
|
|
61
|
-
// Resolve the contact identifier (email, or mobile/org_user_id for
|
|
62
|
-
// mobile-only logins) for the sidebar and consent manager.
|
|
63
|
-
const contact = resolveContactFromJwt(decoded);
|
|
64
|
-
if (contact) {
|
|
65
|
-
sessionStorage.setItem('email', contact);
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
// Use slug prop if provided, otherwise fall back to JWT-derived slug
|
|
71
|
-
const effectiveSlug = slug || orgSlug || '';
|
|
72
|
-
|
|
73
|
-
if (accessToken && orgId && workspaceId && effectiveSlug) {
|
|
74
|
-
// Prefer organisation_name from JWT; fall back to slug-derived name
|
|
75
|
-
const decoded = decodeJwtToken(accessToken);
|
|
76
|
-
const orgNameFromJwt = decoded?.organisation_name;
|
|
77
|
-
const orgName =
|
|
78
|
-
typeof orgNameFromJwt === 'string' && orgNameFromJwt.trim() !== ''
|
|
79
|
-
? orgNameFromJwt
|
|
80
|
-
: effectiveSlug
|
|
81
|
-
.split('-')
|
|
82
|
-
.map((word: string) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())
|
|
83
|
-
.join(' ');
|
|
84
|
-
|
|
85
|
-
setOrganization({
|
|
86
|
-
uuid: orgId,
|
|
87
|
-
suid: '',
|
|
88
|
-
name: orgName,
|
|
89
|
-
slug: effectiveSlug,
|
|
90
|
-
description: '',
|
|
91
|
-
domain: '',
|
|
92
|
-
workspaces: [{
|
|
93
|
-
uuid: workspaceId,
|
|
94
|
-
suid: '',
|
|
95
|
-
name: '',
|
|
96
|
-
description: '',
|
|
97
|
-
workspace_type: '',
|
|
98
|
-
status: '',
|
|
99
|
-
}],
|
|
100
|
-
ai_summary: {},
|
|
101
|
-
icon_url: null,
|
|
102
|
-
activated: true,
|
|
103
|
-
allowed_domains: [],
|
|
104
|
-
});
|
|
105
|
-
setIsLoadingOrg(false);
|
|
106
|
-
} else {
|
|
107
|
-
// If organization info is not available, set loading to false
|
|
108
|
-
setIsLoadingOrg(false);
|
|
109
|
-
}
|
|
110
|
-
}, [slug, authAccessToken]);
|
|
111
|
-
|
|
112
|
-
useEffect(() => {
|
|
113
|
-
// Don't check auth while still loading organization
|
|
114
|
-
if (isLoadingOrg || !organization) {
|
|
115
|
-
return;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
// Prevent multiple simultaneous auth checks
|
|
119
|
-
if (authCheckInProgressRef.current) {
|
|
120
|
-
return;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
// Check authentication status with token refresh capability
|
|
124
|
-
const checkAuth = async () => {
|
|
125
|
-
authCheckInProgressRef.current = true;
|
|
126
|
-
|
|
127
|
-
try {
|
|
128
|
-
// Check if user is authenticated, attempt refresh if needed
|
|
129
|
-
await checkAndRefreshAuth(
|
|
130
|
-
organization.slug || slug,
|
|
131
|
-
organization?.uuid,
|
|
132
|
-
organization?.workspaces[0]?.uuid,
|
|
133
|
-
consentClient
|
|
134
|
-
);
|
|
135
|
-
|
|
136
|
-
// User is authenticated, allow access
|
|
137
|
-
hasRedirectedRef.current = false;
|
|
138
|
-
setIsCheckingAuth(false);
|
|
139
|
-
} catch (error) {
|
|
140
|
-
// Auth check failed - user will need to provide tokens via props
|
|
141
|
-
setIsCheckingAuth(false);
|
|
142
|
-
} finally {
|
|
143
|
-
authCheckInProgressRef.current = false;
|
|
144
|
-
}
|
|
145
|
-
};
|
|
146
|
-
|
|
147
|
-
// Check auth after organization is loaded
|
|
148
|
-
checkAuth();
|
|
149
|
-
}, [slug, organization, isLoadingOrg, consentClient, authAccessToken]);
|
|
150
|
-
|
|
151
|
-
// Show loading state while checking authentication or loading organization
|
|
152
|
-
if (isLoadingOrg || !organization || isCheckingAuth) {
|
|
153
|
-
return (
|
|
154
|
-
<div style={{
|
|
155
|
-
...pcStyles.flex,
|
|
156
|
-
...pcStyles.hScreen,
|
|
157
|
-
...pcStyles.wScreen,
|
|
158
|
-
...pcStyles.itemsCenter,
|
|
159
|
-
...pcStyles.justifyCenter,
|
|
160
|
-
}}>
|
|
161
|
-
<PCLoader variant="spinner" color="info" size="lg" />
|
|
162
|
-
</div>
|
|
163
|
-
);
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
return (
|
|
167
|
-
<OrganizationProvider organization={organization}>
|
|
168
|
-
<SelectUserGate>
|
|
169
|
-
<DataAvailabilityProvider>
|
|
170
|
-
<AppShell onBack={onBack}>
|
|
171
|
-
{children}
|
|
172
|
-
</AppShell>
|
|
173
|
-
</DataAvailabilityProvider>
|
|
174
|
-
</SelectUserGate>
|
|
175
|
-
</OrganizationProvider>
|
|
176
|
-
);
|
|
177
|
-
}
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import { useEffect } from 'react';
|
|
2
|
-
import i18n from './lib/i18n';
|
|
3
|
-
import ReceiptsList from './components/ReceiptsList';
|
|
4
|
-
|
|
5
|
-
export function PrivacyCenterMyReceiptPage() {
|
|
6
|
-
useEffect(() => {
|
|
7
|
-
if (!i18n.language) {
|
|
8
|
-
i18n.changeLanguage('en');
|
|
9
|
-
}
|
|
10
|
-
}, []);
|
|
11
|
-
|
|
12
|
-
return (
|
|
13
|
-
<div
|
|
14
|
-
style={{
|
|
15
|
-
width: '100%',
|
|
16
|
-
display: 'flex',
|
|
17
|
-
flexDirection: 'column',
|
|
18
|
-
gap: '0.5rem',
|
|
19
|
-
}}
|
|
20
|
-
>
|
|
21
|
-
<div style={{ paddingTop: '0.25rem' }}>
|
|
22
|
-
<ReceiptsList />
|
|
23
|
-
</div>
|
|
24
|
-
</div>
|
|
25
|
-
);
|
|
26
|
-
}
|
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
import { I18nextProvider } from 'react-i18next';
|
|
2
|
-
import i18n from './lib/i18n';
|
|
3
|
-
import { PrivacyCenterLayout } from './PrivacyCenterLayout';
|
|
4
|
-
import { PrivacyCenterHomePage } from './PrivacyCenterHomePage';
|
|
5
|
-
import { BaseUrlProvider } from './context/BaseUrlContext';
|
|
6
|
-
import { AuthProvider } from './context/AuthContext';
|
|
7
|
-
import { NavigationProvider } from './context/NavigationContext';
|
|
8
|
-
import type { InternalPage } from './context/NavigationContext';
|
|
9
|
-
import { PageChromeProvider } from './context/PageChromeContext';
|
|
10
|
-
import { BrandingProvider } from './context/BrandingContext';
|
|
11
|
-
import { injectPCStyles } from './styles/injectStyles';
|
|
12
|
-
|
|
13
|
-
// Inject Privacy Center CSS styles on module load
|
|
14
|
-
injectPCStyles();
|
|
15
|
-
|
|
16
|
-
interface RedactoPrivacyCenterProps {
|
|
17
|
-
baseUrl: string; // Consent server base URL
|
|
18
|
-
ledgerBaseUrl?: string; // Go ledger base URL — serves user-consents; omit to use the legacy Python privacy-center consent endpoints
|
|
19
|
-
slug: string;
|
|
20
|
-
/** JWT access token. Optional so sandbox mode (see `token`) can omit it. */
|
|
21
|
-
accessToken?: string;
|
|
22
|
-
/** JWT refresh token. Optional; used by the OTP-refresh loop in the JWT flow. */
|
|
23
|
-
refreshToken?: string;
|
|
24
|
-
/**
|
|
25
|
-
* Sandbox PoC: a pasted static token. When set, the Privacy Center runs
|
|
26
|
-
* against the sandbox with no JWT — it sends the single `X-Consent-Token`
|
|
27
|
-
* header, carries the acting identity (`email` || `mobile`) in each request's
|
|
28
|
-
* own payload, takes org/workspace from `organisationUuid`/`workspaceUuid`,
|
|
29
|
-
* and never calls `/otp/refresh`.
|
|
30
|
-
*/
|
|
31
|
-
token?: string;
|
|
32
|
-
/** Sandbox test subject email (carried in the request payload when set). */
|
|
33
|
-
email?: string;
|
|
34
|
-
/** Sandbox test subject mobile (fallback subject when `email` is absent). */
|
|
35
|
-
mobile?: string;
|
|
36
|
-
/**
|
|
37
|
-
* Sandbox UCIC: the client's own user id / org_user_id, e.g. a UUID or
|
|
38
|
-
* customer code; optional third identifier alongside email/mobile.
|
|
39
|
-
*/
|
|
40
|
-
ucic?: string;
|
|
41
|
-
/** Sandbox org UUID (replaces the JWT-decoded org in sandbox mode). */
|
|
42
|
-
organisationUuid?: string;
|
|
43
|
-
/** Sandbox workspace UUID (replaces the JWT-decoded workspace in sandbox mode). */
|
|
44
|
-
workspaceUuid?: string;
|
|
45
|
-
onError: (error: Error) => boolean;
|
|
46
|
-
initialPage?: InternalPage;
|
|
47
|
-
onBack?: 'back' | 'signout';
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
export function RedactoPrivacyCenter({
|
|
51
|
-
baseUrl,
|
|
52
|
-
ledgerBaseUrl,
|
|
53
|
-
slug,
|
|
54
|
-
accessToken,
|
|
55
|
-
refreshToken,
|
|
56
|
-
token,
|
|
57
|
-
email,
|
|
58
|
-
mobile,
|
|
59
|
-
ucic,
|
|
60
|
-
organisationUuid,
|
|
61
|
-
workspaceUuid,
|
|
62
|
-
onError,
|
|
63
|
-
initialPage = 'consent-manager',
|
|
64
|
-
onBack,
|
|
65
|
-
}: RedactoPrivacyCenterProps) {
|
|
66
|
-
return (
|
|
67
|
-
<I18nextProvider i18n={i18n}>
|
|
68
|
-
<BrandingProvider slug={slug} baseUrl={baseUrl}>
|
|
69
|
-
<BaseUrlProvider baseUrl={baseUrl} ledgerBaseUrl={ledgerBaseUrl}>
|
|
70
|
-
<AuthProvider
|
|
71
|
-
accessToken={accessToken}
|
|
72
|
-
refreshToken={refreshToken}
|
|
73
|
-
token={token}
|
|
74
|
-
sandboxUcic={ucic}
|
|
75
|
-
sandboxSubject={email || mobile}
|
|
76
|
-
organisationUuid={organisationUuid}
|
|
77
|
-
workspaceUuid={workspaceUuid}
|
|
78
|
-
slug={slug}
|
|
79
|
-
onError={onError}
|
|
80
|
-
>
|
|
81
|
-
<NavigationProvider initialPage={initialPage}>
|
|
82
|
-
<PageChromeProvider>
|
|
83
|
-
<PrivacyCenterLayout slug={slug} onBack={onBack}>
|
|
84
|
-
<PrivacyCenterHomePage />
|
|
85
|
-
</PrivacyCenterLayout>
|
|
86
|
-
</PageChromeProvider>
|
|
87
|
-
</NavigationProvider>
|
|
88
|
-
</AuthProvider>
|
|
89
|
-
</BaseUrlProvider>
|
|
90
|
-
</BrandingProvider>
|
|
91
|
-
</I18nextProvider>
|
|
92
|
-
);
|
|
93
|
-
}
|