@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.
Files changed (76) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +462 -0
  3. package/package.json +1 -3
  4. package/src/application/README.md +229 -0
  5. package/src/application/ports/README.md +103 -0
  6. package/src/domain/README.md +402 -0
  7. package/src/domain/constants/README.md +80 -0
  8. package/src/domain/entities/README.md +176 -0
  9. package/src/domain/errors/README.md +307 -0
  10. package/src/domain/value-objects/README.md +186 -0
  11. package/src/domains/config/README.md +390 -0
  12. package/src/domains/paywall/README.md +371 -0
  13. package/src/domains/paywall/components/PaywallHeader.tsx +8 -11
  14. package/src/domains/paywall/components/README.md +185 -0
  15. package/src/domains/paywall/entities/README.md +199 -0
  16. package/src/domains/paywall/hooks/README.md +129 -0
  17. package/src/domains/wallet/README.md +292 -0
  18. package/src/domains/wallet/domain/README.md +108 -0
  19. package/src/domains/wallet/domain/entities/README.md +122 -0
  20. package/src/domains/wallet/domain/errors/README.md +157 -0
  21. package/src/domains/wallet/infrastructure/README.md +96 -0
  22. package/src/domains/wallet/presentation/components/BalanceCard.tsx +6 -12
  23. package/src/domains/wallet/presentation/components/README.md +231 -0
  24. package/src/domains/wallet/presentation/hooks/README.md +255 -0
  25. package/src/infrastructure/README.md +514 -0
  26. package/src/infrastructure/mappers/README.md +34 -0
  27. package/src/infrastructure/models/README.md +26 -0
  28. package/src/infrastructure/repositories/README.md +385 -0
  29. package/src/infrastructure/services/README.md +374 -0
  30. package/src/presentation/README.md +410 -0
  31. package/src/presentation/components/README.md +183 -0
  32. package/src/presentation/components/details/CreditRow.md +337 -0
  33. package/src/presentation/components/details/DetailRow.md +283 -0
  34. package/src/presentation/components/details/PremiumDetailsCard.md +266 -0
  35. package/src/presentation/components/details/PremiumStatusBadge.md +266 -0
  36. package/src/presentation/components/details/README.md +449 -0
  37. package/src/presentation/components/feedback/PaywallFeedbackModal.md +314 -0
  38. package/src/presentation/components/feedback/README.md +447 -0
  39. package/src/presentation/components/paywall/PaywallModal.md +444 -0
  40. package/src/presentation/components/paywall/README.md +190 -0
  41. package/src/presentation/components/sections/README.md +468 -0
  42. package/src/presentation/components/sections/SubscriptionSection.md +246 -0
  43. package/src/presentation/hooks/README.md +743 -0
  44. package/src/presentation/hooks/useAuthAwarePurchase.md +359 -0
  45. package/src/presentation/hooks/useAuthGate.md +403 -0
  46. package/src/presentation/hooks/useAuthSubscriptionSync.md +398 -0
  47. package/src/presentation/hooks/useCreditChecker.md +407 -0
  48. package/src/presentation/hooks/useCredits.md +342 -0
  49. package/src/presentation/hooks/useCreditsGate.md +346 -0
  50. package/src/presentation/hooks/useDeductCredit.md +160 -0
  51. package/src/presentation/hooks/useDevTestCallbacks.md +422 -0
  52. package/src/presentation/hooks/useFeatureGate.md +157 -0
  53. package/src/presentation/hooks/useInitializeCredits.md +458 -0
  54. package/src/presentation/hooks/usePaywall.md +334 -0
  55. package/src/presentation/hooks/usePaywallOperations.md +486 -0
  56. package/src/presentation/hooks/usePaywallVisibility.md +344 -0
  57. package/src/presentation/hooks/usePremium.md +230 -0
  58. package/src/presentation/hooks/usePremiumGate.md +423 -0
  59. package/src/presentation/hooks/usePremiumWithCredits.md +429 -0
  60. package/src/presentation/hooks/useSubscription.md +450 -0
  61. package/src/presentation/hooks/useSubscriptionDetails.md +438 -0
  62. package/src/presentation/hooks/useSubscriptionGate.md +168 -0
  63. package/src/presentation/hooks/useSubscriptionSettingsConfig.md +374 -0
  64. package/src/presentation/hooks/useSubscriptionStatus.md +424 -0
  65. package/src/presentation/hooks/useUserTier.md +356 -0
  66. package/src/presentation/hooks/useUserTierWithRepository.md +452 -0
  67. package/src/presentation/screens/README.md +194 -0
  68. package/src/presentation/types/README.md +38 -0
  69. package/src/presentation/utils/README.md +52 -0
  70. package/src/revenuecat/README.md +523 -0
  71. package/src/revenuecat/domain/README.md +147 -0
  72. package/src/revenuecat/domain/errors/README.md +197 -0
  73. package/src/revenuecat/infrastructure/config/README.md +40 -0
  74. package/src/revenuecat/infrastructure/managers/README.md +49 -0
  75. package/src/revenuecat/presentation/hooks/README.md +56 -0
  76. package/src/utils/README.md +529 -0
@@ -0,0 +1,122 @@
1
+ # Wallet Domain Entities
2
+
3
+ Core entities for credits and transaction management.
4
+
5
+ ## Overview
6
+
7
+ This directory contains domain entities representing credits, transactions, and wallet-related business concepts.
8
+
9
+ ## Entities
10
+
11
+ ### UserCredits
12
+ Represents user's credit balance and metadata.
13
+
14
+ ```typescript
15
+ interface UserCredits {
16
+ credits: number; // Current credit balance
17
+ purchasedAt: Date; // When credits were purchased
18
+ lastUpdatedAt: Date; // Last update timestamp
19
+ }
20
+
21
+ interface CreditsResult {
22
+ success: boolean;
23
+ data?: UserCredits;
24
+ error?: {
25
+ code: string;
26
+ message: string;
27
+ };
28
+ duplicate?: boolean; // If this was a duplicate operation
29
+ }
30
+ ```
31
+
32
+ **Usage:**
33
+ ```typescript
34
+ const credits: UserCredits = {
35
+ credits: 100,
36
+ purchasedAt: new Date('2024-01-01'),
37
+ lastUpdatedAt: new Date('2024-01-15'),
38
+ };
39
+ ```
40
+
41
+ ### Transaction
42
+ Represents a credit transaction record.
43
+
44
+ ```typescript
45
+ interface Transaction {
46
+ id: string;
47
+ amount: number; // Positive for additions, negative for deductions
48
+ reason: string; // Description of transaction
49
+ timestamp: Date; // When transaction occurred
50
+ type: TransactionType; // Transaction category
51
+ }
52
+
53
+ type TransactionType =
54
+ | 'purchase' // Initial purchase
55
+ | 'deduction' // Feature usage
56
+ | 'bonus' // Bonus credits
57
+ | 'renewal' // Subscription renewal
58
+ | 'adjustment'; // Manual adjustment
59
+ ```
60
+
61
+ **Usage:**
62
+ ```typescript
63
+ const transaction: Transaction = {
64
+ id: 'tx_123',
65
+ amount: -5,
66
+ reason: 'ai_generation',
67
+ timestamp: new Date(),
68
+ type: 'deduction',
69
+ };
70
+ ```
71
+
72
+ ### CreditPackage
73
+ Represents a credit package for purchase.
74
+
75
+ ```typescript
76
+ interface CreditPackage {
77
+ id: string;
78
+ amount: number; // Number of credits
79
+ price: number; // Price in currency units
80
+ currency: string; // Currency code (USD, EUR, etc.)
81
+ description?: string;
82
+ }
83
+ ```
84
+
85
+ ## Key Operations
86
+
87
+ ### Check Balance
88
+ ```typescript
89
+ function hasEnoughCredits(credits: UserCredits, required: number): boolean {
90
+ return credits.credits >= required;
91
+ }
92
+ ```
93
+
94
+ ### Calculate Remaining
95
+ ```typescript
96
+ function calculateRemaining(credits: UserCredits, spent: number): number {
97
+ return Math.max(0, credits.credits - spent);
98
+ }
99
+ ```
100
+
101
+ ### Validate Credits
102
+ ```typescript
103
+ function validateCredits(amount: number): void {
104
+ if (amount < 0) {
105
+ throw new Error('Credits cannot be negative');
106
+ }
107
+ }
108
+ ```
109
+
110
+ ## Best Practices
111
+
112
+ 1. **Immutability**: Treat entities as immutable values
113
+ 2. **Validation**: Validate in entity methods
114
+ 3. **Type Safety**: Use strict TypeScript types
115
+ 4. **Business Rules**: Keep business logic in entities
116
+ 5. **Serialization**: Handle date serialization properly
117
+
118
+ ## Related
119
+
120
+ - [Wallet Domain](../README.md)
121
+ - [Credits Repository](../../infrastructure/repositories/README.md)
122
+ - [useCredits Hook](../../../../presentation/hooks/useCredits.md)
@@ -0,0 +1,157 @@
1
+ # Wallet Domain Errors
2
+
3
+ Domain-specific errors for wallet and credit operations.
4
+
5
+ ## Overview
6
+
7
+ This directory contains custom error classes representing wallet-related error conditions.
8
+
9
+ ## Error Types
10
+
11
+ ### CreditsExhaustedError
12
+ Thrown when user doesn't have enough credits for an operation.
13
+
14
+ ```typescript
15
+ class CreditsExhaustedError extends Error {
16
+ constructor(
17
+ public currentBalance: number,
18
+ public required: number
19
+ ) {
20
+ super(
21
+ `Insufficient credits: ${currentBalance}/${required} required`,
22
+ 'CREDITS_EXHAUSTED'
23
+ );
24
+ this.name = 'CreditsExhaustedError';
25
+ }
26
+ }
27
+ ```
28
+
29
+ **Usage:**
30
+ ```typescript
31
+ import { CreditsExhaustedError } from './errors/CreditsExhaustedError';
32
+
33
+ function deductCredits(credits: UserCredits, amount: number) {
34
+ if (credits.credits < amount) {
35
+ throw new CreditsExhaustedError(credits.credits, amount);
36
+ }
37
+ // Proceed with deduction
38
+ }
39
+ ```
40
+
41
+ ### DuplicatePurchaseError
42
+ Thrown when attempting to add credits for a duplicate purchase ID.
43
+
44
+ ```typescript
45
+ class DuplicatePurchaseError extends Error {
46
+ constructor(
47
+ public purchaseId: string,
48
+ public existingCredits: UserCredits
49
+ ) {
50
+ super(
51
+ `Duplicate purchase ID: ${purchaseId}`,
52
+ 'DUPLICATE_PURCHASE'
53
+ );
54
+ this.name = 'DuplicatePurchaseError';
55
+ }
56
+ }
57
+ ```
58
+
59
+ **Usage:**
60
+ ```typescript
61
+ try {
62
+ await repository.initializeCredits(userId, purchaseId);
63
+ } catch (error) {
64
+ if (error instanceof DuplicatePurchaseError) {
65
+ console.log('Credits already added for this purchase');
66
+ }
67
+ }
68
+ ```
69
+
70
+ ### CreditsValidationError
71
+ Thrown when credit validation fails.
72
+
73
+ ```typescript
74
+ class CreditsValidationError extends Error {
75
+ constructor(
76
+ message: string,
77
+ public code: string
78
+ ) {
79
+ super(message, code);
80
+ this.name = 'CreditsValidationError';
81
+ }
82
+ }
83
+ ```
84
+
85
+ **Usage:**
86
+ ```typescript
87
+ function validateCreditAmount(amount: number) {
88
+ if (amount < 0) {
89
+ throw new CreditsValidationError(
90
+ 'Credit amount cannot be negative',
91
+ 'INVALID_AMOUNT'
92
+ );
93
+ }
94
+ if (amount > 10000) {
95
+ throw new CreditsValidationError(
96
+ 'Credit amount exceeds maximum',
97
+ 'EXCEEDS_MAXIMUM'
98
+ );
99
+ }
100
+ }
101
+ ```
102
+
103
+ ## Error Handling Pattern
104
+
105
+ ```typescript
106
+ import {
107
+ CreditsExhaustedError,
108
+ DuplicatePurchaseError,
109
+ CreditsValidationError
110
+ } from './errors';
111
+
112
+ async function handleCreditOperation(userId: string, cost: number) {
113
+ try {
114
+ const result = await repository.deductCredit(userId, cost);
115
+ return result;
116
+ } catch (error) {
117
+ if (error instanceof CreditsExhaustedError) {
118
+ // Show paywall or upgrade prompt
119
+ showPaywall({ required: cost, current: error.currentBalance });
120
+ } else if (error instanceof DuplicatePurchaseError) {
121
+ // Log and continue (not a critical error)
122
+ console.warn('Duplicate purchase detected');
123
+ } else if (error instanceof CreditsValidationError) {
124
+ // Log validation error
125
+ console.error('Validation failed:', error.message);
126
+ } else {
127
+ // Unexpected error
128
+ console.error('Unexpected error:', error);
129
+ }
130
+ throw error;
131
+ }
132
+ }
133
+ ```
134
+
135
+ ## Error Codes Reference
136
+
137
+ | Code | Description | Recovery |
138
+ |------|-------------|----------|
139
+ | `CREDITS_EXHAUSTED` | Not enough credits | Show paywall/upgrade |
140
+ | `DUPLICATE_PURCHASE` | Duplicate purchase ID | Ignore (idempotent) |
141
+ | `INVALID_AMOUNT` | Invalid credit amount | Validate input |
142
+ | `EXCEEDS_MAXIMUM` | Amount too large | Cap at maximum |
143
+ | `USER_NOT_FOUND` | User doesn't exist | Create user record |
144
+ | `INITIALIZATION_FAILED` | Credit init failed | Retry operation |
145
+
146
+ ## Best Practices
147
+
148
+ 1. **Specific Errors**: Use specific error types for different scenarios
149
+ 2. **Error Context**: Include relevant data in error properties
150
+ 3. **Graceful Handling**: Handle errors appropriately at boundaries
151
+ 4. **Logging**: Log errors for debugging
152
+ 5. **User Feedback**: Convert errors to user-friendly messages
153
+
154
+ ## Related
155
+
156
+ - [Wallet Entities](../entities/README.md)
157
+ - [Credits Repository](../../infrastructure/repositories/README.md)
@@ -0,0 +1,96 @@
1
+ # Wallet Infrastructure
2
+
3
+ Infrastructure layer for wallet and credits functionality.
4
+
5
+ ## Overview
6
+
7
+ This directory contains implementations for credit persistence, transactions, and credit operations.
8
+
9
+ ## Structure
10
+
11
+ ```
12
+ infrastructure/
13
+ ├── repositories/ # Data persistence implementations
14
+ │ └── CreditsRepository.ts
15
+ └── services/ # External service integrations
16
+ └── CreditsService.ts
17
+ ```
18
+
19
+ ## Credits Repository
20
+
21
+ Handles credit data persistence with duplicate protection.
22
+
23
+ ### Key Features
24
+
25
+ - **Duplicate Protection**: Prevents duplicate credit allocations
26
+ - **Optimistic Updates**: Immediate UI updates with rollback
27
+ - **Transactional**: Atomic credit operations
28
+ - **ACCUMULATE Mode**: Adds credits on renewal
29
+
30
+ ### Core Methods
31
+
32
+ ```typescript
33
+ class CreditsRepository implements ICreditsRepository {
34
+ async getCredits(userId: string): Promise<UserCredits | null>;
35
+ async initializeCredits(
36
+ userId: string,
37
+ purchaseId?: string,
38
+ productId?: string
39
+ ): Promise<CreditsResult>;
40
+ async deductCredit(userId: string, amount: number): Promise<CreditsResult>;
41
+ async addCredits(userId: string, amount: number): Promise<CreditsResult>;
42
+ }
43
+ ```
44
+
45
+ ### Usage
46
+
47
+ ```typescript
48
+ import { CreditsRepository } from './repositories/CreditsRepository';
49
+ import { getCreditsRepository } from './repositories/CreditsRepositoryProvider';
50
+
51
+ const repository = getCreditsRepository();
52
+
53
+ // Initialize credits
54
+ const result = await repository.initializeCredits('user-123', 'purchase-456', 'premium_monthly');
55
+ if (result.success) {
56
+ console.log('Credits:', result.data.credits);
57
+ }
58
+
59
+ // Deduct credits
60
+ const deductResult = await repository.deductCredit('user-123', 5);
61
+ if (deductResult.success) {
62
+ console.log('Credits deducted successfully');
63
+ } else if (deductResult.error?.code === 'CREDITS_EXHAUSTED') {
64
+ console.log('Not enough credits');
65
+ }
66
+ ```
67
+
68
+ ## Duplicate Protection
69
+
70
+ The repository prevents duplicate credit allocations based on `purchaseId`:
71
+
72
+ ```typescript
73
+ // First call
74
+ await repository.initializeCredits(userId, 'renewal-123', 'premium');
75
+ // Returns: { success: true, data: { credits: 100 } }
76
+
77
+ // Second call with same purchaseId
78
+ await repository.initializeCredits(userId, 'renewal-123', 'premium');
79
+ // Returns: { success: true, duplicate: true, data: { credits: 100 } }
80
+ // Credits not added again
81
+ ```
82
+
83
+ ## Best Practices
84
+
85
+ 1. **Check Before Deduct**: Always verify credit balance
86
+ 2. **Handle Errors**: Catch and handle credit errors appropriately
87
+ 3. **Use Transactions**: Ensure data consistency
88
+ 4. **Log Operations**: Track credit operations for debugging
89
+ 5. **Test Edge Cases**: Zero credits, max credits, duplicates
90
+ 6. **Validate Input**: Validate all input parameters
91
+
92
+ ## Related
93
+
94
+ - [Wallet Domain](../domain/README.md)
95
+ - [Credits Entity](../domain/entities/README.md)
96
+ - [useCredits Hook](../../presentation/hooks/useCredits.md)
@@ -1,13 +1,13 @@
1
1
  /**
2
2
  * Balance Card Component
3
3
  *
4
- * Displays user's credit balance with gradient background.
4
+ * Displays user's credit balance with solid background.
5
5
  * Props-driven for full customization.
6
6
  */
7
7
 
8
8
  import React from "react";
9
9
  import { View, StyleSheet } from "react-native";
10
- import { LinearGradient } from "expo-linear-gradient";
10
+
11
11
  import {
12
12
  useAppDesignTokens,
13
13
  AtomicText,
@@ -31,17 +31,11 @@ export const BalanceCard: React.FC<BalanceCardProps> = ({
31
31
  iconName = "wallet",
32
32
  }) => {
33
33
  const tokens = useAppDesignTokens();
34
- const gradientColors = [
35
- tokens.colors.primary,
36
- tokens.colors.primaryDark || tokens.colors.primary,
37
- ] as const;
34
+
38
35
 
39
36
  return (
40
- <LinearGradient
41
- colors={gradientColors}
42
- start={{ x: 0, y: 0 }}
43
- end={{ x: 1, y: 1 }}
44
- style={styles.container}
37
+ <View
38
+ style={[styles.container, { backgroundColor: tokens.colors.primary }]}
45
39
  >
46
40
  <View style={styles.content}>
47
41
  <View style={styles.textContainer}>
@@ -73,7 +67,7 @@ export const BalanceCard: React.FC<BalanceCardProps> = ({
73
67
  <AtomicIcon name={iconName} size="xl" color="onPrimary" />
74
68
  </View>
75
69
  </View>
76
- </LinearGradient>
70
+ </View>
77
71
  );
78
72
  };
79
73
 
@@ -0,0 +1,231 @@
1
+ # Wallet Presentation Components
2
+
3
+ UI components for wallet and credit display.
4
+
5
+ ## Overview
6
+
7
+ This directory contains React Native components for displaying credits, transactions, and wallet information.
8
+
9
+ ## Components
10
+
11
+ ### CreditBalanceCard
12
+ Card displaying current credit balance.
13
+
14
+ ```typescript
15
+ interface CreditBalanceCardProps {
16
+ credits: number;
17
+ balance: number;
18
+ isLoading?: boolean;
19
+ onPress?: () => void;
20
+ onRefresh?: () => void;
21
+ }
22
+ ```
23
+
24
+ **Usage:**
25
+ ```typescript
26
+ <CreditBalanceCard
27
+ credits={50}
28
+ balance={0.50}
29
+ onPress={() => navigation.navigate('CreditHistory')}
30
+ onRefresh={() => refetch()}
31
+ />
32
+ ```
33
+
34
+ ### TransactionItem
35
+ Individual transaction display component.
36
+
37
+ ```typescript
38
+ interface TransactionItemProps {
39
+ transaction: Transaction;
40
+ format?: 'full' | 'compact';
41
+ }
42
+ ```
43
+
44
+ **Usage:**
45
+ ```typescript
46
+ <TransactionItem
47
+ transaction={{
48
+ id: 'tx_123',
49
+ amount: -5,
50
+ reason: 'AI Generation',
51
+ timestamp: new Date(),
52
+ type: 'deduction',
53
+ }}
54
+ format="full"
55
+ />
56
+ ```
57
+
58
+ ### CreditProgressBar
59
+ Progress bar showing credit usage.
60
+
61
+ ```typescript
62
+ interface CreditProgressBarProps {
63
+ current: number;
64
+ total: number;
65
+ showLabel?: boolean;
66
+ showPercentage?: boolean;
67
+ height?: number;
68
+ }
69
+ ```
70
+
71
+ **Usage:**
72
+ ```typescript
73
+ <CreditProgressBar
74
+ current={50}
75
+ total={100}
76
+ showLabel={true}
77
+ showPercentage={true}
78
+ height={8}
79
+ />
80
+ ```
81
+
82
+ ### CreditPackageCard
83
+ Display card for purchasable credit packages.
84
+
85
+ ```typescript
86
+ interface CreditPackageCardProps {
87
+ package: {
88
+ id: string;
89
+ amount: number;
90
+ price: number;
91
+ bonus?: number;
92
+ currency: string;
93
+ };
94
+ onPress: () => void;
95
+ highlight?: boolean;
96
+ }
97
+ ```
98
+
99
+ **Usage:**
100
+ ```typescript
101
+ <CreditPackageCard
102
+ package={{
103
+ id: 'premium_credits',
104
+ amount: 100,
105
+ price: 9.99,
106
+ bonus: 10,
107
+ currency: 'USD',
108
+ }}
109
+ onPress={() => purchaseCredits('premium_credits')}
110
+ highlight={true}
111
+ />
112
+ ```
113
+
114
+ ## Usage Patterns
115
+
116
+ ### Complete Credit Dashboard
117
+
118
+ ```typescript
119
+ function CreditDashboard() {
120
+ const { credits, transactions, isLoading, refetch } = useCredits();
121
+
122
+ return (
123
+ <ScrollView>
124
+ <CreditBalanceCard
125
+ credits={credits}
126
+ balance={calculateBalance(credits)}
127
+ onRefresh={refetch}
128
+ />
129
+
130
+ <View style={styles.section}>
131
+ <Text style={styles.title}>Recent Transactions</Text>
132
+ {transactions.slice(0, 10).map(tx => (
133
+ <TransactionItem key={tx.id} transaction={tx} />
134
+ ))}
135
+ </View>
136
+
137
+ <Button onPress={() => navigation.navigate('CreditPackages')}>
138
+ Get More Credits
139
+ </Button>
140
+ </ScrollView>
141
+ );
142
+ }
143
+ ```
144
+
145
+ ### Credit Warning Banner
146
+
147
+ ```typescript
148
+ function LowCreditWarning() {
149
+ const { credits } = useCredits();
150
+ const warningThreshold = 20;
151
+
152
+ if (credits > warningThreshold) return null;
153
+
154
+ return (
155
+ <Banner type={credits === 0 ? 'error' : 'warning'}>
156
+ <Text>
157
+ {credits === 0
158
+ ? 'No credits remaining'
159
+ : `Only ${credits} credits left`
160
+ }
161
+ </Text>
162
+ <Button onPress={() => navigation.navigate('CreditPackages')}>
163
+ Get More
164
+ </Button>
165
+ </Banner>
166
+ );
167
+ }
168
+ ```
169
+
170
+ ### Credit History List
171
+
172
+ ```typescript
173
+ function TransactionHistory() {
174
+ const { transactions } = useCredits();
175
+
176
+ return (
177
+ <FlatList
178
+ data={transactions}
179
+ keyExtractor={(item) => item.id}
180
+ renderItem={({ item }) => (
181
+ <TransactionItem transaction={item} format="compact" />
182
+ )}
183
+ ListHeaderComponent={() => (
184
+ <Text style={styles.title}>Transaction History</Text>
185
+ )}
186
+ ListEmptyComponent={() => (
187
+ <EmptyState
188
+ icon="receipt"
189
+ title="No transactions yet"
190
+ message="Your credit transaction history will appear here"
191
+ />
192
+ )}
193
+ />
194
+ );
195
+ }
196
+ ```
197
+
198
+ ## Styling
199
+
200
+ Components use design system:
201
+
202
+ ```typescript
203
+ import { useAppDesignTokens } from '@umituz/react-native-design-system';
204
+
205
+ const tokens = useAppDesignTokens();
206
+
207
+ const styles = StyleSheet.create({
208
+ card: {
209
+ backgroundColor: tokens.colors.surface,
210
+ borderRadius: tokens.radius.lg,
211
+ padding: tokens.spacing.lg,
212
+ marginBottom: tokens.spacing.md,
213
+ },
214
+ });
215
+ ```
216
+
217
+ ## Best Practices
218
+
219
+ 1. **Visual Hierarchy**: Emphasize important information
220
+ 2. **Color Coding**: Use colors to indicate status (low/warning/good)
221
+ 3. **Loading States**: Show skeletons while loading
222
+ 4. **Empty States**: Provide helpful empty state messages
223
+ 5. **Refresh Capability**: Allow manual refresh
224
+ 6. **Transactional History**: Show clear transaction history
225
+ 7. **Purchase Links**: Easy access to purchase more credits
226
+
227
+ ## Related
228
+
229
+ - [Credit Row](../../../presentation/components/details/CreditRow.md)
230
+ - [Credits Hook](../hooks/README.md)
231
+ - [Wallet Domain](../../domain/README.md)