@umituz/react-native-subscription 2.10.10 → 2.10.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@umituz/react-native-subscription",
3
- "version": "2.10.10",
3
+ "version": "2.10.11",
4
4
  "description": "Complete subscription management with RevenueCat, paywall UI, and credits system for React Native apps",
5
5
  "main": "./src/index.ts",
6
6
  "types": "./src/index.ts",
@@ -4,6 +4,7 @@ import { AtomicText } from "@umituz/react-native-design-system";
4
4
  import { useAppDesignTokens } from "@umituz/react-native-design-system";
5
5
  import type { PurchasesPackage } from "react-native-purchases";
6
6
  import { SubscriptionPlanCard } from "./SubscriptionPlanCard";
7
+ import { isYearlyPackage } from "../../../utils/packagePeriodUtils";
7
8
 
8
9
  interface SubscriptionPackageListProps {
9
10
  isLoading: boolean;
@@ -12,6 +13,8 @@ interface SubscriptionPackageListProps {
12
13
  loadingText: string;
13
14
  emptyText: string;
14
15
  onSelect: (pkg: PurchasesPackage) => void;
16
+ /** Optional: Manually specify which package should show "Best Value" badge by identifier */
17
+ bestValueIdentifier?: string;
15
18
  }
16
19
 
17
20
  export const SubscriptionPackageList: React.FC<SubscriptionPackageListProps> = React.memo(
@@ -22,6 +25,7 @@ export const SubscriptionPackageList: React.FC<SubscriptionPackageListProps> = R
22
25
  loadingText,
23
26
  emptyText,
24
27
  onSelect,
28
+ bestValueIdentifier,
25
29
  }) => {
26
30
  const tokens = useAppDesignTokens();
27
31
  const hasPackages = packages.length > 0;
@@ -69,15 +73,28 @@ export const SubscriptionPackageList: React.FC<SubscriptionPackageListProps> = R
69
73
 
70
74
  return (
71
75
  <View style={styles.packagesContainer}>
72
- {packages.map((pkg, index) => (
73
- <SubscriptionPlanCard
74
- key={pkg.product.identifier}
75
- package={pkg}
76
- isSelected={selectedPkg?.product.identifier === pkg.product.identifier}
77
- onSelect={() => onSelect(pkg)}
78
- isBestValue={index === 0}
79
- />
80
- ))}
76
+ {packages.map((pkg) => {
77
+ // Determine if this package should show "Best Value" badge
78
+ let isBestValue = false;
79
+
80
+ if (bestValueIdentifier) {
81
+ // Use manual override if provided
82
+ isBestValue = pkg.product.identifier === bestValueIdentifier;
83
+ } else {
84
+ // Auto-detect: mark yearly packages as best value
85
+ isBestValue = isYearlyPackage(pkg);
86
+ }
87
+
88
+ return (
89
+ <SubscriptionPlanCard
90
+ key={pkg.product.identifier}
91
+ package={pkg}
92
+ isSelected={selectedPkg?.product.identifier === pkg.product.identifier}
93
+ onSelect={() => onSelect(pkg)}
94
+ isBestValue={isBestValue}
95
+ />
96
+ );
97
+ })}
81
98
  </View>
82
99
  );
83
100
  }
@@ -12,6 +12,7 @@ import { formatPrice } from "../../../utils/priceUtils";
12
12
  import { useLocalization } from "@umituz/react-native-localization";
13
13
  import { BestValueBadge } from "./BestValueBadge";
14
14
 
15
+ import { getPeriodLabel, isYearlyPackage } from "../../../utils/packagePeriodUtils";
15
16
  // @ts-ignore
16
17
  import { LinearGradient } from "expo-linear-gradient";
17
18
 
@@ -22,26 +23,13 @@ interface SubscriptionPlanCardProps {
22
23
  isBestValue?: boolean;
23
24
  }
24
25
 
25
- const getPeriodLabel = (period: string | null | undefined): string => {
26
- if (!period) return "";
27
- if (period.includes("Y") || period.includes("year")) return "yearly";
28
- if (period.includes("M") || period.includes("month")) return "monthly";
29
- if (period.includes("W") || period.includes("week")) return "weekly";
30
- if (period.includes("D") || period.includes("day")) return "daily";
31
- return "";
32
- };
33
-
34
- const isYearlyPeriod = (period: string | null | undefined): boolean => {
35
- return period?.includes("Y") || period?.includes("year") || false;
36
- };
37
-
38
26
  export const SubscriptionPlanCard: React.FC<SubscriptionPlanCardProps> =
39
27
  React.memo(({ package: pkg, isSelected, onSelect, isBestValue = false }) => {
40
28
  const tokens = useAppDesignTokens();
41
29
  const { t } = useLocalization();
42
30
 
43
31
  const period = pkg.product.subscriptionPeriod;
44
- const isYearly = isYearlyPeriod(period);
32
+ const isYearly = isYearlyPackage(pkg);
45
33
  const periodLabel = getPeriodLabel(period);
46
34
  const price = formatPrice(pkg.product.price, pkg.product.currencyCode);
47
35
  const monthlyEquivalent = isYearly
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Package Period Utilities
3
+ * Helper functions for working with subscription periods
4
+ */
5
+
6
+ import type { PurchasesPackage } from "react-native-purchases";
7
+
8
+ /**
9
+ * Get period label from subscription period string
10
+ */
11
+ export const getPeriodLabel = (period: string | null | undefined): string => {
12
+ if (!period) return "";
13
+ if (period.includes("Y") || period.includes("year")) return "yearly";
14
+ if (period.includes("M") || period.includes("month")) return "monthly";
15
+ if (period.includes("W") || period.includes("week")) return "weekly";
16
+ if (period.includes("D") || period.includes("day")) return "daily";
17
+ return "";
18
+ };
19
+
20
+ /**
21
+ * Check if a package has a yearly subscription period
22
+ */
23
+ export const isYearlyPackage = (pkg: PurchasesPackage): boolean => {
24
+ const period = pkg.product.subscriptionPeriod;
25
+ return period?.includes("Y") || period?.includes("year") || false;
26
+ };
27
+
28
+ /**
29
+ * Check if a package has a monthly subscription period
30
+ */
31
+ export const isMonthlyPackage = (pkg: PurchasesPackage): boolean => {
32
+ const period = pkg.product.subscriptionPeriod;
33
+ return period?.includes("M") || period?.includes("month") || false;
34
+ };
35
+
36
+ /**
37
+ * Check if a package has a weekly subscription period
38
+ */
39
+ export const isWeeklyPackage = (pkg: PurchasesPackage): boolean => {
40
+ const period = pkg.product.subscriptionPeriod;
41
+ return period?.includes("W") || period?.includes("week") || false;
42
+ };
43
+
44
+ /**
45
+ * Find the first yearly package in an array of packages
46
+ */
47
+ export const findYearlyPackage = (
48
+ packages: PurchasesPackage[]
49
+ ): PurchasesPackage | undefined => {
50
+ return packages.find(isYearlyPackage);
51
+ };