@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
@@ -20,6 +20,7 @@ import { fontFamilies } from '../styles/fonts';
20
20
  import { toast } from '../../lib/sonner';
21
21
  import { confirmAction } from '../utils/confirmAction';
22
22
  import { Ionicons } from '@expo/vector-icons';
23
+ import { Header, Section, GroupedSection, GroupedItem } from '../components';
23
24
 
24
25
  /**
25
26
  * AccountOverviewScreen - Optimized for performance
@@ -29,6 +30,7 @@ import { Ionicons } from '@expo/vector-icons';
29
30
  * - useMemo for additional accounts filtering (only recalculates when dependencies change)
30
31
  * - useCallback for event handlers to prevent unnecessary re-renders
31
32
  * - React.memo wrapper to prevent re-renders when props haven't changed
33
+ * - GroupedSection components for better organization and cleaner code
32
34
  */
33
35
  const AccountOverviewScreen: React.FC<BaseScreenProps> = ({
34
36
  onClose,
@@ -166,373 +168,293 @@ const AccountOverviewScreen: React.FC<BaseScreenProps> = ({
166
168
  return (
167
169
  <View style={[styles.container, { backgroundColor: '#f2f2f2' }]}>
168
170
  {/* Header */}
169
- <View style={styles.header}>
170
- <Text style={styles.headerTitle}>Account</Text>
171
- {onClose && (
172
- <TouchableOpacity style={styles.closeButton} onPress={onClose}>
173
- <Text style={styles.closeButtonText}>×</Text>
174
- </TouchableOpacity>
175
- )}
176
- </View>
171
+ <Header
172
+ title="Account"
173
+ theme={theme}
174
+ onBack={onClose}
175
+ variant="minimal"
176
+ elevation="subtle"
177
+ />
177
178
 
178
179
  <ScrollView style={styles.content}>
179
180
  {/* User Profile Section */}
180
- <View style={styles.section}>
181
- <Text style={styles.sectionTitle}>Profile</Text>
182
-
183
- <View style={[styles.settingItem, styles.firstSettingItem, styles.lastSettingItem]}>
184
- <View style={styles.userIcon}>
185
- <Avatar
186
- uri={user?.avatar?.url}
187
- name={user?.name?.full}
188
- size={40}
189
- theme={theme}
190
- />
191
- </View>
192
- <View style={styles.settingInfo}>
193
- <View>
194
- <Text style={styles.settingLabel}>
195
- {user ? (typeof user.name === 'string' ? user.name : user.name?.full || user.name?.first || user.username) : 'Loading...'}
196
- </Text>
197
- <Text style={styles.settingDescription}>{user ? (user.email || user.username) : 'Loading...'}</Text>
198
- </View>
199
- </View>
200
- <TouchableOpacity
201
- style={styles.manageButton}
202
- onPress={() => toast.info('Manage your Oxy Account feature coming soon!')}
203
- >
204
- <Text style={styles.manageButtonText}>Manage</Text>
205
- </TouchableOpacity>
206
- </View>
207
- </View>
181
+ <Section title="Profile" theme={theme} isFirst={true}>
182
+ <GroupedSection
183
+ items={[
184
+ {
185
+ id: 'profile-info',
186
+ icon: 'person',
187
+ iconColor: '#007AFF',
188
+ title: user ? (typeof user.name === 'string' ? user.name : user.name?.full || user.name?.first || user.username) : 'Loading...',
189
+ subtitle: user ? (user.email || user.username) : 'Loading...',
190
+ onPress: () => toast.info('Manage your Oxy Account feature coming soon!'),
191
+ customContent: (
192
+ <>
193
+ <View style={styles.userIcon}>
194
+ <Avatar
195
+ uri={user?.avatar?.url}
196
+ name={user?.name?.full}
197
+ size={40}
198
+ theme={theme}
199
+ />
200
+ </View>
201
+ <TouchableOpacity
202
+ style={styles.manageButton}
203
+ onPress={() => toast.info('Manage your Oxy Account feature coming soon!')}
204
+ >
205
+ <Text style={styles.manageButtonText}>Manage</Text>
206
+ </TouchableOpacity>
207
+ </>
208
+ ),
209
+ },
210
+ ]}
211
+ theme={theme}
212
+ />
213
+ </Section>
208
214
 
209
215
  {/* Account Settings */}
210
- <View style={styles.section}>
211
- <Text style={styles.sectionTitle}>Account Settings</Text>
212
-
213
- <TouchableOpacity
214
- style={[styles.settingItem, styles.firstSettingItem]}
215
- onPress={() => navigate?.('AccountSettings', { activeTab: 'profile' })}
216
- >
217
- <View style={styles.settingInfo}>
218
- <OxyIcon name="person-circle" size={20} color="#007AFF" style={styles.settingIcon} />
219
- <View>
220
- <Text style={styles.settingLabel}>Edit Profile</Text>
221
- <Text style={styles.settingDescription}>Update your personal information</Text>
222
- </View>
223
- </View>
224
- <OxyIcon name="chevron-forward" size={16} color="#ccc" />
225
- </TouchableOpacity>
226
-
227
- <TouchableOpacity
228
- style={styles.settingItem}
229
- onPress={() => navigate?.('AccountSettings', { activeTab: 'password' })}
230
- >
231
- <View style={styles.settingInfo}>
232
- <OxyIcon name="shield-checkmark" size={20} color="#30D158" style={styles.settingIcon} />
233
- <View>
234
- <Text style={styles.settingLabel}>Security & Privacy</Text>
235
- <Text style={styles.settingDescription}>Password, 2FA, and privacy settings</Text>
236
- </View>
237
- </View>
238
- <OxyIcon name="chevron-forward" size={16} color="#ccc" />
239
- </TouchableOpacity>
240
-
241
- <TouchableOpacity
242
- style={styles.settingItem}
243
- onPress={() => navigate?.('AccountSettings', { activeTab: 'notifications' })}
244
- >
245
- <View style={styles.settingInfo}>
246
- <OxyIcon name="notifications" size={20} color="#FF9500" style={styles.settingIcon} />
247
- <View>
248
- <Text style={styles.settingLabel}>Notifications</Text>
249
- <Text style={styles.settingDescription}>Manage your notification preferences</Text>
250
- </View>
251
- </View>
252
- <OxyIcon name="chevron-forward" size={16} color="#ccc" />
253
- </TouchableOpacity>
254
-
255
- <TouchableOpacity
256
- style={[styles.settingItem]}
257
- onPress={() => navigate?.('PremiumSubscription')}
258
- >
259
- <View style={styles.settingInfo}>
260
- <OxyIcon name="star" size={20} color="#FFD700" style={styles.settingIcon} />
261
- <View>
262
- <Text style={styles.settingLabel}>Oxy+ Subscriptions</Text>
263
- <Text style={styles.settingDescription}>{user?.isPremium ? 'Manage your premium plan' : 'Upgrade to premium features'}</Text>
264
- </View>
265
- </View>
266
- <OxyIcon name="chevron-forward" size={16} color="#ccc" />
267
- </TouchableOpacity>
268
-
269
- {user?.isPremium && (
270
- <TouchableOpacity
271
- style={[styles.settingItem, styles.lastSettingItem]}
272
- >
273
- <View style={styles.settingInfo}>
274
- <OxyIcon name="card" size={20} color="#34C759" style={styles.settingIcon} />
275
- <View>
276
- <Text style={styles.settingLabel}>Billing Management</Text>
277
- <Text style={styles.settingDescription}>Payment methods and invoices</Text>
278
- </View>
279
- </View>
280
- <OxyIcon name="chevron-forward" size={16} color="#ccc" />
281
- </TouchableOpacity>
282
- )}
283
- </View>
216
+ <Section title="Account Settings" theme={theme}>
217
+ <GroupedSection
218
+ items={[
219
+ {
220
+ id: 'edit-profile',
221
+ icon: 'person-circle',
222
+ iconColor: '#007AFF',
223
+ title: 'Edit Profile',
224
+ subtitle: 'Update your personal information',
225
+ onPress: () => navigate?.('EditProfile', { activeTab: 'profile' }),
226
+ },
227
+ {
228
+ id: 'security-privacy',
229
+ icon: 'shield-checkmark',
230
+ iconColor: '#30D158',
231
+ title: 'Security & Privacy',
232
+ subtitle: 'Password, 2FA, and privacy settings',
233
+ onPress: () => navigate?.('EditProfile', { activeTab: 'password' }),
234
+ },
235
+ {
236
+ id: 'notifications',
237
+ icon: 'notifications',
238
+ iconColor: '#FF9500',
239
+ title: 'Notifications',
240
+ subtitle: 'Manage your notification preferences',
241
+ onPress: () => navigate?.('EditProfile', { activeTab: 'notifications' }),
242
+ },
243
+ {
244
+ id: 'premium-subscription',
245
+ icon: 'star',
246
+ iconColor: '#FFD700',
247
+ title: 'Oxy+ Subscriptions',
248
+ subtitle: user?.isPremium ? 'Manage your premium plan' : 'Upgrade to premium features',
249
+ onPress: () => navigate?.('PremiumSubscription'),
250
+ },
251
+ ...(user?.isPremium ? [{
252
+ id: 'billing-management',
253
+ icon: 'card',
254
+ iconColor: '#34C759',
255
+ title: 'Billing Management',
256
+ subtitle: 'Payment methods and invoices',
257
+ onPress: () => toast.info('Billing management feature coming soon!'),
258
+ }] : []),
259
+ ]}
260
+ theme={theme}
261
+ />
262
+ </Section>
284
263
 
285
264
  {/* Additional Accounts */}
286
265
  {showMoreAccounts && (
287
- <View style={styles.section}>
288
- <Text style={styles.sectionTitle}>Additional Accounts{additionalAccountsData.length > 0 ? ` (${additionalAccountsData.length})` : ''}</Text>
289
-
266
+ <Section title={`Additional Accounts${additionalAccountsData.length > 0 ? ` (${additionalAccountsData.length})` : ''}`} theme={theme}>
290
267
  {loadingAdditionalAccounts ? (
291
- <View style={[styles.settingItem, styles.firstSettingItem, styles.lastSettingItem]}>
292
- <View style={styles.loadingContainer}>
293
- <ActivityIndicator size="small" color="#007AFF" />
294
- <Text style={styles.loadingText}>Loading accounts...</Text>
295
- </View>
296
- </View>
268
+ <GroupedSection
269
+ items={[
270
+ {
271
+ id: 'loading-accounts',
272
+ icon: 'sync',
273
+ iconColor: '#007AFF',
274
+ title: 'Loading accounts...',
275
+ subtitle: 'Please wait while we load your additional accounts',
276
+ customContent: (
277
+ <View style={styles.loadingContainer}>
278
+ <ActivityIndicator size="small" color="#007AFF" />
279
+ <Text style={styles.loadingText}>Loading accounts...</Text>
280
+ </View>
281
+ ),
282
+ },
283
+ ]}
284
+ theme={theme}
285
+ />
297
286
  ) : additionalAccountsData.length > 0 ? (
298
- <>
299
- {additionalAccountsData.map((account, index) => (
300
- <TouchableOpacity
301
- key={account.id}
302
- style={[
303
- styles.settingItem,
304
- index === 0 && styles.firstSettingItem,
305
- index === additionalAccountsData.length - 1 && styles.lastSettingItem
306
- ]}
307
- onPress={() => {
308
- toast.info(`Switch to ${account.username}?`);
309
- // TODO: Implement account switching logic
310
- // switchSession(account.sessionId);
311
- }}
312
- >
313
- <View style={styles.userIcon}>
314
- {account.avatar?.url ? (
315
- <Image source={{ uri: account.avatar.url }} style={styles.accountAvatarImage} />
316
- ) : (
317
- <View style={styles.accountAvatarFallback}>
318
- <Text style={styles.accountAvatarText}>
319
- {account.username?.charAt(0).toUpperCase() || '?'}
320
- </Text>
321
- </View>
322
- )}
323
- </View>
324
- <View style={styles.settingInfo}>
325
- <View>
326
- <Text style={styles.settingLabel}>
327
- {typeof account.name === 'object'
328
- ? account.name?.full || account.name?.first || account.username
329
- : account.name || account.username
330
- }
331
- </Text>
332
- <Text style={styles.settingDescription}>{account.email || account.username}</Text>
287
+ <GroupedSection
288
+ items={additionalAccountsData.map((account, index) => ({
289
+ id: `account-${account.id}`,
290
+ icon: 'person',
291
+ iconColor: '#5856D6',
292
+ title: typeof account.name === 'object'
293
+ ? account.name?.full || account.name?.first || account.username
294
+ : account.name || account.username,
295
+ subtitle: account.email || account.username,
296
+ onPress: () => {
297
+ toast.info(`Switch to ${account.username}?`);
298
+ // TODO: Implement account switching logic
299
+ // switchSession(account.sessionId);
300
+ },
301
+ customContent: (
302
+ <>
303
+ <View style={styles.userIcon}>
304
+ {account.avatar?.url ? (
305
+ <Image source={{ uri: account.avatar.url }} style={styles.accountAvatarImage} />
306
+ ) : (
307
+ <View style={styles.accountAvatarFallback}>
308
+ <Text style={styles.accountAvatarText}>
309
+ {account.username?.charAt(0).toUpperCase() || '?'}
310
+ </Text>
311
+ </View>
312
+ )}
333
313
  </View>
334
- </View>
335
- <OxyIcon name="chevron-forward" size={16} color="#ccc" />
336
- </TouchableOpacity>
337
- ))}
338
- </>
314
+ <OxyIcon name="chevron-forward" size={16} color="#ccc" />
315
+ </>
316
+ ),
317
+ }))}
318
+ theme={theme}
319
+ />
339
320
  ) : (
340
- <View style={[styles.settingItem, styles.firstSettingItem, styles.lastSettingItem]}>
341
- <View style={styles.settingInfo}>
342
- <OxyIcon name="person-outline" size={20} color="#ccc" style={styles.settingIcon} />
343
- <View>
344
- <Text style={styles.settingLabel}>No other accounts</Text>
345
- <Text style={styles.settingDescription}>Add another account to switch between them</Text>
346
- </View>
347
- </View>
348
- </View>
321
+ <GroupedSection
322
+ items={[
323
+ {
324
+ id: 'no-accounts',
325
+ icon: 'person-outline',
326
+ iconColor: '#ccc',
327
+ title: 'No other accounts',
328
+ subtitle: 'Add another account to switch between them',
329
+ },
330
+ ]}
331
+ theme={theme}
332
+ />
349
333
  )}
350
- </View>
334
+ </Section>
351
335
  )}
352
336
 
353
337
  {/* Account Management */}
354
338
  {showMoreAccounts && (
355
- <View style={styles.section}>
356
- <Text style={styles.sectionTitle}>Account Management</Text>
357
-
358
- <TouchableOpacity
359
- style={[styles.settingItem, styles.firstSettingItem]}
360
- onPress={handleAddAccount}
361
- >
362
- <View style={styles.settingInfo}>
363
- <OxyIcon name="add" size={20} color="#007AFF" style={styles.settingIcon} />
364
- <View>
365
- <Text style={styles.settingLabel}>Add another account</Text>
366
- <Text style={styles.settingDescription}>Sign in with a different account</Text>
367
- </View>
368
- </View>
369
- <OxyIcon name="chevron-forward" size={16} color="#ccc" />
370
- </TouchableOpacity>
371
-
372
- <TouchableOpacity
373
- style={[styles.settingItem, styles.lastSettingItem]}
374
- onPress={handleSignOutAll}
375
- >
376
- <View style={styles.settingInfo}>
377
- <OxyIcon name="log-out" size={20} color="#FF3B30" style={styles.settingIcon} />
378
- <View>
379
- <Text style={styles.settingLabel}>Sign out of all accounts</Text>
380
- <Text style={styles.settingDescription}>Remove all accounts from this device</Text>
381
- </View>
382
- </View>
383
- <OxyIcon name="chevron-forward" size={16} color="#ccc" />
384
- </TouchableOpacity>
385
- </View>
339
+ <Section title="Account Management" theme={theme}>
340
+ <GroupedSection
341
+ items={[
342
+ {
343
+ id: 'add-account',
344
+ icon: 'add',
345
+ iconColor: '#007AFF',
346
+ title: 'Add another account',
347
+ subtitle: 'Sign in with a different account',
348
+ onPress: handleAddAccount,
349
+ },
350
+ {
351
+ id: 'sign-out-all',
352
+ icon: 'log-out',
353
+ iconColor: '#FF3B30',
354
+ title: 'Sign out of all accounts',
355
+ subtitle: 'Remove all accounts from this device',
356
+ onPress: handleSignOutAll,
357
+ },
358
+ ]}
359
+ theme={theme}
360
+ />
361
+ </Section>
386
362
  )}
387
363
 
388
364
  {/* Quick Actions */}
389
- <View style={styles.section}>
390
- <Text style={styles.sectionTitle}>Quick Actions</Text>
391
-
392
- <TouchableOpacity
393
- style={[styles.settingItem, styles.firstSettingItem]}
394
- onPress={() => setShowMoreAccounts(!showMoreAccounts)}
395
- >
396
- <View style={styles.settingInfo}>
397
- <OxyIcon name="people" size={20} color="#5856D6" style={styles.settingIcon} />
398
- <View>
399
- <Text style={styles.settingLabel}>
400
- {showMoreAccounts ? 'Hide' : 'Show'} Account Switcher
401
- </Text>
402
- <Text style={styles.settingDescription}>
403
- {showMoreAccounts
404
- ? 'Hide account switcher'
405
- : additionalAccountsData.length > 0
406
- ? `Switch between ${additionalAccountsData.length + 1} accounts`
407
- : loadingAdditionalAccounts
408
- ? 'Loading additional accounts...'
409
- : 'Manage multiple accounts'
410
- }
411
- </Text>
412
- </View>
413
- </View>
414
- <OxyIcon name="chevron-forward" size={16} color="#ccc" />
415
- </TouchableOpacity>
416
-
417
- <TouchableOpacity
418
- style={styles.settingItem}
419
- onPress={() => toast.info('Download account data feature coming soon!')}
420
- >
421
- <View style={styles.settingInfo}>
422
- <OxyIcon name="download" size={20} color="#34C759" style={styles.settingIcon} />
423
- <View>
424
- <Text style={styles.settingLabel}>Download My Data</Text>
425
- <Text style={styles.settingDescription}>Export your account information</Text>
426
- </View>
427
- </View>
428
- <OxyIcon name="chevron-forward" size={16} color="#ccc" />
429
- </TouchableOpacity>
430
-
431
- <TouchableOpacity
432
- style={[styles.settingItem, styles.lastSettingItem]}
433
- onPress={() => toast.info('Delete account feature coming soon!')}
434
- >
435
- <View style={styles.settingInfo}>
436
- <OxyIcon name="trash" size={20} color="#FF3B30" style={styles.settingIcon} />
437
- <View>
438
- <Text style={styles.settingLabel}>Delete Account</Text>
439
- <Text style={styles.settingDescription}>Permanently delete your account</Text>
440
- </View>
441
- </View>
442
- <OxyIcon name="chevron-forward" size={16} color="#ccc" />
443
- </TouchableOpacity>
444
- </View>
365
+ <Section title="Quick Actions" theme={theme}>
366
+ <GroupedSection
367
+ items={[
368
+ {
369
+ id: 'account-switcher',
370
+ icon: 'people',
371
+ iconColor: '#5856D6',
372
+ title: `${showMoreAccounts ? 'Hide' : 'Show'} Account Switcher`,
373
+ subtitle: showMoreAccounts
374
+ ? 'Hide account switcher'
375
+ : additionalAccountsData.length > 0
376
+ ? `Switch between ${additionalAccountsData.length + 1} accounts`
377
+ : loadingAdditionalAccounts
378
+ ? 'Loading additional accounts...'
379
+ : 'Manage multiple accounts',
380
+ onPress: () => setShowMoreAccounts(!showMoreAccounts),
381
+ },
382
+ {
383
+ id: 'download-data',
384
+ icon: 'download',
385
+ iconColor: '#34C759',
386
+ title: 'Download My Data',
387
+ subtitle: 'Export your account information',
388
+ onPress: () => toast.info('Download account data feature coming soon!'),
389
+ },
390
+ {
391
+ id: 'delete-account',
392
+ icon: 'trash',
393
+ iconColor: '#FF3B30',
394
+ title: 'Delete Account',
395
+ subtitle: 'Permanently delete your account',
396
+ onPress: () => toast.info('Delete account feature coming soon!'),
397
+ },
398
+ ]}
399
+ theme={theme}
400
+ />
401
+ </Section>
445
402
 
446
403
  {/* Support & Settings */}
447
- <View style={styles.section}>
448
- <Text style={styles.sectionTitle}>Support & Settings</Text>
449
-
450
- <TouchableOpacity
451
- style={[styles.settingItem, styles.firstSettingItem]}
452
- onPress={() => toast.info('Account preferences coming soon!')}
453
- >
454
- <View style={styles.settingInfo}>
455
- <OxyIcon name="settings" size={20} color="#8E8E93" style={styles.settingIcon} />
456
- <View>
457
- <Text style={styles.settingLabel}>Account Preferences</Text>
458
- <Text style={styles.settingDescription}>Customize your account experience</Text>
459
- </View>
460
- </View>
461
- <OxyIcon name="chevron-forward" size={16} color="#ccc" />
462
- </TouchableOpacity>
463
-
464
- <TouchableOpacity
465
- style={styles.settingItem}
466
- onPress={() => toast.info('Help & support feature coming soon!')}
467
- >
468
- <View style={styles.settingInfo}>
469
- <OxyIcon name="help-circle" size={20} color="#007AFF" style={styles.settingIcon} />
470
- <View>
471
- <Text style={styles.settingLabel}>Help & Support</Text>
472
- <Text style={styles.settingDescription}>Get help with your account</Text>
473
- </View>
474
- </View>
475
- <OxyIcon name="chevron-forward" size={16} color="#ccc" />
476
- </TouchableOpacity>
477
-
478
- <TouchableOpacity
479
- style={styles.settingItem}
480
- onPress={() => toast.info('Connected apps feature coming soon!')}
481
- >
482
- <View style={styles.settingInfo}>
483
- <OxyIcon name="link" size={20} color="#32D74B" style={styles.settingIcon} />
484
- <View>
485
- <Text style={styles.settingLabel}>Connected Apps</Text>
486
- <Text style={styles.settingDescription}>Manage third-party app access</Text>
487
- </View>
488
- </View>
489
- <OxyIcon name="chevron-forward" size={16} color="#ccc" />
490
- </TouchableOpacity>
491
-
492
- <TouchableOpacity
493
- style={styles.settingItem}
494
- onPress={() => toast.info('Privacy Policy feature coming soon!')}
495
- >
496
- <View style={styles.settingInfo}>
497
- <OxyIcon name="document-lock" size={20} color="#FF9F0A" style={styles.settingIcon} />
498
- <View>
499
- <Text style={styles.settingLabel}>Privacy Policy</Text>
500
- <Text style={styles.settingDescription}>Learn about data protection</Text>
501
- </View>
502
- </View>
503
- <OxyIcon name="chevron-forward" size={16} color="#ccc" />
504
- </TouchableOpacity>
505
-
506
- <TouchableOpacity
507
- style={[styles.settingItem, styles.lastSettingItem]}
508
- onPress={() => toast.info('Terms of Service feature coming soon!')}
509
- >
510
- <View style={styles.settingInfo}>
511
- <OxyIcon name="document-text" size={20} color="#5856D6" style={styles.settingIcon} />
512
- <View>
513
- <Text style={styles.settingLabel}>Terms of Service</Text>
514
- <Text style={styles.settingDescription}>Read our terms and conditions</Text>
515
- </View>
516
- </View>
517
- <OxyIcon name="chevron-forward" size={16} color="#ccc" />
518
- </TouchableOpacity>
519
- </View>
404
+ <Section title="Support & Settings" theme={theme}>
405
+ <GroupedSection
406
+ items={[
407
+ {
408
+ id: 'account-preferences',
409
+ icon: 'settings',
410
+ iconColor: '#8E8E93',
411
+ title: 'Account Preferences',
412
+ subtitle: 'Customize your account experience',
413
+ onPress: () => toast.info('Account preferences coming soon!'),
414
+ },
415
+ {
416
+ id: 'help-support',
417
+ icon: 'help-circle',
418
+ iconColor: '#007AFF',
419
+ title: 'Help & Support',
420
+ subtitle: 'Get help with your account',
421
+ onPress: () => toast.info('Help & support feature coming soon!'),
422
+ },
423
+ {
424
+ id: 'connected-apps',
425
+ icon: 'link',
426
+ iconColor: '#32D74B',
427
+ title: 'Connected Apps',
428
+ subtitle: 'Manage third-party app access',
429
+ onPress: () => toast.info('Connected apps feature coming soon!'),
430
+ },
431
+ {
432
+ id: 'about',
433
+ icon: 'information-circle',
434
+ iconColor: '#8E8E93',
435
+ title: 'About',
436
+ subtitle: 'App version and information',
437
+ onPress: () => navigate?.('AppInfo'),
438
+ },
439
+ ]}
440
+ theme={theme}
441
+ />
442
+ </Section>
520
443
 
521
444
  {/* Sign Out */}
522
- <View style={styles.section}>
523
- <TouchableOpacity
524
- style={[styles.settingItem, styles.firstSettingItem, styles.lastSettingItem, styles.signOutButton]}
445
+ <Section title="Account Actions" theme={theme}>
446
+ <GroupedItem
447
+ icon="log-out"
448
+ iconColor="#FF3B30"
449
+ title="Sign Out"
450
+ subtitle="Sign out of your current account"
451
+ theme={theme}
525
452
  onPress={confirmLogout}
526
- >
527
- <View style={styles.settingInfo}>
528
- <OxyIcon name="log-out" size={20} color="#ff4757" style={styles.settingIcon} />
529
- <View>
530
- <Text style={[styles.settingLabel, { color: '#ff4757' }]}>Sign Out</Text>
531
- <Text style={styles.settingDescription}>Sign out of your account</Text>
532
- </View>
533
- </View>
534
- </TouchableOpacity>
535
- </View>
453
+ isFirst={true}
454
+ isLast={true}
455
+ showChevron={false}
456
+ />
457
+ </Section>
536
458
  </ScrollView>
537
459
  </View>
538
460
  );
@@ -543,78 +465,11 @@ const styles = StyleSheet.create({
543
465
  flex: 1,
544
466
  backgroundColor: '#f2f2f2',
545
467
  },
546
- header: {
547
- paddingHorizontal: 20,
548
- paddingTop: 60,
549
- paddingBottom: 16,
550
- backgroundColor: '#fff',
551
- borderBottomWidth: 1,
552
- borderBottomColor: '#e0e0e0',
553
- flexDirection: 'row',
554
- justifyContent: 'space-between',
555
- alignItems: 'center',
556
- },
557
- headerTitle: {
558
- fontSize: 24,
559
- fontWeight: 'bold',
560
- color: '#000',
561
- },
562
- closeButton: {
563
- padding: 8,
564
- },
565
- closeButtonText: {
566
- fontSize: 24,
567
- color: '#000',
568
- fontWeight: '300',
569
- },
570
468
  content: {
571
469
  flex: 1,
572
470
  padding: 16,
573
471
  },
574
- section: {
575
- marginBottom: 24,
576
- },
577
- sectionTitle: {
578
- fontSize: 16,
579
- fontWeight: '600',
580
- color: '#333',
581
- marginBottom: 12,
582
- },
583
- settingItem: {
584
- backgroundColor: '#fff',
585
- padding: 16,
586
- flexDirection: 'row',
587
- alignItems: 'center',
588
- justifyContent: 'space-between',
589
- marginBottom: 2,
590
- },
591
- firstSettingItem: {
592
- borderTopLeftRadius: 24,
593
- borderTopRightRadius: 24,
594
- },
595
- lastSettingItem: {
596
- borderBottomLeftRadius: 24,
597
- borderBottomRightRadius: 24,
598
- marginBottom: 8,
599
- },
600
- settingInfo: {
601
- flexDirection: 'row',
602
- alignItems: 'center',
603
- flex: 1,
604
- },
605
- settingIcon: {
606
- marginRight: 12,
607
- },
608
- settingLabel: {
609
- fontSize: 16,
610
- fontWeight: '500',
611
- color: '#333',
612
- marginBottom: 2,
613
- },
614
- settingDescription: {
615
- fontSize: 14,
616
- color: '#666',
617
- },
472
+
618
473
  userIcon: {
619
474
  marginRight: 12,
620
475
  },
@@ -647,10 +502,6 @@ const styles = StyleSheet.create({
647
502
  fontSize: 18,
648
503
  fontWeight: 'bold',
649
504
  },
650
- signOutButton: {
651
- borderWidth: 1,
652
- borderColor: '#ff4757',
653
- },
654
505
  message: {
655
506
  fontSize: 16,
656
507
  textAlign: 'center',