@umituz/react-native-subscription 2.26.13 → 2.26.15

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 (39) 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 -15
  7. package/src/presentation/hooks/useFeatureGate.ts +41 -116
  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/useAuthAwarePurchase.ts +0 -138
  13. package/src/presentation/hooks/useAuthGate.md +0 -89
  14. package/src/presentation/hooks/useAuthGate.ts +0 -65
  15. package/src/presentation/hooks/useCreditChecker.md +0 -102
  16. package/src/presentation/hooks/useCreditChecker.ts +0 -41
  17. package/src/presentation/hooks/useCreditsGate.md +0 -94
  18. package/src/presentation/hooks/useCreditsGate.ts +0 -81
  19. package/src/presentation/hooks/useDevTestCallbacks.md +0 -91
  20. package/src/presentation/hooks/useDevTestCallbacks.ts +0 -142
  21. package/src/presentation/hooks/useInitializeCredits.md +0 -92
  22. package/src/presentation/hooks/useInitializeCredits.ts +0 -57
  23. package/src/presentation/hooks/usePremiumGate.md +0 -88
  24. package/src/presentation/hooks/usePremiumGate.ts +0 -116
  25. package/src/presentation/hooks/usePremiumWithCredits.md +0 -92
  26. package/src/presentation/hooks/usePremiumWithCredits.ts +0 -48
  27. package/src/presentation/hooks/useSubscription.md +0 -94
  28. package/src/presentation/hooks/useSubscription.ts +0 -119
  29. package/src/presentation/hooks/useSubscriptionDetails.md +0 -93
  30. package/src/presentation/hooks/useSubscriptionDetails.ts +0 -85
  31. package/src/presentation/hooks/useSubscriptionGate.md +0 -84
  32. package/src/presentation/hooks/useSubscriptionGate.ts +0 -67
  33. package/src/presentation/hooks/useSubscriptionStatus.md +0 -94
  34. package/src/presentation/hooks/useSubscriptionStatus.ts +0 -64
  35. package/src/presentation/hooks/useTrialEligibility.ts +0 -66
  36. package/src/presentation/hooks/useUserTier.md +0 -91
  37. package/src/presentation/hooks/useUserTier.ts +0 -78
  38. package/src/presentation/hooks/useUserTierWithRepository.md +0 -92
  39. package/src/presentation/hooks/useUserTierWithRepository.ts +0 -151
@@ -1,48 +0,0 @@
1
- /**
2
- * usePremiumWithCredits Hook
3
- *
4
- * Combined hook for premium subscription with credits system.
5
- * Ensures premium users always have credits initialized.
6
- */
7
-
8
- import { useEffect, useCallback } from "react";
9
- import { useCredits, type UseCreditsResult } from "./useCredits";
10
- import { useInitializeCredits } from "./useInitializeCredits";
11
-
12
- export interface UsePremiumWithCreditsParams {
13
- userId: string | undefined;
14
- isPremium: boolean;
15
- }
16
-
17
- export interface UsePremiumWithCreditsResult extends UseCreditsResult {
18
- ensureCreditsInitialized: () => Promise<void>;
19
- }
20
-
21
- export const usePremiumWithCredits = ({
22
- userId,
23
- isPremium,
24
- }: UsePremiumWithCreditsParams): UsePremiumWithCreditsResult => {
25
- const creditsResult = useCredits({ userId });
26
- const { initializeCredits, isInitializing } = useInitializeCredits({
27
- userId,
28
- });
29
-
30
- const ensureCreditsInitialized = useCallback(async () => {
31
- if (!userId || !isPremium) return;
32
- if (creditsResult.credits) return;
33
- if (isInitializing) return;
34
-
35
- await initializeCredits();
36
- }, [userId, isPremium, creditsResult.credits, isInitializing, initializeCredits]);
37
-
38
- useEffect(() => {
39
- if (isPremium && userId && !creditsResult.credits && !creditsResult.isLoading) {
40
- ensureCreditsInitialized();
41
- }
42
- }, [isPremium, userId, creditsResult.credits, creditsResult.isLoading, ensureCreditsInitialized]);
43
-
44
- return {
45
- ...creditsResult,
46
- ensureCreditsInitialized,
47
- };
48
- };
@@ -1,94 +0,0 @@
1
- # useSubscription Hook
2
-
3
- Core hook for subscription status management and operations.
4
-
5
- ## Location
6
-
7
- **Import Path**: `@umituz/react-native-subscription`
8
-
9
- **File**: `src/presentation/hooks/useSubscription.ts`
10
-
11
- **Type**: Hook
12
-
13
- ## Strategy
14
-
15
- ### Subscription Management Flow
16
-
17
- 1. **Status Retrieval**: Fetch current subscription status from repository
18
- 2. **State Caching**: Cache status for 5 minutes using TanStack Query
19
- 3. **Real-time Updates**: Auto-refresh when user auth state changes
20
- 4. **Manual Operations**: Provide functions for manual activation/deactivation
21
- 5. **Loading States**: Handle loading and error states properly
22
- 6. **Refresh Mechanisms**: Support both load and refresh operations
23
-
24
- ### Integration Points
25
-
26
- - **Subscription Repository**: `src/infrastructure/repositories/SubscriptionRepository.ts`
27
- - **TanStack Query**: For caching and background updates
28
- - **Auth Context**: Sync with user authentication state
29
- - **RevenueCat**: For subscription data source
30
-
31
- ## Restrictions
32
-
33
- ### REQUIRED
34
-
35
- - **User ID**: MUST provide valid userId for operations
36
- - **Loading State**: MUST handle loading state in UI
37
- - **Error Handling**: MUST handle error state
38
- - **Status Check**: MUST verify isPremium before showing premium features
39
-
40
- ### PROHIBITED
41
-
42
- - **NEVER** assume instant data availability (always check loading state)
43
- - **NEVER** use for security decisions without server validation
44
- - **DO NOT** call loadStatus/refreshStatus without userId
45
- - **DO NOT** activate/deactivate subscriptions without proper validation
46
-
47
- ### CRITICAL SAFETY
48
-
49
- - **ALWAYS** check loading state before accessing status
50
- - **NEVER** trust client-side state for security enforcement
51
- - **MUST** validate userId before all operations
52
- - **ALWAYS** handle errors gracefully
53
-
54
- ## AI Agent Guidelines
55
-
56
- ### When Implementing Subscription Features
57
-
58
- 1. **Always** check loading state before rendering subscription data
59
- 2. **Always** handle error state
60
- 3. **Always** verify isPremium before showing premium features
61
- 4. **Always** validate userId before operations
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
- - [ ] Handle loading state
68
- - [ ] Handle error state
69
- - [ ] Check isPremium before rendering premium content
70
- - [ ] Validate userId before operations
71
- - [ ] Implement refresh mechanism
72
- - [ ] Test with premium user
73
- - [ ] Test with free user
74
- - [ ] Test with guest user
75
- - [ ] Test offline scenario
76
-
77
- ### Common Patterns
78
-
79
- 1. **Status Display**: Show current subscription status
80
- 2. **Conditional Rendering**: Show/hide features based on isPremium
81
- 3. **Manual Refresh**: Provide refresh button for users
82
- 4. **Auto-refresh**: Refresh on screen focus or app foreground
83
- 5. **Status Polling**: Periodic refresh for real-time updates
84
- 6. **Purchase Completion**: Refresh after successful purchase
85
- 7. **Error Recovery**: Provide retry mechanism on failure
86
-
87
- ## Related Documentation
88
-
89
- - **usePremium**: Simplified premium checking
90
- - **useSubscriptionStatus**: Detailed subscription status
91
- - **useSubscriptionDetails**: Package and pricing info
92
- - **useUserTier**: Tier information
93
- - **Subscription Repository**: `src/infrastructure/repositories/README.md`
94
- - **Domain Layer**: `src/domain/README.md`
@@ -1,119 +0,0 @@
1
- /**
2
- * useSubscription Hook
3
- * React hook for subscription management
4
- */
5
-
6
- import { useState, useCallback } from 'react';
7
- import type { SubscriptionStatus } from '../../domain/entities/SubscriptionStatus';
8
- import { isSubscriptionValid } from '../../domain/entities/SubscriptionStatus';
9
- import {
10
- checkSubscriptionService,
11
- validateUserId,
12
- executeSubscriptionOperation,
13
- } from './useSubscription.utils';
14
-
15
- export interface UseSubscriptionResult {
16
- /** Current subscription status */
17
- status: SubscriptionStatus | null;
18
- /** Whether subscription is loading */
19
- loading: boolean;
20
- /** Error if any */
21
- error: string | null;
22
- /** Whether user has active subscription */
23
- isPremium: boolean;
24
- /** Load subscription status */
25
- loadStatus: (userId: string) => Promise<void>;
26
- /** Refresh subscription status */
27
- refreshStatus: (userId: string) => Promise<void>;
28
- /** Activate subscription */
29
- activateSubscription: (
30
- userId: string,
31
- productId: string,
32
- expiresAt: string | null,
33
- ) => Promise<void>;
34
- /** Deactivate subscription */
35
- deactivateSubscription: (userId: string) => Promise<void>;
36
- }
37
-
38
- /**
39
- * Hook for subscription operations
40
- *
41
- * @example
42
- * ```typescript
43
- * const { status, isPremium, loadStatus } = useSubscription();
44
- * ```
45
- */
46
- export function useSubscription(): UseSubscriptionResult {
47
- const [status, setStatus] = useState<SubscriptionStatus | null>(null);
48
- const [loading, setLoading] = useState(false);
49
- const [error, setError] = useState<string | null>(null);
50
-
51
- const performOperation = useCallback(async (
52
- userId: string,
53
- operation: () => Promise<SubscriptionStatus | null | void>
54
- ) => {
55
- const errorMsg = validateUserId(userId);
56
- if (errorMsg) {
57
- setError(errorMsg);
58
- return;
59
- }
60
-
61
- const check = checkSubscriptionService();
62
- if (!check.success) {
63
- setError(check.error || "Service error");
64
- return;
65
- }
66
-
67
- await executeSubscriptionOperation(
68
- operation,
69
- setLoading,
70
- setError,
71
- (result) => { if (result) setStatus(result as SubscriptionStatus); }
72
- );
73
- }, []);
74
-
75
- const loadStatus = useCallback((userId: string) =>
76
- performOperation(userId, () => {
77
- const { service } = checkSubscriptionService();
78
-
79
- return service!.getSubscriptionStatus(userId);
80
- }), [performOperation]);
81
-
82
- const refreshStatus = loadStatus;
83
-
84
- const activateSubscription = useCallback(
85
- (userId: string, productId: string, expiresAt: string | null) => {
86
- if (!productId) {
87
- setError("Product ID is required");
88
- return Promise.resolve();
89
- }
90
- return performOperation(userId, () => {
91
- const { service } = checkSubscriptionService();
92
-
93
- return service!.activateSubscription(userId, productId, expiresAt).then(res => res ?? undefined);
94
- });
95
- },
96
- [performOperation]
97
- );
98
-
99
- const deactivateSubscription = useCallback((userId: string) =>
100
- performOperation(userId, () => {
101
- const { service } = checkSubscriptionService();
102
-
103
- return service!.deactivateSubscription(userId).then(res => res ?? undefined);
104
- }), [performOperation]);
105
-
106
- const isPremium = isSubscriptionValid(status);
107
-
108
- return {
109
- status,
110
- loading,
111
- error,
112
- isPremium,
113
- loadStatus,
114
- refreshStatus,
115
- activateSubscription,
116
- deactivateSubscription,
117
- };
118
- }
119
-
@@ -1,93 +0,0 @@
1
- # useSubscriptionDetails Hook
2
-
3
- Hook for accessing detailed subscription information including package details.
4
-
5
- ## Location
6
-
7
- **Import Path**: `@umituz/react-native-subscription`
8
-
9
- **File**: `src/presentation/hooks/useSubscriptionDetails.ts`
10
-
11
- **Type**: Hook
12
-
13
- ## Strategy
14
-
15
- ### Detailed Subscription Information
16
-
17
- 1. **Subscription Status**: Fetch current subscription status object
18
- 2. **Package Details**: Retrieve RevenueCat package information
19
- 3. **Period Detection**: Determine subscription period (monthly/annual/lifetime)
20
- 4. **Price Calculation**: Calculate current price and monthly equivalent
21
- 5. **Feature List**: Extract feature list from package configuration
22
- 6. **Real-time Updates**: Refresh when subscription changes
23
-
24
- ### Integration Points
25
-
26
- - **Subscription Repository**: `src/infrastructure/repositories/SubscriptionRepository.ts`
27
- - **Package Configuration**: RevenueCat package definitions
28
- - **useSubscriptionStatus**: For detailed status information
29
- - **TanStack Query**: For caching and background updates
30
-
31
- ## Restrictions
32
-
33
- ### REQUIRED
34
-
35
- - **Loading State**: MUST handle loading state
36
- - **Null Handling**: MUST handle null subscription and package
37
- - **Error Handling**: MUST handle error state
38
- - **Price Formatting**: MUST format prices appropriately
39
-
40
- ### PROHIBITED
41
-
42
- - **NEVER** assume subscription exists (check for null)
43
- - **NEVER** assume package exists (check for null)
44
- - **DO NOT** use prices without formatting
45
- - **DO NOT** hardcode feature lists
46
-
47
- ### CRITICAL SAFETY
48
-
49
- - **ALWAYS** check for null subscription and package
50
- - **MUST** handle loading state before accessing details
51
- - **ALWAYS** format prices with currency codes
52
- - **NEVER** trust client-side details for security
53
-
54
- ## AI Agent Guidelines
55
-
56
- ### When Implementing Subscription Details
57
-
58
- 1. **Always** check for null subscription and package
59
- 2. **Always** handle loading state
60
- 3. **Always** format prices properly
61
- 4. **Always** handle all period types (monthly, annual, lifetime)
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
- - [ ] Handle loading state
68
- - [ ] Check subscription for null
69
- - [ ] Check package for null
70
- - [ ] Format prices with currency codes
71
- - [ ] Handle all period types
72
- - [ ] Display features properly
73
- - [ ] Test with monthly subscription
74
- - [ ] Test with annual subscription
75
- - [ ] Test with lifetime subscription
76
- - [ ] Test with no subscription
77
-
78
- ### Common Patterns
79
-
80
- 1. **Detailed Card**: Display comprehensive subscription information
81
- 2. **Price Comparison**: Show monthly vs annual pricing
82
- 3. **Upgrade Suggestion**: Suggest upgrades based on current plan
83
- 4. **Feature List**: Display included features
84
- 5. **Billing History**: Show subscription history
85
- 6. **Cancellation Flow**: Handle subscription cancellation
86
-
87
- ## Related Documentation
88
-
89
- - **useSubscription**: Basic subscription status
90
- - **useSubscriptionStatus**: Detailed status
91
- - **usePremium**: Simple premium check
92
- - **useSubscriptionPackages**: Available packages
93
- - **Package Utilities**: `src/utils/README.md`
@@ -1,85 +0,0 @@
1
- import { useMemo } from "react";
2
- import {
3
- type SubscriptionStatus,
4
- SUBSCRIPTION_STATUS,
5
- type SubscriptionStatusType,
6
- isSubscriptionValid,
7
- calculateDaysRemaining
8
- } from "../../domain/entities/SubscriptionStatus";
9
- import { formatDate } from "../utils/subscriptionDateUtils";
10
-
11
- export interface SubscriptionDetails {
12
- /** Raw subscription status */
13
- status: SubscriptionStatus | null;
14
- /** Whether user has active premium */
15
- isPremium: boolean;
16
- /** Whether subscription is expired */
17
- isExpired: boolean;
18
- /** Whether this is a lifetime subscription */
19
- isLifetime: boolean;
20
- /** Days remaining until expiration (null for lifetime) */
21
- daysRemaining: number | null;
22
- /** Formatted expiration date (null if lifetime) */
23
- formattedExpirationDate: string | null;
24
- /** Formatted purchase date */
25
- formattedPurchaseDate: string | null;
26
- /** Status text key for localization */
27
- statusKey: SubscriptionStatusType;
28
- }
29
-
30
- interface UseSubscriptionDetailsParams {
31
- status: SubscriptionStatus | null;
32
- }
33
-
34
- /**
35
- * Hook for formatted subscription details
36
- */
37
- export function useSubscriptionDetails(
38
- params: UseSubscriptionDetailsParams,
39
- ): SubscriptionDetails {
40
- const { status } = params;
41
-
42
- return useMemo(() => {
43
- if (!status) {
44
- return {
45
- status: null,
46
- isPremium: false,
47
- isExpired: false,
48
- isLifetime: false,
49
- daysRemaining: null,
50
- formattedExpirationDate: null,
51
- formattedPurchaseDate: null,
52
- statusKey: SUBSCRIPTION_STATUS.NONE,
53
- };
54
- }
55
-
56
- const isValid = isSubscriptionValid(status);
57
- const isExpired = status.isPremium && !isValid;
58
- const isLifetime = status.isPremium && !status.expiresAt;
59
- const daysRemainingValue = calculateDaysRemaining(status.expiresAt ?? null);
60
- const isPremium = status.isPremium && isValid;
61
-
62
- let statusKey: SubscriptionStatusType = status.status || SUBSCRIPTION_STATUS.NONE;
63
-
64
- // Override status key based on current calculation for active/expired
65
- if (status.isPremium) {
66
- statusKey = isExpired ? SUBSCRIPTION_STATUS.EXPIRED : SUBSCRIPTION_STATUS.ACTIVE;
67
- } else if (status.status === SUBSCRIPTION_STATUS.CANCELED) {
68
- statusKey = SUBSCRIPTION_STATUS.CANCELED;
69
- } else {
70
- statusKey = SUBSCRIPTION_STATUS.NONE;
71
- }
72
-
73
- return {
74
- status,
75
- isPremium,
76
- isExpired,
77
- isLifetime,
78
- daysRemaining: daysRemainingValue,
79
- formattedExpirationDate: formatDate(status.expiresAt ?? null),
80
- formattedPurchaseDate: formatDate(status.purchasedAt ?? null),
81
- statusKey,
82
- };
83
- }, [status]);
84
- }
85
-
@@ -1,84 +0,0 @@
1
- # useSubscriptionGate Hook
2
-
3
- Subscription-only feature gating with simple, focused API.
4
-
5
- ## Location
6
-
7
- **Import Path**: `@umituz/react-native-subscription`
8
-
9
- **File**: `src/presentation/hooks/useSubscriptionGate.ts`
10
-
11
- **Type**: Hook
12
-
13
- ## Strategy
14
-
15
- ### Subscription Gating Flow
16
-
17
- 1. **Subscription Check**: Verify if user has active subscription
18
- 2. **Gate Function**: Provide requireSubscription function for gating
19
- 3. **Action Wrapping**: Wrap actions behind subscription check
20
- 4. **Callback Trigger**: Execute callback when subscription is required
21
- 5. **Boolean Access**: Provide simple hasSubscription boolean for conditional rendering
22
-
23
- ### Integration Points
24
-
25
- - **usePremium**: For subscription status check
26
- - **Paywall Domain**: For subscription upgrade flow
27
- - **Feature Gates**: For unified feature access control
28
-
29
- ## Restrictions
30
-
31
- ### REQUIRED
32
-
33
- - **Subscription Status**: MUST provide hasSubscription parameter
34
- - **Callback**: MUST implement onSubscriptionRequired callback
35
- - **Return Check**: SHOULD check return value from requireSubscription
36
-
37
- ### PROHIBITED
38
-
39
- - **NEVER** show protected content without checking hasSubscription
40
- - **NEVER** use for security decisions without server validation
41
- - **DO NOT** assume subscription status (always verify)
42
-
43
- ### CRITICAL SAFETY
44
-
45
- - **ALWAYS** verify hasSubscription before allowing access
46
- - **NEVER** trust client-side state for security
47
- - **MUST** implement proper upgrade flow
48
- - **ALWAYS** handle both subscribed and non-subscribed states
49
-
50
- ## AI Agent Guidelines
51
-
52
- ### When Implementing Subscription Gates
53
-
54
- 1. **Always** check hasSubscription before showing protected content
55
- 2. **Always** provide clear upgrade path in callback
56
- 3. **Always** use requireSubscription for action gating
57
- 4. **Never** bypass subscription checks
58
- 5. **Always** test with both subscribed and non-subscribed users
59
-
60
- ### Integration Checklist
61
-
62
- - [ ] Import from correct path: `@umituz/react-native-subscription`
63
- - [ ] Provide hasSubscription from usePremium
64
- - [ ] Implement onSubscriptionRequired callback
65
- - [ ] Use requireSubscription for action gating
66
- - [ ] Check hasSubscription for conditional rendering
67
- - [ ] Test with subscribed user
68
- - [ ] Test with non-subscribed user
69
- - [ ] Verify upgrade flow triggers correctly
70
-
71
- ### Common Patterns
72
-
73
- 1. **Action Gating**: Use requireSubscription to wrap actions
74
- 2. **Conditional Rendering**: Check hasSubscription for UI
75
- 3. **Button States**: Disable buttons when not subscribed
76
- 4. **Upgrade Prompts**: Show in callback when not subscribed
77
-
78
- ## Related Documentation
79
-
80
- - **usePremium**: Subscription status check
81
- - **usePremiumGate**: Premium feature gating
82
- - **useAuthGate**: Auth + subscription gating
83
- - **useFeatureGate**: Unified feature gating
84
- - **Paywall Domain**: `src/domains/paywall/README.md`
@@ -1,67 +0,0 @@
1
- /**
2
- * useSubscriptionGate Hook
3
- *
4
- * Single responsibility: Subscription/Premium gating
5
- * Checks if user has active subscription before allowing actions.
6
- *
7
- * @example
8
- * ```typescript
9
- * const { requireSubscription, hasSubscription } = useSubscriptionGate({
10
- * hasSubscription: isPremium,
11
- * onSubscriptionRequired: () => showPaywall(),
12
- * });
13
- *
14
- * const handlePremiumAction = () => {
15
- * requireSubscription(() => doPremiumThing());
16
- * };
17
- * ```
18
- */
19
-
20
- import { useCallback } from "react";
21
-
22
- declare const __DEV__: boolean;
23
-
24
- export interface UseSubscriptionGateParams {
25
- /** Whether user has active subscription */
26
- hasSubscription: boolean;
27
- /** Callback when subscription is required */
28
- onSubscriptionRequired: () => void;
29
- }
30
-
31
- export interface UseSubscriptionGateResult {
32
- /** Whether user has active subscription */
33
- hasSubscription: boolean;
34
- /** Gate action behind subscription - executes if subscribed, else shows paywall */
35
- requireSubscription: (action: () => void | Promise<void>) => boolean;
36
- }
37
-
38
- export function useSubscriptionGate(
39
- params: UseSubscriptionGateParams
40
- ): UseSubscriptionGateResult {
41
- const { hasSubscription, onSubscriptionRequired } = params;
42
-
43
- const requireSubscription = useCallback(
44
- (_action: () => void | Promise<void>): boolean => {
45
- if (!hasSubscription) {
46
- if (__DEV__) {
47
-
48
- console.log("[useSubscriptionGate] No subscription, showing paywall");
49
- }
50
- onSubscriptionRequired();
51
- return false;
52
- }
53
-
54
- if (__DEV__) {
55
-
56
- console.log("[useSubscriptionGate] Has subscription, proceeding");
57
- }
58
- return true;
59
- },
60
- [hasSubscription, onSubscriptionRequired]
61
- );
62
-
63
- return {
64
- hasSubscription,
65
- requireSubscription,
66
- };
67
- }
@@ -1,94 +0,0 @@
1
- # useSubscriptionStatus Hook
2
-
3
- Hook for accessing detailed subscription status information.
4
-
5
- ## Location
6
-
7
- **Import Path**: `@umituz/react-native-subscription`
8
-
9
- **File**: `src/presentation/hooks/useSubscriptionStatus.ts`
10
-
11
- **Type**: Hook
12
-
13
- ## Strategy
14
-
15
- ### Subscription Status Flow
16
-
17
- 1. **Status Fetch**: Retrieve current subscription status from repository
18
- 2. **Status Parsing**: Extract tier, active state, expiration info
19
- 3. **Real-time Updates**: Update when subscription changes
20
- 4. **Expiration Tracking**: Calculate days until expiration
21
- 5. **Renewal Status**: Determine if subscription will auto-renew
22
- 6. **Caching**: Cache status for performance (5 min default)
23
-
24
- ### Integration Points
25
-
26
- - **Subscription Repository**: `src/infrastructure/repositories/SubscriptionRepository.ts`
27
- - **SubscriptionStatus Entity**: `src/domain/entities/README.md`
28
- - **TanStack Query**: For caching and real-time updates
29
- - **RevenueCat**: For subscription data source
30
-
31
- ## Restrictions
32
-
33
- ### REQUIRED
34
-
35
- - **Loading State**: MUST handle loading state
36
- - **Error Handling**: MUST handle error state
37
- - **Null Check**: MUST handle null status (guest users)
38
- - **Expiration**: SHOULD warn users before expiration
39
-
40
- ### PROHIBITED
41
-
42
- - **NEVER** assume status exists (check for null)
43
- - **NEVER** use for security decisions without server validation
44
- - **DO NOT** show expiration for lifetime subscriptions
45
- - **DO NOT** cache beyond configured time
46
-
47
- ### CRITICAL SAFETY
48
-
49
- - **ALWAYS** check if status is null before accessing properties
50
- - **NEVER** trust client-side status for security
51
- - **MUST** implement error boundaries
52
- - **ALWAYS** refresh status when app comes to foreground
53
-
54
- ## AI Agent Guidelines
55
-
56
- ### When Displaying Subscription Info
57
-
58
- 1. **Always** check for null status (guest users)
59
- 2. **Always** handle loading and error states
60
- 3. **Always** show expiration warnings
61
- 4. **Always** display auto-renewal status
62
- 5. **Never** show technical details to end users
63
-
64
- ### Integration Checklist
65
-
66
- - [ ] Import from correct path: `@umituz/react-native-subscription`
67
- - [ ] Handle loading state
68
- - [ ] Handle error state
69
- - [ ] Check for null status (guest users)
70
- - [ ] Display subscription tier
71
- - [ ] Show expiration date
72
- - [ ] Show days until expiration
73
- - [ ] Show auto-renewal status
74
- - [ ] Implement expiration warnings
75
- - [ ] Test with active subscription
76
- - [ ] Test with expired subscription
77
- - [ ] Test with guest user (null status)
78
-
79
- ### Common Patterns
80
-
81
- 1. **Status Badge**: Visual indicator of subscription status
82
- 2. **Expiration Countdown**: Days remaining until expiration
83
- 3. **Warning System**: Notify users before expiration
84
- 4. **Detail Card**: Comprehensive subscription information
85
- 5. **Lifecycle Management**: Handle subscription events
86
-
87
- ## Related Documentation
88
-
89
- - **usePremium**: Simple premium status check
90
- - **useSubscription**: Detailed subscription information
91
- - **useSubscriptionDetails**: Package and feature details
92
- - **useUserTier**: Tier information
93
- - **SubscriptionStatus Entity**: `src/domain/entities/README.md`
94
- - **Subscription Repository**: `src/infrastructure/repositories/README.md`