@umituz/react-native-subscription 2.14.27 → 2.14.28

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.14.27",
3
+ "version": "2.14.28",
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",
package/src/index.ts CHANGED
@@ -174,6 +174,9 @@ export {
174
174
  type SubscriptionDetailTranslations,
175
175
  type DevTestActions,
176
176
  type DevToolsConfig,
177
+ type UpgradeBenefit,
178
+ type UpgradePromptConfig,
179
+ type UpgradePromptProps,
177
180
  } from "./presentation/screens/SubscriptionDetailScreen";
178
181
 
179
182
  export type {
@@ -42,6 +42,7 @@ export const useSubscriptionSettingsConfig = (
42
42
  currentLanguage = "en",
43
43
  translations,
44
44
  getCreditLimit,
45
+ upgradePrompt,
45
46
  } = params;
46
47
 
47
48
  // Internal hooks
@@ -147,6 +148,7 @@ export const useSubscriptionSettingsConfig = (
147
148
  upgradeButton: translations.upgradeButton,
148
149
  },
149
150
  onUpgrade: openPaywall,
151
+ upgradePrompt,
150
152
  },
151
153
  }),
152
154
  [
@@ -160,6 +162,7 @@ export const useSubscriptionSettingsConfig = (
160
162
  willRenew,
161
163
  creditsArray,
162
164
  openPaywall,
165
+ upgradePrompt,
163
166
  ]
164
167
  );
165
168
 
@@ -6,10 +6,13 @@
6
6
 
7
7
  import React, { useMemo } from "react";
8
8
  import { StyleSheet, View } from "react-native";
9
- import { useAppDesignTokens, ScreenLayout } from "@umituz/react-native-design-system";
9
+ import {
10
+ useAppDesignTokens,
11
+ ScreenLayout,
12
+ } from "@umituz/react-native-design-system";
10
13
  import { SubscriptionHeader } from "./components/SubscriptionHeader";
11
14
  import { CreditsList } from "./components/CreditsList";
12
- import { SubscriptionActions } from "./components/SubscriptionActions";
15
+ import { UpgradePrompt } from "./components/UpgradePrompt";
13
16
  import { DevTestSection } from "./components/DevTestSection";
14
17
  import type { SubscriptionDetailScreenProps } from "../types/SubscriptionDetailTypes";
15
18
 
@@ -19,14 +22,17 @@ export type {
19
22
  SubscriptionDetailScreenProps,
20
23
  DevTestActions,
21
24
  DevToolsConfig,
25
+ UpgradeBenefit,
26
+ UpgradePromptConfig,
27
+ UpgradePromptProps,
22
28
  } from "../types/SubscriptionDetailTypes";
23
29
 
24
- export const SubscriptionDetailScreen: React.FC<SubscriptionDetailScreenProps> = ({
25
- config,
26
- }) => {
30
+ export const SubscriptionDetailScreen: React.FC<
31
+ SubscriptionDetailScreenProps
32
+ > = ({ config }) => {
27
33
  const tokens = useAppDesignTokens();
28
- const showCredits = config.credits && config.credits.length > 0;
29
- const showUpgradeButton = !config.isPremium && config.onUpgrade;
34
+ const showCredits = config.isPremium && config.credits && config.credits.length > 0;
35
+ const showUpgradePrompt = !config.isPremium && config.upgradePrompt;
30
36
 
31
37
  const styles = useMemo(
32
38
  () =>
@@ -62,38 +68,42 @@ export const SubscriptionDetailScreen: React.FC<SubscriptionDetailScreenProps> =
62
68
  ) : undefined
63
69
  }
64
70
  >
65
- <View style={styles.cardsContainer}>
66
- <SubscriptionHeader
67
- statusType={config.statusType}
68
- isPremium={config.isPremium}
69
- isLifetime={config.isLifetime}
70
- expirationDate={config.expirationDate}
71
- purchaseDate={config.purchaseDate}
72
- daysRemaining={config.daysRemaining}
73
- translations={config.translations}
74
- />
71
+ {config.isPremium ? (
72
+ <View style={styles.cardsContainer}>
73
+ <SubscriptionHeader
74
+ statusType={config.statusType}
75
+ isPremium={config.isPremium}
76
+ isLifetime={config.isLifetime}
77
+ expirationDate={config.expirationDate}
78
+ purchaseDate={config.purchaseDate}
79
+ daysRemaining={config.daysRemaining}
80
+ translations={config.translations}
81
+ />
75
82
 
76
- {showCredits && (
77
- <CreditsList
78
- credits={config.credits!}
79
- title={
80
- config.translations.usageTitle || config.translations.creditsTitle
81
- }
82
- description={config.translations.creditsResetInfo}
83
- remainingLabel={config.translations.remainingLabel}
83
+ {showCredits && (
84
+ <CreditsList
85
+ credits={config.credits!}
86
+ title={
87
+ config.translations.usageTitle || config.translations.creditsTitle
88
+ }
89
+ description={config.translations.creditsResetInfo}
90
+ remainingLabel={config.translations.remainingLabel}
91
+ />
92
+ )}
93
+ </View>
94
+ ) : (
95
+ showUpgradePrompt && (
96
+ <UpgradePrompt
97
+ title={config.upgradePrompt!.title}
98
+ subtitle={config.upgradePrompt!.subtitle}
99
+ benefits={config.upgradePrompt!.benefits}
100
+ upgradeButtonLabel={config.translations.upgradeButton}
101
+ onUpgrade={config.onUpgrade}
84
102
  />
85
- )}
86
- </View>
103
+ )
104
+ )}
87
105
 
88
106
  <View style={styles.spacer} />
89
-
90
- {showUpgradeButton && (
91
- <SubscriptionActions
92
- isPremium={config.isPremium}
93
- upgradeButtonLabel={config.translations.upgradeButton}
94
- onUpgrade={config.onUpgrade}
95
- />
96
- )}
97
107
  </ScreenLayout>
98
108
  );
99
109
  };
@@ -0,0 +1,140 @@
1
+ /**
2
+ * Upgrade Prompt Component
3
+ * Displays premium benefits for free users to encourage upgrade
4
+ */
5
+
6
+ import React, { useMemo } from "react";
7
+ import { View, StyleSheet, TouchableOpacity } from "react-native";
8
+ import {
9
+ useAppDesignTokens,
10
+ AtomicText,
11
+ AtomicIcon,
12
+ } from "@umituz/react-native-design-system";
13
+ import type { UpgradePromptProps } from "../../types/SubscriptionDetailTypes";
14
+
15
+ export const UpgradePrompt: React.FC<UpgradePromptProps> = ({
16
+ title,
17
+ subtitle,
18
+ benefits,
19
+ upgradeButtonLabel,
20
+ onUpgrade,
21
+ }) => {
22
+ const tokens = useAppDesignTokens();
23
+
24
+ const styles = useMemo(
25
+ () =>
26
+ StyleSheet.create({
27
+ container: {
28
+ gap: tokens.spacing.lg,
29
+ },
30
+ header: {
31
+ alignItems: "center",
32
+ gap: tokens.spacing.md,
33
+ paddingVertical: tokens.spacing.md,
34
+ },
35
+ iconContainer: {
36
+ width: 64,
37
+ height: 64,
38
+ borderRadius: 32,
39
+ alignItems: "center",
40
+ justifyContent: "center",
41
+ backgroundColor: tokens.colors.primaryContainer,
42
+ },
43
+ title: {
44
+ fontWeight: "700",
45
+ textAlign: "center",
46
+ },
47
+ subtitle: {
48
+ textAlign: "center",
49
+ lineHeight: 22,
50
+ },
51
+ benefitsCard: {
52
+ borderRadius: tokens.borderRadius.lg,
53
+ padding: tokens.spacing.lg,
54
+ gap: tokens.spacing.md,
55
+ backgroundColor: tokens.colors.surface,
56
+ },
57
+ benefitItem: {
58
+ flexDirection: "row",
59
+ alignItems: "center",
60
+ gap: tokens.spacing.md,
61
+ },
62
+ benefitIconWrapper: {
63
+ width: 32,
64
+ height: 32,
65
+ borderRadius: 16,
66
+ alignItems: "center",
67
+ justifyContent: "center",
68
+ backgroundColor: tokens.colors.primaryContainer,
69
+ },
70
+ benefitText: {
71
+ flex: 1,
72
+ },
73
+ upgradeButton: {
74
+ paddingVertical: tokens.spacing.lg,
75
+ borderRadius: tokens.borderRadius.lg,
76
+ alignItems: "center",
77
+ backgroundColor: tokens.colors.primary,
78
+ },
79
+ buttonText: {
80
+ color: tokens.colors.onPrimary,
81
+ fontWeight: "700",
82
+ },
83
+ }),
84
+ [tokens]
85
+ );
86
+
87
+ return (
88
+ <View style={styles.container}>
89
+ <View style={styles.header}>
90
+ <View style={styles.iconContainer}>
91
+ <AtomicIcon name="Sparkles" customSize={32} color="primary" />
92
+ </View>
93
+ <AtomicText
94
+ type="headlineSmall"
95
+ style={[styles.title, { color: tokens.colors.textPrimary }]}
96
+ >
97
+ {title}
98
+ </AtomicText>
99
+ {subtitle && (
100
+ <AtomicText
101
+ type="bodyMedium"
102
+ style={[styles.subtitle, { color: tokens.colors.textSecondary }]}
103
+ >
104
+ {subtitle}
105
+ </AtomicText>
106
+ )}
107
+ </View>
108
+
109
+ {benefits && benefits.length > 0 && (
110
+ <View style={styles.benefitsCard}>
111
+ {benefits.map((benefit, index) => (
112
+ <View key={index} style={styles.benefitItem}>
113
+ <View style={styles.benefitIconWrapper}>
114
+ <AtomicIcon
115
+ name={benefit.icon || "Check"}
116
+ customSize={16}
117
+ color="primary"
118
+ />
119
+ </View>
120
+ <AtomicText
121
+ type="bodyMedium"
122
+ style={[styles.benefitText, { color: tokens.colors.textPrimary }]}
123
+ >
124
+ {benefit.text}
125
+ </AtomicText>
126
+ </View>
127
+ ))}
128
+ </View>
129
+ )}
130
+
131
+ {onUpgrade && upgradeButtonLabel && (
132
+ <TouchableOpacity style={styles.upgradeButton} onPress={onUpgrade}>
133
+ <AtomicText type="titleMedium" style={styles.buttonText}>
134
+ {upgradeButtonLabel}
135
+ </AtomicText>
136
+ </TouchableOpacity>
137
+ )}
138
+ </View>
139
+ );
140
+ };
@@ -40,6 +40,19 @@ export interface DevToolsConfig {
40
40
  title?: string;
41
41
  }
42
42
 
43
+ /** Benefit item for upgrade prompt */
44
+ export interface UpgradeBenefit {
45
+ icon?: string;
46
+ text: string;
47
+ }
48
+
49
+ /** Upgrade prompt configuration */
50
+ export interface UpgradePromptConfig {
51
+ title: string;
52
+ subtitle?: string;
53
+ benefits?: UpgradeBenefit[];
54
+ }
55
+
43
56
  /** Configuration for subscription detail screen */
44
57
  export interface SubscriptionDetailConfig {
45
58
  statusType: SubscriptionStatusType;
@@ -54,6 +67,7 @@ export interface SubscriptionDetailConfig {
54
67
  onManageSubscription?: () => void;
55
68
  onUpgrade?: () => void;
56
69
  devTools?: DevToolsConfig;
70
+ upgradePrompt?: UpgradePromptConfig;
57
71
  }
58
72
 
59
73
  /** Props for subscription detail screen */
@@ -111,3 +125,12 @@ export interface DevTestSectionProps {
111
125
  actions: DevTestActions;
112
126
  title?: string;
113
127
  }
128
+
129
+ /** Props for upgrade prompt component */
130
+ export interface UpgradePromptProps {
131
+ title: string;
132
+ subtitle?: string;
133
+ benefits?: UpgradeBenefit[];
134
+ upgradeButtonLabel?: string;
135
+ onUpgrade?: () => void;
136
+ }
@@ -4,9 +4,12 @@
4
4
  */
5
5
 
6
6
  import type { SubscriptionStatusType } from "../../domain/entities/SubscriptionStatus";
7
- import type { SubscriptionDetailConfig } from "./SubscriptionDetailTypes";
7
+ import type {
8
+ SubscriptionDetailConfig,
9
+ UpgradePromptConfig,
10
+ } from "./SubscriptionDetailTypes";
8
11
 
9
- export type { SubscriptionStatusType };
12
+ export type { SubscriptionStatusType, UpgradePromptConfig };
10
13
 
11
14
  /** Configuration for settings list item */
12
15
  export interface SubscriptionSettingsItemConfig {
@@ -64,4 +67,6 @@ export interface UseSubscriptionSettingsConfigParams {
64
67
  translations: SubscriptionSettingsTranslations;
65
68
  /** Credit limit calculator */
66
69
  getCreditLimit?: (currentCredits: number) => number;
70
+ /** Upgrade prompt configuration for free users */
71
+ upgradePrompt?: UpgradePromptConfig;
67
72
  }