@umituz/react-native-subscription 2.14.99 → 2.14.100
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 +1 -1
- 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/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/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/README.md +95 -370
- 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/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/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,167 +2,83 @@
|
|
|
2
2
|
|
|
3
3
|
Subscription-only feature gating with simple, focused API.
|
|
4
4
|
|
|
5
|
-
##
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
###
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
return (
|
|
86
|
-
<View>
|
|
87
|
-
<PremiumLockedIcon />
|
|
88
|
-
<Text>This feature requires Premium</Text>
|
|
89
|
-
<Button
|
|
90
|
-
onPress={() => requireSubscription(() => {})}
|
|
91
|
-
title="Upgrade Now"
|
|
92
|
-
/>
|
|
93
|
-
</View>
|
|
94
|
-
);
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
return (
|
|
98
|
-
<View>
|
|
99
|
-
<Text>Premium Content</Text>
|
|
100
|
-
<PremiumFeatureComponent />
|
|
101
|
-
</View>
|
|
102
|
-
);
|
|
103
|
-
}
|
|
104
|
-
```
|
|
105
|
-
|
|
106
|
-
### With Async Actions
|
|
107
|
-
|
|
108
|
-
```typescript
|
|
109
|
-
function AsyncPremiumFeature() {
|
|
110
|
-
const { isPremium } = usePremium();
|
|
111
|
-
|
|
112
|
-
const { requireSubscription } = useSubscriptionGate({
|
|
113
|
-
hasSubscription: isPremium,
|
|
114
|
-
onSubscriptionRequired: () => {
|
|
115
|
-
showPaywall({
|
|
116
|
-
feature: 'Advanced Analytics',
|
|
117
|
-
onSubscribe: () => {
|
|
118
|
-
// Action will execute after subscription
|
|
119
|
-
},
|
|
120
|
-
});
|
|
121
|
-
},
|
|
122
|
-
});
|
|
123
|
-
|
|
124
|
-
const handleExportData = () => {
|
|
125
|
-
requireSubscription(async () => {
|
|
126
|
-
await exportLargeDataset();
|
|
127
|
-
Alert.alert('Success', 'Data exported successfully');
|
|
128
|
-
});
|
|
129
|
-
};
|
|
130
|
-
|
|
131
|
-
return <Button onPress={handleExportData} title="Export Data" />;
|
|
132
|
-
}
|
|
133
|
-
```
|
|
134
|
-
|
|
135
|
-
## Best Practices
|
|
136
|
-
|
|
137
|
-
1. **Simple checks** - Keep gating logic straightforward
|
|
138
|
-
2. **Clear messaging** - Tell users what they're missing
|
|
139
|
-
3. **Smooth upgrades** - Make subscription path obvious
|
|
140
|
-
4. **Track access** - Monitor gate triggers for optimization
|
|
141
|
-
5. **Value first** - Show benefits before locking
|
|
142
|
-
6. **Graceful fallbacks** - Show preview or limited version
|
|
143
|
-
7. **Context-aware** - Customize paywall based on feature
|
|
144
|
-
|
|
145
|
-
## Development Logging
|
|
146
|
-
|
|
147
|
-
In development mode, the hook logs useful information:
|
|
148
|
-
|
|
149
|
-
```typescript
|
|
150
|
-
// User not premium
|
|
151
|
-
[useSubscriptionGate] No subscription, showing paywall
|
|
152
|
-
|
|
153
|
-
// User has subscription
|
|
154
|
-
[useSubscriptionGate] Has subscription, proceeding
|
|
155
|
-
```
|
|
156
|
-
|
|
157
|
-
## Related Hooks
|
|
158
|
-
|
|
159
|
-
- **useAuthGate** - Add authentication requirements
|
|
160
|
-
- **useCreditsGate** - Credits-based gating
|
|
161
|
-
- **useFeatureGate** - Combined auth + subscription + credits
|
|
162
|
-
- **usePremiumGate** - Premium feature gating with auth option
|
|
163
|
-
|
|
164
|
-
## See Also
|
|
165
|
-
|
|
166
|
-
- [Subscription Gating](../../../docs/SUBSCRIPTION_GATING.md)
|
|
167
|
-
- [Paywall Triggers](../screens/README.md#triggers)
|
|
168
|
-
- [usePremium](./usePremium.md)
|
|
5
|
+
## Location
|
|
6
|
+
|
|
7
|
+
**Import Path**: `@umituz/react-native-subscription`
|
|
8
|
+
|
|
9
|
+
**File**: `src/presentation/hooks/useSubscriptionGate.ts`
|
|
10
|
+
|
|
11
|
+
**Type**: Hook
|
|
12
|
+
|
|
13
|
+
## Strategy
|
|
14
|
+
|
|
15
|
+
### Subscription Gating Flow
|
|
16
|
+
|
|
17
|
+
1. **Subscription Check**: Verify if user has active subscription
|
|
18
|
+
2. **Gate Function**: Provide requireSubscription function for gating
|
|
19
|
+
3. **Action Wrapping**: Wrap actions behind subscription check
|
|
20
|
+
4. **Callback Trigger**: Execute callback when subscription is required
|
|
21
|
+
5. **Boolean Access**: Provide simple hasSubscription boolean for conditional rendering
|
|
22
|
+
|
|
23
|
+
### Integration Points
|
|
24
|
+
|
|
25
|
+
- **usePremium**: For subscription status check
|
|
26
|
+
- **Paywall Domain**: For subscription upgrade flow
|
|
27
|
+
- **Feature Gates**: For unified feature access control
|
|
28
|
+
|
|
29
|
+
## Restrictions
|
|
30
|
+
|
|
31
|
+
### REQUIRED
|
|
32
|
+
|
|
33
|
+
- **Subscription Status**: MUST provide hasSubscription parameter
|
|
34
|
+
- **Callback**: MUST implement onSubscriptionRequired callback
|
|
35
|
+
- **Return Check**: SHOULD check return value from requireSubscription
|
|
36
|
+
|
|
37
|
+
### PROHIBITED
|
|
38
|
+
|
|
39
|
+
- **NEVER** show protected content without checking hasSubscription
|
|
40
|
+
- **NEVER** use for security decisions without server validation
|
|
41
|
+
- **DO NOT** assume subscription status (always verify)
|
|
42
|
+
|
|
43
|
+
### CRITICAL SAFETY
|
|
44
|
+
|
|
45
|
+
- **ALWAYS** verify hasSubscription before allowing access
|
|
46
|
+
- **NEVER** trust client-side state for security
|
|
47
|
+
- **MUST** implement proper upgrade flow
|
|
48
|
+
- **ALWAYS** handle both subscribed and non-subscribed states
|
|
49
|
+
|
|
50
|
+
## AI Agent Guidelines
|
|
51
|
+
|
|
52
|
+
### When Implementing Subscription Gates
|
|
53
|
+
|
|
54
|
+
1. **Always** check hasSubscription before showing protected content
|
|
55
|
+
2. **Always** provide clear upgrade path in callback
|
|
56
|
+
3. **Always** use requireSubscription for action gating
|
|
57
|
+
4. **Never** bypass subscription checks
|
|
58
|
+
5. **Always** test with both subscribed and non-subscribed users
|
|
59
|
+
|
|
60
|
+
### Integration Checklist
|
|
61
|
+
|
|
62
|
+
- [ ] Import from correct path: `@umituz/react-native-subscription`
|
|
63
|
+
- [ ] Provide hasSubscription from usePremium
|
|
64
|
+
- [ ] Implement onSubscriptionRequired callback
|
|
65
|
+
- [ ] Use requireSubscription for action gating
|
|
66
|
+
- [ ] Check hasSubscription for conditional rendering
|
|
67
|
+
- [ ] Test with subscribed user
|
|
68
|
+
- [ ] Test with non-subscribed user
|
|
69
|
+
- [ ] Verify upgrade flow triggers correctly
|
|
70
|
+
|
|
71
|
+
### Common Patterns
|
|
72
|
+
|
|
73
|
+
1. **Action Gating**: Use requireSubscription to wrap actions
|
|
74
|
+
2. **Conditional Rendering**: Check hasSubscription for UI
|
|
75
|
+
3. **Button States**: Disable buttons when not subscribed
|
|
76
|
+
4. **Upgrade Prompts**: Show in callback when not subscribed
|
|
77
|
+
|
|
78
|
+
## Related Documentation
|
|
79
|
+
|
|
80
|
+
- **usePremium**: Subscription status check
|
|
81
|
+
- **usePremiumGate**: Premium feature gating
|
|
82
|
+
- **useAuthGate**: Auth + subscription gating
|
|
83
|
+
- **useFeatureGate**: Unified feature gating
|
|
84
|
+
- **Paywall Domain**: `src/domains/paywall/README.md`
|
|
@@ -2,373 +2,93 @@
|
|
|
2
2
|
|
|
3
3
|
Returns ready-to-use configuration for subscription settings screens.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Location
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
import {
|
|
9
|
-
useSubscriptionSettingsConfig,
|
|
10
|
-
type SubscriptionSettingsConfig
|
|
11
|
-
} from '@umituz/react-native-subscription';
|
|
12
|
-
```
|
|
7
|
+
**Import Path**: `@umituz/react-native-subscription`
|
|
13
8
|
|
|
14
|
-
|
|
9
|
+
**File**: `src/presentation/hooks/useSubscriptionSettingsConfig.ts`
|
|
15
10
|
|
|
16
|
-
|
|
17
|
-
function useSubscriptionSettingsConfig(
|
|
18
|
-
params: UseSubscriptionSettingsConfigParams
|
|
19
|
-
): SubscriptionSettingsConfig
|
|
11
|
+
**Type**: Hook
|
|
20
12
|
|
|
21
|
-
|
|
22
|
-
userId: string | undefined;
|
|
23
|
-
translations: SubscriptionSettingsTranslations;
|
|
24
|
-
creditLimit?: number;
|
|
25
|
-
upgradePrompt?: UpgradePromptConfig;
|
|
26
|
-
}
|
|
13
|
+
## Strategy
|
|
27
14
|
|
|
28
|
-
|
|
29
|
-
enabled: boolean;
|
|
30
|
-
settingsItem: SettingsItemConfig;
|
|
31
|
-
sectionConfig: SectionConfig;
|
|
32
|
-
}
|
|
33
|
-
```
|
|
15
|
+
### Settings Configuration Generation
|
|
34
16
|
|
|
35
|
-
|
|
17
|
+
1. **Data Aggregation**: Combine subscription, credits, and tier information
|
|
18
|
+
2. **Status Determination**: Calculate status type (active/expired/free/canceled)
|
|
19
|
+
3. **Date Formatting**: Format expiration and purchase dates
|
|
20
|
+
4. **Credit Items**: Generate credit item list with optional limit
|
|
21
|
+
5. **Translation Support**: Apply provided translations to all strings
|
|
22
|
+
6. **Upgrade Prompt**: Optional upgrade prompt configuration
|
|
36
23
|
|
|
37
|
-
|
|
38
|
-
|-----------|------|---------|-------------|
|
|
39
|
-
| `userId` | `string \| undefined` | **Required** | User ID |
|
|
40
|
-
| `translations` | `SubscriptionSettingsTranslations` | **Required** | Localized strings |
|
|
41
|
-
| `creditLimit` | `number` | `undefined` | Max credits to display |
|
|
42
|
-
| `upgradePrompt` | `UpgradePromptConfig` | `undefined` | Upgrade prompt configuration |
|
|
24
|
+
### Integration Points
|
|
43
25
|
|
|
44
|
-
|
|
26
|
+
- **useSubscriptionStatus**: For subscription status details
|
|
27
|
+
- **useCredits**: For credits information
|
|
28
|
+
- **useUserTier**: For tier determination
|
|
29
|
+
- **Settings UI**: For settings screen integration
|
|
30
|
+
- **Translation System**: For localization support
|
|
45
31
|
|
|
46
|
-
|
|
47
|
-
interface SubscriptionSettingsTranslations {
|
|
48
|
-
title: string; // e.g., "Subscription"
|
|
49
|
-
description: string; // e.g., "Manage your subscription"
|
|
50
|
-
statusLabel: string; // e.g., "Status"
|
|
51
|
-
statusActive: string; // e.g., "Active"
|
|
52
|
-
statusExpired: string; // e.g., "Expired"
|
|
53
|
-
statusFree: string; // e.g., "Free"
|
|
54
|
-
statusCanceled: string; // e.g., "Canceled"
|
|
55
|
-
expiresLabel: string; // e.g., "Expires on"
|
|
56
|
-
purchasedLabel: string; // e.g., "Purchased on"
|
|
57
|
-
lifetimeLabel: string; // e.g., "Lifetime"
|
|
58
|
-
creditsTitle: string; // e.g., "Credits"
|
|
59
|
-
remainingLabel: string; // e.g., "remaining"
|
|
60
|
-
manageButton: string; // e.g., "Manage Subscription"
|
|
61
|
-
upgradeButton: string; // e.g., "Upgrade to Premium"
|
|
62
|
-
}
|
|
63
|
-
```
|
|
32
|
+
## Restrictions
|
|
64
33
|
|
|
65
|
-
|
|
34
|
+
### REQUIRED
|
|
66
35
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
36
|
+
- **User ID**: MUST provide valid userId parameter
|
|
37
|
+
- **Translations**: MUST provide all translation strings
|
|
38
|
+
- **Null Handling**: MUST handle null dates and values
|
|
39
|
+
- **Enabled Check**: MUST check config.enabled before use
|
|
70
40
|
|
|
71
|
-
|
|
72
|
-
userId: user?.uid,
|
|
73
|
-
translations: {
|
|
74
|
-
title: 'Subscription',
|
|
75
|
-
description: 'Manage your subscription',
|
|
76
|
-
statusLabel: 'Status',
|
|
77
|
-
statusActive: 'Active',
|
|
78
|
-
statusExpired: 'Expired',
|
|
79
|
-
statusFree: 'Free',
|
|
80
|
-
statusCanceled: 'Canceled',
|
|
81
|
-
expiresLabel: 'Expires on',
|
|
82
|
-
purchasedLabel: 'Purchased on',
|
|
83
|
-
lifetimeLabel: 'Lifetime',
|
|
84
|
-
creditsTitle: 'Credits',
|
|
85
|
-
remainingLabel: 'remaining',
|
|
86
|
-
manageButton: 'Manage Subscription',
|
|
87
|
-
upgradeButton: 'Upgrade to Premium',
|
|
88
|
-
},
|
|
89
|
-
});
|
|
41
|
+
### PROHIBITED
|
|
90
42
|
|
|
91
|
-
|
|
43
|
+
- **NEVER** use without providing all translations
|
|
44
|
+
- **NEVER** assume config is enabled (check enabled flag)
|
|
45
|
+
- **DO NOT** hardcode translation strings
|
|
46
|
+
- **DO NOT** use without userId
|
|
92
47
|
|
|
93
|
-
|
|
94
|
-
<SettingsSection>
|
|
95
|
-
<SettingsItem
|
|
96
|
-
title={config.settingsItem.title}
|
|
97
|
-
description={config.settingsItem.description}
|
|
98
|
-
onPress={config.settingsItem.onPress}
|
|
99
|
-
icon={config.settingsItem.icon}
|
|
100
|
-
/>
|
|
101
|
-
</SettingsSection>
|
|
102
|
-
);
|
|
103
|
-
}
|
|
104
|
-
```
|
|
48
|
+
### CRITICAL SAFETY
|
|
105
49
|
|
|
106
|
-
|
|
50
|
+
- **ALWAYS** check config.enabled before rendering
|
|
51
|
+
- **MUST** provide complete translation objects
|
|
52
|
+
- **ALWAYS** handle null dates gracefully
|
|
53
|
+
- **NEVER** trust client-side config for security
|
|
107
54
|
|
|
108
|
-
|
|
55
|
+
## AI Agent Guidelines
|
|
109
56
|
|
|
110
|
-
|
|
111
|
-
function LocalizedSettings() {
|
|
112
|
-
const { t } = useTranslation();
|
|
113
|
-
const { user } = useAuth();
|
|
57
|
+
### When Implementing Settings Config
|
|
114
58
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
statusLabel: t('subscription.status_label'),
|
|
121
|
-
statusActive: t('subscription.status_active'),
|
|
122
|
-
statusExpired: t('subscription.status_expired'),
|
|
123
|
-
statusFree: t('subscription.status_free'),
|
|
124
|
-
statusCanceled: t('subscription.status_canceled'),
|
|
125
|
-
expiresLabel: t('subscription.expires_label'),
|
|
126
|
-
purchasedLabel: t('subscription.purchased_label'),
|
|
127
|
-
lifetimeLabel: t('subscription.lifetime_label'),
|
|
128
|
-
creditsTitle: t('subscription.credits_title'),
|
|
129
|
-
remainingLabel: t('subscription.remaining_label'),
|
|
130
|
-
manageButton: t('subscription.manage_button'),
|
|
131
|
-
upgradeButton: t('subscription.upgrade_button'),
|
|
132
|
-
},
|
|
133
|
-
});
|
|
59
|
+
1. **Always** provide complete translations
|
|
60
|
+
2. **Always** check config.enabled
|
|
61
|
+
3. **Always** handle null dates
|
|
62
|
+
4. **Always** format dates appropriately
|
|
63
|
+
5. **Never** use for security decisions without server validation
|
|
134
64
|
|
|
135
|
-
|
|
136
|
-
}
|
|
137
|
-
```
|
|
65
|
+
### Integration Checklist
|
|
138
66
|
|
|
139
|
-
|
|
67
|
+
- [ ] Import from correct path: `@umituz/react-native-subscription`
|
|
68
|
+
- [ ] Provide valid userId
|
|
69
|
+
- [ ] Provide complete translations
|
|
70
|
+
- [ ] Check config.enabled
|
|
71
|
+
- [ ] Handle null dates
|
|
72
|
+
- [ ] Format dates appropriately
|
|
73
|
+
- [ ] Apply credit limit if needed
|
|
74
|
+
- [ ] Configure upgrade prompt if needed
|
|
75
|
+
- [ ] Test with active subscription
|
|
76
|
+
- [ ] Test with expired subscription
|
|
77
|
+
- [ ] Test with free user
|
|
78
|
+
- [ ] Test with lifetime subscription
|
|
140
79
|
|
|
141
|
-
|
|
142
|
-
function SettingsWithCreditLimit() {
|
|
143
|
-
const { user } = useAuth();
|
|
80
|
+
### Common Patterns
|
|
144
81
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
82
|
+
1. **Settings List Item**: Quick access item in settings
|
|
83
|
+
2. **Detailed Section**: Comprehensive subscription section
|
|
84
|
+
3. **Localized Settings**: Use with translation libraries
|
|
85
|
+
4. **Credit Limit**: Limit displayed credit items
|
|
86
|
+
5. **Upgrade Prompt**: Show upgrade prompt for free users
|
|
150
87
|
|
|
151
|
-
|
|
152
|
-
<ScrollView>
|
|
153
|
-
<SubscriptionSection config={config} />
|
|
154
|
-
</ScrollView>
|
|
155
|
-
);
|
|
156
|
-
}
|
|
157
|
-
```
|
|
88
|
+
## Related Documentation
|
|
158
89
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
const config = useSubscriptionSettingsConfig({
|
|
166
|
-
userId: user?.uid,
|
|
167
|
-
translations: englishTranslations,
|
|
168
|
-
upgradePrompt: {
|
|
169
|
-
showPrompt: true,
|
|
170
|
-
highlightBenefits: [
|
|
171
|
-
'Unlimited access',
|
|
172
|
-
'Priority support',
|
|
173
|
-
'Ad-free experience',
|
|
174
|
-
],
|
|
175
|
-
discountOffer: 'Save 50% with annual plan',
|
|
176
|
-
},
|
|
177
|
-
});
|
|
178
|
-
|
|
179
|
-
return (
|
|
180
|
-
<View>
|
|
181
|
-
<SubscriptionSection config={config} />
|
|
182
|
-
{!config.sectionConfig.isPremium && config.sectionConfig.upgradePrompt && (
|
|
183
|
-
<UpgradePromptCard prompt={config.sectionConfig.upgradePrompt} />
|
|
184
|
-
)}
|
|
185
|
-
</View>
|
|
186
|
-
);
|
|
187
|
-
}
|
|
188
|
-
```
|
|
189
|
-
|
|
190
|
-
### Complete Subscription Settings Screen
|
|
191
|
-
|
|
192
|
-
```typescript
|
|
193
|
-
function SubscriptionSettingsScreen() {
|
|
194
|
-
const { user } = useAuth();
|
|
195
|
-
|
|
196
|
-
const config = useSubscriptionSettingsConfig({
|
|
197
|
-
userId: user?.uid,
|
|
198
|
-
translations: {
|
|
199
|
-
title: 'Subscription',
|
|
200
|
-
description: 'Manage your subscription',
|
|
201
|
-
statusLabel: 'Status',
|
|
202
|
-
statusActive: 'Active',
|
|
203
|
-
statusExpired: 'Expired',
|
|
204
|
-
statusFree: 'Free',
|
|
205
|
-
statusCanceled: 'Canceled',
|
|
206
|
-
expiresLabel: 'Expires on',
|
|
207
|
-
purchasedLabel: 'Purchased on',
|
|
208
|
-
lifetimeLabel: 'Lifetime',
|
|
209
|
-
creditsTitle: 'Credits',
|
|
210
|
-
remainingLabel: 'remaining',
|
|
211
|
-
manageButton: 'Manage Subscription',
|
|
212
|
-
upgradeButton: 'Upgrade to Premium',
|
|
213
|
-
},
|
|
214
|
-
creditLimit: 8,
|
|
215
|
-
upgradePrompt: {
|
|
216
|
-
showPrompt: true,
|
|
217
|
-
highlightBenefits: [
|
|
218
|
-
'Unlimited access to all features',
|
|
219
|
-
'Priority customer support',
|
|
220
|
-
'Ad-free experience',
|
|
221
|
-
],
|
|
222
|
-
},
|
|
223
|
-
});
|
|
224
|
-
|
|
225
|
-
if (!config.enabled) return null;
|
|
226
|
-
|
|
227
|
-
const { settingsItem, sectionConfig } = config;
|
|
228
|
-
|
|
229
|
-
return (
|
|
230
|
-
<ScrollView style={styles.container}>
|
|
231
|
-
{/* Settings List Item */}
|
|
232
|
-
<SettingsList>
|
|
233
|
-
<SettingsListItem
|
|
234
|
-
title={settingsItem.title}
|
|
235
|
-
description={settingsItem.description}
|
|
236
|
-
icon={settingsItem.icon}
|
|
237
|
-
onPress={settingsItem.onPress}
|
|
238
|
-
badge={settingsItem.statusLabel}
|
|
239
|
-
/>
|
|
240
|
-
</SettingsList>
|
|
241
|
-
|
|
242
|
-
{/* Detailed Section */}
|
|
243
|
-
<Card style={styles.card}>
|
|
244
|
-
<Card.Title>{sectionConfig.translations.title}</Card.Title>
|
|
245
|
-
|
|
246
|
-
<View style={styles.section}>
|
|
247
|
-
<DetailRow
|
|
248
|
-
label={sectionConfig.translations.statusLabel}
|
|
249
|
-
value={sectionConfig.statusType === 'active'
|
|
250
|
-
? sectionConfig.translations.statusActive
|
|
251
|
-
: sectionConfig.statusType === 'expired'
|
|
252
|
-
? sectionConfig.translations.statusExpired
|
|
253
|
-
: sectionConfig.translations.statusFree}
|
|
254
|
-
/>
|
|
255
|
-
|
|
256
|
-
{sectionConfig.expirationDate && (
|
|
257
|
-
<DetailRow
|
|
258
|
-
label={sectionConfig.translations.expiresLabel}
|
|
259
|
-
value={sectionConfig.expirationDate}
|
|
260
|
-
/>
|
|
261
|
-
)}
|
|
262
|
-
|
|
263
|
-
{sectionConfig.purchaseDate && (
|
|
264
|
-
<DetailRow
|
|
265
|
-
label={sectionConfig.translations.purchasedLabel}
|
|
266
|
-
value={sectionConfig.purchaseDate}
|
|
267
|
-
/>
|
|
268
|
-
)}
|
|
269
|
-
|
|
270
|
-
{sectionConfig.isLifetime && (
|
|
271
|
-
<DetailRow
|
|
272
|
-
label=""
|
|
273
|
-
value={sectionConfig.translations.lifetimeLabel}
|
|
274
|
-
/>
|
|
275
|
-
)}
|
|
276
|
-
</View>
|
|
277
|
-
|
|
278
|
-
{/* Credits Section */}
|
|
279
|
-
{sectionConfig.credits.length > 0 && (
|
|
280
|
-
<View style={styles.section}>
|
|
281
|
-
<Text style={styles.creditsTitle}>
|
|
282
|
-
{sectionConfig.translations.creditsTitle}
|
|
283
|
-
</Text>
|
|
284
|
-
{sectionConfig.credits.map((credit, index) => (
|
|
285
|
-
<View key={index} style={styles.creditItem}>
|
|
286
|
-
<Icon name="coin" size={16} />
|
|
287
|
-
<Text>{credit.amount}</Text>
|
|
288
|
-
<Text>{sectionConfig.translations.remainingLabel}</Text>
|
|
289
|
-
</View>
|
|
290
|
-
))}
|
|
291
|
-
</View>
|
|
292
|
-
)}
|
|
293
|
-
|
|
294
|
-
{/* Actions */}
|
|
295
|
-
<View style={styles.actions}>
|
|
296
|
-
{sectionConfig.onUpgrade && !sectionConfig.isPremium && (
|
|
297
|
-
<Button
|
|
298
|
-
onPress={sectionConfig.onUpgrade}
|
|
299
|
-
title={sectionConfig.translations.upgradeButton}
|
|
300
|
-
/>
|
|
301
|
-
)}
|
|
302
|
-
|
|
303
|
-
{sectionConfig.isPremium && (
|
|
304
|
-
<Button
|
|
305
|
-
onPress={() => Linking.openURL('https://apps.apple.com/account/subscriptions')}
|
|
306
|
-
title={sectionConfig.translations.manageButton}
|
|
307
|
-
variant="outline"
|
|
308
|
-
/>
|
|
309
|
-
)}
|
|
310
|
-
</View>
|
|
311
|
-
</Card>
|
|
312
|
-
</ScrollView>
|
|
313
|
-
);
|
|
314
|
-
}
|
|
315
|
-
```
|
|
316
|
-
|
|
317
|
-
## Configuration Object
|
|
318
|
-
|
|
319
|
-
### settingsItem
|
|
320
|
-
|
|
321
|
-
Quick access item for settings list:
|
|
322
|
-
|
|
323
|
-
```typescript
|
|
324
|
-
interface SettingsItemConfig {
|
|
325
|
-
title: string; // "Subscription"
|
|
326
|
-
description: string; // "Manage your subscription"
|
|
327
|
-
isPremium: boolean; // Premium status
|
|
328
|
-
statusLabel: string; // "Active" or "Free"
|
|
329
|
-
icon: string; // "diamond"
|
|
330
|
-
onPress: () => void; // Open paywall
|
|
331
|
-
}
|
|
332
|
-
```
|
|
333
|
-
|
|
334
|
-
### sectionConfig
|
|
335
|
-
|
|
336
|
-
Detailed section configuration:
|
|
337
|
-
|
|
338
|
-
```typescript
|
|
339
|
-
interface SectionConfig {
|
|
340
|
-
statusType: 'active' | 'expired' | 'free' | 'canceled';
|
|
341
|
-
isPremium: boolean;
|
|
342
|
-
expirationDate: string | null; // "January 15, 2024"
|
|
343
|
-
purchaseDate: string | null; // "January 15, 2023"
|
|
344
|
-
isLifetime: boolean;
|
|
345
|
-
daysRemaining: number | null; // 30
|
|
346
|
-
willRenew: boolean;
|
|
347
|
-
credits: CreditItem[];
|
|
348
|
-
translations: SubscriptionSettingsTranslations;
|
|
349
|
-
onUpgrade: () => void;
|
|
350
|
-
upgradePrompt?: UpgradePromptConfig;
|
|
351
|
-
}
|
|
352
|
-
```
|
|
353
|
-
|
|
354
|
-
## Best Practices
|
|
355
|
-
|
|
356
|
-
1. **Provide all translations** - Ensure all strings are localized
|
|
357
|
-
2. **Handle null values** - Dates may be null for lifetime subs
|
|
358
|
-
3. **Use credit limit** - Limit credit items for better UX
|
|
359
|
-
4. **Customize upgrade prompt** - Tailor to your app's benefits
|
|
360
|
-
5. **Test all states** - Active, expired, free, lifetime
|
|
361
|
-
6. **Handle navigation** - Implement onPress handlers
|
|
362
|
-
7. **Format dates** - Use locale-appropriate formatting
|
|
363
|
-
|
|
364
|
-
## Related Hooks
|
|
365
|
-
|
|
366
|
-
- **useSubscriptionStatus** - For subscription status details
|
|
367
|
-
- **useCredits** - For credits information
|
|
368
|
-
- **useSubscriptionDetails** - For package and pricing info
|
|
369
|
-
|
|
370
|
-
## See Also
|
|
371
|
-
|
|
372
|
-
- [Settings Screen](../screens/README.md#settings)
|
|
373
|
-
- [Subscription Utilities](../utils/subscriptionDateUtils.md)
|
|
374
|
-
- [Config Types](../types/SubscriptionSettingsTypes.md)
|
|
90
|
+
- **useSubscriptionStatus**: For subscription status details
|
|
91
|
+
- **useCredits**: For credits information
|
|
92
|
+
- **useSubscriptionDetails**: For package and pricing info
|
|
93
|
+
- **Settings Screen**: `src/presentation/screens/README.md`
|
|
94
|
+
- **Subscription Utilities**: `src/utils/subscriptionDateUtils.md`
|