@umituz/react-native-subscription 2.14.97 → 2.14.99

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 (90) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +461 -0
  3. package/package.json +1 -3
  4. package/src/application/README.md +229 -0
  5. package/src/application/ports/README.md +103 -0
  6. package/src/domain/README.md +402 -0
  7. package/src/domain/constants/README.md +80 -0
  8. package/src/domain/entities/README.md +176 -0
  9. package/src/domain/errors/README.md +307 -0
  10. package/src/domain/value-objects/README.md +186 -0
  11. package/src/domains/README.md +240 -0
  12. package/src/domains/config/README.md +390 -0
  13. package/src/domains/config/domain/README.md +390 -0
  14. package/src/domains/config/domain/entities/README.md +350 -0
  15. package/src/domains/paywall/README.md +371 -0
  16. package/src/domains/paywall/components/PaywallHeader.tsx +8 -11
  17. package/src/domains/paywall/components/README.md +185 -0
  18. package/src/domains/paywall/entities/README.md +199 -0
  19. package/src/domains/paywall/hooks/README.md +129 -0
  20. package/src/domains/wallet/README.md +292 -0
  21. package/src/domains/wallet/domain/README.md +108 -0
  22. package/src/domains/wallet/domain/entities/README.md +122 -0
  23. package/src/domains/wallet/domain/errors/README.md +157 -0
  24. package/src/domains/wallet/infrastructure/README.md +96 -0
  25. package/src/domains/wallet/presentation/components/BalanceCard.tsx +6 -12
  26. package/src/domains/wallet/presentation/components/README.md +231 -0
  27. package/src/domains/wallet/presentation/hooks/README.md +255 -0
  28. package/src/infrastructure/README.md +514 -0
  29. package/src/infrastructure/mappers/README.md +34 -0
  30. package/src/infrastructure/models/README.md +26 -0
  31. package/src/infrastructure/repositories/README.md +385 -0
  32. package/src/infrastructure/services/README.md +374 -0
  33. package/src/presentation/README.md +410 -0
  34. package/src/presentation/components/README.md +183 -0
  35. package/src/presentation/components/details/CreditRow.md +337 -0
  36. package/src/presentation/components/details/DetailRow.md +283 -0
  37. package/src/presentation/components/details/PremiumDetailsCard.md +266 -0
  38. package/src/presentation/components/details/PremiumStatusBadge.md +266 -0
  39. package/src/presentation/components/details/README.md +449 -0
  40. package/src/presentation/components/feedback/PaywallFeedbackModal.md +314 -0
  41. package/src/presentation/components/feedback/README.md +447 -0
  42. package/src/presentation/components/paywall/PaywallModal.md +444 -0
  43. package/src/presentation/components/paywall/README.md +190 -0
  44. package/src/presentation/components/sections/README.md +468 -0
  45. package/src/presentation/components/sections/SubscriptionSection.md +246 -0
  46. package/src/presentation/hooks/README.md +743 -0
  47. package/src/presentation/hooks/useAuthAwarePurchase.md +359 -0
  48. package/src/presentation/hooks/useAuthGate.md +403 -0
  49. package/src/presentation/hooks/useAuthSubscriptionSync.md +398 -0
  50. package/src/presentation/hooks/useCreditChecker.md +407 -0
  51. package/src/presentation/hooks/useCredits.md +342 -0
  52. package/src/presentation/hooks/useCreditsGate.md +346 -0
  53. package/src/presentation/hooks/useDeductCredit.md +176 -0
  54. package/src/presentation/hooks/useDevTestCallbacks.md +422 -0
  55. package/src/presentation/hooks/useFeatureGate.md +157 -0
  56. package/src/presentation/hooks/useInitializeCredits.md +458 -0
  57. package/src/presentation/hooks/usePaywall.md +334 -0
  58. package/src/presentation/hooks/usePaywallOperations.md +486 -0
  59. package/src/presentation/hooks/usePaywallVisibility.md +344 -0
  60. package/src/presentation/hooks/usePremium.md +230 -0
  61. package/src/presentation/hooks/usePremiumGate.md +423 -0
  62. package/src/presentation/hooks/usePremiumWithCredits.md +429 -0
  63. package/src/presentation/hooks/useSubscription.md +450 -0
  64. package/src/presentation/hooks/useSubscriptionDetails.md +438 -0
  65. package/src/presentation/hooks/useSubscriptionGate.md +168 -0
  66. package/src/presentation/hooks/useSubscriptionSettingsConfig.md +374 -0
  67. package/src/presentation/hooks/useSubscriptionStatus.md +424 -0
  68. package/src/presentation/hooks/useUserTier.md +356 -0
  69. package/src/presentation/hooks/useUserTierWithRepository.md +452 -0
  70. package/src/presentation/screens/README.md +194 -0
  71. package/src/presentation/types/README.md +38 -0
  72. package/src/presentation/utils/README.md +52 -0
  73. package/src/revenuecat/README.md +523 -0
  74. package/src/revenuecat/application/README.md +158 -0
  75. package/src/revenuecat/application/ports/README.md +169 -0
  76. package/src/revenuecat/domain/README.md +147 -0
  77. package/src/revenuecat/domain/constants/README.md +183 -0
  78. package/src/revenuecat/domain/entities/README.md +382 -0
  79. package/src/revenuecat/domain/errors/README.md +197 -0
  80. package/src/revenuecat/domain/types/README.md +373 -0
  81. package/src/revenuecat/domain/value-objects/README.md +441 -0
  82. package/src/revenuecat/infrastructure/README.md +50 -0
  83. package/src/revenuecat/infrastructure/config/README.md +40 -0
  84. package/src/revenuecat/infrastructure/handlers/README.md +218 -0
  85. package/src/revenuecat/infrastructure/managers/README.md +49 -0
  86. package/src/revenuecat/infrastructure/services/README.md +325 -0
  87. package/src/revenuecat/infrastructure/utils/README.md +382 -0
  88. package/src/revenuecat/presentation/README.md +184 -0
  89. package/src/revenuecat/presentation/hooks/README.md +56 -0
  90. package/src/utils/README.md +529 -0
@@ -0,0 +1,96 @@
1
+ # Wallet Infrastructure
2
+
3
+ Infrastructure layer for wallet and credits functionality.
4
+
5
+ ## Overview
6
+
7
+ This directory contains implementations for credit persistence, transactions, and credit operations.
8
+
9
+ ## Structure
10
+
11
+ ```
12
+ infrastructure/
13
+ ├── repositories/ # Data persistence implementations
14
+ │ └── CreditsRepository.ts
15
+ └── services/ # External service integrations
16
+ └── CreditsService.ts
17
+ ```
18
+
19
+ ## Credits Repository
20
+
21
+ Handles credit data persistence with duplicate protection.
22
+
23
+ ### Key Features
24
+
25
+ - **Duplicate Protection**: Prevents duplicate credit allocations
26
+ - **Optimistic Updates**: Immediate UI updates with rollback
27
+ - **Transactional**: Atomic credit operations
28
+ - **ACCUMULATE Mode**: Adds credits on renewal
29
+
30
+ ### Core Methods
31
+
32
+ ```typescript
33
+ class CreditsRepository implements ICreditsRepository {
34
+ async getCredits(userId: string): Promise<UserCredits | null>;
35
+ async initializeCredits(
36
+ userId: string,
37
+ purchaseId?: string,
38
+ productId?: string
39
+ ): Promise<CreditsResult>;
40
+ async deductCredit(userId: string, amount: number): Promise<CreditsResult>;
41
+ async addCredits(userId: string, amount: number): Promise<CreditsResult>;
42
+ }
43
+ ```
44
+
45
+ ### Usage
46
+
47
+ ```typescript
48
+ import { CreditsRepository } from './repositories/CreditsRepository';
49
+ import { getCreditsRepository } from './repositories/CreditsRepositoryProvider';
50
+
51
+ const repository = getCreditsRepository();
52
+
53
+ // Initialize credits
54
+ const result = await repository.initializeCredits('user-123', 'purchase-456', 'premium_monthly');
55
+ if (result.success) {
56
+ console.log('Credits:', result.data.credits);
57
+ }
58
+
59
+ // Deduct credits
60
+ const deductResult = await repository.deductCredit('user-123', 5);
61
+ if (deductResult.success) {
62
+ console.log('Credits deducted successfully');
63
+ } else if (deductResult.error?.code === 'CREDITS_EXHAUSTED') {
64
+ console.log('Not enough credits');
65
+ }
66
+ ```
67
+
68
+ ## Duplicate Protection
69
+
70
+ The repository prevents duplicate credit allocations based on `purchaseId`:
71
+
72
+ ```typescript
73
+ // First call
74
+ await repository.initializeCredits(userId, 'renewal-123', 'premium');
75
+ // Returns: { success: true, data: { credits: 100 } }
76
+
77
+ // Second call with same purchaseId
78
+ await repository.initializeCredits(userId, 'renewal-123', 'premium');
79
+ // Returns: { success: true, duplicate: true, data: { credits: 100 } }
80
+ // Credits not added again
81
+ ```
82
+
83
+ ## Best Practices
84
+
85
+ 1. **Check Before Deduct**: Always verify credit balance
86
+ 2. **Handle Errors**: Catch and handle credit errors appropriately
87
+ 3. **Use Transactions**: Ensure data consistency
88
+ 4. **Log Operations**: Track credit operations for debugging
89
+ 5. **Test Edge Cases**: Zero credits, max credits, duplicates
90
+ 6. **Validate Input**: Validate all input parameters
91
+
92
+ ## Related
93
+
94
+ - [Wallet Domain](../domain/README.md)
95
+ - [Credits Entity](../domain/entities/README.md)
96
+ - [useCredits Hook](../../presentation/hooks/useCredits.md)
@@ -1,13 +1,13 @@
1
1
  /**
2
2
  * Balance Card Component
3
3
  *
4
- * Displays user's credit balance with gradient background.
4
+ * Displays user's credit balance with solid background.
5
5
  * Props-driven for full customization.
6
6
  */
7
7
 
8
8
  import React from "react";
9
9
  import { View, StyleSheet } from "react-native";
10
- import { LinearGradient } from "expo-linear-gradient";
10
+
11
11
  import {
12
12
  useAppDesignTokens,
13
13
  AtomicText,
@@ -31,17 +31,11 @@ export const BalanceCard: React.FC<BalanceCardProps> = ({
31
31
  iconName = "wallet",
32
32
  }) => {
33
33
  const tokens = useAppDesignTokens();
34
- const gradientColors = [
35
- tokens.colors.primary,
36
- tokens.colors.primaryDark || tokens.colors.primary,
37
- ] as const;
34
+
38
35
 
39
36
  return (
40
- <LinearGradient
41
- colors={gradientColors}
42
- start={{ x: 0, y: 0 }}
43
- end={{ x: 1, y: 1 }}
44
- style={styles.container}
37
+ <View
38
+ style={[styles.container, { backgroundColor: tokens.colors.primary }]}
45
39
  >
46
40
  <View style={styles.content}>
47
41
  <View style={styles.textContainer}>
@@ -73,7 +67,7 @@ export const BalanceCard: React.FC<BalanceCardProps> = ({
73
67
  <AtomicIcon name={iconName} size="xl" color="onPrimary" />
74
68
  </View>
75
69
  </View>
76
- </LinearGradient>
70
+ </View>
77
71
  );
78
72
  };
79
73
 
@@ -0,0 +1,231 @@
1
+ # Wallet Presentation Components
2
+
3
+ UI components for wallet and credit display.
4
+
5
+ ## Overview
6
+
7
+ This directory contains React Native components for displaying credits, transactions, and wallet information.
8
+
9
+ ## Components
10
+
11
+ ### CreditBalanceCard
12
+ Card displaying current credit balance.
13
+
14
+ ```typescript
15
+ interface CreditBalanceCardProps {
16
+ credits: number;
17
+ balance: number;
18
+ isLoading?: boolean;
19
+ onPress?: () => void;
20
+ onRefresh?: () => void;
21
+ }
22
+ ```
23
+
24
+ **Usage:**
25
+ ```typescript
26
+ <CreditBalanceCard
27
+ credits={50}
28
+ balance={0.50}
29
+ onPress={() => navigation.navigate('CreditHistory')}
30
+ onRefresh={() => refetch()}
31
+ />
32
+ ```
33
+
34
+ ### TransactionItem
35
+ Individual transaction display component.
36
+
37
+ ```typescript
38
+ interface TransactionItemProps {
39
+ transaction: Transaction;
40
+ format?: 'full' | 'compact';
41
+ }
42
+ ```
43
+
44
+ **Usage:**
45
+ ```typescript
46
+ <TransactionItem
47
+ transaction={{
48
+ id: 'tx_123',
49
+ amount: -5,
50
+ reason: 'AI Generation',
51
+ timestamp: new Date(),
52
+ type: 'deduction',
53
+ }}
54
+ format="full"
55
+ />
56
+ ```
57
+
58
+ ### CreditProgressBar
59
+ Progress bar showing credit usage.
60
+
61
+ ```typescript
62
+ interface CreditProgressBarProps {
63
+ current: number;
64
+ total: number;
65
+ showLabel?: boolean;
66
+ showPercentage?: boolean;
67
+ height?: number;
68
+ }
69
+ ```
70
+
71
+ **Usage:**
72
+ ```typescript
73
+ <CreditProgressBar
74
+ current={50}
75
+ total={100}
76
+ showLabel={true}
77
+ showPercentage={true}
78
+ height={8}
79
+ />
80
+ ```
81
+
82
+ ### CreditPackageCard
83
+ Display card for purchasable credit packages.
84
+
85
+ ```typescript
86
+ interface CreditPackageCardProps {
87
+ package: {
88
+ id: string;
89
+ amount: number;
90
+ price: number;
91
+ bonus?: number;
92
+ currency: string;
93
+ };
94
+ onPress: () => void;
95
+ highlight?: boolean;
96
+ }
97
+ ```
98
+
99
+ **Usage:**
100
+ ```typescript
101
+ <CreditPackageCard
102
+ package={{
103
+ id: 'premium_credits',
104
+ amount: 100,
105
+ price: 9.99,
106
+ bonus: 10,
107
+ currency: 'USD',
108
+ }}
109
+ onPress={() => purchaseCredits('premium_credits')}
110
+ highlight={true}
111
+ />
112
+ ```
113
+
114
+ ## Usage Patterns
115
+
116
+ ### Complete Credit Dashboard
117
+
118
+ ```typescript
119
+ function CreditDashboard() {
120
+ const { credits, transactions, isLoading, refetch } = useCredits();
121
+
122
+ return (
123
+ <ScrollView>
124
+ <CreditBalanceCard
125
+ credits={credits}
126
+ balance={calculateBalance(credits)}
127
+ onRefresh={refetch}
128
+ />
129
+
130
+ <View style={styles.section}>
131
+ <Text style={styles.title}>Recent Transactions</Text>
132
+ {transactions.slice(0, 10).map(tx => (
133
+ <TransactionItem key={tx.id} transaction={tx} />
134
+ ))}
135
+ </View>
136
+
137
+ <Button onPress={() => navigation.navigate('CreditPackages')}>
138
+ Get More Credits
139
+ </Button>
140
+ </ScrollView>
141
+ );
142
+ }
143
+ ```
144
+
145
+ ### Credit Warning Banner
146
+
147
+ ```typescript
148
+ function LowCreditWarning() {
149
+ const { credits } = useCredits();
150
+ const warningThreshold = 20;
151
+
152
+ if (credits > warningThreshold) return null;
153
+
154
+ return (
155
+ <Banner type={credits === 0 ? 'error' : 'warning'}>
156
+ <Text>
157
+ {credits === 0
158
+ ? 'No credits remaining'
159
+ : `Only ${credits} credits left`
160
+ }
161
+ </Text>
162
+ <Button onPress={() => navigation.navigate('CreditPackages')}>
163
+ Get More
164
+ </Button>
165
+ </Banner>
166
+ );
167
+ }
168
+ ```
169
+
170
+ ### Credit History List
171
+
172
+ ```typescript
173
+ function TransactionHistory() {
174
+ const { transactions } = useCredits();
175
+
176
+ return (
177
+ <FlatList
178
+ data={transactions}
179
+ keyExtractor={(item) => item.id}
180
+ renderItem={({ item }) => (
181
+ <TransactionItem transaction={item} format="compact" />
182
+ )}
183
+ ListHeaderComponent={() => (
184
+ <Text style={styles.title}>Transaction History</Text>
185
+ )}
186
+ ListEmptyComponent={() => (
187
+ <EmptyState
188
+ icon="receipt"
189
+ title="No transactions yet"
190
+ message="Your credit transaction history will appear here"
191
+ />
192
+ )}
193
+ />
194
+ );
195
+ }
196
+ ```
197
+
198
+ ## Styling
199
+
200
+ Components use design system:
201
+
202
+ ```typescript
203
+ import { useAppDesignTokens } from '@umituz/react-native-design-system';
204
+
205
+ const tokens = useAppDesignTokens();
206
+
207
+ const styles = StyleSheet.create({
208
+ card: {
209
+ backgroundColor: tokens.colors.surface,
210
+ borderRadius: tokens.radius.lg,
211
+ padding: tokens.spacing.lg,
212
+ marginBottom: tokens.spacing.md,
213
+ },
214
+ });
215
+ ```
216
+
217
+ ## Best Practices
218
+
219
+ 1. **Visual Hierarchy**: Emphasize important information
220
+ 2. **Color Coding**: Use colors to indicate status (low/warning/good)
221
+ 3. **Loading States**: Show skeletons while loading
222
+ 4. **Empty States**: Provide helpful empty state messages
223
+ 5. **Refresh Capability**: Allow manual refresh
224
+ 6. **Transactional History**: Show clear transaction history
225
+ 7. **Purchase Links**: Easy access to purchase more credits
226
+
227
+ ## Related
228
+
229
+ - [Credit Row](../../../presentation/components/details/CreditRow.md)
230
+ - [Credits Hook](../hooks/README.md)
231
+ - [Wallet Domain](../../domain/README.md)
@@ -0,0 +1,255 @@
1
+ # Wallet Presentation Hooks
2
+
3
+ React hooks for wallet and credit functionality.
4
+
5
+ ## Overview
6
+
7
+ This directory contains React hooks specifically for credit management and wallet operations.
8
+
9
+ ## Hooks
10
+
11
+ ### useCredits
12
+ Access and manage credit balance.
13
+
14
+ ```typescript
15
+ function useCredits(params: {
16
+ userId: string | undefined;
17
+ enabled?: boolean;
18
+ }): {
19
+ credits: number;
20
+ balance: number;
21
+ transactions: Transaction[];
22
+ isLoading: boolean;
23
+ error: Error | null;
24
+ refetch: () => Promise<void>;
25
+ }
26
+ ```
27
+
28
+ **Usage:**
29
+ ```typescript
30
+ function CreditBalance() {
31
+ const { credits, isLoading } = useCredits({ userId: user?.uid });
32
+
33
+ if (isLoading) return <LoadingSpinner />;
34
+
35
+ return (
36
+ <View>
37
+ <Text>Balance: {credits} credits</Text>
38
+ </View>
39
+ );
40
+ }
41
+ ```
42
+
43
+ ### useDeductCredit
44
+ Deduct credits with optimistic updates.
45
+
46
+ ```typescript
47
+ function useDeductCredit(params: {
48
+ userId: string | undefined;
49
+ onCreditsExhausted?: () => void;
50
+ }): {
51
+ deductCredit: (cost?: number) => Promise<boolean>;
52
+ deductCredits: (cost: number) => Promise<boolean>;
53
+ isDeducting: boolean;
54
+ }
55
+ ```
56
+
57
+ **Usage:**
58
+ ```typescript
59
+ function AIGeneration() {
60
+ const { deductCredit } = useDeductCredit({
61
+ userId: user?.uid,
62
+ onCreditsExhausted: () => showPaywall(),
63
+ });
64
+
65
+ const handleGenerate = async () => {
66
+ const success = await deductCredit(5);
67
+ if (success) {
68
+ await callAIGenerationAPI();
69
+ }
70
+ };
71
+ }
72
+ ```
73
+
74
+ ### useInitializeCredits
75
+ Initialize credits after purchase.
76
+
77
+ ```typescript
78
+ function useInitializeCredits(params: {
79
+ userId: string | undefined;
80
+ }): {
81
+ initializeCredits: (options?: {
82
+ purchaseId?: string;
83
+ productId?: string;
84
+ }) => Promise<boolean>;
85
+ isInitializing: boolean;
86
+ }
87
+ ```
88
+
89
+ **Usage:**
90
+ ```typescript
91
+ function PurchaseCompletion() {
92
+ const { initializeCredits } = useInitializeCredits({
93
+ userId: user?.uid,
94
+ });
95
+
96
+ const handlePurchaseComplete = async (transaction: Purchase) => {
97
+ const success = await initializeCredits({
98
+ purchaseId: transaction.transactionId,
99
+ productId: transaction.productId,
100
+ });
101
+
102
+ if (success) {
103
+ Alert.alert('Success', 'Credits added!');
104
+ }
105
+ };
106
+ }
107
+ ```
108
+
109
+ ### useCreditChecker
110
+ Check credit availability before operations.
111
+
112
+ ```typescript
113
+ function useCreditChecker(params?: {
114
+ onCreditDeducted?: (userId: string, cost: number) => void;
115
+ }): {
116
+ checkCreditsAvailable: (
117
+ userId: string | undefined,
118
+ cost?: number
119
+ ) => Promise<CreditCheckResult>;
120
+ deductCreditsAfterSuccess: (
121
+ userId: string | undefined,
122
+ cost?: number
123
+ ) => Promise<void>;
124
+ }
125
+ ```
126
+
127
+ **Usage:**
128
+ ```typescript
129
+ function PreCheckFeature() {
130
+ const { checkCreditsAvailable } = useCreditChecker();
131
+
132
+ const handleCheck = async () => {
133
+ const result = await checkCreditsAvailable(user?.uid, 10);
134
+
135
+ if (!result.canProceed) {
136
+ Alert.alert(
137
+ 'Insufficient Credits',
138
+ `You need ${result.required} credits but have ${result.currentBalance}`
139
+ );
140
+ return;
141
+ }
142
+
143
+ await executeFeature();
144
+ };
145
+ }
146
+ ```
147
+
148
+ ## Usage Patterns
149
+
150
+ ### Two-Step Credit Process
151
+
152
+ ```typescript
153
+ function TwoStepCreditProcess() {
154
+ const { checkCreditsAvailable } = useCreditChecker();
155
+ const { deductCreditsAfterSuccess } = useCreditChecker();
156
+
157
+ const handleOperation = async () => {
158
+ // Step 1: Check credits
159
+ const check = await checkCreditsAvailable(user?.uid, 10);
160
+
161
+ if (!check.canProceed) {
162
+ showPaywall({ required: 10 });
163
+ return;
164
+ }
165
+
166
+ try {
167
+ // Step 2: Perform operation
168
+ await performOperation();
169
+
170
+ // Step 3: Deduct credits after success
171
+ await deductCreditsAfterSuccess(user?.uid, 10);
172
+
173
+ Alert.alert('Success', 'Operation completed');
174
+ } catch (error) {
175
+ Alert.alert('Error', 'Operation failed');
176
+ }
177
+ };
178
+ }
179
+ ```
180
+
181
+ ### With Loading and Error States
182
+
183
+ ```typescript
184
+ function CreditOperation() {
185
+ const { credits, isLoading, error } = useCredits({ userId: user?.uid });
186
+ const { deductCredit } = useDeductCredit({
187
+ userId: user?.uid,
188
+ });
189
+
190
+ const handleDeduct = async () => {
191
+ if (isLoading) return;
192
+
193
+ const success = await deductCredit(5);
194
+
195
+ if (success) {
196
+ await executeFeature();
197
+ } else {
198
+ Alert.alert('Failed', 'Could not deduct credits');
199
+ }
200
+ };
201
+
202
+ return (
203
+ <View>
204
+ {error && <ErrorBanner message={error.message} />}
205
+ {isLoading ? (
206
+ <LoadingSpinner />
207
+ ) : (
208
+ <>
209
+ <Text>Credits: {credits}</Text>
210
+ <Button onPress={handleDeduct} disabled={isLoading}>
211
+ Use 5 Credits
212
+ </Button>
213
+ </>
214
+ )}
215
+ </View>
216
+ );
217
+ }
218
+ ```
219
+
220
+ ### With Auto-Initialization
221
+
222
+ ```typescript
223
+ function AutoInitialize() {
224
+ const { isPremium } = usePremium();
225
+ const { credits } = useCredits({ userId: user?.uid });
226
+ const { initializeCredits, isInitializing } = useInitializeCredits({
227
+ userId: user?.uid,
228
+ });
229
+
230
+ useEffect(() => {
231
+ // Auto-initialize if premium but no credits
232
+ if (isPremium && !credits && !isInitializing) {
233
+ initializeCredits();
234
+ }
235
+ }, [isPremium, credits]);
236
+
237
+ return <YourComponent />;
238
+ }
239
+ ```
240
+
241
+ ## Best Practices
242
+
243
+ 1. **Check Balance First**: Always check before deducting
244
+ 2. **Handle Loading**: Show loading states appropriately
245
+ 3. **Error Recovery**: Handle deduction failures gracefully
246
+ 4. **Optimistic Updates**: Use optimistic updates for better UX
247
+ 5. **Track Usage**: Log all credit operations
248
+ 6. **Auto-Init**: Initialize credits after premium purchase
249
+ 7. **Test Scenarios**: Test zero credits, max credits, failures
250
+
251
+ ## Related
252
+
253
+ - [useCredits Hook Documentation](../../../presentation/hooks/useCredits.md)
254
+ - [useDeductCredit Hook Documentation](../../../presentation/hooks/useDeductCredit.md)
255
+ - [Credits Entity](../../domain/entities/README.md)