@umituz/react-native-subscription 2.14.16 → 2.14.18
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 +9 -1
- package/src/presentation/components/details/PremiumDetailsCard.tsx +2 -2
- package/src/presentation/components/details/PremiumStatusBadge.tsx +31 -27
- package/src/presentation/hooks/useSubscriptionSettingsConfig.ts +10 -14
- package/src/presentation/screens/SubscriptionDetailScreen.tsx +80 -96
- package/src/presentation/screens/components/CreditItem.tsx +81 -86
- package/src/presentation/screens/components/CreditsList.tsx +62 -60
- package/src/presentation/screens/components/DevTestSection.tsx +70 -66
- package/src/presentation/screens/components/SubscriptionActions.tsx +40 -66
- package/src/presentation/screens/components/SubscriptionHeader.tsx +138 -144
- package/src/presentation/types/SubscriptionDetailTypes.ts +113 -0
- package/src/presentation/types/SubscriptionSettingsTypes.ts +3 -3
|
@@ -3,69 +3,71 @@
|
|
|
3
3
|
* Displays list of credit usages
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import React from "react";
|
|
7
|
-
import { View,
|
|
8
|
-
import { useAppDesignTokens } from "@umituz/react-native-design-system";
|
|
6
|
+
import React, { useMemo } from "react";
|
|
7
|
+
import { View, StyleSheet } from "react-native";
|
|
8
|
+
import { useAppDesignTokens, AtomicText } from "@umituz/react-native-design-system";
|
|
9
9
|
import { CreditItem } from "./CreditItem";
|
|
10
|
-
import type {
|
|
11
|
-
|
|
12
|
-
interface CreditsListProps {
|
|
13
|
-
credits: CreditInfo[];
|
|
14
|
-
title?: string;
|
|
15
|
-
description?: string;
|
|
16
|
-
remainingLabel?: string;
|
|
17
|
-
}
|
|
10
|
+
import type { CreditsListProps } from "../../types/SubscriptionDetailTypes";
|
|
18
11
|
|
|
19
12
|
export const CreditsList: React.FC<CreditsListProps> = ({
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
13
|
+
credits,
|
|
14
|
+
title,
|
|
15
|
+
description,
|
|
16
|
+
remainingLabel,
|
|
24
17
|
}) => {
|
|
25
|
-
|
|
18
|
+
const tokens = useAppDesignTokens();
|
|
26
19
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
))}
|
|
49
|
-
</View>
|
|
50
|
-
</View>
|
|
51
|
-
);
|
|
52
|
-
};
|
|
20
|
+
const styles = useMemo(
|
|
21
|
+
() =>
|
|
22
|
+
StyleSheet.create({
|
|
23
|
+
container: {
|
|
24
|
+
borderRadius: tokens.borderRadius.lg,
|
|
25
|
+
padding: tokens.spacing.lg,
|
|
26
|
+
gap: tokens.spacing.lg,
|
|
27
|
+
backgroundColor: tokens.colors.surface,
|
|
28
|
+
},
|
|
29
|
+
title: {
|
|
30
|
+
fontWeight: "700",
|
|
31
|
+
},
|
|
32
|
+
description: {
|
|
33
|
+
marginTop: -tokens.spacing.sm,
|
|
34
|
+
},
|
|
35
|
+
list: {
|
|
36
|
+
gap: tokens.spacing.lg,
|
|
37
|
+
},
|
|
38
|
+
}),
|
|
39
|
+
[tokens]
|
|
40
|
+
);
|
|
53
41
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
}
|
|
42
|
+
return (
|
|
43
|
+
<View style={styles.container}>
|
|
44
|
+
{title && (
|
|
45
|
+
<AtomicText
|
|
46
|
+
type="titleMedium"
|
|
47
|
+
style={[styles.title, { color: tokens.colors.textPrimary }]}
|
|
48
|
+
>
|
|
49
|
+
{title}
|
|
50
|
+
</AtomicText>
|
|
51
|
+
)}
|
|
52
|
+
{description && (
|
|
53
|
+
<AtomicText
|
|
54
|
+
type="bodySmall"
|
|
55
|
+
style={[styles.description, { color: tokens.colors.textSecondary }]}
|
|
56
|
+
>
|
|
57
|
+
{description}
|
|
58
|
+
</AtomicText>
|
|
59
|
+
)}
|
|
60
|
+
<View style={styles.list}>
|
|
61
|
+
{credits.map((credit) => (
|
|
62
|
+
<CreditItem
|
|
63
|
+
key={credit.id}
|
|
64
|
+
label={credit.label}
|
|
65
|
+
current={credit.current}
|
|
66
|
+
total={credit.total}
|
|
67
|
+
remainingLabel={remainingLabel}
|
|
68
|
+
/>
|
|
69
|
+
))}
|
|
70
|
+
</View>
|
|
71
|
+
</View>
|
|
72
|
+
);
|
|
73
|
+
};
|
|
@@ -4,118 +4,122 @@
|
|
|
4
4
|
* Only visible in __DEV__ mode
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import React from "react";
|
|
7
|
+
import React, { useMemo } from "react";
|
|
8
8
|
import { View, TouchableOpacity, StyleSheet } from "react-native";
|
|
9
9
|
import { AtomicText, useAppDesignTokens } from "@umituz/react-native-design-system";
|
|
10
|
+
import type { DevTestSectionProps } from "../../types/SubscriptionDetailTypes";
|
|
10
11
|
|
|
11
|
-
export
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
export type { DevTestActions, DevTestSectionProps } from "../../types/SubscriptionDetailTypes";
|
|
13
|
+
|
|
14
|
+
/** Dev test button translations */
|
|
15
|
+
export interface DevTestTranslations {
|
|
16
|
+
title: string;
|
|
17
|
+
testRenewal: string;
|
|
18
|
+
checkCredits: string;
|
|
19
|
+
testDuplicate: string;
|
|
15
20
|
}
|
|
16
21
|
|
|
17
|
-
export interface DevTestSectionProps {
|
|
18
|
-
|
|
19
|
-
title?: string;
|
|
22
|
+
export interface DevTestSectionWithTranslationsProps extends DevTestSectionProps {
|
|
23
|
+
translations?: DevTestTranslations;
|
|
20
24
|
}
|
|
21
25
|
|
|
22
|
-
export const DevTestSection: React.FC<
|
|
26
|
+
export const DevTestSection: React.FC<DevTestSectionWithTranslationsProps> = ({
|
|
23
27
|
actions,
|
|
24
|
-
title
|
|
28
|
+
title,
|
|
29
|
+
translations,
|
|
25
30
|
}) => {
|
|
26
31
|
const tokens = useAppDesignTokens();
|
|
27
32
|
|
|
33
|
+
const styles = useMemo(
|
|
34
|
+
() =>
|
|
35
|
+
StyleSheet.create({
|
|
36
|
+
container: {
|
|
37
|
+
padding: tokens.spacing.lg,
|
|
38
|
+
gap: tokens.spacing.md,
|
|
39
|
+
borderTopWidth: 1,
|
|
40
|
+
backgroundColor: tokens.colors.surfaceSecondary,
|
|
41
|
+
borderTopColor: tokens.colors.border,
|
|
42
|
+
},
|
|
43
|
+
title: {
|
|
44
|
+
fontWeight: "600",
|
|
45
|
+
marginBottom: tokens.spacing.xs,
|
|
46
|
+
},
|
|
47
|
+
button: {
|
|
48
|
+
paddingVertical: tokens.spacing.md,
|
|
49
|
+
paddingHorizontal: tokens.spacing.lg,
|
|
50
|
+
borderRadius: tokens.borderRadius.md,
|
|
51
|
+
alignItems: "center",
|
|
52
|
+
},
|
|
53
|
+
primaryButton: {
|
|
54
|
+
backgroundColor: tokens.colors.primary,
|
|
55
|
+
},
|
|
56
|
+
secondaryButton: {
|
|
57
|
+
backgroundColor: tokens.colors.surfaceSecondary,
|
|
58
|
+
borderWidth: 1,
|
|
59
|
+
borderColor: tokens.colors.border,
|
|
60
|
+
},
|
|
61
|
+
buttonText: {
|
|
62
|
+
fontWeight: "500",
|
|
63
|
+
},
|
|
64
|
+
}),
|
|
65
|
+
[tokens]
|
|
66
|
+
);
|
|
67
|
+
|
|
28
68
|
if (!__DEV__) {
|
|
29
69
|
return null;
|
|
30
70
|
}
|
|
31
71
|
|
|
72
|
+
const displayTitle = title || translations?.title;
|
|
73
|
+
const renewalText = translations?.testRenewal || "Test Auto-Renewal";
|
|
74
|
+
const creditsText = translations?.checkCredits || "Check Credits";
|
|
75
|
+
const duplicateText = translations?.testDuplicate || "Test Duplicate Protection";
|
|
76
|
+
|
|
32
77
|
return (
|
|
33
|
-
<View
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
<AtomicText
|
|
43
|
-
type="titleMedium"
|
|
44
|
-
style={[styles.title, { color: tokens.colors.textPrimary }]}
|
|
45
|
-
>
|
|
46
|
-
{title}
|
|
47
|
-
</AtomicText>
|
|
78
|
+
<View style={styles.container}>
|
|
79
|
+
{displayTitle && (
|
|
80
|
+
<AtomicText
|
|
81
|
+
type="titleMedium"
|
|
82
|
+
style={[styles.title, { color: tokens.colors.textPrimary }]}
|
|
83
|
+
>
|
|
84
|
+
{displayTitle}
|
|
85
|
+
</AtomicText>
|
|
86
|
+
)}
|
|
48
87
|
|
|
49
88
|
<TouchableOpacity
|
|
50
|
-
style={[styles.button,
|
|
89
|
+
style={[styles.button, styles.primaryButton]}
|
|
51
90
|
onPress={actions.onTestRenewal}
|
|
52
91
|
>
|
|
53
92
|
<AtomicText
|
|
54
93
|
type="bodyMedium"
|
|
55
94
|
style={[styles.buttonText, { color: tokens.colors.onPrimary }]}
|
|
56
95
|
>
|
|
57
|
-
|
|
96
|
+
{renewalText}
|
|
58
97
|
</AtomicText>
|
|
59
98
|
</TouchableOpacity>
|
|
60
99
|
|
|
61
100
|
<TouchableOpacity
|
|
62
|
-
style={[
|
|
63
|
-
styles.button,
|
|
64
|
-
{
|
|
65
|
-
backgroundColor: tokens.colors.surfaceSecondary,
|
|
66
|
-
borderWidth: 1,
|
|
67
|
-
borderColor: tokens.colors.border,
|
|
68
|
-
},
|
|
69
|
-
]}
|
|
101
|
+
style={[styles.button, styles.secondaryButton]}
|
|
70
102
|
onPress={actions.onCheckCredits}
|
|
71
103
|
>
|
|
72
104
|
<AtomicText
|
|
73
105
|
type="bodyMedium"
|
|
74
106
|
style={[styles.buttonText, { color: tokens.colors.textPrimary }]}
|
|
75
107
|
>
|
|
76
|
-
|
|
108
|
+
{creditsText}
|
|
77
109
|
</AtomicText>
|
|
78
110
|
</TouchableOpacity>
|
|
79
111
|
|
|
80
112
|
<TouchableOpacity
|
|
81
|
-
style={[
|
|
82
|
-
styles.button,
|
|
83
|
-
{
|
|
84
|
-
backgroundColor: tokens.colors.surfaceSecondary,
|
|
85
|
-
borderWidth: 1,
|
|
86
|
-
borderColor: tokens.colors.border,
|
|
87
|
-
},
|
|
88
|
-
]}
|
|
113
|
+
style={[styles.button, styles.secondaryButton]}
|
|
89
114
|
onPress={actions.onTestDuplicate}
|
|
90
115
|
>
|
|
91
116
|
<AtomicText
|
|
92
117
|
type="bodyMedium"
|
|
93
118
|
style={[styles.buttonText, { color: tokens.colors.textPrimary }]}
|
|
94
119
|
>
|
|
95
|
-
|
|
120
|
+
{duplicateText}
|
|
96
121
|
</AtomicText>
|
|
97
122
|
</TouchableOpacity>
|
|
98
123
|
</View>
|
|
99
124
|
);
|
|
100
125
|
};
|
|
101
|
-
|
|
102
|
-
const styles = StyleSheet.create({
|
|
103
|
-
container: {
|
|
104
|
-
padding: 16,
|
|
105
|
-
gap: 12,
|
|
106
|
-
borderTopWidth: 1,
|
|
107
|
-
},
|
|
108
|
-
title: {
|
|
109
|
-
fontWeight: "600",
|
|
110
|
-
marginBottom: 4,
|
|
111
|
-
},
|
|
112
|
-
button: {
|
|
113
|
-
paddingVertical: 12,
|
|
114
|
-
paddingHorizontal: 16,
|
|
115
|
-
borderRadius: 8,
|
|
116
|
-
alignItems: "center",
|
|
117
|
-
},
|
|
118
|
-
buttonText: {
|
|
119
|
-
fontWeight: "500",
|
|
120
|
-
},
|
|
121
|
-
});
|
|
@@ -1,77 +1,51 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Subscription Actions Component
|
|
3
|
-
* Displays
|
|
3
|
+
* Displays upgrade button for non-premium users
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import React from "react";
|
|
6
|
+
import React, { useMemo } from "react";
|
|
7
7
|
import { View, StyleSheet, TouchableOpacity } from "react-native";
|
|
8
8
|
import { useAppDesignTokens, AtomicText } from "@umituz/react-native-design-system";
|
|
9
|
-
|
|
10
|
-
interface SubscriptionActionsProps {
|
|
11
|
-
isPremium: boolean;
|
|
12
|
-
manageButtonLabel?: string;
|
|
13
|
-
upgradeButtonLabel?: string;
|
|
14
|
-
onManage?: () => void;
|
|
15
|
-
onUpgrade?: () => void;
|
|
16
|
-
}
|
|
9
|
+
import type { SubscriptionActionsProps } from "../../types/SubscriptionDetailTypes";
|
|
17
10
|
|
|
18
11
|
export const SubscriptionActions: React.FC<SubscriptionActionsProps> = ({
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
onManage,
|
|
23
|
-
onUpgrade,
|
|
12
|
+
isPremium,
|
|
13
|
+
upgradeButtonLabel,
|
|
14
|
+
onUpgrade,
|
|
24
15
|
}) => {
|
|
25
|
-
|
|
16
|
+
const tokens = useAppDesignTokens();
|
|
26
17
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
<TouchableOpacity
|
|
47
|
-
style={[styles.primaryButton, { backgroundColor: tokens.colors.primary }]}
|
|
48
|
-
onPress={onUpgrade}
|
|
49
|
-
>
|
|
50
|
-
<AtomicText
|
|
51
|
-
type="titleMedium"
|
|
52
|
-
style={{ color: tokens.colors.onPrimary, fontWeight: "700" }}
|
|
53
|
-
>
|
|
54
|
-
{upgradeButtonLabel}
|
|
55
|
-
</AtomicText>
|
|
56
|
-
</TouchableOpacity>
|
|
57
|
-
)}
|
|
58
|
-
</View>
|
|
59
|
-
);
|
|
60
|
-
};
|
|
18
|
+
const styles = useMemo(
|
|
19
|
+
() =>
|
|
20
|
+
StyleSheet.create({
|
|
21
|
+
container: {
|
|
22
|
+
paddingBottom: tokens.spacing.xl,
|
|
23
|
+
},
|
|
24
|
+
primaryButton: {
|
|
25
|
+
paddingVertical: tokens.spacing.md,
|
|
26
|
+
borderRadius: tokens.borderRadius.lg,
|
|
27
|
+
alignItems: "center",
|
|
28
|
+
backgroundColor: tokens.colors.primary,
|
|
29
|
+
},
|
|
30
|
+
buttonText: {
|
|
31
|
+
color: tokens.colors.onPrimary,
|
|
32
|
+
fontWeight: "700",
|
|
33
|
+
},
|
|
34
|
+
}),
|
|
35
|
+
[tokens]
|
|
36
|
+
);
|
|
61
37
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
},
|
|
77
|
-
});
|
|
38
|
+
if (isPremium || !onUpgrade || !upgradeButtonLabel) {
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return (
|
|
43
|
+
<View style={styles.container}>
|
|
44
|
+
<TouchableOpacity style={styles.primaryButton} onPress={onUpgrade}>
|
|
45
|
+
<AtomicText type="titleMedium" style={styles.buttonText}>
|
|
46
|
+
{upgradeButtonLabel}
|
|
47
|
+
</AtomicText>
|
|
48
|
+
</TouchableOpacity>
|
|
49
|
+
</View>
|
|
50
|
+
);
|
|
51
|
+
};
|