@umituz/react-native-subscription 2.14.99 → 2.14.101

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 (98) hide show
  1. package/README.md +211 -394
  2. package/package.json +3 -3
  3. package/src/application/README.md +46 -225
  4. package/src/application/ports/README.md +42 -97
  5. package/src/domain/README.md +36 -384
  6. package/src/domain/constants/README.md +0 -56
  7. package/src/domain/entities/README.md +43 -169
  8. package/src/domain/entities/SubscriptionStatus.ts +1 -1
  9. package/src/domain/errors/README.md +33 -287
  10. package/src/domain/value-objects/README.md +43 -179
  11. package/src/domains/README.md +50 -238
  12. package/src/domains/README.md.bak +274 -0
  13. package/src/domains/config/README.md +93 -383
  14. package/src/domains/config/domain/README.md +23 -376
  15. package/src/domains/config/domain/entities/README.md +34 -343
  16. package/src/domains/paywall/README.md +99 -369
  17. package/src/domains/paywall/components/README.md +34 -178
  18. package/src/domains/paywall/entities/README.md +34 -193
  19. package/src/domains/paywall/hooks/README.md +34 -122
  20. package/src/domains/wallet/README.md +34 -275
  21. package/src/domains/wallet/README.md.bak +209 -0
  22. package/src/domains/wallet/domain/README.md +34 -101
  23. package/src/domains/wallet/domain/entities/README.md +34 -115
  24. package/src/domains/wallet/domain/errors/README.md +34 -151
  25. package/src/domains/wallet/infrastructure/README.md +34 -89
  26. package/src/domains/wallet/presentation/components/README.md +34 -224
  27. package/src/domains/wallet/presentation/components/TransactionItem.tsx +1 -1
  28. package/src/domains/wallet/presentation/hooks/README.md +34 -248
  29. package/src/infrastructure/README.md +37 -496
  30. package/src/infrastructure/mappers/README.md +0 -13
  31. package/src/infrastructure/repositories/README.md +74 -360
  32. package/src/infrastructure/services/ActivationHandler.ts +1 -1
  33. package/src/infrastructure/services/README.md +95 -370
  34. package/src/infrastructure/services/SubscriptionService.ts +1 -1
  35. package/src/presentation/README.md +123 -408
  36. package/src/presentation/README.md.bak +172 -0
  37. package/src/presentation/components/README.md +151 -179
  38. package/src/presentation/components/README.md.bak +217 -0
  39. package/src/presentation/components/details/CreditRow.md +65 -310
  40. package/src/presentation/components/details/DetailRow.md +63 -255
  41. package/src/presentation/components/details/PremiumDetailsCard.md +65 -238
  42. package/src/presentation/components/details/PremiumStatusBadge.md +64 -239
  43. package/src/presentation/components/details/README.md +97 -447
  44. package/src/presentation/components/feedback/PaywallFeedbackModal.md +63 -287
  45. package/src/presentation/components/feedback/README.md +97 -445
  46. package/src/presentation/components/paywall/PaywallModal.md +66 -416
  47. package/src/presentation/components/paywall/README.md +50 -186
  48. package/src/presentation/components/sections/README.md +97 -466
  49. package/src/presentation/components/sections/SubscriptionSection.md +92 -244
  50. package/src/presentation/hooks/README.md +154 -741
  51. package/src/presentation/hooks/useAuthAwarePurchase.md +58 -325
  52. package/src/presentation/hooks/useAuthGate.md +61 -375
  53. package/src/presentation/hooks/useAuthSubscriptionSync.md +66 -370
  54. package/src/presentation/hooks/useCreditChecker.md +73 -378
  55. package/src/presentation/hooks/useCredits.md +74 -313
  56. package/src/presentation/hooks/useCredits.md.bak +231 -0
  57. package/src/presentation/hooks/useCreditsGate.md +66 -318
  58. package/src/presentation/hooks/useDeductCredit.md +0 -76
  59. package/src/presentation/hooks/useDeductCredit.ts +1 -1
  60. package/src/presentation/hooks/useDevTestCallbacks.md +63 -394
  61. package/src/presentation/hooks/useFeatureGate.md +105 -150
  62. package/src/presentation/hooks/useFeatureGate.md.bak +284 -0
  63. package/src/presentation/hooks/useInitializeCredits.md +64 -430
  64. package/src/presentation/hooks/usePaywall.md +61 -306
  65. package/src/presentation/hooks/usePaywallOperations.md +64 -458
  66. package/src/presentation/hooks/usePaywallVisibility.md +67 -316
  67. package/src/presentation/hooks/usePremium.md +84 -226
  68. package/src/presentation/hooks/usePremiumGate.md +60 -395
  69. package/src/presentation/hooks/usePremiumWithCredits.md +64 -401
  70. package/src/presentation/hooks/useSubscription.md +66 -422
  71. package/src/presentation/hooks/useSubscriptionDetails.md +65 -410
  72. package/src/presentation/hooks/useSubscriptionGate.md +80 -164
  73. package/src/presentation/hooks/useSubscriptionSettingsConfig.md +66 -346
  74. package/src/presentation/hooks/useSubscriptionStatus.md +66 -396
  75. package/src/presentation/hooks/useUserTier.md +63 -328
  76. package/src/presentation/hooks/useUserTierWithRepository.md +64 -424
  77. package/src/presentation/screens/README.md +48 -190
  78. package/src/presentation/types/README.md +0 -16
  79. package/src/presentation/utils/README.md +0 -21
  80. package/src/presentation/utils/subscriptionDateUtils.ts +1 -1
  81. package/src/revenuecat/README.md +99 -518
  82. package/src/revenuecat/application/README.md +35 -150
  83. package/src/revenuecat/application/ports/README.md +34 -162
  84. package/src/revenuecat/domain/README.md +42 -141
  85. package/src/revenuecat/domain/constants/README.md +34 -176
  86. package/src/revenuecat/domain/entities/README.md +34 -374
  87. package/src/revenuecat/domain/errors/README.md +47 -191
  88. package/src/revenuecat/domain/types/README.md +34 -366
  89. package/src/revenuecat/domain/value-objects/README.md +34 -434
  90. package/src/revenuecat/infrastructure/README.md +34 -43
  91. package/src/revenuecat/infrastructure/config/README.md +32 -23
  92. package/src/revenuecat/infrastructure/handlers/README.md +34 -211
  93. package/src/revenuecat/infrastructure/managers/README.md +34 -42
  94. package/src/revenuecat/infrastructure/services/README.md +35 -318
  95. package/src/revenuecat/infrastructure/utils/README.md +34 -375
  96. package/src/revenuecat/presentation/README.md +34 -176
  97. package/src/revenuecat/presentation/hooks/README.md +29 -35
  98. package/src/utils/README.md +38 -525
@@ -2,345 +2,93 @@
2
2
 
3
3
  Hook for gating features behind credit requirements.
4
4
 
5
- ## Import
5
+ ## Location
6
6
 
7
- ```typescript
8
- import { useCreditsGate } from '@umituz/react-native-subscription';
9
- ```
7
+ **Import Path**: `@umituz/react-native-subscription`
10
8
 
11
- ## Signature
9
+ **File**: `src/presentation/hooks/useCreditsGate.ts`
12
10
 
13
- ```typescript
14
- function useCreditsGate(config: {
15
- creditCost: number;
16
- featureId: string;
17
- }): {
18
- hasCredits: boolean;
19
- credits: number;
20
- consumeCredit: () => Promise<CreditsResult>;
21
- isLoading: boolean;
22
- showPurchasePrompt: () => void;
23
- }
24
- ```
11
+ **Type**: Hook
25
12
 
26
- ## Parameters
13
+ ## Strategy
27
14
 
28
- | Parameter | Type | Required | Description |
29
- |-----------|------|----------|-------------|
30
- | `config.creditCost` | `number` | Yes | Number of credits required |
31
- | `config.featureId` | `string` | Yes | Unique identifier for the feature |
15
+ ### Credit Gating Flow
32
16
 
33
- ## Returns
17
+ 1. **Credit Check**: Verify user has sufficient credits for feature
18
+ 2. **Balance Display**: Show current credit balance to user
19
+ 3. **Feature Access Control**: Enable/disable features based on credit availability
20
+ 4. **Consumption**: Deduct credits when feature is used
21
+ 5. **Purchase Prompt**: Guide users to purchase when insufficient
22
+ 6. **Transaction Tracking**: Record all credit transactions
34
23
 
35
- | Property | Type | Description |
36
- |----------|------|-------------|
37
- | `hasCredits` | `boolean` | Whether user has enough credits |
38
- | `credits` | `number` | Current credit balance |
39
- | `consumeCredit` | `() => Promise<CreditsResult>` | Function to consume credits |
40
- | `isLoading` | `boolean` | Whether hook is loading |
41
- | `showPurchasePrompt` | `() => void` | Show purchase prompt UI |
24
+ ### Integration Points
42
25
 
43
- ## Basic Usage
26
+ - **Credits Repository**: `src/domains/wallet/infrastructure/repositories/CreditsRepository.ts`
27
+ - **Credits Entity**: `src/domains/wallet/domain/entities/UserCredits.ts`
28
+ - **TanStack Query**: For optimistic updates and caching
29
+ - **Paywall Domain**: For purchase flow integration
44
30
 
45
- ```typescript
46
- function CreditFeature() {
47
- const { hasCredits, credits, consumeCredit } = useCreditsGate({
48
- creditCost: 5,
49
- featureId: 'export_data',
50
- });
31
+ ## Restrictions
51
32
 
52
- const handleExport = async () => {
53
- if (!hasCredits) {
54
- Alert.alert('Insufficient Credits', `You need 5 credits, have ${credits}`);
55
- return;
56
- }
33
+ ### REQUIRED
57
34
 
58
- const result = await consumeCredit();
35
+ - **Credit Cost**: MUST specify credit cost for feature
36
+ - **Feature ID**: MUST provide unique feature identifier
37
+ - **Balance Check**: MUST verify hasCredits before allowing action
38
+ - **Error Handling**: MUST handle consumption failures
59
39
 
60
- if (result.success) {
61
- await exportData();
62
- Alert.alert('Success', `Data exported! ${result.newBalance} credits remaining`);
63
- } else {
64
- Alert.alert('Error', result.error?.message || 'Failed to consume credits');
65
- }
66
- };
40
+ ### PROHIBITED
67
41
 
68
- return (
69
- <Button
70
- onPress={handleExport}
71
- title={`Export Data (5 credits)`}
72
- disabled={!hasCredits}
73
- />
74
- );
75
- }
76
- ```
42
+ - **NEVER** allow feature access when hasCredits is false
43
+ - **NEVER** consume credits without checking balance first
44
+ - **NEVER** assume credits will be sufficient (always check)
45
+ - **DO NOT** use for security decisions without server validation
77
46
 
78
- ## Advanced Usage
47
+ ### CRITICAL SAFETY
79
48
 
80
- ### With Purchase Prompt
49
+ - **ALWAYS** check return value from consumeCredit
50
+ - **NEVER** allow negative credit balance
51
+ - **MUST** handle insufficient credits gracefully
52
+ - **ALWAYS** show credit cost to user before action
81
53
 
82
- ```typescript
83
- function AdvancedCreditFeature() {
84
- const { hasCredits, credits, consumeCredit, showPurchasePrompt } =
85
- useCreditsGate({
86
- creditCost: 10,
87
- featureId: 'ai_analysis',
88
- });
54
+ ## AI Agent Guidelines
89
55
 
90
- const handleAnalyze = async () => {
91
- if (!hasCredits) {
92
- showPurchasePrompt();
93
- return;
94
- }
56
+ ### When Implementing Credit Gates
95
57
 
96
- const result = await consumeCredit();
58
+ 1. **Always** display credit cost to user before action
59
+ 2. **Always** check hasCredits before enabling buttons
60
+ 3. **Always** handle consumeCredit result
61
+ 4. **Never** allow action when credits are insufficient
62
+ 5. **Always** provide purchase path for credits
97
63
 
98
- if (result.success) {
99
- await performAIAnalysis();
100
- }
101
- };
64
+ ### Integration Checklist
102
65
 
103
- return (
104
- <View>
105
- <Text>Credits: {credits}</Text>
106
- <Text>Cost: 10 credits</Text>
66
+ - [ ] Import from correct path: `@umituz/react-native-subscription`
67
+ - [ ] Specify credit cost in config
68
+ - [ ] Provide unique feature ID
69
+ - [ ] Check hasCredits before enabling feature
70
+ - [ ] Handle consumeCredit result
71
+ - [ ] Show credit cost in UI
72
+ - [ ] Display current balance
73
+ - [ ] Implement purchase prompt for insufficient credits
74
+ - [ ] Test with zero balance
75
+ - [ ] Test with insufficient credits
76
+ - [ ] Test with sufficient credits
107
77
 
108
- <Button
109
- onPress={handleAnalyze}
110
- title={hasCredits ? 'Analyze (10 credits)' : 'Get More Credits'}
111
- disabled={!hasCredits && credits < 10}
112
- />
113
- </View>
114
- );
115
- }
116
- ```
78
+ ### Common Patterns
117
79
 
118
- ### With Transaction Tracking
80
+ 1. **Pre-check**: Verify balance before showing feature
81
+ 2. **Confirmation**: Ask user before expensive operations
82
+ 3. **Success Feedback**: Show message after successful consumption
83
+ 4. **Failure Handling**: Display appropriate error on failure
84
+ 5. **Purchase Flow**: Navigate to purchase screen on exhaustion
119
85
 
120
- ```typescript
121
- function TrackedCreditFeature() {
122
- const { consumeCredit, hasCredits } = useCreditsGate({
123
- creditCost: 3,
124
- featureId: 'filter_apply',
125
- });
86
+ ## Related Documentation
126
87
 
127
- const handleApplyFilter = async () => {
128
- const result = await consumeCredit();
129
-
130
- if (result.success) {
131
- // Track usage
132
- analytics.track('credit_consumed', {
133
- feature_id: 'filter_apply',
134
- amount: 3,
135
- transaction_id: result.transaction?.id,
136
- });
137
-
138
- // Apply filter
139
- await applyFilter();
140
- }
141
- };
142
-
143
- return <Button onPress={handleApplyFilter} title="Apply Filter (3 credits)" />;
144
- }
145
- ```
146
-
147
- ### With Loading State
148
-
149
- ```typescript
150
- function CreditFeatureWithLoading() {
151
- const { consumeCredit, isLoading, hasCredits } = useCreditsGate({
152
- creditCost: 5,
153
- featureId: 'premium_template',
154
- });
155
-
156
- const handleUse = async () => {
157
- if (!hasCredits) return;
158
-
159
- const result = await consumeCredit();
160
-
161
- if (result.success) {
162
- // Show loading while processing
163
- await processFeature();
164
- }
165
- };
166
-
167
- return (
168
- <View>
169
- <Button
170
- onPress={handleUse}
171
- disabled={isLoading || !hasCredits}
172
- title={isLoading ? 'Processing...' : 'Use Feature (5 credits)'}
173
- />
174
- </View>
175
- );
176
- }
177
- ```
178
-
179
- ## Examples
180
-
181
- ### Credit-Based Action Button
182
-
183
- ```typescript
184
- function CreditActionButton({ featureId, cost, action, label }) {
185
- const { hasCredits, credits, consumeCredit } = useCreditsGate({
186
- creditCost: cost,
187
- featureId,
188
- });
189
-
190
- const handlePress = async () => {
191
- if (!hasCredits) {
192
- showInsufficientCreditsDialog(cost, credits);
193
- return;
194
- }
195
-
196
- const result = await consumeCredit();
197
- if (result.success) {
198
- await action();
199
- }
200
- };
201
-
202
- return (
203
- <TouchableOpacity
204
- onPress={handlePress}
205
- disabled={!hasCredits}
206
- style={hasCredits ? styles.buttonEnabled : styles.buttonDisabled}
207
- >
208
- <Text style={styles.buttonText}>{label}</Text>
209
- <Text style={styles.costText}>{cost} credits</Text>
210
- </TouchableOpacity>
211
- );
212
- }
213
- ```
214
-
215
- ### Credit Balance Display
216
-
217
- ```typescript
218
- function CreditBalanceDisplay() {
219
- const { credits, isLoading } = useCreditsGate({
220
- creditCost: 1,
221
- featureId: 'any',
222
- });
223
-
224
- return (
225
- <View style={styles.balanceContainer}>
226
- <Text style={styles.balanceLabel}>Your Credits:</Text>
227
-
228
- {isLoading ? (
229
- <ActivityIndicator size="small" />
230
- ) : (
231
- <Text style={styles.balanceValue}>{credits}</Text>
232
- )}
233
- </View>
234
- );
235
- }
236
- ```
237
-
238
- ### Multiple Credit Tiers
239
-
240
- ```typescript
241
- function TieredFeatureAccess() {
242
- const { credits: basicCredits, hasCredits: hasBasic } = useCreditsGate({
243
- creditCost: 5,
244
- featureId: 'basic_feature',
245
- });
246
-
247
- const { credits: proCredits, hasCredits: hasPro } = useCreditsGate({
248
- creditCost: 20,
249
- featureId: 'pro_feature',
250
- });
251
-
252
- return (
253
- <View>
254
- <Button
255
- onPress={handleBasicFeature}
256
- disabled={!hasBasic}
257
- title={`Basic Feature (5 credits)`}
258
- />
259
-
260
- <Button
261
- onPress={handleProFeature}
262
- disabled={!hasPro}
263
- title={`Pro Feature (20 credits)`}
264
- />
265
-
266
- <Text>Balance: {basicCredits} credits</Text>
267
- </View>
268
- );
269
- }
270
- ```
271
-
272
- ## Result Type
273
-
274
- ```typescript
275
- interface CreditsResult {
276
- success: boolean;
277
- newBalance?: number;
278
- transaction?: {
279
- id: string;
280
- amount: number;
281
- reason: string;
282
- timestamp: string;
283
- };
284
- error?: Error;
285
- }
286
- ```
287
-
288
- ## Error Handling
289
-
290
- ```typescript
291
- function RobustCreditFeature() {
292
- const { consumeCredit } = useCreditsGate({
293
- creditCost: 10,
294
- featureId: 'robust_feature',
295
- });
296
-
297
- const handleAction = async () => {
298
- const result = await consumeCredit();
299
-
300
- if (!result.success) {
301
- if (result.error?.message.includes('Insufficient')) {
302
- Alert.alert('Insufficient Credits', 'Please purchase more credits');
303
- } else if (result.error?.message.includes('Network')) {
304
- Alert.alert('Network Error', 'Please check your connection');
305
- } else {
306
- Alert.alert('Error', 'Failed to process. Please try again');
307
- }
308
-
309
- // Log error
310
- analytics.track('credit_consumption_failed', {
311
- feature_id: 'robust_feature',
312
- error: result.error?.message,
313
- });
314
- return;
315
- }
316
-
317
- // Success
318
- await executeFeature();
319
- };
320
-
321
- return <Button onPress={handleAction} title="Execute (10 credits)" />;
322
- }
323
- ```
324
-
325
- ## Best Practices
326
-
327
- 1. **Always check `hasCredits`** before enabling actions
328
- 2. **Show credit cost** in UI
329
- 3. **Handle errors gracefully**
330
- 4. **Provide purchase prompt** when credits are insufficient
331
- 5. **Display current balance**
332
- 6. **Track credit consumption** in analytics
333
- 7. **Refetch balance** after consumption
334
-
335
- ## Related Hooks
336
-
337
- - **useCredits** - For credit balance only
338
- - **useDeductCredit** - For manual credit deduction
339
- - **usePremiumWithCredits** - For premium OR credits access
340
- - **useCreditChecker** - For simple credit checks
341
-
342
- ## See Also
343
-
344
- - [useCredits](./useCredits.md)
345
- - [useDeductCredit](./useDeductCredit.md)
346
- - [usePremiumWithCredits](./usePremiumWithCredits.md)
88
+ - **useCredits**: Access current credit balance
89
+ - **useDeductCredit**: Manual credit deduction with optimistic updates
90
+ - **useCreditChecker**: Simple credit validation
91
+ - **usePremiumWithCredits**: Hybrid premium/credits access
92
+ - **useFeatureGate**: Unified feature gating
93
+ - **Credits Repository**: `src/domains/wallet/infrastructure/repositories/README.md`
94
+ - **Wallet Domain**: `src/domains/wallet/README.md`
@@ -60,82 +60,6 @@ Hook for deducting credits from user balance with optimistic updates.
60
60
  - **NEVER** assume deduction succeeded without checking return value
61
61
  - **MUST** implement error boundaries when using this hook
62
62
 
63
- ## Rules
64
-
65
- ### Initialization
66
-
67
- ```typescript
68
- // CORRECT
69
- const { deductCredit, isDeducting } = useDeductCredit({
70
- userId: user?.uid,
71
- onCreditsExhausted: () => showPaywall(),
72
- });
73
-
74
- // INCORRECT - Missing callback
75
- const { deductCredit } = useDeductCredit({
76
- userId: user?.uid,
77
- });
78
-
79
- // INCORRECT - userId undefined
80
- const { deductCredit } = useDeductCredit({
81
- userId: undefined,
82
- });
83
- ```
84
-
85
- ### Deduction Execution
86
-
87
- ```typescript
88
- // CORRECT - Check return value
89
- const success = await deductCredit(5);
90
- if (success) {
91
- executeFeature();
92
- }
93
-
94
- // INCORRECT - No return value check
95
- await deductCredit(5);
96
- executeFeature(); // May execute even if deduction failed
97
-
98
- // INCORRECT - Multiple simultaneous calls
99
- Promise.all([
100
- deductCredit(5),
101
- deductCredit(3), // Race condition!
102
- ]);
103
- ```
104
-
105
- ### Loading States
106
-
107
- ```typescript
108
- // CORRECT - Respect loading state
109
- <Button onPress={handleDeduct} disabled={isDeducting}>
110
- {isDeducting ? 'Deducting...' : 'Use Feature'}
111
- </Button>
112
-
113
- // INCORRECT - Ignore loading state
114
- <Button onPress={handleDeduct}>
115
- Use Feature
116
- </Button>
117
- ```
118
-
119
- ### Credit Exhaustion Handling
120
-
121
- ```typescript
122
- // CORRECT - Implement callback
123
- const { deductCredit } = useDeductCredit({
124
- userId: user?.uid,
125
- onCreditsExhausted: () => {
126
- navigation.navigate('CreditPackages');
127
- },
128
- });
129
-
130
- // MINIMUM - Show alert
131
- const { deductCredit } = useDeductCredit({
132
- userId: user?.uid,
133
- onCreditsExhausted: () => {
134
- Alert.alert('No Credits', 'Please purchase more credits');
135
- },
136
- });
137
- ```
138
-
139
63
  ## AI Agent Guidelines
140
64
 
141
65
  ### When Implementing Features
@@ -9,7 +9,7 @@ import type { UserCredits } from "../../domain/entities/Credits";
9
9
  import { getCreditsRepository } from "../../infrastructure/repositories/CreditsRepositoryProvider";
10
10
  import { creditsQueryKeys } from "./useCredits";
11
11
 
12
- import { timezoneService } from "@umituz/react-native-timezone";
12
+ import { timezoneService } from "@umituz/react-native-design-system";
13
13
 
14
14
  export interface UseDeductCreditParams {
15
15
  userId: string | undefined;