@redacto.io/consent-sdk-react-native 5.0.0-beta.8 → 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.
@@ -11968,6 +11968,18 @@ var decodeJwtToken = (token) => {
11968
11968
  return null;
11969
11969
  }
11970
11970
  };
11971
+ var resolveContactFromJwt = (decoded) => {
11972
+ if (!decoded) {
11973
+ return null;
11974
+ }
11975
+ const userData = decoded.user_data || {};
11976
+ const candidate = decoded.contact || decoded.primary_email || userData.primary_email || userData.primary_mobile || userData.org_user_id;
11977
+ if (typeof candidate !== "string") {
11978
+ return null;
11979
+ }
11980
+ const contact = candidate.trim();
11981
+ return contact === "" ? null : contact;
11982
+ };
11971
11983
  var isJwtExpired = (token, bufferSeconds = 30) => {
11972
11984
  if (!token || typeof token !== "string") return true;
11973
11985
  try {
@@ -12108,6 +12120,23 @@ var formatDateTime = (timestamp) => {
12108
12120
  hours = hours % 12 || 12;
12109
12121
  return `${month} ${day}, ${year} at ${hours}:${minutes} ${ampm}`;
12110
12122
  };
12123
+ var extractCaseRef = (response) => {
12124
+ if (!response || typeof response !== "object") {
12125
+ return null;
12126
+ }
12127
+ const wrapper = response;
12128
+ const candidates = [wrapper.detail, response];
12129
+ for (const candidate of candidates) {
12130
+ if (!candidate || typeof candidate !== "object") {
12131
+ continue;
12132
+ }
12133
+ const { case_id: caseId, uuid } = candidate;
12134
+ if (caseId || uuid) {
12135
+ return { case_id: caseId != null ? caseId : "", uuid: uuid != null ? uuid : "" };
12136
+ }
12137
+ }
12138
+ return null;
12139
+ };
12111
12140
  var generateUuid = () => {
12112
12141
  return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
12113
12142
  const r = Math.random() * 16 | 0;
@@ -12127,10 +12156,10 @@ function extractJwtAuthData(token) {
12127
12156
  if (!decoded) {
12128
12157
  return { email: null, organizationId: null, workspaceId: null, organizationName: null };
12129
12158
  }
12130
- const userData = decoded.user_data;
12131
- const userEmail = decoded.contact || decoded.primary_email || decoded.email || decoded.user_uuid || decoded.sub || (userData && typeof userData === "object" ? userData.primary_email || userData.email || userData.contact : null) || null;
12159
+ const contact = resolveContactFromJwt(decoded);
12132
12160
  return {
12133
- email: typeof userEmail === "string" ? userEmail : null,
12161
+ // `resolveContactFromJwt` already returns a trimmed, non-empty string or null.
12162
+ email: contact,
12134
12163
  organizationId: decoded.organisation_uuid || null,
12135
12164
  workspaceId: decoded.workspace_uuid || null,
12136
12165
  organizationName: decoded.organisation_name || null
@@ -12139,7 +12168,11 @@ function extractJwtAuthData(token) {
12139
12168
  function syncJwtDataToStore(token) {
12140
12169
  const authData = extractJwtAuthData(token);
12141
12170
  setStoredValue("access_token", token);
12142
- if (authData.email) setStoredValue("email", authData.email);
12171
+ if (authData.email) {
12172
+ setStoredValue("email", authData.email);
12173
+ } else {
12174
+ removeStoredValue("email");
12175
+ }
12143
12176
  if (authData.organizationId) setStoredValue("pc_org_id", authData.organizationId);
12144
12177
  if (authData.workspaceId) setStoredValue("pc_workspace_id", authData.workspaceId);
12145
12178
  return authData;
@@ -14749,6 +14782,11 @@ var useTimePeriodOptions = () => {
14749
14782
  );
14750
14783
  };
14751
14784
  var MAX_DISPLAYED_PURPOSE_NAMES_IN_ERASURE_MODAL = 3;
14785
+ var PRODUCT_SCOPED_REQUEST_TYPES = [
14786
+ "ACCESS" /* ACCESS */,
14787
+ "erasure" /* ERASURE */,
14788
+ "CORRECTION" /* CORRECTION */
14789
+ ];
14752
14790
  var SEARCH_DEBOUNCE_DELAY = 500;
14753
14791
  var FORM_PICKER_GROUP_LIMIT = 100;
14754
14792
  var LEGACY_PRODUCT_GROUP_UUID = "__legacy_flat_purposes__";
@@ -16569,6 +16607,25 @@ var uploadFileWithS2S = async ({
16569
16607
  }
16570
16608
  };
16571
16609
 
16610
+ // src/RedactoPrivacyCenter/lib/requestType.ts
16611
+ var isRequestType = (requestType, expected) => typeof requestType === "string" && requestType.toLowerCase() === expected.toLowerCase();
16612
+ var isProductScopedRequestType = (requestType) => PRODUCT_SCOPED_REQUEST_TYPES.some((type) => isRequestType(requestType, type));
16613
+
16614
+ // src/RedactoPrivacyCenter/lib/erasureConsent.ts
16615
+ var isErasureRequestType = (requestType) => isRequestType(requestType, "erasure" /* ERASURE */);
16616
+ var resolveErasurePurposeNames = (purposeNames, fallback) => {
16617
+ if (purposeNames.length === 0 || purposeNames.length > MAX_DISPLAYED_PURPOSE_NAMES_IN_ERASURE_MODAL) {
16618
+ return fallback;
16619
+ }
16620
+ return purposeNames.join(", ");
16621
+ };
16622
+ var erasureConsentPayload = (requestType, revokeConsentOnFulfilment) => {
16623
+ if (!isErasureRequestType(requestType)) {
16624
+ return {};
16625
+ }
16626
+ return { revoke_consent_on_fulfilment: revokeConsentOnFulfilment };
16627
+ };
16628
+
16572
16629
  // src/RedactoPrivacyCenter/lib/filePicker.ts
16573
16630
  var import_react_native42 = require("react-native");
16574
16631
  async function pickFile() {
@@ -16805,12 +16862,6 @@ var buildGroupDataElements = (group) => {
16805
16862
  // src/RedactoPrivacyCenter/components/Form.tsx
16806
16863
  var import_jsx_runtime43 = require("react/jsx-runtime");
16807
16864
  var TOTAL_STEPS = 3;
16808
- var PRODUCT_SCOPED_REQUEST_TYPES = /* @__PURE__ */ new Set([
16809
- "ACCESS" /* ACCESS */,
16810
- "erasure" /* ERASURE */,
16811
- "CORRECTION" /* CORRECTION */
16812
- ]);
16813
- var isProductScopedRequestType = (rt) => PRODUCT_SCOPED_REQUEST_TYPES.has(rt);
16814
16865
  function Form({ onCreateRequest }) {
16815
16866
  const { t } = (0, import_react_i18next16.useTranslation)();
16816
16867
  const { accessToken, refreshToken, email, organizationId, workspaceId, updateTokens, onError } = useAuth();
@@ -16954,7 +17005,7 @@ function Form({ onCreateRequest }) {
16954
17005
  setSelectedProductKey(null);
16955
17006
  }
16956
17007
  setNominationData({ nominee_email: "", nominee_mobile: "" });
16957
- if (requestType === "grievance" /* GRIEVANCE */ && grievanceOptions.length > 0) {
17008
+ if (isRequestType(requestType, "grievance" /* GRIEVANCE */) && grievanceOptions.length > 0) {
16958
17009
  const resetGrievances = grievanceOptions.reduce(
16959
17010
  (acc, option) => {
16960
17011
  acc[option.value] = false;
@@ -16983,12 +17034,10 @@ function Form({ onCreateRequest }) {
16983
17034
  () => groupPurposes.filter((p) => selectedPurposes.has(p.uuid)).map((p) => p.name).filter(Boolean),
16984
17035
  [groupPurposes, selectedPurposes]
16985
17036
  );
16986
- const selectedErasurePurposeNames = (0, import_react29.useMemo)(() => {
16987
- if (selectedErasurePurposeList.length === 0 || selectedErasurePurposeList.length > MAX_DISPLAYED_PURPOSE_NAMES_IN_ERASURE_MODAL) {
16988
- return t("revokeConsentModalYourPurposes");
16989
- }
16990
- return selectedErasurePurposeList.join(", ");
16991
- }, [selectedErasurePurposeList, t]);
17037
+ const selectedErasurePurposeNames = (0, import_react29.useMemo)(
17038
+ () => resolveErasurePurposeNames(selectedErasurePurposeList, t("revokeConsentModalYourPurposes")),
17039
+ [selectedErasurePurposeList, t]
17040
+ );
16992
17041
  const togglePurpose = (0, import_react29.useCallback)(
16993
17042
  (purpose) => {
16994
17043
  const uuid = purpose.uuid;
@@ -17095,7 +17144,7 @@ function Form({ onCreateRequest }) {
17095
17144
  if (isProductScopedRequestType(requestType)) {
17096
17145
  if (allGroups.length === 0) return false;
17097
17146
  if (!selectedGroup) return false;
17098
- if (requestType === "CORRECTION" /* CORRECTION */) {
17147
+ if (isRequestType(requestType, "CORRECTION" /* CORRECTION */)) {
17099
17148
  if (selectedCorrectionFields.size === 0) return false;
17100
17149
  return Array.from(selectedCorrectionFields).every((fieldUuid) => {
17101
17150
  var _a3, _b;
@@ -17103,15 +17152,15 @@ function Form({ onCreateRequest }) {
17103
17152
  return Boolean(((_a3 = v == null ? void 0 : v.current) == null ? void 0 : _a3.trim()) && ((_b = v == null ? void 0 : v.updated) == null ? void 0 : _b.trim()));
17104
17153
  });
17105
17154
  }
17106
- if (requestType === "ACCESS" /* ACCESS */ || requestType === "erasure" /* ERASURE */) {
17155
+ if (isRequestType(requestType, "ACCESS" /* ACCESS */) || isErasureRequestType(requestType)) {
17107
17156
  return selectedPurposes.size > 0;
17108
17157
  }
17109
17158
  return false;
17110
17159
  }
17111
- if (requestType === "grievance" /* GRIEVANCE */) {
17160
+ if (isRequestType(requestType, "grievance" /* GRIEVANCE */)) {
17112
17161
  return Object.values(selectedGrievances).some(Boolean);
17113
17162
  }
17114
- if (requestType === "nomination" /* NOMINATION */) {
17163
+ if (isRequestType(requestType, "nomination" /* NOMINATION */)) {
17115
17164
  return Boolean(nominationData.nominee_email);
17116
17165
  }
17117
17166
  return false;
@@ -17125,7 +17174,10 @@ function Form({ onCreateRequest }) {
17125
17174
  selectedGrievances,
17126
17175
  nominationData
17127
17176
  ]);
17128
- const isFormValid = (0, import_react29.useMemo)(() => detailsValid && confirmChecked, [detailsValid, confirmChecked]);
17177
+ const isFormValid = (0, import_react29.useMemo)(
17178
+ () => Boolean(contact.trim()) && detailsValid && confirmChecked,
17179
+ [contact, detailsValid, confirmChecked]
17180
+ );
17129
17181
  const handleUpload = (0, import_react29.useCallback)(async () => {
17130
17182
  if (!organizationId || !workspaceId) return;
17131
17183
  const caseUuid = formDataResponse == null ? void 0 : formDataResponse.uuid;
@@ -17177,9 +17229,18 @@ function Form({ onCreateRequest }) {
17177
17229
  const removeUploadedDoc = (0, import_react29.useCallback)((uuid) => {
17178
17230
  setUploadedDocs((prev) => prev.filter((d) => d.uuid !== uuid));
17179
17231
  }, []);
17232
+ const alertSubmitFailed = (0, import_react29.useCallback)(
17233
+ (message) => {
17234
+ import_react_native44.Alert.alert(t("submit"), message || t("unableToSubmit") || "Unable to submit request. Please try again.");
17235
+ },
17236
+ [t]
17237
+ );
17180
17238
  const handleSubmit = (0, import_react29.useCallback)(async (revoke = false) => {
17181
- var _a3, _b, _c, _d;
17182
- if (!organizationId || !workspaceId || !contact || !requestType || !formDataResponse) return;
17239
+ var _a3;
17240
+ if (!organizationId || !workspaceId || !contact || !requestType || !formDataResponse) {
17241
+ alertSubmitFailed();
17242
+ return;
17243
+ }
17183
17244
  setRevokeConsentOnFulfilment(revoke);
17184
17245
  setIsSubmitting(true);
17185
17246
  try {
@@ -17206,27 +17267,27 @@ function Form({ onCreateRequest }) {
17206
17267
  purposes: updatePurposes,
17207
17268
  correction_data: correctionData,
17208
17269
  grievance_types: grievanceTypes,
17209
- ...requestType === "nomination" /* NOMINATION */ ? { nomination_data: nominationData } : {}
17270
+ ...isRequestType(requestType, "nomination" /* NOMINATION */) ? { nomination_data: nominationData } : {}
17210
17271
  },
17211
- time_period: requestType === "ACCESS" /* ACCESS */ ? parseInt(timePeriod || "30", 10) : 0,
17272
+ time_period: isRequestType(requestType, "ACCESS" /* ACCESS */) ? parseInt(timePeriod || "30", 10) : 0,
17212
17273
  requestor_note: additionalNote || "",
17213
- ...requestType === "erasure" /* ERASURE */ ? { revoke_consent_on_fulfilment: revoke } : {},
17274
+ ...erasureConsentPayload(requestType, revoke),
17214
17275
  ...anchorGroup ? { product_uuid: anchorGroup.product_uuid } : {},
17215
17276
  ...(anchorGroup == null ? void 0 : anchorGroup.nominator) ? { data_principal_uuid: anchorGroup.nominator.uuid } : {}
17216
17277
  };
17217
17278
  const response = await createCaseRequest(organizationId, workspaceId, request, false, false, authContext, consentClient);
17218
- const responseAny = response;
17219
- const newCaseId = (_c = (_b = responseAny == null ? void 0 : responseAny.case_id) != null ? _b : (_a3 = responseAny == null ? void 0 : responseAny.detail) == null ? void 0 : _a3.case_id) != null ? _c : null;
17279
+ const caseRef = extractCaseRef(response);
17280
+ const newCaseId = (caseRef == null ? void 0 : caseRef.case_id) || (caseRef == null ? void 0 : caseRef.uuid) || null;
17220
17281
  if (newCaseId) {
17221
17282
  setCaseId(newCaseId);
17222
- setSubmittedProductName((_d = anchorGroup == null ? void 0 : anchorGroup.product_name) != null ? _d : "");
17283
+ setSubmittedProductName((_a3 = anchorGroup == null ? void 0 : anchorGroup.product_name) != null ? _a3 : "");
17223
17284
  setIsSubmitted(true);
17224
17285
  } else {
17225
- import_react_native44.Alert.alert(t("submit"), t("unableToSubmit") || "Unable to submit request. Please try again.");
17286
+ alertSubmitFailed();
17226
17287
  }
17227
17288
  } catch (error) {
17228
17289
  console.warn("Error submitting request:", error);
17229
- import_react_native44.Alert.alert(t("submit"), (error == null ? void 0 : error.message) || t("unableToSubmit") || "Unable to submit request.");
17290
+ alertSubmitFailed(error == null ? void 0 : error.message);
17230
17291
  } finally {
17231
17292
  setIsSubmitting(false);
17232
17293
  }
@@ -17249,11 +17310,13 @@ function Form({ onCreateRequest }) {
17249
17310
  consentClient,
17250
17311
  groupDataElements,
17251
17312
  uploadedDocs,
17252
- t
17313
+ alertSubmitFailed
17253
17314
  ]);
17254
17315
  const handleSubmitClick = (0, import_react29.useCallback)(() => {
17255
- if (!isFormValid) return;
17256
- if (requestType === "erasure" /* ERASURE */) {
17316
+ if (!isFormValid) {
17317
+ return;
17318
+ }
17319
+ if (isErasureRequestType(requestType)) {
17257
17320
  setIsErasureConsentModalOpen(true);
17258
17321
  return;
17259
17322
  }
@@ -17342,7 +17405,7 @@ function Form({ onCreateRequest }) {
17342
17405
  if (groupPurposes.length === 0) {
17343
17406
  return /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_react_native44.Text, { style: [styles33.placeholder, { color: colors.textSecondary }], children: t("noPurposesAvailable") || "No purposes available" });
17344
17407
  }
17345
- const isErasure = requestType === "erasure" /* ERASURE */;
17408
+ const isErasure = isErasureRequestType(requestType);
17346
17409
  const allPurposesSelected = groupPurposes.every(
17347
17410
  (p) => (p.data_elements || []).every((de) => {
17348
17411
  var _a3;
@@ -17462,18 +17525,18 @@ function Form({ onCreateRequest }) {
17462
17525
  ] }),
17463
17526
  selectedGroup ? /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(import_react_native44.View, { style: styles33.section, children: [
17464
17527
  /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_react_native44.Text, { style: [styles33.sectionLabel, { color: colors.textSecondary }], children: t("requestDetails") }),
17465
- /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_react_native44.View, { style: [styles33.sectionCard, elevation.card, { backgroundColor: colors.surface }], children: requestType === "CORRECTION" /* CORRECTION */ ? renderCorrectionFields() : renderPurposeFields() })
17528
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_react_native44.View, { style: [styles33.sectionCard, elevation.card, { backgroundColor: colors.surface }], children: isRequestType(requestType, "CORRECTION" /* CORRECTION */) ? renderCorrectionFields() : renderPurposeFields() })
17466
17529
  ] }) : /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(import_react_native44.View, { style: [styles33.hintCard, { backgroundColor: colors.surfaceAlt }], children: [
17467
17530
  /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(Icon, { name: "circle-alert", size: 18, color: colors.textSecondary }),
17468
17531
  /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_react_native44.Text, { style: [styles33.hintText, { color: colors.textSecondary }], children: t("selectProductFirst", { defaultValue: "Select a product to continue" }) })
17469
17532
  ] }),
17470
- requestType === "ACCESS" /* ACCESS */ && selectedGroup ? /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(import_react_native44.View, { style: styles33.section, children: [
17533
+ isRequestType(requestType, "ACCESS" /* ACCESS */) && selectedGroup ? /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(import_react_native44.View, { style: styles33.section, children: [
17471
17534
  /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_react_native44.Text, { style: [styles33.sectionLabel, { color: colors.textSecondary }], children: t("timePeriod") }),
17472
17535
  /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(PCSelect, { value: timePeriod, options: timePeriodOptions, onChange: setTimePeriod, placeholder: t("timePeriod") })
17473
17536
  ] }) : null
17474
17537
  ] });
17475
17538
  }
17476
- if (requestType === "grievance" /* GRIEVANCE */) {
17539
+ if (isRequestType(requestType, "grievance" /* GRIEVANCE */)) {
17477
17540
  if (grievanceOptions.length === 0) {
17478
17541
  return /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_react_native44.View, { style: styles33.stepBody, children: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_react_native44.Text, { style: [styles33.placeholder, { color: colors.textSecondary }], children: t("noPurposesAvailable") || "No grievance types available" }) });
17479
17542
  }
@@ -17489,7 +17552,7 @@ function Form({ onCreateRequest }) {
17489
17552
  ] })
17490
17553
  ] }) });
17491
17554
  }
17492
- if (requestType === "nomination" /* NOMINATION */) {
17555
+ if (isRequestType(requestType, "nomination" /* NOMINATION */)) {
17493
17556
  return /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_react_native44.View, { style: styles33.stepBody, children: /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(import_react_native44.View, { style: styles33.section, children: [
17494
17557
  /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_react_native44.Text, { style: [styles33.sectionLabel, { color: colors.textSecondary }], children: t("enterNomineeDetails") }),
17495
17558
  /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(import_react_native44.View, { style: [styles33.sectionCard, elevation.card, { backgroundColor: colors.surface }], children: [
@@ -18467,10 +18530,26 @@ var styles35 = import_react_native46.StyleSheet.create({
18467
18530
  });
18468
18531
 
18469
18532
  // src/RedactoPrivacyCenter/components/SlimTopBar.tsx
18470
- var import_react34 = require("react");
18533
+ var import_react35 = require("react");
18471
18534
  var import_react_native49 = require("react-native");
18472
18535
  var import_react_i18next19 = require("react-i18next");
18473
18536
 
18537
+ // src/RedactoPrivacyCenter/context/ProfileSwitchContext.tsx
18538
+ var import_react32 = require("react");
18539
+ var import_jsx_runtime46 = require("react/jsx-runtime");
18540
+ var ProfileSwitchContext = (0, import_react32.createContext)({
18541
+ switchProfile: null
18542
+ });
18543
+ function ProfileSwitchProvider({
18544
+ switchProfile,
18545
+ children
18546
+ }) {
18547
+ return /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(ProfileSwitchContext.Provider, { value: { switchProfile }, children });
18548
+ }
18549
+ function useProfileSwitch() {
18550
+ return (0, import_react32.useContext)(ProfileSwitchContext);
18551
+ }
18552
+
18474
18553
  // src/RedactoPrivacyCenter/lib/navigation.ts
18475
18554
  function navigateBack(onBack) {
18476
18555
  var _a3, _b;
@@ -18494,12 +18573,12 @@ function navigateBack(onBack) {
18494
18573
 
18495
18574
  // src/RedactoPrivacyCenter/components/NotificationHub/NotificationBell.tsx
18496
18575
  var import_react_native47 = require("react-native");
18497
- var import_jsx_runtime46 = require("react/jsx-runtime");
18576
+ var import_jsx_runtime47 = require("react/jsx-runtime");
18498
18577
  var NotificationBell = ({ count, onPress }) => {
18499
18578
  const { colors } = useTheme();
18500
18579
  const showBadge = count > 0;
18501
18580
  const badgeLabel = count > 99 ? "99+" : String(count);
18502
- return /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(
18581
+ return /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(
18503
18582
  import_react_native47.TouchableOpacity,
18504
18583
  {
18505
18584
  onPress,
@@ -18509,8 +18588,8 @@ var NotificationBell = ({ count, onPress }) => {
18509
18588
  accessibilityRole: "button",
18510
18589
  accessibilityLabel: showBadge ? `Notifications, ${count} unread` : "Notifications",
18511
18590
  children: [
18512
- /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Icon, { name: "bell", size: 22, color: colors.text }),
18513
- showBadge ? /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(import_react_native47.View, { style: [styles36.badge, { backgroundColor: colors.error, borderColor: colors.canvasSubtle }], children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(import_react_native47.Text, { style: styles36.badgeText, numberOfLines: 1, children: badgeLabel }) }) : null
18591
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Icon, { name: "bell", size: 22, color: colors.text }),
18592
+ showBadge ? /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(import_react_native47.View, { style: [styles36.badge, { backgroundColor: colors.error, borderColor: colors.canvasSubtle }], children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(import_react_native47.Text, { style: styles36.badgeText, numberOfLines: 1, children: badgeLabel }) }) : null
18514
18593
  ]
18515
18594
  }
18516
18595
  );
@@ -18542,27 +18621,27 @@ var styles36 = import_react_native47.StyleSheet.create({
18542
18621
  });
18543
18622
 
18544
18623
  // src/RedactoPrivacyCenter/components/NotificationHub/useUnreadCount.ts
18545
- var import_react32 = require("react");
18624
+ var import_react33 = require("react");
18546
18625
  function useUnreadCount() {
18547
18626
  const { accessToken, refreshToken, onError, updateTokens, organizationId, workspaceId } = useAuth();
18548
18627
  const { consentClient } = useBaseUrl();
18549
- const [count, setCount] = (0, import_react32.useState)(0);
18550
- const authContext = (0, import_react32.useMemo)(
18628
+ const [count, setCount] = (0, import_react33.useState)(0);
18629
+ const authContext = (0, import_react33.useMemo)(
18551
18630
  () => ({ accessToken, refreshToken, onError, updateTokens }),
18552
18631
  [accessToken, refreshToken, onError, updateTokens]
18553
18632
  );
18554
- const loadRef = (0, import_react32.useRef)();
18633
+ const loadRef = (0, import_react33.useRef)();
18555
18634
  loadRef.current = async () => {
18556
18635
  if (!organizationId || !workspaceId) return;
18557
18636
  if (isRefreshBlocked(authContext)) return;
18558
18637
  const res = await fetchUnreadCount(organizationId, workspaceId, authContext, consentClient);
18559
18638
  if (res && typeof res.count === "number") setCount(res.count);
18560
18639
  };
18561
- (0, import_react32.useEffect)(() => {
18640
+ (0, import_react33.useEffect)(() => {
18562
18641
  var _a3;
18563
18642
  (_a3 = loadRef.current) == null ? void 0 : _a3.call(loadRef);
18564
18643
  }, [organizationId, workspaceId]);
18565
- (0, import_react32.useEffect)(() => {
18644
+ (0, import_react33.useEffect)(() => {
18566
18645
  const id = setInterval(() => {
18567
18646
  var _a3;
18568
18647
  (_a3 = loadRef.current) == null ? void 0 : _a3.call(loadRef);
@@ -18573,17 +18652,17 @@ function useUnreadCount() {
18573
18652
  }
18574
18653
 
18575
18654
  // src/RedactoPrivacyCenter/components/NavDrawer.tsx
18576
- var import_react33 = require("react");
18655
+ var import_react34 = require("react");
18577
18656
  var import_react_native48 = require("react-native");
18578
18657
  var import_react_i18next18 = require("react-i18next");
18579
- var import_jsx_runtime47 = require("react/jsx-runtime");
18658
+ var import_jsx_runtime48 = require("react/jsx-runtime");
18580
18659
  var NavDrawer = ({ visible, onClose, onBack }) => {
18581
18660
  const { t } = (0, import_react_i18next18.useTranslation)();
18582
18661
  const { colors, branding } = useTheme();
18583
18662
  const { organizationName, email } = useAuth();
18584
18663
  const { currentPage, navigateTo } = useInternalNavigation();
18585
- const [locale, setLocale] = (0, import_react33.useState)(i18n_default.language || "en");
18586
- const items = (0, import_react33.useMemo)(
18664
+ const [locale, setLocale] = (0, import_react34.useState)(i18n_default.language || "en");
18665
+ const items = (0, import_react34.useMemo)(
18587
18666
  () => [
18588
18667
  { page: "home", label: t("privacyCenter") || "Home", icon: "shield", tone: "primary" },
18589
18668
  { page: "consent-manager", label: t("manageConsent") || "Consents", icon: "shield-check", tone: "primary" },
@@ -18598,18 +18677,18 @@ var NavDrawer = ({ visible, onClose, onBack }) => {
18598
18677
  i18n_default.changeLanguage(value);
18599
18678
  };
18600
18679
  const brandName = (branding == null ? void 0 : branding.brand_name) || organizationName || t("privacyCenter") || "Privacy Center";
18601
- return /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(BottomSheet, { visible, onClose, title: t("menu") || "Menu", children: /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(import_react_native48.View, { style: styles37.body, children: [
18602
- /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(import_react_native48.View, { style: [styles37.identity, { backgroundColor: colors.surfaceAlt }], children: [
18603
- /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(PCAvatar, { name: brandName, imageUrl: branding == null ? void 0 : branding.icon_url, size: 40 }),
18604
- /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(import_react_native48.View, { style: styles37.identityText, children: [
18605
- /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(import_react_native48.Text, { style: [styles37.brandName, { color: colors.text }], numberOfLines: 1, children: brandName }),
18606
- email ? /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(import_react_native48.Text, { style: [styles37.email, { color: colors.textSecondary }], numberOfLines: 1, children: email }) : null
18680
+ return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(BottomSheet, { visible, onClose, title: t("menu") || "Menu", children: /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(import_react_native48.View, { style: styles37.body, children: [
18681
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(import_react_native48.View, { style: [styles37.identity, { backgroundColor: colors.surfaceAlt }], children: [
18682
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(PCAvatar, { name: brandName, imageUrl: branding == null ? void 0 : branding.icon_url, size: 40 }),
18683
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(import_react_native48.View, { style: styles37.identityText, children: [
18684
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(import_react_native48.Text, { style: [styles37.brandName, { color: colors.text }], numberOfLines: 1, children: brandName }),
18685
+ email ? /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(import_react_native48.Text, { style: [styles37.email, { color: colors.textSecondary }], numberOfLines: 1, children: email }) : null
18607
18686
  ] })
18608
18687
  ] }),
18609
- /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(import_react_native48.View, { style: [styles37.menuGroup, { borderColor: colors.border, backgroundColor: colors.surface }], children: items.map((item, index) => {
18688
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(import_react_native48.View, { style: [styles37.menuGroup, { borderColor: colors.border, backgroundColor: colors.surface }], children: items.map((item, index) => {
18610
18689
  const isActive = currentPage === item.page;
18611
- return /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(import_react_native48.View, { children: [
18612
- /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(
18690
+ return /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(import_react_native48.View, { children: [
18691
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(
18613
18692
  import_react_native48.TouchableOpacity,
18614
18693
  {
18615
18694
  style: styles37.menuItem,
@@ -18622,8 +18701,8 @@ var NavDrawer = ({ visible, onClose, onBack }) => {
18622
18701
  accessibilityState: { selected: isActive },
18623
18702
  accessibilityLabel: item.label,
18624
18703
  children: [
18625
- /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(IconTile, { name: item.icon, tone: item.tone, size: "sm" }),
18626
- /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
18704
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(IconTile, { name: item.icon, tone: item.tone, size: "sm" }),
18705
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
18627
18706
  import_react_native48.Text,
18628
18707
  {
18629
18708
  style: [styles37.menuLabel, { color: isActive ? colors.primary : colors.text }],
@@ -18631,14 +18710,14 @@ var NavDrawer = ({ visible, onClose, onBack }) => {
18631
18710
  children: item.label
18632
18711
  }
18633
18712
  ),
18634
- /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Icon, { name: "chevron-right", size: 18, color: colors.textSecondary })
18713
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(Icon, { name: "chevron-right", size: 18, color: colors.textSecondary })
18635
18714
  ]
18636
18715
  }
18637
18716
  ),
18638
- index < items.length - 1 ? /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(import_react_native48.View, { style: [styles37.separator, { backgroundColor: colors.hairline }] }) : null
18717
+ index < items.length - 1 ? /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(import_react_native48.View, { style: [styles37.separator, { backgroundColor: colors.hairline }] }) : null
18639
18718
  ] }, item.page);
18640
18719
  }) }),
18641
- /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
18720
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
18642
18721
  PCSelect,
18643
18722
  {
18644
18723
  label: t("language"),
@@ -18648,7 +18727,7 @@ var NavDrawer = ({ visible, onClose, onBack }) => {
18648
18727
  placeholder: t("language")
18649
18728
  }
18650
18729
  ),
18651
- onBack ? /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(
18730
+ onBack ? /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(
18652
18731
  import_react_native48.TouchableOpacity,
18653
18732
  {
18654
18733
  style: [styles37.actionButton, { borderColor: colors.border, backgroundColor: colors.surface }],
@@ -18659,7 +18738,7 @@ var NavDrawer = ({ visible, onClose, onBack }) => {
18659
18738
  activeOpacity: 0.7,
18660
18739
  accessibilityRole: "button",
18661
18740
  children: [
18662
- /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
18741
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
18663
18742
  Icon,
18664
18743
  {
18665
18744
  name: onBack === "signout" ? "log-out" : "arrow-left",
@@ -18667,11 +18746,11 @@ var NavDrawer = ({ visible, onClose, onBack }) => {
18667
18746
  color: onBack === "signout" ? colors.error : colors.text
18668
18747
  }
18669
18748
  ),
18670
- /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(import_react_native48.Text, { style: [styles37.actionLabel, { color: onBack === "signout" ? colors.error : colors.text }], children: onBack === "signout" ? t("signOut") || "Sign Out" : t("back") || "Back" })
18749
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(import_react_native48.Text, { style: [styles37.actionLabel, { color: onBack === "signout" ? colors.error : colors.text }], children: onBack === "signout" ? t("signOut") || "Sign Out" : t("back") || "Back" })
18671
18750
  ]
18672
18751
  }
18673
18752
  ) : null,
18674
- /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Footer, { inline: true })
18753
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(Footer, { inline: true })
18675
18754
  ] }) });
18676
18755
  };
18677
18756
  var styles37 = import_react_native48.StyleSheet.create({
@@ -18733,7 +18812,7 @@ var styles37 = import_react_native48.StyleSheet.create({
18733
18812
  });
18734
18813
 
18735
18814
  // src/RedactoPrivacyCenter/components/SlimTopBar.tsx
18736
- var import_jsx_runtime48 = require("react/jsx-runtime");
18815
+ var import_jsx_runtime49 = require("react/jsx-runtime");
18737
18816
  var SlimTopBar = ({ mode = "primary", onBack }) => {
18738
18817
  const { t } = (0, import_react_i18next19.useTranslation)();
18739
18818
  const { currentPage, navigateTo } = useInternalNavigation();
@@ -18741,10 +18820,11 @@ var SlimTopBar = ({ mode = "primary", onBack }) => {
18741
18820
  const { organizationName } = useAuth();
18742
18821
  const unreadCount = useUnreadCount();
18743
18822
  const insets = useSafeInsets();
18744
- const [menuOpen, setMenuOpen] = (0, import_react34.useState)(false);
18823
+ const [menuOpen, setMenuOpen] = (0, import_react35.useState)(false);
18824
+ const { switchProfile } = useProfileSwitch();
18745
18825
  const pageChrome = PAGE_CHROME_BY_PAGE[currentPage];
18746
18826
  const isDetail = mode === "detail";
18747
- const brandLabel = (0, import_react34.useMemo)(
18827
+ const brandLabel = (0, import_react35.useMemo)(
18748
18828
  () => (branding == null ? void 0 : branding.brand_name) || organizationName || t("privacyCenter") || "Privacy Center",
18749
18829
  [branding == null ? void 0 : branding.brand_name, organizationName, t]
18750
18830
  );
@@ -18759,16 +18839,16 @@ var SlimTopBar = ({ mode = "primary", onBack }) => {
18759
18839
  }
18760
18840
  navigateBack(onBack);
18761
18841
  };
18762
- return /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(import_jsx_runtime48.Fragment, { children: [
18763
- /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
18842
+ return /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(import_jsx_runtime49.Fragment, { children: [
18843
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
18764
18844
  import_react_native49.View,
18765
18845
  {
18766
18846
  style: [
18767
18847
  styles38.container,
18768
18848
  { backgroundColor: colors.canvasSubtle, borderBottomColor: colors.hairline, paddingTop: insets.top + spacing.xs }
18769
18849
  ],
18770
- children: isDetail ? /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(import_react_native49.View, { style: styles38.detailRow, children: [
18771
- /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
18850
+ children: isDetail ? /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(import_react_native49.View, { style: styles38.detailRow, children: [
18851
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
18772
18852
  import_react_native49.TouchableOpacity,
18773
18853
  {
18774
18854
  style: styles38.iconButton,
@@ -18777,27 +18857,39 @@ var SlimTopBar = ({ mode = "primary", onBack }) => {
18777
18857
  hitSlop: DEFAULT_HIT_SLOP,
18778
18858
  accessibilityRole: "button",
18779
18859
  accessibilityLabel: t("back") || "Back",
18780
- children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(Icon, { name: "arrow-left", size: 22, color: colors.text })
18860
+ children: /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(Icon, { name: "arrow-left", size: 22, color: colors.text })
18781
18861
  }
18782
18862
  ),
18783
- /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(import_react_native49.Text, { style: [styles38.detailTitle, { color: colors.text }], numberOfLines: 1, children: t((pageChrome == null ? void 0 : pageChrome.titleKey) || "privacyCenter") }),
18784
- /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(import_react_native49.View, { style: styles38.placeholder })
18785
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(import_react_native49.View, { style: styles38.row, children: [
18786
- /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(import_react_native49.View, { style: styles38.brandWrap, children: (branding == null ? void 0 : branding.logo_url) ? /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
18863
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(import_react_native49.Text, { style: [styles38.detailTitle, { color: colors.text }], numberOfLines: 1, children: t((pageChrome == null ? void 0 : pageChrome.titleKey) || "privacyCenter") }),
18864
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(import_react_native49.View, { style: styles38.placeholder })
18865
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(import_react_native49.View, { style: styles38.row, children: [
18866
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(import_react_native49.View, { style: styles38.brandWrap, children: (branding == null ? void 0 : branding.logo_url) ? /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
18787
18867
  BrandImage,
18788
18868
  {
18789
18869
  uri: branding.logo_url,
18790
18870
  height: 24,
18791
18871
  maxWidth: 124,
18792
- fallback: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(PCAvatar, { name: brandLabel, imageUrl: branding == null ? void 0 : branding.icon_url, size: 24 })
18872
+ fallback: /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(PCAvatar, { name: brandLabel, imageUrl: branding == null ? void 0 : branding.icon_url, size: 24 })
18793
18873
  }
18794
- ) : /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(import_react_native49.View, { style: styles38.brandLockup, children: [
18795
- /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(PCAvatar, { name: brandLabel, imageUrl: branding == null ? void 0 : branding.icon_url, size: 24 }),
18796
- /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(import_react_native49.Text, { style: [styles38.brandText, { color: colors.text }], numberOfLines: 1, children: brandLabel })
18874
+ ) : /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(import_react_native49.View, { style: styles38.brandLockup, children: [
18875
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(PCAvatar, { name: brandLabel, imageUrl: branding == null ? void 0 : branding.icon_url, size: 24 }),
18876
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(import_react_native49.Text, { style: [styles38.brandText, { color: colors.text }], numberOfLines: 1, children: brandLabel })
18797
18877
  ] }) }),
18798
- /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(import_react_native49.View, { style: styles38.actions, children: [
18799
- /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(NotificationBell, { count: unreadCount, onPress: () => navigateTo("notifications") }),
18800
- /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
18878
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(import_react_native49.View, { style: styles38.actions, children: [
18879
+ switchProfile ? /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
18880
+ import_react_native49.TouchableOpacity,
18881
+ {
18882
+ style: styles38.iconButton,
18883
+ onPress: switchProfile,
18884
+ activeOpacity: 0.7,
18885
+ hitSlop: DEFAULT_HIT_SLOP,
18886
+ accessibilityRole: "button",
18887
+ accessibilityLabel: t("switchProfile"),
18888
+ children: /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(Icon, { name: "users", size: 22, color: colors.text })
18889
+ }
18890
+ ) : null,
18891
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(NotificationBell, { count: unreadCount, onPress: () => navigateTo("notifications") }),
18892
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
18801
18893
  import_react_native49.TouchableOpacity,
18802
18894
  {
18803
18895
  style: styles38.iconButton,
@@ -18806,14 +18898,14 @@ var SlimTopBar = ({ mode = "primary", onBack }) => {
18806
18898
  hitSlop: DEFAULT_HIT_SLOP,
18807
18899
  accessibilityRole: "button",
18808
18900
  accessibilityLabel: t("menu") || "Menu",
18809
- children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(Icon, { name: "menu", size: 22, color: colors.text })
18901
+ children: /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(Icon, { name: "menu", size: 22, color: colors.text })
18810
18902
  }
18811
18903
  )
18812
18904
  ] })
18813
18905
  ] })
18814
18906
  }
18815
18907
  ),
18816
- /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(NavDrawer, { visible: menuOpen, onClose: () => setMenuOpen(false), onBack })
18908
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(NavDrawer, { visible: menuOpen, onClose: () => setMenuOpen(false), onBack })
18817
18909
  ] });
18818
18910
  };
18819
18911
  var styles38 = import_react_native49.StyleSheet.create({
@@ -18874,18 +18966,18 @@ var styles38 = import_react_native49.StyleSheet.create({
18874
18966
 
18875
18967
  // src/RedactoPrivacyCenter/components/PrivacyCenterEmptyState.tsx
18876
18968
  var import_react_i18next20 = require("react-i18next");
18877
- var import_jsx_runtime49 = require("react/jsx-runtime");
18969
+ var import_jsx_runtime50 = require("react/jsx-runtime");
18878
18970
  function PrivacyCenterEmptyState() {
18879
18971
  const { t } = (0, import_react_i18next20.useTranslation)();
18880
- return /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(PCEmpty, { iconName: "shield", title: t("noDataTitle"), description: t("noDataDescription") });
18972
+ return /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(PCEmpty, { iconName: "shield", title: t("noDataTitle"), description: t("noDataDescription") });
18881
18973
  }
18882
18974
 
18883
18975
  // src/RedactoPrivacyCenter/components/PrivacyCenterSessionExpired.tsx
18884
18976
  var import_react_i18next21 = require("react-i18next");
18885
- var import_jsx_runtime50 = require("react/jsx-runtime");
18977
+ var import_jsx_runtime51 = require("react/jsx-runtime");
18886
18978
  function PrivacyCenterSessionExpired() {
18887
18979
  const { t } = (0, import_react_i18next21.useTranslation)();
18888
- return /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
18980
+ return /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
18889
18981
  PCEmpty,
18890
18982
  {
18891
18983
  iconName: "shield",
@@ -18899,22 +18991,6 @@ function PrivacyCenterSessionExpired() {
18899
18991
  var import_react36 = require("react");
18900
18992
  var import_react_native51 = require("react-native");
18901
18993
 
18902
- // src/RedactoPrivacyCenter/context/ProfileSwitchContext.tsx
18903
- var import_react35 = require("react");
18904
- var import_jsx_runtime51 = require("react/jsx-runtime");
18905
- var ProfileSwitchContext = (0, import_react35.createContext)({
18906
- switchProfile: null
18907
- });
18908
- function ProfileSwitchProvider({
18909
- switchProfile,
18910
- children
18911
- }) {
18912
- return /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(ProfileSwitchContext.Provider, { value: { switchProfile }, children });
18913
- }
18914
- function useProfileSwitch() {
18915
- return (0, import_react35.useContext)(ProfileSwitchContext);
18916
- }
18917
-
18918
18994
  // src/RedactoPrivacyCenter/components/SelectUser.tsx
18919
18995
  var import_react_native50 = require("react-native");
18920
18996
  var import_react_i18next22 = require("react-i18next");
@@ -21676,6 +21752,7 @@ function Navbar({ mode = "primary", onBack }) {
21676
21752
  const [menuOpen, setMenuOpen] = (0, import_react46.useState)(false);
21677
21753
  const unreadCount = useUnreadCount();
21678
21754
  const { status: pageStatus } = usePageStatus();
21755
+ const { switchProfile } = useProfileSwitch();
21679
21756
  const pageChrome = PAGE_CHROME_BY_PAGE[currentPage] || PAGE_CHROME_BY_PAGE["consent-manager"];
21680
21757
  const isDetail = mode === "detail";
21681
21758
  (0, import_react46.useEffect)(() => {
@@ -21778,6 +21855,36 @@ function Navbar({ mode = "primary", onBack }) {
21778
21855
  ) : null,
21779
21856
  /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(import_react_native69.View, { style: styles57.brandWrap, children: (branding == null ? void 0 : branding.logo_url) ? /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(BrandImage, { uri: branding.logo_url, height: 34, maxWidth: 170, fallback: brandLockup }) : brandLockup }),
21780
21857
  /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)(import_react_native69.View, { style: styles57.actions, children: [
21858
+ switchProfile ? /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
21859
+ import_react_native69.TouchableOpacity,
21860
+ {
21861
+ style: styles57.iconButton,
21862
+ onPress: switchProfile,
21863
+ activeOpacity: 0.7,
21864
+ hitSlop: DEFAULT_HIT_SLOP,
21865
+ accessibilityRole: "button",
21866
+ accessibilityLabel: t("switchProfile"),
21867
+ children: /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
21868
+ import_react_native69.View,
21869
+ {
21870
+ style: [
21871
+ styles57.iconCircle,
21872
+ { backgroundColor: colors.surface, borderColor: colors.border }
21873
+ ],
21874
+ children: /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(import_react_native_svg6.default, { width: 18, height: 18, viewBox: "0 0 24 24", fill: "none", children: /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
21875
+ import_react_native_svg6.Path,
21876
+ {
21877
+ d: "M16 3h5v5 M21 3l-7 7 M8 21H3v-5 M3 21l7-7",
21878
+ stroke: colors.text,
21879
+ strokeWidth: 2,
21880
+ strokeLinecap: "round",
21881
+ strokeLinejoin: "round"
21882
+ }
21883
+ ) })
21884
+ }
21885
+ )
21886
+ }
21887
+ ) : null,
21781
21888
  /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(NotificationBell, { count: unreadCount, onPress: () => navigateTo("notifications") }),
21782
21889
  /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(PCSelect, { value: locale, options: languageOptions, onChange: handleLanguageChange, placeholder: t("language"), compact: true }),
21783
21890
  /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
@@ -21854,6 +21961,21 @@ var styles57 = import_react_native69.StyleSheet.create({
21854
21961
  alignItems: "center",
21855
21962
  justifyContent: "center"
21856
21963
  },
21964
+ iconButton: {
21965
+ width: MIN_TAP_TARGET,
21966
+ height: MIN_TAP_TARGET,
21967
+ alignItems: "center",
21968
+ justifyContent: "center"
21969
+ },
21970
+ // Matches the Flutter navbar's 34pt bordered circle.
21971
+ iconCircle: {
21972
+ width: 34,
21973
+ height: 34,
21974
+ borderRadius: 17,
21975
+ borderWidth: 1,
21976
+ alignItems: "center",
21977
+ justifyContent: "center"
21978
+ },
21857
21979
  pageHeader: {
21858
21980
  marginTop: spacing.sm
21859
21981
  },