@umituz/react-native-subscription 2.14.98 → 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 -395
- 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 +52 -0
- package/src/domains/README.md.bak +274 -0
- package/src/domains/config/README.md +93 -383
- package/src/domains/config/domain/README.md +37 -0
- package/src/domains/config/domain/entities/README.md +41 -0
- 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 +96 -156
- 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 +43 -0
- package/src/revenuecat/application/ports/README.md +41 -0
- package/src/revenuecat/domain/README.md +42 -141
- package/src/revenuecat/domain/constants/README.md +41 -0
- package/src/revenuecat/domain/entities/README.md +42 -0
- package/src/revenuecat/domain/errors/README.md +47 -191
- package/src/revenuecat/domain/types/README.md +41 -0
- package/src/revenuecat/domain/value-objects/README.md +41 -0
- package/src/revenuecat/infrastructure/README.md +41 -0
- package/src/revenuecat/infrastructure/config/README.md +32 -23
- package/src/revenuecat/infrastructure/handlers/README.md +41 -0
- package/src/revenuecat/infrastructure/managers/README.md +34 -42
- package/src/revenuecat/infrastructure/services/README.md +42 -0
- package/src/revenuecat/infrastructure/utils/README.md +41 -0
- package/src/revenuecat/presentation/README.md +42 -0
- package/src/revenuecat/presentation/hooks/README.md +29 -35
- package/src/utils/README.md +38 -525
|
@@ -1,410 +1,125 @@
|
|
|
1
1
|
# Presentation Layer
|
|
2
2
|
|
|
3
|
-
|
|
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
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
components
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
**
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
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
|
-
```
|
|
3
|
+
UI/UX layer for the subscription system - React hooks, components, and screens.
|
|
4
|
+
|
|
5
|
+
## Location
|
|
6
|
+
|
|
7
|
+
**Directory**: `src/presentation/`
|
|
8
|
+
|
|
9
|
+
**Type**: Layer
|
|
10
|
+
|
|
11
|
+
## Strategy
|
|
12
|
+
|
|
13
|
+
### Layer Responsibilities
|
|
14
|
+
|
|
15
|
+
The Presentation Layer is responsible for:
|
|
16
|
+
|
|
17
|
+
1. **State Management**
|
|
18
|
+
- React hooks for data fetching and mutations
|
|
19
|
+
- TanStack Query for server state management
|
|
20
|
+
- Local state management for UI state
|
|
21
|
+
|
|
22
|
+
2. **UI Components**
|
|
23
|
+
- Reusable subscription components
|
|
24
|
+
- Feature gating UI elements
|
|
25
|
+
- Credit display components
|
|
26
|
+
- Paywall components
|
|
27
|
+
|
|
28
|
+
3. **User Interaction**
|
|
29
|
+
- Handle user actions
|
|
30
|
+
- Display appropriate feedback
|
|
31
|
+
- Guide users through purchase flows
|
|
32
|
+
- Show upgrade prompts at right time
|
|
33
|
+
|
|
34
|
+
### Architecture Pattern
|
|
35
|
+
|
|
36
|
+
The presentation layer follows a layered architecture where:
|
|
37
|
+
- Hooks manage state and data fetching at the top level
|
|
38
|
+
- Components consume hooks and render UI
|
|
39
|
+
- Screens compose multiple components together
|
|
40
|
+
- All layers communicate with the domain layer for business logic
|
|
41
|
+
|
|
42
|
+
### Integration Points
|
|
43
|
+
|
|
44
|
+
- **Domain Layer**: Business logic and data access
|
|
45
|
+
- **TanStack Query**: Server state management
|
|
46
|
+
- **RevenueCat**: Purchase operations
|
|
47
|
+
- **Navigation**: Screen routing
|
|
48
|
+
|
|
49
|
+
## Restrictions
|
|
50
|
+
|
|
51
|
+
### REQUIRED
|
|
52
|
+
|
|
53
|
+
- **Type Safety**: All components MUST be typed with TypeScript
|
|
54
|
+
- **Error Boundaries**: MUST implement error boundaries for all screens
|
|
55
|
+
- **Loading States**: MUST show loading indicators during async operations
|
|
56
|
+
- **User Feedback**: MUST provide feedback for all user actions
|
|
57
|
+
|
|
58
|
+
### PROHIBITED
|
|
59
|
+
|
|
60
|
+
- **NEVER** include business logic in components (use hooks instead)
|
|
61
|
+
- **NEVER** make direct API calls from components (use hooks)
|
|
62
|
+
- **DO NOT** store sensitive data in component state
|
|
63
|
+
- **NEVER** hardcode strings (use localization)
|
|
64
|
+
|
|
65
|
+
### CRITICAL SAFETY
|
|
66
|
+
|
|
67
|
+
- **ALWAYS** validate props before rendering
|
|
68
|
+
- **ALWAYS** handle loading and error states
|
|
69
|
+
- **NEVER** trust client-side state for security decisions
|
|
70
|
+
- **MUST** implement proper error boundaries
|
|
71
|
+
- **ALWAYS** sanitize user inputs before display
|
|
72
|
+
|
|
73
|
+
## AI Agent Guidelines
|
|
74
|
+
|
|
75
|
+
### When Building Presentation Layer
|
|
76
|
+
|
|
77
|
+
1. **Always** use hooks for data fetching and state management
|
|
78
|
+
2. **Always** handle loading and error states
|
|
79
|
+
3. **Always** provide user feedback for actions
|
|
80
|
+
4. **Always** implement error boundaries
|
|
81
|
+
5. **Never** include business logic in components
|
|
82
|
+
|
|
83
|
+
### Integration Checklist
|
|
84
|
+
|
|
85
|
+
- [ ] Use appropriate hooks for data access
|
|
86
|
+
- [ ] Handle loading states
|
|
87
|
+
- [ ] Handle error states
|
|
88
|
+
- [ ] Implement error boundaries
|
|
89
|
+
- [ ] Provide user feedback
|
|
90
|
+
- [ ] Test with various data states
|
|
91
|
+
- [ ] Test error scenarios
|
|
92
|
+
- [ ] Ensure type safety
|
|
93
|
+
- [ ] Use localization for all strings
|
|
94
|
+
- [ ] Test accessibility
|
|
95
|
+
|
|
96
|
+
### Common Patterns
|
|
97
|
+
|
|
98
|
+
1. **Compound Components**: Build complex UIs from simple components
|
|
99
|
+
2. **Render Props**: Share stateful logic between components
|
|
100
|
+
3. **Custom Hooks**: Extract reusable stateful logic
|
|
101
|
+
4. **Error Boundaries**: Prevent crashes from propagating
|
|
102
|
+
5. **Loading Skeletons**: Show placeholder during loading
|
|
103
|
+
6. **Optimistic Updates**: Update UI immediately, rollback on failure
|
|
104
|
+
7. **Graceful Degradation**: Show limited version on error
|
|
105
|
+
8. **Responsive Design**: Support different screen sizes
|
|
106
|
+
|
|
107
|
+
## Related Documentation
|
|
108
|
+
|
|
109
|
+
- **Hooks**: `hooks/README.md`
|
|
110
|
+
- **Components**: `components/README.md`
|
|
111
|
+
- **Screens**: `screens/README.md`
|
|
112
|
+
- **Wallet Domain**: `../../domains/wallet/README.md`
|
|
113
|
+
- **Paywall Domain**: `../../domains/paywall/README.md`
|
|
114
|
+
- **RevenueCat**: `../../revenuecat/README.md`
|
|
115
|
+
|
|
116
|
+
## Directory Structure
|
|
117
|
+
|
|
118
|
+
The presentation layer contains:
|
|
119
|
+
- **hooks/** - React hooks for state management (usePremium, useSubscription, useCredits, useDeductCredit, useFeatureGate)
|
|
120
|
+
- **components/** - UI components organized by functionality
|
|
121
|
+
- **details/** - Detail cards, badges
|
|
122
|
+
- **feedback/** - Modals, feedback components
|
|
123
|
+
- **sections/** - Section components
|
|
124
|
+
- **paywall/** - Paywall components
|
|
125
|
+
- **screens/** - Full-screen components (SubscriptionDetailScreen)
|