@redacto.io/consent-sdk-react 5.3.0 → 6.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.
Files changed (57) hide show
  1. package/.turbo/turbo-build.log +24 -0
  2. package/CHANGELOG.md +6 -0
  3. package/dist/privacy-center.d.mts +98 -38
  4. package/dist/privacy-center.d.ts +98 -38
  5. package/dist/privacy-center.js +3679 -1491
  6. package/dist/privacy-center.mjs +3614 -1423
  7. package/package.json +1 -1
  8. package/src/RedactoPrivacyCenter/api/actions.ts +52 -8
  9. package/src/RedactoPrivacyCenter/api/client.ts +58 -15
  10. package/src/RedactoPrivacyCenter/components/ConsentManager.tsx +722 -273
  11. package/src/RedactoPrivacyCenter/components/ConsentManagerCells.tsx +187 -0
  12. package/src/RedactoPrivacyCenter/components/ConsentManagerColumns.tsx +65 -165
  13. package/src/RedactoPrivacyCenter/components/ConsentManagerExpandedRow.tsx +179 -0
  14. package/src/RedactoPrivacyCenter/components/ConsentManagerGroupedColumns.tsx +318 -0
  15. package/src/RedactoPrivacyCenter/components/ConsentManagerProductCards.tsx +333 -0
  16. package/src/RedactoPrivacyCenter/components/ConsentManagerPurposeCards.tsx +102 -0
  17. package/src/RedactoPrivacyCenter/components/ConsentManagerTableSkeleton.tsx +6 -2
  18. package/src/RedactoPrivacyCenter/components/ModifyConsentModal.tsx +8 -5
  19. package/src/RedactoPrivacyCenter/components/NotificationHub/NotificationBell.tsx +1 -1
  20. package/src/RedactoPrivacyCenter/components/PrivacyCenterLayout.tsx +102 -53
  21. package/src/RedactoPrivacyCenter/components/types.ts +2 -5
  22. package/src/RedactoPrivacyCenter/context/PageChromeContext.tsx +21 -1
  23. package/src/RedactoPrivacyCenter/lib/api.ts +70 -28
  24. package/src/RedactoPrivacyCenter/lib/consent-manager/utils.tsx +4 -2
  25. package/src/RedactoPrivacyCenter/lib/types.ts +57 -36
  26. package/src/RedactoPrivacyCenter/locales/as/translation.json +12 -1
  27. package/src/RedactoPrivacyCenter/locales/bho/translation.json +12 -1
  28. package/src/RedactoPrivacyCenter/locales/bn/translation.json +12 -1
  29. package/src/RedactoPrivacyCenter/locales/brx/translation.json +12 -1
  30. package/src/RedactoPrivacyCenter/locales/doi/translation.json +12 -1
  31. package/src/RedactoPrivacyCenter/locales/en/translation.json +16 -1
  32. package/src/RedactoPrivacyCenter/locales/gom/translation.json +12 -1
  33. package/src/RedactoPrivacyCenter/locales/gu/translation.json +12 -1
  34. package/src/RedactoPrivacyCenter/locales/hi/translation.json +15 -1
  35. package/src/RedactoPrivacyCenter/locales/kn/translation.json +12 -1
  36. package/src/RedactoPrivacyCenter/locales/ks/translation.json +12 -1
  37. package/src/RedactoPrivacyCenter/locales/mai/translation.json +12 -1
  38. package/src/RedactoPrivacyCenter/locales/ml/translation.json +12 -1
  39. package/src/RedactoPrivacyCenter/locales/mni-Mtei/translation.json +12 -1
  40. package/src/RedactoPrivacyCenter/locales/mr/translation.json +12 -1
  41. package/src/RedactoPrivacyCenter/locales/ne/translation.json +12 -1
  42. package/src/RedactoPrivacyCenter/locales/or/translation.json +12 -1
  43. package/src/RedactoPrivacyCenter/locales/pa/translation.json +12 -1
  44. package/src/RedactoPrivacyCenter/locales/sa/translation.json +12 -1
  45. package/src/RedactoPrivacyCenter/locales/sat/translation.json +12 -1
  46. package/src/RedactoPrivacyCenter/locales/sd/translation.json +12 -1
  47. package/src/RedactoPrivacyCenter/locales/ta/translation.json +12 -1
  48. package/src/RedactoPrivacyCenter/locales/te/translation.json +12 -1
  49. package/src/RedactoPrivacyCenter/locales/ur/translation.json +12 -1
  50. package/src/RedactoPrivacyCenter/styles/injectStyles.ts +527 -5
  51. package/src/RedactoPrivacyCenter/styles/variables.css +5 -0
  52. package/src/RedactoPrivacyCenter/table/AdvancedTable.tsx +36 -16
  53. package/src/RedactoPrivacyCenter/table/AdvancedTablePagination.tsx +4 -12
  54. package/src/RedactoPrivacyCenter/ui/PCInput.tsx +1 -1
  55. package/src/RedactoPrivacyCenter/ui/PCSelect.tsx +51 -5
  56. package/src/RedactoPrivacyCenter/ui/ThemeToggle.tsx +2 -4
  57. package/src/privacy-center.ts +7 -3
@@ -0,0 +1,102 @@
1
+ import { useTranslation } from 'react-i18next';
2
+ import { PCEmpty, PCText } from '../ui';
3
+ import type { ConsentModalRecord, DisplayPurposeRow } from '../lib/types';
4
+ import {
5
+ renderGivenDate,
6
+ renderMethod,
7
+ renderModifyButton,
8
+ renderStatusBadge,
9
+ renderValidTill,
10
+ } from './ConsentManagerCells';
11
+
12
+ type ConsentManagerPurposeCardsProps = {
13
+ rows: DisplayPurposeRow[];
14
+ onModify: (record: ConsentModalRecord) => void;
15
+ };
16
+
17
+ const toModalRecord = (row: DisplayPurposeRow): ConsentModalRecord => ({
18
+ ...row,
19
+ });
20
+
21
+ export function ConsentManagerPurposeCards({
22
+ rows,
23
+ onModify,
24
+ }: ConsentManagerPurposeCardsProps) {
25
+ const { t } = useTranslation();
26
+
27
+ if (rows.length === 0) {
28
+ return (
29
+ <div className="pc-consent-mobile-empty">
30
+ <PCEmpty title={t('noData')} />
31
+ </div>
32
+ );
33
+ }
34
+
35
+ return (
36
+ <div className="pc-consent-mobile-list">
37
+ {rows.map((row) => (
38
+ <article
39
+ key={`${row.product_uuid}:${row.purpose_uuid}`}
40
+ className="pc-consent-mobile-card"
41
+ >
42
+ <div className="pc-consent-mobile-purpose-head">
43
+ <div style={{ minWidth: 0 }}>
44
+ <PCText size="sm" weight="semibold">{row.name}</PCText>
45
+ {row.description && (
46
+ <PCText size="sm" color="secondary" className="pc-consent-mobile-subtle-text">
47
+ {row.description}
48
+ </PCText>
49
+ )}
50
+ </div>
51
+ {renderStatusBadge(row.status, t)}
52
+ </div>
53
+
54
+ <div className="pc-consent-mobile-activity-row">
55
+ <PCText size="sm" color="secondary" className="pc-consent-mobile-meta-label">
56
+ {t('product')}
57
+ </PCText>
58
+ <PCText size="sm" weight="medium">{row.product_name || '-'}</PCText>
59
+ </div>
60
+
61
+ {row.nominator && (
62
+ <div className="pc-consent-mobile-activity-row">
63
+ <PCText size="sm" color="secondary" className="pc-consent-mobile-meta-label">
64
+ {t('nominatedBy')}
65
+ </PCText>
66
+ <PCText size="sm" weight="medium">
67
+ {row.nominator.name || row.nominator.email || row.nominator.org_user_id}
68
+ </PCText>
69
+ </div>
70
+ )}
71
+
72
+ <div className="pc-consent-mobile-meta-grid">
73
+ <div>
74
+ <PCText size="sm" color="secondary" className="pc-consent-mobile-meta-label">
75
+ {t('givenDate')}
76
+ </PCText>
77
+ {renderGivenDate(row.given_date, { showTooltip: false })}
78
+ </div>
79
+ <div>
80
+ <PCText size="sm" color="secondary" className="pc-consent-mobile-meta-label">
81
+ {t('validTill')}
82
+ </PCText>
83
+ {renderValidTill(row, t)}
84
+ </div>
85
+ <div>
86
+ <PCText size="sm" color="secondary" className="pc-consent-mobile-meta-label">
87
+ {t('method')}
88
+ </PCText>
89
+ {renderMethod(row.method)}
90
+ </div>
91
+ <div className="pc-consent-mobile-action-cell">
92
+ <PCText size="sm" color="secondary" className="pc-consent-mobile-meta-label">
93
+ {t('action')}
94
+ </PCText>
95
+ {renderModifyButton(toModalRecord(row), onModify, t)}
96
+ </div>
97
+ </div>
98
+ </article>
99
+ ))}
100
+ </div>
101
+ );
102
+ }
@@ -6,8 +6,9 @@ const getVar = (varName: string): string => `var(${varName})`;
6
6
  export const ConsentManagerTableSkeleton = () => {
7
7
  return (
8
8
  <div style={{
9
- borderRadius: getVar('--pc-border-radius-md'),
9
+ borderRadius: `${getVar('--pc-border-radius-lg')} ${getVar('--pc-border-radius-lg')} 0 0`,
10
10
  border: `1px solid ${getVar('--pc-border-color')}`,
11
+ borderBottom: 'none',
11
12
  backgroundColor: getVar('--pc-bg-primary'),
12
13
  }}>
13
14
  {/* Table Header */}
@@ -44,7 +45,10 @@ export const ConsentManagerTableSkeleton = () => {
44
45
  <div
45
46
  key={index}
46
47
  style={{
47
- borderBottom: `1px solid ${getVar('--pc-border-color')}`,
48
+ borderBottom:
49
+ index === SKELETON_ROW_COUNT - 1
50
+ ? 'none'
51
+ : `1px solid ${getVar('--pc-border-color')}`,
48
52
  backgroundColor: getVar('--pc-bg-primary'),
49
53
  }}
50
54
  >
@@ -19,7 +19,7 @@ export const ModifyConsentModal = ({
19
19
  const [isAccordionOpen, setIsAccordionOpen] = useState(false);
20
20
  const [selectedDataElementUuids, setSelectedDataElementUuids] = useState<string[]>([]);
21
21
 
22
- const nominatorInfo = selectedRecord?.nominator_info;
22
+ const nominatorInfo = selectedRecord?.nominator;
23
23
  const nominatorLabel = nominatorInfo?.name || nominatorInfo?.email || nominatorInfo?.org_user_id || null;
24
24
 
25
25
  const actionConfig = useMemo(() => {
@@ -39,7 +39,10 @@ export const ModifyConsentModal = ({
39
39
  };
40
40
  }
41
41
 
42
- if (status === ConsentStatusEnum.WITHDRAWN) {
42
+ if (
43
+ status === ConsentStatusEnum.WITHDRAWN ||
44
+ status === ConsentStatusEnum.REVOKED
45
+ ) {
43
46
  return {
44
47
  action: 'regrant' as ConsentAction,
45
48
  buttonLabel: t('regrantConsent'),
@@ -158,7 +161,7 @@ export const ModifyConsentModal = ({
158
161
  fontWeight: pcStyles.fontWeightSemibold.fontWeight,
159
162
  color: pcStyles.textPrimary.color,
160
163
  }}>
161
- {selectedRecord.purpose}
164
+ {selectedRecord.name}
162
165
  </p>
163
166
  <p style={{
164
167
  textAlign: 'left',
@@ -167,7 +170,7 @@ export const ModifyConsentModal = ({
167
170
  color: pcStyles.textSecondary.color,
168
171
  margin: 0,
169
172
  }}>
170
- {selectedRecord.purpose_description}
173
+ {selectedRecord.description}
171
174
  </p>
172
175
  </div>
173
176
  <ChevronDownIcon
@@ -309,7 +312,7 @@ export const ModifyConsentModal = ({
309
312
  variant={actionConfig.buttonVariant}
310
313
  onClick={() => {
311
314
  if (selectedRecord.purpose_uuid) {
312
- const nomContact = selectedRecord.nominator_info?.email || selectedRecord.nominator_info?.org_user_id || undefined;
315
+ const nomContact = selectedRecord.nominator?.email || selectedRecord.nominator?.org_user_id || undefined;
313
316
  onManageConsent(
314
317
  selectedRecord.purpose_uuid,
315
318
  actionConfig.action,
@@ -148,7 +148,7 @@ export const NotificationBell = () => {
148
148
  <PCTooltip content={t('notifications')} placement="bottom" color="invert">
149
149
  <div className="pc-notification-bell-wrapper">
150
150
  <button type="button" aria-label={t('notifications')} className="pc-notification-bell-btn">
151
- <IoNotificationsOutline size={20} />
151
+ <IoNotificationsOutline size={18} />
152
152
  </button>
153
153
  {unreadCount > 0 && (
154
154
  <span className="pc-notification-badge">{unreadCount}</span>
@@ -14,6 +14,7 @@ import { pcStyles } from '../styles/pcStyles';
14
14
  import type { PrivacyCenterLayoutProps } from './types';
15
15
  import { NotificationBell } from './NotificationHub/NotificationBell';
16
16
  import { getVar } from '../lib/utils';
17
+ import { Globe2 } from 'lucide-react';
17
18
 
18
19
  export default function PrivacyCenterLayout({
19
20
  children,
@@ -23,7 +24,7 @@ export default function PrivacyCenterLayout({
23
24
  }: PrivacyCenterLayoutProps) {
24
25
  const { t } = useTranslation();
25
26
  const { currentPage } = useInternalNavigation();
26
- const { pageChromeOverride } = usePageChrome();
27
+ const { pageChromeOverride, headerStatus } = usePageChrome();
27
28
  const [locale, setLocale] = useState(i18n.language);
28
29
  const pageChrome = pageChromeOverride ?? PAGE_CHROME_BY_PAGE[currentPage];
29
30
 
@@ -59,12 +60,11 @@ export default function PrivacyCenterLayout({
59
60
  flex: 1,
60
61
  minWidth: 0,
61
62
  backgroundColor: getVar('--pc-bg-shell'),
63
+ minHeight: 0,
62
64
  }} className="pc-content-wrapper">
63
65
  {/* Top Navbar with Theme Toggle */}
64
66
  <nav style={{
65
- position: 'fixed',
66
- top: 0,
67
- zIndex: 50,
67
+ position: 'relative',
68
68
  ...pcStyles.flex,
69
69
  ...pcStyles.itemsCenter,
70
70
  ...pcStyles.justifyBetween,
@@ -74,8 +74,8 @@ export default function PrivacyCenterLayout({
74
74
  paddingRight: 'var(--pc-navbar-padding-right, 0.75rem)',
75
75
  paddingTop: 'var(--pc-navbar-padding-top, 0.625rem)',
76
76
  paddingBottom: 'var(--pc-navbar-padding-bottom, 0.625rem)',
77
- transition: 'background-color 0.3s ease, border-color 0.3s ease, width 0.3s ease, left 0.3s ease',
78
- willChange: 'background-color, border-color, width, left',
77
+ transition: 'background-color 0.3s ease, border-color 0.3s ease',
78
+ willChange: 'background-color, border-color',
79
79
  }} className="pc-navbar">
80
80
  <div
81
81
  className="pc-navbar-page-meta"
@@ -85,32 +85,76 @@ export default function PrivacyCenterLayout({
85
85
  justifyContent: 'center',
86
86
  minWidth: 0,
87
87
  flex: 1,
88
- gap: '0.125rem',
88
+ gap: '0.1875rem',
89
89
  }}
90
90
  >
91
- <p
92
- className="pc-navbar-title"
93
- style={{
94
- margin: 0,
95
- color: getVar('--pc-text-primary'),
96
- fontSize: '1rem',
97
- fontWeight: 600,
98
- lineHeight: 1.3,
99
- whiteSpace: 'nowrap',
100
- overflow: 'hidden',
101
- textOverflow: 'ellipsis',
102
- }}
103
- >
104
- {t(pageChrome.titleKey)}
105
- </p>
91
+ <div style={{ display: 'flex', alignItems: 'center', gap: '0.625rem', minWidth: 0 }}>
92
+ <p
93
+ className="pc-navbar-title"
94
+ style={{
95
+ margin: 0,
96
+ color: getVar('--pc-text-primary'),
97
+ fontSize: '1.0625rem',
98
+ fontWeight: 700,
99
+ lineHeight: 1.2,
100
+ whiteSpace: 'nowrap',
101
+ overflow: 'hidden',
102
+ textOverflow: 'ellipsis',
103
+ }}
104
+ >
105
+ {t(pageChrome.titleKey)}
106
+ </p>
107
+ {headerStatus && (
108
+ <span
109
+ style={{
110
+ display: 'inline-flex',
111
+ alignItems: 'center',
112
+ flexShrink: 0,
113
+ borderRadius: '9999px',
114
+ gap: '0.375rem',
115
+ padding: '0.25rem 0.75rem',
116
+ fontSize: '0.625rem',
117
+ fontWeight: 600,
118
+ lineHeight: 1.2,
119
+ border: `1px solid ${
120
+ headerStatus.variant === 'success'
121
+ ? 'rgba(16, 185, 129, 0.35)'
122
+ : 'rgba(245, 158, 11, 0.35)'
123
+ }`,
124
+ backgroundColor:
125
+ headerStatus.variant === 'success'
126
+ ? 'rgba(16, 185, 129, 0.1)'
127
+ : '#fff7ed',
128
+ color:
129
+ headerStatus.variant === 'success'
130
+ ? getVar('--pc-success')
131
+ : '#d97706',
132
+ }}
133
+ >
134
+ <span
135
+ aria-hidden="true"
136
+ style={{
137
+ width: '0.4375rem',
138
+ height: '0.4375rem',
139
+ borderRadius: '9999px',
140
+ backgroundColor:
141
+ headerStatus.variant === 'success'
142
+ ? getVar('--pc-success')
143
+ : '#d97706',
144
+ }}
145
+ />
146
+ {headerStatus.label}
147
+ </span>
148
+ )}
149
+ </div>
106
150
  {pageChrome.descriptionKey && (
107
151
  <p
108
152
  className="pc-navbar-description"
109
153
  style={{
110
154
  margin: 0,
111
155
  color: getVar('--pc-text-secondary'),
112
- fontSize: '0.8125rem',
113
- lineHeight: 1.35,
156
+ fontSize: '0.75rem',
157
+ lineHeight: 1.2,
114
158
  whiteSpace: 'nowrap',
115
159
  overflow: 'hidden',
116
160
  textOverflow: 'ellipsis',
@@ -123,18 +167,20 @@ export default function PrivacyCenterLayout({
123
167
  <div style={{
124
168
  display: 'flex',
125
169
  alignItems: 'center',
126
- gap: '0.5rem',
170
+ gap: '0.375rem',
127
171
  flexShrink: 0,
128
172
  }} className="pc-navbar-actions">
129
173
  <PCSelect
174
+ className="pc-navbar-language-select"
130
175
  size="sm"
131
176
  searchable
177
+ prefix={<Globe2 size={12} strokeWidth={1.8} />}
132
178
  searchPlaceholder={t('searchPlaceholder')}
133
179
  noOptionsMessage={t('noOptionsFound')}
134
180
  style={{
135
181
  width: 'auto',
136
- minWidth: '92px',
137
- maxWidth: '136px',
182
+ minWidth: '120px',
183
+ maxWidth: 'min(65vw, 320px)',
138
184
  flexShrink: 0,
139
185
  }}
140
186
  options={languageOptions}
@@ -142,34 +188,36 @@ export default function PrivacyCenterLayout({
142
188
  onChange={handleLanguageChange}
143
189
  />
144
190
  <NotificationBell />
145
- <ThemeToggle />
191
+ <ThemeToggle className="pc-navbar-icon-btn" />
146
192
  </div>
147
193
  </nav>
148
194
  <div style={{
149
195
  ...pcStyles.flex,
150
196
  ...pcStyles.flexCol,
151
- flexGrow: 1,
197
+ flex: 1,
198
+ minHeight: 0,
152
199
  paddingLeft: 'var(--pc-content-padding-left, 0.75rem)',
153
200
  paddingRight: 'var(--pc-content-padding-right, 0.75rem)',
154
- paddingTop: 'var(--pc-content-padding-top, 4rem)',
201
+ paddingTop: 'var(--pc-content-padding-top, 0)',
155
202
  minWidth: 0,
156
203
  backgroundColor: getVar('--pc-bg-shell'),
157
204
  }} className="pc-content-container">
158
205
  <div style={{
159
- minHeight: '100vh',
206
+ display: 'flex',
207
+ flexDirection: 'column',
208
+ flex: 1,
209
+ minHeight: 0,
160
210
  width: '100%',
161
211
  }}>
162
212
  <div style={{
163
213
  ...pcStyles.flex,
164
214
  ...pcStyles.flexCol,
165
- height: '100%',
166
- minHeight: '100vh',
215
+ flex: 1,
216
+ minHeight: 0,
167
217
  ...pcStyles.justifyBetween,
168
- ...pcStyles.gapMd,
169
- paddingLeft: '0.5rem',
170
- paddingRight: '0.5rem',
171
- paddingTop: '1rem',
172
- paddingBottom: '1rem',
218
+ ...pcStyles.gapSm,
219
+ paddingTop: '0.625rem',
220
+ paddingBottom: '0.75rem',
173
221
  }}>
174
222
  <div className={contentClassName} style={{ width: '100%' }}>{children}</div>
175
223
  <div style={{
@@ -199,17 +247,14 @@ export default function PrivacyCenterLayout({
199
247
  .pc-navbar {
200
248
  --pc-navbar-padding-left: 0.75rem;
201
249
  --pc-navbar-padding-right: 0.75rem;
202
- --pc-navbar-padding-top: 0.625rem;
203
- --pc-navbar-padding-bottom: 0.625rem;
204
- left: var(--pc-sidebar-offset) !important;
205
- width: calc(100% - var(--pc-sidebar-offset)) !important;
206
- transition: left 0.3s ease, width 0.3s ease !important;
250
+ --pc-navbar-padding-top: 0.875rem;
251
+ --pc-navbar-padding-bottom: 0.75rem;
207
252
  }
208
253
 
209
254
  .pc-content-container {
210
255
  --pc-content-padding-left: 0.75rem;
211
256
  --pc-content-padding-right: 0.75rem;
212
- --pc-content-padding-top: 4rem;
257
+ --pc-content-padding-top: 0;
213
258
  }
214
259
 
215
260
  .pc-navbar-page-meta {
@@ -247,7 +292,7 @@ export default function PrivacyCenterLayout({
247
292
  .pc-navbar {
248
293
  --pc-navbar-padding-left: 3.75rem;
249
294
  --pc-navbar-padding-right: 0.75rem;
250
- --pc-navbar-padding-top: 0.625rem;
295
+ --pc-navbar-padding-top: 0.75rem;
251
296
  --pc-navbar-padding-bottom: 0.625rem;
252
297
  }
253
298
  .pc-navbar-description {
@@ -261,21 +306,21 @@ export default function PrivacyCenterLayout({
261
306
  gap: 0.375rem;
262
307
  }
263
308
  .pc-content-container {
264
- --pc-content-padding-top: 4rem;
309
+ --pc-content-padding-top: 0;
265
310
  }
266
311
  }
267
312
  @media (min-width: 768px) {
268
313
  .pc-navbar {
269
- --pc-navbar-padding-left: 1rem;
270
- --pc-navbar-padding-right: 1rem;
271
- --pc-navbar-padding-top: 0.75rem;
314
+ --pc-navbar-padding-left: 1.25rem;
315
+ --pc-navbar-padding-right: 1.25rem;
316
+ --pc-navbar-padding-top: 0.875rem;
272
317
  --pc-navbar-padding-bottom: 0.75rem;
273
318
  }
274
319
  .pc-navbar-description {
275
320
  display: block;
276
321
  }
277
322
  .pc-content-container {
278
- --pc-content-padding-top: 4.5rem;
323
+ --pc-content-padding-top: 0;
279
324
  }
280
325
  }
281
326
  @media (min-width: 768px) {
@@ -283,19 +328,23 @@ export default function PrivacyCenterLayout({
283
328
  font-size: 1.0625rem;
284
329
  }
285
330
  .pc-navbar-description {
286
- font-size: 0.8125rem;
331
+ font-size: 0.6875rem;
287
332
  }
288
333
  .pc-content-container {
289
334
  --pc-content-padding-left: 1.25rem;
290
335
  --pc-content-padding-right: 1.25rem;
291
- --pc-content-padding-top: 4.5rem;
336
+ --pc-content-padding-top: 0;
292
337
  }
293
338
  }
294
339
  @media (min-width: 1024px) {
340
+ .pc-navbar {
341
+ --pc-navbar-padding-left: 1.5rem;
342
+ --pc-navbar-padding-right: 1.5rem;
343
+ }
295
344
  .pc-content-container {
296
345
  --pc-content-padding-left: 1.5rem;
297
346
  --pc-content-padding-right: 1.5rem;
298
- --pc-content-padding-top: 4.75rem;
347
+ --pc-content-padding-top: 0;
299
348
  }
300
349
  }
301
350
  `}</style>
@@ -1,5 +1,5 @@
1
1
  import type { ReactNode } from 'react';
2
- import type { CaseRequest, UserConsent } from '../lib/types';
2
+ import type { CaseRequest, ConsentModalRecord } from '../lib/types';
3
3
 
4
4
  export type TableColumnAlign = 'left' | 'center' | 'right';
5
5
 
@@ -61,7 +61,7 @@ export type ConsentManagerProps = {
61
61
  export type ModifyConsentModalProps = {
62
62
  isOpen: boolean;
63
63
  onClose: () => void;
64
- selectedRecord: UserConsent | null;
64
+ selectedRecord: ConsentModalRecord | null;
65
65
  isLoading: boolean;
66
66
  onManageConsent: (
67
67
  purposeId: string,
@@ -71,6 +71,3 @@ export type ModifyConsentModalProps = {
71
71
  ) => void;
72
72
  };
73
73
 
74
- export type UseConsentManagerColumnsProps = {
75
- onOpenModal: (record: UserConsent) => void;
76
- };
@@ -12,10 +12,17 @@ export type PageChromeOverride = {
12
12
  descriptionKey?: string;
13
13
  };
14
14
 
15
+ export type PageHeaderStatus = {
16
+ label: string;
17
+ variant: 'success' | 'warning';
18
+ };
19
+
15
20
  type PageChromeContextValue = {
16
21
  pageChromeOverride: PageChromeOverride | null;
17
22
  setPageChromeOverride: (override: PageChromeOverride | null) => void;
18
23
  clearPageChromeOverride: () => void;
24
+ headerStatus: PageHeaderStatus | null;
25
+ setHeaderStatus: (status: PageHeaderStatus | null) => void;
19
26
  };
20
27
 
21
28
  const PageChromeContext = createContext<PageChromeContextValue | null>(null);
@@ -23,6 +30,7 @@ const PageChromeContext = createContext<PageChromeContextValue | null>(null);
23
30
  export function PageChromeProvider({ children }: { children: ReactNode }) {
24
31
  const [pageChromeOverride, setPageChromeOverrideState] =
25
32
  useState<PageChromeOverride | null>(null);
33
+ const [headerStatus, setHeaderStatusState] = useState<PageHeaderStatus | null>(null);
26
34
 
27
35
  const setPageChromeOverride = useCallback(
28
36
  (override: PageChromeOverride | null) => {
@@ -35,13 +43,25 @@ export function PageChromeProvider({ children }: { children: ReactNode }) {
35
43
  setPageChromeOverrideState(null);
36
44
  }, []);
37
45
 
46
+ const setHeaderStatus = useCallback((status: PageHeaderStatus | null) => {
47
+ setHeaderStatusState(status);
48
+ }, []);
49
+
38
50
  const value = useMemo(
39
51
  () => ({
40
52
  pageChromeOverride,
41
53
  setPageChromeOverride,
42
54
  clearPageChromeOverride,
55
+ headerStatus,
56
+ setHeaderStatus,
43
57
  }),
44
- [pageChromeOverride, setPageChromeOverride, clearPageChromeOverride]
58
+ [
59
+ pageChromeOverride,
60
+ setPageChromeOverride,
61
+ clearPageChromeOverride,
62
+ headerStatus,
63
+ setHeaderStatus,
64
+ ]
45
65
  );
46
66
 
47
67
  return (