@umituz/react-native-subscription 2.14.47 → 2.14.48

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 (32) hide show
  1. package/package.json +2 -2
  2. package/src/domains/paywall/components/PaywallHeader.tsx +1 -0
  3. package/src/domains/paywall/components/PaywallModal.styles.ts +49 -0
  4. package/src/domains/paywall/components/PaywallModal.tsx +2 -37
  5. package/src/domains/wallet/domain/entities/CreditCost.ts +3 -3
  6. package/src/domains/wallet/infrastructure/repositories/TransactionRepository.ts +11 -20
  7. package/src/domains/wallet/presentation/components/BalanceCard.tsx +4 -3
  8. package/src/domains/wallet/presentation/components/TransactionItem.tsx +4 -3
  9. package/src/domains/wallet/presentation/components/TransactionList.tsx +7 -5
  10. package/src/domains/wallet/presentation/hooks/useWallet.ts +6 -4
  11. package/src/domains/wallet/presentation/screens/WalletScreen.tsx +11 -8
  12. package/src/infrastructure/repositories/CreditsRepository.ts +7 -42
  13. package/src/infrastructure/services/CreditsInitializer.ts +1 -52
  14. package/src/presentation/components/feedback/PaywallFeedbackModal.tsx +1 -0
  15. package/src/presentation/components/sections/SubscriptionSection.tsx +4 -3
  16. package/src/presentation/hooks/useCreditChecker.ts +3 -2
  17. package/src/presentation/hooks/useCredits.ts +4 -3
  18. package/src/presentation/hooks/usePremium.ts +4 -3
  19. package/src/presentation/hooks/useSubscriptionDetails.ts +3 -2
  20. package/src/presentation/hooks/useSubscriptionSettingsConfig.ts +4 -3
  21. package/src/presentation/screens/SubscriptionDetailScreen.tsx +3 -2
  22. package/src/presentation/screens/components/UpgradePrompt.tsx +4 -3
  23. package/src/revenuecat/infrastructure/services/CustomerInfoListenerManager.ts +60 -158
  24. package/src/revenuecat/infrastructure/services/OfferingsFetcher.ts +13 -29
  25. package/src/revenuecat/infrastructure/services/PurchaseHandler.ts +64 -88
  26. package/src/revenuecat/infrastructure/services/RestoreHandler.ts +32 -48
  27. package/src/revenuecat/infrastructure/services/RevenueCatInitializer.ts +90 -219
  28. package/src/revenuecat/infrastructure/services/RevenueCatService.ts +121 -126
  29. package/src/revenuecat/infrastructure/utils/InitializationCache.ts +25 -29
  30. package/src/revenuecat/infrastructure/utils/PremiumStatusSyncer.ts +52 -100
  31. package/src/revenuecat/infrastructure/utils/UserIdProvider.ts +17 -25
  32. package/src/revenuecat/presentation/hooks/usePaywallFlow.ts +9 -8
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@umituz/react-native-subscription",
3
- "version": "2.14.47",
3
+ "version": "2.14.48",
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",
@@ -63,7 +63,7 @@
63
63
  "expo-constants": "~16.0.0",
64
64
  "expo-image": "~3.0.0",
65
65
  "expo-linear-gradient": "~15.0.0",
66
- "firebase": "^10.0.0",
66
+ "firebase": "^11.0.0",
67
67
  "react": "19.1.0",
68
68
  "react-native": "0.81.5",
69
69
  "react-native-purchases": "^7.0.0",
@@ -6,6 +6,7 @@
6
6
  import React from "react";
7
7
  import { View, StyleSheet, TouchableOpacity } from "react-native";
8
8
  import { LinearGradient } from "expo-linear-gradient";
9
+ import {
9
10
  AtomicText,
10
11
  AtomicIcon,
11
12
  useDesignSystemTheme,
@@ -0,0 +1,49 @@
1
+ /**
2
+ * PaywallModal Styles
3
+ */
4
+
5
+ import { StyleSheet } from "react-native";
6
+
7
+ export const paywallModalStyles = StyleSheet.create({
8
+ modalContent: { padding: 0, borderWidth: 0, overflow: "hidden" },
9
+ container: { flex: 1 },
10
+ closeBtn: {
11
+ position: "absolute",
12
+ top: 12,
13
+ right: 12,
14
+ width: 32,
15
+ height: 32,
16
+ borderRadius: 16,
17
+ justifyContent: "center",
18
+ alignItems: "center",
19
+ zIndex: 10,
20
+ },
21
+ scroll: { flexGrow: 1, padding: 16, paddingTop: 16, paddingBottom: 32 },
22
+ heroContainer: { alignItems: "center", marginBottom: 20, marginTop: 32 },
23
+ heroImage: { width: 180, height: 180, borderRadius: 90 },
24
+ header: { alignItems: "center", marginBottom: 12 },
25
+ title: { fontWeight: "700", textAlign: "center", marginBottom: 4 },
26
+ subtitle: { textAlign: "center" },
27
+ features: { borderRadius: 12, padding: 12, marginBottom: 12, gap: 8 },
28
+ featureRow: { flexDirection: "row", alignItems: "center" },
29
+ featureIcon: {
30
+ width: 32,
31
+ height: 32,
32
+ borderRadius: 16,
33
+ justifyContent: "center",
34
+ alignItems: "center",
35
+ marginRight: 8,
36
+ },
37
+ featureText: { flex: 1, fontWeight: "500" },
38
+ loading: { alignItems: "center", paddingVertical: 24 },
39
+ loadingText: { marginTop: 8 },
40
+ plans: { marginBottom: 12 },
41
+ cta: { borderRadius: 12, paddingVertical: 14, alignItems: "center", marginBottom: 12 },
42
+ ctaDisabled: { opacity: 0.5 },
43
+ ctaText: { fontWeight: "700" },
44
+ footer: { flexDirection: "column", alignItems: "center", gap: 8 },
45
+ restoreButton: { marginBottom: 8 },
46
+ restoreButtonDisabled: { opacity: 0.5 },
47
+ legalRow: { flexDirection: "row", justifyContent: "center", gap: 16 },
48
+ footerLink: {},
49
+ });
@@ -4,13 +4,14 @@
4
4
  */
5
5
 
6
6
  import React, { useState, useCallback } from "react";
7
- import { View, ScrollView, StyleSheet, TouchableOpacity, ActivityIndicator, Linking, type ImageSourcePropType } from "react-native";
7
+ import { View, ScrollView, TouchableOpacity, ActivityIndicator, Linking, type ImageSourcePropType } from "react-native";
8
8
  import { BaseModal, useAppDesignTokens, AtomicText, AtomicIcon } from "@umituz/react-native-design-system";
9
9
  import { Image } from "expo-image";
10
10
  import type { PurchasesPackage } from "react-native-purchases";
11
11
  import { PlanCard } from "./PlanCard";
12
12
  import { CreditCard } from "./CreditCard";
13
13
  import type { PaywallMode, CreditsPackage, SubscriptionFeature, PaywallTranslations, PaywallLegalUrls } from '../entities';
14
+ import { paywallModalStyles as styles } from "./PaywallModal.styles";
14
15
 
15
16
  export interface PaywallModalProps {
16
17
  visible: boolean;
@@ -60,15 +61,6 @@ export const PaywallModal: React.FC<PaywallModalProps> = React.memo((props) => {
60
61
  const showCredits = mode === "credits";
61
62
  const showSubscription = mode === "subscription" || mode === "hybrid";
62
63
 
63
- // Debug logging
64
- if (__DEV__ && visible) {
65
- console.log("[PaywallModal] Props:", {
66
- hasHeroImage: !!heroImage,
67
- heroImageType: typeof heroImage,
68
- packagesCount: subscriptionPackages.length,
69
- });
70
- }
71
-
72
64
  const handlePurchase = useCallback(async () => {
73
65
  setIsProcessing(true);
74
66
  try {
@@ -234,30 +226,3 @@ export const PaywallModal: React.FC<PaywallModalProps> = React.memo((props) => {
234
226
  });
235
227
 
236
228
  PaywallModal.displayName = "PaywallModal";
237
-
238
- const styles = StyleSheet.create({
239
- modalContent: { padding: 0, borderWidth: 0, overflow: "hidden" },
240
- container: { flex: 1 },
241
- closeBtn: { position: "absolute", top: 12, right: 12, width: 32, height: 32, borderRadius: 16, justifyContent: "center", alignItems: "center", zIndex: 10 },
242
- scroll: { flexGrow: 1, padding: 16, paddingTop: 16, paddingBottom: 32 },
243
- heroContainer: { alignItems: "center", marginBottom: 20, marginTop: 32 },
244
- heroImage: { width: 180, height: 180, borderRadius: 90 },
245
- header: { alignItems: "center", marginBottom: 12 },
246
- title: { fontWeight: "700", textAlign: "center", marginBottom: 4 },
247
- subtitle: { textAlign: "center" },
248
- features: { borderRadius: 12, padding: 12, marginBottom: 12, gap: 8 },
249
- featureRow: { flexDirection: "row", alignItems: "center" },
250
- featureIcon: { width: 32, height: 32, borderRadius: 16, justifyContent: "center", alignItems: "center", marginRight: 8 },
251
- featureText: { flex: 1, fontWeight: "500" },
252
- loading: { alignItems: "center", paddingVertical: 24 },
253
- loadingText: { marginTop: 8 },
254
- plans: { marginBottom: 12 },
255
- cta: { borderRadius: 12, paddingVertical: 14, alignItems: "center", marginBottom: 12 },
256
- ctaDisabled: { opacity: 0.5 },
257
- ctaText: { fontWeight: "700" },
258
- footer: { flexDirection: "column", alignItems: "center", gap: 8 },
259
- restoreButton: { marginBottom: 8 },
260
- restoreButtonDisabled: { opacity: 0.5 },
261
- legalRow: { flexDirection: "row", justifyContent: "center", gap: 16 },
262
- footerLink: {},
263
- });
@@ -6,9 +6,9 @@
6
6
  */
7
7
 
8
8
  import type { AICreditCosts } from "../types/credit-cost.types";
9
-
10
- DEFAULT_AI_CREDIT_COSTS,
11
- createCreditCostConfig,
9
+ import {
10
+ DEFAULT_AI_CREDIT_COSTS,
11
+ createCreditCostConfig,
12
12
  } from "../types/credit-cost.types";
13
13
 
14
14
  export interface CreditCostEntity {
@@ -5,16 +5,17 @@
5
5
  * Generic repository for use across hundreds of apps.
6
6
  */
7
7
 
8
- collection,
9
- getDocs,
10
- addDoc,
11
- query,
12
- where,
13
- orderBy,
14
- limit as firestoreLimit,
15
- serverTimestamp,
16
- type Firestore,
17
- type QueryConstraint,
8
+ import {
9
+ collection,
10
+ getDocs,
11
+ addDoc,
12
+ query,
13
+ where,
14
+ orderBy,
15
+ limit as firestoreLimit,
16
+ serverTimestamp,
17
+ type Firestore,
18
+ type QueryConstraint,
18
19
  } from "firebase/firestore";
19
20
  import { BaseRepository, getFirestore } from "@umituz/react-native-firebase";
20
21
  import type {
@@ -83,9 +84,6 @@ export class TransactionRepository extends BaseRepository {
83
84
 
84
85
  return { success: true, data: transactions };
85
86
  } catch (error) {
86
- if (__DEV__) {
87
- console.error("[TransactionRepository] Error:", error);
88
- }
89
87
  return {
90
88
  success: false,
91
89
  error: {
@@ -127,10 +125,6 @@ export class TransactionRepository extends BaseRepository {
127
125
 
128
126
  const docRef = await addDoc(colRef, docData);
129
127
 
130
- if (__DEV__) {
131
- console.log("[TransactionRepository] Added:", docRef.id);
132
- }
133
-
134
128
  return {
135
129
  success: true,
136
130
  data: {
@@ -143,9 +137,6 @@ export class TransactionRepository extends BaseRepository {
143
137
  },
144
138
  };
145
139
  } catch (error) {
146
- if (__DEV__) {
147
- console.error("[TransactionRepository] Add error:", error);
148
- }
149
140
  return {
150
141
  success: false,
151
142
  error: {
@@ -8,9 +8,10 @@
8
8
  import React from "react";
9
9
  import { View, StyleSheet } from "react-native";
10
10
  import { LinearGradient } from "expo-linear-gradient";
11
- useAppDesignTokens,
12
- AtomicText,
13
- AtomicIcon,
11
+ import {
12
+ useAppDesignTokens,
13
+ AtomicText,
14
+ AtomicIcon,
14
15
  } from "@umituz/react-native-design-system";
15
16
 
16
17
  export interface BalanceCardTranslations {
@@ -7,9 +7,10 @@
7
7
 
8
8
  import React, { useMemo } from "react";
9
9
  import { View, StyleSheet } from "react-native";
10
- useAppDesignTokens,
11
- AtomicText,
12
- AtomicIcon,
10
+ import {
11
+ useAppDesignTokens,
12
+ AtomicText,
13
+ AtomicIcon,
13
14
  } from "@umituz/react-native-design-system";
14
15
  import type { CreditLog, TransactionReason } from "../../domain/types/transaction.types";
15
16
 
@@ -7,13 +7,15 @@
7
7
 
8
8
  import React from "react";
9
9
  import { View, StyleSheet, ScrollView, ActivityIndicator } from "react-native";
10
- useAppDesignTokens,
11
- AtomicText,
12
- AtomicIcon,
10
+ import {
11
+ useAppDesignTokens,
12
+ AtomicText,
13
+ AtomicIcon,
13
14
  } from "@umituz/react-native-design-system";
14
15
  import type { CreditLog } from "../../domain/types/transaction.types";
15
- TransactionItem,
16
- type TransactionItemTranslations,
16
+ import {
17
+ TransactionItem,
18
+ type TransactionItemTranslations,
17
19
  } from "./TransactionItem";
18
20
 
19
21
  export interface TransactionListTranslations extends TransactionItemTranslations {
@@ -6,11 +6,13 @@
6
6
  */
7
7
 
8
8
  import { useCallback, useMemo } from "react";
9
- useCredits,
10
- type UseCreditsParams,
9
+ import {
10
+ useCredits,
11
+ type UseCreditsParams,
11
12
  } from "../../../../presentation/hooks/useCredits";
12
- useTransactionHistory,
13
- type UseTransactionHistoryParams,
13
+ import {
14
+ useTransactionHistory,
15
+ type UseTransactionHistoryParams,
14
16
  } from "./useTransactionHistory";
15
17
  import type { CreditLog } from "../../domain/types/transaction.types";
16
18
 
@@ -9,16 +9,19 @@
9
9
  import React from "react";
10
10
  import { View, StyleSheet, ActivityIndicator, TouchableOpacity } from "react-native";
11
11
  import { useSafeAreaInsets } from "react-native-safe-area-context";
12
- useAppDesignTokens,
13
- AtomicText,
14
- AtomicIcon,
15
- ScreenLayout,
12
+ import {
13
+ useAppDesignTokens,
14
+ AtomicText,
15
+ AtomicIcon,
16
+ ScreenLayout,
16
17
  } from "@umituz/react-native-design-system";
17
- BalanceCard,
18
- type BalanceCardTranslations,
18
+ import {
19
+ BalanceCard,
20
+ type BalanceCardTranslations,
19
21
  } from "../components/BalanceCard";
20
- TransactionList,
21
- type TransactionListTranslations,
22
+ import {
23
+ TransactionList,
24
+ type TransactionListTranslations,
22
25
  } from "../components/TransactionList";
23
26
  import type { CreditLog } from "../../domain/types/transaction.types";
24
27
 
@@ -1,4 +1,3 @@
1
-
2
1
  /**
3
2
  * Credits Repository
4
3
  *
@@ -6,12 +5,13 @@
6
5
  * Extends BaseRepository from @umituz/react-native-firebase.
7
6
  */
8
7
 
9
- doc,
10
- getDoc,
11
- runTransaction,
12
- serverTimestamp,
13
- type Firestore,
14
- type Transaction,
8
+ import {
9
+ doc,
10
+ getDoc,
11
+ runTransaction,
12
+ serverTimestamp,
13
+ type Firestore,
14
+ type Transaction,
15
15
  } from "firebase/firestore";
16
16
  import { BaseRepository, getFirestore } from "@umituz/react-native-firebase";
17
17
  import type {
@@ -91,14 +91,6 @@ export class CreditsRepository extends BaseRepository {
91
91
  };
92
92
  }
93
93
 
94
- if (__DEV__) {
95
- console.log("[CreditsRepository] Initialize credits:", {
96
- userId,
97
- purchaseId,
98
- productId,
99
- });
100
- }
101
-
102
94
  try {
103
95
  const creditsRef = this.getCreditsDocRef(db, userId);
104
96
 
@@ -110,27 +102,11 @@ export class CreditsRepository extends BaseRepository {
110
102
  const allocation = getCreditAllocation(packageType);
111
103
 
112
104
  if (allocation) {
113
- // Override config with tier-specific credit amounts
114
105
  configToUse = {
115
106
  ...this.config,
116
107
  imageCreditLimit: allocation.imageCredits,
117
108
  textCreditLimit: allocation.textCredits,
118
109
  };
119
-
120
- if (__DEV__) {
121
- console.log("[CreditsRepository] Using tier-based allocation:", {
122
- packageType,
123
- imageCredits: allocation.imageCredits,
124
- textCredits: allocation.textCredits,
125
- });
126
- }
127
- } else {
128
- if (__DEV__) {
129
- console.warn(
130
- "[CreditsRepository] Could not determine package type, using default config:",
131
- this.config
132
- );
133
- }
134
110
  }
135
111
  }
136
112
 
@@ -141,13 +117,6 @@ export class CreditsRepository extends BaseRepository {
141
117
  purchaseId
142
118
  );
143
119
 
144
- if (__DEV__) {
145
- console.log("[CreditsRepository] Credits initialized successfully:", {
146
- imageCredits: result.imageCredits,
147
- textCredits: result.textCredits,
148
- });
149
- }
150
-
151
120
  return {
152
121
  success: true,
153
122
  data: {
@@ -158,10 +127,6 @@ export class CreditsRepository extends BaseRepository {
158
127
  },
159
128
  };
160
129
  } catch (error) {
161
- if (__DEV__) {
162
- console.error("[CreditsRepository] Failed to initialize credits:", error);
163
- }
164
-
165
130
  return {
166
131
  success: false,
167
132
  error: {
@@ -1,4 +1,4 @@
1
-
1
+ import {
2
2
  runTransaction,
3
3
  serverTimestamp,
4
4
  type Firestore,
@@ -20,14 +20,6 @@ export async function initializeCreditsTransaction(
20
20
  config: CreditsConfig,
21
21
  purchaseId?: string
22
22
  ): Promise<InitializationResult> {
23
- if (__DEV__) {
24
- console.log("[CreditsInitializer] Starting transaction with config:", {
25
- textCreditLimit: config.textCreditLimit,
26
- imageCreditLimit: config.imageCreditLimit,
27
- purchaseId,
28
- });
29
- }
30
-
31
23
  return runTransaction(db, async (transaction: Transaction) => {
32
24
  const creditsDoc = await transaction.get(creditsRef);
33
25
  const now = serverTimestamp();
@@ -41,21 +33,7 @@ export async function initializeCreditsTransaction(
41
33
  const existing = creditsDoc.data() as UserCreditsDocumentRead;
42
34
  processedPurchases = existing.processedPurchases || [];
43
35
 
44
- if (__DEV__) {
45
- console.log("[CreditsInitializer] Existing credits found:", {
46
- textCredits: existing.textCredits,
47
- imageCredits: existing.imageCredits,
48
- processedPurchases,
49
- });
50
- }
51
-
52
36
  if (purchaseId && processedPurchases.includes(purchaseId)) {
53
- if (__DEV__) {
54
- console.warn(
55
- "[CreditsInitializer] Purchase already processed:",
56
- purchaseId
57
- );
58
- }
59
37
  return {
60
38
  textCredits: existing.textCredits,
61
39
  imageCredits: existing.imageCredits,
@@ -66,31 +44,9 @@ export async function initializeCreditsTransaction(
66
44
  newTextCredits = (existing.textCredits || 0) + config.textCreditLimit;
67
45
  newImageCredits = (existing.imageCredits || 0) + config.imageCreditLimit;
68
46
 
69
- if (__DEV__) {
70
- console.log("[CreditsInitializer] Adding to existing credits:", {
71
- existingText: existing.textCredits || 0,
72
- existingImage: existing.imageCredits || 0,
73
- adding: {
74
- text: config.textCreditLimit,
75
- image: config.imageCreditLimit,
76
- },
77
- newTotal: {
78
- text: newTextCredits,
79
- image: newImageCredits,
80
- },
81
- });
82
- }
83
-
84
47
  if (existing.purchasedAt) {
85
48
  purchasedAt = existing.purchasedAt as unknown as FieldValue;
86
49
  }
87
- } else {
88
- if (__DEV__) {
89
- console.log("[CreditsInitializer] Creating new credits document:", {
90
- textCredits: newTextCredits,
91
- imageCredits: newImageCredits,
92
- });
93
- }
94
50
  }
95
51
 
96
52
  if (purchaseId) {
@@ -106,13 +62,6 @@ export async function initializeCreditsTransaction(
106
62
  processedPurchases,
107
63
  });
108
64
 
109
- if (__DEV__) {
110
- console.log("[CreditsInitializer] Transaction completed successfully:", {
111
- textCredits: newTextCredits,
112
- imageCredits: newImageCredits,
113
- });
114
- }
115
-
116
65
  return { textCredits: newTextCredits, imageCredits: newImageCredits };
117
66
  });
118
67
  }
@@ -4,6 +4,7 @@
4
4
  */
5
5
 
6
6
  import React, { useMemo } from "react";
7
+ import {
7
8
  View,
8
9
  Modal,
9
10
  TouchableOpacity,
@@ -7,9 +7,10 @@
7
7
  import React from "react";
8
8
  import { View, TouchableOpacity } from "react-native";
9
9
  import type { StyleProp, ViewStyle } from "react-native";
10
- PremiumDetailsCard,
11
- type CreditInfo,
12
- type PremiumDetailsTranslations,
10
+ import {
11
+ PremiumDetailsCard,
12
+ type CreditInfo,
13
+ type PremiumDetailsTranslations,
13
14
  } from "../details/PremiumDetailsCard";
14
15
  import type { SubscriptionStatusType } from "../details/PremiumStatusBadge";
15
16
 
@@ -7,8 +7,9 @@
7
7
  import { useMemo } from "react";
8
8
  import type { CreditType } from "../../domain/entities/Credits";
9
9
  import { getCreditsRepository } from "../../infrastructure/repositories/CreditsRepositoryProvider";
10
- createCreditChecker,
11
- type CreditCheckResult,
10
+ import {
11
+ createCreditChecker,
12
+ type CreditCheckResult,
12
13
  } from "../../utils/creditChecker";
13
14
 
14
15
  export interface UseCreditCheckerParams {
@@ -10,9 +10,10 @@ import { useCallback, useMemo } from "react";
10
10
  import type { UserCredits, CreditType } from "../../domain/entities/Credits";
11
11
 
12
12
  declare const __DEV__: boolean;
13
- getCreditsRepository,
14
- getCreditsConfig,
15
- isCreditsRepositoryConfigured,
13
+ import {
14
+ getCreditsRepository,
15
+ getCreditsConfig,
16
+ isCreditsRepositoryConfigured,
16
17
  } from "../../infrastructure/repositories/CreditsRepositoryProvider";
17
18
 
18
19
  export const creditsQueryKeys = {
@@ -12,9 +12,10 @@ import type { PurchasesPackage } from 'react-native-purchases';
12
12
  import type { UserCredits } from '../../domain/entities/Credits';
13
13
  import { useCredits } from './useCredits';
14
14
  import { useSubscriptionStatus } from './useSubscriptionStatus';
15
- useSubscriptionPackages,
16
- usePurchasePackage,
17
- useRestorePurchase,
15
+ import {
16
+ useSubscriptionPackages,
17
+ usePurchasePackage,
18
+ useRestorePurchase,
18
19
  } from '../../revenuecat/presentation/hooks/useSubscriptionQueries';
19
20
  import { usePaywallVisibility } from './usePaywallVisibility';
20
21
 
@@ -5,8 +5,9 @@
5
5
 
6
6
  import { useMemo } from "react";
7
7
  import type { SubscriptionStatus } from "../../domain/entities/SubscriptionStatus";
8
- getDaysUntilExpiration,
9
- isSubscriptionExpired,
8
+ import {
9
+ getDaysUntilExpiration,
10
+ isSubscriptionExpired,
10
11
  } from "../../utils/dateValidationUtils";
11
12
 
12
13
  export interface SubscriptionDetails {
@@ -10,9 +10,10 @@ import { useSubscriptionStatus } from "./useSubscriptionStatus";
10
10
  import { useCustomerInfo } from "../../revenuecat/presentation/hooks/useCustomerInfo";
11
11
  import { usePaywallVisibility } from "./usePaywallVisibility";
12
12
  import { SubscriptionManager } from "../../revenuecat/infrastructure/managers/SubscriptionManager";
13
- convertPurchasedAt,
14
- formatDateForLocale,
15
- calculateDaysRemaining,
13
+ import {
14
+ convertPurchasedAt,
15
+ formatDateForLocale,
16
+ calculateDaysRemaining,
16
17
  } from "../utils/subscriptionDateUtils";
17
18
  import type {
18
19
  SubscriptionSettingsConfig,
@@ -6,8 +6,9 @@
6
6
 
7
7
  import React, { useMemo } from "react";
8
8
  import { StyleSheet, View } from "react-native";
9
- useAppDesignTokens,
10
- ScreenLayout,
9
+ import {
10
+ useAppDesignTokens,
11
+ ScreenLayout,
11
12
  } from "@umituz/react-native-design-system";
12
13
  import { SubscriptionHeader } from "./components/SubscriptionHeader";
13
14
  import { CreditsList } from "./components/CreditsList";
@@ -5,9 +5,10 @@
5
5
 
6
6
  import React, { useMemo } from "react";
7
7
  import { View, StyleSheet, TouchableOpacity } from "react-native";
8
- useAppDesignTokens,
9
- AtomicText,
10
- AtomicIcon,
8
+ import {
9
+ useAppDesignTokens,
10
+ AtomicText,
11
+ AtomicIcon,
11
12
  } from "@umituz/react-native-design-system";
12
13
  import type { UpgradePromptProps } from "../../types/SubscriptionDetailTypes";
13
14