@oxyhq/services 5.7.5 → 5.8.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 (239) hide show
  1. package/README.md +76 -76
  2. package/lib/commonjs/core/index.js +177 -102
  3. package/lib/commonjs/core/index.js.map +1 -1
  4. package/lib/commonjs/index.js +88 -29
  5. package/lib/commonjs/index.js.map +1 -1
  6. package/lib/commonjs/node/createAuth.js +585 -7
  7. package/lib/commonjs/node/createAuth.js.map +1 -1
  8. package/lib/commonjs/node/index.js +38 -1
  9. package/lib/commonjs/node/index.js.map +1 -1
  10. package/lib/commonjs/ui/components/Avatar.js +15 -6
  11. package/lib/commonjs/ui/components/Avatar.js.map +1 -1
  12. package/lib/commonjs/ui/components/GroupedItem.js +58 -13
  13. package/lib/commonjs/ui/components/GroupedItem.js.map +1 -1
  14. package/lib/commonjs/ui/components/GroupedSection.js +7 -1
  15. package/lib/commonjs/ui/components/GroupedSection.js.map +1 -1
  16. package/lib/commonjs/ui/components/Header.js +322 -0
  17. package/lib/commonjs/ui/components/Header.js.map +1 -0
  18. package/lib/commonjs/ui/components/OxyProvider.js +23 -7
  19. package/lib/commonjs/ui/components/OxyProvider.js.map +1 -1
  20. package/lib/commonjs/ui/components/index.js +7 -0
  21. package/lib/commonjs/ui/components/index.js.map +1 -1
  22. package/lib/commonjs/ui/components/internal/GroupedPillButtons.js +1 -1
  23. package/lib/commonjs/ui/components/internal/GroupedPillButtons.js.map +1 -1
  24. package/lib/commonjs/ui/components/internal/TextField.js +606 -546
  25. package/lib/commonjs/ui/components/internal/TextField.js.map +1 -1
  26. package/lib/commonjs/ui/components/internal/TextField.md +436 -0
  27. package/lib/commonjs/ui/context/OxyContext.js +122 -78
  28. package/lib/commonjs/ui/context/OxyContext.js.map +1 -1
  29. package/lib/commonjs/ui/hooks/useSessionSocket.js +5 -2
  30. package/lib/commonjs/ui/hooks/useSessionSocket.js.map +1 -1
  31. package/lib/commonjs/ui/navigation/OxyRouter.js +1 -1
  32. package/lib/commonjs/ui/navigation/OxyRouter.js.map +1 -1
  33. package/lib/commonjs/ui/screens/AccountCenterScreen.js +6 -6
  34. package/lib/commonjs/ui/screens/AccountCenterScreen.js.map +1 -1
  35. package/lib/commonjs/ui/screens/AccountManagementDemo.js +3 -3
  36. package/lib/commonjs/ui/screens/AccountManagementDemo.js.map +1 -1
  37. package/lib/commonjs/ui/screens/AccountOverviewScreen.js +241 -598
  38. package/lib/commonjs/ui/screens/AccountOverviewScreen.js.map +1 -1
  39. package/lib/commonjs/ui/screens/AccountSettingsScreen.js +1151 -406
  40. package/lib/commonjs/ui/screens/AccountSettingsScreen.js.map +1 -1
  41. package/lib/commonjs/ui/screens/AccountSwitcherScreen.js +135 -237
  42. package/lib/commonjs/ui/screens/AccountSwitcherScreen.js.map +1 -1
  43. package/lib/commonjs/ui/screens/AppInfoScreen.js +246 -463
  44. package/lib/commonjs/ui/screens/AppInfoScreen.js.map +1 -1
  45. package/lib/commonjs/ui/screens/FeedbackScreen.js +3 -3
  46. package/lib/commonjs/ui/screens/FeedbackScreen.js.map +1 -1
  47. package/lib/commonjs/ui/screens/PaymentGatewayScreen.js +808 -650
  48. package/lib/commonjs/ui/screens/PaymentGatewayScreen.js.map +1 -1
  49. package/lib/commonjs/ui/screens/RecoverAccountScreen.js +51 -72
  50. package/lib/commonjs/ui/screens/RecoverAccountScreen.js.map +1 -1
  51. package/lib/commonjs/ui/screens/SessionManagementScreen.js +11 -29
  52. package/lib/commonjs/ui/screens/SessionManagementScreen.js.map +1 -1
  53. package/lib/commonjs/ui/screens/SignInScreen.js +30 -303
  54. package/lib/commonjs/ui/screens/SignInScreen.js.map +1 -1
  55. package/lib/commonjs/ui/screens/SignUpScreen.js +4 -4
  56. package/lib/commonjs/ui/screens/SignUpScreen.js.map +1 -1
  57. package/lib/commonjs/ui/screens/internal/SignInPasswordStep.js +19 -31
  58. package/lib/commonjs/ui/screens/internal/SignInPasswordStep.js.map +1 -1
  59. package/lib/commonjs/ui/screens/internal/SignInUsernameStep.js +7 -10
  60. package/lib/commonjs/ui/screens/internal/SignInUsernameStep.js.map +1 -1
  61. package/lib/commonjs/ui/screens/internal/SignUpIdentityStep.js +11 -5
  62. package/lib/commonjs/ui/screens/internal/SignUpIdentityStep.js.map +1 -1
  63. package/lib/commonjs/ui/screens/internal/SignUpSecurityStep.js +11 -4
  64. package/lib/commonjs/ui/screens/internal/SignUpSecurityStep.js.map +1 -1
  65. package/lib/commonjs/ui/stores/authStore.js +12 -0
  66. package/lib/commonjs/ui/stores/authStore.js.map +1 -1
  67. package/lib/commonjs/ui/styles/authStyles.js +337 -0
  68. package/lib/commonjs/ui/styles/authStyles.js.map +1 -0
  69. package/lib/commonjs/ui/styles/index.js +11 -0
  70. package/lib/commonjs/ui/styles/index.js.map +1 -1
  71. package/lib/module/core/index.js +177 -41
  72. package/lib/module/core/index.js.map +1 -1
  73. package/lib/module/index.js +26 -4
  74. package/lib/module/index.js.map +1 -1
  75. package/lib/module/node/createAuth.js +584 -7
  76. package/lib/module/node/createAuth.js.map +1 -1
  77. package/lib/module/node/index.js +7 -1
  78. package/lib/module/node/index.js.map +1 -1
  79. package/lib/module/ui/components/Avatar.js +15 -6
  80. package/lib/module/ui/components/Avatar.js.map +1 -1
  81. package/lib/module/ui/components/GroupedItem.js +59 -14
  82. package/lib/module/ui/components/GroupedItem.js.map +1 -1
  83. package/lib/module/ui/components/GroupedSection.js +7 -1
  84. package/lib/module/ui/components/GroupedSection.js.map +1 -1
  85. package/lib/module/ui/components/Header.js +317 -0
  86. package/lib/module/ui/components/Header.js.map +1 -0
  87. package/lib/module/ui/components/OxyProvider.js +25 -9
  88. package/lib/module/ui/components/OxyProvider.js.map +1 -1
  89. package/lib/module/ui/components/index.js +1 -0
  90. package/lib/module/ui/components/index.js.map +1 -1
  91. package/lib/module/ui/components/internal/GroupedPillButtons.js +1 -1
  92. package/lib/module/ui/components/internal/GroupedPillButtons.js.map +1 -1
  93. package/lib/module/ui/components/internal/TextField.js +607 -547
  94. package/lib/module/ui/components/internal/TextField.js.map +1 -1
  95. package/lib/module/ui/components/internal/TextField.md +436 -0
  96. package/lib/module/ui/context/OxyContext.js +121 -77
  97. package/lib/module/ui/context/OxyContext.js.map +1 -1
  98. package/lib/module/ui/hooks/useSessionSocket.js +5 -2
  99. package/lib/module/ui/hooks/useSessionSocket.js.map +1 -1
  100. package/lib/module/ui/navigation/OxyRouter.js +1 -1
  101. package/lib/module/ui/navigation/OxyRouter.js.map +1 -1
  102. package/lib/module/ui/screens/AccountCenterScreen.js +6 -6
  103. package/lib/module/ui/screens/AccountCenterScreen.js.map +1 -1
  104. package/lib/module/ui/screens/AccountManagementDemo.js +3 -3
  105. package/lib/module/ui/screens/AccountManagementDemo.js.map +1 -1
  106. package/lib/module/ui/screens/AccountOverviewScreen.js +242 -597
  107. package/lib/module/ui/screens/AccountOverviewScreen.js.map +1 -1
  108. package/lib/module/ui/screens/AccountSettingsScreen.js +1152 -407
  109. package/lib/module/ui/screens/AccountSettingsScreen.js.map +1 -1
  110. package/lib/module/ui/screens/AccountSwitcherScreen.js +135 -237
  111. package/lib/module/ui/screens/AccountSwitcherScreen.js.map +1 -1
  112. package/lib/module/ui/screens/AppInfoScreen.js +248 -465
  113. package/lib/module/ui/screens/AppInfoScreen.js.map +1 -1
  114. package/lib/module/ui/screens/FeedbackScreen.js +3 -3
  115. package/lib/module/ui/screens/FeedbackScreen.js.map +1 -1
  116. package/lib/module/ui/screens/PaymentGatewayScreen.js +809 -651
  117. package/lib/module/ui/screens/PaymentGatewayScreen.js.map +1 -1
  118. package/lib/module/ui/screens/RecoverAccountScreen.js +53 -74
  119. package/lib/module/ui/screens/RecoverAccountScreen.js.map +1 -1
  120. package/lib/module/ui/screens/SessionManagementScreen.js +11 -29
  121. package/lib/module/ui/screens/SessionManagementScreen.js.map +1 -1
  122. package/lib/module/ui/screens/SignInScreen.js +32 -305
  123. package/lib/module/ui/screens/SignInScreen.js.map +1 -1
  124. package/lib/module/ui/screens/SignUpScreen.js +5 -5
  125. package/lib/module/ui/screens/SignUpScreen.js.map +1 -1
  126. package/lib/module/ui/screens/internal/SignInPasswordStep.js +19 -31
  127. package/lib/module/ui/screens/internal/SignInPasswordStep.js.map +1 -1
  128. package/lib/module/ui/screens/internal/SignInUsernameStep.js +7 -10
  129. package/lib/module/ui/screens/internal/SignInUsernameStep.js.map +1 -1
  130. package/lib/module/ui/screens/internal/SignUpIdentityStep.js +11 -5
  131. package/lib/module/ui/screens/internal/SignUpIdentityStep.js.map +1 -1
  132. package/lib/module/ui/screens/internal/SignUpSecurityStep.js +11 -4
  133. package/lib/module/ui/screens/internal/SignUpSecurityStep.js.map +1 -1
  134. package/lib/module/ui/stores/authStore.js +12 -0
  135. package/lib/module/ui/stores/authStore.js.map +1 -1
  136. package/lib/module/ui/styles/authStyles.js +332 -0
  137. package/lib/module/ui/styles/authStyles.js.map +1 -0
  138. package/lib/module/ui/styles/index.js +1 -0
  139. package/lib/module/ui/styles/index.js.map +1 -1
  140. package/lib/typescript/core/index.d.ts +68 -24
  141. package/lib/typescript/core/index.d.ts.map +1 -1
  142. package/lib/typescript/index.d.ts +13 -3
  143. package/lib/typescript/index.d.ts.map +1 -1
  144. package/lib/typescript/node/createAuth.d.ts +112 -0
  145. package/lib/typescript/node/createAuth.d.ts.map +1 -1
  146. package/lib/typescript/node/index.d.ts +2 -0
  147. package/lib/typescript/node/index.d.ts.map +1 -1
  148. package/lib/typescript/ui/components/Avatar.d.ts.map +1 -1
  149. package/lib/typescript/ui/components/GroupedItem.d.ts +6 -0
  150. package/lib/typescript/ui/components/GroupedItem.d.ts.map +1 -1
  151. package/lib/typescript/ui/components/GroupedSection.d.ts +6 -0
  152. package/lib/typescript/ui/components/GroupedSection.d.ts.map +1 -1
  153. package/lib/typescript/ui/components/Header.d.ts +22 -0
  154. package/lib/typescript/ui/components/Header.d.ts.map +1 -0
  155. package/lib/typescript/ui/components/OxyProvider.d.ts.map +1 -1
  156. package/lib/typescript/ui/components/index.d.ts +1 -0
  157. package/lib/typescript/ui/components/index.d.ts.map +1 -1
  158. package/lib/typescript/ui/components/internal/TextField.d.ts +31 -16
  159. package/lib/typescript/ui/components/internal/TextField.d.ts.map +1 -1
  160. package/lib/typescript/ui/context/OxyContext.d.ts +5 -2
  161. package/lib/typescript/ui/context/OxyContext.d.ts.map +1 -1
  162. package/lib/typescript/ui/hooks/useSessionSocket.d.ts.map +1 -1
  163. package/lib/typescript/ui/navigation/types.d.ts +9 -2
  164. package/lib/typescript/ui/navigation/types.d.ts.map +1 -1
  165. package/lib/typescript/ui/screens/AccountOverviewScreen.d.ts.map +1 -1
  166. package/lib/typescript/ui/screens/AccountSettingsScreen.d.ts.map +1 -1
  167. package/lib/typescript/ui/screens/AccountSwitcherScreen.d.ts.map +1 -1
  168. package/lib/typescript/ui/screens/AppInfoScreen.d.ts.map +1 -1
  169. package/lib/typescript/ui/screens/PaymentGatewayScreen.d.ts.map +1 -1
  170. package/lib/typescript/ui/screens/RecoverAccountScreen.d.ts +5 -1
  171. package/lib/typescript/ui/screens/RecoverAccountScreen.d.ts.map +1 -1
  172. package/lib/typescript/ui/screens/SessionManagementScreen.d.ts.map +1 -1
  173. package/lib/typescript/ui/screens/SignInScreen.d.ts.map +1 -1
  174. package/lib/typescript/ui/screens/internal/SignInPasswordStep.d.ts +1 -1
  175. package/lib/typescript/ui/screens/internal/SignInPasswordStep.d.ts.map +1 -1
  176. package/lib/typescript/ui/screens/internal/SignInUsernameStep.d.ts +0 -1
  177. package/lib/typescript/ui/screens/internal/SignInUsernameStep.d.ts.map +1 -1
  178. package/lib/typescript/ui/screens/internal/SignUpIdentityStep.d.ts.map +1 -1
  179. package/lib/typescript/ui/screens/internal/SignUpSecurityStep.d.ts.map +1 -1
  180. package/lib/typescript/ui/stores/authStore.d.ts.map +1 -1
  181. package/lib/typescript/ui/styles/authStyles.d.ts +326 -0
  182. package/lib/typescript/ui/styles/authStyles.d.ts.map +1 -0
  183. package/lib/typescript/ui/styles/index.d.ts +1 -0
  184. package/lib/typescript/ui/styles/index.d.ts.map +1 -1
  185. package/package.json +1 -4
  186. package/src/core/index.ts +195 -41
  187. package/src/index.ts +72 -4
  188. package/src/node/createAuth.ts +623 -7
  189. package/src/node/index.ts +19 -1
  190. package/src/ui/components/Avatar.tsx +11 -5
  191. package/src/ui/components/GroupedItem.tsx +57 -9
  192. package/src/ui/components/GroupedSection.tsx +12 -0
  193. package/src/ui/components/Header.tsx +364 -0
  194. package/src/ui/components/OxyProvider.tsx +31 -15
  195. package/src/ui/components/index.ts +1 -0
  196. package/src/ui/components/internal/GroupedPillButtons.tsx +1 -1
  197. package/src/ui/components/internal/TextField.md +436 -0
  198. package/src/ui/components/internal/TextField.tsx +720 -620
  199. package/src/ui/context/OxyContext.tsx +150 -63
  200. package/src/ui/hooks/useSessionSocket.ts +5 -2
  201. package/src/ui/navigation/OxyRouter.tsx +1 -1
  202. package/src/ui/navigation/types.ts +10 -2
  203. package/src/ui/screens/AccountCenterScreen.tsx +5 -5
  204. package/src/ui/screens/AccountManagementDemo.tsx +9 -9
  205. package/src/ui/screens/AccountOverviewScreen.tsx +265 -414
  206. package/src/ui/screens/AccountSettingsScreen.tsx +1165 -403
  207. package/src/ui/screens/AccountSwitcherScreen.tsx +158 -202
  208. package/src/ui/screens/AppInfoScreen.tsx +270 -497
  209. package/src/ui/screens/FeedbackScreen.tsx +3 -3
  210. package/src/ui/screens/PaymentGatewayScreen.tsx +668 -365
  211. package/src/ui/screens/ProfileScreen.tsx +5 -5
  212. package/src/ui/screens/RecoverAccountScreen.tsx +46 -74
  213. package/src/ui/screens/SessionManagementScreen.tsx +14 -22
  214. package/src/ui/screens/SignInScreen.tsx +27 -294
  215. package/src/ui/screens/SignUpScreen.tsx +5 -5
  216. package/src/ui/screens/internal/SignInPasswordStep.tsx +11 -22
  217. package/src/ui/screens/internal/SignInUsernameStep.tsx +3 -10
  218. package/src/ui/screens/internal/SignUpIdentityStep.tsx +2 -5
  219. package/src/ui/screens/internal/SignUpSecurityStep.tsx +3 -4
  220. package/src/ui/stores/authStore.ts +12 -0
  221. package/src/ui/styles/authStyles.ts +352 -0
  222. package/src/ui/styles/index.ts +1 -0
  223. package/lib/commonjs/core/auth-manager.js +0 -440
  224. package/lib/commonjs/core/auth-manager.js.map +0 -1
  225. package/lib/commonjs/core/use-auth.js +0 -244
  226. package/lib/commonjs/core/use-auth.js.map +0 -1
  227. package/lib/module/core/auth-manager.js +0 -432
  228. package/lib/module/core/auth-manager.js.map +0 -1
  229. package/lib/module/core/use-auth.js +0 -235
  230. package/lib/module/core/use-auth.js.map +0 -1
  231. package/lib/typescript/core/auth-manager.d.ts +0 -136
  232. package/lib/typescript/core/auth-manager.d.ts.map +0 -1
  233. package/lib/typescript/core/use-auth.d.ts +0 -79
  234. package/lib/typescript/core/use-auth.d.ts.map +0 -1
  235. package/src/__tests__/middleware.test.ts +0 -105
  236. package/src/__tests__/setup.ts +0 -10
  237. package/src/__tests__/zero-config-auth.test.ts +0 -607
  238. package/src/core/auth-manager.ts +0 -500
  239. package/src/core/use-auth.tsx +0 -245
@@ -21,6 +21,7 @@ import { confirmAction } from '../utils/confirmAction';
21
21
  import OxyIcon from '../components/icon/OxyIcon';
22
22
  import { Ionicons } from '@expo/vector-icons';
23
23
  import Avatar from '../components/Avatar';
24
+ import { Header, GroupedSection } from '../components';
24
25
 
25
26
  interface SessionWithUser extends SecureClientSession {
26
27
  userProfile?: User;
@@ -51,6 +52,7 @@ const ModernAccountSwitcherScreen: React.FC<BaseScreenProps> = ({
51
52
  switchSession,
52
53
  removeSession,
53
54
  logoutAll,
55
+ refreshSessions,
54
56
  isLoading,
55
57
  isAuthenticated
56
58
  } = useOxy();
@@ -84,8 +86,20 @@ const ModernAccountSwitcherScreen: React.FC<BaseScreenProps> = ({
84
86
  shadow: isDarkTheme ? 'rgba(0,0,0,0.3)' : 'rgba(0,0,0,0.1)',
85
87
  };
86
88
 
89
+ // Refresh sessions when screen loads
90
+ useEffect(() => {
91
+ if (isAuthenticated && activeSessionId) {
92
+ refreshSessions();
93
+ }
94
+ }, [isAuthenticated, activeSessionId]);
95
+
87
96
  // Load user profiles for sessions
88
97
  useEffect(() => {
98
+ console.log('AccountSwitcherScreen - sessions changed:', sessions);
99
+ console.log('AccountSwitcherScreen - sessions length:', sessions.length);
100
+ console.log('AccountSwitcherScreen - activeSessionId:', activeSessionId);
101
+ console.log('AccountSwitcherScreen - isAuthenticated:', isAuthenticated);
102
+
89
103
  const loadUserProfiles = async () => {
90
104
  if (!sessions.length || !oxyServices) return;
91
105
 
@@ -162,44 +176,22 @@ const ModernAccountSwitcherScreen: React.FC<BaseScreenProps> = ({
162
176
  };
163
177
 
164
178
  const handleLogoutAll = async () => {
165
- // IMPORTANT DEBUG INFO - Check this in console
166
- console.log('🔴 DEBUG handleLogoutAll called');
167
- console.log('🔴 Current user:', user);
168
- console.log('🔴 activeSessionId:', activeSessionId);
169
- console.log('🔴 sessions count:', sessions?.length || 0);
170
- console.log('🔴 sessions array:', sessions);
171
- console.log('🔴 isLoading:', isLoading);
172
- console.log('🔴 logoutAll function type:', typeof logoutAll);
173
-
174
- // Check if we have the required data
175
- if (!activeSessionId) {
176
- console.error('🔴 ERROR: No activeSessionId found!');
177
- toast.error('No active session found. You may already be logged out.');
178
- return;
179
- }
180
-
181
- if (typeof logoutAll !== 'function') {
182
- console.error('🔴 ERROR: logoutAll is not a function!', typeof logoutAll);
183
- toast.error('Logout function not available. Please try refreshing the app.');
184
- return;
185
- }
186
-
187
- // TEMPORARY: Skip confirmation dialog to test direct logout
188
- console.log('🔴 TESTING: Bypassing confirmation dialog for direct test');
189
- try {
190
- console.log('🔴 TESTING: About to call logoutAll() directly');
191
- await logoutAll();
192
- console.log('🔴 TESTING: logoutAll() completed successfully');
193
- toast.success('All accounts signed out successfully!');
194
- if (onClose) {
195
- console.log('🔴 TESTING: Calling onClose');
196
- onClose();
179
+ confirmAction(
180
+ 'Are you sure you want to sign out of all accounts? This will remove all saved accounts from this device.',
181
+ async () => {
182
+ try {
183
+ await logoutAll();
184
+ toast.success('All accounts signed out successfully!');
185
+ if (onClose) {
186
+ onClose();
187
+ }
188
+ } catch (error) {
189
+ console.error('Logout all failed:', error);
190
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred';
191
+ toast.error(`There was a problem signing out: ${errorMessage}`);
192
+ }
197
193
  }
198
- } catch (error) {
199
- console.error('🔴 TESTING: Logout all failed:', error);
200
- const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred';
201
- toast.error(`There was a problem signing out: ${errorMessage}`);
202
- }
194
+ );
203
195
  };
204
196
 
205
197
  // Device session management functions
@@ -269,17 +261,22 @@ const ModernAccountSwitcherScreen: React.FC<BaseScreenProps> = ({
269
261
  return (
270
262
  <View style={[styles.container, { backgroundColor: '#f2f2f2' }]}>
271
263
  {/* Header */}
272
- <View style={styles.header}>
273
- <TouchableOpacity style={styles.backButton} onPress={goBack}>
274
- <OxyIcon name="chevron-back" size={24} color="#007AFF" />
275
- </TouchableOpacity>
276
- <Text style={styles.headerTitle}>Account Switcher</Text>
277
- {onClose && (
278
- <TouchableOpacity style={styles.closeButton} onPress={onClose}>
279
- <Text style={styles.closeButtonText}>×</Text>
280
- </TouchableOpacity>
281
- )}
282
- </View>
264
+ <Header
265
+ title="Account Switcher"
266
+ theme={theme}
267
+ onBack={goBack}
268
+ onClose={onClose}
269
+ showBackButton={true}
270
+ showCloseButton={true}
271
+ elevation="subtle"
272
+ rightAction={{
273
+ icon: "refresh",
274
+ onPress: () => {
275
+ console.log('Manual refresh triggered');
276
+ refreshSessions();
277
+ }
278
+ }}
279
+ />
283
280
 
284
281
  <ScrollView style={styles.content}>
285
282
  {isLoading ? (
@@ -410,56 +407,36 @@ const ModernAccountSwitcherScreen: React.FC<BaseScreenProps> = ({
410
407
  <View style={styles.section}>
411
408
  <Text style={styles.sectionTitle}>Quick Actions</Text>
412
409
 
413
- <TouchableOpacity
414
- style={[styles.settingItem, styles.firstSettingItem]}
415
- onPress={() => navigate?.('SignIn')}
416
- >
417
- <View style={styles.settingInfo}>
418
- <OxyIcon name="person-add" size={20} color="#007AFF" style={styles.settingIcon} />
419
- <View>
420
- <Text style={styles.settingLabel}>Add Another Account</Text>
421
- <Text style={styles.settingDescription}>Sign in with a different account</Text>
422
- </View>
423
- </View>
424
- <OxyIcon name="chevron-forward" size={16} color="#ccc" />
425
- </TouchableOpacity>
426
-
427
- <TouchableOpacity
428
- style={styles.settingItem}
429
- onPress={() => setShowDeviceManagement(!showDeviceManagement)}
430
- >
431
- <View style={styles.settingInfo}>
432
- <OxyIcon name="devices" size={20} color="#5856D6" style={styles.settingIcon} />
433
- <View>
434
- <Text style={styles.settingLabel}>
435
- {showDeviceManagement ? 'Hide' : 'Manage'} Device Sessions
436
- </Text>
437
- <Text style={styles.settingDescription}>
438
- View and manage sessions on other devices
439
- </Text>
440
- </View>
441
- </View>
442
- <OxyIcon name="chevron-forward" size={16} color="#ccc" />
443
- </TouchableOpacity>
444
-
445
- <TouchableOpacity
446
- style={[styles.settingItem, styles.lastSettingItem]}
447
- onPress={handleLogoutAll}
448
- disabled={sessionsWithUsers.length === 0}
449
- >
450
- <View style={styles.settingInfo}>
451
- <OxyIcon name="log-out" size={20} color="#FF3B30" style={styles.settingIcon} />
452
- <View>
453
- <Text style={[styles.settingLabel, { color: sessionsWithUsers.length === 0 ? '#ccc' : '#FF3B30' }]}>
454
- Sign Out All Accounts
455
- </Text>
456
- <Text style={styles.settingDescription}>
457
- Remove all accounts from this device
458
- </Text>
459
- </View>
460
- </View>
461
- <OxyIcon name="chevron-forward" size={16} color="#ccc" />
462
- </TouchableOpacity>
410
+ <GroupedSection
411
+ items={[
412
+ {
413
+ id: 'add-account',
414
+ icon: 'person-add',
415
+ iconColor: '#007AFF',
416
+ title: 'Add Another Account',
417
+ subtitle: 'Sign in with a different account',
418
+ onPress: () => navigate?.('SignIn'),
419
+ },
420
+ {
421
+ id: 'device-management',
422
+ icon: 'phone-portrait',
423
+ iconColor: '#5856D6',
424
+ title: `${showDeviceManagement ? 'Hide' : 'Manage'} Device Sessions`,
425
+ subtitle: 'View and manage sessions on other devices',
426
+ onPress: () => setShowDeviceManagement(!showDeviceManagement),
427
+ },
428
+ {
429
+ id: 'sign-out-all',
430
+ icon: 'log-out',
431
+ iconColor: '#FF3B30',
432
+ title: 'Sign Out All Accounts',
433
+ subtitle: 'Remove all accounts from this device',
434
+ onPress: handleLogoutAll,
435
+ disabled: sessionsWithUsers.length === 0,
436
+ },
437
+ ]}
438
+ theme={theme}
439
+ />
463
440
  </View>
464
441
 
465
442
  {/* Device Management Section */}
@@ -468,67 +445,62 @@ const ModernAccountSwitcherScreen: React.FC<BaseScreenProps> = ({
468
445
  <Text style={styles.sectionTitle}>Device Sessions</Text>
469
446
 
470
447
  {loadingDeviceSessions ? (
471
- <View style={[styles.settingItem, styles.firstSettingItem, styles.lastSettingItem]}>
472
- <View style={styles.loadingContainer}>
473
- <ActivityIndicator size="small" color="#007AFF" />
474
- <Text style={styles.loadingText}>Loading device sessions...</Text>
475
- </View>
476
- </View>
448
+ <GroupedSection
449
+ items={[
450
+ {
451
+ id: 'loading-device-sessions',
452
+ icon: 'sync',
453
+ iconColor: '#007AFF',
454
+ title: 'Loading device sessions...',
455
+ subtitle: 'Please wait while we fetch your device sessions',
456
+ disabled: true,
457
+ customContent: (
458
+ <ActivityIndicator size="small" color="#007AFF" style={{ marginRight: 16 }} />
459
+ ),
460
+ },
461
+ ]}
462
+ theme={theme}
463
+ />
477
464
  ) : deviceSessions.length === 0 ? (
478
- <View style={[styles.settingItem, styles.firstSettingItem, styles.lastSettingItem]}>
479
- <View style={styles.settingInfo}>
480
- <OxyIcon name="phone-portrait" size={20} color="#ccc" style={styles.settingIcon} />
481
- <View>
482
- <Text style={styles.settingLabel}>No device sessions found</Text>
483
- <Text style={styles.settingDescription}>
484
- Device session management not available
485
- </Text>
486
- </View>
487
- </View>
488
- </View>
465
+ <GroupedSection
466
+ items={[
467
+ {
468
+ id: 'no-device-sessions',
469
+ icon: 'phone-portrait',
470
+ iconColor: '#ccc',
471
+ title: 'No device sessions found',
472
+ subtitle: 'Device session management not available',
473
+ disabled: true,
474
+ },
475
+ ]}
476
+ theme={theme}
477
+ />
489
478
  ) : (
490
- <>
491
- {deviceSessions.map((session, index) => (
492
- <View
493
- key={session.sessionId}
494
- style={[
495
- styles.settingItem,
496
- index === 0 && styles.firstSettingItem,
497
- index === deviceSessions.length - 1 && styles.lastSettingItem,
498
- ]}
499
- >
500
- <View style={styles.settingInfo}>
501
- <OxyIcon
502
- name={session.isCurrent ? "phone-portrait" : "phone-portrait-outline"}
503
- size={20}
504
- color={session.isCurrent ? "#34C759" : "#8E8E93"}
505
- style={styles.settingIcon}
506
- />
507
- <View>
508
- <Text style={styles.settingLabel}>
509
- {session.deviceName} {session.isCurrent ? '(This device)' : ''}
510
- </Text>
511
- <Text style={styles.settingDescription}>
512
- Last active: {new Date(session.lastActive).toLocaleDateString()}
513
- </Text>
514
- </View>
515
- </View>
516
- {!session.isCurrent && (
517
- <TouchableOpacity
518
- style={styles.removeButton}
519
- onPress={() => handleRemoteSessionLogout(session.sessionId, session.deviceName)}
520
- disabled={remotingLogoutSessionId === session.sessionId}
521
- >
522
- {remotingLogoutSessionId === session.sessionId ? (
523
- <ActivityIndicator size="small" color="#FF3B30" />
524
- ) : (
525
- <OxyIcon name="log-out" size={16} color="#FF3B30" />
526
- )}
527
- </TouchableOpacity>
528
- )}
529
- </View>
530
- ))}
531
- </>
479
+ <GroupedSection
480
+ items={deviceSessions.map((session, index) => ({
481
+ id: `device-session-${session.sessionId}`,
482
+ icon: session.isCurrent ? 'phone-portrait' : 'phone-portrait-outline',
483
+ iconColor: session.isCurrent ? '#34C759' : '#8E8E93',
484
+ title: `${session.deviceName} ${session.isCurrent ? '(This device)' : ''}`,
485
+ subtitle: `Last active: ${new Date(session.lastActive).toLocaleDateString()}`,
486
+ onPress: session.isCurrent ? undefined : () => handleRemoteSessionLogout(session.sessionId, session.deviceName),
487
+ disabled: session.isCurrent || remotingLogoutSessionId === session.sessionId,
488
+ customContent: !session.isCurrent ? (
489
+ <TouchableOpacity
490
+ style={styles.removeButton}
491
+ onPress={() => handleRemoteSessionLogout(session.sessionId, session.deviceName)}
492
+ disabled={remotingLogoutSessionId === session.sessionId}
493
+ >
494
+ {remotingLogoutSessionId === session.sessionId ? (
495
+ <ActivityIndicator size="small" color="#FF3B30" />
496
+ ) : (
497
+ <OxyIcon name="log-out" size={16} color="#FF3B30" />
498
+ )}
499
+ </TouchableOpacity>
500
+ ) : undefined,
501
+ }))}
502
+ theme={theme}
503
+ />
532
504
  )}
533
505
  </View>
534
506
  )}
@@ -536,21 +508,34 @@ const ModernAccountSwitcherScreen: React.FC<BaseScreenProps> = ({
536
508
  {/* Empty State */}
537
509
  {sessionsWithUsers.length === 0 && (
538
510
  <View style={styles.section}>
539
- <View style={[styles.settingItem, styles.firstSettingItem, styles.lastSettingItem]}>
540
- <View style={styles.emptyStateContainer}>
541
- <OxyIcon name="person-outline" size={48} color="#ccc" />
542
- <Text style={styles.emptyStateTitle}>No saved accounts</Text>
543
- <Text style={styles.emptyStateDescription}>
544
- Add another account to switch between them quickly
545
- </Text>
546
- <TouchableOpacity
547
- style={styles.addAccountButton}
548
- onPress={() => navigate?.('SignIn')}
549
- >
550
- <Text style={styles.addAccountButtonText}>Add Account</Text>
551
- </TouchableOpacity>
552
- </View>
553
- </View>
511
+ <GroupedSection
512
+ items={[
513
+ {
514
+ id: 'empty-state',
515
+ icon: 'person-outline',
516
+ iconColor: '#ccc',
517
+ title: 'No saved accounts',
518
+ subtitle: 'Add another account to switch between them quickly',
519
+ onPress: () => navigate?.('SignIn'),
520
+ customContent: (
521
+ <View style={styles.emptyStateContainer}>
522
+ <OxyIcon name="person-outline" size={48} color="#ccc" />
523
+ <Text style={styles.emptyStateTitle}>No saved accounts</Text>
524
+ <Text style={styles.emptyStateDescription}>
525
+ Add another account to switch between them quickly
526
+ </Text>
527
+ <TouchableOpacity
528
+ style={styles.addAccountButton}
529
+ onPress={() => navigate?.('SignIn')}
530
+ >
531
+ <Text style={styles.addAccountButtonText}>Add Account</Text>
532
+ </TouchableOpacity>
533
+ </View>
534
+ ),
535
+ },
536
+ ]}
537
+ theme={theme}
538
+ />
554
539
  </View>
555
540
  )}
556
541
  </>
@@ -565,33 +550,7 @@ const styles = StyleSheet.create({
565
550
  flex: 1,
566
551
  backgroundColor: '#f2f2f2',
567
552
  },
568
- header: {
569
- paddingHorizontal: 20,
570
- paddingTop: 60,
571
- paddingBottom: 16,
572
- backgroundColor: '#fff',
573
- borderBottomWidth: 1,
574
- borderBottomColor: '#e0e0e0',
575
- flexDirection: 'row',
576
- justifyContent: 'space-between',
577
- alignItems: 'center',
578
- },
579
- headerTitle: {
580
- fontSize: 24,
581
- fontWeight: 'bold',
582
- color: '#000',
583
- },
584
- backButton: {
585
- padding: 8,
586
- },
587
- closeButton: {
588
- padding: 8,
589
- },
590
- closeButtonText: {
591
- fontSize: 24,
592
- color: '#000',
593
- fontWeight: '300',
594
- },
553
+
595
554
  content: {
596
555
  flex: 1,
597
556
  padding: 16,
@@ -632,9 +591,6 @@ const styles = StyleSheet.create({
632
591
  alignItems: 'center',
633
592
  flex: 1,
634
593
  },
635
- settingIcon: {
636
- marginRight: 12,
637
- },
638
594
  settingLabel: {
639
595
  fontSize: 16,
640
596
  fontWeight: '500',