@redacto.io/consent-sdk-react-native 5.0.0-beta.3 → 5.0.0-beta.4

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.
@@ -33,12 +33,20 @@ var languageOptions = [
33
33
  ];
34
34
  var codeByLabel = new Map(languageOptions.map((o) => [o.label, o.value]));
35
35
  var codeByLower = new Map(languageOptions.map((o) => [o.value.toLowerCase(), o.value]));
36
- function toLanguageCode(lang) {
36
+ var englishName = (label) => {
37
37
  var _a, _b;
38
+ return (_b = (_a = label.match(/\(([^)]+)\)\s*$/)) == null ? void 0 : _a[1]) != null ? _b : label;
39
+ };
40
+ var codeByName = new Map(
41
+ languageOptions.map((o) => [englishName(o.label).toLowerCase(), o.value])
42
+ );
43
+ function toLanguageCode(lang) {
44
+ var _a, _b, _c;
38
45
  if (!lang) return void 0;
39
46
  const trimmed = lang.trim();
40
47
  if (!trimmed) return void 0;
41
- return (_b = (_a = codeByLabel.get(trimmed)) != null ? _a : codeByLower.get(trimmed.toLowerCase())) != null ? _b : trimmed;
48
+ const lower = trimmed.toLowerCase();
49
+ return (_c = (_b = (_a = codeByLabel.get(trimmed)) != null ? _a : codeByName.get(lower)) != null ? _b : codeByLower.get(lower)) != null ? _c : trimmed;
42
50
  }
43
51
 
44
52
  export {
package/dist/index.js CHANGED
@@ -74,12 +74,20 @@ var languageOptions = [
74
74
  ];
75
75
  var codeByLabel = new Map(languageOptions.map((o) => [o.label, o.value]));
76
76
  var codeByLower = new Map(languageOptions.map((o) => [o.value.toLowerCase(), o.value]));
77
- function toLanguageCode(lang) {
77
+ var englishName = (label) => {
78
78
  var _a, _b;
79
+ return (_b = (_a = label.match(/\(([^)]+)\)\s*$/)) == null ? void 0 : _a[1]) != null ? _b : label;
80
+ };
81
+ var codeByName = new Map(
82
+ languageOptions.map((o) => [englishName(o.label).toLowerCase(), o.value])
83
+ );
84
+ function toLanguageCode(lang) {
85
+ var _a, _b, _c;
79
86
  if (!lang) return void 0;
80
87
  const trimmed = lang.trim();
81
88
  if (!trimmed) return void 0;
82
- return (_b = (_a = codeByLabel.get(trimmed)) != null ? _a : codeByLower.get(trimmed.toLowerCase())) != null ? _b : trimmed;
89
+ const lower = trimmed.toLowerCase();
90
+ return (_c = (_b = (_a = codeByLabel.get(trimmed)) != null ? _a : codeByName.get(lower)) != null ? _b : codeByLower.get(lower)) != null ? _c : trimmed;
83
91
  }
84
92
 
85
93
  // src/RedactoNoticeConsent/api/index.ts
package/dist/index.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  toLanguageCode
3
- } from "./chunk-IVOOB4JK.mjs";
3
+ } from "./chunk-UVRSRLYW.mjs";
4
4
 
5
5
  // src/RedactoNoticeConsent/RedactoNoticeConsent.tsx
6
6
  import {
@@ -5,6 +5,63 @@ import * as react_native from 'react-native';
5
5
  import { StyleProp, ViewStyle, TextStyle, KeyboardTypeOptions, DimensionValue, Animated } from 'react-native';
6
6
  import * as lucide_react_native from 'lucide-react-native';
7
7
 
8
+ interface ThemeColors {
9
+ background: string;
10
+ /** Page canvas. Flat mode keeps this equal to background. */
11
+ canvas: string;
12
+ surface: string;
13
+ text: string;
14
+ textSecondary: string;
15
+ border: string;
16
+ primary: string;
17
+ primaryText: string;
18
+ error: string;
19
+ success: string;
20
+ warning: string;
21
+ /** Hyperlink / accent text color. Falls back to primary. */
22
+ link: string;
23
+ /** Secondary brand color. Falls back to primary. */
24
+ secondary: string;
25
+ /** Quiet gray app background that cards sit on. */
26
+ canvasSubtle: string;
27
+ /** Secondary surface fill — inset rows, pressed states, skeletons. */
28
+ surfaceAlt: string;
29
+ /** Separator lighter than `border` (used inside cards). */
30
+ hairline: string;
31
+ /** Soft tint of `primary` for icon tiles / active pills. */
32
+ primarySoft: string;
33
+ /** Foreground (icon/label) color used on `primarySoft`. */
34
+ primaryOn: string;
35
+ /** Informational accent (badges / info states). */
36
+ info: string;
37
+ /** Soft status tints for badges, empty states, and icon tiles. */
38
+ successSoft: string;
39
+ warningSoft: string;
40
+ errorSoft: string;
41
+ infoSoft: string;
42
+ /** Scrim behind modals / bottom sheets. */
43
+ overlay: string;
44
+ }
45
+ type BrandingMeta = {
46
+ logo_url: string | null;
47
+ icon_url: string | null;
48
+ brand_name: string;
49
+ hide_platform_branding: boolean;
50
+ };
51
+ interface ThemeContextType {
52
+ colors: ThemeColors;
53
+ /** Org branding metadata (logo, brand name). Null until/unless it resolves. */
54
+ branding: BrandingMeta | null;
55
+ /** True while org branding is being fetched (used to gate first paint). */
56
+ isLoading: boolean;
57
+ }
58
+ declare function ThemeProvider({ children, slug, baseUrl, }: {
59
+ children: ReactNode;
60
+ slug?: string;
61
+ baseUrl?: string;
62
+ }): React.JSX.Element;
63
+ declare function useTheme(): ThemeContextType;
64
+
8
65
  type Workspace = {
9
66
  uuid: string;
10
67
  suid: string;
@@ -818,63 +875,6 @@ interface AuthProviderProps {
818
875
  declare function AuthProvider({ children, accessToken: initialAccessToken, refreshToken: initialRefreshToken, onError }: AuthProviderProps): React.JSX.Element;
819
876
  declare function useAuth(): AuthContextType;
820
877
 
821
- interface ThemeColors {
822
- background: string;
823
- /** Page canvas. Flat mode keeps this equal to background. */
824
- canvas: string;
825
- surface: string;
826
- text: string;
827
- textSecondary: string;
828
- border: string;
829
- primary: string;
830
- primaryText: string;
831
- error: string;
832
- success: string;
833
- warning: string;
834
- /** Hyperlink / accent text color. Falls back to primary. */
835
- link: string;
836
- /** Secondary brand color. Falls back to primary. */
837
- secondary: string;
838
- /** Quiet gray app background that cards sit on. */
839
- canvasSubtle: string;
840
- /** Secondary surface fill — inset rows, pressed states, skeletons. */
841
- surfaceAlt: string;
842
- /** Separator lighter than `border` (used inside cards). */
843
- hairline: string;
844
- /** Soft tint of `primary` for icon tiles / active pills. */
845
- primarySoft: string;
846
- /** Foreground (icon/label) color used on `primarySoft`. */
847
- primaryOn: string;
848
- /** Informational accent (badges / info states). */
849
- info: string;
850
- /** Soft status tints for badges, empty states, and icon tiles. */
851
- successSoft: string;
852
- warningSoft: string;
853
- errorSoft: string;
854
- infoSoft: string;
855
- /** Scrim behind modals / bottom sheets. */
856
- overlay: string;
857
- }
858
- type BrandingMeta = {
859
- logo_url: string | null;
860
- icon_url: string | null;
861
- brand_name: string;
862
- hide_platform_branding: boolean;
863
- };
864
- interface ThemeContextType {
865
- colors: ThemeColors;
866
- /** Org branding metadata (logo, brand name). Null until/unless it resolves. */
867
- branding: BrandingMeta | null;
868
- /** True while org branding is being fetched (used to gate first paint). */
869
- isLoading: boolean;
870
- }
871
- declare function ThemeProvider({ children, slug, baseUrl, }: {
872
- children: ReactNode;
873
- slug?: string;
874
- baseUrl?: string;
875
- }): React.JSX.Element;
876
- declare function useTheme(): ThemeContextType;
877
-
878
878
  /**
879
879
  * Curated icon registry. The whole Privacy Center draws icons through this one
880
880
  * component so sizing, stroke weight and color stay consistent and the icon
@@ -5,6 +5,63 @@ import * as react_native from 'react-native';
5
5
  import { StyleProp, ViewStyle, TextStyle, KeyboardTypeOptions, DimensionValue, Animated } from 'react-native';
6
6
  import * as lucide_react_native from 'lucide-react-native';
7
7
 
8
+ interface ThemeColors {
9
+ background: string;
10
+ /** Page canvas. Flat mode keeps this equal to background. */
11
+ canvas: string;
12
+ surface: string;
13
+ text: string;
14
+ textSecondary: string;
15
+ border: string;
16
+ primary: string;
17
+ primaryText: string;
18
+ error: string;
19
+ success: string;
20
+ warning: string;
21
+ /** Hyperlink / accent text color. Falls back to primary. */
22
+ link: string;
23
+ /** Secondary brand color. Falls back to primary. */
24
+ secondary: string;
25
+ /** Quiet gray app background that cards sit on. */
26
+ canvasSubtle: string;
27
+ /** Secondary surface fill — inset rows, pressed states, skeletons. */
28
+ surfaceAlt: string;
29
+ /** Separator lighter than `border` (used inside cards). */
30
+ hairline: string;
31
+ /** Soft tint of `primary` for icon tiles / active pills. */
32
+ primarySoft: string;
33
+ /** Foreground (icon/label) color used on `primarySoft`. */
34
+ primaryOn: string;
35
+ /** Informational accent (badges / info states). */
36
+ info: string;
37
+ /** Soft status tints for badges, empty states, and icon tiles. */
38
+ successSoft: string;
39
+ warningSoft: string;
40
+ errorSoft: string;
41
+ infoSoft: string;
42
+ /** Scrim behind modals / bottom sheets. */
43
+ overlay: string;
44
+ }
45
+ type BrandingMeta = {
46
+ logo_url: string | null;
47
+ icon_url: string | null;
48
+ brand_name: string;
49
+ hide_platform_branding: boolean;
50
+ };
51
+ interface ThemeContextType {
52
+ colors: ThemeColors;
53
+ /** Org branding metadata (logo, brand name). Null until/unless it resolves. */
54
+ branding: BrandingMeta | null;
55
+ /** True while org branding is being fetched (used to gate first paint). */
56
+ isLoading: boolean;
57
+ }
58
+ declare function ThemeProvider({ children, slug, baseUrl, }: {
59
+ children: ReactNode;
60
+ slug?: string;
61
+ baseUrl?: string;
62
+ }): React.JSX.Element;
63
+ declare function useTheme(): ThemeContextType;
64
+
8
65
  type Workspace = {
9
66
  uuid: string;
10
67
  suid: string;
@@ -818,63 +875,6 @@ interface AuthProviderProps {
818
875
  declare function AuthProvider({ children, accessToken: initialAccessToken, refreshToken: initialRefreshToken, onError }: AuthProviderProps): React.JSX.Element;
819
876
  declare function useAuth(): AuthContextType;
820
877
 
821
- interface ThemeColors {
822
- background: string;
823
- /** Page canvas. Flat mode keeps this equal to background. */
824
- canvas: string;
825
- surface: string;
826
- text: string;
827
- textSecondary: string;
828
- border: string;
829
- primary: string;
830
- primaryText: string;
831
- error: string;
832
- success: string;
833
- warning: string;
834
- /** Hyperlink / accent text color. Falls back to primary. */
835
- link: string;
836
- /** Secondary brand color. Falls back to primary. */
837
- secondary: string;
838
- /** Quiet gray app background that cards sit on. */
839
- canvasSubtle: string;
840
- /** Secondary surface fill — inset rows, pressed states, skeletons. */
841
- surfaceAlt: string;
842
- /** Separator lighter than `border` (used inside cards). */
843
- hairline: string;
844
- /** Soft tint of `primary` for icon tiles / active pills. */
845
- primarySoft: string;
846
- /** Foreground (icon/label) color used on `primarySoft`. */
847
- primaryOn: string;
848
- /** Informational accent (badges / info states). */
849
- info: string;
850
- /** Soft status tints for badges, empty states, and icon tiles. */
851
- successSoft: string;
852
- warningSoft: string;
853
- errorSoft: string;
854
- infoSoft: string;
855
- /** Scrim behind modals / bottom sheets. */
856
- overlay: string;
857
- }
858
- type BrandingMeta = {
859
- logo_url: string | null;
860
- icon_url: string | null;
861
- brand_name: string;
862
- hide_platform_branding: boolean;
863
- };
864
- interface ThemeContextType {
865
- colors: ThemeColors;
866
- /** Org branding metadata (logo, brand name). Null until/unless it resolves. */
867
- branding: BrandingMeta | null;
868
- /** True while org branding is being fetched (used to gate first paint). */
869
- isLoading: boolean;
870
- }
871
- declare function ThemeProvider({ children, slug, baseUrl, }: {
872
- children: ReactNode;
873
- slug?: string;
874
- baseUrl?: string;
875
- }): React.JSX.Element;
876
- declare function useTheme(): ThemeContextType;
877
-
878
878
  /**
879
879
  * Curated icon registry. The whole Privacy Center draws icons through this one
880
880
  * component so sizing, stroke weight and color stay consistent and the icon
@@ -14247,6 +14247,13 @@ var languageOptions = [
14247
14247
  ];
14248
14248
  var codeByLabel = new Map(languageOptions.map((o) => [o.label, o.value]));
14249
14249
  var codeByLower = new Map(languageOptions.map((o) => [o.value.toLowerCase(), o.value]));
14250
+ var englishName = (label) => {
14251
+ var _a3, _b;
14252
+ return (_b = (_a3 = label.match(/\(([^)]+)\)\s*$/)) == null ? void 0 : _a3[1]) != null ? _b : label;
14253
+ };
14254
+ var codeByName = new Map(
14255
+ languageOptions.map((o) => [englishName(o.label).toLowerCase(), o.value])
14256
+ );
14250
14257
 
14251
14258
  // src/RedactoPrivacyCenter/lib/constants.ts
14252
14259
  var PAGE_CHROME_BY_PAGE = {
@@ -15630,10 +15637,10 @@ var import_react_i18next14 = require("react-i18next");
15630
15637
  // src/RedactoPrivacyCenter/lib/dateGroup.ts
15631
15638
  var import_react27 = require("react");
15632
15639
  var import_react_i18next13 = require("react-i18next");
15633
- function monthKey(ts) {
15640
+ function monthKey(ts, locale) {
15634
15641
  if (!ts) return "";
15635
15642
  try {
15636
- return new Date(ts).toLocaleDateString(void 0, { month: "long", year: "numeric" });
15643
+ return new Date(ts).toLocaleDateString(locale || void 0, { month: "long", year: "numeric" });
15637
15644
  } catch {
15638
15645
  return "";
15639
15646
  }
@@ -15709,7 +15716,7 @@ function groupByTime(items, getTs, classify) {
15709
15716
  );
15710
15717
  }
15711
15718
  function useRelativeDate() {
15712
- const { t } = (0, import_react_i18next13.useTranslation)();
15719
+ const { t, i18n: i18n2 } = (0, import_react_i18next13.useTranslation)();
15713
15720
  return (0, import_react27.useCallback)(
15714
15721
  (ts) => {
15715
15722
  if (!ts) return "";
@@ -15722,7 +15729,7 @@ function useRelativeDate() {
15722
15729
  if (dayDiff <= 0) return t("today", { defaultValue: "Today" });
15723
15730
  if (dayDiff === 1) return t("yesterday", { defaultValue: "Yesterday" });
15724
15731
  if (dayDiff < 7) return t("daysAgo", { count: dayDiff, defaultValue: "{{count}} days ago" });
15725
- return d.toLocaleDateString(void 0, {
15732
+ return d.toLocaleDateString(i18n2.language || void 0, {
15726
15733
  month: "short",
15727
15734
  day: "numeric",
15728
15735
  ...d.getFullYear() !== now.getFullYear() ? { year: "numeric" } : {}
@@ -15731,10 +15738,28 @@ function useRelativeDate() {
15731
15738
  return ts;
15732
15739
  }
15733
15740
  },
15734
- [t]
15741
+ [t, i18n2.language]
15735
15742
  );
15736
15743
  }
15737
15744
 
15745
+ // src/RedactoPrivacyCenter/lib/receiptEvent.ts
15746
+ function eventLabelKey(eventType) {
15747
+ const v = String(eventType || "").toUpperCase();
15748
+ if (v.includes("GRANT")) {
15749
+ return "consentGranted";
15750
+ }
15751
+ if (v.includes("WITHDRAW") || v.includes("REVOK")) {
15752
+ return "consentRevoked";
15753
+ }
15754
+ if (v.includes("DECLIN")) {
15755
+ return "consentDeclined";
15756
+ }
15757
+ if (v.includes("EXPIR")) {
15758
+ return "consentExpired";
15759
+ }
15760
+ return void 0;
15761
+ }
15762
+
15738
15763
  // src/RedactoPrivacyCenter/components/ReceiptsList.tsx
15739
15764
  var import_jsx_runtime41 = require("react/jsx-runtime");
15740
15765
  var PAGE_SIZE2 = 10;
@@ -15770,11 +15795,10 @@ function receiptBadgeStatus(eventType) {
15770
15795
  if (v.includes("EXPIR")) return "warning";
15771
15796
  return "secondary";
15772
15797
  }
15773
- var ReceiptRow = import_react28.default.memo(({ item, colors, downloading, onDownload, downloadLabel, dateLabel }) => {
15798
+ var ReceiptRow = import_react28.default.memo(({ item, colors, downloading, onDownload, downloadLabel, dateLabel, eventLabel }) => {
15774
15799
  const product = item.product_name_display || item.product_name || "";
15775
- const event = item.event_type_display || item.event_type || "";
15776
- const primary = product || event || "-";
15777
- const badgeLabel = event || "-";
15800
+ const primary = product || eventLabel || "-";
15801
+ const badgeLabel = eventLabel || "-";
15778
15802
  return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(import_react_native41.View, { style: styles31.row, children: [
15779
15803
  /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(NameAvatar, { name: primary, seed: item.uuid || primary, size: "sm" }),
15780
15804
  /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(import_react_native41.View, { style: styles31.body, children: [
@@ -15801,7 +15825,7 @@ var ReceiptRow = import_react28.default.memo(({ item, colors, downloading, onDow
15801
15825
  });
15802
15826
  ReceiptRow.displayName = "ReceiptRow";
15803
15827
  function ReceiptsList() {
15804
- const { t } = (0, import_react_i18next14.useTranslation)();
15828
+ const { t, i18n: i18n2 } = (0, import_react_i18next14.useTranslation)();
15805
15829
  const { accessToken, refreshToken, organizationId, workspaceId, updateTokens, onError } = useAuth();
15806
15830
  const { consentClient } = useBaseUrl();
15807
15831
  const { colors } = useTheme();
@@ -15886,14 +15910,18 @@ function ReceiptsList() {
15886
15910
  const sections = (0, import_react28.useMemo)(() => {
15887
15911
  const map = /* @__PURE__ */ new Map();
15888
15912
  for (const r of receipts) {
15889
- const key = monthKey(r.created_at);
15913
+ const key = monthKey(r.created_at, i18n2.language);
15890
15914
  const arr = map.get(key);
15891
15915
  if (arr) arr.push(r);
15892
15916
  else map.set(key, [r]);
15893
15917
  }
15894
15918
  return Array.from(map, ([title, data]) => ({ title, data }));
15895
- }, [receipts]);
15919
+ }, [receipts, i18n2.language]);
15896
15920
  const downloadLabel = t("download") || "Download";
15921
+ const eventLabelFor = (r) => {
15922
+ const key = eventLabelKey(r.event_type);
15923
+ return key ? t(key) : r.event_type_display || r.event_type || "-";
15924
+ };
15897
15925
  const handleScroll = (0, import_react28.useCallback)(
15898
15926
  (e) => {
15899
15927
  const { layoutMeasurement, contentOffset, contentSize } = e.nativeEvent;
@@ -15975,7 +16003,8 @@ function ReceiptsList() {
15975
16003
  downloading: downloadingUuid === item.uuid,
15976
16004
  onDownload: handleDownload,
15977
16005
  downloadLabel,
15978
- dateLabel: relativeLabel(item.created_at)
16006
+ dateLabel: relativeLabel(item.created_at),
16007
+ eventLabel: eventLabelFor(item)
15979
16008
  }
15980
16009
  )
15981
16010
  ] }, `${item.uuid || item.created_at}-${index}`)) }, section2.title)),
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  __require,
3
3
  languageOptions
4
- } from "./chunk-IVOOB4JK.mjs";
4
+ } from "./chunk-UVRSRLYW.mjs";
5
5
 
6
6
  // src/RedactoPrivacyCenter/RedactoPrivacyCenter.tsx
7
7
  import { useEffect as useEffect20 } from "react";
@@ -15626,10 +15626,10 @@ import { useTranslation as useTranslation13 } from "react-i18next";
15626
15626
  // src/RedactoPrivacyCenter/lib/dateGroup.ts
15627
15627
  import { useCallback as useCallback8 } from "react";
15628
15628
  import { useTranslation as useTranslation12 } from "react-i18next";
15629
- function monthKey(ts) {
15629
+ function monthKey(ts, locale) {
15630
15630
  if (!ts) return "";
15631
15631
  try {
15632
- return new Date(ts).toLocaleDateString(void 0, { month: "long", year: "numeric" });
15632
+ return new Date(ts).toLocaleDateString(locale || void 0, { month: "long", year: "numeric" });
15633
15633
  } catch {
15634
15634
  return "";
15635
15635
  }
@@ -15705,7 +15705,7 @@ function groupByTime(items, getTs, classify) {
15705
15705
  );
15706
15706
  }
15707
15707
  function useRelativeDate() {
15708
- const { t } = useTranslation12();
15708
+ const { t, i18n: i18n2 } = useTranslation12();
15709
15709
  return useCallback8(
15710
15710
  (ts) => {
15711
15711
  if (!ts) return "";
@@ -15718,7 +15718,7 @@ function useRelativeDate() {
15718
15718
  if (dayDiff <= 0) return t("today", { defaultValue: "Today" });
15719
15719
  if (dayDiff === 1) return t("yesterday", { defaultValue: "Yesterday" });
15720
15720
  if (dayDiff < 7) return t("daysAgo", { count: dayDiff, defaultValue: "{{count}} days ago" });
15721
- return d.toLocaleDateString(void 0, {
15721
+ return d.toLocaleDateString(i18n2.language || void 0, {
15722
15722
  month: "short",
15723
15723
  day: "numeric",
15724
15724
  ...d.getFullYear() !== now.getFullYear() ? { year: "numeric" } : {}
@@ -15727,10 +15727,28 @@ function useRelativeDate() {
15727
15727
  return ts;
15728
15728
  }
15729
15729
  },
15730
- [t]
15730
+ [t, i18n2.language]
15731
15731
  );
15732
15732
  }
15733
15733
 
15734
+ // src/RedactoPrivacyCenter/lib/receiptEvent.ts
15735
+ function eventLabelKey(eventType) {
15736
+ const v = String(eventType || "").toUpperCase();
15737
+ if (v.includes("GRANT")) {
15738
+ return "consentGranted";
15739
+ }
15740
+ if (v.includes("WITHDRAW") || v.includes("REVOK")) {
15741
+ return "consentRevoked";
15742
+ }
15743
+ if (v.includes("DECLIN")) {
15744
+ return "consentDeclined";
15745
+ }
15746
+ if (v.includes("EXPIR")) {
15747
+ return "consentExpired";
15748
+ }
15749
+ return void 0;
15750
+ }
15751
+
15734
15752
  // src/RedactoPrivacyCenter/components/ReceiptsList.tsx
15735
15753
  import { Fragment as Fragment7, jsx as jsx41, jsxs as jsxs25 } from "react/jsx-runtime";
15736
15754
  var PAGE_SIZE2 = 10;
@@ -15766,11 +15784,10 @@ function receiptBadgeStatus(eventType) {
15766
15784
  if (v.includes("EXPIR")) return "warning";
15767
15785
  return "secondary";
15768
15786
  }
15769
- var ReceiptRow = React15.memo(({ item, colors, downloading, onDownload, downloadLabel, dateLabel }) => {
15787
+ var ReceiptRow = React15.memo(({ item, colors, downloading, onDownload, downloadLabel, dateLabel, eventLabel }) => {
15770
15788
  const product = item.product_name_display || item.product_name || "";
15771
- const event = item.event_type_display || item.event_type || "";
15772
- const primary = product || event || "-";
15773
- const badgeLabel = event || "-";
15789
+ const primary = product || eventLabel || "-";
15790
+ const badgeLabel = eventLabel || "-";
15774
15791
  return /* @__PURE__ */ jsxs25(View30, { style: styles31.row, children: [
15775
15792
  /* @__PURE__ */ jsx41(NameAvatar, { name: primary, seed: item.uuid || primary, size: "sm" }),
15776
15793
  /* @__PURE__ */ jsxs25(View30, { style: styles31.body, children: [
@@ -15797,7 +15814,7 @@ var ReceiptRow = React15.memo(({ item, colors, downloading, onDownload, download
15797
15814
  });
15798
15815
  ReceiptRow.displayName = "ReceiptRow";
15799
15816
  function ReceiptsList() {
15800
- const { t } = useTranslation13();
15817
+ const { t, i18n: i18n2 } = useTranslation13();
15801
15818
  const { accessToken, refreshToken, organizationId, workspaceId, updateTokens, onError } = useAuth();
15802
15819
  const { consentClient } = useBaseUrl();
15803
15820
  const { colors } = useTheme();
@@ -15882,14 +15899,18 @@ function ReceiptsList() {
15882
15899
  const sections = useMemo13(() => {
15883
15900
  const map = /* @__PURE__ */ new Map();
15884
15901
  for (const r of receipts) {
15885
- const key = monthKey(r.created_at);
15902
+ const key = monthKey(r.created_at, i18n2.language);
15886
15903
  const arr = map.get(key);
15887
15904
  if (arr) arr.push(r);
15888
15905
  else map.set(key, [r]);
15889
15906
  }
15890
15907
  return Array.from(map, ([title, data]) => ({ title, data }));
15891
- }, [receipts]);
15908
+ }, [receipts, i18n2.language]);
15892
15909
  const downloadLabel = t("download") || "Download";
15910
+ const eventLabelFor = (r) => {
15911
+ const key = eventLabelKey(r.event_type);
15912
+ return key ? t(key) : r.event_type_display || r.event_type || "-";
15913
+ };
15893
15914
  const handleScroll = useCallback9(
15894
15915
  (e) => {
15895
15916
  const { layoutMeasurement, contentOffset, contentSize } = e.nativeEvent;
@@ -15971,7 +15992,8 @@ function ReceiptsList() {
15971
15992
  downloading: downloadingUuid === item.uuid,
15972
15993
  onDownload: handleDownload,
15973
15994
  downloadLabel,
15974
- dateLabel: relativeLabel(item.created_at)
15995
+ dateLabel: relativeLabel(item.created_at),
15996
+ eventLabel: eventLabelFor(item)
15975
15997
  }
15976
15998
  )
15977
15999
  ] }, `${item.uuid || item.created_at}-${index}`)) }, section2.title)),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@redacto.io/consent-sdk-react-native",
3
- "version": "5.0.0-beta.3",
3
+ "version": "5.0.0-beta.4",
4
4
  "description": "React Native SDK for integrating Redacto consent notices and privacy center in mobile apps.",
5
5
  "keywords": [
6
6
  "consent",