@umituz/react-native-subscription 2.26.14 → 2.26.16

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 (37) hide show
  1. package/package.json +1 -1
  2. package/src/domains/paywall/components/PaywallModal.tsx +36 -13
  3. package/src/domains/paywall/components/PlanCard.tsx +16 -3
  4. package/src/domains/paywall/entities/types.ts +4 -0
  5. package/src/domains/paywall/hooks/usePaywallTranslations.ts +8 -0
  6. package/src/presentation/hooks/index.ts +0 -13
  7. package/src/presentation/hooks/useFeatureGate.ts +12 -33
  8. package/src/revenuecat/domain/types/RevenueCatTypes.ts +32 -0
  9. package/src/revenuecat/index.ts +1 -0
  10. package/src/revenuecat/presentation/hooks/useRevenueCatTrialEligibility.ts +179 -0
  11. package/src/presentation/hooks/useAuthAwarePurchase.md +0 -92
  12. package/src/presentation/hooks/useAuthGate.md +0 -89
  13. package/src/presentation/hooks/useAuthGate.ts +0 -65
  14. package/src/presentation/hooks/useCreditChecker.md +0 -102
  15. package/src/presentation/hooks/useCreditChecker.ts +0 -41
  16. package/src/presentation/hooks/useCreditsGate.md +0 -94
  17. package/src/presentation/hooks/useCreditsGate.ts +0 -67
  18. package/src/presentation/hooks/useDevTestCallbacks.md +0 -91
  19. package/src/presentation/hooks/useDevTestCallbacks.ts +0 -142
  20. package/src/presentation/hooks/useInitializeCredits.md +0 -92
  21. package/src/presentation/hooks/useInitializeCredits.ts +0 -57
  22. package/src/presentation/hooks/usePremiumGate.md +0 -88
  23. package/src/presentation/hooks/usePremiumGate.ts +0 -116
  24. package/src/presentation/hooks/usePremiumWithCredits.md +0 -92
  25. package/src/presentation/hooks/usePremiumWithCredits.ts +0 -48
  26. package/src/presentation/hooks/useSubscription.md +0 -94
  27. package/src/presentation/hooks/useSubscription.ts +0 -119
  28. package/src/presentation/hooks/useSubscriptionDetails.md +0 -93
  29. package/src/presentation/hooks/useSubscriptionDetails.ts +0 -85
  30. package/src/presentation/hooks/useSubscriptionGate.md +0 -84
  31. package/src/presentation/hooks/useSubscriptionGate.ts +0 -67
  32. package/src/presentation/hooks/useSubscriptionStatus.md +0 -94
  33. package/src/presentation/hooks/useTrialEligibility.ts +0 -66
  34. package/src/presentation/hooks/useUserTier.md +0 -91
  35. package/src/presentation/hooks/useUserTier.ts +0 -78
  36. package/src/presentation/hooks/useUserTierWithRepository.md +0 -92
  37. package/src/presentation/hooks/useUserTierWithRepository.ts +0 -151
@@ -1,78 +0,0 @@
1
- /**
2
- * useUserTier Hook
3
- *
4
- * Centralized hook for determining user tier (Guest, Freemium, Premium)
5
- * Single source of truth for all premium/freemium/guest checks
6
- *
7
- * This hook only handles LOGICAL tier determination.
8
- * Database operations should be handled by the app via PremiumStatusFetcher.
9
- *
10
- * @example
11
- * ```typescript
12
- * const { tier, isPremium, isGuest } = useUserTier({
13
- * isGuest: false,
14
- * userId: 'user123',
15
- * isPremium: true, // App should fetch this from database
16
- * });
17
- *
18
- * // Simple, clean checks
19
- * if (tier === "guest") {
20
- * // Show guest upgrade card
21
- * } else if (tier === "freemium") {
22
- * // Show freemium limits
23
- * } else {
24
- * // Premium features
25
- * }
26
- * ```
27
- */
28
-
29
- import { useMemo } from 'react';
30
- import { getUserTierInfo } from '../../utils/tierUtils';
31
- import type { UserTierInfo } from '../../utils/types';
32
-
33
- export interface UseUserTierParams {
34
- /** Whether user is a guest */
35
- isGuest: boolean;
36
- /** User ID (null for guests) */
37
- userId: string | null;
38
- /** Whether user has active premium subscription (app should fetch from database) */
39
- isPremium: boolean;
40
- /** Optional: Loading state from app */
41
- isLoading?: boolean;
42
- /** Optional: Error state from app */
43
- error?: string | null;
44
- }
45
-
46
- export interface UseUserTierResult extends UserTierInfo {
47
- /** Whether premium status is currently loading */
48
- isLoading: boolean;
49
- /** Premium status error (if any) */
50
- error: string | null;
51
- }
52
-
53
- /**
54
- * Hook to get user tier information
55
- * Combines auth state and premium status into single source of truth
56
- *
57
- * All premium/freemium/guest checks are centralized here:
58
- * - Guest: isGuest || !userId → always freemium, never premium
59
- * - Freemium: authenticated but !isPremium
60
- * - Premium: authenticated && isPremium
61
- *
62
- * Note: This hook only handles LOGICAL tier determination.
63
- * Database operations (fetching premium status) should be handled by the app.
64
- */
65
- export function useUserTier(params: UseUserTierParams): UseUserTierResult {
66
- const { isGuest, userId, isPremium, isLoading = false, error = null } = params;
67
-
68
- // Calculate tier info using centralized logic
69
- const tierInfo = useMemo(() => {
70
- return getUserTierInfo(isGuest, userId, isPremium);
71
- }, [isGuest, userId, isPremium]);
72
-
73
- return {
74
- ...tierInfo,
75
- isLoading,
76
- error,
77
- };
78
- }
@@ -1,92 +0,0 @@
1
- # useUserTierWithRepository Hook
2
-
3
- Automatically fetches premium status and provides tier information with repository integration.
4
-
5
- ## Location
6
-
7
- **Import Path**: `@umituz/react-native-subscription`
8
-
9
- **File**: `src/presentation/hooks/useUserTierWithRepository.ts`
10
-
11
- **Type**: Hook
12
-
13
- ## Strategy
14
-
15
- ### Tier Determination with Repository
16
-
17
- 1. **Auth State Check**: Use provided auth provider to check authentication
18
- 2. **Premium Fetch**: Automatically fetch premium status from repository for authenticated users
19
- 3. **Tier Assignment**: Assign tier based on auth + subscription (guest/freemium/premium)
20
- 4. **Abort Control**: Use AbortController to prevent race conditions on rapid user changes
21
- 5. **Guest Optimization**: Skip repository fetch for guest users (no fetch needed)
22
- 6. **Real-time Updates**: React to auth state changes
23
-
24
- ### Integration Points
25
-
26
- - **Auth Provider**: Custom auth provider with user state
27
- - **Subscription Repository**: `src/infrastructure/repositories/SubscriptionRepository.ts`
28
- - **Domain Layer**: `src/domain/entities/README.md`
29
- - **TanStack Query**: For caching and real-time updates
30
-
31
- ## Restrictions
32
-
33
- ### REQUIRED
34
-
35
- - **Auth Provider**: MUST provide valid auth provider object
36
- - **Repository**: MUST provide subscription repository
37
- - **Loading State**: MUST handle loading state
38
- - **Error Handling**: MUST handle error state
39
-
40
- ### PROHIBITED
41
-
42
- - **NEVER** call without valid auth provider
43
- - **NEVER** call without valid repository
44
- - **DO NOT** hardcode tier values (use hook return values)
45
- - **DO NOT** assume instant data availability
46
-
47
- ### CRITICAL SAFETY
48
-
49
- - **ALWAYS** check loading state before using tier values
50
- - **NEVER** trust client-side tier for security enforcement
51
- - **MUST** provide valid auth provider structure
52
- - **ALWAYS** handle tier transitions gracefully
53
-
54
- ## AI Agent Guidelines
55
-
56
- ### When Implementing Tier Determination
57
-
58
- 1. **Always** provide valid auth provider with user, isGuest, isAuthenticated
59
- 2. **Always** provide valid subscription repository
60
- 3. **Always** handle loading state
61
- 4. **Always** handle error state
62
- 5. **Never** use for security decisions without server validation
63
-
64
- ### Integration Checklist
65
-
66
- - [ ] Import from correct path: `@umituz/react-native-subscription`
67
- - [ ] Provide valid auth provider object
68
- - [ ] Provide valid subscription repository
69
- - [ ] Handle loading state
70
- - [ ] Handle error state
71
- - [ ] Use refresh() when needed
72
- - [ ] Test with guest user
73
- - [ ] Test with freemium user
74
- - [ ] Test with premium user
75
- - [ ] Test user switching scenarios
76
-
77
- ### Common Patterns
78
-
79
- 1. **Auth Provider Setup**: Use with Firebase, custom auth, or auth library
80
- 2. **Tier-Based UI**: Show different features based on tier
81
- 3. **Navigation Guards**: Redirect based on tier requirements
82
- 4. **Tier Monitoring**: Track tier changes for analytics
83
- 5. **Manual Refresh**: Call refresh() after subscription changes
84
-
85
- ## Related Documentation
86
-
87
- - **useUserTier**: Tier logic without repository
88
- - **usePremium**: Premium status checking
89
- - **useAuthGate**: Authentication gating
90
- - **useSubscription**: Subscription details
91
- - **Repository Pattern**: `src/infrastructure/repositories/README.md`
92
- - **User Tier Utils**: `src/utils/README.md`
@@ -1,151 +0,0 @@
1
- /**
2
- * useUserTierWithRepository Hook
3
- * Automatically fetches premium status and provides user tier information.
4
- */
5
-
6
- import { useEffect, useState, useCallback } from 'react';
7
- import { useUserTier, type UseUserTierParams } from './useUserTier';
8
- import type { ISubscriptionRepository } from '../../application/ports/ISubscriptionRepository';
9
-
10
- /**
11
- * Auth provider interface
12
- * Apps should provide an object that matches this interface
13
- */
14
- export interface AuthProvider {
15
- /** Current user object (null for guests) */
16
- user: { uid: string } | null;
17
- /** Whether user is a guest */
18
- isGuest: boolean;
19
- /** Whether user is authenticated */
20
- isAuthenticated: boolean;
21
- }
22
-
23
- export interface UseUserTierWithRepositoryParams {
24
- /** Auth provider (e.g., result of useAuth hook) */
25
- auth: AuthProvider;
26
- /** Subscription repository for fetching premium status */
27
- repository: ISubscriptionRepository;
28
- }
29
-
30
- export interface UseUserTierWithRepositoryResult {
31
- /** User tier: 'guest' | 'freemium' | 'premium' */
32
- tier: 'guest' | 'freemium' | 'premium';
33
- /** Whether user has premium access */
34
- isPremium: boolean;
35
- /** Whether user is a guest */
36
- isGuest: boolean;
37
- /** Whether user is authenticated */
38
- isAuthenticated: boolean;
39
- /** User ID (null for guests) */
40
- userId: string | null;
41
- /** Whether premium status is currently loading */
42
- isLoading: boolean;
43
- /** Premium status error (if any) */
44
- error: string | null;
45
- /** Refresh premium status from repository */
46
- refresh: () => Promise<void>;
47
- }
48
-
49
- /**
50
- * Hook that automatically fetches premium status and provides user tier information
51
- *
52
- * This hook eliminates the need for app-specific useUserTier wrappers by:
53
- * 1. Automatically fetching premium status from repository
54
- * 2. Handling loading and error states
55
- * 3. Providing refresh functionality
56
- * 4. Using centralized tier logic from useUserTier
57
- */
58
- export function useUserTierWithRepository(
59
- params: UseUserTierWithRepositoryParams,
60
- ): UseUserTierWithRepositoryResult {
61
- const { auth, repository } = params;
62
- const { user, isGuest, isAuthenticated } = auth;
63
-
64
- const [isPremium, setIsPremium] = useState<boolean>(false);
65
- const [isLoading, setIsLoading] = useState<boolean>(true);
66
- const [error, setError] = useState<string | null>(null);
67
-
68
- // Fetch premium status from repository
69
- const fetchPremiumStatus = useCallback(async (signal?: AbortSignal) => {
70
- // Guest users are never premium - no need to fetch
71
- if (!isAuthenticated || !user) {
72
- setIsPremium(false);
73
- setIsLoading(false);
74
- setError(null);
75
- return;
76
- }
77
-
78
- try {
79
- setIsLoading(true);
80
- setError(null);
81
-
82
- const status = await repository.getSubscriptionStatus(user.uid);
83
-
84
- // Check if operation was aborted
85
- if (signal?.aborted) {
86
- return;
87
- }
88
-
89
- const isPremiumValue =
90
- status !== null && repository.isSubscriptionValid(status);
91
-
92
- // Check again before setting state
93
- if (!signal?.aborted) {
94
- setIsPremium(isPremiumValue);
95
- setIsLoading(false);
96
- }
97
- } catch (err) {
98
- // Don't set state if operation was aborted
99
- if (!signal?.aborted) {
100
- const errorMessage =
101
- err instanceof Error ? err.message : 'Failed to fetch premium status';
102
- setError(errorMessage);
103
- setIsPremium(false);
104
- setIsLoading(false);
105
- }
106
- }
107
- }, [isAuthenticated, user, repository]);
108
-
109
- // Fetch premium status when auth state changes
110
- useEffect(() => {
111
- const abortController = new AbortController();
112
-
113
- fetchPremiumStatus(abortController.signal).catch(() => {
114
- // Error is handled in fetchPremiumStatus
115
- });
116
-
117
- return () => {
118
- abortController.abort();
119
- };
120
- }, [fetchPremiumStatus]);
121
-
122
- // Refresh function
123
- const refresh = useCallback(async () => {
124
- if (!isAuthenticated || !user) {
125
- return;
126
- }
127
- const abortController = new AbortController();
128
- try {
129
- await fetchPremiumStatus(abortController.signal);
130
- } finally {
131
- abortController.abort();
132
- }
133
- }, [isAuthenticated, user, fetchPremiumStatus]);
134
-
135
- // Use base useUserTier hook for tier logic
136
- const useUserTierParams: UseUserTierParams = {
137
- isGuest: isGuest || !isAuthenticated,
138
- userId: user?.uid || null,
139
- isPremium,
140
- isLoading,
141
- error,
142
- };
143
-
144
- const tierInfo = useUserTier(useUserTierParams);
145
-
146
- return {
147
- ...tierInfo,
148
- refresh,
149
- };
150
- }
151
-