@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.
- package/LICENSE +21 -0
- package/README.md +461 -0
- package/package.json +1 -3
- package/src/application/README.md +229 -0
- package/src/application/ports/README.md +103 -0
- package/src/domain/README.md +402 -0
- package/src/domain/constants/README.md +80 -0
- package/src/domain/entities/README.md +176 -0
- package/src/domain/errors/README.md +307 -0
- package/src/domain/value-objects/README.md +186 -0
- package/src/domains/README.md +240 -0
- package/src/domains/config/README.md +390 -0
- package/src/domains/config/domain/README.md +390 -0
- package/src/domains/config/domain/entities/README.md +350 -0
- package/src/domains/paywall/README.md +371 -0
- package/src/domains/paywall/components/PaywallHeader.tsx +8 -11
- package/src/domains/paywall/components/README.md +185 -0
- package/src/domains/paywall/entities/README.md +199 -0
- package/src/domains/paywall/hooks/README.md +129 -0
- package/src/domains/wallet/README.md +292 -0
- package/src/domains/wallet/domain/README.md +108 -0
- package/src/domains/wallet/domain/entities/README.md +122 -0
- package/src/domains/wallet/domain/errors/README.md +157 -0
- package/src/domains/wallet/infrastructure/README.md +96 -0
- package/src/domains/wallet/presentation/components/BalanceCard.tsx +6 -12
- package/src/domains/wallet/presentation/components/README.md +231 -0
- package/src/domains/wallet/presentation/hooks/README.md +255 -0
- package/src/infrastructure/README.md +514 -0
- package/src/infrastructure/mappers/README.md +34 -0
- package/src/infrastructure/models/README.md +26 -0
- package/src/infrastructure/repositories/README.md +385 -0
- package/src/infrastructure/services/README.md +374 -0
- package/src/presentation/README.md +410 -0
- package/src/presentation/components/README.md +183 -0
- package/src/presentation/components/details/CreditRow.md +337 -0
- package/src/presentation/components/details/DetailRow.md +283 -0
- package/src/presentation/components/details/PremiumDetailsCard.md +266 -0
- package/src/presentation/components/details/PremiumStatusBadge.md +266 -0
- package/src/presentation/components/details/README.md +449 -0
- package/src/presentation/components/feedback/PaywallFeedbackModal.md +314 -0
- package/src/presentation/components/feedback/README.md +447 -0
- package/src/presentation/components/paywall/PaywallModal.md +444 -0
- package/src/presentation/components/paywall/README.md +190 -0
- package/src/presentation/components/sections/README.md +468 -0
- package/src/presentation/components/sections/SubscriptionSection.md +246 -0
- package/src/presentation/hooks/README.md +743 -0
- package/src/presentation/hooks/useAuthAwarePurchase.md +359 -0
- package/src/presentation/hooks/useAuthGate.md +403 -0
- package/src/presentation/hooks/useAuthSubscriptionSync.md +398 -0
- package/src/presentation/hooks/useCreditChecker.md +407 -0
- package/src/presentation/hooks/useCredits.md +342 -0
- package/src/presentation/hooks/useCreditsGate.md +346 -0
- package/src/presentation/hooks/useDeductCredit.md +176 -0
- package/src/presentation/hooks/useDevTestCallbacks.md +422 -0
- package/src/presentation/hooks/useFeatureGate.md +157 -0
- package/src/presentation/hooks/useInitializeCredits.md +458 -0
- package/src/presentation/hooks/usePaywall.md +334 -0
- package/src/presentation/hooks/usePaywallOperations.md +486 -0
- package/src/presentation/hooks/usePaywallVisibility.md +344 -0
- package/src/presentation/hooks/usePremium.md +230 -0
- package/src/presentation/hooks/usePremiumGate.md +423 -0
- package/src/presentation/hooks/usePremiumWithCredits.md +429 -0
- package/src/presentation/hooks/useSubscription.md +450 -0
- package/src/presentation/hooks/useSubscriptionDetails.md +438 -0
- package/src/presentation/hooks/useSubscriptionGate.md +168 -0
- package/src/presentation/hooks/useSubscriptionSettingsConfig.md +374 -0
- package/src/presentation/hooks/useSubscriptionStatus.md +424 -0
- package/src/presentation/hooks/useUserTier.md +356 -0
- package/src/presentation/hooks/useUserTierWithRepository.md +452 -0
- package/src/presentation/screens/README.md +194 -0
- package/src/presentation/types/README.md +38 -0
- package/src/presentation/utils/README.md +52 -0
- package/src/revenuecat/README.md +523 -0
- package/src/revenuecat/application/README.md +158 -0
- package/src/revenuecat/application/ports/README.md +169 -0
- package/src/revenuecat/domain/README.md +147 -0
- package/src/revenuecat/domain/constants/README.md +183 -0
- package/src/revenuecat/domain/entities/README.md +382 -0
- package/src/revenuecat/domain/errors/README.md +197 -0
- package/src/revenuecat/domain/types/README.md +373 -0
- package/src/revenuecat/domain/value-objects/README.md +441 -0
- package/src/revenuecat/infrastructure/README.md +50 -0
- package/src/revenuecat/infrastructure/config/README.md +40 -0
- package/src/revenuecat/infrastructure/handlers/README.md +218 -0
- package/src/revenuecat/infrastructure/managers/README.md +49 -0
- package/src/revenuecat/infrastructure/services/README.md +325 -0
- package/src/revenuecat/infrastructure/utils/README.md +382 -0
- package/src/revenuecat/presentation/README.md +184 -0
- package/src/revenuecat/presentation/hooks/README.md +56 -0
- package/src/utils/README.md +529 -0
|
@@ -0,0 +1,743 @@
|
|
|
1
|
+
# Subscription Hooks
|
|
2
|
+
|
|
3
|
+
Abonelik, premium ve kredi yönetimi için React Hooks koleksiyonu.
|
|
4
|
+
|
|
5
|
+
## İçindekiler
|
|
6
|
+
|
|
7
|
+
- [Subscription Hooks](#subscription-hooks)
|
|
8
|
+
- [Premium Hooks](#premium-hooks)
|
|
9
|
+
- [Credits Hooks](#credits-hooks)
|
|
10
|
+
- [Gate Hooks](#gate-hooks)
|
|
11
|
+
- [Auth Hooks](#auth-hooks)
|
|
12
|
+
- [Paywall Hooks](#paywall-hooks)
|
|
13
|
+
|
|
14
|
+
## Subscription Hooks
|
|
15
|
+
|
|
16
|
+
### useSubscription
|
|
17
|
+
|
|
18
|
+
Kullanıcının abonelik durumunu yönetmek için:
|
|
19
|
+
|
|
20
|
+
```typescript
|
|
21
|
+
import { useSubscription } from '@umituz/react-native-subscription';
|
|
22
|
+
|
|
23
|
+
function MyComponent() {
|
|
24
|
+
const {
|
|
25
|
+
isSubscribed,
|
|
26
|
+
isActive,
|
|
27
|
+
subscription,
|
|
28
|
+
isLoading,
|
|
29
|
+
error,
|
|
30
|
+
checkSubscription,
|
|
31
|
+
} = useSubscription();
|
|
32
|
+
|
|
33
|
+
if (isLoading) return <ActivityIndicator />;
|
|
34
|
+
|
|
35
|
+
return (
|
|
36
|
+
<View>
|
|
37
|
+
<Text>Status: {isSubscribed ? 'Premium' : 'Free'}</Text>
|
|
38
|
+
{subscription && (
|
|
39
|
+
<Text>
|
|
40
|
+
Expires: {new Date(subscription.expirationDate).toLocaleDateString()}
|
|
41
|
+
</Text>
|
|
42
|
+
)}
|
|
43
|
+
</View>
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### useSubscriptionStatus
|
|
49
|
+
|
|
50
|
+
Detaylı abonelik durumu bilgileri için:
|
|
51
|
+
|
|
52
|
+
```typescript
|
|
53
|
+
import { useSubscriptionStatus } from '@umituz/react-native-subscription';
|
|
54
|
+
|
|
55
|
+
function SubscriptionBadge() {
|
|
56
|
+
const {
|
|
57
|
+
status,
|
|
58
|
+
tier,
|
|
59
|
+
isActive,
|
|
60
|
+
willRenew,
|
|
61
|
+
expirationDate,
|
|
62
|
+
isLoading,
|
|
63
|
+
} = useSubscriptionStatus();
|
|
64
|
+
|
|
65
|
+
if (isLoading) return null;
|
|
66
|
+
|
|
67
|
+
return (
|
|
68
|
+
<View>
|
|
69
|
+
<Badge
|
|
70
|
+
color={isActive ? 'green' : 'gray'}
|
|
71
|
+
>
|
|
72
|
+
{tier.toUpperCase()}
|
|
73
|
+
</Badge>
|
|
74
|
+
{willRenew && <Text>Auto-renewal on</Text>}
|
|
75
|
+
{expirationDate && (
|
|
76
|
+
<Text>
|
|
77
|
+
Expires: {new Date(expirationDate).toLocaleDateString()}
|
|
78
|
+
</Text>
|
|
79
|
+
)}
|
|
80
|
+
</View>
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### useSubscriptionDetails
|
|
86
|
+
|
|
87
|
+
Abonelik detaylarını görüntülemek için:
|
|
88
|
+
|
|
89
|
+
```typescript
|
|
90
|
+
import { useSubscriptionDetails } from '@umituz/react-native-subscription';
|
|
91
|
+
|
|
92
|
+
function SubscriptionDetails() {
|
|
93
|
+
const {
|
|
94
|
+
subscription,
|
|
95
|
+
package,
|
|
96
|
+
period,
|
|
97
|
+
price,
|
|
98
|
+
features,
|
|
99
|
+
isLoading,
|
|
100
|
+
refetch,
|
|
101
|
+
} = useSubscriptionDetails();
|
|
102
|
+
|
|
103
|
+
if (isLoading) return <ActivityIndicator />;
|
|
104
|
+
|
|
105
|
+
return (
|
|
106
|
+
<Card>
|
|
107
|
+
<Text>{package?.title}</Text>
|
|
108
|
+
<Text>{price} / {period}</Text>
|
|
109
|
+
<Text>Features:</Text>
|
|
110
|
+
{features?.map((feature) => (
|
|
111
|
+
<Text key={feature}>• {feature}</Text>
|
|
112
|
+
))}
|
|
113
|
+
<Button onPress={refetch} title="Refresh" />
|
|
114
|
+
</Card>
|
|
115
|
+
);
|
|
116
|
+
}
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## Premium Hooks
|
|
120
|
+
|
|
121
|
+
### usePremium
|
|
122
|
+
|
|
123
|
+
Premium durumunu kontrol etmek için:
|
|
124
|
+
|
|
125
|
+
```typescript
|
|
126
|
+
import { usePremium } from '@umituz/react-native-subscription';
|
|
127
|
+
|
|
128
|
+
function PremiumFeature() {
|
|
129
|
+
const { isPremium, isLoading } = usePremium();
|
|
130
|
+
|
|
131
|
+
if (isLoading) return <ActivityIndicator />;
|
|
132
|
+
|
|
133
|
+
if (!isPremium) {
|
|
134
|
+
return <UpgradePrompt />;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
return <PremiumContent />;
|
|
138
|
+
}
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### usePremiumGate
|
|
142
|
+
|
|
143
|
+
Premium özelliklere erişimi kontrol etmek için:
|
|
144
|
+
|
|
145
|
+
```typescript
|
|
146
|
+
import { usePremiumGate } from '@umituz/react-native-subscription';
|
|
147
|
+
|
|
148
|
+
function ProtectedFeature() {
|
|
149
|
+
const { isPremium, showPaywall, canAccess } = usePremiumGate({
|
|
150
|
+
featureId: 'advanced_analytics',
|
|
151
|
+
onUpgradeRequired: showPaywall,
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
const handleAction = () => {
|
|
155
|
+
if (!canAccess) {
|
|
156
|
+
showPaywall();
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
// Premium feature logic
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
return (
|
|
163
|
+
<Button onPress={handleAction} title="Run Analytics" />
|
|
164
|
+
);
|
|
165
|
+
}
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### usePremiumWithCredits
|
|
169
|
+
|
|
170
|
+
Premium veya kredi ile kullanılabilen özellikler için:
|
|
171
|
+
|
|
172
|
+
```typescript
|
|
173
|
+
import { usePremiumWithCredits } from '@umituz/react-native-subscription';
|
|
174
|
+
|
|
175
|
+
function HybridFeature() {
|
|
176
|
+
const {
|
|
177
|
+
isPremium,
|
|
178
|
+
hasCredits,
|
|
179
|
+
credits,
|
|
180
|
+
consumeCredit,
|
|
181
|
+
isLoading,
|
|
182
|
+
} = usePremiumWithCredits({
|
|
183
|
+
creditCost: 1,
|
|
184
|
+
featureId: 'ai_generation',
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
const handleGenerate = async () => {
|
|
188
|
+
if (isPremium) {
|
|
189
|
+
// Premium users have unlimited access
|
|
190
|
+
await generateContent();
|
|
191
|
+
} else if (hasCredits) {
|
|
192
|
+
// Use credits
|
|
193
|
+
const result = await consumeCredit();
|
|
194
|
+
if (result.success) {
|
|
195
|
+
await generateContent();
|
|
196
|
+
}
|
|
197
|
+
} else {
|
|
198
|
+
// Show upgrade prompt
|
|
199
|
+
showPaywall();
|
|
200
|
+
}
|
|
201
|
+
};
|
|
202
|
+
|
|
203
|
+
return (
|
|
204
|
+
<View>
|
|
205
|
+
<Button onPress={handleGenerate} title="Generate" />
|
|
206
|
+
{!isPremium && <Text>Credits: {credits}</Text>}
|
|
207
|
+
</View>
|
|
208
|
+
);
|
|
209
|
+
}
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
## Credits Hooks
|
|
213
|
+
|
|
214
|
+
### useCredits
|
|
215
|
+
|
|
216
|
+
Kredi bakiyesi yönetimi için:
|
|
217
|
+
|
|
218
|
+
```typescript
|
|
219
|
+
import { useCredits } from '@umituz/react-native-subscription';
|
|
220
|
+
|
|
221
|
+
function CreditsDisplay() {
|
|
222
|
+
const {
|
|
223
|
+
credits,
|
|
224
|
+
balance,
|
|
225
|
+
isLoading,
|
|
226
|
+
refetch,
|
|
227
|
+
} = useCredits();
|
|
228
|
+
|
|
229
|
+
return (
|
|
230
|
+
<View>
|
|
231
|
+
<Text>Credits: {credits}</Text>
|
|
232
|
+
<Text>Balance: ${balance}</Text>
|
|
233
|
+
<Button onPress={refetch} title="Refresh" />
|
|
234
|
+
</View>
|
|
235
|
+
);
|
|
236
|
+
}
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
### useCreditsGate
|
|
240
|
+
|
|
241
|
+
Kredi gerektiren özellikler için:
|
|
242
|
+
|
|
243
|
+
```typescript
|
|
244
|
+
import { useCreditsGate } from '@umituz/react-native-subscription';
|
|
245
|
+
|
|
246
|
+
function CreditBasedFeature() {
|
|
247
|
+
const {
|
|
248
|
+
hasCredits,
|
|
249
|
+
credits,
|
|
250
|
+
consumeCredit,
|
|
251
|
+
isLoading,
|
|
252
|
+
showPurchasePrompt,
|
|
253
|
+
} = useCreditsGate({
|
|
254
|
+
creditCost: 5,
|
|
255
|
+
featureId: 'export',
|
|
256
|
+
});
|
|
257
|
+
|
|
258
|
+
const handleExport = async () => {
|
|
259
|
+
if (!hasCredits) {
|
|
260
|
+
showPurchasePrompt();
|
|
261
|
+
return;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
const result = await consumeCredit();
|
|
265
|
+
if (result.success) {
|
|
266
|
+
await exportData();
|
|
267
|
+
}
|
|
268
|
+
};
|
|
269
|
+
|
|
270
|
+
return (
|
|
271
|
+
<Button onPress={handleExport} title="Export (5 credits)" />
|
|
272
|
+
);
|
|
273
|
+
}
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
### useDeductCredit
|
|
277
|
+
|
|
278
|
+
Kredi düşme işlemi için:
|
|
279
|
+
|
|
280
|
+
```typescript
|
|
281
|
+
import { useDeductCredit } from '@umituz/react-native-subscription';
|
|
282
|
+
|
|
283
|
+
function PaidAction() {
|
|
284
|
+
const { deductCredit, isLoading } = useDeductCredit();
|
|
285
|
+
|
|
286
|
+
const handleAction = async () => {
|
|
287
|
+
const result = await deductCredit({
|
|
288
|
+
amount: 10,
|
|
289
|
+
reason: 'feature_usage',
|
|
290
|
+
metadata: { featureId: 'ai_analysis' },
|
|
291
|
+
});
|
|
292
|
+
|
|
293
|
+
if (result.success) {
|
|
294
|
+
console.log('Credit deducted successfully');
|
|
295
|
+
// Continue with action
|
|
296
|
+
} else {
|
|
297
|
+
Alert.alert('Error', result.error?.message);
|
|
298
|
+
}
|
|
299
|
+
};
|
|
300
|
+
|
|
301
|
+
return <Button onPress={handleAction} title="Use Feature (10 credits)" />;
|
|
302
|
+
}
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
### useInitializeCredits
|
|
306
|
+
|
|
307
|
+
Kredi sistemini başlatmak için:
|
|
308
|
+
|
|
309
|
+
```typescript
|
|
310
|
+
import { useInitializeCredits } from '@umituz/react-native-subscription';
|
|
311
|
+
|
|
312
|
+
function App() {
|
|
313
|
+
const { isInitialized, initialize, error } = useInitializeCredits();
|
|
314
|
+
|
|
315
|
+
useEffect(() => {
|
|
316
|
+
if (!isInitialized) {
|
|
317
|
+
initialize({
|
|
318
|
+
initialCredits: 100,
|
|
319
|
+
creditPackages: [
|
|
320
|
+
{ id: 'small', amount: 100, price: 0.99 },
|
|
321
|
+
{ id: 'medium', amount: 500, price: 3.99 },
|
|
322
|
+
],
|
|
323
|
+
});
|
|
324
|
+
}
|
|
325
|
+
}, []);
|
|
326
|
+
|
|
327
|
+
if (error) {
|
|
328
|
+
return <ErrorScreen error={error} />;
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
return <AppContent />;
|
|
332
|
+
}
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
## Gate Hooks
|
|
336
|
+
|
|
337
|
+
### useFeatureGate
|
|
338
|
+
|
|
339
|
+
Genel özellik erişim kontrolü için:
|
|
340
|
+
|
|
341
|
+
```typescript
|
|
342
|
+
import { useFeatureGate } from '@umituz/react-native-subscription';
|
|
343
|
+
|
|
344
|
+
function GatedFeature() {
|
|
345
|
+
const { canAccess, gateState, showUpgradePrompt } = useFeatureGate({
|
|
346
|
+
featureId: 'advanced_filters',
|
|
347
|
+
requirements: {
|
|
348
|
+
tier: 'premium',
|
|
349
|
+
minCredits: 0,
|
|
350
|
+
},
|
|
351
|
+
});
|
|
352
|
+
|
|
353
|
+
if (!canAccess) {
|
|
354
|
+
return (
|
|
355
|
+
<View>
|
|
356
|
+
<Text>This feature requires Premium</Text>
|
|
357
|
+
<Button onPress={showUpgradePrompt} title="Upgrade" />
|
|
358
|
+
</View>
|
|
359
|
+
);
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
return <FeatureContent />;
|
|
363
|
+
}
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
### useSubscriptionGate
|
|
367
|
+
|
|
368
|
+
Abonelik kontrolü için:
|
|
369
|
+
|
|
370
|
+
```typescript
|
|
371
|
+
import { useSubscriptionGate } from '@umituz/react-native-subscription';
|
|
372
|
+
|
|
373
|
+
function SubscriptionOnlyFeature() {
|
|
374
|
+
const {
|
|
375
|
+
isSubscribed,
|
|
376
|
+
subscriptionType,
|
|
377
|
+
canAccess,
|
|
378
|
+
showPaywall,
|
|
379
|
+
} = useSubscriptionGate({
|
|
380
|
+
requiredTier: 'premium',
|
|
381
|
+
});
|
|
382
|
+
|
|
383
|
+
if (!canAccess) {
|
|
384
|
+
return (
|
|
385
|
+
<LockedScreen
|
|
386
|
+
onUpgrade={showPaywall}
|
|
387
|
+
message="Upgrade to Premium to access this feature"
|
|
388
|
+
/>
|
|
389
|
+
);
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
return <FeatureContent />;
|
|
393
|
+
}
|
|
394
|
+
```
|
|
395
|
+
|
|
396
|
+
### useAuthGate
|
|
397
|
+
|
|
398
|
+
Auth + abonelik kontrolü için:
|
|
399
|
+
|
|
400
|
+
```typescript
|
|
401
|
+
import { useAuthGate } from '@umituz/react-native-subscription';
|
|
402
|
+
|
|
403
|
+
function ProtectedContent() {
|
|
404
|
+
const {
|
|
405
|
+
isAuthenticated,
|
|
406
|
+
isAuthorized,
|
|
407
|
+
user,
|
|
408
|
+
signIn,
|
|
409
|
+
signOut,
|
|
410
|
+
} = useAuthGate({
|
|
411
|
+
requireAuth: true,
|
|
412
|
+
requireSubscription: true,
|
|
413
|
+
});
|
|
414
|
+
|
|
415
|
+
if (!isAuthenticated) {
|
|
416
|
+
return <SignInPrompt onSignIn={signIn} />;
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
if (!isAuthorized) {
|
|
420
|
+
return <UpgradePrompt />;
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
return <ProtectedData />;
|
|
424
|
+
}
|
|
425
|
+
```
|
|
426
|
+
|
|
427
|
+
## Auth Hooks
|
|
428
|
+
|
|
429
|
+
### useAuthAwarePurchase
|
|
430
|
+
|
|
431
|
+
Auth-aware satın alma için:
|
|
432
|
+
|
|
433
|
+
```typescript
|
|
434
|
+
import { useAuthAwarePurchase } from '@umituz/react-native-subscription';
|
|
435
|
+
|
|
436
|
+
function PurchaseButton() {
|
|
437
|
+
const { purchase, isLoading, requiresAuth } = useAuthAwarePurchase({
|
|
438
|
+
productId: 'premium_monthly',
|
|
439
|
+
});
|
|
440
|
+
|
|
441
|
+
const handlePurchase = async () => {
|
|
442
|
+
const result = await purchase();
|
|
443
|
+
|
|
444
|
+
if (result.requiresAuth) {
|
|
445
|
+
// Show auth screen
|
|
446
|
+
navigateToAuth();
|
|
447
|
+
} else if (result.success) {
|
|
448
|
+
// Purchase successful
|
|
449
|
+
Alert.alert('Success', 'You are now Premium!');
|
|
450
|
+
}
|
|
451
|
+
};
|
|
452
|
+
|
|
453
|
+
return (
|
|
454
|
+
<Button
|
|
455
|
+
onPress={handlePurchase}
|
|
456
|
+
disabled={isLoading}
|
|
457
|
+
title="Subscribe"
|
|
458
|
+
/>
|
|
459
|
+
);
|
|
460
|
+
}
|
|
461
|
+
```
|
|
462
|
+
|
|
463
|
+
### useAuthSubscriptionSync
|
|
464
|
+
|
|
465
|
+
Auth ve abonelik senkronizasyonu için:
|
|
466
|
+
|
|
467
|
+
```typescript
|
|
468
|
+
import { useAuthSubscriptionSync } from '@umituz/react-native-subscription';
|
|
469
|
+
|
|
470
|
+
function AuthManager() {
|
|
471
|
+
const { user } = useAuth();
|
|
472
|
+
const { syncSubscription, clearSubscription } = useAuthSubscriptionSync();
|
|
473
|
+
|
|
474
|
+
useEffect(() => {
|
|
475
|
+
if (user) {
|
|
476
|
+
// Sync subscription with auth user
|
|
477
|
+
syncSubscription(user.uid);
|
|
478
|
+
} else {
|
|
479
|
+
// Clear subscription on logout
|
|
480
|
+
clearSubscription();
|
|
481
|
+
}
|
|
482
|
+
}, [user?.uid]);
|
|
483
|
+
|
|
484
|
+
return null;
|
|
485
|
+
}
|
|
486
|
+
```
|
|
487
|
+
|
|
488
|
+
## Paywall Hooks
|
|
489
|
+
|
|
490
|
+
### usePaywallOperations
|
|
491
|
+
|
|
492
|
+
Paywall işlemleri için:
|
|
493
|
+
|
|
494
|
+
```typescript
|
|
495
|
+
import { usePaywallOperations } from '@umituz/react-native-subscription';
|
|
496
|
+
|
|
497
|
+
function PaywallManager() {
|
|
498
|
+
const {
|
|
499
|
+
showPaywall,
|
|
500
|
+
hidePaywall,
|
|
501
|
+
isPaywallVisible,
|
|
502
|
+
paywallState,
|
|
503
|
+
} = usePaywallOperations();
|
|
504
|
+
|
|
505
|
+
const handleUpgradeClick = () => {
|
|
506
|
+
showPaywall({
|
|
507
|
+
trigger: 'upgrade_button',
|
|
508
|
+
featureId: 'advanced_features',
|
|
509
|
+
});
|
|
510
|
+
};
|
|
511
|
+
|
|
512
|
+
return (
|
|
513
|
+
<>
|
|
514
|
+
<Button onPress={handleUpgradeClick} title="Upgrade" />
|
|
515
|
+
<Paywall isVisible={isPaywallVisible} onClose={hidePaywall} />
|
|
516
|
+
</>
|
|
517
|
+
);
|
|
518
|
+
}
|
|
519
|
+
```
|
|
520
|
+
|
|
521
|
+
### usePaywallVisibility
|
|
522
|
+
|
|
523
|
+
Paywall görünürlük kontrolü için:
|
|
524
|
+
|
|
525
|
+
```typescript
|
|
526
|
+
import { usePaywallVisibility } from '@umituz/react-native-subscription';
|
|
527
|
+
|
|
528
|
+
function AutoPaywall() {
|
|
529
|
+
const {
|
|
530
|
+
shouldShowPaywall,
|
|
531
|
+
showPaywall,
|
|
532
|
+
dismissPaywall,
|
|
533
|
+
hasSeenPaywall,
|
|
534
|
+
} = usePaywallVisibility({
|
|
535
|
+
trigger: 'feature_usage_limit',
|
|
536
|
+
showAfter: 3, // Show after 3 actions
|
|
537
|
+
frequency: 'once_per_session',
|
|
538
|
+
});
|
|
539
|
+
|
|
540
|
+
useEffect(() => {
|
|
541
|
+
if (shouldShowPaywall) {
|
|
542
|
+
showPaywall();
|
|
543
|
+
}
|
|
544
|
+
}, [shouldShowPaywall]);
|
|
545
|
+
|
|
546
|
+
return <FeatureContent />;
|
|
547
|
+
}
|
|
548
|
+
```
|
|
549
|
+
|
|
550
|
+
### useUserTier
|
|
551
|
+
|
|
552
|
+
Kullanıcı tier yönetimi için:
|
|
553
|
+
|
|
554
|
+
```typescript
|
|
555
|
+
import { useUserTier } from '@umituz/react-native-subscription';
|
|
556
|
+
|
|
557
|
+
function TierAwareComponent() {
|
|
558
|
+
const {
|
|
559
|
+
tier,
|
|
560
|
+
isGuest,
|
|
561
|
+
isFree,
|
|
562
|
+
isPremium,
|
|
563
|
+
canUpgrade,
|
|
564
|
+
isLoading,
|
|
565
|
+
} = useUserTier();
|
|
566
|
+
|
|
567
|
+
return (
|
|
568
|
+
<View>
|
|
569
|
+
<Badge>{tier?.toUpperCase()}</Badge>
|
|
570
|
+
|
|
571
|
+
{isGuest && <Text>Sign in to save your progress</Text>}
|
|
572
|
+
{isFree && <Button onPress={showUpgrade} title="Go Premium" />}
|
|
573
|
+
{isPremium && <Text>Welcome, Premium user!</Text>}
|
|
574
|
+
</View>
|
|
575
|
+
);
|
|
576
|
+
}
|
|
577
|
+
```
|
|
578
|
+
|
|
579
|
+
## Helper Hooks
|
|
580
|
+
|
|
581
|
+
### useCreditChecker
|
|
582
|
+
|
|
583
|
+
Kredi kontrolü için basit hook:
|
|
584
|
+
|
|
585
|
+
```typescript
|
|
586
|
+
import { useCreditChecker } from '@umituz/react-native-subscription';
|
|
587
|
+
|
|
588
|
+
function FeatureWithCreditCheck() {
|
|
589
|
+
const { hasEnoughCredits, credits, checkCredits } = useCreditChecker(10);
|
|
590
|
+
|
|
591
|
+
const handleAction = () => {
|
|
592
|
+
if (hasEnoughCredits) {
|
|
593
|
+
// Execute action
|
|
594
|
+
} else {
|
|
595
|
+
Alert.alert('Insufficient credits', `You need 10 credits, have ${credits}`);
|
|
596
|
+
}
|
|
597
|
+
};
|
|
598
|
+
|
|
599
|
+
return <Button onPress={handleAction} title="Execute" />;
|
|
600
|
+
}
|
|
601
|
+
```
|
|
602
|
+
|
|
603
|
+
### useDevTestCallbacks
|
|
604
|
+
|
|
605
|
+
Development ve test için callback hook'u:
|
|
606
|
+
|
|
607
|
+
```typescript
|
|
608
|
+
import { useDevTestCallbacks } from '@umituz/react-native-subscription';
|
|
609
|
+
|
|
610
|
+
function DevTestPanel() {
|
|
611
|
+
const { setTestPremium, setTestCredits, resetTestState } = useDevTestCallbacks();
|
|
612
|
+
|
|
613
|
+
if (!__DEV__) return null;
|
|
614
|
+
|
|
615
|
+
return (
|
|
616
|
+
<View>
|
|
617
|
+
<Button onPress={() => setTestPremium(true)} title="Set Premium" />
|
|
618
|
+
<Button onPress={() => setTestCredits(100)} title="Add 100 Credits" />
|
|
619
|
+
<Button onPress={resetTestState} title="Reset" />
|
|
620
|
+
</View>
|
|
621
|
+
);
|
|
622
|
+
}
|
|
623
|
+
```
|
|
624
|
+
|
|
625
|
+
## Best Practices
|
|
626
|
+
|
|
627
|
+
1. **Loading States**: Her zaman loading durumunu kontrol edin
|
|
628
|
+
2. **Error Handling**: Hataları uygun şekilde yakalayın ve gösterin
|
|
629
|
+
3. **Gate Hooks**: Özellik erişimi için gate hooks kullanın
|
|
630
|
+
4. **User Experience**: Anlaşılır mesajlar ve smooth transitions sağlayın
|
|
631
|
+
5. **Cache**: Gereksiz re-render'lardan kaçınmak için veriyi cache'leyin
|
|
632
|
+
6. **Cleanup**: Component unmount olduğunda subscription'ları temizleyin
|
|
633
|
+
|
|
634
|
+
## Örnek Uygulama
|
|
635
|
+
|
|
636
|
+
```typescript
|
|
637
|
+
import React from 'react';
|
|
638
|
+
import { View, Text, Button } from 'react-native';
|
|
639
|
+
import {
|
|
640
|
+
usePremiumGate,
|
|
641
|
+
useCreditsGate,
|
|
642
|
+
useUserTier,
|
|
643
|
+
} from '@umituz/react-native-subscription';
|
|
644
|
+
|
|
645
|
+
export default function FeatureExample() {
|
|
646
|
+
const { tier, isPremium } = useUserTier();
|
|
647
|
+
|
|
648
|
+
// Premium gate
|
|
649
|
+
const { canAccess: canAccessPremium, showPaywall } = usePremiumGate({
|
|
650
|
+
featureId: 'ai_tools',
|
|
651
|
+
});
|
|
652
|
+
|
|
653
|
+
// Credits gate
|
|
654
|
+
const {
|
|
655
|
+
hasCredits,
|
|
656
|
+
credits,
|
|
657
|
+
consumeCredit,
|
|
658
|
+
} = useCreditsGate({
|
|
659
|
+
creditCost: 5,
|
|
660
|
+
featureId: 'ai_generation',
|
|
661
|
+
});
|
|
662
|
+
|
|
663
|
+
const handleAIAction = async () => {
|
|
664
|
+
if (!canAccessPremium) {
|
|
665
|
+
showPaywall();
|
|
666
|
+
return;
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
if (isPremium) {
|
|
670
|
+
// Premium users: unlimited access
|
|
671
|
+
await performAIAction();
|
|
672
|
+
} else if (hasCredits) {
|
|
673
|
+
// Free users: use credits
|
|
674
|
+
const result = await consumeCredit();
|
|
675
|
+
if (result.success) {
|
|
676
|
+
await performAIAction();
|
|
677
|
+
}
|
|
678
|
+
} else {
|
|
679
|
+
// No credits: show purchase prompt
|
|
680
|
+
showCreditPurchasePrompt();
|
|
681
|
+
}
|
|
682
|
+
};
|
|
683
|
+
|
|
684
|
+
return (
|
|
685
|
+
<View>
|
|
686
|
+
<Text>Current Tier: {tier}</Text>
|
|
687
|
+
{!isPremium && <Text>Credits: {credits}</Text>}
|
|
688
|
+
|
|
689
|
+
<Button
|
|
690
|
+
onPress={handleAIAction}
|
|
691
|
+
title={isPremium ? "Generate (Unlimited)" : "Generate (5 credits)"}
|
|
692
|
+
/>
|
|
693
|
+
</View>
|
|
694
|
+
);
|
|
695
|
+
}
|
|
696
|
+
```
|
|
697
|
+
|
|
698
|
+
## Hook Reference
|
|
699
|
+
|
|
700
|
+
### Tüm Export Edilen Hooks
|
|
701
|
+
|
|
702
|
+
```typescript
|
|
703
|
+
// Auth & Sync
|
|
704
|
+
export { useAuthAwarePurchase } from './useAuthAwarePurchase';
|
|
705
|
+
export { useAuthGate } from './useAuthGate';
|
|
706
|
+
export { useAuthSubscriptionSync } from './useAuthSubscriptionSync';
|
|
707
|
+
|
|
708
|
+
// Credits
|
|
709
|
+
export { useCreditChecker } from './useCreditChecker';
|
|
710
|
+
export { useCredits } from './useCredits';
|
|
711
|
+
export { useCreditsGate } from './useCreditsGate';
|
|
712
|
+
export { useDeductCredit } from './useDeductCredit';
|
|
713
|
+
export { useInitializeCredits } from './useInitializeCredits';
|
|
714
|
+
|
|
715
|
+
// Features
|
|
716
|
+
export { useFeatureGate } from './useFeatureGate';
|
|
717
|
+
|
|
718
|
+
// Premium
|
|
719
|
+
export { usePremium } from './usePremium';
|
|
720
|
+
export { usePremiumGate } from './usePremiumGate';
|
|
721
|
+
export { usePremiumWithCredits } from './usePremiumWithCredits';
|
|
722
|
+
|
|
723
|
+
// Subscription
|
|
724
|
+
export { useSubscription } from './useSubscription';
|
|
725
|
+
export { useSubscriptionDetails } from './useSubscriptionDetails';
|
|
726
|
+
export { useSubscriptionGate } from './useSubscriptionGate';
|
|
727
|
+
export { useSubscriptionSettingsConfig } from './useSubscriptionSettingsConfig';
|
|
728
|
+
export { useSubscriptionStatus } from './useSubscriptionStatus';
|
|
729
|
+
|
|
730
|
+
// User Tier
|
|
731
|
+
export { useUserTier } from './useUserTier';
|
|
732
|
+
export { useUserTierWithRepository } from './useUserTierWithRepository';
|
|
733
|
+
|
|
734
|
+
// Paywall
|
|
735
|
+
export { usePaywallOperations } from './usePaywallOperations';
|
|
736
|
+
export { usePaywallVisibility } from './usePaywallVisibility';
|
|
737
|
+
|
|
738
|
+
// Feedback
|
|
739
|
+
export { usePaywallFeedback } from './feedback/usePaywallFeedback';
|
|
740
|
+
|
|
741
|
+
// Dev/Test
|
|
742
|
+
export { useDevTestCallbacks } from './useDevTestCallbacks';
|
|
743
|
+
```
|