@umituz/react-native-subscription 2.12.16 → 2.12.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.
Files changed (48) hide show
  1. package/package.json +14 -7
  2. package/src/application/ports/ISubscriptionRepository.ts +1 -1
  3. package/src/application/ports/ISubscriptionService.ts +1 -1
  4. package/src/domain/value-objects/SubscriptionConfig.ts +1 -1
  5. package/src/domains/paywall/components/CreditCard.tsx +5 -2
  6. package/src/domains/paywall/components/FeatureList.tsx +1 -1
  7. package/src/domains/paywall/components/PaywallModal.tsx +7 -3
  8. package/src/domains/paywall/components/PaywallTabBar.tsx +1 -1
  9. package/src/domains/paywall/components/PlanCard.tsx +3 -1
  10. package/src/domains/paywall/entities/types.ts +1 -0
  11. package/src/index.ts +55 -53
  12. package/src/infrastructure/repositories/CreditsRepository.ts +3 -3
  13. package/src/infrastructure/repositories/CreditsRepositoryProvider.ts +2 -2
  14. package/src/infrastructure/services/ActivationHandler.ts +3 -3
  15. package/src/infrastructure/services/CreditsInitializer.ts +1 -1
  16. package/src/infrastructure/services/SubscriptionService.ts +6 -6
  17. package/src/presentation/components/details/PremiumDetailsCard.tsx +19 -48
  18. package/src/presentation/components/details/PremiumDetailsCardTypes.ts +5 -3
  19. package/src/presentation/components/details/PremiumStatusBadge.tsx +9 -9
  20. package/src/presentation/hooks/useCreditChecker.ts +3 -3
  21. package/src/presentation/hooks/useCredits.ts +2 -2
  22. package/src/presentation/hooks/useDeductCredit.ts +2 -2
  23. package/src/presentation/hooks/useDevTestCallbacks.ts +143 -0
  24. package/src/presentation/hooks/usePremiumWithConfig.ts +2 -2
  25. package/src/presentation/hooks/useSubscription.ts +3 -3
  26. package/src/presentation/hooks/useSubscriptionDetails.ts +2 -2
  27. package/src/presentation/hooks/useUserTier.ts +2 -2
  28. package/src/presentation/hooks/useUserTierWithRepository.ts +1 -1
  29. package/src/presentation/screens/SubscriptionDetailScreen.tsx +12 -11
  30. package/src/presentation/screens/components/CreditItem.tsx +8 -11
  31. package/src/presentation/screens/components/SubscriptionActions.tsx +10 -22
  32. package/src/presentation/screens/components/SubscriptionHeader.tsx +22 -22
  33. package/src/revenuecat/infrastructure/handlers/PackageHandler.ts +2 -2
  34. package/src/revenuecat/infrastructure/managers/SubscriptionManager.ts +7 -7
  35. package/src/revenuecat/infrastructure/services/CustomerInfoListenerManager.ts +2 -2
  36. package/src/revenuecat/infrastructure/services/PurchaseHandler.ts +5 -5
  37. package/src/revenuecat/infrastructure/services/RestoreHandler.ts +5 -5
  38. package/src/revenuecat/infrastructure/services/RevenueCatInitializer.ts +4 -4
  39. package/src/revenuecat/infrastructure/services/RevenueCatService.ts +3 -3
  40. package/src/revenuecat/infrastructure/services/ServiceStateManager.ts +2 -2
  41. package/src/revenuecat/infrastructure/utils/ApiKeyResolver.ts +1 -1
  42. package/src/revenuecat/infrastructure/utils/ExpirationDateCalculator.ts +1 -1
  43. package/src/revenuecat/infrastructure/utils/PremiumStatusSyncer.ts +2 -2
  44. package/src/revenuecat/presentation/hooks/useInitializeSubscription.ts +1 -1
  45. package/src/revenuecat/presentation/hooks/usePurchasePackage.ts +1 -1
  46. package/src/revenuecat/presentation/hooks/useRestorePurchase.ts +1 -1
  47. package/src/revenuecat/presentation/hooks/useRevenueCat.ts +2 -2
  48. package/src/revenuecat/presentation/hooks/useSubscriptionPackages.ts +1 -1
@@ -5,8 +5,8 @@
5
5
  */
6
6
 
7
7
  import React from "react";
8
- import { View, Text, StyleSheet, TouchableOpacity } from "react-native";
9
- import { useAppDesignTokens } from "@umituz/react-native-design-system";
8
+ import { View, StyleSheet, TouchableOpacity } from "react-native";
9
+ import { useAppDesignTokens, AtomicText } from "@umituz/react-native-design-system";
10
10
  import { PremiumStatusBadge } from "./PremiumStatusBadge";
11
11
  import { DetailRow } from "./DetailRow";
12
12
  import { CreditRow } from "./CreditRow";
@@ -33,14 +33,15 @@ export const PremiumDetailsCard: React.FC<PremiumDetailsCardProps> = ({
33
33
  <View style={[styles.card, { backgroundColor: tokens.colors.surface }]}>
34
34
  {(isPremium || showCredits) && (
35
35
  <View style={styles.header}>
36
- <Text style={[styles.title, { color: tokens.colors.text }]}>
36
+ <AtomicText type="titleLarge" style={{ color: tokens.colors.textPrimary }}>
37
37
  {translations.title}
38
- </Text>
38
+ </AtomicText>
39
39
  <PremiumStatusBadge
40
40
  status={statusType}
41
41
  activeLabel={translations.statusActive}
42
42
  expiredLabel={translations.statusExpired}
43
43
  noneLabel={translations.statusFree}
44
+ canceledLabel={translations.statusCanceled}
44
45
  />
45
46
  </View>
46
47
  )}
@@ -48,12 +49,12 @@ export const PremiumDetailsCard: React.FC<PremiumDetailsCardProps> = ({
48
49
  {!isPremium && !showCredits && (
49
50
  <View style={styles.freeUserHeader}>
50
51
  <View style={styles.freeUserTextContainer}>
51
- <Text style={[styles.freeUserTitle, { color: tokens.colors.text }]}>
52
+ <AtomicText type="headlineSmall" style={{ color: tokens.colors.textPrimary, fontWeight: "700" }}>
52
53
  {translations.title}
53
- </Text>
54
- <Text style={[styles.freeUserDescription, { color: tokens.colors.textSecondary }]}>
55
- Unlock all features and create unlimited magic
56
- </Text>
54
+ </AtomicText>
55
+ <AtomicText type="bodyMedium" style={{ color: tokens.colors.textSecondary }}>
56
+ {translations.freeDescription}
57
+ </AtomicText>
57
58
  </View>
58
59
  </View>
59
60
  )}
@@ -94,9 +95,9 @@ export const PremiumDetailsCard: React.FC<PremiumDetailsCardProps> = ({
94
95
  style={[styles.creditsSection, { borderTopColor: tokens.colors.border }]}
95
96
  >
96
97
  {translations.creditsTitle && (
97
- <Text style={[styles.sectionTitle, { color: tokens.colors.text }]}>
98
+ <AtomicText type="labelMedium" style={[styles.sectionTitle, { color: tokens.colors.textPrimary }]}>
98
99
  {translations.creditsTitle}
99
- </Text>
100
+ </AtomicText>
100
101
  )}
101
102
  {credits.map((credit) => (
102
103
  <CreditRow
@@ -119,9 +120,9 @@ export const PremiumDetailsCard: React.FC<PremiumDetailsCardProps> = ({
119
120
  ]}
120
121
  onPress={onManageSubscription}
121
122
  >
122
- <Text style={[styles.secondaryButtonText, { color: tokens.colors.text }]}>
123
+ <AtomicText type="labelLarge" style={{ color: tokens.colors.textPrimary }}>
123
124
  {translations.manageButton}
124
- </Text>
125
+ </AtomicText>
125
126
  </TouchableOpacity>
126
127
  )}
127
128
  {!isPremium && onUpgrade && translations.upgradeButton && (
@@ -129,11 +130,12 @@ export const PremiumDetailsCard: React.FC<PremiumDetailsCardProps> = ({
129
130
  style={[styles.premiumButton, { backgroundColor: tokens.colors.primary }]}
130
131
  onPress={onUpgrade}
131
132
  >
132
- <Text
133
- style={[styles.premiumButtonText, { color: tokens.colors.onPrimary }]}
133
+ <AtomicText
134
+ type="titleMedium"
135
+ style={{ color: tokens.colors.onPrimary, fontWeight: "700" }}
134
136
  >
135
137
  {translations.upgradeButton}
136
- </Text>
138
+ </AtomicText>
137
139
  </TouchableOpacity>
138
140
  )}
139
141
  </View>
@@ -152,41 +154,23 @@ const styles = StyleSheet.create({
152
154
  justifyContent: "space-between",
153
155
  alignItems: "center",
154
156
  },
155
- title: {
156
- fontSize: 18,
157
- fontWeight: "600",
158
- },
159
157
  freeUserHeader: {
160
158
  marginBottom: 4,
161
159
  },
162
160
  freeUserTextContainer: {
163
161
  gap: 6,
164
162
  },
165
- freeUserTitle: {
166
- fontSize: 20,
167
- fontWeight: "700",
168
- },
169
- freeUserDescription: {
170
- fontSize: 15,
171
- fontWeight: "400",
172
- lineHeight: 20,
173
- },
174
163
  premiumButton: {
175
164
  paddingVertical: 16,
176
165
  borderRadius: 12,
177
166
  alignItems: "center",
178
167
  },
179
- premiumButtonText: {
180
- fontSize: 16,
181
- fontWeight: "700",
182
- },
183
168
  detailsSection: {
184
169
  gap: 8,
185
170
  },
186
171
  sectionTitle: {
187
- fontSize: 14,
188
- fontWeight: "600",
189
172
  marginBottom: 4,
173
+ fontWeight: "600",
190
174
  },
191
175
  creditsSection: {
192
176
  gap: 8,
@@ -196,22 +180,9 @@ const styles = StyleSheet.create({
196
180
  actionsSection: {
197
181
  gap: 8,
198
182
  },
199
- primaryButton: {
200
- paddingVertical: 12,
201
- borderRadius: 8,
202
- alignItems: "center",
203
- },
204
- primaryButtonText: {
205
- fontSize: 14,
206
- fontWeight: "600",
207
- },
208
183
  secondaryButton: {
209
184
  paddingVertical: 12,
210
185
  borderRadius: 8,
211
186
  alignItems: "center",
212
187
  },
213
- secondaryButtonText: {
214
- fontSize: 14,
215
- fontWeight: "500",
216
- },
217
188
  });
@@ -14,6 +14,7 @@ export interface CreditInfo {
14
14
 
15
15
  export interface PremiumDetailsTranslations {
16
16
  title: string;
17
+ freeDescription?: string;
17
18
  statusLabel: string;
18
19
  expiresLabel: string;
19
20
  purchasedLabel: string;
@@ -22,9 +23,10 @@ export interface PremiumDetailsTranslations {
22
23
  manageButton?: string;
23
24
  upgradeButton?: string;
24
25
  lifetimeLabel?: string;
25
- statusActive?: string;
26
- statusExpired?: string;
27
- statusFree?: string;
26
+ statusActive: string;
27
+ statusExpired: string;
28
+ statusFree: string;
29
+ statusCanceled: string;
28
30
  }
29
31
 
30
32
  export interface PremiumDetailsCardProps {
@@ -6,15 +6,15 @@
6
6
  import React from "react";
7
7
  import { View, StyleSheet } from "react-native";
8
8
  import { useAppDesignTokens, AtomicText } from "@umituz/react-native-design-system";
9
- import { SubscriptionStatusType } from "../../../domain/entities/SubscriptionStatus";
9
+ import { SubscriptionStatusType } from "@domain/entities/SubscriptionStatus";
10
10
  export type { SubscriptionStatusType };
11
11
 
12
12
  export interface PremiumStatusBadgeProps {
13
13
  status: SubscriptionStatusType;
14
- activeLabel?: string;
15
- expiredLabel?: string;
16
- noneLabel?: string;
17
- canceledLabel?: string;
14
+ activeLabel: string;
15
+ expiredLabel: string;
16
+ noneLabel: string;
17
+ canceledLabel: string;
18
18
  }
19
19
 
20
20
  /**
@@ -22,10 +22,10 @@ export interface PremiumStatusBadgeProps {
22
22
  */
23
23
  export const PremiumStatusBadge: React.FC<PremiumStatusBadgeProps> = ({
24
24
  status,
25
- activeLabel = "Active",
26
- expiredLabel = "Expired",
27
- noneLabel = "Free",
28
- canceledLabel = "Canceled",
25
+ activeLabel,
26
+ expiredLabel,
27
+ noneLabel,
28
+ canceledLabel,
29
29
  }) => {
30
30
  const tokens = useAppDesignTokens();
31
31
 
@@ -5,12 +5,12 @@
5
5
  */
6
6
 
7
7
  import { useMemo } from "react";
8
- import type { CreditType } from "../../domain/entities/Credits";
9
- import { getCreditsRepository } from "../../infrastructure/repositories/CreditsRepositoryProvider";
8
+ import type { CreditType } from "@domain/entities/Credits";
9
+ import { getCreditsRepository } from "@infrastructure/repositories/CreditsRepositoryProvider";
10
10
  import {
11
11
  createCreditChecker,
12
12
  type CreditCheckResult,
13
- } from "../../utils/creditChecker";
13
+ } from "@utils/creditChecker";
14
14
 
15
15
  export interface UseCreditCheckerParams {
16
16
  getCreditType: (operationType: string) => CreditType;
@@ -6,11 +6,11 @@
6
6
  */
7
7
 
8
8
  import { useQuery } from "@tanstack/react-query";
9
- import type { UserCredits, CreditType } from "../../domain/entities/Credits";
9
+ import type { UserCredits, CreditType } from "@domain/entities/Credits";
10
10
  import {
11
11
  getCreditsRepository,
12
12
  getCreditsConfig,
13
- } from "../../infrastructure/repositories/CreditsRepositoryProvider";
13
+ } from "@infrastructure/repositories/CreditsRepositoryProvider";
14
14
 
15
15
  const CACHE_CONFIG = {
16
16
  staleTime: 30 * 1000,
@@ -7,8 +7,8 @@
7
7
 
8
8
  import { useCallback } from "react";
9
9
  import { useMutation, useQueryClient } from "@tanstack/react-query";
10
- import type { CreditType, UserCredits } from "../../domain/entities/Credits";
11
- import { getCreditsRepository } from "../../infrastructure/repositories/CreditsRepositoryProvider";
10
+ import type { CreditType, UserCredits } from "@domain/entities/Credits";
11
+ import { getCreditsRepository } from "@infrastructure/repositories/CreditsRepositoryProvider";
12
12
  import { creditsQueryKeys } from "./useCredits";
13
13
 
14
14
  export interface UseDeductCreditParams {
@@ -0,0 +1,143 @@
1
+ /**
2
+ * Dev Test Callbacks Hook
3
+ * Provides test functions for subscription renewal testing
4
+ * Only used in __DEV__ mode
5
+ */
6
+
7
+ import { useCallback } from "react";
8
+ import { Alert } from "react-native";
9
+ import { useAuth } from "@umituz/react-native-auth";
10
+ import { getCreditsRepository } from "@infrastructure/repositories/CreditsRepositoryProvider";
11
+ import { useCredits } from "./useCredits";
12
+ import type { DevTestActions } from "@presentation/screens/components/DevTestSection";
13
+
14
+ export const useDevTestCallbacks = (): DevTestActions | undefined => {
15
+ const { user } = useAuth();
16
+ const { credits, refetch } = useCredits({ userId: user?.uid });
17
+
18
+ const onTestRenewal = useCallback(async () => {
19
+ if (!user?.uid) {
20
+ Alert.alert("Error", "No user logged in");
21
+ return;
22
+ }
23
+
24
+ try {
25
+ const repository = getCreditsRepository();
26
+ const renewalId = `dev_renewal_${Date.now()}`;
27
+ const productId = "test_yearly_subscription";
28
+
29
+ if (__DEV__) {
30
+ console.log("🧪 [Dev Test] Simulating auto-renewal...", {
31
+ userId: user.uid,
32
+ renewalId,
33
+ });
34
+ }
35
+
36
+ const result = await repository.initializeCredits(
37
+ user.uid,
38
+ renewalId,
39
+ productId,
40
+ );
41
+
42
+ if (__DEV__) {
43
+ console.log("✅ [Dev Test] Renewal completed:", {
44
+ success: result.success,
45
+ textCredits: result.data?.textCredits,
46
+ imageCredits: result.data?.imageCredits,
47
+ });
48
+ }
49
+
50
+ await refetch();
51
+
52
+ Alert.alert(
53
+ "✅ Test Renewal Success",
54
+ `Credits Updated!\n\nText: ${result.data?.textCredits || 0}\nImage: ${result.data?.imageCredits || 0}\n\n(ACCUMULATE mode - credits added to existing)`,
55
+ [{ text: "OK" }],
56
+ );
57
+ } catch (error) {
58
+ if (__DEV__) {
59
+ console.error("❌ [Dev Test] Renewal failed:", error);
60
+ }
61
+ Alert.alert(
62
+ "Test Failed",
63
+ error instanceof Error ? error.message : "Unknown error",
64
+ );
65
+ }
66
+ }, [user?.uid, refetch]);
67
+
68
+ const onCheckCredits = useCallback(() => {
69
+ if (!credits) {
70
+ Alert.alert("Credits", "No credits data available");
71
+ return;
72
+ }
73
+
74
+ Alert.alert(
75
+ "📊 Current Credits",
76
+ `Text Generation: ${credits.textCredits}\nImage Generation: ${credits.imageCredits}\n\nPurchased: ${credits.purchasedAt?.toLocaleDateString() || "N/A"}`,
77
+ [{ text: "OK" }],
78
+ );
79
+ }, [credits]);
80
+
81
+ const onTestDuplicate = useCallback(async () => {
82
+ if (!user?.uid) {
83
+ Alert.alert("Error", "No user logged in");
84
+ return;
85
+ }
86
+
87
+ try {
88
+ const repository = getCreditsRepository();
89
+ const sameRenewalId = "dev_duplicate_test_12345";
90
+
91
+ if (__DEV__) {
92
+ console.log("🧪 [Dev Test] Testing duplicate protection...");
93
+ }
94
+
95
+ const result1 = await repository.initializeCredits(
96
+ user.uid,
97
+ sameRenewalId,
98
+ "test_product",
99
+ );
100
+ if (__DEV__) {
101
+ console.log("First call:", result1.data);
102
+ }
103
+
104
+ const result2 = await repository.initializeCredits(
105
+ user.uid,
106
+ sameRenewalId,
107
+ "test_product",
108
+ );
109
+ if (__DEV__) {
110
+ console.log("Second call:", result2.data);
111
+ }
112
+
113
+ await refetch();
114
+
115
+ const duplicateProtectionWorks =
116
+ result2.data?.textCredits === result1.data?.textCredits;
117
+
118
+ Alert.alert(
119
+ "Duplicate Test",
120
+ `First call: ${result1.success ? "✅ Added credits" : "❌ Failed"}\n\nSecond call: ${duplicateProtectionWorks ? "✅ Skipped (protection works!)" : "❌ Added again (protection failed!)"}`,
121
+ [{ text: "OK" }],
122
+ );
123
+ } catch (error) {
124
+ if (__DEV__) {
125
+ console.error("❌ [Dev Test] Duplicate test failed:", error);
126
+ }
127
+ Alert.alert(
128
+ "Test Failed",
129
+ error instanceof Error ? error.message : "Unknown error",
130
+ );
131
+ }
132
+ }, [user?.uid, refetch]);
133
+
134
+ if (!__DEV__) {
135
+ return undefined;
136
+ }
137
+
138
+ return {
139
+ onTestRenewal,
140
+ onCheckCredits,
141
+ onTestDuplicate,
142
+ };
143
+ };
@@ -11,13 +11,13 @@
11
11
 
12
12
  import { useCallback } from "react";
13
13
  import type { PurchasesPackage } from "react-native-purchases";
14
- import type { UserCredits } from "../../domain/entities/Credits";
14
+ import type { UserCredits } from "@domain/entities/Credits";
15
15
  import { useCredits } from "./useCredits";
16
16
  import {
17
17
  useSubscriptionPackages,
18
18
  usePurchasePackage,
19
19
  useRestorePurchase,
20
- } from "../../revenuecat/presentation/hooks/useSubscriptionQueries";
20
+ } from "@revenuecat/presentation/hooks/useSubscriptionQueries";
21
21
  import { usePaywallVisibility } from "./usePaywallVisibility";
22
22
 
23
23
  export interface UsePremiumWithConfigParams {
@@ -4,9 +4,9 @@
4
4
  */
5
5
 
6
6
  import { useState, useCallback } from 'react';
7
- import { getSubscriptionService } from '../../infrastructure/services/SubscriptionService';
8
- import type { SubscriptionStatus } from '../../domain/entities/SubscriptionStatus';
9
- import { isSubscriptionValid } from '../../domain/entities/SubscriptionStatus';
7
+ import { getSubscriptionService } from '@infrastructure/services/SubscriptionService';
8
+ import type { SubscriptionStatus } from '@domain/entities/SubscriptionStatus';
9
+ import { isSubscriptionValid } from '@domain/entities/SubscriptionStatus';
10
10
 
11
11
  export interface UseSubscriptionResult {
12
12
  /** Current subscription status */
@@ -4,11 +4,11 @@
4
4
  */
5
5
 
6
6
  import { useMemo } from "react";
7
- import type { SubscriptionStatus } from "../../domain/entities/SubscriptionStatus";
7
+ import type { SubscriptionStatus } from "@domain/entities/SubscriptionStatus";
8
8
  import {
9
9
  getDaysUntilExpiration,
10
10
  isSubscriptionExpired,
11
- } from "../../utils/dateValidationUtils";
11
+ } from "@utils/dateValidationUtils";
12
12
 
13
13
  export interface SubscriptionDetails {
14
14
  /** Raw subscription status */
@@ -27,8 +27,8 @@
27
27
  */
28
28
 
29
29
  import { useMemo } from 'react';
30
- import { getUserTierInfo } from '../../utils/tierUtils';
31
- import type { UserTierInfo } from '../../utils/types';
30
+ import { getUserTierInfo } from '@utils/tierUtils';
31
+ import type { UserTierInfo } from '@utils/types';
32
32
 
33
33
  export interface UseUserTierParams {
34
34
  /** Whether user is a guest */
@@ -25,7 +25,7 @@
25
25
 
26
26
  import { useEffect, useState, useCallback } from 'react';
27
27
  import { useUserTier, type UseUserTierParams } from './useUserTier';
28
- import type { ISubscriptionRepository } from '../../application/ports/ISubscriptionRepository';
28
+ import type { ISubscriptionRepository } from '@application/ports/ISubscriptionRepository';
29
29
 
30
30
  /**
31
31
  * Auth provider interface
@@ -16,18 +16,19 @@ import type { CreditInfo } from "../components/details/PremiumDetailsCard";
16
16
 
17
17
  export interface SubscriptionDetailTranslations {
18
18
  title: string;
19
- statusLabel?: string;
20
- statusActive?: string;
21
- statusExpired?: string;
22
- statusFree?: string;
23
- expiresLabel?: string;
24
- purchasedLabel?: string;
25
- lifetimeLabel?: string;
26
- creditsTitle?: string;
27
- remainingLabel?: string;
19
+ statusLabel: string;
20
+ statusActive: string;
21
+ statusExpired: string;
22
+ statusFree: string;
23
+ statusCanceled: string;
24
+ expiresLabel: string;
25
+ purchasedLabel: string;
26
+ lifetimeLabel: string;
27
+ creditsTitle: string;
28
+ remainingLabel: string;
28
29
  usageTitle?: string;
29
- manageButton?: string;
30
- upgradeButton?: string;
30
+ manageButton: string;
31
+ upgradeButton: string;
31
32
  creditsResetInfo?: string;
32
33
  }
33
34
 
@@ -4,8 +4,8 @@
4
4
  */
5
5
 
6
6
  import React from "react";
7
- import { View, Text, StyleSheet } from "react-native";
8
- import { useAppDesignTokens } from "@umituz/react-native-design-system";
7
+ import { View, StyleSheet } from "react-native";
8
+ import { useAppDesignTokens, AtomicText } from "@umituz/react-native-design-system";
9
9
 
10
10
  interface CreditItemProps {
11
11
  label: string;
@@ -34,13 +34,13 @@ export const CreditItem: React.FC<CreditItemProps> = ({
34
34
  return (
35
35
  <View style={styles.container}>
36
36
  <View style={styles.header}>
37
- <Text style={[styles.label, { color: tokens.colors.textPrimary }]}>
37
+ <AtomicText type="bodyMedium" style={[styles.label, { color: tokens.colors.textPrimary }]}>
38
38
  {label}
39
- </Text>
39
+ </AtomicText>
40
40
  <View style={[styles.badge, { backgroundColor: tokens.colors.surfaceSecondary }]}>
41
- <Text style={[styles.count, { color: getColor() }]}>
41
+ <AtomicText type="labelSmall" style={[styles.count, { color: getColor() }]}>
42
42
  {current} / {total}
43
- </Text>
43
+ </AtomicText>
44
44
  </View>
45
45
  </View>
46
46
  <View
@@ -59,9 +59,9 @@ export const CreditItem: React.FC<CreditItemProps> = ({
59
59
  ]}
60
60
  />
61
61
  </View>
62
- <Text style={[styles.remaining, { color: tokens.colors.textSecondary }]}>
62
+ <AtomicText type="bodySmall" style={[styles.remaining, { color: tokens.colors.textSecondary }]}>
63
63
  {current} {remainingLabel}
64
- </Text>
64
+ </AtomicText>
65
65
  </View>
66
66
  );
67
67
  };
@@ -76,7 +76,6 @@ const styles = StyleSheet.create({
76
76
  alignItems: "center",
77
77
  },
78
78
  label: {
79
- fontSize: 15,
80
79
  fontWeight: "500",
81
80
  },
82
81
  badge: {
@@ -85,7 +84,6 @@ const styles = StyleSheet.create({
85
84
  borderRadius: 12,
86
85
  },
87
86
  count: {
88
- fontSize: 13,
89
87
  fontWeight: "600",
90
88
  },
91
89
  progressBar: {
@@ -98,6 +96,5 @@ const styles = StyleSheet.create({
98
96
  borderRadius: 4,
99
97
  },
100
98
  remaining: {
101
- fontSize: 12,
102
99
  },
103
100
  });
@@ -4,8 +4,8 @@
4
4
  */
5
5
 
6
6
  import React from "react";
7
- import { View, Text, StyleSheet, TouchableOpacity } from "react-native";
8
- import { useAppDesignTokens } from "@umituz/react-native-design-system";
7
+ import { View, StyleSheet, TouchableOpacity } from "react-native";
8
+ import { useAppDesignTokens, AtomicText } from "@umituz/react-native-design-system";
9
9
 
10
10
  interface SubscriptionActionsProps {
11
11
  isPremium: boolean;
@@ -34,14 +34,12 @@ export const SubscriptionActions: React.FC<SubscriptionActionsProps> = ({
34
34
  ]}
35
35
  onPress={onManage}
36
36
  >
37
- <Text
38
- style={[
39
- styles.secondaryButtonText,
40
- { color: tokens.colors.textPrimary },
41
- ]}
37
+ <AtomicText
38
+ type="titleMedium"
39
+ style={{ color: tokens.colors.textPrimary, fontWeight: "600" }}
42
40
  >
43
41
  {manageButtonLabel}
44
- </Text>
42
+ </AtomicText>
45
43
  </TouchableOpacity>
46
44
  )}
47
45
  {!isPremium && onUpgrade && upgradeButtonLabel && (
@@ -49,14 +47,12 @@ export const SubscriptionActions: React.FC<SubscriptionActionsProps> = ({
49
47
  style={[styles.primaryButton, { backgroundColor: tokens.colors.primary }]}
50
48
  onPress={onUpgrade}
51
49
  >
52
- <Text
53
- style={[
54
- styles.primaryButtonText,
55
- { color: tokens.colors.onPrimary },
56
- ]}
50
+ <AtomicText
51
+ type="titleMedium"
52
+ style={{ color: tokens.colors.onPrimary, fontWeight: "700" }}
57
53
  >
58
54
  {upgradeButtonLabel}
59
- </Text>
55
+ </AtomicText>
60
56
  </TouchableOpacity>
61
57
  )}
62
58
  </View>
@@ -73,17 +69,9 @@ const styles = StyleSheet.create({
73
69
  borderRadius: 12,
74
70
  alignItems: "center",
75
71
  },
76
- primaryButtonText: {
77
- fontSize: 16,
78
- fontWeight: "700",
79
- },
80
72
  secondaryButton: {
81
73
  paddingVertical: 16,
82
74
  borderRadius: 12,
83
75
  alignItems: "center",
84
76
  },
85
- secondaryButtonText: {
86
- fontSize: 16,
87
- fontWeight: "600",
88
- },
89
77
  });