@umituz/react-native-subscription 2.14.96 → 2.14.98

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 (77) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +462 -0
  3. package/package.json +3 -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/config/README.md +390 -0
  12. package/src/domains/paywall/README.md +371 -0
  13. package/src/domains/paywall/components/PaywallHeader.tsx +8 -11
  14. package/src/domains/paywall/components/README.md +185 -0
  15. package/src/domains/paywall/entities/README.md +199 -0
  16. package/src/domains/paywall/hooks/README.md +129 -0
  17. package/src/domains/wallet/README.md +292 -0
  18. package/src/domains/wallet/domain/README.md +108 -0
  19. package/src/domains/wallet/domain/entities/README.md +122 -0
  20. package/src/domains/wallet/domain/errors/README.md +157 -0
  21. package/src/domains/wallet/infrastructure/README.md +96 -0
  22. package/src/domains/wallet/presentation/components/BalanceCard.tsx +6 -12
  23. package/src/domains/wallet/presentation/components/README.md +231 -0
  24. package/src/domains/wallet/presentation/hooks/README.md +255 -0
  25. package/src/infrastructure/README.md +514 -0
  26. package/src/infrastructure/mappers/README.md +34 -0
  27. package/src/infrastructure/models/README.md +26 -0
  28. package/src/infrastructure/repositories/README.md +385 -0
  29. package/src/infrastructure/services/README.md +374 -0
  30. package/src/presentation/README.md +410 -0
  31. package/src/presentation/components/README.md +183 -0
  32. package/src/presentation/components/details/CreditRow.md +337 -0
  33. package/src/presentation/components/details/DetailRow.md +283 -0
  34. package/src/presentation/components/details/PremiumDetailsCard.md +266 -0
  35. package/src/presentation/components/details/PremiumStatusBadge.md +266 -0
  36. package/src/presentation/components/details/README.md +449 -0
  37. package/src/presentation/components/feedback/PaywallFeedbackModal.md +314 -0
  38. package/src/presentation/components/feedback/README.md +447 -0
  39. package/src/presentation/components/paywall/PaywallModal.md +444 -0
  40. package/src/presentation/components/paywall/README.md +190 -0
  41. package/src/presentation/components/sections/README.md +468 -0
  42. package/src/presentation/components/sections/SubscriptionSection.md +246 -0
  43. package/src/presentation/hooks/README.md +743 -0
  44. package/src/presentation/hooks/useAuthAwarePurchase.md +359 -0
  45. package/src/presentation/hooks/useAuthGate.md +403 -0
  46. package/src/presentation/hooks/useAuthSubscriptionSync.md +398 -0
  47. package/src/presentation/hooks/useCreditChecker.md +407 -0
  48. package/src/presentation/hooks/useCredits.md +342 -0
  49. package/src/presentation/hooks/useCreditsGate.md +346 -0
  50. package/src/presentation/hooks/useDeductCredit.md +160 -0
  51. package/src/presentation/hooks/useDevTestCallbacks.md +422 -0
  52. package/src/presentation/hooks/useFeatureGate.md +157 -0
  53. package/src/presentation/hooks/useInitializeCredits.md +458 -0
  54. package/src/presentation/hooks/usePaywall.md +334 -0
  55. package/src/presentation/hooks/usePaywallOperations.md +486 -0
  56. package/src/presentation/hooks/usePaywallVisibility.md +344 -0
  57. package/src/presentation/hooks/usePremium.md +230 -0
  58. package/src/presentation/hooks/usePremiumGate.md +423 -0
  59. package/src/presentation/hooks/usePremiumWithCredits.md +429 -0
  60. package/src/presentation/hooks/useSubscription.md +450 -0
  61. package/src/presentation/hooks/useSubscriptionDetails.md +438 -0
  62. package/src/presentation/hooks/useSubscriptionGate.md +168 -0
  63. package/src/presentation/hooks/useSubscriptionSettingsConfig.md +374 -0
  64. package/src/presentation/hooks/useSubscriptionStatus.md +424 -0
  65. package/src/presentation/hooks/useUserTier.md +356 -0
  66. package/src/presentation/hooks/useUserTierWithRepository.md +452 -0
  67. package/src/presentation/screens/README.md +194 -0
  68. package/src/presentation/types/README.md +38 -0
  69. package/src/presentation/utils/README.md +52 -0
  70. package/src/revenuecat/README.md +523 -0
  71. package/src/revenuecat/domain/README.md +147 -0
  72. package/src/revenuecat/domain/errors/README.md +197 -0
  73. package/src/revenuecat/infrastructure/config/README.md +40 -0
  74. package/src/revenuecat/infrastructure/managers/README.md +49 -0
  75. package/src/revenuecat/presentation/hooks/README.md +56 -0
  76. package/src/revenuecat/presentation/hooks/usePurchasePackage.ts +1 -1
  77. package/src/utils/README.md +529 -0
@@ -0,0 +1,429 @@
1
+ # usePremiumWithCredits Hook
2
+
3
+ Combined hook for premium subscription with credits system integration.
4
+
5
+ ## Import
6
+
7
+ ```typescript
8
+ import { usePremiumWithCredits } from '@umituz/react-native-subscription';
9
+ ```
10
+
11
+ ## Signature
12
+
13
+ ```typescript
14
+ function usePremiumWithCredits(params: {
15
+ userId: string | undefined;
16
+ isPremium: boolean;
17
+ }): {
18
+ credits: number;
19
+ balance: number;
20
+ transactions: Transaction[];
21
+ isLoading: boolean;
22
+ error: Error | null;
23
+ refetch: () => Promise<void>;
24
+ ensureCreditsInitialized: () => Promise<void>;
25
+ }
26
+ ```
27
+
28
+ ## Parameters
29
+
30
+ | Parameter | Type | Default | Description |
31
+ |-----------|------|---------|-------------|
32
+ | `userId` | `string \| undefined` | **Required** | User ID |
33
+ | `isPremium` | `boolean` | **Required** | Whether user has premium subscription |
34
+
35
+ ## Returns
36
+
37
+ Returns all properties from `useCredits` plus:
38
+
39
+ | Property | Type | Description |
40
+ |----------|------|-------------|
41
+ | `ensureCreditsInitialized` | `() => Promise<void>` | Ensure credits are initialized |
42
+
43
+ ## Basic Usage
44
+
45
+ ```typescript
46
+ function PremiumUserDashboard() {
47
+ const { user } = useAuth();
48
+ const { isPremium } = usePremium();
49
+
50
+ const { credits, isLoading, ensureCreditsInitialized } = usePremiumWithCredits({
51
+ userId: user?.uid,
52
+ isPremium,
53
+ });
54
+
55
+ useEffect(() => {
56
+ if (isPremium) {
57
+ ensureCreditsInitialized();
58
+ }
59
+ }, [isPremium]);
60
+
61
+ if (isLoading) return <ActivityIndicator />;
62
+
63
+ return (
64
+ <View>
65
+ <Text>Credits: {credits}</Text>
66
+ <Text>Status: {isPremium ? 'Premium' : 'Free'}</Text>
67
+ </View>
68
+ );
69
+ }
70
+ ```
71
+
72
+ ## Advanced Usage
73
+
74
+ ### With Auto-Initialization
75
+
76
+ ```typescript
77
+ function PremiumCreditsManager() {
78
+ const { user } = useAuth();
79
+ const { isPremium } = usePremium();
80
+
81
+ const {
82
+ credits,
83
+ transactions,
84
+ isLoading,
85
+ ensureCreditsInitialized,
86
+ } = usePremiumWithCredits({
87
+ userId: user?.uid,
88
+ isPremium,
89
+ });
90
+
91
+ // Hook automatically initializes credits when user becomes premium
92
+ useEffect(() => {
93
+ if (isPremium && !credits) {
94
+ console.log('User is premium but has no credits, initializing...');
95
+ ensureCreditsInitialized();
96
+ }
97
+ }, [isPremium, credits]);
98
+
99
+ if (isLoading) return <LoadingScreen />;
100
+
101
+ return (
102
+ <View>
103
+ <CreditBalance credits={credits} />
104
+ <TransactionHistory transactions={transactions} />
105
+ </View>
106
+ );
107
+ }
108
+ ```
109
+
110
+ ### With Subscription Change Detection
111
+
112
+ ```typescript
113
+ function SubscriptionWatcher() {
114
+ const { user } = useAuth();
115
+ const { isPremium } = usePremium();
116
+
117
+ const { credits, ensureCreditsInitialized } = usePremiumWithCredits({
118
+ userId: user?.uid,
119
+ isPremium,
120
+ });
121
+
122
+ const previousPremium = useRef(isPremium);
123
+
124
+ useEffect(() => {
125
+ // User just subscribed
126
+ if (isPremium && !previousPremium.current) {
127
+ console.log('User subscribed to premium!');
128
+ ensureCreditsInitialized();
129
+ }
130
+
131
+ previousPremium.current = isPremium;
132
+ }, [isPremium]);
133
+
134
+ return (
135
+ <View>
136
+ <Text>Status: {isPremium ? 'Premium' : 'Free'}</Text>
137
+ <Text>Credits: {credits || 0}</Text>
138
+ </View>
139
+ );
140
+ }
141
+ ```
142
+
143
+ ### With Manual Initialization
144
+
145
+ ```typescript
146
+ function ManualCreditInit() {
147
+ const { user } = useAuth();
148
+ const { isPremium } = usePremium();
149
+
150
+ const { credits, isLoading, ensureCreditsInitialized } = usePremiumWithCredits({
151
+ userId: user?.uid,
152
+ isPremium,
153
+ });
154
+
155
+ const handleInitializeCredits = async () => {
156
+ if (!isPremium) {
157
+ Alert.alert('Premium Required', 'This feature requires a subscription');
158
+ return;
159
+ }
160
+
161
+ if (credits) {
162
+ Alert.alert('Already Initialized', 'Credits are already set up');
163
+ return;
164
+ }
165
+
166
+ await ensureCreditsInitialized();
167
+ Alert.alert('Success', 'Credits initialized successfully');
168
+ };
169
+
170
+ return (
171
+ <View>
172
+ <Text>Credits: {credits || 'Not initialized'}</Text>
173
+
174
+ {!credits && isPremium && (
175
+ <Button
176
+ onPress={handleInitializeCredits}
177
+ disabled={isLoading}
178
+ title="Initialize Credits"
179
+ />
180
+ )}
181
+ </View>
182
+ );
183
+ }
184
+ ```
185
+
186
+ ### With Error Handling
187
+
188
+ ```typescript
189
+ function RobustCreditManager() {
190
+ const { user } = useAuth();
191
+ const { isPremium } = usePremium();
192
+
193
+ const {
194
+ credits,
195
+ error,
196
+ isLoading,
197
+ ensureCreditsInitialized,
198
+ } = usePremiumWithCredits({
199
+ userId: user?.uid,
200
+ isPremium,
201
+ });
202
+
203
+ useEffect(() => {
204
+ if (error) {
205
+ console.error('Credits error:', error);
206
+ Alert.alert('Error', 'Failed to load credits');
207
+ }
208
+ }, [error]);
209
+
210
+ const handleRetry = async () => {
211
+ try {
212
+ await ensureCreditsInitialized();
213
+ } catch (err) {
214
+ Alert.alert('Error', 'Failed to initialize credits');
215
+ }
216
+ };
217
+
218
+ if (isLoading) return <LoadingScreen />;
219
+
220
+ return (
221
+ <View>
222
+ <Text>Credits: {credits || 0}</Text>
223
+
224
+ {error && (
225
+ <Button onPress={handleRetry} title="Retry" />
226
+ )}
227
+ </View>
228
+ );
229
+ }
230
+ ```
231
+
232
+ ## Examples
233
+
234
+ ### Premium Onboarding Flow
235
+
236
+ ```typescript
237
+ function PremiumOnboarding() {
238
+ const { user } = useAuth();
239
+ const { isPremium } = usePremium();
240
+
241
+ const {
242
+ credits,
243
+ isLoading,
244
+ ensureCreditsInitialized,
245
+ } = usePremiumWithCredits({
246
+ userId: user?.uid,
247
+ isPremium,
248
+ });
249
+
250
+ useEffect(() => {
251
+ // Auto-initialize credits for new premium users
252
+ if (isPremium && !credits && !isLoading) {
253
+ const initialize = async () => {
254
+ await ensureCreditsInitialized();
255
+ analytics.track('premium_credits_initialized', {
256
+ userId: user?.uid,
257
+ });
258
+ };
259
+ initialize();
260
+ }
261
+ }, [isPremium, credits, isLoading]);
262
+
263
+ if (!isPremium) {
264
+ return <PremiumUpgradePrompt />;
265
+ }
266
+
267
+ if (isLoading) {
268
+ return <LoadingScreen message="Setting up your account..." />;
269
+ }
270
+
271
+ return (
272
+ <View>
273
+ <CongratulationsMessage />
274
+
275
+ <CreditCard credits={credits} />
276
+
277
+ <Button
278
+ onPress={() => navigation.navigate('Home')}
279
+ title="Get Started"
280
+ />
281
+ </View>
282
+ );
283
+ }
284
+ ```
285
+
286
+ ### Premium Benefits Display
287
+
288
+ ```typescript
289
+ function PremiumBenefits() {
290
+ const { user } = useAuth();
291
+ const { isPremium } = usePremium();
292
+
293
+ const { credits, balance, transactions } = usePremiumWithCredits({
294
+ userId: user?.uid,
295
+ isPremium,
296
+ });
297
+
298
+ return (
299
+ <ScrollView>
300
+ <PremiumBadge />
301
+
302
+ <View style={styles.section}>
303
+ <Text style={styles.title}>Your Premium Benefits</Text>
304
+ <BenefitItem icon="✓" text="Ad-free experience" />
305
+ <BenefitItem icon="✓" text="Unlimited access" />
306
+ <BenefitItem icon="✓" text={`${credits} monthly credits`} />
307
+ <BenefitItem icon="✓" text="Priority support" />
308
+ </View>
309
+
310
+ <View style={styles.section}>
311
+ <Text style={styles.title}>Credit Balance</Text>
312
+ <Text style={styles.balance}>{credits} Credits</Text>
313
+ <Text style={styles.value}>Worth ~${balance.toFixed(2)}</Text>
314
+ </View>
315
+
316
+ <View style={styles.section}>
317
+ <Text style={styles.title}>Recent Activity</Text>
318
+ {transactions.slice(0, 5).map((tx) => (
319
+ <TransactionItem key={tx.id} transaction={tx} />
320
+ ))}
321
+ </View>
322
+ </ScrollView>
323
+ );
324
+ }
325
+ ```
326
+
327
+ ### Subscription Status Monitor
328
+
329
+ ```typescript
330
+ function SubscriptionMonitor() {
331
+ const { user } = useAuth();
332
+ const { isPremium } = usePremium();
333
+
334
+ const {
335
+ credits,
336
+ isLoading,
337
+ ensureCreditsInitialized,
338
+ } = usePremiumWithCredits({
339
+ userId: user?.uid,
340
+ isPremium,
341
+ });
342
+
343
+ const [lastChecked, setLastChecked] = useState<Date | null>(null);
344
+
345
+ const handleRefresh = async () => {
346
+ await ensureCreditsInitialized();
347
+ setLastChecked(new Date());
348
+ };
349
+
350
+ useEffect(() => {
351
+ // Periodic refresh every 5 minutes
352
+ const interval = setInterval(() => {
353
+ if (isPremium) {
354
+ handleRefresh();
355
+ }
356
+ }, 5 * 60 * 1000);
357
+
358
+ return () => clearInterval(interval);
359
+ }, [isPremium]);
360
+
361
+ return (
362
+ <View>
363
+ <Text>Subscription Status: {isPremium ? 'Active' : 'Inactive'}</Text>
364
+ <Text>Credits: {credits || 0}</Text>
365
+ {lastChecked && (
366
+ <Text>Last checked: {lastChecked.toLocaleTimeString()}</Text>
367
+ )}
368
+
369
+ <Button
370
+ onPress={handleRefresh}
371
+ disabled={isLoading}
372
+ title="Refresh Status"
373
+ />
374
+ </View>
375
+ );
376
+ }
377
+ ```
378
+
379
+ ## How It Works
380
+
381
+ ### Automatic Initialization
382
+
383
+ The hook automatically:
384
+
385
+ 1. **Detects premium status** - Checks if user is premium
386
+ 2. **Monitors credits** - Watches credits value
387
+ 3. **Initializes when needed** - Calls init if premium but no credits
388
+ 4. **Prevents duplicate inits** - Won't initialize if credits exist
389
+ 5. **Handles loading** - Shows loading state during initialization
390
+
391
+ ```typescript
392
+ // Premium user without credits
393
+ isPremium = true
394
+ credits = undefined
395
+ → Auto-initializes credits ✅
396
+
397
+ // Premium user with credits
398
+ isPremium = true
399
+ credits = 100
400
+ → No initialization needed ✅
401
+
402
+ // Free user
403
+ isPremium = false
404
+ credits = undefined
405
+ → No initialization (not premium) ✅
406
+ ```
407
+
408
+ ## Best Practices
409
+
410
+ 1. **Trust the hook** - Let it handle auto-initialization
411
+ 2. **Monitor loading** - Show loading during initialization
412
+ 3. **Handle errors** - Catch and display init failures
413
+ 4. **Track events** - Log credit initialization
414
+ 5. **Refresh periodically** - Keep credits up to date
415
+ 6. **Check premium first** - Verify user is premium before showing features
416
+ 7. **Test scenarios** - Test new subscription, existing subscription, cancellation
417
+
418
+ ## Related Hooks
419
+
420
+ - **useCredits** - Credits management
421
+ - **useInitializeCredits** - Manual credit initialization
422
+ - **usePremium** - Premium status
423
+ - **useDeductCredit** - Credit deduction
424
+
425
+ ## See Also
426
+
427
+ - [Credits System](../../../domains/wallet/README.md)
428
+ - [Premium Integration](../../../docs/PREMIUM_INTEGRATION.md)
429
+ - [Credits README](./useCredits.md)