@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
@@ -16,6 +16,10 @@ import { useOxy } from '../context/OxyContext';
16
16
  import { fontFamilies } from '../styles/fonts';
17
17
  import { packageInfo } from '../../constants/version';
18
18
  import { toast } from '../../lib/sonner';
19
+ import OxyIcon from '../components/icon/OxyIcon';
20
+ import { Ionicons } from '@expo/vector-icons';
21
+ import OxyServicesLogo from '../../assets/icons/OxyServices';
22
+
19
23
 
20
24
  interface SystemInfo {
21
25
  platform: string;
@@ -32,28 +36,62 @@ const AppInfoScreen: React.FC<BaseScreenProps> = ({
32
36
  theme,
33
37
  navigate,
34
38
  }) => {
35
- const { user, sessions } = useOxy();
39
+ const { user, sessions, oxyServices } = useOxy();
36
40
  const [systemInfo, setSystemInfo] = useState<SystemInfo | null>(null);
41
+ const [isRunningSystemCheck, setIsRunningSystemCheck] = useState(false);
42
+ const [connectionStatus, setConnectionStatus] = useState<'checking' | 'connected' | 'disconnected' | 'unknown'>('unknown');
37
43
 
38
44
  const isDarkTheme = theme === 'dark';
39
- const textColor = isDarkTheme ? '#FFFFFF' : '#000000';
40
- const backgroundColor = isDarkTheme ? '#121212' : '#FFFFFF';
41
- const secondaryBackgroundColor = isDarkTheme ? '#222222' : '#F5F5F5';
42
- const borderColor = isDarkTheme ? '#444444' : '#E0E0E0';
43
- const primaryColor = '#0066CC';
44
- const successColor = '#4CAF50';
45
+ const backgroundColor = isDarkTheme ? '#121212' : '#f2f2f2';
46
+ const primaryColor = '#007AFF';
45
47
 
46
48
  useEffect(() => {
47
- const dimensions = Dimensions.get('window');
48
- setSystemInfo({
49
- platform: Platform.OS,
50
- version: Platform.Version?.toString() || 'Unknown',
51
- screenDimensions: {
52
- width: dimensions.width,
53
- height: dimensions.height,
54
- },
55
- timestamp: new Date().toISOString(),
56
- });
49
+ const updateDimensions = () => {
50
+ const dimensions = Dimensions.get('window');
51
+ setSystemInfo(prev => ({
52
+ ...prev,
53
+ platform: Platform.OS,
54
+ version: Platform.Version?.toString() || 'Unknown',
55
+ screenDimensions: {
56
+ width: dimensions.width,
57
+ height: dimensions.height,
58
+ },
59
+ timestamp: new Date().toISOString(),
60
+ }));
61
+ };
62
+
63
+ // Set initial dimensions
64
+ updateDimensions();
65
+
66
+ // Listen for dimension changes
67
+ const subscription = Dimensions.addEventListener('change', updateDimensions);
68
+
69
+ // Check API connection on mount
70
+ const checkConnection = async () => {
71
+ setConnectionStatus('checking');
72
+ const apiBaseUrl = oxyServices?.getBaseURL() || 'https://api.oxy.so';
73
+ try {
74
+ const response = await fetch(`${apiBaseUrl}/`, {
75
+ method: 'GET',
76
+ timeout: 3000,
77
+ } as any);
78
+
79
+ if (response.ok) {
80
+ setConnectionStatus('connected');
81
+ } else {
82
+ setConnectionStatus('disconnected');
83
+ }
84
+ } catch (error) {
85
+ setConnectionStatus('disconnected');
86
+ }
87
+ };
88
+
89
+ checkConnection();
90
+
91
+ // Cleanup listener on unmount
92
+ return () => {
93
+ subscription?.remove();
94
+ };
57
95
  }, []);
58
96
 
59
97
  const copyToClipboard = async (text: string, label: string) => {
@@ -65,6 +103,138 @@ const AppInfoScreen: React.FC<BaseScreenProps> = ({
65
103
  }
66
104
  };
67
105
 
106
+ const runSystemCheck = async () => {
107
+ if (!oxyServices) {
108
+ toast.error('OxyServices not initialized');
109
+ return;
110
+ }
111
+
112
+ setIsRunningSystemCheck(true);
113
+ const checks = [];
114
+
115
+ // Get the API base URL from the services instance
116
+ const apiBaseUrl = oxyServices?.getBaseURL() || 'https://api.oxy.so'; // Default for now, could be made configurable
117
+
118
+ try {
119
+ // Check 1: API Server Health
120
+ checks.push('🔍 Checking API server connection...');
121
+ toast.info('Running system checks...', { duration: 2000 });
122
+
123
+ try {
124
+ const response = await fetch(`${apiBaseUrl}/`, {
125
+ method: 'GET',
126
+ timeout: 5000,
127
+ } as any);
128
+
129
+ if (response.ok) {
130
+ const data = await response.json();
131
+ checks.push('✅ API server is responding');
132
+ checks.push(`📊 Server stats: ${data.users || 0} users`);
133
+ checks.push(`🌐 API URL: ${apiBaseUrl}`);
134
+ setConnectionStatus('connected');
135
+ } else {
136
+ checks.push('❌ API server returned error status');
137
+ checks.push(` Status: ${response.status} ${response.statusText}`);
138
+ setConnectionStatus('disconnected');
139
+ }
140
+ } catch (error) {
141
+ checks.push('❌ API server connection failed');
142
+ checks.push(` Error: ${error instanceof Error ? error.message : 'Unknown error'}`);
143
+ checks.push(` URL: ${apiBaseUrl}`);
144
+ setConnectionStatus('disconnected');
145
+ }
146
+
147
+ // Check 2: Authentication Status
148
+ checks.push('🔍 Checking authentication...');
149
+ if (oxyServices.isAuthenticated()) {
150
+ checks.push('✅ User is authenticated');
151
+
152
+ // Check 3: Token Validation
153
+ try {
154
+ const isValid = await oxyServices.validate();
155
+ if (isValid) {
156
+ checks.push('✅ Authentication token is valid');
157
+ } else {
158
+ checks.push('❌ Authentication token is invalid');
159
+ }
160
+ } catch (error) {
161
+ checks.push('❌ Token validation failed');
162
+ checks.push(` Error: ${error instanceof Error ? error.message : 'Unknown error'}`);
163
+ }
164
+ } else {
165
+ checks.push('⚠️ User is not authenticated');
166
+ }
167
+
168
+ // Check 4: Session Validation (if user has active sessions)
169
+ if (user && sessions && sessions.length > 0) {
170
+ checks.push('🔍 Checking active sessions...');
171
+ try {
172
+ // Just check if we can fetch sessions
173
+ const userSessions = await oxyServices.getUserSessions();
174
+ checks.push(`✅ Session validation successful (${userSessions.length} sessions)`);
175
+ } catch (error) {
176
+ checks.push('❌ Session validation failed');
177
+ checks.push(` Error: ${error instanceof Error ? error.message : 'Unknown error'}`);
178
+ }
179
+ }
180
+
181
+ // Check 5: Platform Information
182
+ checks.push('🔍 Checking platform information...');
183
+ checks.push(`✅ Platform: ${Platform.OS} ${Platform.Version || 'Unknown'}`);
184
+ checks.push(`✅ Screen: ${systemInfo?.screenDimensions.width || 0}x${systemInfo?.screenDimensions.height || 0}`);
185
+ checks.push(`✅ Environment: ${__DEV__ ? 'Development' : 'Production'}`);
186
+
187
+ // Check 6: Package Information
188
+ checks.push('🔍 Checking package information...');
189
+ checks.push(`✅ Package: ${packageInfo.name}@${packageInfo.version}`);
190
+
191
+ // Check 7: Memory and Performance (basic)
192
+ checks.push('🔍 Checking performance metrics...');
193
+ const memoryUsage = (performance as any).memory;
194
+ if (memoryUsage) {
195
+ const usedMB = Math.round(memoryUsage.usedJSHeapSize / 1024 / 1024);
196
+ const totalMB = Math.round(memoryUsage.totalJSHeapSize / 1024 / 1024);
197
+ checks.push(`✅ Memory usage: ${usedMB}MB / ${totalMB}MB`);
198
+ } else {
199
+ checks.push('✅ Performance metrics not available on this platform');
200
+ }
201
+
202
+ // Final summary
203
+ const errorCount = checks.filter(check => check.includes('❌')).length;
204
+ const warningCount = checks.filter(check => check.includes('⚠️')).length;
205
+
206
+ checks.push('');
207
+ checks.push('📋 SYSTEM CHECK SUMMARY:');
208
+ if (errorCount === 0 && warningCount === 0) {
209
+ checks.push('✅ All systems operational');
210
+ toast.success('System check completed - All systems operational!');
211
+ } else if (errorCount === 0) {
212
+ checks.push(`⚠️ ${warningCount} warning(s) found`);
213
+ toast.warning(`System check completed with ${warningCount} warning(s)`);
214
+ } else {
215
+ checks.push(`❌ ${errorCount} error(s) and ${warningCount} warning(s) found`);
216
+ toast.error(`System check failed with ${errorCount} error(s)`);
217
+ }
218
+
219
+ // Show results in an alert and copy to clipboard
220
+ const report = checks.join('\n');
221
+ Alert.alert(
222
+ 'System Check Results',
223
+ `Check completed. Results copied to clipboard.\n\nSummary: ${errorCount} errors, ${warningCount} warnings`,
224
+ [
225
+ { text: 'View Full Report', onPress: () => copyToClipboard(report, 'System check report') },
226
+ { text: 'OK', style: 'default' }
227
+ ]
228
+ );
229
+
230
+ } catch (error) {
231
+ toast.error('System check failed to run');
232
+ console.error('System check error:', error);
233
+ } finally {
234
+ setIsRunningSystemCheck(false);
235
+ }
236
+ };
237
+
68
238
  const generateFullReport = () => {
69
239
  const report = {
70
240
  packageInfo: {
@@ -80,7 +250,7 @@ const AppInfoScreen: React.FC<BaseScreenProps> = ({
80
250
  totalUsers: sessions?.length || 0,
81
251
  },
82
252
  apiConfiguration: {
83
- apiUrl: 'http://localhost:3001',
253
+ apiUrl: oxyServices?.getBaseURL() || 'Not configured',
84
254
  },
85
255
  buildInfo: {
86
256
  timestamp: new Date().toISOString(),
@@ -96,110 +266,359 @@ const AppInfoScreen: React.FC<BaseScreenProps> = ({
96
266
  copyToClipboard(report, 'Full application report');
97
267
  };
98
268
 
99
- const InfoSection: React.FC<{ title: string; children: React.ReactNode }> = ({ title, children }) => (
100
- <View style={[styles.section, { backgroundColor: secondaryBackgroundColor, borderColor }]}>
101
- <Text style={[styles.sectionTitle, { color: primaryColor }]}>{title}</Text>
102
- {children}
103
- </View>
104
- );
105
-
106
- const InfoRow: React.FC<{ label: string; value: string; copyable?: boolean }> = ({
269
+ const InfoRow: React.FC<{
270
+ label: string;
271
+ value: string;
272
+ copyable?: boolean;
273
+ icon?: string;
274
+ iconComponent?: React.ReactNode;
275
+ color?: string;
276
+ isFirst?: boolean;
277
+ isLast?: boolean;
278
+ onPress?: () => void;
279
+ showChevron?: boolean;
280
+ }> = ({
107
281
  label,
108
282
  value,
109
- copyable = false
110
- }) => (
111
- <View style={styles.infoRow}>
112
- <Text style={[styles.infoLabel, { color: isDarkTheme ? '#CCCCCC' : '#666666' }]}>
113
- {label}:
114
- </Text>
283
+ copyable = false,
284
+ icon = 'information-circle',
285
+ iconComponent,
286
+ color = '#8E8E93',
287
+ isFirst = false,
288
+ isLast = false,
289
+ onPress,
290
+ showChevron = false,
291
+ }) => {
292
+ const handlePress = () => {
293
+ if (onPress) {
294
+ onPress();
295
+ } else if (copyable) {
296
+ copyToClipboard(value, label);
297
+ }
298
+ };
299
+
300
+ const isInteractive = copyable || !!onPress;
301
+
302
+ return (
115
303
  <TouchableOpacity
116
- style={styles.infoValueContainer}
117
- onPress={copyable ? () => copyToClipboard(value, label) : undefined}
118
- disabled={!copyable}
304
+ style={[
305
+ styles.settingItem,
306
+ isFirst && styles.firstSettingItem,
307
+ isLast && styles.lastSettingItem,
308
+ ]}
309
+ onPress={isInteractive ? handlePress : undefined}
310
+ disabled={!isInteractive}
119
311
  >
120
- <Text style={[
121
- styles.infoValue,
122
- { color: textColor },
123
- copyable && { color: primaryColor, textDecorationLine: 'underline' }
124
- ]}>
125
- {value}
126
- </Text>
312
+ <View style={styles.settingInfo}>
313
+ {iconComponent ? (
314
+ React.cloneElement(iconComponent as React.ReactElement, { style: styles.settingIcon })
315
+ ) : (
316
+ <OxyIcon name={icon} size={20} color={color} style={styles.settingIcon} />
317
+ )}
318
+ <View style={styles.settingDetails}>
319
+ <Text style={styles.settingLabel}>{label}</Text>
320
+ <Text style={[
321
+ styles.settingValue,
322
+ (copyable || onPress) && { color: primaryColor }
323
+ ]}>
324
+ {value}
325
+ </Text>
326
+ </View>
327
+ </View>
328
+ {copyable && <OxyIcon name="copy" size={16} color="#ccc" />}
329
+ {showChevron && <OxyIcon name="chevron-forward" size={16} color="#ccc" />}
127
330
  </TouchableOpacity>
128
- </View>
129
- );
331
+ );
332
+ };
130
333
 
131
334
  return (
132
335
  <View style={[styles.container, { backgroundColor }]}>
133
- <View style={[styles.header, { borderBottomColor: borderColor }]}>
134
- <Text style={[styles.title, { color: textColor }]}>Application Information</Text>
135
- <TouchableOpacity onPress={onClose} style={styles.closeButton}>
136
- <Text style={[styles.closeButtonText, { color: primaryColor }]}>×</Text>
336
+ {/* Header */}
337
+ <View style={styles.header}>
338
+ <TouchableOpacity style={styles.cancelButton} onPress={onClose}>
339
+ <Ionicons name="close" size={24} color="#666" />
137
340
  </TouchableOpacity>
341
+ <Text style={styles.headerTitle}>App Information</Text>
342
+ <View style={styles.placeholder} />
138
343
  </View>
139
344
 
140
345
  <ScrollView style={styles.content} showsVerticalScrollIndicator={false}>
141
- <InfoSection title="Package Information">
142
- <InfoRow label="Name" value={packageInfo.name} copyable />
143
- <InfoRow label="Version" value={packageInfo.version} copyable />
144
- <InfoRow label="Description" value={packageInfo.description || 'No description'} />
145
- <InfoRow label="Main Entry" value={packageInfo.main || 'N/A'} />
146
- <InfoRow label="Module Entry" value={packageInfo.module || 'N/A'} />
147
- <InfoRow label="Types Entry" value={packageInfo.types || 'N/A'} />
148
- </InfoSection>
149
-
150
- <InfoSection title="System Information">
151
- <InfoRow label="Platform" value={Platform.OS} />
152
- <InfoRow label="Platform Version" value={systemInfo?.version || 'Loading...'} />
153
- <InfoRow label="Screen Width" value={`${systemInfo?.screenDimensions.width || 0}px`} />
154
- <InfoRow label="Screen Height" value={`${systemInfo?.screenDimensions.height || 0}px`} />
155
- <InfoRow label="Environment" value={__DEV__ ? 'Development' : 'Production'} />
156
- </InfoSection>
157
-
158
- <InfoSection title="User Information">
159
- <InfoRow label="Authentication Status" value={user ? 'Authenticated' : 'Not Authenticated'} />
346
+ {/* Package Information */}
347
+ <View style={styles.section}>
348
+ <Text style={styles.sectionTitle}>Package Information</Text>
349
+
350
+ <InfoRow
351
+ label="Name"
352
+ value={packageInfo.name}
353
+ copyable
354
+ iconComponent={<OxyServicesLogo width={20} height={20} />}
355
+ color="#007AFF"
356
+ isFirst
357
+ />
358
+ <InfoRow
359
+ label="Version"
360
+ value={packageInfo.version}
361
+ copyable
362
+ icon="pricetag"
363
+ color="#5856D6"
364
+ />
365
+ <InfoRow
366
+ label="Description"
367
+ value={packageInfo.description || 'No description'}
368
+ icon="document-text"
369
+ color="#34C759"
370
+ />
371
+ <InfoRow
372
+ label="Main Entry"
373
+ value={packageInfo.main || 'N/A'}
374
+ icon="code"
375
+ color="#FF9500"
376
+ />
377
+ <InfoRow
378
+ label="Module Entry"
379
+ value={packageInfo.module || 'N/A'}
380
+ icon="library"
381
+ color="#FF3B30"
382
+ />
383
+ <InfoRow
384
+ label="Types Entry"
385
+ value={packageInfo.types || 'N/A'}
386
+ icon="construct"
387
+ color="#32D74B"
388
+ isLast
389
+ />
390
+ </View>
391
+
392
+ {/* System Information */}
393
+ <View style={styles.section}>
394
+ <Text style={styles.sectionTitle}>System Information</Text>
395
+
396
+ <InfoRow
397
+ label="Platform"
398
+ value={Platform.OS}
399
+ icon="phone-portrait"
400
+ color="#007AFF"
401
+ isFirst
402
+ />
403
+ <InfoRow
404
+ label="Platform Version"
405
+ value={systemInfo?.version || 'Loading...'}
406
+ icon="hardware-chip"
407
+ color="#5856D6"
408
+ />
409
+ <InfoRow
410
+ label="Screen Width"
411
+ value={`${systemInfo?.screenDimensions.width || 0}px`}
412
+ icon="resize"
413
+ color="#FF9500"
414
+ />
415
+ <InfoRow
416
+ label="Screen Height"
417
+ value={`${systemInfo?.screenDimensions.height || 0}px`}
418
+ icon="resize"
419
+ color="#FF3B30"
420
+ />
421
+ <InfoRow
422
+ label="Environment"
423
+ value={__DEV__ ? 'Development' : 'Production'}
424
+ icon="settings"
425
+ color="#34C759"
426
+ isLast
427
+ />
428
+ </View>
429
+
430
+ {/* User Information */}
431
+ <View style={styles.section}>
432
+ <Text style={styles.sectionTitle}>User Information</Text>
433
+
434
+ <InfoRow
435
+ label="Authentication Status"
436
+ value={user ? 'Authenticated' : 'Not Authenticated'}
437
+ icon="shield-checkmark"
438
+ color={user ? '#34C759' : '#FF3B30'}
439
+ isFirst
440
+ />
160
441
  {user && (
161
442
  <>
162
- <InfoRow label="User ID" value={user.id} copyable />
163
- <InfoRow label="Username" value={user.username || 'N/A'} />
164
- <InfoRow label="Email" value={user.email || 'N/A'} />
165
- <InfoRow label="Premium Status" value={user.isPremium ? 'Premium' : 'Standard'} />
443
+ <InfoRow
444
+ label="User ID"
445
+ value={user.id}
446
+ copyable
447
+ icon="person"
448
+ color="#007AFF"
449
+ />
450
+ <InfoRow
451
+ label="Username"
452
+ value={user.username || 'N/A'}
453
+ icon="at"
454
+ color="#5856D6"
455
+ onPress={() => {
456
+ if (user?.username && navigate) {
457
+ navigate('Profile', { userId: user.id });
458
+ } else {
459
+ toast.info('No username available or navigation not supported');
460
+ }
461
+ }}
462
+ showChevron={true}
463
+ />
464
+ <InfoRow
465
+ label="Email"
466
+ value={user.email || 'N/A'}
467
+ icon="mail"
468
+ color="#FF9500"
469
+ />
470
+ <InfoRow
471
+ label="Premium Status"
472
+ value={user.isPremium ? 'Premium' : 'Standard'}
473
+ icon="star"
474
+ color={user.isPremium ? '#FFD700' : '#8E8E93'}
475
+ />
166
476
  </>
167
477
  )}
168
- <InfoRow label="Total Active Sessions" value={sessions?.length?.toString() || '0'} />
169
- </InfoSection>
170
-
171
- <InfoSection title="API Configuration">
172
- <InfoRow label="API Base URL" value="http://localhost:3001" copyable />
173
- <InfoRow label="Connection Status" value="Unknown" />
174
- </InfoSection>
175
-
176
- <InfoSection title="Build Information">
177
- <InfoRow label="Build Timestamp" value={systemInfo?.timestamp || 'Loading...'} copyable />
178
- <InfoRow label="React Native" value="Expo/React Native" />
179
- <InfoRow label="JavaScript Engine" value="Hermes" />
180
- </InfoSection>
181
-
182
- <InfoSection title="Dependencies">
183
- <InfoRow label="React Native Version" value="Latest" />
184
- <InfoRow label="Expo SDK" value="Latest" />
185
- <InfoRow label="TypeScript" value="Enabled" />
186
- </InfoSection>
187
-
188
- <View style={styles.actionSection}>
478
+ <InfoRow
479
+ label="Total Active Sessions"
480
+ value={sessions?.length?.toString() || '0'}
481
+ icon="people"
482
+ color="#32D74B"
483
+ isLast
484
+ />
485
+ </View>
486
+
487
+ {/* API Configuration */}
488
+ <View style={styles.section}>
489
+ <Text style={styles.sectionTitle}>API Configuration</Text>
490
+
491
+ <InfoRow
492
+ label="API Base URL"
493
+ value={oxyServices?.getBaseURL() || 'Not configured'}
494
+ copyable
495
+ icon="server"
496
+ color="#007AFF"
497
+ isFirst
498
+ />
499
+ <InfoRow
500
+ label="Connection Status"
501
+ value={
502
+ connectionStatus === 'checking' ? 'Checking...' :
503
+ connectionStatus === 'connected' ? 'Connected' :
504
+ connectionStatus === 'disconnected' ? 'Disconnected' :
505
+ 'Unknown'
506
+ }
507
+ icon={
508
+ connectionStatus === 'checking' ? 'sync' :
509
+ connectionStatus === 'connected' ? 'wifi' :
510
+ 'wifi-off'
511
+ }
512
+ color={
513
+ connectionStatus === 'checking' ? '#FF9500' :
514
+ connectionStatus === 'connected' ? '#34C759' :
515
+ '#FF3B30'
516
+ }
517
+ onPress={async () => {
518
+ setConnectionStatus('checking');
519
+ const apiBaseUrl = oxyServices?.getBaseURL() || 'https://api.oxy.so';
520
+ try {
521
+ const response = await fetch(`${apiBaseUrl}/`, {
522
+ method: 'GET',
523
+ timeout: 3000,
524
+ } as any);
525
+
526
+ if (response.ok) {
527
+ setConnectionStatus('connected');
528
+ toast.success('API connection successful');
529
+ } else {
530
+ setConnectionStatus('disconnected');
531
+ toast.error(`API server error: ${response.status}`);
532
+ }
533
+ } catch (error) {
534
+ setConnectionStatus('disconnected');
535
+ toast.error('Failed to connect to API server');
536
+ }
537
+ }}
538
+ showChevron={true}
539
+ isLast
540
+ />
541
+ </View>
542
+
543
+ {/* Build Information */}
544
+ <View style={styles.section}>
545
+ <Text style={styles.sectionTitle}>Build Information</Text>
546
+
547
+ <InfoRow
548
+ label="Build Timestamp"
549
+ value={systemInfo?.timestamp || 'Loading...'}
550
+ copyable
551
+ icon="time"
552
+ color="#007AFF"
553
+ isFirst
554
+ />
555
+ <InfoRow
556
+ label="React Native"
557
+ value="Expo/React Native"
558
+ icon="logo-react"
559
+ color="#61DAFB"
560
+ />
561
+ <InfoRow
562
+ label="JavaScript Engine"
563
+ value="Hermes"
564
+ icon="flash"
565
+ color="#FF3B30"
566
+ isLast
567
+ />
568
+ </View>
569
+
570
+ {/* Quick Actions */}
571
+ <View style={styles.section}>
572
+ <Text style={styles.sectionTitle}>Quick Actions</Text>
573
+
189
574
  <TouchableOpacity
190
- style={[styles.actionButton, { backgroundColor: primaryColor }]}
575
+ style={[styles.settingItem, styles.firstSettingItem]}
191
576
  onPress={handleCopyFullReport}
192
577
  >
193
- <Text style={styles.actionButtonText}>Copy Full Report</Text>
578
+ <View style={styles.settingInfo}>
579
+ <OxyIcon name="copy" size={20} color="#007AFF" style={styles.settingIcon} />
580
+ <View style={styles.settingDetails}>
581
+ <Text style={styles.settingLabel}>Copy Full Report</Text>
582
+ <Text style={styles.settingDescription}>
583
+ Copy complete application information to clipboard
584
+ </Text>
585
+ </View>
586
+ </View>
587
+ <OxyIcon name="chevron-forward" size={16} color="#ccc" />
194
588
  </TouchableOpacity>
195
589
 
196
590
  <TouchableOpacity
197
- style={[styles.actionButton, { backgroundColor: successColor }]}
198
- onPress={() => {
199
- toast.success('All systems operational');
200
- }}
591
+ style={[
592
+ styles.settingItem,
593
+ styles.lastSettingItem,
594
+ isRunningSystemCheck && styles.disabledSettingItem
595
+ ]}
596
+ onPress={runSystemCheck}
597
+ disabled={isRunningSystemCheck}
201
598
  >
202
- <Text style={styles.actionButtonText}>Run System Check</Text>
599
+ <View style={styles.settingInfo}>
600
+ <OxyIcon
601
+ name={isRunningSystemCheck ? "sync" : "checkmark-circle"}
602
+ size={20}
603
+ color={isRunningSystemCheck ? "#FF9500" : "#34C759"}
604
+ style={[
605
+ styles.settingIcon,
606
+ isRunningSystemCheck && styles.spinningIcon
607
+ ]}
608
+ />
609
+ <View style={styles.settingDetails}>
610
+ <Text style={styles.settingLabel}>
611
+ {isRunningSystemCheck ? 'Running System Check...' : 'Run System Check'}
612
+ </Text>
613
+ <Text style={styles.settingDescription}>
614
+ {isRunningSystemCheck
615
+ ? 'Checking API, authentication, and platform status...'
616
+ : 'Verify application health and status'
617
+ }
618
+ </Text>
619
+ </View>
620
+ </View>
621
+ {!isRunningSystemCheck && <OxyIcon name="chevron-forward" size={16} color="#ccc" />}
203
622
  </TouchableOpacity>
204
623
  </View>
205
624
  </ScrollView>
@@ -213,74 +632,86 @@ const styles = StyleSheet.create({
213
632
  },
214
633
  header: {
215
634
  flexDirection: 'row',
216
- justifyContent: 'space-between',
217
635
  alignItems: 'center',
218
- padding: 20,
219
- borderBottomWidth: 1,
220
- },
221
- title: {
222
- fontSize: 20,
223
- fontFamily: fontFamilies.phuduBold,
636
+ justifyContent: 'space-between',
637
+ paddingHorizontal: 16,
638
+ paddingVertical: 12,
639
+ backgroundColor: '#fff',
224
640
  },
225
- closeButton: {
226
- padding: 10,
641
+ cancelButton: {
642
+ padding: 5,
227
643
  },
228
- closeButtonText: {
644
+ headerTitle: {
229
645
  fontSize: 24,
646
+ fontWeight: 'bold',
647
+ color: '#000',
230
648
  fontFamily: fontFamilies.phuduBold,
231
649
  },
650
+ placeholder: {
651
+ width: 34, // Same width as cancel button to center title
652
+ },
232
653
  content: {
233
654
  flex: 1,
234
655
  padding: 16,
235
656
  },
236
657
  section: {
237
- marginBottom: 20,
238
- borderRadius: 12,
239
- padding: 16,
240
- borderWidth: 1,
658
+ marginBottom: 24,
241
659
  },
242
660
  sectionTitle: {
243
- fontSize: 18,
244
- fontFamily: fontFamilies.phuduBold,
661
+ fontSize: 16,
662
+ fontWeight: '600',
663
+ color: '#333',
245
664
  marginBottom: 12,
665
+ fontFamily: fontFamilies.phuduSemiBold,
246
666
  },
247
- infoRow: {
667
+ settingItem: {
668
+ backgroundColor: '#fff',
669
+ padding: 16,
248
670
  flexDirection: 'row',
671
+ alignItems: 'center',
249
672
  justifyContent: 'space-between',
250
- alignItems: 'flex-start',
673
+ marginBottom: 2,
674
+ },
675
+ firstSettingItem: {
676
+ borderTopLeftRadius: 24,
677
+ borderTopRightRadius: 24,
678
+ },
679
+ lastSettingItem: {
680
+ borderBottomLeftRadius: 24,
681
+ borderBottomRightRadius: 24,
251
682
  marginBottom: 8,
252
- minHeight: 24,
253
683
  },
254
- infoLabel: {
255
- fontSize: 14,
256
- fontFamily: fontFamilies.phuduMedium,
684
+ settingInfo: {
685
+ flexDirection: 'row',
686
+ alignItems: 'center',
257
687
  flex: 1,
688
+ },
689
+ settingIcon: {
258
690
  marginRight: 12,
259
691
  },
260
- infoValueContainer: {
261
- flex: 2,
692
+ settingDetails: {
693
+ flex: 1,
262
694
  },
263
- infoValue: {
695
+ settingLabel: {
696
+ fontSize: 16,
697
+ fontWeight: '500',
698
+ color: '#333',
699
+ marginBottom: 2,
700
+ },
701
+ settingValue: {
264
702
  fontSize: 14,
265
- fontFamily: fontFamilies.phudu,
266
- textAlign: 'right',
267
- flexWrap: 'wrap',
703
+ color: '#666',
268
704
  },
269
- actionSection: {
270
- marginTop: 20,
271
- marginBottom: 40,
705
+ settingDescription: {
706
+ fontSize: 14,
707
+ color: '#999',
272
708
  },
273
- actionButton: {
274
- paddingVertical: 12,
275
- paddingHorizontal: 24,
276
- borderRadius: 8,
277
- marginBottom: 12,
278
- alignItems: 'center',
709
+ disabledSettingItem: {
710
+ opacity: 0.6,
279
711
  },
280
- actionButtonText: {
281
- color: '#FFFFFF',
282
- fontSize: 16,
283
- fontFamily: fontFamilies.phuduMedium,
712
+ spinningIcon: {
713
+ // Note: Animation would need to be implemented with Animated API
714
+ // For now, just showing the sync icon to indicate loading
284
715
  },
285
716
  });
286
717