@oxyhq/services 5.3.11 → 5.4.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 (213) hide show
  1. package/README.md +21 -0
  2. package/lib/commonjs/assets/assets/icons/OxyServices.tsx +67 -0
  3. package/lib/commonjs/assets/assets/icons/logo_OxyServices.svg +1 -0
  4. package/lib/commonjs/assets/icons/OxyServices.js +53 -0
  5. package/lib/commonjs/assets/icons/OxyServices.js.map +1 -0
  6. package/lib/commonjs/assets/icons/logo_OxyServices.svg +1 -0
  7. package/lib/commonjs/core/index.js +119 -23
  8. package/lib/commonjs/core/index.js.map +1 -1
  9. package/lib/commonjs/index.js +2 -0
  10. package/lib/commonjs/index.js.map +1 -1
  11. package/lib/commonjs/lib/sonner.js +15 -11
  12. package/lib/commonjs/lib/sonner.js.map +1 -1
  13. package/lib/commonjs/node/index.js +2 -0
  14. package/lib/commonjs/node/index.js.map +1 -1
  15. package/lib/commonjs/ui/components/GroupedItem.js +109 -0
  16. package/lib/commonjs/ui/components/GroupedItem.js.map +1 -0
  17. package/lib/commonjs/ui/components/GroupedSection.js +33 -0
  18. package/lib/commonjs/ui/components/GroupedSection.js.map +1 -0
  19. package/lib/commonjs/ui/components/OxyProvider.js +95 -112
  20. package/lib/commonjs/ui/components/OxyProvider.js.map +1 -1
  21. package/lib/commonjs/ui/components/ProfileCard.js +124 -0
  22. package/lib/commonjs/ui/components/ProfileCard.js.map +1 -0
  23. package/lib/commonjs/ui/components/QuickActions.js +87 -0
  24. package/lib/commonjs/ui/components/QuickActions.js.map +1 -0
  25. package/lib/commonjs/ui/components/Section.js +36 -0
  26. package/lib/commonjs/ui/components/Section.js.map +1 -0
  27. package/lib/commonjs/ui/components/SectionTitle.js +35 -0
  28. package/lib/commonjs/ui/components/SectionTitle.js.map +1 -0
  29. package/lib/commonjs/ui/components/bottomSheet/index.js +6 -6
  30. package/lib/commonjs/ui/components/index.js +97 -0
  31. package/lib/commonjs/ui/components/index.js.map +1 -0
  32. package/lib/commonjs/ui/navigation/OxyRouter.js +20 -3
  33. package/lib/commonjs/ui/navigation/OxyRouter.js.map +1 -1
  34. package/lib/commonjs/ui/screens/AccountCenterScreen.js +190 -207
  35. package/lib/commonjs/ui/screens/AccountCenterScreen.js.map +1 -1
  36. package/lib/commonjs/ui/screens/AccountManagementDemo.js +299 -0
  37. package/lib/commonjs/ui/screens/AccountManagementDemo.js.map +1 -0
  38. package/lib/commonjs/ui/screens/AccountOverviewScreen.js +669 -401
  39. package/lib/commonjs/ui/screens/AccountOverviewScreen.js.map +1 -1
  40. package/lib/commonjs/ui/screens/AccountSettingsScreen.js +695 -498
  41. package/lib/commonjs/ui/screens/AccountSettingsScreen.js.map +1 -1
  42. package/lib/commonjs/ui/screens/AccountSwitcherScreen.js +451 -488
  43. package/lib/commonjs/ui/screens/AccountSwitcherScreen.js.map +1 -1
  44. package/lib/commonjs/ui/screens/AppInfoScreen.js +498 -185
  45. package/lib/commonjs/ui/screens/AppInfoScreen.js.map +1 -1
  46. package/lib/commonjs/ui/screens/BillingManagementScreen.js +636 -0
  47. package/lib/commonjs/ui/screens/BillingManagementScreen.js.map +1 -0
  48. package/lib/commonjs/ui/screens/FileManagementScreen.js +2497 -0
  49. package/lib/commonjs/ui/screens/FileManagementScreen.js.map +1 -0
  50. package/lib/commonjs/ui/screens/PremiumSubscriptionScreen.js +1620 -0
  51. package/lib/commonjs/ui/screens/PremiumSubscriptionScreen.js.map +1 -0
  52. package/lib/commonjs/ui/screens/ProfileScreen.js +117 -13
  53. package/lib/commonjs/ui/screens/ProfileScreen.js.map +1 -1
  54. package/lib/commonjs/ui/screens/SessionManagementScreen.js.map +1 -1
  55. package/lib/commonjs/ui/screens/SignInScreen.js +1 -1
  56. package/lib/commonjs/ui/screens/SignUpScreen.js +1 -1
  57. package/lib/commonjs/utils/polyfills.js +42 -0
  58. package/lib/commonjs/utils/polyfills.js.map +1 -0
  59. package/lib/module/assets/assets/icons/OxyServices.tsx +67 -0
  60. package/lib/module/assets/assets/icons/logo_OxyServices.svg +1 -0
  61. package/lib/module/assets/icons/OxyServices.js +46 -0
  62. package/lib/module/assets/icons/OxyServices.js.map +1 -0
  63. package/lib/module/assets/icons/logo_OxyServices.svg +1 -0
  64. package/lib/module/core/index.js +119 -23
  65. package/lib/module/core/index.js.map +1 -1
  66. package/lib/module/index.js +3 -0
  67. package/lib/module/index.js.map +1 -1
  68. package/lib/module/lib/sonner.js +13 -1
  69. package/lib/module/lib/sonner.js.map +1 -1
  70. package/lib/module/node/index.js +3 -0
  71. package/lib/module/node/index.js.map +1 -1
  72. package/lib/module/ui/components/GroupedItem.js +104 -0
  73. package/lib/module/ui/components/GroupedItem.js.map +1 -0
  74. package/lib/module/ui/components/GroupedSection.js +28 -0
  75. package/lib/module/ui/components/GroupedSection.js.map +1 -0
  76. package/lib/module/ui/components/OxyProvider.js +97 -114
  77. package/lib/module/ui/components/OxyProvider.js.map +1 -1
  78. package/lib/module/ui/components/ProfileCard.js +119 -0
  79. package/lib/module/ui/components/ProfileCard.js.map +1 -0
  80. package/lib/module/ui/components/QuickActions.js +82 -0
  81. package/lib/module/ui/components/QuickActions.js.map +1 -0
  82. package/lib/module/ui/components/Section.js +31 -0
  83. package/lib/module/ui/components/Section.js.map +1 -0
  84. package/lib/module/ui/components/SectionTitle.js +30 -0
  85. package/lib/module/ui/components/SectionTitle.js.map +1 -0
  86. package/lib/module/ui/components/bottomSheet/index.js +2 -5
  87. package/lib/module/ui/components/bottomSheet/index.js.map +1 -1
  88. package/lib/module/ui/components/index.js +18 -0
  89. package/lib/module/ui/components/index.js.map +1 -0
  90. package/lib/module/ui/navigation/OxyRouter.js +20 -3
  91. package/lib/module/ui/navigation/OxyRouter.js.map +1 -1
  92. package/lib/module/ui/screens/AccountCenterScreen.js +191 -208
  93. package/lib/module/ui/screens/AccountCenterScreen.js.map +1 -1
  94. package/lib/module/ui/screens/AccountManagementDemo.js +296 -0
  95. package/lib/module/ui/screens/AccountManagementDemo.js.map +1 -0
  96. package/lib/module/ui/screens/AccountOverviewScreen.js +671 -403
  97. package/lib/module/ui/screens/AccountOverviewScreen.js.map +1 -1
  98. package/lib/module/ui/screens/AccountSettingsScreen.js +698 -501
  99. package/lib/module/ui/screens/AccountSettingsScreen.js.map +1 -1
  100. package/lib/module/ui/screens/AccountSwitcherScreen.js +450 -488
  101. package/lib/module/ui/screens/AccountSwitcherScreen.js.map +1 -1
  102. package/lib/module/ui/screens/AppInfoScreen.js +498 -186
  103. package/lib/module/ui/screens/AppInfoScreen.js.map +1 -1
  104. package/lib/module/ui/screens/BillingManagementScreen.js +631 -0
  105. package/lib/module/ui/screens/BillingManagementScreen.js.map +1 -0
  106. package/lib/module/ui/screens/FileManagementScreen.js +2492 -0
  107. package/lib/module/ui/screens/FileManagementScreen.js.map +1 -0
  108. package/lib/module/ui/screens/PremiumSubscriptionScreen.js +1615 -0
  109. package/lib/module/ui/screens/PremiumSubscriptionScreen.js.map +1 -0
  110. package/lib/module/ui/screens/ProfileScreen.js +118 -14
  111. package/lib/module/ui/screens/ProfileScreen.js.map +1 -1
  112. package/lib/module/ui/screens/SessionManagementScreen.js.map +1 -1
  113. package/lib/module/ui/screens/SignInScreen.js +1 -1
  114. package/lib/module/ui/screens/SignInScreen.js.map +1 -1
  115. package/lib/module/ui/screens/SignUpScreen.js +1 -1
  116. package/lib/module/ui/screens/SignUpScreen.js.map +1 -1
  117. package/lib/module/utils/polyfills.js +36 -0
  118. package/lib/module/utils/polyfills.js.map +1 -0
  119. package/lib/typescript/assets/icons/OxyServices.d.ts +29 -0
  120. package/lib/typescript/assets/icons/OxyServices.d.ts.map +1 -0
  121. package/lib/typescript/core/index.d.ts +26 -1
  122. package/lib/typescript/core/index.d.ts.map +1 -1
  123. package/lib/typescript/index.d.ts +1 -0
  124. package/lib/typescript/index.d.ts.map +1 -1
  125. package/lib/typescript/lib/sonner.d.ts +5 -1
  126. package/lib/typescript/lib/sonner.d.ts.map +1 -1
  127. package/lib/typescript/models/interfaces.d.ts +1 -2
  128. package/lib/typescript/models/interfaces.d.ts.map +1 -1
  129. package/lib/typescript/node/index.d.ts +1 -0
  130. package/lib/typescript/node/index.d.ts.map +1 -1
  131. package/lib/typescript/ui/components/GroupedItem.d.ts +17 -0
  132. package/lib/typescript/ui/components/GroupedItem.d.ts.map +1 -0
  133. package/lib/typescript/ui/components/GroupedSection.d.ts +19 -0
  134. package/lib/typescript/ui/components/GroupedSection.d.ts.map +1 -0
  135. package/lib/typescript/ui/components/OxyProvider.d.ts.map +1 -1
  136. package/lib/typescript/ui/components/ProfileCard.d.ts +20 -0
  137. package/lib/typescript/ui/components/ProfileCard.d.ts.map +1 -0
  138. package/lib/typescript/ui/components/QuickActions.d.ts +15 -0
  139. package/lib/typescript/ui/components/QuickActions.d.ts.map +1 -0
  140. package/lib/typescript/ui/components/Section.d.ts +11 -0
  141. package/lib/typescript/ui/components/Section.d.ts.map +1 -0
  142. package/lib/typescript/ui/components/SectionTitle.d.ts +9 -0
  143. package/lib/typescript/ui/components/SectionTitle.d.ts.map +1 -0
  144. package/lib/typescript/ui/components/bottomSheet/index.d.ts +3 -2
  145. package/lib/typescript/ui/components/bottomSheet/index.d.ts.map +1 -1
  146. package/lib/typescript/ui/components/index.d.ts +13 -0
  147. package/lib/typescript/ui/components/index.d.ts.map +1 -0
  148. package/lib/typescript/ui/navigation/OxyRouter.d.ts.map +1 -1
  149. package/lib/typescript/ui/navigation/types.d.ts +8 -0
  150. package/lib/typescript/ui/navigation/types.d.ts.map +1 -1
  151. package/lib/typescript/ui/screens/AccountCenterScreen.d.ts.map +1 -1
  152. package/lib/typescript/ui/screens/AccountManagementDemo.d.ts +8 -0
  153. package/lib/typescript/ui/screens/AccountManagementDemo.d.ts.map +1 -0
  154. package/lib/typescript/ui/screens/AccountOverviewScreen.d.ts.map +1 -1
  155. package/lib/typescript/ui/screens/AccountSettingsScreen.d.ts +1 -4
  156. package/lib/typescript/ui/screens/AccountSettingsScreen.d.ts.map +1 -1
  157. package/lib/typescript/ui/screens/AccountSwitcherScreen.d.ts.map +1 -1
  158. package/lib/typescript/ui/screens/AppInfoScreen.d.ts.map +1 -1
  159. package/lib/typescript/ui/screens/BillingManagementScreen.d.ts +5 -0
  160. package/lib/typescript/ui/screens/BillingManagementScreen.d.ts.map +1 -0
  161. package/lib/typescript/ui/screens/FileManagementScreen.d.ts +8 -0
  162. package/lib/typescript/ui/screens/FileManagementScreen.d.ts.map +1 -0
  163. package/lib/typescript/ui/screens/PremiumSubscriptionScreen.d.ts +5 -0
  164. package/lib/typescript/ui/screens/PremiumSubscriptionScreen.d.ts.map +1 -0
  165. package/lib/typescript/ui/screens/ProfileScreen.d.ts.map +1 -1
  166. package/lib/typescript/ui/screens/SessionManagementScreen.d.ts.map +1 -1
  167. package/lib/typescript/utils/polyfills.d.ts +6 -0
  168. package/lib/typescript/utils/polyfills.d.ts.map +1 -0
  169. package/package.json +11 -3
  170. package/src/__tests__/polyfills.test.ts +30 -0
  171. package/src/__tests__/setup.ts +43 -0
  172. package/src/__tests__/ui/screens/AccountSettingsScreen.test.tsx +8 -8
  173. package/src/assets/icons/OxyServices.tsx +67 -0
  174. package/src/assets/icons/logo_OxyServices.svg +1 -0
  175. package/src/core/index.ts +127 -19
  176. package/src/index.ts +3 -0
  177. package/src/lib/sonner.ts +10 -1
  178. package/src/models/interfaces.ts +1 -2
  179. package/src/node/index.ts +3 -0
  180. package/src/ui/components/GroupedItem.tsx +118 -0
  181. package/src/ui/components/GroupedSection.tsx +45 -0
  182. package/src/ui/components/OxyProvider.tsx +95 -120
  183. package/src/ui/components/ProfileCard.tsx +129 -0
  184. package/src/ui/components/QuickActions.tsx +90 -0
  185. package/src/ui/components/Section.tsx +37 -0
  186. package/src/ui/components/SectionTitle.tsx +31 -0
  187. package/src/ui/components/bottomSheet/index.tsx +13 -11
  188. package/src/ui/components/index.ts +15 -0
  189. package/src/ui/navigation/OxyRouter.tsx +20 -3
  190. package/src/ui/navigation/types.ts +10 -1
  191. package/src/ui/screens/AccountCenterScreen.tsx +188 -159
  192. package/src/ui/screens/AccountManagementDemo.tsx +297 -0
  193. package/src/ui/screens/AccountOverviewScreen.tsx +474 -310
  194. package/src/ui/screens/AccountSettingsScreen.tsx +648 -463
  195. package/src/ui/screens/AccountSwitcherScreen.tsx +385 -449
  196. package/src/ui/screens/AppInfoScreen.tsx +571 -140
  197. package/src/ui/screens/BillingManagementScreen.tsx +589 -0
  198. package/src/ui/screens/FileManagementScreen.tsx +2513 -0
  199. package/src/ui/screens/PremiumSubscriptionScreen.tsx +1628 -0
  200. package/src/ui/screens/ProfileScreen.tsx +101 -7
  201. package/src/ui/screens/SessionManagementScreen.tsx +1 -0
  202. package/src/ui/screens/SignInScreen.tsx +1 -1
  203. package/src/ui/screens/SignUpScreen.tsx +1 -1
  204. package/src/utils/polyfills.ts +34 -0
  205. package/lib/commonjs/lib/sonner.web.js +0 -17
  206. package/lib/commonjs/lib/sonner.web.js.map +0 -1
  207. package/lib/module/lib/sonner.web.js +0 -4
  208. package/lib/module/lib/sonner.web.js.map +0 -1
  209. package/lib/typescript/__tests__/ui/screens/AccountSettingsScreen.test.d.ts +0 -2
  210. package/lib/typescript/__tests__/ui/screens/AccountSettingsScreen.test.d.ts.map +0 -1
  211. package/lib/typescript/lib/sonner.web.d.ts +0 -2
  212. package/lib/typescript/lib/sonner.web.d.ts.map +0 -1
  213. package/src/lib/sonner.web.ts +0 -1
@@ -0,0 +1,589 @@
1
+ import React, { useState, useEffect } from 'react';
2
+ import {
3
+ View,
4
+ Text,
5
+ TouchableOpacity,
6
+ StyleSheet,
7
+ ScrollView,
8
+ ActivityIndicator,
9
+ Alert,
10
+ Platform,
11
+ } from 'react-native';
12
+ import { BaseScreenProps } from '../navigation/types';
13
+ import { useOxy } from '../context/OxyContext';
14
+ import { fontFamilies } from '../styles/fonts';
15
+ import { toast } from '../../lib/sonner';
16
+ import { Ionicons } from '@expo/vector-icons';
17
+
18
+ interface PaymentMethod {
19
+ id: string;
20
+ type: 'card' | 'paypal' | 'bank';
21
+ last4?: string;
22
+ brand?: string;
23
+ expiryMonth?: number;
24
+ expiryYear?: number;
25
+ isDefault: boolean;
26
+ }
27
+
28
+ interface Invoice {
29
+ id: string;
30
+ date: string;
31
+ amount: number;
32
+ currency: string;
33
+ status: 'paid' | 'pending' | 'failed';
34
+ description: string;
35
+ downloadUrl?: string;
36
+ }
37
+
38
+ const BillingManagementScreen: React.FC<BaseScreenProps> = ({
39
+ onClose,
40
+ theme,
41
+ navigate,
42
+ goBack,
43
+ }) => {
44
+ const { user } = useOxy();
45
+ const [loading, setLoading] = useState(true);
46
+ const [paymentMethods, setPaymentMethods] = useState<PaymentMethod[]>([]);
47
+ const [invoices, setInvoices] = useState<Invoice[]>([]);
48
+ const [processingPayment, setProcessingPayment] = useState(false);
49
+
50
+ const isDarkTheme = theme === 'dark';
51
+ const textColor = isDarkTheme ? '#FFFFFF' : '#000000';
52
+ const backgroundColor = isDarkTheme ? '#121212' : '#FFFFFF';
53
+ const secondaryBackgroundColor = isDarkTheme ? '#222222' : '#F5F5F5';
54
+ const borderColor = isDarkTheme ? '#444444' : '#E0E0E0';
55
+ const primaryColor = '#007AFF';
56
+ const successColor = '#30D158';
57
+ const warningColor = '#FF9500';
58
+ const dangerColor = '#FF3B30';
59
+
60
+ // Mock data
61
+ const mockPaymentMethods: PaymentMethod[] = [
62
+ {
63
+ id: 'pm_1',
64
+ type: 'card',
65
+ last4: '4242',
66
+ brand: 'Visa',
67
+ expiryMonth: 12,
68
+ expiryYear: 2027,
69
+ isDefault: true
70
+ },
71
+ {
72
+ id: 'pm_2',
73
+ type: 'paypal',
74
+ isDefault: false
75
+ }
76
+ ];
77
+
78
+ const mockInvoices: Invoice[] = [
79
+ {
80
+ id: 'inv_1',
81
+ date: '2024-12-01',
82
+ amount: 19.99,
83
+ currency: 'USD',
84
+ status: 'paid',
85
+ description: 'Pro Plan - Monthly'
86
+ },
87
+ {
88
+ id: 'inv_2',
89
+ date: '2024-11-01',
90
+ amount: 19.99,
91
+ currency: 'USD',
92
+ status: 'paid',
93
+ description: 'Pro Plan - Monthly'
94
+ },
95
+ {
96
+ id: 'inv_3',
97
+ date: '2024-10-01',
98
+ amount: 19.99,
99
+ currency: 'USD',
100
+ status: 'paid',
101
+ description: 'Pro Plan - Monthly'
102
+ }
103
+ ];
104
+
105
+ useEffect(() => {
106
+ loadBillingData();
107
+ }, []);
108
+
109
+ const loadBillingData = async () => {
110
+ try {
111
+ setLoading(true);
112
+
113
+ // Simulate API calls
114
+ await new Promise(resolve => setTimeout(resolve, 1000));
115
+
116
+ setPaymentMethods(mockPaymentMethods);
117
+ setInvoices(mockInvoices);
118
+ } catch (error) {
119
+ console.error('Failed to load billing data:', error);
120
+ toast.error('Failed to load billing information');
121
+ } finally {
122
+ setLoading(false);
123
+ }
124
+ };
125
+
126
+ const handleAddPaymentMethod = () => {
127
+ Alert.alert(
128
+ 'Add Payment Method',
129
+ 'This would open a secure payment form to add a new payment method.',
130
+ [{ text: 'OK' }]
131
+ );
132
+ };
133
+
134
+ const handleSetDefaultPaymentMethod = async (methodId: string) => {
135
+ try {
136
+ setPaymentMethods(prev => prev.map(method => ({
137
+ ...method,
138
+ isDefault: method.id === methodId
139
+ })));
140
+ toast.success('Default payment method updated');
141
+ } catch (error) {
142
+ toast.error('Failed to update payment method');
143
+ }
144
+ };
145
+
146
+ const handleRemovePaymentMethod = (methodId: string) => {
147
+ Alert.alert(
148
+ 'Remove Payment Method',
149
+ 'Are you sure you want to remove this payment method?',
150
+ [
151
+ { text: 'Cancel', style: 'cancel' },
152
+ {
153
+ text: 'Remove',
154
+ style: 'destructive',
155
+ onPress: async () => {
156
+ try {
157
+ setPaymentMethods(prev => prev.filter(method => method.id !== methodId));
158
+ toast.success('Payment method removed');
159
+ } catch (error) {
160
+ toast.error('Failed to remove payment method');
161
+ }
162
+ }
163
+ }
164
+ ]
165
+ );
166
+ };
167
+
168
+ const handleDownloadInvoice = (invoice: Invoice) => {
169
+ toast.info('Invoice download would start here');
170
+ };
171
+
172
+ const getPaymentMethodIcon = (method: PaymentMethod) => {
173
+ switch (method.type) {
174
+ case 'card':
175
+ return method.brand?.toLowerCase() === 'visa' ? 'card' : 'card-outline';
176
+ case 'paypal':
177
+ return 'logo-paypal';
178
+ case 'bank':
179
+ return 'business';
180
+ default:
181
+ return 'card';
182
+ }
183
+ };
184
+
185
+ const getPaymentMethodDisplay = (method: PaymentMethod) => {
186
+ switch (method.type) {
187
+ case 'card':
188
+ return `${method.brand} •••• ${method.last4}`;
189
+ case 'paypal':
190
+ return 'PayPal';
191
+ case 'bank':
192
+ return 'Bank Transfer';
193
+ default:
194
+ return 'Unknown';
195
+ }
196
+ };
197
+
198
+ const getStatusColor = (status: string) => {
199
+ switch (status) {
200
+ case 'paid':
201
+ return successColor;
202
+ case 'pending':
203
+ return warningColor;
204
+ case 'failed':
205
+ return dangerColor;
206
+ default:
207
+ return textColor;
208
+ }
209
+ };
210
+
211
+ if (loading) {
212
+ return (
213
+ <View style={[styles.container, { backgroundColor, justifyContent: 'center' }]}>
214
+ <ActivityIndicator size="large" color={primaryColor} />
215
+ <Text style={[styles.loadingText, { color: textColor }]}>Loading billing information...</Text>
216
+ </View>
217
+ );
218
+ }
219
+
220
+ return (
221
+ <View style={[styles.container, { backgroundColor }]}>
222
+ {/* Header */}
223
+ <View style={[styles.header, { borderBottomColor: borderColor }]}>
224
+ <TouchableOpacity style={styles.backButton} onPress={goBack}>
225
+ <Ionicons name="arrow-back" size={24} color={textColor} />
226
+ </TouchableOpacity>
227
+ <Text style={[styles.headerTitle, { color: textColor }]}>Billing Management</Text>
228
+ {onClose && (
229
+ <TouchableOpacity style={styles.closeButton} onPress={onClose}>
230
+ <Ionicons name="close" size={24} color={textColor} />
231
+ </TouchableOpacity>
232
+ )}
233
+ </View>
234
+
235
+ <ScrollView style={styles.content} showsVerticalScrollIndicator={false}>
236
+ {/* Payment Methods */}
237
+ <View style={styles.section}>
238
+ <View style={styles.sectionHeader}>
239
+ <Text style={[styles.sectionTitle, { color: textColor }]}>Payment Methods</Text>
240
+ <TouchableOpacity
241
+ style={[styles.addButton, { backgroundColor: primaryColor }]}
242
+ onPress={handleAddPaymentMethod}
243
+ >
244
+ <Ionicons name="add" size={20} color="#FFFFFF" />
245
+ <Text style={styles.addButtonText}>Add</Text>
246
+ </TouchableOpacity>
247
+ </View>
248
+
249
+ {paymentMethods.map((method) => (
250
+ <View
251
+ key={method.id}
252
+ style={[styles.paymentMethodCard, { backgroundColor: secondaryBackgroundColor, borderColor }]}
253
+ >
254
+ <View style={styles.paymentMethodHeader}>
255
+ <View style={styles.paymentMethodInfo}>
256
+ <Ionicons
257
+ name={getPaymentMethodIcon(method)}
258
+ size={24}
259
+ color={primaryColor}
260
+ style={styles.paymentMethodIcon}
261
+ />
262
+ <View>
263
+ <Text style={[styles.paymentMethodName, { color: textColor }]}>
264
+ {getPaymentMethodDisplay(method)}
265
+ </Text>
266
+ {method.type === 'card' && (
267
+ <Text style={[styles.paymentMethodExpiry, { color: isDarkTheme ? '#BBBBBB' : '#666666' }]}>
268
+ Expires {method.expiryMonth}/{method.expiryYear}
269
+ </Text>
270
+ )}
271
+ {method.isDefault && (
272
+ <View style={[styles.defaultBadge, { backgroundColor: successColor }]}>
273
+ <Text style={styles.defaultText}>Default</Text>
274
+ </View>
275
+ )}
276
+ </View>
277
+ </View>
278
+
279
+ <View style={styles.paymentMethodActions}>
280
+ {!method.isDefault && (
281
+ <TouchableOpacity
282
+ style={[styles.actionButton, { borderColor }]}
283
+ onPress={() => handleSetDefaultPaymentMethod(method.id)}
284
+ >
285
+ <Text style={[styles.actionButtonText, { color: textColor }]}>
286
+ Set Default
287
+ </Text>
288
+ </TouchableOpacity>
289
+ )}
290
+ <TouchableOpacity
291
+ style={[styles.actionButton, { borderColor: dangerColor }]}
292
+ onPress={() => handleRemovePaymentMethod(method.id)}
293
+ >
294
+ <Text style={[styles.actionButtonText, { color: dangerColor }]}>
295
+ Remove
296
+ </Text>
297
+ </TouchableOpacity>
298
+ </View>
299
+ </View>
300
+ </View>
301
+ ))}
302
+ </View>
303
+
304
+ {/* Billing History */}
305
+ <View style={styles.section}>
306
+ <Text style={[styles.sectionTitle, { color: textColor }]}>Billing History</Text>
307
+
308
+ {invoices.map((invoice) => (
309
+ <View
310
+ key={invoice.id}
311
+ style={[styles.invoiceCard, { backgroundColor: secondaryBackgroundColor, borderColor }]}
312
+ >
313
+ <View style={styles.invoiceHeader}>
314
+ <View style={styles.invoiceInfo}>
315
+ <Text style={[styles.invoiceDescription, { color: textColor }]}>
316
+ {invoice.description}
317
+ </Text>
318
+ <Text style={[styles.invoiceDate, { color: isDarkTheme ? '#BBBBBB' : '#666666' }]}>
319
+ {new Date(invoice.date).toLocaleDateString()}
320
+ </Text>
321
+ </View>
322
+
323
+ <View style={styles.invoiceAmount}>
324
+ <Text style={[styles.invoicePrice, { color: textColor }]}>
325
+ ${invoice.amount.toFixed(2)}
326
+ </Text>
327
+ <View style={[styles.statusBadge, { backgroundColor: getStatusColor(invoice.status) }]}>
328
+ <Text style={styles.statusText}>
329
+ {invoice.status.toUpperCase()}
330
+ </Text>
331
+ </View>
332
+ </View>
333
+ </View>
334
+
335
+ <View style={styles.invoiceActions}>
336
+ <TouchableOpacity
337
+ style={[styles.downloadButton, { borderColor }]}
338
+ onPress={() => handleDownloadInvoice(invoice)}
339
+ >
340
+ <Ionicons name="download" size={16} color={primaryColor} />
341
+ <Text style={[styles.downloadButtonText, { color: primaryColor }]}>
342
+ Download
343
+ </Text>
344
+ </TouchableOpacity>
345
+ </View>
346
+ </View>
347
+ ))}
348
+ </View>
349
+
350
+ {/* Billing Information */}
351
+ <View style={styles.section}>
352
+ <Text style={[styles.sectionTitle, { color: textColor }]}>Billing Information</Text>
353
+
354
+ <View style={[styles.billingInfoCard, { backgroundColor: secondaryBackgroundColor, borderColor }]}>
355
+ <View style={styles.billingInfoItem}>
356
+ <Ionicons name="business" size={20} color={primaryColor} />
357
+ <View style={styles.billingInfoContent}>
358
+ <Text style={[styles.billingInfoLabel, { color: textColor }]}>Billing Address</Text>
359
+ <Text style={[styles.billingInfoValue, { color: isDarkTheme ? '#BBBBBB' : '#666666' }]}>
360
+ Update your billing address
361
+ </Text>
362
+ </View>
363
+ <TouchableOpacity>
364
+ <Ionicons name="chevron-forward" size={20} color={isDarkTheme ? '#666666' : '#999999'} />
365
+ </TouchableOpacity>
366
+ </View>
367
+
368
+ <View style={styles.billingInfoItem}>
369
+ <Ionicons name="receipt" size={20} color={primaryColor} />
370
+ <View style={styles.billingInfoContent}>
371
+ <Text style={[styles.billingInfoLabel, { color: textColor }]}>Tax Information</Text>
372
+ <Text style={[styles.billingInfoValue, { color: isDarkTheme ? '#BBBBBB' : '#666666' }]}>
373
+ Manage tax settings
374
+ </Text>
375
+ </View>
376
+ <TouchableOpacity>
377
+ <Ionicons name="chevron-forward" size={20} color={isDarkTheme ? '#666666' : '#999999'} />
378
+ </TouchableOpacity>
379
+ </View>
380
+ </View>
381
+ </View>
382
+
383
+ <View style={styles.bottomSpacing} />
384
+ </ScrollView>
385
+ </View>
386
+ );
387
+ };
388
+
389
+ const styles = StyleSheet.create({
390
+ container: {
391
+ flex: 1,
392
+ },
393
+ header: {
394
+ flexDirection: 'row',
395
+ alignItems: 'center',
396
+ justifyContent: 'space-between',
397
+ paddingHorizontal: 20,
398
+ paddingTop: 20,
399
+ paddingBottom: 16,
400
+ borderBottomWidth: 1,
401
+ },
402
+ backButton: {
403
+ padding: 8,
404
+ },
405
+ headerTitle: {
406
+ fontSize: 20,
407
+ fontWeight: '600',
408
+ fontFamily: fontFamilies.phuduSemiBold,
409
+ },
410
+ closeButton: {
411
+ padding: 8,
412
+ },
413
+ content: {
414
+ flex: 1,
415
+ },
416
+ section: {
417
+ padding: 20,
418
+ },
419
+ sectionHeader: {
420
+ flexDirection: 'row',
421
+ justifyContent: 'space-between',
422
+ alignItems: 'center',
423
+ marginBottom: 16,
424
+ },
425
+ sectionTitle: {
426
+ fontSize: 20,
427
+ fontWeight: 'bold',
428
+ fontFamily: fontFamilies.phuduBold,
429
+ },
430
+ addButton: {
431
+ flexDirection: 'row',
432
+ alignItems: 'center',
433
+ paddingHorizontal: 12,
434
+ paddingVertical: 8,
435
+ borderRadius: 8,
436
+ },
437
+ addButtonText: {
438
+ color: '#FFFFFF',
439
+ fontSize: 14,
440
+ fontWeight: '600',
441
+ marginLeft: 4,
442
+ },
443
+ loadingText: {
444
+ fontSize: 16,
445
+ textAlign: 'center',
446
+ marginTop: 16,
447
+ },
448
+ paymentMethodCard: {
449
+ borderRadius: 12,
450
+ padding: 16,
451
+ marginBottom: 12,
452
+ borderWidth: 1,
453
+ },
454
+ paymentMethodHeader: {
455
+ flexDirection: 'row',
456
+ justifyContent: 'space-between',
457
+ alignItems: 'flex-start',
458
+ },
459
+ paymentMethodInfo: {
460
+ flexDirection: 'row',
461
+ alignItems: 'flex-start',
462
+ flex: 1,
463
+ },
464
+ paymentMethodIcon: {
465
+ marginRight: 12,
466
+ marginTop: 2,
467
+ },
468
+ paymentMethodName: {
469
+ fontSize: 16,
470
+ fontWeight: '600',
471
+ marginBottom: 4,
472
+ },
473
+ paymentMethodExpiry: {
474
+ fontSize: 14,
475
+ marginBottom: 8,
476
+ },
477
+ defaultBadge: {
478
+ paddingHorizontal: 8,
479
+ paddingVertical: 2,
480
+ borderRadius: 4,
481
+ alignSelf: 'flex-start',
482
+ },
483
+ defaultText: {
484
+ color: '#FFFFFF',
485
+ fontSize: 12,
486
+ fontWeight: '600',
487
+ },
488
+ paymentMethodActions: {
489
+ flexDirection: 'row',
490
+ gap: 8,
491
+ },
492
+ actionButton: {
493
+ paddingHorizontal: 12,
494
+ paddingVertical: 6,
495
+ borderRadius: 6,
496
+ borderWidth: 1,
497
+ },
498
+ actionButtonText: {
499
+ fontSize: 12,
500
+ fontWeight: '600',
501
+ },
502
+ invoiceCard: {
503
+ borderRadius: 12,
504
+ padding: 16,
505
+ marginBottom: 12,
506
+ borderWidth: 1,
507
+ },
508
+ invoiceHeader: {
509
+ flexDirection: 'row',
510
+ justifyContent: 'space-between',
511
+ alignItems: 'flex-start',
512
+ marginBottom: 12,
513
+ },
514
+ invoiceInfo: {
515
+ flex: 1,
516
+ },
517
+ invoiceDescription: {
518
+ fontSize: 16,
519
+ fontWeight: '600',
520
+ marginBottom: 4,
521
+ },
522
+ invoiceDate: {
523
+ fontSize: 14,
524
+ },
525
+ invoiceAmount: {
526
+ alignItems: 'flex-end',
527
+ },
528
+ invoicePrice: {
529
+ fontSize: 16,
530
+ fontWeight: '600',
531
+ marginBottom: 4,
532
+ },
533
+ statusBadge: {
534
+ paddingHorizontal: 8,
535
+ paddingVertical: 2,
536
+ borderRadius: 4,
537
+ },
538
+ statusText: {
539
+ color: '#FFFFFF',
540
+ fontSize: 12,
541
+ fontWeight: '600',
542
+ },
543
+ invoiceActions: {
544
+ flexDirection: 'row',
545
+ justifyContent: 'flex-end',
546
+ },
547
+ downloadButton: {
548
+ flexDirection: 'row',
549
+ alignItems: 'center',
550
+ paddingHorizontal: 12,
551
+ paddingVertical: 6,
552
+ borderRadius: 6,
553
+ borderWidth: 1,
554
+ },
555
+ downloadButtonText: {
556
+ fontSize: 12,
557
+ fontWeight: '600',
558
+ marginLeft: 4,
559
+ },
560
+ billingInfoCard: {
561
+ borderRadius: 12,
562
+ borderWidth: 1,
563
+ overflow: 'hidden',
564
+ },
565
+ billingInfoItem: {
566
+ flexDirection: 'row',
567
+ alignItems: 'center',
568
+ padding: 16,
569
+ borderBottomWidth: 1,
570
+ borderBottomColor: 'rgba(0, 0, 0, 0.05)',
571
+ },
572
+ billingInfoContent: {
573
+ flex: 1,
574
+ marginLeft: 12,
575
+ },
576
+ billingInfoLabel: {
577
+ fontSize: 16,
578
+ fontWeight: '600',
579
+ marginBottom: 4,
580
+ },
581
+ billingInfoValue: {
582
+ fontSize: 14,
583
+ },
584
+ bottomSpacing: {
585
+ height: 40,
586
+ },
587
+ });
588
+
589
+ export default BillingManagementScreen;