@digilogiclabs/create-saas-app 1.14.1 → 1.17.1

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 (147) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/README.md +285 -39
  3. package/bin/index.js +1 -1
  4. package/dist/.tsbuildinfo +1 -1
  5. package/dist/cli/prompts/project-setup.d.ts.map +1 -1
  6. package/dist/cli/prompts/project-setup.js +49 -12
  7. package/dist/cli/prompts/project-setup.js.map +1 -1
  8. package/dist/generators/template-generator.d.ts.map +1 -1
  9. package/dist/generators/template-generator.js +27 -4
  10. package/dist/generators/template-generator.js.map +1 -1
  11. package/dist/templates/mobile/base/template/App.tsx +2 -0
  12. package/dist/templates/mobile/ui-auth-payments/template/.env.example +20 -0
  13. package/dist/templates/mobile/ui-auth-payments/template/README.md +218 -0
  14. package/dist/templates/mobile/ui-auth-payments/template/app/(tabs)/_layout.tsx +153 -0
  15. package/dist/templates/mobile/ui-auth-payments/template/app/(tabs)/analytics.tsx +668 -0
  16. package/dist/templates/mobile/ui-auth-payments/template/app/(tabs)/billing.tsx +743 -0
  17. package/dist/templates/mobile/ui-auth-payments/template/app/(tabs)/index.tsx +757 -0
  18. package/dist/templates/mobile/ui-auth-payments/template/app/(tabs)/orders.tsx +402 -0
  19. package/dist/templates/mobile/ui-auth-payments/template/app/(tabs)/profile.tsx +580 -0
  20. package/dist/templates/mobile/ui-auth-payments/template/app/_layout.tsx +127 -0
  21. package/dist/templates/mobile/ui-auth-payments/template/app/auth/login.tsx +246 -0
  22. package/dist/templates/mobile/ui-auth-payments/template/app/auth/signup.tsx +362 -0
  23. package/dist/templates/mobile/ui-auth-payments/template/app/onboarding/index.tsx +193 -0
  24. package/dist/templates/mobile/ui-auth-payments/template/app/tour/index.tsx +272 -0
  25. package/dist/templates/mobile/ui-auth-payments/template/app.json +93 -0
  26. package/dist/templates/mobile/ui-auth-payments/template/babel.config.js +23 -0
  27. package/dist/templates/mobile/ui-auth-payments/template/eas.json +45 -0
  28. package/dist/templates/mobile/ui-auth-payments/template/expo-env.d.ts +3 -0
  29. package/dist/templates/mobile/ui-auth-payments/template/jest-setup.ts +74 -0
  30. package/dist/templates/mobile/ui-auth-payments/template/metro.config.js +11 -0
  31. package/dist/templates/mobile/ui-auth-payments/template/package.json +106 -0
  32. package/dist/templates/mobile/ui-auth-payments/template/tsconfig.json +31 -0
  33. package/dist/templates/mobile/ui-auth-payments-ai/template/.env.example +23 -0
  34. package/dist/templates/mobile/ui-auth-payments-ai/template/README.md +254 -0
  35. package/dist/templates/mobile/ui-auth-payments-ai/template/app/(tabs)/_layout.tsx +169 -0
  36. package/dist/templates/mobile/ui-auth-payments-ai/template/app/(tabs)/ai.tsx +522 -0
  37. package/dist/templates/mobile/ui-auth-payments-ai/template/app/(tabs)/analytics.tsx +668 -0
  38. package/dist/templates/mobile/ui-auth-payments-ai/template/app/(tabs)/billing.tsx +743 -0
  39. package/dist/templates/mobile/ui-auth-payments-ai/template/app/(tabs)/index.tsx +676 -0
  40. package/dist/templates/mobile/ui-auth-payments-ai/template/app/(tabs)/orders.tsx +402 -0
  41. package/dist/templates/mobile/ui-auth-payments-ai/template/app/(tabs)/profile.tsx +580 -0
  42. package/dist/templates/mobile/ui-auth-payments-ai/template/app/_layout.tsx +127 -0
  43. package/dist/templates/mobile/ui-auth-payments-ai/template/app/auth/login.tsx +246 -0
  44. package/dist/templates/mobile/ui-auth-payments-ai/template/app/auth/signup.tsx +362 -0
  45. package/dist/templates/mobile/ui-auth-payments-ai/template/app/onboarding/index.tsx +193 -0
  46. package/dist/templates/mobile/ui-auth-payments-ai/template/app/tour/index.tsx +272 -0
  47. package/dist/templates/mobile/ui-auth-payments-ai/template/app.json +93 -0
  48. package/dist/templates/mobile/ui-auth-payments-ai/template/babel.config.js +23 -0
  49. package/dist/templates/mobile/ui-auth-payments-ai/template/eas.json +45 -0
  50. package/dist/templates/mobile/ui-auth-payments-ai/template/expo-env.d.ts +3 -0
  51. package/dist/templates/mobile/ui-auth-payments-ai/template/jest-setup.ts +74 -0
  52. package/dist/templates/mobile/ui-auth-payments-ai/template/metro.config.js +11 -0
  53. package/dist/templates/mobile/ui-auth-payments-ai/template/package.json +108 -0
  54. package/dist/templates/mobile/ui-auth-payments-ai/template/tsconfig.json +31 -0
  55. package/dist/templates/web/base/template/src/app/dashboard/page.tsx +62 -20
  56. package/dist/templates/web/base/template/src/app/loading.tsx +45 -27
  57. package/dist/templates/web/base/template/src/components/providers/app-providers.tsx +2 -0
  58. package/dist/templates/web/ui-auth/template/package.json +1 -1
  59. package/dist/templates/web/ui-auth/template/src/app/loading.tsx +30 -12
  60. package/dist/templates/web/ui-auth/template/src/components/providers/app-providers.tsx +2 -0
  61. package/dist/templates/web/ui-auth/template/src/components/shared/header.tsx +43 -2
  62. package/dist/templates/web/ui-auth-ai/template/package.json +1 -1
  63. package/dist/templates/web/ui-auth-payments/template/package.json +1 -1
  64. package/dist/templates/web/ui-auth-payments/template/src/app/dashboard/page.tsx +69 -17
  65. package/dist/templates/web/ui-auth-payments/template/src/components/providers/app-providers.tsx +2 -0
  66. package/dist/templates/web/ui-auth-payments-ai/template/package.json +1 -1
  67. package/dist/templates/web/ui-auth-payments-ai/template/src/app/billing/page.tsx +218 -7
  68. package/dist/templates/web/ui-auth-payments-ai/template/src/app/dashboard/page.tsx +62 -9
  69. package/dist/templates/web/ui-auth-payments-ai/template/src/app/onboarding/page.tsx +364 -0
  70. package/dist/templates/web/ui-auth-payments-ai/template/src/app/settings/page.tsx +532 -0
  71. package/dist/templates/web/ui-auth-payments-ai/template/src/components/client/login-form.tsx +70 -51
  72. package/dist/templates/web/ui-auth-payments-ai/template/src/components/client/signup-form.tsx +76 -60
  73. package/dist/templates/web/ui-auth-payments-ai/template/src/components/providers/app-providers.tsx +2 -0
  74. package/dist/templates/web/ui-auth-payments-audio/template/package.json +1 -1
  75. package/dist/templates/web/ui-auth-payments-audio/template/src/app/dashboard/page.tsx +71 -17
  76. package/dist/templates/web/ui-auth-payments-audio/template/src/components/providers/app-providers.tsx +2 -0
  77. package/dist/templates/web/ui-auth-payments-video/template/package.json +1 -1
  78. package/dist/templates/web/ui-auth-payments-video/template/src/components/providers/app-providers.tsx +2 -0
  79. package/package.json +1 -1
  80. package/src/templates/mobile/base/template/App.tsx +2 -0
  81. package/src/templates/mobile/ui-auth-payments/template/.env.example +20 -0
  82. package/src/templates/mobile/ui-auth-payments/template/README.md +218 -0
  83. package/src/templates/mobile/ui-auth-payments/template/app/(tabs)/_layout.tsx +153 -0
  84. package/src/templates/mobile/ui-auth-payments/template/app/(tabs)/analytics.tsx +668 -0
  85. package/src/templates/mobile/ui-auth-payments/template/app/(tabs)/billing.tsx +743 -0
  86. package/src/templates/mobile/ui-auth-payments/template/app/(tabs)/index.tsx +757 -0
  87. package/src/templates/mobile/ui-auth-payments/template/app/(tabs)/orders.tsx +402 -0
  88. package/src/templates/mobile/ui-auth-payments/template/app/(tabs)/profile.tsx +580 -0
  89. package/src/templates/mobile/ui-auth-payments/template/app/_layout.tsx +127 -0
  90. package/src/templates/mobile/ui-auth-payments/template/app/auth/login.tsx +246 -0
  91. package/src/templates/mobile/ui-auth-payments/template/app/auth/signup.tsx +362 -0
  92. package/src/templates/mobile/ui-auth-payments/template/app/onboarding/index.tsx +193 -0
  93. package/src/templates/mobile/ui-auth-payments/template/app/tour/index.tsx +272 -0
  94. package/src/templates/mobile/ui-auth-payments/template/app.json +93 -0
  95. package/src/templates/mobile/ui-auth-payments/template/babel.config.js +23 -0
  96. package/src/templates/mobile/ui-auth-payments/template/eas.json +45 -0
  97. package/src/templates/mobile/ui-auth-payments/template/expo-env.d.ts +3 -0
  98. package/src/templates/mobile/ui-auth-payments/template/jest-setup.ts +74 -0
  99. package/src/templates/mobile/ui-auth-payments/template/metro.config.js +11 -0
  100. package/src/templates/mobile/ui-auth-payments/template/package.json +106 -0
  101. package/src/templates/mobile/ui-auth-payments/template/tsconfig.json +31 -0
  102. package/src/templates/mobile/ui-auth-payments-ai/template/.env.example +23 -0
  103. package/src/templates/mobile/ui-auth-payments-ai/template/README.md +254 -0
  104. package/src/templates/mobile/ui-auth-payments-ai/template/app/(tabs)/_layout.tsx +169 -0
  105. package/src/templates/mobile/ui-auth-payments-ai/template/app/(tabs)/ai.tsx +522 -0
  106. package/src/templates/mobile/ui-auth-payments-ai/template/app/(tabs)/analytics.tsx +668 -0
  107. package/src/templates/mobile/ui-auth-payments-ai/template/app/(tabs)/billing.tsx +743 -0
  108. package/src/templates/mobile/ui-auth-payments-ai/template/app/(tabs)/index.tsx +676 -0
  109. package/src/templates/mobile/ui-auth-payments-ai/template/app/(tabs)/orders.tsx +402 -0
  110. package/src/templates/mobile/ui-auth-payments-ai/template/app/(tabs)/profile.tsx +580 -0
  111. package/src/templates/mobile/ui-auth-payments-ai/template/app/_layout.tsx +127 -0
  112. package/src/templates/mobile/ui-auth-payments-ai/template/app/auth/login.tsx +246 -0
  113. package/src/templates/mobile/ui-auth-payments-ai/template/app/auth/signup.tsx +362 -0
  114. package/src/templates/mobile/ui-auth-payments-ai/template/app/onboarding/index.tsx +193 -0
  115. package/src/templates/mobile/ui-auth-payments-ai/template/app/tour/index.tsx +272 -0
  116. package/src/templates/mobile/ui-auth-payments-ai/template/app.json +93 -0
  117. package/src/templates/mobile/ui-auth-payments-ai/template/babel.config.js +23 -0
  118. package/src/templates/mobile/ui-auth-payments-ai/template/eas.json +45 -0
  119. package/src/templates/mobile/ui-auth-payments-ai/template/expo-env.d.ts +3 -0
  120. package/src/templates/mobile/ui-auth-payments-ai/template/jest-setup.ts +74 -0
  121. package/src/templates/mobile/ui-auth-payments-ai/template/metro.config.js +11 -0
  122. package/src/templates/mobile/ui-auth-payments-ai/template/package.json +108 -0
  123. package/src/templates/mobile/ui-auth-payments-ai/template/tsconfig.json +31 -0
  124. package/src/templates/web/base/template/src/app/dashboard/page.tsx +62 -20
  125. package/src/templates/web/base/template/src/app/loading.tsx +45 -27
  126. package/src/templates/web/base/template/src/components/providers/app-providers.tsx +2 -0
  127. package/src/templates/web/ui-auth/template/package.json +1 -1
  128. package/src/templates/web/ui-auth/template/src/app/loading.tsx +30 -12
  129. package/src/templates/web/ui-auth/template/src/components/providers/app-providers.tsx +2 -0
  130. package/src/templates/web/ui-auth/template/src/components/shared/header.tsx +43 -2
  131. package/src/templates/web/ui-auth-ai/template/package.json +1 -1
  132. package/src/templates/web/ui-auth-payments/template/package.json +1 -1
  133. package/src/templates/web/ui-auth-payments/template/src/app/dashboard/page.tsx +69 -17
  134. package/src/templates/web/ui-auth-payments/template/src/components/providers/app-providers.tsx +2 -0
  135. package/src/templates/web/ui-auth-payments-ai/template/package.json +1 -1
  136. package/src/templates/web/ui-auth-payments-ai/template/src/app/billing/page.tsx +218 -7
  137. package/src/templates/web/ui-auth-payments-ai/template/src/app/dashboard/page.tsx +62 -9
  138. package/src/templates/web/ui-auth-payments-ai/template/src/app/onboarding/page.tsx +364 -0
  139. package/src/templates/web/ui-auth-payments-ai/template/src/app/settings/page.tsx +532 -0
  140. package/src/templates/web/ui-auth-payments-ai/template/src/components/client/login-form.tsx +70 -51
  141. package/src/templates/web/ui-auth-payments-ai/template/src/components/client/signup-form.tsx +76 -60
  142. package/src/templates/web/ui-auth-payments-ai/template/src/components/providers/app-providers.tsx +2 -0
  143. package/src/templates/web/ui-auth-payments-audio/template/package.json +1 -1
  144. package/src/templates/web/ui-auth-payments-audio/template/src/app/dashboard/page.tsx +71 -17
  145. package/src/templates/web/ui-auth-payments-audio/template/src/components/providers/app-providers.tsx +2 -0
  146. package/src/templates/web/ui-auth-payments-video/template/package.json +1 -1
  147. package/src/templates/web/ui-auth-payments-video/template/src/components/providers/app-providers.tsx +2 -0
@@ -0,0 +1,743 @@
1
+ import React, { useState, useEffect } from 'react';
2
+ import { View, Text, StyleSheet, ScrollView, Alert, RefreshControl, Animated } from 'react-native';
3
+ import { useStripe } from '@stripe/stripe-react-native';
4
+ import { LinearGradient } from 'expo-linear-gradient';
5
+ import { BlurView } from 'expo-blur';
6
+ import * as Haptics from 'expo-haptics';
7
+
8
+ // UI Components
9
+ import {
10
+ NativeCard as Card,
11
+ NativeMobileContainer as MobileContainer,
12
+ NativeButton as Button,
13
+ NativeBadge as Badge,
14
+ NativePageTransition as PageTransition,
15
+ NativeModal as Modal,
16
+ NativeInput as Input,
17
+ NativeMobileHero as MobileHero,
18
+ NativePullToRefresh as PullToRefresh,
19
+ useTheme
20
+ } from '@digilogiclabs/saas-factory-ui/native';
21
+
22
+ // Payments Hook
23
+ import { usePayments } from '@digilogiclabs/saas-factory-payments/native';
24
+
25
+ // Icons
26
+ import {
27
+ CreditCard,
28
+ Plus,
29
+ Trash2,
30
+ Shield,
31
+ Calendar,
32
+ DollarSign,
33
+ Receipt,
34
+ Star
35
+ } from 'react-native-heroicons/outline';
36
+
37
+ interface PaymentMethod {
38
+ id: string;
39
+ type: 'card';
40
+ card: {
41
+ brand: string;
42
+ last4: string;
43
+ expiryMonth: number;
44
+ expiryYear: number;
45
+ };
46
+ isDefault: boolean;
47
+ }
48
+
49
+ interface Subscription {
50
+ id: string;
51
+ name: string;
52
+ price: number;
53
+ interval: 'month' | 'year';
54
+ status: 'active' | 'cancelled' | 'past_due';
55
+ currentPeriodEnd: string;
56
+ features: string[];
57
+ }
58
+
59
+ interface Invoice {
60
+ id: string;
61
+ number: string;
62
+ amount: number;
63
+ status: 'paid' | 'pending' | 'failed';
64
+ date: string;
65
+ dueDate: string;
66
+ description: string;
67
+ }
68
+
69
+ const mockPaymentMethods: PaymentMethod[] = [
70
+ {
71
+ id: '1',
72
+ type: 'card',
73
+ card: {
74
+ brand: 'visa',
75
+ last4: '4242',
76
+ expiryMonth: 12,
77
+ expiryYear: 2025
78
+ },
79
+ isDefault: true
80
+ },
81
+ {
82
+ id: '2',
83
+ type: 'card',
84
+ card: {
85
+ brand: 'mastercard',
86
+ last4: '5555',
87
+ expiryMonth: 8,
88
+ expiryYear: 2026
89
+ },
90
+ isDefault: false
91
+ }
92
+ ];
93
+
94
+ const mockSubscription: Subscription = {
95
+ id: 'sub_1',
96
+ name: 'Pro Plan',
97
+ price: 29.99,
98
+ interval: 'month',
99
+ status: 'active',
100
+ currentPeriodEnd: '2024-02-15',
101
+ features: [
102
+ 'Unlimited projects',
103
+ 'Priority support',
104
+ 'Advanced analytics',
105
+ 'Custom integrations'
106
+ ]
107
+ };
108
+
109
+ const mockInvoices: Invoice[] = [
110
+ {
111
+ id: 'inv_1',
112
+ number: 'INV-001234',
113
+ amount: 29.99,
114
+ status: 'paid',
115
+ date: '2024-01-15',
116
+ dueDate: '2024-01-15',
117
+ description: 'Pro Plan - January 2024'
118
+ },
119
+ {
120
+ id: 'inv_2',
121
+ number: 'INV-001233',
122
+ amount: 29.99,
123
+ status: 'paid',
124
+ date: '2023-12-15',
125
+ dueDate: '2023-12-15',
126
+ description: 'Pro Plan - December 2023'
127
+ }
128
+ ];
129
+
130
+ export default function BillingScreen() {
131
+ const { initPaymentSheet, presentPaymentSheet } = useStripe();
132
+ const { createPaymentMethod, deletePaymentMethod, updateSubscription } = usePayments();
133
+ const { theme, isDark } = useTheme();
134
+
135
+ const [paymentMethods, setPaymentMethods] = useState<PaymentMethod[]>(mockPaymentMethods);
136
+ const [subscription, setSubscription] = useState<Subscription | null>(mockSubscription);
137
+ const [invoices, setInvoices] = useState<Invoice[]>(mockInvoices);
138
+ const [loading, setLoading] = useState(false);
139
+ const [refreshing, setRefreshing] = useState(false);
140
+ const [showAddCard, setShowAddCard] = useState(false);
141
+
142
+ // Animation values
143
+ const fadeAnim = useState(new Animated.Value(0))[0];
144
+ const slideAnim = useState(new Animated.Value(50))[0];
145
+
146
+ useEffect(() => {
147
+ // Entrance animations
148
+ Animated.parallel([
149
+ Animated.timing(fadeAnim, {
150
+ toValue: 1,
151
+ duration: 600,
152
+ useNativeDriver: true,
153
+ }),
154
+ Animated.spring(slideAnim, {
155
+ toValue: 0,
156
+ tension: 50,
157
+ friction: 8,
158
+ useNativeDriver: true,
159
+ }),
160
+ ]).start();
161
+ }, []);
162
+
163
+ const onRefresh = async () => {
164
+ setRefreshing(true);
165
+ Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Medium);
166
+ // Simulate refresh
167
+ await new Promise(resolve => setTimeout(resolve, 1500));
168
+ setRefreshing(false);
169
+ };
170
+
171
+ const handleAddPaymentMethod = async () => {
172
+ try {
173
+ setLoading(true);
174
+ Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light);
175
+
176
+ const { error } = await initPaymentSheet({
177
+ merchantDisplayName: '{{titleCaseName}}',
178
+ paymentIntentClientSecret: 'your-payment-intent-client-secret',
179
+ setupIntentClientSecret: 'your-setup-intent-client-secret',
180
+ allowsDelayedPaymentMethods: true,
181
+ defaultBillingDetails: {
182
+ name: 'John Doe',
183
+ }
184
+ });
185
+
186
+ if (!error) {
187
+ const { error: presentError } = await presentPaymentSheet();
188
+
189
+ if (presentError) {
190
+ Alert.alert('Error', presentError.message);
191
+ } else {
192
+ Alert.alert('Success', 'Payment method added successfully!');
193
+ Haptics.notificationAsync(Haptics.NotificationFeedbackType.Success);
194
+ // Refresh payment methods
195
+ }
196
+ }
197
+ } catch (error: any) {
198
+ Alert.alert('Error', error.message);
199
+ } finally {
200
+ setLoading(false);
201
+ }
202
+ };
203
+
204
+ const handleDeletePaymentMethod = async (methodId: string) => {
205
+ Alert.alert(
206
+ 'Delete Payment Method',
207
+ 'Are you sure you want to delete this payment method?',
208
+ [
209
+ { text: 'Cancel', style: 'cancel' },
210
+ {
211
+ text: 'Delete',
212
+ style: 'destructive',
213
+ onPress: async () => {
214
+ try {
215
+ await deletePaymentMethod(methodId);
216
+ setPaymentMethods(prev => prev.filter(method => method.id !== methodId));
217
+ Alert.alert('Success', 'Payment method deleted successfully');
218
+ } catch (error: any) {
219
+ Alert.alert('Error', error.message);
220
+ }
221
+ }
222
+ }
223
+ ]
224
+ );
225
+ };
226
+
227
+ const handleSetDefaultPaymentMethod = async (methodId: string) => {
228
+ try {
229
+ // Update default payment method
230
+ setPaymentMethods(prev =>
231
+ prev.map(method => ({
232
+ ...method,
233
+ isDefault: method.id === methodId
234
+ }))
235
+ );
236
+ Alert.alert('Success', 'Default payment method updated');
237
+ } catch (error: any) {
238
+ Alert.alert('Error', error.message);
239
+ }
240
+ };
241
+
242
+ const renderPaymentMethod = (method: PaymentMethod) => (
243
+ <Card key={method.id} style={styles.paymentMethodCard}>
244
+ <View style={styles.paymentMethodHeader}>
245
+ <View style={styles.cardInfo}>
246
+ <View style={styles.cardBrand}>
247
+ <CreditCard width={24} height={24} color="#64748b" />
248
+ <Text style={styles.cardText}>
249
+ •••• •••• •••• {method.card.last4}
250
+ </Text>
251
+ </View>
252
+ <Text style={styles.cardExpiry}>
253
+ {String(method.card.expiryMonth).padStart(2, '0')}/{method.card.expiryYear}
254
+ </Text>
255
+ </View>
256
+ {method.isDefault && (
257
+ <Badge variant="success" style={styles.defaultBadge}>
258
+ <Star width={12} height={12} />
259
+ <Text>Default</Text>
260
+ </Badge>
261
+ )}
262
+ </View>
263
+
264
+ <View style={styles.paymentMethodActions}>
265
+ {!method.isDefault && (
266
+ <Button
267
+ variant="outline"
268
+ size="sm"
269
+ onPress={() => handleSetDefaultPaymentMethod(method.id)}
270
+ >
271
+ Set as Default
272
+ </Button>
273
+ )}
274
+ <Button
275
+ variant="outline"
276
+ size="sm"
277
+ onPress={() => handleDeletePaymentMethod(method.id)}
278
+ style={styles.deleteButton}
279
+ >
280
+ <Trash2 width={16} height={16} color="#ef4444" />
281
+ </Button>
282
+ </View>
283
+ </Card>
284
+ );
285
+
286
+ const renderInvoice = (invoice: Invoice) => (
287
+ <Card key={invoice.id} style={styles.invoiceCard}>
288
+ <View style={styles.invoiceHeader}>
289
+ <View>
290
+ <Text style={styles.invoiceNumber}>{invoice.number}</Text>
291
+ <Text style={styles.invoiceDescription}>{invoice.description}</Text>
292
+ </View>
293
+ <Badge
294
+ variant={invoice.status === 'paid' ? 'success' : invoice.status === 'pending' ? 'warning' : 'error'}
295
+ >
296
+ {invoice.status.toUpperCase()}
297
+ </Badge>
298
+ </View>
299
+
300
+ <View style={styles.invoiceDetails}>
301
+ <View style={styles.invoiceAmount}>
302
+ <DollarSign width={16} height={16} color="#64748b" />
303
+ <Text style={styles.amountText}>${invoice.amount.toFixed(2)}</Text>
304
+ </View>
305
+ <View style={styles.invoiceDate}>
306
+ <Calendar width={16} height={16} color="#64748b" />
307
+ <Text style={styles.dateText}>{invoice.date}</Text>
308
+ </View>
309
+ <Button variant="ghost" size="sm">
310
+ <Receipt width={16} height={16} />
311
+ <Text>Download</Text>
312
+ </Button>
313
+ </View>
314
+ </Card>
315
+ );
316
+
317
+ return (
318
+ <PageTransition type="fade">
319
+ <View style={styles.mainContainer}>
320
+ {/* Enhanced gradient background with floating elements */}
321
+ <LinearGradient
322
+ colors={isDark
323
+ ? ['#0F172A', '#1E293B', '#334155']
324
+ : ['#F8FAFC', '#E2E8F0', '#CBD5E1']
325
+ }
326
+ style={styles.gradientBackground}
327
+ />
328
+
329
+ {/* Floating animated elements */}
330
+ <Animated.View style={[styles.floatingElement, styles.element1, {
331
+ opacity: fadeAnim,
332
+ transform: [{ translateY: slideAnim }]
333
+ }]}>
334
+ <LinearGradient
335
+ colors={['rgba(34, 197, 94, 0.3)', 'rgba(22, 163, 74, 0.3)']}
336
+ style={styles.gradientOrb}
337
+ />
338
+ </Animated.View>
339
+
340
+ <Animated.View style={[styles.floatingElement, styles.element2, {
341
+ opacity: fadeAnim,
342
+ transform: [{ translateY: slideAnim }]
343
+ }]}>
344
+ <LinearGradient
345
+ colors={['rgba(59, 130, 246, 0.3)', 'rgba(37, 99, 235, 0.3)']}
346
+ style={styles.gradientOrb}
347
+ />
348
+ </Animated.View>
349
+
350
+ <PullToRefresh
351
+ onRefresh={onRefresh}
352
+ refreshing={refreshing}
353
+ >
354
+ <ScrollView
355
+ style={styles.scrollView}
356
+ showsVerticalScrollIndicator={false}
357
+ refreshControl={
358
+ <RefreshControl refreshing={refreshing} onRefresh={onRefresh} />
359
+ }
360
+ >
361
+ <MobileContainer style={styles.container}>
362
+ {/* Hero Section */}
363
+ <Animated.View style={{
364
+ opacity: fadeAnim,
365
+ transform: [{ translateY: slideAnim }]
366
+ }}>
367
+ <MobileHero
368
+ badge={{
369
+ text: "💳 Billing Center",
370
+ variant: "secondary"
371
+ }}
372
+ title={{
373
+ text: "Manage Payments",
374
+ size: "lg"
375
+ }}
376
+ description="View your subscription, manage payment methods, and access billing history."
377
+ className="text-center mb-6"
378
+ />
379
+ </Animated.View>
380
+ {/* Current Subscription with Glass Effect */}
381
+ {subscription && (
382
+ <Animated.View style={{
383
+ opacity: fadeAnim,
384
+ transform: [{ translateY: slideAnim }]
385
+ }}>
386
+ <BlurView intensity={30} style={styles.subscriptionBlur}>
387
+ <Card style={styles.subscriptionCard}>
388
+ <View style={styles.subscriptionHeader}>
389
+ <Text style={styles.subscriptionTitle}>{subscription.name}</Text>
390
+ <Badge
391
+ variant={subscription.status === 'active' ? 'success' : 'error'}
392
+ style={styles.statusBadge}
393
+ >
394
+ {subscription.status.toUpperCase()}
395
+ </Badge>
396
+ </View>
397
+
398
+ <View style={styles.subscriptionPricing}>
399
+ <Text style={styles.price}>
400
+ ${subscription.price.toFixed(2)}
401
+ <Text style={styles.interval}>/{subscription.interval}</Text>
402
+ </Text>
403
+ <Text style={styles.nextBilling}>
404
+ Next billing: {subscription.currentPeriodEnd}
405
+ </Text>
406
+ </View>
407
+
408
+ <View style={styles.features}>
409
+ {subscription.features.map((feature, index) => (
410
+ <View key={index} style={styles.feature}>
411
+ <Shield width={16} height={16} color="#10b981" />
412
+ <Text style={styles.featureText}>{feature}</Text>
413
+ </View>
414
+ ))}
415
+ </View>
416
+
417
+ <View style={styles.subscriptionActions}>
418
+ <Button variant="outline" style={styles.actionButton}>
419
+ Change Plan
420
+ </Button>
421
+ <Button variant="ghost" style={styles.actionButton}>
422
+ Cancel Subscription
423
+ </Button>
424
+ </View>
425
+ </Card>
426
+ </BlurView>
427
+ </Animated.View>
428
+ )}
429
+
430
+ {/* Payment Methods with Glass Effect */}
431
+ <Animated.View style={[styles.section, {
432
+ opacity: fadeAnim,
433
+ transform: [{ translateY: slideAnim }]
434
+ }]}>
435
+ <View style={styles.sectionHeader}>
436
+ <Text style={styles.sectionTitle}>Payment Methods</Text>
437
+ <Button
438
+ variant="outline"
439
+ size="sm"
440
+ onPress={handleAddPaymentMethod}
441
+ loading={loading}
442
+ >
443
+ <Plus width={16} height={16} />
444
+ <Text>Add Card</Text>
445
+ </Button>
446
+ </View>
447
+
448
+ {paymentMethods.map((method) => (
449
+ <BlurView key={method.id} intensity={25} style={styles.paymentMethodBlur}>
450
+ {renderPaymentMethod(method)}
451
+ </BlurView>
452
+ ))}
453
+
454
+ {paymentMethods.length === 0 && (
455
+ <BlurView intensity={20} style={styles.emptyStateBlur}>
456
+ <Card style={styles.emptyState}>
457
+ <CreditCard width={48} height={48} color="#94a3b8" />
458
+ <Text style={styles.emptyTitle}>No payment methods</Text>
459
+ <Text style={styles.emptySubtitle}>
460
+ Add a payment method to continue
461
+ </Text>
462
+ <Button
463
+ style={styles.addFirstCard}
464
+ onPress={handleAddPaymentMethod}
465
+ loading={loading}
466
+ >
467
+ Add Payment Method
468
+ </Button>
469
+ </Card>
470
+ </BlurView>
471
+ )}
472
+ </Animated.View>
473
+
474
+ {/* Billing History with Glass Effect */}
475
+ <Animated.View style={[styles.section, {
476
+ opacity: fadeAnim,
477
+ transform: [{ translateY: slideAnim }]
478
+ }]}>
479
+ <Text style={styles.sectionTitle}>Billing History</Text>
480
+ {invoices.map((invoice) => (
481
+ <BlurView key={invoice.id} intensity={25} style={styles.invoiceBlur}>
482
+ {renderInvoice(invoice)}
483
+ </BlurView>
484
+ ))}
485
+ </Animated.View>
486
+ </MobileContainer>
487
+ </ScrollView>
488
+ </PullToRefresh>
489
+ </View>
490
+ </PageTransition>
491
+ );
492
+ }
493
+
494
+ const styles = StyleSheet.create({
495
+ mainContainer: {
496
+ flex: 1,
497
+ backgroundColor: 'transparent',
498
+ },
499
+ gradientBackground: {
500
+ position: 'absolute',
501
+ left: 0,
502
+ right: 0,
503
+ top: 0,
504
+ bottom: 0,
505
+ },
506
+ floatingElement: {
507
+ position: 'absolute',
508
+ borderRadius: 100,
509
+ },
510
+ element1: {
511
+ top: 150,
512
+ right: 30,
513
+ width: 100,
514
+ height: 100,
515
+ },
516
+ element2: {
517
+ bottom: 300,
518
+ left: 50,
519
+ width: 80,
520
+ height: 80,
521
+ },
522
+ gradientOrb: {
523
+ flex: 1,
524
+ borderRadius: 100,
525
+ },
526
+ scrollView: {
527
+ flex: 1,
528
+ backgroundColor: 'transparent',
529
+ },
530
+ container: {
531
+ padding: 16,
532
+ paddingBottom: 100,
533
+ },
534
+ subscriptionBlur: {
535
+ borderRadius: 20,
536
+ overflow: 'hidden',
537
+ backgroundColor: 'rgba(255, 255, 255, 0.1)',
538
+ marginBottom: 24,
539
+ },
540
+ subscriptionCard: {
541
+ padding: 20,
542
+ backgroundColor: 'transparent',
543
+ shadowOpacity: 0,
544
+ elevation: 0,
545
+ },
546
+ subscriptionHeader: {
547
+ flexDirection: 'row',
548
+ justifyContent: 'space-between',
549
+ alignItems: 'center',
550
+ marginBottom: 16,
551
+ },
552
+ subscriptionTitle: {
553
+ fontSize: 20,
554
+ fontWeight: 'bold',
555
+ color: '#1e293b',
556
+ },
557
+ statusBadge: {
558
+ paddingHorizontal: 8,
559
+ paddingVertical: 4,
560
+ },
561
+ subscriptionPricing: {
562
+ marginBottom: 20,
563
+ },
564
+ price: {
565
+ fontSize: 28,
566
+ fontWeight: 'bold',
567
+ color: '#1e293b',
568
+ marginBottom: 4,
569
+ },
570
+ interval: {
571
+ fontSize: 16,
572
+ fontWeight: 'normal',
573
+ color: '#64748b',
574
+ },
575
+ nextBilling: {
576
+ fontSize: 14,
577
+ color: '#64748b',
578
+ },
579
+ features: {
580
+ gap: 12,
581
+ marginBottom: 20,
582
+ },
583
+ feature: {
584
+ flexDirection: 'row',
585
+ alignItems: 'center',
586
+ gap: 8,
587
+ },
588
+ featureText: {
589
+ fontSize: 14,
590
+ color: '#374151',
591
+ },
592
+ subscriptionActions: {
593
+ flexDirection: 'row',
594
+ gap: 12,
595
+ },
596
+ actionButton: {
597
+ flex: 1,
598
+ },
599
+ section: {
600
+ marginBottom: 24,
601
+ },
602
+ sectionHeader: {
603
+ flexDirection: 'row',
604
+ justifyContent: 'space-between',
605
+ alignItems: 'center',
606
+ marginBottom: 16,
607
+ },
608
+ sectionTitle: {
609
+ fontSize: 20,
610
+ fontWeight: '700',
611
+ color: '#1e293b',
612
+ marginBottom: 16,
613
+ },
614
+ paymentMethodBlur: {
615
+ borderRadius: 16,
616
+ overflow: 'hidden',
617
+ backgroundColor: 'rgba(255, 255, 255, 0.1)',
618
+ marginBottom: 12,
619
+ },
620
+ paymentMethodCard: {
621
+ padding: 16,
622
+ backgroundColor: 'transparent',
623
+ shadowOpacity: 0,
624
+ elevation: 0,
625
+ },
626
+ paymentMethodHeader: {
627
+ flexDirection: 'row',
628
+ justifyContent: 'space-between',
629
+ alignItems: 'center',
630
+ marginBottom: 12,
631
+ },
632
+ cardInfo: {
633
+ flex: 1,
634
+ },
635
+ cardBrand: {
636
+ flexDirection: 'row',
637
+ alignItems: 'center',
638
+ gap: 8,
639
+ marginBottom: 4,
640
+ },
641
+ cardText: {
642
+ fontSize: 16,
643
+ fontWeight: '500',
644
+ color: '#1e293b',
645
+ },
646
+ cardExpiry: {
647
+ fontSize: 14,
648
+ color: '#64748b',
649
+ },
650
+ defaultBadge: {
651
+ flexDirection: 'row',
652
+ alignItems: 'center',
653
+ gap: 4,
654
+ },
655
+ paymentMethodActions: {
656
+ flexDirection: 'row',
657
+ justifyContent: 'flex-end',
658
+ gap: 8,
659
+ },
660
+ deleteButton: {
661
+ borderColor: '#ef4444',
662
+ },
663
+ emptyStateBlur: {
664
+ borderRadius: 16,
665
+ overflow: 'hidden',
666
+ backgroundColor: 'rgba(255, 255, 255, 0.1)',
667
+ },
668
+ emptyState: {
669
+ alignItems: 'center',
670
+ padding: 32,
671
+ backgroundColor: 'transparent',
672
+ shadowOpacity: 0,
673
+ elevation: 0,
674
+ },
675
+ emptyTitle: {
676
+ fontSize: 16,
677
+ fontWeight: '600',
678
+ color: '#64748b',
679
+ marginTop: 12,
680
+ marginBottom: 4,
681
+ },
682
+ emptySubtitle: {
683
+ fontSize: 14,
684
+ color: '#94a3b8',
685
+ textAlign: 'center',
686
+ marginBottom: 20,
687
+ },
688
+ addFirstCard: {
689
+ paddingHorizontal: 24,
690
+ },
691
+ invoiceBlur: {
692
+ borderRadius: 16,
693
+ overflow: 'hidden',
694
+ backgroundColor: 'rgba(255, 255, 255, 0.1)',
695
+ marginBottom: 12,
696
+ },
697
+ invoiceCard: {
698
+ padding: 16,
699
+ backgroundColor: 'transparent',
700
+ shadowOpacity: 0,
701
+ elevation: 0,
702
+ },
703
+ invoiceHeader: {
704
+ flexDirection: 'row',
705
+ justifyContent: 'space-between',
706
+ alignItems: 'flex-start',
707
+ marginBottom: 12,
708
+ },
709
+ invoiceNumber: {
710
+ fontSize: 16,
711
+ fontWeight: '600',
712
+ color: '#1e293b',
713
+ marginBottom: 4,
714
+ },
715
+ invoiceDescription: {
716
+ fontSize: 14,
717
+ color: '#64748b',
718
+ },
719
+ invoiceDetails: {
720
+ flexDirection: 'row',
721
+ alignItems: 'center',
722
+ gap: 16,
723
+ },
724
+ invoiceAmount: {
725
+ flexDirection: 'row',
726
+ alignItems: 'center',
727
+ gap: 4,
728
+ },
729
+ amountText: {
730
+ fontSize: 14,
731
+ fontWeight: '500',
732
+ color: '#1e293b',
733
+ },
734
+ invoiceDate: {
735
+ flexDirection: 'row',
736
+ alignItems: 'center',
737
+ gap: 4,
738
+ },
739
+ dateText: {
740
+ fontSize: 12,
741
+ color: '#64748b',
742
+ },
743
+ });