@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.
@@ -3,163 +3,157 @@
3
3
  * Displays status badge and subscription details
4
4
  */
5
5
 
6
- import React from "react";
6
+ import React, { useMemo } from "react";
7
7
  import { View, StyleSheet } from "react-native";
8
8
  import { useAppDesignTokens, AtomicText } from "@umituz/react-native-design-system";
9
- import {
10
- PremiumStatusBadge,
11
- type SubscriptionStatusType,
12
- } from "../../components/details/PremiumStatusBadge";
13
-
14
- interface SubscriptionHeaderTranslations {
15
- title: string;
16
- statusLabel: string;
17
- statusActive: string;
18
- statusExpired: string;
19
- statusFree: string;
20
- statusCanceled: string;
21
- expiresLabel: string;
22
- purchasedLabel: string;
23
- lifetimeLabel: string;
24
- }
25
-
26
- interface SubscriptionHeaderProps {
27
- statusType: SubscriptionStatusType;
28
- isPremium: boolean;
29
- isLifetime?: boolean;
30
- expirationDate?: string | null;
31
- purchaseDate?: string | null;
32
- daysRemaining?: number | null;
33
- translations: SubscriptionHeaderTranslations;
34
- }
9
+ import { PremiumStatusBadge } from "../../components/details/PremiumStatusBadge";
10
+ import type { SubscriptionHeaderProps } from "../../types/SubscriptionDetailTypes";
35
11
 
36
12
  export const SubscriptionHeader: React.FC<SubscriptionHeaderProps> = ({
37
- statusType,
38
- isPremium,
39
- isLifetime,
40
- expirationDate,
41
- purchaseDate,
42
- daysRemaining,
43
- translations,
13
+ statusType,
14
+ isPremium,
15
+ isLifetime,
16
+ expirationDate,
17
+ purchaseDate,
18
+ daysRemaining,
19
+ translations,
44
20
  }) => {
45
- const tokens = useAppDesignTokens();
46
- const showExpiring =
47
- daysRemaining !== null &&
48
- daysRemaining !== undefined &&
49
- daysRemaining <= 7;
21
+ const tokens = useAppDesignTokens();
22
+ const showExpiring =
23
+ daysRemaining !== null && daysRemaining !== undefined && daysRemaining <= 7;
50
24
 
51
- return (
52
- <View style={[styles.container, { backgroundColor: tokens.colors.surface }]}>
53
- <View style={styles.header}>
54
- <View style={styles.titleContainer}>
55
- <AtomicText type="headlineSmall" style={[styles.title, { color: tokens.colors.textPrimary }]}>
56
- {translations.title}
57
- </AtomicText>
58
- </View>
59
- <PremiumStatusBadge
60
- status={statusType}
61
- activeLabel={translations.statusActive}
62
- expiredLabel={translations.statusExpired}
63
- noneLabel={translations.statusFree}
64
- canceledLabel={translations.statusCanceled}
65
- />
66
- </View>
25
+ const styles = useMemo(
26
+ () =>
27
+ StyleSheet.create({
28
+ container: {
29
+ borderRadius: tokens.borderRadius.lg,
30
+ padding: tokens.spacing.lg,
31
+ gap: tokens.spacing.lg,
32
+ backgroundColor: tokens.colors.surface,
33
+ },
34
+ header: {
35
+ flexDirection: "row",
36
+ justifyContent: "space-between",
37
+ alignItems: "center",
38
+ },
39
+ titleContainer: {
40
+ flex: 1,
41
+ marginRight: tokens.spacing.md,
42
+ },
43
+ title: {
44
+ fontWeight: "700",
45
+ },
46
+ details: {
47
+ gap: tokens.spacing.md,
48
+ paddingTop: tokens.spacing.md,
49
+ },
50
+ row: {
51
+ flexDirection: "row",
52
+ justifyContent: "space-between",
53
+ alignItems: "center",
54
+ gap: tokens.spacing.lg,
55
+ },
56
+ label: {
57
+ flex: 1,
58
+ },
59
+ value: {
60
+ fontWeight: "600",
61
+ textAlign: "right",
62
+ },
63
+ }),
64
+ [tokens]
65
+ );
66
+
67
+ return (
68
+ <View style={styles.container}>
69
+ <View style={styles.header}>
70
+ <View style={styles.titleContainer}>
71
+ <AtomicText
72
+ type="headlineSmall"
73
+ style={[styles.title, { color: tokens.colors.textPrimary }]}
74
+ >
75
+ {translations.title}
76
+ </AtomicText>
77
+ </View>
78
+ <PremiumStatusBadge
79
+ status={statusType}
80
+ activeLabel={translations.statusActive}
81
+ expiredLabel={translations.statusExpired}
82
+ noneLabel={translations.statusFree}
83
+ canceledLabel={translations.statusCanceled}
84
+ />
85
+ </View>
67
86
 
68
- {isPremium && (
69
- <View style={styles.details}>
70
- {isLifetime ? (
71
- <DetailRow
72
- label={translations.statusLabel}
73
- value={translations.lifetimeLabel}
74
- tokens={tokens}
75
- />
76
- ) : (
77
- <>
78
- {expirationDate && (
79
- <DetailRow
80
- label={translations.expiresLabel}
81
- value={expirationDate}
82
- highlight={showExpiring}
83
- tokens={tokens}
84
- />
85
- )}
86
- {purchaseDate && (
87
- <DetailRow
88
- label={translations.purchasedLabel}
89
- value={purchaseDate}
90
- tokens={tokens}
91
- />
92
- )}
93
- </>
94
- )}
95
- </View>
96
- )}
87
+ {isPremium && (
88
+ <View style={styles.details}>
89
+ {isLifetime ? (
90
+ <DetailRow
91
+ label={translations.statusLabel}
92
+ value={translations.lifetimeLabel}
93
+ tokens={tokens}
94
+ styles={styles}
95
+ />
96
+ ) : (
97
+ <>
98
+ {expirationDate && (
99
+ <DetailRow
100
+ label={translations.expiresLabel}
101
+ value={expirationDate}
102
+ highlight={showExpiring}
103
+ tokens={tokens}
104
+ styles={styles}
105
+ />
106
+ )}
107
+ {purchaseDate && (
108
+ <DetailRow
109
+ label={translations.purchasedLabel}
110
+ value={purchaseDate}
111
+ tokens={tokens}
112
+ styles={styles}
113
+ />
114
+ )}
115
+ </>
116
+ )}
97
117
  </View>
98
- );
118
+ )}
119
+ </View>
120
+ );
99
121
  };
100
122
 
101
123
  interface DetailRowProps {
102
- label: string;
103
- value: string;
104
- highlight?: boolean;
105
- tokens: ReturnType<typeof useAppDesignTokens>;
124
+ label: string;
125
+ value: string;
126
+ highlight?: boolean;
127
+ tokens: ReturnType<typeof useAppDesignTokens>;
128
+ styles: {
129
+ row: object;
130
+ label: object;
131
+ value: object;
132
+ };
106
133
  }
107
134
 
108
135
  const DetailRow: React.FC<DetailRowProps> = ({
109
- label,
110
- value,
111
- highlight,
112
- tokens,
136
+ label,
137
+ value,
138
+ highlight,
139
+ tokens,
140
+ styles,
113
141
  }) => (
114
- <View style={styles.row}>
115
- <AtomicText type="bodyMedium" style={[styles.label, { color: tokens.colors.textSecondary }]}>
116
- {label}
117
- </AtomicText>
118
- <AtomicText
119
- type="bodyMedium"
120
- style={[
121
- styles.value,
122
- { color: highlight ? tokens.colors.warning : tokens.colors.textPrimary },
123
- ]}
124
- >
125
- {value}
126
- </AtomicText>
127
- </View>
142
+ <View style={styles.row}>
143
+ <AtomicText
144
+ type="bodyMedium"
145
+ style={[styles.label, { color: tokens.colors.textSecondary }]}
146
+ >
147
+ {label}
148
+ </AtomicText>
149
+ <AtomicText
150
+ type="bodyMedium"
151
+ style={[
152
+ styles.value,
153
+ { color: highlight ? tokens.colors.warning : tokens.colors.textPrimary },
154
+ ]}
155
+ >
156
+ {value}
157
+ </AtomicText>
158
+ </View>
128
159
  );
129
-
130
- const styles = StyleSheet.create({
131
- container: {
132
- borderRadius: 16,
133
- padding: 20,
134
- gap: 16,
135
- },
136
- header: {
137
- flexDirection: "row",
138
- justifyContent: "space-between",
139
- alignItems: "center",
140
- },
141
- titleContainer: {
142
- flex: 1,
143
- marginRight: 12,
144
- },
145
- title: {
146
- fontWeight: "700",
147
- },
148
- details: {
149
- gap: 12,
150
- paddingTop: 12,
151
- },
152
- row: {
153
- flexDirection: "row",
154
- justifyContent: "space-between",
155
- alignItems: "center",
156
- gap: 16,
157
- },
158
- label: {
159
- flex: 1,
160
- },
161
- value: {
162
- fontWeight: "600",
163
- textAlign: "right",
164
- },
165
- });
@@ -0,0 +1,113 @@
1
+ /**
2
+ * Subscription Detail Types
3
+ * Type definitions for subscription detail screen and components
4
+ */
5
+
6
+ import type { SubscriptionStatusType } from "../../domain/entities/SubscriptionStatus";
7
+ import type { CreditInfo } from "../components/details/PremiumDetailsCardTypes";
8
+
9
+ export type { SubscriptionStatusType, CreditInfo };
10
+
11
+ /** Translation strings for subscription detail screen */
12
+ export interface SubscriptionDetailTranslations {
13
+ title: string;
14
+ statusLabel: string;
15
+ statusActive: string;
16
+ statusExpired: string;
17
+ statusFree: string;
18
+ statusCanceled: string;
19
+ expiresLabel: string;
20
+ purchasedLabel: string;
21
+ lifetimeLabel: string;
22
+ creditsTitle: string;
23
+ remainingLabel: string;
24
+ usageTitle?: string;
25
+ manageButton: string;
26
+ upgradeButton: string;
27
+ creditsResetInfo?: string;
28
+ }
29
+
30
+ /** Dev test action callbacks */
31
+ export interface DevTestActions {
32
+ onTestRenewal: () => Promise<void>;
33
+ onCheckCredits: () => void;
34
+ onTestDuplicate: () => Promise<void>;
35
+ }
36
+
37
+ /** Dev tools configuration */
38
+ export interface DevToolsConfig {
39
+ actions: DevTestActions;
40
+ title?: string;
41
+ }
42
+
43
+ /** Configuration for subscription detail screen */
44
+ export interface SubscriptionDetailConfig {
45
+ statusType: SubscriptionStatusType;
46
+ isPremium: boolean;
47
+ expirationDate?: string | null;
48
+ purchaseDate?: string | null;
49
+ isLifetime?: boolean;
50
+ daysRemaining?: number | null;
51
+ willRenew?: boolean;
52
+ credits?: CreditInfo[];
53
+ translations: SubscriptionDetailTranslations;
54
+ onManageSubscription?: () => void;
55
+ onUpgrade?: () => void;
56
+ devTools?: DevToolsConfig;
57
+ }
58
+
59
+ /** Props for subscription detail screen */
60
+ export interface SubscriptionDetailScreenProps {
61
+ config: SubscriptionDetailConfig;
62
+ }
63
+
64
+ /** Props for subscription header component */
65
+ export interface SubscriptionHeaderProps {
66
+ statusType: SubscriptionStatusType;
67
+ isPremium: boolean;
68
+ isLifetime?: boolean;
69
+ expirationDate?: string | null;
70
+ purchaseDate?: string | null;
71
+ daysRemaining?: number | null;
72
+ translations: Pick<
73
+ SubscriptionDetailTranslations,
74
+ | "title"
75
+ | "statusLabel"
76
+ | "statusActive"
77
+ | "statusExpired"
78
+ | "statusFree"
79
+ | "statusCanceled"
80
+ | "expiresLabel"
81
+ | "purchasedLabel"
82
+ | "lifetimeLabel"
83
+ >;
84
+ }
85
+
86
+ /** Props for credits list component */
87
+ export interface CreditsListProps {
88
+ credits: CreditInfo[];
89
+ title?: string;
90
+ description?: string;
91
+ remainingLabel?: string;
92
+ }
93
+
94
+ /** Props for credit item component */
95
+ export interface CreditItemProps {
96
+ label: string;
97
+ current: number;
98
+ total: number;
99
+ remainingLabel?: string;
100
+ }
101
+
102
+ /** Props for subscription actions component */
103
+ export interface SubscriptionActionsProps {
104
+ isPremium: boolean;
105
+ upgradeButtonLabel?: string;
106
+ onUpgrade?: () => void;
107
+ }
108
+
109
+ /** Props for dev test section */
110
+ export interface DevTestSectionProps {
111
+ actions: DevTestActions;
112
+ title?: string;
113
+ }
@@ -3,10 +3,10 @@
3
3
  * Type definitions for subscription settings configuration
4
4
  */
5
5
 
6
- import type { SubscriptionDetailConfig } from "../screens/SubscriptionDetailScreen";
6
+ import type { SubscriptionStatusType } from "../../domain/entities/SubscriptionStatus";
7
+ import type { SubscriptionDetailConfig } from "./SubscriptionDetailTypes";
7
8
 
8
- /** Status type for subscription state */
9
- export type SubscriptionStatusType = "none" | "active" | "expired";
9
+ export type { SubscriptionStatusType };
10
10
 
11
11
  /** Configuration for settings list item */
12
12
  export interface SubscriptionSettingsItemConfig {