@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 +1 -1
- package/src/index.ts +3 -0
- package/src/presentation/hooks/useSubscriptionSettingsConfig.ts +3 -0
- package/src/presentation/screens/SubscriptionDetailScreen.tsx +45 -35
- package/src/presentation/screens/components/UpgradePrompt.tsx +140 -0
- package/src/presentation/types/SubscriptionDetailTypes.ts +23 -0
- package/src/presentation/types/SubscriptionSettingsTypes.ts +7 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@umituz/react-native-subscription",
|
|
3
|
-
"version": "2.14.
|
|
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 {
|
|
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 {
|
|
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<
|
|
25
|
-
|
|
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
|
|
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
|
-
|
|
66
|
-
<
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
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
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
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
|
-
|
|
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 {
|
|
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
|
}
|