@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.
- package/README.md +211 -394
- package/package.json +3 -3
- package/src/application/README.md +46 -225
- package/src/application/ports/README.md +42 -97
- package/src/domain/README.md +36 -384
- package/src/domain/constants/README.md +0 -56
- package/src/domain/entities/README.md +43 -169
- package/src/domain/entities/SubscriptionStatus.ts +1 -1
- package/src/domain/errors/README.md +33 -287
- package/src/domain/value-objects/README.md +43 -179
- package/src/domains/README.md +50 -238
- package/src/domains/README.md.bak +274 -0
- package/src/domains/config/README.md +93 -383
- package/src/domains/config/domain/README.md +23 -376
- package/src/domains/config/domain/entities/README.md +34 -343
- package/src/domains/paywall/README.md +99 -369
- package/src/domains/paywall/components/README.md +34 -178
- package/src/domains/paywall/entities/README.md +34 -193
- package/src/domains/paywall/hooks/README.md +34 -122
- package/src/domains/wallet/README.md +34 -275
- package/src/domains/wallet/README.md.bak +209 -0
- package/src/domains/wallet/domain/README.md +34 -101
- package/src/domains/wallet/domain/entities/README.md +34 -115
- package/src/domains/wallet/domain/errors/README.md +34 -151
- package/src/domains/wallet/infrastructure/README.md +34 -89
- package/src/domains/wallet/presentation/components/README.md +34 -224
- package/src/domains/wallet/presentation/components/TransactionItem.tsx +1 -1
- package/src/domains/wallet/presentation/hooks/README.md +34 -248
- package/src/infrastructure/README.md +37 -496
- package/src/infrastructure/mappers/README.md +0 -13
- package/src/infrastructure/repositories/README.md +74 -360
- package/src/infrastructure/services/ActivationHandler.ts +1 -1
- package/src/infrastructure/services/README.md +95 -370
- package/src/infrastructure/services/SubscriptionService.ts +1 -1
- package/src/presentation/README.md +123 -408
- package/src/presentation/README.md.bak +172 -0
- package/src/presentation/components/README.md +151 -179
- package/src/presentation/components/README.md.bak +217 -0
- package/src/presentation/components/details/CreditRow.md +65 -310
- package/src/presentation/components/details/DetailRow.md +63 -255
- package/src/presentation/components/details/PremiumDetailsCard.md +65 -238
- package/src/presentation/components/details/PremiumStatusBadge.md +64 -239
- package/src/presentation/components/details/README.md +97 -447
- package/src/presentation/components/feedback/PaywallFeedbackModal.md +63 -287
- package/src/presentation/components/feedback/README.md +97 -445
- package/src/presentation/components/paywall/PaywallModal.md +66 -416
- package/src/presentation/components/paywall/README.md +50 -186
- package/src/presentation/components/sections/README.md +97 -466
- package/src/presentation/components/sections/SubscriptionSection.md +92 -244
- package/src/presentation/hooks/README.md +154 -741
- package/src/presentation/hooks/useAuthAwarePurchase.md +58 -325
- package/src/presentation/hooks/useAuthGate.md +61 -375
- package/src/presentation/hooks/useAuthSubscriptionSync.md +66 -370
- package/src/presentation/hooks/useCreditChecker.md +73 -378
- package/src/presentation/hooks/useCredits.md +74 -313
- package/src/presentation/hooks/useCredits.md.bak +231 -0
- package/src/presentation/hooks/useCreditsGate.md +66 -318
- package/src/presentation/hooks/useDeductCredit.md +0 -76
- package/src/presentation/hooks/useDeductCredit.ts +1 -1
- package/src/presentation/hooks/useDevTestCallbacks.md +63 -394
- package/src/presentation/hooks/useFeatureGate.md +105 -150
- package/src/presentation/hooks/useFeatureGate.md.bak +284 -0
- package/src/presentation/hooks/useInitializeCredits.md +64 -430
- package/src/presentation/hooks/usePaywall.md +61 -306
- package/src/presentation/hooks/usePaywallOperations.md +64 -458
- package/src/presentation/hooks/usePaywallVisibility.md +67 -316
- package/src/presentation/hooks/usePremium.md +84 -226
- package/src/presentation/hooks/usePremiumGate.md +60 -395
- package/src/presentation/hooks/usePremiumWithCredits.md +64 -401
- package/src/presentation/hooks/useSubscription.md +66 -422
- package/src/presentation/hooks/useSubscriptionDetails.md +65 -410
- package/src/presentation/hooks/useSubscriptionGate.md +80 -164
- package/src/presentation/hooks/useSubscriptionSettingsConfig.md +66 -346
- package/src/presentation/hooks/useSubscriptionStatus.md +66 -396
- package/src/presentation/hooks/useUserTier.md +63 -328
- package/src/presentation/hooks/useUserTierWithRepository.md +64 -424
- package/src/presentation/screens/README.md +48 -190
- package/src/presentation/types/README.md +0 -16
- package/src/presentation/utils/README.md +0 -21
- package/src/presentation/utils/subscriptionDateUtils.ts +1 -1
- package/src/revenuecat/README.md +99 -518
- package/src/revenuecat/application/README.md +35 -150
- package/src/revenuecat/application/ports/README.md +34 -162
- package/src/revenuecat/domain/README.md +42 -141
- package/src/revenuecat/domain/constants/README.md +34 -176
- package/src/revenuecat/domain/entities/README.md +34 -374
- package/src/revenuecat/domain/errors/README.md +47 -191
- package/src/revenuecat/domain/types/README.md +34 -366
- package/src/revenuecat/domain/value-objects/README.md +34 -434
- package/src/revenuecat/infrastructure/README.md +34 -43
- package/src/revenuecat/infrastructure/config/README.md +32 -23
- package/src/revenuecat/infrastructure/handlers/README.md +34 -211
- package/src/revenuecat/infrastructure/managers/README.md +34 -42
- package/src/revenuecat/infrastructure/services/README.md +35 -318
- package/src/revenuecat/infrastructure/utils/README.md +34 -375
- package/src/revenuecat/presentation/README.md +34 -176
- package/src/revenuecat/presentation/hooks/README.md +29 -35
- package/src/utils/README.md +38 -525
|
@@ -2,422 +2,87 @@
|
|
|
2
2
|
|
|
3
3
|
Feature gating hook for premium-only features with optional authentication.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Location
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
import { usePremiumGate } from '@umituz/react-native-subscription';
|
|
9
|
-
```
|
|
7
|
+
**Import Path**: `@umituz/react-native-subscription`
|
|
10
8
|
|
|
11
|
-
|
|
9
|
+
**File**: `src/presentation/hooks/usePremiumGate.ts`
|
|
12
10
|
|
|
13
|
-
|
|
14
|
-
function usePremiumGate(params: {
|
|
15
|
-
isPremium: boolean;
|
|
16
|
-
onPremiumRequired: () => void;
|
|
17
|
-
isAuthenticated?: boolean;
|
|
18
|
-
onAuthRequired?: () => void;
|
|
19
|
-
}): {
|
|
20
|
-
isPremium: boolean;
|
|
21
|
-
isAuthenticated: boolean;
|
|
22
|
-
requirePremium: (action: () => void) => void;
|
|
23
|
-
requireAuth: (action: () => void) => void;
|
|
24
|
-
requirePremiumWithAuth: (action: () => void) => void;
|
|
25
|
-
canAccess: boolean;
|
|
26
|
-
canAccessWithAuth: boolean;
|
|
27
|
-
}
|
|
28
|
-
```
|
|
11
|
+
**Type**: Hook
|
|
29
12
|
|
|
30
|
-
##
|
|
13
|
+
## Strategy
|
|
31
14
|
|
|
32
|
-
|
|
33
|
-
|-----------|------|---------|-------------|
|
|
34
|
-
| `isPremium` | `boolean` | **Required** | Whether user has premium access |
|
|
35
|
-
| `onPremiumRequired` | `() => void` | **Required** | Callback when premium is required |
|
|
36
|
-
| `isAuthenticated` | `boolean` | `true` | Whether user is authenticated |
|
|
37
|
-
| `onAuthRequired` | `() => void` | `undefined` | Callback when auth is required |
|
|
15
|
+
### Premium Gating Flow
|
|
38
16
|
|
|
39
|
-
|
|
17
|
+
1. **Premium Check**: Verify if user has premium access
|
|
18
|
+
2. **Auth Check**: Optionally verify authentication status
|
|
19
|
+
3. **Gate Functions**: Provide requirePremium, requireAuth, requirePremiumWithAuth
|
|
20
|
+
4. **Access Control**: Simple booleans for conditional rendering (canAccess, canAccessWithAuth)
|
|
21
|
+
5. **Callback Triggers**: Execute appropriate callback when requirements not met
|
|
40
22
|
|
|
41
|
-
|
|
42
|
-
|----------|------|-------------|
|
|
43
|
-
| `isPremium` | `boolean` | User has premium access |
|
|
44
|
-
| `isAuthenticated` | `boolean` | User is authenticated |
|
|
45
|
-
| `requirePremium` | `(action) => void` | Gate action behind premium |
|
|
46
|
-
| `requireAuth` | `(action) => void` | Gate action behind auth |
|
|
47
|
-
| `requirePremiumWithAuth` | `(action) => void` | Gate behind both auth and premium |
|
|
48
|
-
| `canAccess` | `boolean` | Can access premium feature |
|
|
49
|
-
| `canAccessWithAuth` | `boolean` | Can access (auth + premium) |
|
|
23
|
+
### Integration Points
|
|
50
24
|
|
|
51
|
-
|
|
25
|
+
- **usePremium**: For premium status check
|
|
26
|
+
- **useAuth**: For authentication status
|
|
27
|
+
- **Paywall Domain**: For premium upgrade flow
|
|
28
|
+
- **Auth UI**: For authentication flow
|
|
52
29
|
|
|
53
|
-
|
|
54
|
-
function PremiumFeature() {
|
|
55
|
-
const { isPremium } = usePremium();
|
|
30
|
+
## Restrictions
|
|
56
31
|
|
|
57
|
-
|
|
58
|
-
isPremium,
|
|
59
|
-
onPremiumRequired: () => {
|
|
60
|
-
showPaywall();
|
|
61
|
-
},
|
|
62
|
-
});
|
|
32
|
+
### REQUIRED
|
|
63
33
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
generatePremiumContent();
|
|
68
|
-
});
|
|
69
|
-
};
|
|
34
|
+
- **Premium Status**: MUST provide isPremium parameter
|
|
35
|
+
- **Callback**: MUST implement onPremiumRequired callback
|
|
36
|
+
- **Access Check**: MUST verify canAccess before showing premium content
|
|
70
37
|
|
|
71
|
-
|
|
72
|
-
<Button
|
|
73
|
-
onPress={handleGenerate}
|
|
74
|
-
disabled={!canAccess}
|
|
75
|
-
title={canAccess ? 'Generate' : 'Upgrade to Premium'}
|
|
76
|
-
/>
|
|
77
|
-
);
|
|
78
|
-
}
|
|
79
|
-
```
|
|
38
|
+
### PROHIBITED
|
|
80
39
|
|
|
81
|
-
|
|
40
|
+
- **NEVER** show premium content without checking isPremium
|
|
41
|
+
- **NEVER** use for security decisions without server validation
|
|
42
|
+
- **DO NOT** assume premium status (always verify)
|
|
82
43
|
|
|
83
|
-
###
|
|
44
|
+
### CRITICAL SAFETY
|
|
84
45
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
46
|
+
- **ALWAYS** verify canAccess before showing premium features
|
|
47
|
+
- **NEVER** trust client-side state for security
|
|
48
|
+
- **MUST** implement proper upgrade flow
|
|
49
|
+
- **ALWAYS** handle authentication when required
|
|
89
50
|
|
|
90
|
-
|
|
91
|
-
isPremium,
|
|
92
|
-
onPremiumRequired: () => showPaywall(),
|
|
93
|
-
isAuthenticated: !!user,
|
|
94
|
-
onAuthRequired: () => showAuthModal(),
|
|
95
|
-
});
|
|
51
|
+
## AI Agent Guidelines
|
|
96
52
|
|
|
97
|
-
|
|
98
|
-
requirePremiumWithAuth(() => {
|
|
99
|
-
// Only runs if user is both authenticated AND premium
|
|
100
|
-
executeAction();
|
|
101
|
-
});
|
|
102
|
-
};
|
|
53
|
+
### When Implementing Premium Gates
|
|
103
54
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
/>
|
|
110
|
-
);
|
|
111
|
-
}
|
|
112
|
-
```
|
|
55
|
+
1. **Always** check canAccess before showing premium content
|
|
56
|
+
2. **Always** provide clear upgrade path in callback
|
|
57
|
+
3. **Always** use requirePremium for action gating
|
|
58
|
+
4. **Always** handle authentication when using requirePremiumWithAuth
|
|
59
|
+
5. **Never** bypass premium checks
|
|
113
60
|
|
|
114
|
-
###
|
|
61
|
+
### Integration Checklist
|
|
115
62
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
63
|
+
- [ ] Import from correct path: `@umituz/react-native-subscription`
|
|
64
|
+
- [ ] Provide isPremium from usePremium
|
|
65
|
+
- [ ] Implement onPremiumRequired callback
|
|
66
|
+
- [ ] Optionally provide auth status and callback
|
|
67
|
+
- [ ] Use requirePremium for action gating
|
|
68
|
+
- [ ] Check canAccess for conditional rendering
|
|
69
|
+
- [ ] Test with premium user
|
|
70
|
+
- [ ] Test with non-premium user
|
|
71
|
+
- [ ] Test with authenticated user
|
|
72
|
+
- [ ] Test with unauthenticated user
|
|
120
73
|
|
|
121
|
-
|
|
122
|
-
requirePremium,
|
|
123
|
-
requireAuth,
|
|
124
|
-
canAccess,
|
|
125
|
-
} = usePremiumGate({
|
|
126
|
-
isPremium,
|
|
127
|
-
onPremiumRequired: () => showPaywall(),
|
|
128
|
-
isAuthenticated: !!user,
|
|
129
|
-
onAuthRequired: () => showAuthModal(),
|
|
130
|
-
});
|
|
74
|
+
### Common Patterns
|
|
131
75
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
/>
|
|
76
|
+
1. **Premium Only**: Gate features behind premium only
|
|
77
|
+
2. **Auth + Premium**: Require both authentication and premium
|
|
78
|
+
3. **Conditional Rendering**: Check canAccess for UI
|
|
79
|
+
4. **Button States**: Disable buttons when not premium
|
|
80
|
+
5. **Upgrade Prompts**: Show in callback when not premium
|
|
138
81
|
|
|
139
|
-
|
|
140
|
-
onPress={() => requirePremium(() => usePremiumFeature())}
|
|
141
|
-
title="Premium Feature (Premium required)"
|
|
142
|
-
/>
|
|
143
|
-
</View>
|
|
144
|
-
);
|
|
145
|
-
}
|
|
146
|
-
```
|
|
82
|
+
## Related Documentation
|
|
147
83
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
const { user } = useAuth();
|
|
154
|
-
|
|
155
|
-
const {
|
|
156
|
-
isPremium: premium,
|
|
157
|
-
isAuthenticated: auth,
|
|
158
|
-
canAccess,
|
|
159
|
-
canAccessWithAuth,
|
|
160
|
-
} = usePremiumGate({
|
|
161
|
-
isPremium,
|
|
162
|
-
onPremiumRequired: () => showPaywall(),
|
|
163
|
-
isAuthenticated: !!user,
|
|
164
|
-
onAuthRequired: () => showAuthModal(),
|
|
165
|
-
});
|
|
166
|
-
|
|
167
|
-
const getAccessLevel = () => {
|
|
168
|
-
if (!auth) return 'guest';
|
|
169
|
-
if (!premium) return 'free';
|
|
170
|
-
return 'premium';
|
|
171
|
-
};
|
|
172
|
-
|
|
173
|
-
const accessLevel = getAccessLevel();
|
|
174
|
-
|
|
175
|
-
return (
|
|
176
|
-
<View>
|
|
177
|
-
<Badge text={accessLevel} />
|
|
178
|
-
|
|
179
|
-
<FeatureList accessibleTo={['guest', 'free', 'premium']} />
|
|
180
|
-
<FeatureList accessibleTo={['free', 'premium']} />
|
|
181
|
-
<FeatureList accessibleTo={['premium']} />
|
|
182
|
-
</View>
|
|
183
|
-
);
|
|
184
|
-
}
|
|
185
|
-
```
|
|
186
|
-
|
|
187
|
-
### With Navigation Guard
|
|
188
|
-
|
|
189
|
-
```typescript
|
|
190
|
-
function PremiumScreen() {
|
|
191
|
-
const { isPremium } = usePremium();
|
|
192
|
-
const navigation = useNavigation();
|
|
193
|
-
|
|
194
|
-
const { requirePremium } = usePremiumGate({
|
|
195
|
-
isPremium,
|
|
196
|
-
onPremiumRequired: () => {
|
|
197
|
-
navigation.replace('Paywall', {
|
|
198
|
-
returnTo: 'PremiumScreen',
|
|
199
|
-
});
|
|
200
|
-
},
|
|
201
|
-
});
|
|
202
|
-
|
|
203
|
-
useEffect(() => {
|
|
204
|
-
// Redirect if not premium
|
|
205
|
-
requirePremium(() => {});
|
|
206
|
-
}, []);
|
|
207
|
-
|
|
208
|
-
if (!isPremium) return null;
|
|
209
|
-
|
|
210
|
-
return (
|
|
211
|
-
<View>
|
|
212
|
-
<Text>Premium Screen Content</Text>
|
|
213
|
-
</View>
|
|
214
|
-
);
|
|
215
|
-
}
|
|
216
|
-
```
|
|
217
|
-
|
|
218
|
-
## Examples
|
|
219
|
-
|
|
220
|
-
### Premium Button Component
|
|
221
|
-
|
|
222
|
-
```typescript
|
|
223
|
-
function PremiumButton({
|
|
224
|
-
children,
|
|
225
|
-
onAction,
|
|
226
|
-
showUpgradeMessage = true,
|
|
227
|
-
}) {
|
|
228
|
-
const { isPremium } = usePremium();
|
|
229
|
-
|
|
230
|
-
const { requirePremium, canAccess } = usePremiumGate({
|
|
231
|
-
isPremium,
|
|
232
|
-
onPremiumRequired: () => {
|
|
233
|
-
if (showUpgradeMessage) {
|
|
234
|
-
Alert.alert(
|
|
235
|
-
'Premium Feature',
|
|
236
|
-
'This feature requires a Premium subscription',
|
|
237
|
-
[
|
|
238
|
-
{ text: 'Cancel', style: 'cancel' },
|
|
239
|
-
{ text: 'Upgrade', onPress: () => navigation.navigate('Paywall') },
|
|
240
|
-
]
|
|
241
|
-
);
|
|
242
|
-
}
|
|
243
|
-
},
|
|
244
|
-
});
|
|
245
|
-
|
|
246
|
-
const handlePress = () => {
|
|
247
|
-
requirePremium(() => {
|
|
248
|
-
onAction?.();
|
|
249
|
-
});
|
|
250
|
-
};
|
|
251
|
-
|
|
252
|
-
return (
|
|
253
|
-
<TouchableOpacity
|
|
254
|
-
onPress={handlePress}
|
|
255
|
-
style={[styles.button, !canAccess && styles.lockedButton]}
|
|
256
|
-
disabled={!canAccess}
|
|
257
|
-
>
|
|
258
|
-
<PremiumIcon active={canAccess} />
|
|
259
|
-
<Text style={styles.text}>{children}</Text>
|
|
260
|
-
{!canAccess && <LockIcon />}
|
|
261
|
-
</TouchableOpacity>
|
|
262
|
-
);
|
|
263
|
-
}
|
|
264
|
-
```
|
|
265
|
-
|
|
266
|
-
### Batch Premium Operations
|
|
267
|
-
|
|
268
|
-
```typescript
|
|
269
|
-
function BatchPremiumOperations({ items }) {
|
|
270
|
-
const { isPremium } = usePremium();
|
|
271
|
-
|
|
272
|
-
const { requirePremium } = usePremiumGate({
|
|
273
|
-
isPremium,
|
|
274
|
-
onPremiumRequired: () => {
|
|
275
|
-
showPaywall({
|
|
276
|
-
feature: 'Batch Operations',
|
|
277
|
-
highlight: `Process ${items.length} items at once`,
|
|
278
|
-
});
|
|
279
|
-
},
|
|
280
|
-
});
|
|
281
|
-
|
|
282
|
-
const handleBatchProcess = () => {
|
|
283
|
-
requirePremium(async () => {
|
|
284
|
-
for (const item of items) {
|
|
285
|
-
await processItem(item);
|
|
286
|
-
updateProgress();
|
|
287
|
-
}
|
|
288
|
-
Alert.alert('Complete', `Processed ${items.length} items`);
|
|
289
|
-
});
|
|
290
|
-
};
|
|
291
|
-
|
|
292
|
-
return (
|
|
293
|
-
<Button
|
|
294
|
-
onPress={handleBatchProcess}
|
|
295
|
-
title={`Process ${items.length} items`}
|
|
296
|
-
/>
|
|
297
|
-
);
|
|
298
|
-
}
|
|
299
|
-
```
|
|
300
|
-
|
|
301
|
-
### Conditional Rendering
|
|
302
|
-
|
|
303
|
-
```typescript
|
|
304
|
-
function ConditionalPremiumFeature() {
|
|
305
|
-
const { isPremium } = usePremium();
|
|
306
|
-
|
|
307
|
-
const { canAccess } = usePremiumGate({
|
|
308
|
-
isPremium,
|
|
309
|
-
onPremiumRequired: () => showPaywall(),
|
|
310
|
-
});
|
|
311
|
-
|
|
312
|
-
if (!canAccess) {
|
|
313
|
-
return (
|
|
314
|
-
<View style={styles.lockedContainer}>
|
|
315
|
-
<LockIcon size={48} />
|
|
316
|
-
<Text style={styles.title}>Premium Feature</Text>
|
|
317
|
-
<Text style={styles.message}>
|
|
318
|
-
Upgrade to access this feature
|
|
319
|
-
</Text>
|
|
320
|
-
<Button
|
|
321
|
-
onPress={() => showPaywall()}
|
|
322
|
-
title="Upgrade Now"
|
|
323
|
-
/>
|
|
324
|
-
</View>
|
|
325
|
-
);
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
return (
|
|
329
|
-
<View>
|
|
330
|
-
<Text>Premium Content</Text>
|
|
331
|
-
<PremiumFeatureComponent />
|
|
332
|
-
</View>
|
|
333
|
-
);
|
|
334
|
-
}
|
|
335
|
-
```
|
|
336
|
-
|
|
337
|
-
### With Analytics
|
|
338
|
-
|
|
339
|
-
```typescript
|
|
340
|
-
function TrackedPremiumFeature() {
|
|
341
|
-
const { isPremium } = usePremium();
|
|
342
|
-
|
|
343
|
-
const { requirePremium } = usePremiumGate({
|
|
344
|
-
isPremium,
|
|
345
|
-
onPremiumRequired: () => {
|
|
346
|
-
analytics.track('premium_feature_accessed', {
|
|
347
|
-
feature: 'advanced_analytics',
|
|
348
|
-
success: false,
|
|
349
|
-
reason: 'not_premium',
|
|
350
|
-
});
|
|
351
|
-
showPaywall();
|
|
352
|
-
},
|
|
353
|
-
});
|
|
354
|
-
|
|
355
|
-
const handleFeature = () => {
|
|
356
|
-
requirePremium(() => {
|
|
357
|
-
analytics.track('premium_feature_used', {
|
|
358
|
-
feature: 'advanced_analytics',
|
|
359
|
-
success: true,
|
|
360
|
-
});
|
|
361
|
-
executeFeature();
|
|
362
|
-
});
|
|
363
|
-
};
|
|
364
|
-
|
|
365
|
-
return <Button onPress={handleFeature} title="Use Premium Feature" />;
|
|
366
|
-
}
|
|
367
|
-
```
|
|
368
|
-
|
|
369
|
-
## Best Practices
|
|
370
|
-
|
|
371
|
-
1. **Clear messaging** - Tell users what they're missing
|
|
372
|
-
2. **Smooth upgrades** - Make subscription path obvious
|
|
373
|
-
3. **Respect auth** - Check authentication before premium
|
|
374
|
-
4. **Track events** - Monitor gate triggers
|
|
375
|
-
5. **Value first** - Show benefits before locking
|
|
376
|
-
6. **Graceful fallbacks** - Show limited version if appropriate
|
|
377
|
-
7. **Context-aware** - Customize paywall based on feature
|
|
378
|
-
|
|
379
|
-
## Use Case Patterns
|
|
380
|
-
|
|
381
|
-
### Premium Only (No Auth)
|
|
382
|
-
|
|
383
|
-
```typescript
|
|
384
|
-
const { requirePremium } = usePremiumGate({
|
|
385
|
-
isPremium,
|
|
386
|
-
onPremiumRequired: () => showPaywall(),
|
|
387
|
-
});
|
|
388
|
-
```
|
|
389
|
-
|
|
390
|
-
### Auth + Premium Required
|
|
391
|
-
|
|
392
|
-
```typescript
|
|
393
|
-
const { requirePremiumWithAuth } = usePremiumGate({
|
|
394
|
-
isPremium,
|
|
395
|
-
onPremiumRequired: () => showPaywall(),
|
|
396
|
-
isAuthenticated: !!user,
|
|
397
|
-
onAuthRequired: () => showAuthModal(),
|
|
398
|
-
});
|
|
399
|
-
```
|
|
400
|
-
|
|
401
|
-
### Separate Auth and Premium Gates
|
|
402
|
-
|
|
403
|
-
```typescript
|
|
404
|
-
const { requireAuth, requirePremium } = usePremiumGate({
|
|
405
|
-
isPremium,
|
|
406
|
-
onPremiumRequired: () => showPaywall(),
|
|
407
|
-
isAuthenticated: !!user,
|
|
408
|
-
onAuthRequired: () => showAuthModal(),
|
|
409
|
-
});
|
|
410
|
-
```
|
|
411
|
-
|
|
412
|
-
## Related Hooks
|
|
413
|
-
|
|
414
|
-
- **useAuthGate** - Authentication gating only
|
|
415
|
-
- **useSubscriptionGate** - Subscription gating
|
|
416
|
-
- **useFeatureGate** - Combined auth + subscription + credits
|
|
417
|
-
- **usePremium** - Premium status checking
|
|
418
|
-
|
|
419
|
-
## See Also
|
|
420
|
-
|
|
421
|
-
- [Premium Gating](../../../docs/PREMIUM_GATING.md)
|
|
422
|
-
- [Feature Access Patterns](../../../docs/ACCESS_PATTERNS.md)
|
|
423
|
-
- [Paywall Triggers](../screens/README.md#triggers)
|
|
84
|
+
- **usePremium**: Premium status check
|
|
85
|
+
- **useAuthGate**: Auth + subscription gating
|
|
86
|
+
- **useSubscriptionGate**: Subscription-only gating
|
|
87
|
+
- **useFeatureGate**: Unified feature gating
|
|
88
|
+
- **Paywall Domain**: `src/domains/paywall/README.md`
|