@umituz/react-native-subscription 2.14.97 → 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.
- package/LICENSE +21 -0
- package/README.md +462 -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/config/README.md +390 -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 +160 -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/domain/README.md +147 -0
- package/src/revenuecat/domain/errors/README.md +197 -0
- package/src/revenuecat/infrastructure/config/README.md +40 -0
- package/src/revenuecat/infrastructure/managers/README.md +49 -0
- package/src/revenuecat/presentation/hooks/README.md +56 -0
- package/src/utils/README.md +529 -0
|
@@ -0,0 +1,410 @@
|
|
|
1
|
+
# Presentation Layer
|
|
2
|
+
|
|
3
|
+
Abonelik sisteminin UI/UX katmanı - React hooks, components ve screen'ler.
|
|
4
|
+
|
|
5
|
+
## Sorumluluklar
|
|
6
|
+
|
|
7
|
+
- **React Hooks**: State management ve veri erişimi
|
|
8
|
+
- **Components**: UI bileşenleri
|
|
9
|
+
- **Screens**: Tam ekran sayfalar
|
|
10
|
+
- **User Interaction**: Kullanıcı etkileşimlerini yönetme
|
|
11
|
+
|
|
12
|
+
## Yapı
|
|
13
|
+
|
|
14
|
+
```
|
|
15
|
+
presentation/
|
|
16
|
+
├── hooks/ # React hooks
|
|
17
|
+
│ ├── usePremium.ts
|
|
18
|
+
│ ├── useSubscription.ts
|
|
19
|
+
│ ├── useCredits.ts
|
|
20
|
+
│ └── ...
|
|
21
|
+
├── components/ # UI bileşenleri
|
|
22
|
+
│ ├── details/ # Detay kartları, badge'ler
|
|
23
|
+
│ ├── feedback/ # Modal, feedback bileşenleri
|
|
24
|
+
│ └── sections/ # Section bileşenleri
|
|
25
|
+
└── screens/ # Ekranlar
|
|
26
|
+
└── SubscriptionDetailScreen.tsx
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Hooks
|
|
30
|
+
|
|
31
|
+
Tüm hooks `src/presentation/hooks/` dizininde README.md dosyasında detaylı olarak açıklanmıştır.
|
|
32
|
+
|
|
33
|
+
Ana hooks:
|
|
34
|
+
- `usePremium` - Premium durumu
|
|
35
|
+
- `useSubscription` - Abonelik durumu
|
|
36
|
+
- `useCredits` - Kredi bakiyesi
|
|
37
|
+
- `usePremiumGate` - Premium özellik kontrolü
|
|
38
|
+
- `useCreditsGate` - Kredi özellik kontrolü
|
|
39
|
+
- `usePaywall*` - Paywall yönetimi
|
|
40
|
+
|
|
41
|
+
Detaylı bilgi için: [hooks/README.md](./hooks/README.md)
|
|
42
|
+
|
|
43
|
+
## Components
|
|
44
|
+
|
|
45
|
+
### Details Components
|
|
46
|
+
|
|
47
|
+
Detay gösterimi için bileşenler:
|
|
48
|
+
|
|
49
|
+
```
|
|
50
|
+
components/details/
|
|
51
|
+
├── PremiumDetailsCard.tsx # Premium detay kartı
|
|
52
|
+
├── PremiumDetailsCard.styles.ts
|
|
53
|
+
├── PremiumDetailsCardTypes.ts
|
|
54
|
+
├── PremiumStatusBadge.tsx # Durum badge'i
|
|
55
|
+
└── PremiumDetailsCard.styles.ts
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
**PremiumDetailsCard Kullanımı:**
|
|
59
|
+
|
|
60
|
+
```typescript
|
|
61
|
+
import { PremiumDetailsCard } from '@umituz/react-native-subscription';
|
|
62
|
+
|
|
63
|
+
<PremiumDetailsCard
|
|
64
|
+
status={{
|
|
65
|
+
type: 'premium',
|
|
66
|
+
isActive: true,
|
|
67
|
+
expirationDate: '2025-12-31',
|
|
68
|
+
willRenew: true,
|
|
69
|
+
}}
|
|
70
|
+
onUpgradePress={() => console.log('Upgrade pressed')}
|
|
71
|
+
onManagePress={() => console.log('Manage pressed')}
|
|
72
|
+
translations={{
|
|
73
|
+
title: 'Premium',
|
|
74
|
+
status: 'Active',
|
|
75
|
+
expires: 'Expires on',
|
|
76
|
+
renew: 'Renews on',
|
|
77
|
+
}}
|
|
78
|
+
/>
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
**PremiumStatusBadge Kullanımı:**
|
|
82
|
+
|
|
83
|
+
```typescript
|
|
84
|
+
import { PremiumStatusBadge } from '@umituz/react-native-subscription';
|
|
85
|
+
|
|
86
|
+
<PremiumStatusBadge
|
|
87
|
+
status="premium"
|
|
88
|
+
size="medium"
|
|
89
|
+
showIcon={true}
|
|
90
|
+
/>
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### Feedback Components
|
|
94
|
+
|
|
95
|
+
Kullanıcı feedback'i için bileşenler:
|
|
96
|
+
|
|
97
|
+
```
|
|
98
|
+
components/feedback/
|
|
99
|
+
├── PaywallFeedbackModal.tsx # Paywall feedback modal
|
|
100
|
+
├── PaywallFeedbackModal.styles.ts
|
|
101
|
+
└── paywallFeedbackStyles.ts
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
**PaywallFeedbackModal Kullanımı:**
|
|
105
|
+
|
|
106
|
+
```typescript
|
|
107
|
+
import { PaywallFeedbackModal } from '@umituz/react-native-subscription';
|
|
108
|
+
|
|
109
|
+
<PaywallFeedbackModal
|
|
110
|
+
isVisible={showFeedback}
|
|
111
|
+
onClose={() => setShowFeedback(false)}
|
|
112
|
+
onSubmit={(feedback) => {
|
|
113
|
+
console.log('Feedback:', feedback);
|
|
114
|
+
analytics.track('paywall_feedback', feedback);
|
|
115
|
+
}}
|
|
116
|
+
translations={{
|
|
117
|
+
title: 'Tell us why',
|
|
118
|
+
placeholder: 'Share your thoughts...',
|
|
119
|
+
submit: 'Submit',
|
|
120
|
+
}}
|
|
121
|
+
/>
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### Section Components
|
|
125
|
+
|
|
126
|
+
Section bileşenleri:
|
|
127
|
+
|
|
128
|
+
```
|
|
129
|
+
components/sections/
|
|
130
|
+
└── SubscriptionSection.tsx # Abonelik section'ı
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
**SubscriptionSection Kullanımı:**
|
|
134
|
+
|
|
135
|
+
```typescript
|
|
136
|
+
import { SubscriptionSection } from '@umituz/react-native-subscription';
|
|
137
|
+
|
|
138
|
+
<SubscriptionSection
|
|
139
|
+
title="Subscription"
|
|
140
|
+
subscription={subscriptionData}
|
|
141
|
+
onPress={() => navigateToSubscription()}
|
|
142
|
+
translations={{
|
|
143
|
+
manage: 'Manage Subscription',
|
|
144
|
+
upgrade: 'Upgrade to Premium',
|
|
145
|
+
}}
|
|
146
|
+
/>
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
## Screens
|
|
150
|
+
|
|
151
|
+
### SubscriptionDetailScreen
|
|
152
|
+
|
|
153
|
+
Abonelik detay ekranı:
|
|
154
|
+
|
|
155
|
+
```typescript
|
|
156
|
+
import { SubscriptionDetailScreen } from '@umituz/react-native-subscription';
|
|
157
|
+
|
|
158
|
+
function App() {
|
|
159
|
+
return (
|
|
160
|
+
<Stack.Screen
|
|
161
|
+
name="SubscriptionDetail"
|
|
162
|
+
component={SubscriptionDetailScreen}
|
|
163
|
+
options={{
|
|
164
|
+
title: 'Subscription',
|
|
165
|
+
}}
|
|
166
|
+
/>
|
|
167
|
+
);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// Veya doğrudan kullanım
|
|
171
|
+
<SubscriptionDetailScreen
|
|
172
|
+
route={{
|
|
173
|
+
key: 'subscription',
|
|
174
|
+
name: 'SubscriptionDetail',
|
|
175
|
+
params: { userId: 'user-123' },
|
|
176
|
+
}}
|
|
177
|
+
navigation={navigation}
|
|
178
|
+
/>
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
## Tip Tanımlamaları
|
|
182
|
+
|
|
183
|
+
### Component Props
|
|
184
|
+
|
|
185
|
+
```typescript
|
|
186
|
+
// PremiumDetailsCard
|
|
187
|
+
interface PremiumDetailsCardProps {
|
|
188
|
+
status: SubscriptionStatus;
|
|
189
|
+
onUpgradePress?: () => void;
|
|
190
|
+
onManagePress?: () => void;
|
|
191
|
+
style?: ViewStyle;
|
|
192
|
+
translations?: PremiumDetailsCardTranslations;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// PremiumStatusBadge
|
|
196
|
+
interface PremiumStatusBadgeProps {
|
|
197
|
+
status: SubscriptionStatusType;
|
|
198
|
+
size?: 'small' | 'medium' | 'large';
|
|
199
|
+
showIcon?: boolean;
|
|
200
|
+
style?: ViewStyle;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// PaywallFeedbackModal
|
|
204
|
+
interface PaywallFeedbackModalProps {
|
|
205
|
+
isVisible: boolean;
|
|
206
|
+
onClose: () => void;
|
|
207
|
+
onSubmit: (feedback: string) => void;
|
|
208
|
+
translations?: PaywallFeedbackTranslations;
|
|
209
|
+
}
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
## Styling
|
|
213
|
+
|
|
214
|
+
Component stilleri StyleSheet ile tanımlanır:
|
|
215
|
+
|
|
216
|
+
```typescript
|
|
217
|
+
import { premiumDetailsCardStyles } from '@umituz/react-native-subscription';
|
|
218
|
+
|
|
219
|
+
// Özel stil override
|
|
220
|
+
<PremiumDetailsCard
|
|
221
|
+
style={customStyles.card}
|
|
222
|
+
status={status}
|
|
223
|
+
/>
|
|
224
|
+
|
|
225
|
+
const customStyles = StyleSheet.create({
|
|
226
|
+
card: {
|
|
227
|
+
backgroundColor: 'custom-background',
|
|
228
|
+
borderRadius: 16,
|
|
229
|
+
padding: 20,
|
|
230
|
+
},
|
|
231
|
+
});
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
## Translations
|
|
235
|
+
|
|
236
|
+
Tüm component'ler translations desteği sunar:
|
|
237
|
+
|
|
238
|
+
```typescript
|
|
239
|
+
const translations = {
|
|
240
|
+
// PremiumDetailsCard
|
|
241
|
+
title: 'Premium',
|
|
242
|
+
active: 'Active',
|
|
243
|
+
expires: 'Expires on',
|
|
244
|
+
renews: 'Renews on',
|
|
245
|
+
manage: 'Manage Subscription',
|
|
246
|
+
upgrade: 'Upgrade to Premium',
|
|
247
|
+
|
|
248
|
+
// PaywallFeedbackModal
|
|
249
|
+
feedbackTitle: 'Tell us why',
|
|
250
|
+
feedbackPlaceholder: 'Share your thoughts...',
|
|
251
|
+
submit: 'Submit',
|
|
252
|
+
cancel: 'Cancel',
|
|
253
|
+
};
|
|
254
|
+
|
|
255
|
+
<PremiumDetailsCard translations={translations} status={status} />
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
## Theming
|
|
259
|
+
|
|
260
|
+
Component'leri özelleştirin:
|
|
261
|
+
|
|
262
|
+
```typescript
|
|
263
|
+
import { ThemeProvider } from '@umituz/react-native-subscription';
|
|
264
|
+
|
|
265
|
+
const customTheme = {
|
|
266
|
+
colors: {
|
|
267
|
+
primary: '#FF6B6B',
|
|
268
|
+
success: '#4CAF50',
|
|
269
|
+
warning: '#FF9800',
|
|
270
|
+
error: '#F44336',
|
|
271
|
+
background: '#FFFFFF',
|
|
272
|
+
text: '#000000',
|
|
273
|
+
},
|
|
274
|
+
fonts: {
|
|
275
|
+
title: { fontSize: 24, fontWeight: 'bold' },
|
|
276
|
+
body: { fontSize: 16, fontWeight: 'normal' },
|
|
277
|
+
},
|
|
278
|
+
spacing: {
|
|
279
|
+
small: 8,
|
|
280
|
+
medium: 16,
|
|
281
|
+
large: 24,
|
|
282
|
+
},
|
|
283
|
+
};
|
|
284
|
+
|
|
285
|
+
<ThemeProvider theme={customTheme}>
|
|
286
|
+
<YourApp />
|
|
287
|
+
</ThemeProvider>
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
## Best Practices
|
|
291
|
+
|
|
292
|
+
1. **Props Validation**: PropTypes veya TypeScript kullanın
|
|
293
|
+
2. **Styling**: Inline style yerine StyleSheet kullanın
|
|
294
|
+
3. **Translations**: Her zaman translation prop'u sağlayın
|
|
295
|
+
4. **Loading States**: Yüklenme durumlarını gösterin
|
|
296
|
+
5. **Error Handling**: Hataları kullanıcı dostu gösterin
|
|
297
|
+
6. **Accessibility**: Accessibility özelliklerini ekleyin
|
|
298
|
+
7. **Performance**: React.memo ve useMemo kullanın
|
|
299
|
+
|
|
300
|
+
## Örnek: Premium Feature Card
|
|
301
|
+
|
|
302
|
+
```typescript
|
|
303
|
+
import React from 'react';
|
|
304
|
+
import { View, Text, StyleSheet } from 'react-native';
|
|
305
|
+
import { PremiumDetailsCard, usePremium } from '@umituz/react-native-subscription';
|
|
306
|
+
|
|
307
|
+
function PremiumFeatureCard() {
|
|
308
|
+
const { isPremium, subscription } = usePremium();
|
|
309
|
+
|
|
310
|
+
if (!isPremium) {
|
|
311
|
+
return (
|
|
312
|
+
<View style={styles.locked}>
|
|
313
|
+
<Text>🔒 Premium Feature</Text>
|
|
314
|
+
<PremiumDetailsCard
|
|
315
|
+
status={{
|
|
316
|
+
type: 'free',
|
|
317
|
+
isActive: false,
|
|
318
|
+
isPremium: false,
|
|
319
|
+
}}
|
|
320
|
+
onUpgradePress={showPaywall}
|
|
321
|
+
translations={{
|
|
322
|
+
title: 'Upgrade Required',
|
|
323
|
+
upgrade: 'Go Premium',
|
|
324
|
+
}}
|
|
325
|
+
/>
|
|
326
|
+
</View>
|
|
327
|
+
);
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
return (
|
|
331
|
+
<PremiumDetailsCard
|
|
332
|
+
status={subscription}
|
|
333
|
+
onManagePress={navigateToManage}
|
|
334
|
+
translations={{
|
|
335
|
+
title: 'Premium Active',
|
|
336
|
+
manage: 'Manage',
|
|
337
|
+
}}
|
|
338
|
+
/>
|
|
339
|
+
);
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
const styles = StyleSheet.create({
|
|
343
|
+
locked: {
|
|
344
|
+
padding: 16,
|
|
345
|
+
backgroundColor: '#F5F5F5',
|
|
346
|
+
borderRadius: 12,
|
|
347
|
+
},
|
|
348
|
+
});
|
|
349
|
+
|
|
350
|
+
export default PremiumFeatureCard;
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
## Örnek: Full Screen Implementation
|
|
354
|
+
|
|
355
|
+
```typescript
|
|
356
|
+
import React from 'react';
|
|
357
|
+
import { View, ScrollView, ActivityIndicator } from 'react-native';
|
|
358
|
+
import {
|
|
359
|
+
SubscriptionDetailScreen,
|
|
360
|
+
useSubscription,
|
|
361
|
+
usePremium,
|
|
362
|
+
} from '@umituz/react-native-subscription';
|
|
363
|
+
|
|
364
|
+
function MySubscriptionScreen() {
|
|
365
|
+
const { subscription, isLoading } = useSubscription();
|
|
366
|
+
const { isPremium } = usePremium();
|
|
367
|
+
|
|
368
|
+
if (isLoading) {
|
|
369
|
+
return <ActivityIndicator />;
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
return (
|
|
373
|
+
<ScrollView>
|
|
374
|
+
<SubscriptionDetailScreen
|
|
375
|
+
route={{
|
|
376
|
+
key: 'subscription',
|
|
377
|
+
name: 'SubscriptionDetail',
|
|
378
|
+
params: {},
|
|
379
|
+
}}
|
|
380
|
+
navigation={navigation}
|
|
381
|
+
/>
|
|
382
|
+
|
|
383
|
+
{!isPremium && (
|
|
384
|
+
<UpgradePrompt
|
|
385
|
+
onPress={() => navigation.navigate('Paywall')}
|
|
386
|
+
/>
|
|
387
|
+
)}
|
|
388
|
+
</ScrollView>
|
|
389
|
+
);
|
|
390
|
+
}
|
|
391
|
+
```
|
|
392
|
+
|
|
393
|
+
## Component Library
|
|
394
|
+
|
|
395
|
+
Tüm component'leri export edin:
|
|
396
|
+
|
|
397
|
+
```typescript
|
|
398
|
+
// components/index.ts
|
|
399
|
+
export * from './details';
|
|
400
|
+
export * from './feedback';
|
|
401
|
+
export * from './sections';
|
|
402
|
+
|
|
403
|
+
// Kullanım
|
|
404
|
+
import {
|
|
405
|
+
PremiumDetailsCard,
|
|
406
|
+
PremiumStatusBadge,
|
|
407
|
+
PaywallFeedbackModal,
|
|
408
|
+
SubscriptionSection,
|
|
409
|
+
} from '@umituz/react-native-subscription';
|
|
410
|
+
```
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
# Presentation Components
|
|
2
|
+
|
|
3
|
+
React Native UI components for subscription and paywall features.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
This directory contains reusable UI components built with `@umituz/react-native-design-system`. All components are generic and app-agnostic, requiring configuration props for app-specific behavior.
|
|
8
|
+
|
|
9
|
+
## Component Structure
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
presentation/components/
|
|
13
|
+
├── details/ # Subscription detail components
|
|
14
|
+
│ ├── PremiumDetailsCard.md
|
|
15
|
+
│ ├── PremiumStatusBadge.md
|
|
16
|
+
│ ├── DetailRow.md
|
|
17
|
+
│ └── CreditRow.md
|
|
18
|
+
├── sections/ # Section components for settings
|
|
19
|
+
│ └── SubscriptionSection.md
|
|
20
|
+
└── feedback/ # User feedback components
|
|
21
|
+
└── PaywallFeedbackModal.md
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Components
|
|
25
|
+
|
|
26
|
+
### Detail Components
|
|
27
|
+
|
|
28
|
+
#### [PremiumDetailsCard](./details/PremiumDetailsCard.md)
|
|
29
|
+
Complete card displaying subscription details, status, and credits.
|
|
30
|
+
|
|
31
|
+
```typescript
|
|
32
|
+
<PremiumDetailsCard
|
|
33
|
+
statusType="active"
|
|
34
|
+
isPremium={true}
|
|
35
|
+
expirationDate="January 15, 2025"
|
|
36
|
+
purchaseDate="January 15, 2024"
|
|
37
|
+
credits={[{ id: 'monthly', label: 'Credits', current: 50, total: 100 }]}
|
|
38
|
+
translations={translations}
|
|
39
|
+
onManageSubscription={handleManage}
|
|
40
|
+
onUpgrade={handleUpgrade}
|
|
41
|
+
/>
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
#### [PremiumStatusBadge](./details/PremiumStatusBadge.md)
|
|
45
|
+
Colored badge showing subscription status.
|
|
46
|
+
|
|
47
|
+
```typescript
|
|
48
|
+
<PremiumStatusBadge
|
|
49
|
+
status="active"
|
|
50
|
+
activeLabel="Active"
|
|
51
|
+
expiredLabel="Expired"
|
|
52
|
+
noneLabel="Free"
|
|
53
|
+
canceledLabel="Canceled"
|
|
54
|
+
/>
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
#### [DetailRow](./details/DetailRow.md)
|
|
58
|
+
Simple label-value row for displaying subscription details.
|
|
59
|
+
|
|
60
|
+
```typescript
|
|
61
|
+
<DetailRow
|
|
62
|
+
label="Expires"
|
|
63
|
+
value="January 15, 2025"
|
|
64
|
+
highlight={true}
|
|
65
|
+
/>
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
#### [CreditRow](./details/CreditRow.md)
|
|
69
|
+
Credit display with progress bar and color-coded thresholds.
|
|
70
|
+
|
|
71
|
+
```typescript
|
|
72
|
+
<CreditRow
|
|
73
|
+
label="Monthly Credits"
|
|
74
|
+
current={50}
|
|
75
|
+
total={100}
|
|
76
|
+
remainingLabel="credits remaining"
|
|
77
|
+
/>
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### Section Components
|
|
81
|
+
|
|
82
|
+
#### [SubscriptionSection](./sections/SubscriptionSection.md)
|
|
83
|
+
Settings section component with subscription details.
|
|
84
|
+
|
|
85
|
+
```typescript
|
|
86
|
+
<SubscriptionSection
|
|
87
|
+
config={subscriptionConfig}
|
|
88
|
+
onPress={() => navigation.navigate('SubscriptionDetails')}
|
|
89
|
+
/>
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### Feedback Components
|
|
93
|
+
|
|
94
|
+
#### [PaywallFeedbackModal](./feedback/PaywallFeedbackModal.md)
|
|
95
|
+
Modal for collecting user feedback on paywall decline.
|
|
96
|
+
|
|
97
|
+
```typescript
|
|
98
|
+
<PaywallFeedbackModal
|
|
99
|
+
visible={showFeedback}
|
|
100
|
+
onClose={() => setShowFeedback(false)}
|
|
101
|
+
onSubmit={(reason) => trackFeedback(reason)}
|
|
102
|
+
/>
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## Usage Patterns
|
|
106
|
+
|
|
107
|
+
### In Settings Screen
|
|
108
|
+
|
|
109
|
+
```typescript
|
|
110
|
+
function SettingsScreen() {
|
|
111
|
+
const config = useSubscriptionSettingsConfig({
|
|
112
|
+
userId: user?.uid,
|
|
113
|
+
translations: englishTranslations,
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
return (
|
|
117
|
+
<ScrollView>
|
|
118
|
+
<SubscriptionSection
|
|
119
|
+
config={config.sectionConfig}
|
|
120
|
+
onPress={() => navigation.navigate('SubscriptionDetails')}
|
|
121
|
+
/>
|
|
122
|
+
</ScrollView>
|
|
123
|
+
);
|
|
124
|
+
}
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### In Paywall Screen
|
|
128
|
+
|
|
129
|
+
```typescript
|
|
130
|
+
function PaywallScreen() {
|
|
131
|
+
const [showFeedback, setShowFeedback] = useState(false);
|
|
132
|
+
|
|
133
|
+
return (
|
|
134
|
+
<View>
|
|
135
|
+
<PaywallContent onClose={() => setShowFeedback(true)} />
|
|
136
|
+
|
|
137
|
+
<PaywallFeedbackModal
|
|
138
|
+
visible={showFeedback}
|
|
139
|
+
onClose={() => setShowFeedback(false)}
|
|
140
|
+
onSubmit={handleSubmitFeedback}
|
|
141
|
+
/>
|
|
142
|
+
</View>
|
|
143
|
+
);
|
|
144
|
+
}
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
## Design System Integration
|
|
148
|
+
|
|
149
|
+
All components use `@umituz/react-native-design-system` for:
|
|
150
|
+
|
|
151
|
+
- **Tokens**: `useAppDesignTokens()` for colors, spacing, radius
|
|
152
|
+
- **Typography**: `AtomicText` for consistent text styling
|
|
153
|
+
- **Theming**: Automatic dark mode support via design tokens
|
|
154
|
+
|
|
155
|
+
## Styling Customization
|
|
156
|
+
|
|
157
|
+
Components accept style overrides:
|
|
158
|
+
|
|
159
|
+
```typescript
|
|
160
|
+
<PremiumDetailsCard
|
|
161
|
+
translations={translations}
|
|
162
|
+
containerStyle={{
|
|
163
|
+
marginHorizontal: 16,
|
|
164
|
+
borderRadius: 12,
|
|
165
|
+
}}
|
|
166
|
+
/>
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
## Best Practices
|
|
170
|
+
|
|
171
|
+
1. **Use design tokens** - Leverage `useAppDesignTokens()` for consistency
|
|
172
|
+
2. **Provide translations** - Ensure all text is localized
|
|
173
|
+
3. **Handle all states** - Test premium, free, expired, canceled states
|
|
174
|
+
4. **Test edge cases** - Zero credits, max credits, long text
|
|
175
|
+
5. **Match design system** - Follow app's design language
|
|
176
|
+
6. **Accessibility** - Ensure proper contrast and touch targets
|
|
177
|
+
7. **Performance** - Memoize where appropriate
|
|
178
|
+
|
|
179
|
+
## Related
|
|
180
|
+
|
|
181
|
+
- [Hooks](../hooks/README.md)
|
|
182
|
+
- [Screens](../screens/README.md)
|
|
183
|
+
- [Design System](https://github.com/umituz/react-native-design-system)
|