@oxyhq/services 5.13.4 → 5.13.11

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 (170) hide show
  1. package/lib/commonjs/core/HttpClient.js +1 -1
  2. package/lib/commonjs/core/HttpClient.js.map +1 -1
  3. package/lib/commonjs/core/OxyServices.js +91 -30
  4. package/lib/commonjs/core/OxyServices.js.map +1 -1
  5. package/lib/commonjs/core/index.js +0 -7
  6. package/lib/commonjs/core/index.js.map +1 -1
  7. package/lib/commonjs/i18n/locales/en-US.json +222 -6
  8. package/lib/commonjs/index.js +0 -7
  9. package/lib/commonjs/index.js.map +1 -1
  10. package/lib/commonjs/lib/sonner.js.map +1 -1
  11. package/lib/commonjs/ui/components/GroupedItem.js +24 -22
  12. package/lib/commonjs/ui/components/GroupedItem.js.map +1 -1
  13. package/lib/commonjs/ui/components/OxyProvider.js +35 -14
  14. package/lib/commonjs/ui/components/OxyProvider.js.map +1 -1
  15. package/lib/commonjs/ui/navigation/routes.js +36 -1
  16. package/lib/commonjs/ui/navigation/routes.js.map +1 -1
  17. package/lib/commonjs/ui/screens/AccountOverviewScreen.js +150 -5
  18. package/lib/commonjs/ui/screens/AccountOverviewScreen.js.map +1 -1
  19. package/lib/commonjs/ui/screens/AccountSettingsScreen.js +475 -319
  20. package/lib/commonjs/ui/screens/AccountSettingsScreen.js.map +1 -1
  21. package/lib/commonjs/ui/screens/AccountVerificationScreen.js +217 -0
  22. package/lib/commonjs/ui/screens/AccountVerificationScreen.js.map +1 -0
  23. package/lib/commonjs/ui/screens/FileManagementScreen.js +911 -213
  24. package/lib/commonjs/ui/screens/FileManagementScreen.js.map +1 -1
  25. package/lib/commonjs/ui/screens/HelpSupportScreen.js +131 -0
  26. package/lib/commonjs/ui/screens/HelpSupportScreen.js.map +1 -0
  27. package/lib/commonjs/ui/screens/HistoryViewScreen.js +258 -0
  28. package/lib/commonjs/ui/screens/HistoryViewScreen.js.map +1 -0
  29. package/lib/commonjs/ui/screens/LegalDocumentsScreen.js +211 -0
  30. package/lib/commonjs/ui/screens/LegalDocumentsScreen.js.map +1 -0
  31. package/lib/commonjs/ui/screens/PremiumSubscriptionScreen.js +0 -1
  32. package/lib/commonjs/ui/screens/PremiumSubscriptionScreen.js.map +1 -1
  33. package/lib/commonjs/ui/screens/PrivacySettingsScreen.js +307 -0
  34. package/lib/commonjs/ui/screens/PrivacySettingsScreen.js.map +1 -0
  35. package/lib/commonjs/ui/screens/ProfileScreen.js +1 -7
  36. package/lib/commonjs/ui/screens/ProfileScreen.js.map +1 -1
  37. package/lib/commonjs/ui/screens/SavesCollectionsScreen.js +205 -0
  38. package/lib/commonjs/ui/screens/SavesCollectionsScreen.js.map +1 -0
  39. package/lib/commonjs/ui/screens/SearchSettingsScreen.js +239 -0
  40. package/lib/commonjs/ui/screens/SearchSettingsScreen.js.map +1 -0
  41. package/lib/commonjs/ui/screens/SignInScreen.js +14 -29
  42. package/lib/commonjs/ui/screens/SignInScreen.js.map +1 -1
  43. package/lib/commonjs/utils/asyncUtils.js +1 -0
  44. package/lib/commonjs/utils/asyncUtils.js.map +1 -1
  45. package/lib/commonjs/utils/cache.js +4 -4
  46. package/lib/commonjs/utils/cache.js.map +1 -1
  47. package/lib/commonjs/utils/index.js +0 -6
  48. package/lib/commonjs/utils/index.js.map +1 -1
  49. package/lib/module/core/HttpClient.js +1 -1
  50. package/lib/module/core/HttpClient.js.map +1 -1
  51. package/lib/module/core/OxyServices.js +90 -29
  52. package/lib/module/core/OxyServices.js.map +1 -1
  53. package/lib/module/core/index.js +1 -1
  54. package/lib/module/core/index.js.map +1 -1
  55. package/lib/module/i18n/locales/en-US.json +222 -6
  56. package/lib/module/index.js +1 -1
  57. package/lib/module/index.js.map +1 -1
  58. package/lib/module/lib/sonner.js.map +1 -1
  59. package/lib/module/ui/components/GroupedItem.js +24 -22
  60. package/lib/module/ui/components/GroupedItem.js.map +1 -1
  61. package/lib/module/ui/components/OxyProvider.js +40 -17
  62. package/lib/module/ui/components/OxyProvider.js.map +1 -1
  63. package/lib/module/ui/navigation/routes.js +36 -1
  64. package/lib/module/ui/navigation/routes.js.map +1 -1
  65. package/lib/module/ui/screens/AccountOverviewScreen.js +151 -6
  66. package/lib/module/ui/screens/AccountOverviewScreen.js.map +1 -1
  67. package/lib/module/ui/screens/AccountSettingsScreen.js +475 -319
  68. package/lib/module/ui/screens/AccountSettingsScreen.js.map +1 -1
  69. package/lib/module/ui/screens/AccountVerificationScreen.js +212 -0
  70. package/lib/module/ui/screens/AccountVerificationScreen.js.map +1 -0
  71. package/lib/module/ui/screens/FileManagementScreen.js +913 -212
  72. package/lib/module/ui/screens/FileManagementScreen.js.map +1 -1
  73. package/lib/module/ui/screens/HelpSupportScreen.js +126 -0
  74. package/lib/module/ui/screens/HelpSupportScreen.js.map +1 -0
  75. package/lib/module/ui/screens/HistoryViewScreen.js +253 -0
  76. package/lib/module/ui/screens/HistoryViewScreen.js.map +1 -0
  77. package/lib/module/ui/screens/LegalDocumentsScreen.js +206 -0
  78. package/lib/module/ui/screens/LegalDocumentsScreen.js.map +1 -0
  79. package/lib/module/ui/screens/PremiumSubscriptionScreen.js +0 -1
  80. package/lib/module/ui/screens/PremiumSubscriptionScreen.js.map +1 -1
  81. package/lib/module/ui/screens/PrivacySettingsScreen.js +302 -0
  82. package/lib/module/ui/screens/PrivacySettingsScreen.js.map +1 -0
  83. package/lib/module/ui/screens/ProfileScreen.js +1 -7
  84. package/lib/module/ui/screens/ProfileScreen.js.map +1 -1
  85. package/lib/module/ui/screens/SavesCollectionsScreen.js +200 -0
  86. package/lib/module/ui/screens/SavesCollectionsScreen.js.map +1 -0
  87. package/lib/module/ui/screens/SearchSettingsScreen.js +234 -0
  88. package/lib/module/ui/screens/SearchSettingsScreen.js.map +1 -0
  89. package/lib/module/ui/screens/SignInScreen.js +14 -29
  90. package/lib/module/ui/screens/SignInScreen.js.map +1 -1
  91. package/lib/module/utils/asyncUtils.js +1 -0
  92. package/lib/module/utils/asyncUtils.js.map +1 -1
  93. package/lib/module/utils/cache.js +3 -3
  94. package/lib/module/utils/cache.js.map +1 -1
  95. package/lib/module/utils/index.js +1 -1
  96. package/lib/module/utils/index.js.map +1 -1
  97. package/lib/typescript/core/OxyServices.d.ts +35 -23
  98. package/lib/typescript/core/OxyServices.d.ts.map +1 -1
  99. package/lib/typescript/core/index.d.ts +1 -1
  100. package/lib/typescript/core/index.d.ts.map +1 -1
  101. package/lib/typescript/index.d.ts +1 -1
  102. package/lib/typescript/index.d.ts.map +1 -1
  103. package/lib/typescript/lib/sonner.d.ts +1 -0
  104. package/lib/typescript/lib/sonner.d.ts.map +1 -1
  105. package/lib/typescript/types/expo-document-picker.d.ts +36 -0
  106. package/lib/typescript/ui/components/GroupedItem.d.ts.map +1 -1
  107. package/lib/typescript/ui/components/OxyProvider.d.ts.map +1 -1
  108. package/lib/typescript/ui/navigation/routes.d.ts +1 -1
  109. package/lib/typescript/ui/navigation/routes.d.ts.map +1 -1
  110. package/lib/typescript/ui/screens/AccountOverviewScreen.d.ts.map +1 -1
  111. package/lib/typescript/ui/screens/AccountSettingsScreen.d.ts.map +1 -1
  112. package/lib/typescript/ui/screens/AccountVerificationScreen.d.ts +5 -0
  113. package/lib/typescript/ui/screens/AccountVerificationScreen.d.ts.map +1 -0
  114. package/lib/typescript/ui/screens/FileManagementScreen.d.ts.map +1 -1
  115. package/lib/typescript/ui/screens/HelpSupportScreen.d.ts +5 -0
  116. package/lib/typescript/ui/screens/HelpSupportScreen.d.ts.map +1 -0
  117. package/lib/typescript/ui/screens/HistoryViewScreen.d.ts +5 -0
  118. package/lib/typescript/ui/screens/HistoryViewScreen.d.ts.map +1 -0
  119. package/lib/typescript/ui/screens/LegalDocumentsScreen.d.ts +5 -0
  120. package/lib/typescript/ui/screens/LegalDocumentsScreen.d.ts.map +1 -0
  121. package/lib/typescript/ui/screens/PremiumSubscriptionScreen.d.ts.map +1 -1
  122. package/lib/typescript/ui/screens/PrivacySettingsScreen.d.ts +5 -0
  123. package/lib/typescript/ui/screens/PrivacySettingsScreen.d.ts.map +1 -0
  124. package/lib/typescript/ui/screens/ProfileScreen.d.ts.map +1 -1
  125. package/lib/typescript/ui/screens/SavesCollectionsScreen.d.ts +5 -0
  126. package/lib/typescript/ui/screens/SavesCollectionsScreen.d.ts.map +1 -0
  127. package/lib/typescript/ui/screens/SearchSettingsScreen.d.ts +5 -0
  128. package/lib/typescript/ui/screens/SearchSettingsScreen.d.ts.map +1 -0
  129. package/lib/typescript/ui/screens/SignInScreen.d.ts.map +1 -1
  130. package/lib/typescript/utils/asyncUtils.d.ts.map +1 -1
  131. package/lib/typescript/utils/cache.d.ts +3 -3
  132. package/lib/typescript/utils/cache.d.ts.map +1 -1
  133. package/lib/typescript/utils/index.d.ts +1 -1
  134. package/lib/typescript/utils/index.d.ts.map +1 -1
  135. package/package.json +1 -1
  136. package/src/core/HttpClient.ts +1 -1
  137. package/src/core/OxyServices.ts +88 -30
  138. package/src/core/index.ts +1 -1
  139. package/src/i18n/locales/en-US.json +222 -6
  140. package/src/index.ts +1 -1
  141. package/src/lib/sonner.ts +1 -0
  142. package/src/types/expo-document-picker.d.ts +36 -0
  143. package/src/ui/components/GroupedItem.tsx +23 -21
  144. package/src/ui/components/OxyProvider.tsx +33 -11
  145. package/src/ui/navigation/routes.ts +42 -0
  146. package/src/ui/screens/AccountOverviewScreen.tsx +175 -5
  147. package/src/ui/screens/AccountSettingsScreen.tsx +521 -360
  148. package/src/ui/screens/AccountVerificationScreen.tsx +235 -0
  149. package/src/ui/screens/FileManagementScreen.tsx +934 -208
  150. package/src/ui/screens/HelpSupportScreen.tsx +143 -0
  151. package/src/ui/screens/HistoryViewScreen.tsx +280 -0
  152. package/src/ui/screens/LegalDocumentsScreen.tsx +220 -0
  153. package/src/ui/screens/PremiumSubscriptionScreen.tsx +0 -1
  154. package/src/ui/screens/PrivacySettingsScreen.tsx +332 -0
  155. package/src/ui/screens/ProfileScreen.tsx +1 -8
  156. package/src/ui/screens/SavesCollectionsScreen.tsx +222 -0
  157. package/src/ui/screens/SearchSettingsScreen.tsx +219 -0
  158. package/src/ui/screens/SignInScreen.tsx +19 -35
  159. package/src/utils/asyncUtils.ts +1 -0
  160. package/src/utils/cache.ts +3 -3
  161. package/src/utils/index.ts +1 -1
  162. package/lib/commonjs/ui/components/StepBasedScreen.README.md +0 -337
  163. package/lib/commonjs/ui/components/internal/TextField.md +0 -436
  164. package/lib/commonjs/ui/styles/FONTS.md +0 -126
  165. package/lib/module/ui/components/StepBasedScreen.README.md +0 -337
  166. package/lib/module/ui/components/internal/TextField.md +0 -436
  167. package/lib/module/ui/styles/FONTS.md +0 -126
  168. package/src/ui/components/StepBasedScreen.README.md +0 -337
  169. package/src/ui/components/internal/TextField.md +0 -436
  170. package/src/ui/styles/FONTS.md +0 -126
@@ -45,7 +45,7 @@ const GroupedItem: React.FC<GroupedItemProps> = ({
45
45
  }) => {
46
46
  const isDarkTheme = theme === 'dark';
47
47
  const textColor = isDarkTheme ? '#FFFFFF' : '#000000';
48
- const secondaryBackgroundColor = isDarkTheme ? '#222222' : '#FFFFFF';
48
+ const secondaryBackgroundColor = isDarkTheme ? '#1C1C1E' : '#FFFFFF';
49
49
  const selectedBackgroundColor = selected ? `${iconColor}15` : secondaryBackgroundColor;
50
50
 
51
51
  const itemStyles = [
@@ -80,7 +80,7 @@ const GroupedItem: React.FC<GroupedItemProps> = ({
80
80
  <View style={[styles.actionTextContainer, multiRow && styles.actionTextContainerMultiRow]}>
81
81
  <Text style={[styles.actionButtonText, { color: textColor }]}>{title}</Text>
82
82
  {subtitle && (
83
- <Text style={[styles.actionButtonSubtext, { color: isDarkTheme ? '#BBBBBB' : '#666666' }]}>
83
+ <Text style={[styles.actionButtonSubtext, { color: isDarkTheme ? '#98989D' : '#8E8E93' }]}>
84
84
  {subtitle}
85
85
  </Text>
86
86
  )}
@@ -90,7 +90,7 @@ const GroupedItem: React.FC<GroupedItemProps> = ({
90
90
  {selected ? (
91
91
  <Ionicons name="checkmark-circle" size={20} color={iconColor || '#007AFF'} />
92
92
  ) : showChevron ? (
93
- <Ionicons name="chevron-forward" size={16} color={isDarkTheme ? '#666666' : '#999999'} />
93
+ <Ionicons name="chevron-forward" size={16} color={isDarkTheme ? '#636366' : '#C7C7CC'} />
94
94
  ) : null}
95
95
  </View>
96
96
  );
@@ -115,56 +115,58 @@ const styles = StyleSheet.create({
115
115
  flexDirection: 'row',
116
116
  alignItems: 'center',
117
117
  justifyContent: 'space-between',
118
- marginBottom: 2,
118
+ marginBottom: StyleSheet.hairlineWidth,
119
119
  overflow: 'hidden',
120
120
  width: '100%',
121
121
  },
122
122
  firstGroupedItem: {
123
- borderTopLeftRadius: 24,
124
- borderTopRightRadius: 24,
123
+ borderTopLeftRadius: 16,
124
+ borderTopRightRadius: 16,
125
125
  },
126
126
  lastGroupedItem: {
127
- borderBottomLeftRadius: 24,
128
- borderBottomRightRadius: 24,
129
- marginBottom: 8,
127
+ borderBottomLeftRadius: 16,
128
+ borderBottomRightRadius: 16,
129
+ marginBottom: 0,
130
130
  },
131
131
  groupedItemContent: {
132
132
  flexDirection: 'row',
133
133
  alignItems: 'center',
134
- paddingVertical: 12,
135
- paddingHorizontal: 12,
134
+ paddingVertical: 14,
135
+ paddingHorizontal: 16,
136
136
  width: '100%',
137
137
  },
138
138
  groupedItemContentDense: {
139
- paddingVertical: 10,
140
- paddingHorizontal: 12,
139
+ paddingVertical: 12,
140
+ paddingHorizontal: 16,
141
141
  },
142
142
  actionIcon: {
143
143
  marginRight: 12,
144
144
  },
145
145
  iconContainer: {
146
- width: 38,
147
- height: 38,
148
- borderRadius: 19,
146
+ width: 32,
147
+ height: 32,
148
+ borderRadius: 12,
149
149
  alignItems: 'center',
150
150
  justifyContent: 'center',
151
151
  marginRight: 12,
152
152
  },
153
153
  actionImage: {
154
154
  marginRight: 12,
155
- borderRadius: 16,
155
+ borderRadius: 12,
156
156
  },
157
157
  actionTextContainer: {
158
158
  flex: 1,
159
159
  },
160
160
  actionButtonText: {
161
- fontSize: 16,
162
- fontWeight: '500',
161
+ fontSize: 17,
162
+ fontWeight: '400',
163
163
  marginBottom: 2,
164
+ letterSpacing: -0.2,
164
165
  },
165
166
  actionButtonSubtext: {
166
- fontSize: 13,
167
- lineHeight: 18,
167
+ fontSize: 15,
168
+ lineHeight: 20,
169
+ marginTop: 1,
168
170
  },
169
171
  groupedItemContentMultiRow: {
170
172
  alignItems: 'flex-start',
@@ -10,8 +10,9 @@ import { Toaster } from '../../lib/sonner';
10
10
  import { QueryClient, QueryClientProvider, focusManager } from '@tanstack/react-query';
11
11
 
12
12
  // Import bottom sheet components directly - no longer a peer dependency
13
- import { BottomSheetModal, BottomSheetBackdrop, type BottomSheetBackdropProps, BottomSheetModalProvider, BottomSheetView } from '@gorhom/bottom-sheet';
13
+ import { BottomSheetModal, BottomSheetBackdrop, type BottomSheetBackdropProps, BottomSheetModalProvider, BottomSheetScrollView } from '@gorhom/bottom-sheet';
14
14
  import type { BottomSheetModalMethods as BottomSheetModalRef } from '@gorhom/bottom-sheet/lib/typescript/types';
15
+ import { useWindowDimensions } from 'react-native';
15
16
 
16
17
  // Initialize fonts automatically
17
18
  setupFonts();
@@ -113,7 +114,7 @@ const OxyProvider: FC<OxyProviderProps> = (props) => {
113
114
  {/* Global Toaster for app-wide notifications outside of Modal contexts - only show if internal toaster is disabled */}
114
115
  {!showInternalToaster && (
115
116
  <View style={styles.toasterContainer}>
116
- <Toaster position="top-center" swipeToDismissDirection="left" offset={15} />
117
+ <Toaster position="bottom-center" swipeToDismissDirection="left" offset={15} />
117
118
  </View>
118
119
  )}
119
120
  </GestureHandlerRootView>
@@ -146,6 +147,8 @@ const OxyBottomSheet = forwardRef<BottomSheetController, OxyBottomSheetProps>(({
146
147
  const shouldUseNativeDriver = () => {
147
148
  return Platform.OS === 'ios';
148
149
  };
150
+ // Get window dimensions for max height calculation
151
+ const { height: windowHeight } = useWindowDimensions();
149
152
  // Get oxyServices from context if not provided as prop
150
153
  const contextOxy = useOxy();
151
154
  const oxyServices = providedOxyServices || contextOxy?.oxyServices;
@@ -153,6 +156,7 @@ const OxyBottomSheet = forwardRef<BottomSheetController, OxyBottomSheetProps>(({
153
156
  const modalRef = useRef<BottomSheetModalRef>(null);
154
157
  const isOpenRef = useRef(false);
155
158
  const navigationRef = useRef<((screen: any, props?: Record<string, unknown>) => void) | null>(null);
159
+
156
160
  // Remove contentHeight, containerWidth, and snap point state/logic
157
161
  // Animation values - keep for content fade/slide
158
162
  const fadeAnim = useRef(new Animated.Value(Platform.OS === 'android' ? 1 : 0)).current;
@@ -200,6 +204,13 @@ const OxyBottomSheet = forwardRef<BottomSheetController, OxyBottomSheetProps>(({
200
204
  const [keyboardVisible, setKeyboardVisible] = useState(false);
201
205
  const [keyboardHeight, setKeyboardHeight] = useState(0);
202
206
  const insets = useSafeAreaInsets();
207
+
208
+ // Calculate max height for dynamic sizing (screen height minus insets and margin)
209
+ const maxHeight = useMemo(() => {
210
+ const topInset = (insets?.top ?? 0) + (appInsets?.top ?? 0);
211
+ const bottomInset = (insets?.bottom ?? 0) + (appInsets?.bottom ?? 0);
212
+ return windowHeight - topInset - bottomInset - 20; // 20px margin
213
+ }, [windowHeight, insets?.top, insets?.bottom, appInsets?.top, appInsets?.bottom]);
203
214
  useEffect(() => {
204
215
  // Use 'did' events on iOS to avoid multiple intermediate willShow updates
205
216
  const showEvent = Platform.OS === 'ios' ? 'keyboardDidShow' : 'keyboardDidShow';
@@ -293,12 +304,14 @@ const OxyBottomSheet = forwardRef<BottomSheetController, OxyBottomSheetProps>(({
293
304
  ),
294
305
  []
295
306
  );
307
+
296
308
  // Modernized BottomSheetModal usage
297
309
  return (
298
310
  <BottomSheetModal
299
311
  ref={modalRef}
300
312
  index={0}
301
313
  enableDynamicSizing={true}
314
+ maxDynamicContentSize={maxHeight}
302
315
  enablePanDownToClose
303
316
  backdropComponent={renderBackdrop}
304
317
  backgroundStyle={[
@@ -335,12 +348,12 @@ const OxyBottomSheet = forwardRef<BottomSheetController, OxyBottomSheetProps>(({
335
348
  onChange={(index) => { isOpenRef.current = index !== -1; }}
336
349
  onDismiss={() => { isOpenRef.current = false; }}
337
350
  >
338
- <BottomSheetView style={[styles.contentContainer]}>
339
- <View
340
- style={[
341
- styles.centeredContentWrapper,
342
- { paddingBottom: (insets?.bottom ?? 0) + (appInsets?.bottom ?? 0) }
343
- ]}
351
+ <BottomSheetScrollView
352
+ style={[styles.contentContainer]}
353
+ contentContainerStyle={styles.scrollContentContainer}
354
+ showsVerticalScrollIndicator={true}
355
+ bounces={false}
356
+ nestedScrollEnabled={true}
344
357
  >
345
358
  <Animated.View
346
359
  style={[
@@ -348,6 +361,12 @@ const OxyBottomSheet = forwardRef<BottomSheetController, OxyBottomSheetProps>(({
348
361
  Platform.OS === 'android'
349
362
  ? { opacity: 1 }
350
363
  : { opacity: fadeAnim, transform: [{ translateY: slideAnim }] }
364
+ ]}
365
+ >
366
+ <View
367
+ style={[
368
+ styles.centeredContentWrapper,
369
+ { paddingBottom: (insets?.bottom ?? 0) + (appInsets?.bottom ?? 0) }
351
370
  ]}
352
371
  >
353
372
  {oxyServices ? (
@@ -365,12 +384,12 @@ const OxyBottomSheet = forwardRef<BottomSheetController, OxyBottomSheetProps>(({
365
384
  <Text>OxyServices not available</Text>
366
385
  </View>
367
386
  )}
387
+ </View>
368
388
  </Animated.View>
369
- </View>
370
- </BottomSheetView>
389
+ </BottomSheetScrollView>
371
390
  {showInternalToaster && (
372
391
  <View style={styles.toasterContainer}>
373
- <Toaster position="top-center" swipeToDismissDirection="left" />
392
+ <Toaster position="bottom-center" swipeToDismissDirection="left" />
374
393
  </View>
375
394
  )}
376
395
  </BottomSheetModal>
@@ -389,6 +408,9 @@ const styles = StyleSheet.create({
389
408
  borderTopLeftRadius: 35,
390
409
  borderTopRightRadius: 35,
391
410
  },
411
+ scrollContentContainer: {
412
+ // Content will size naturally, ScrollView handles overflow
413
+ },
392
414
  centeredContentWrapper: {
393
415
  width: '100%',
394
416
  alignSelf: 'center',
@@ -22,6 +22,13 @@ import RecoverAccountScreen from '../screens/RecoverAccountScreen';
22
22
  import PaymentGatewayScreen from '../screens/PaymentGatewayScreen';
23
23
  import WelcomeNewUserScreen from '../screens/WelcomeNewUserScreen';
24
24
  import LanguageSelectorScreen from '../screens/LanguageSelectorScreen';
25
+ import HistoryViewScreen from '../screens/HistoryViewScreen';
26
+ import SavesCollectionsScreen from '../screens/SavesCollectionsScreen';
27
+ import SearchSettingsScreen from '../screens/SearchSettingsScreen';
28
+ import HelpSupportScreen from '../screens/HelpSupportScreen';
29
+ import LegalDocumentsScreen from '../screens/LegalDocumentsScreen';
30
+ import PrivacySettingsScreen from '../screens/PrivacySettingsScreen';
31
+ import AccountVerificationScreen from '../screens/AccountVerificationScreen';
25
32
 
26
33
  export interface RouteConfig {
27
34
  component: ComponentType<any>;
@@ -53,6 +60,13 @@ export const routeNames = [
53
60
  'PaymentGateway',
54
61
  'WelcomeNewUser',
55
62
  'LanguageSelector',
63
+ 'HistoryView',
64
+ 'SavesCollections',
65
+ 'SearchSettings',
66
+ 'HelpSupport',
67
+ 'LegalDocuments',
68
+ 'PrivacySettings',
69
+ 'AccountVerification',
56
70
  ] as const;
57
71
 
58
72
  export type RouteName = typeof routeNames[number];
@@ -150,4 +164,32 @@ export const routes: Record<RouteName, RouteConfig> = {
150
164
  component: LanguageSelectorScreen as unknown as ComponentType<any>,
151
165
  snapPoints: ['70%', '100%'],
152
166
  },
167
+ HistoryView: {
168
+ component: HistoryViewScreen as unknown as ComponentType<any>,
169
+ snapPoints: ['70%', '100%'],
170
+ },
171
+ SavesCollections: {
172
+ component: SavesCollectionsScreen as unknown as ComponentType<any>,
173
+ snapPoints: ['70%', '100%'],
174
+ },
175
+ SearchSettings: {
176
+ component: SearchSettingsScreen as unknown as ComponentType<any>,
177
+ snapPoints: ['70%', '100%'],
178
+ },
179
+ HelpSupport: {
180
+ component: HelpSupportScreen as unknown as ComponentType<any>,
181
+ snapPoints: ['70%', '100%'],
182
+ },
183
+ LegalDocuments: {
184
+ component: LegalDocumentsScreen as unknown as ComponentType<any>,
185
+ snapPoints: ['70%', '100%'],
186
+ },
187
+ PrivacySettings: {
188
+ component: PrivacySettingsScreen as unknown as ComponentType<any>,
189
+ snapPoints: ['60%', '100%'],
190
+ },
191
+ AccountVerification: {
192
+ component: AccountVerificationScreen as unknown as ComponentType<any>,
193
+ snapPoints: ['70%', '100%'],
194
+ },
153
195
  };
@@ -145,6 +145,130 @@ const AccountOverviewScreen: React.FC<BaseScreenProps> = ({
145
145
  confirmAction(t('common.confirms.signOutAll'), handleLogout);
146
146
  }, [handleLogout]);
147
147
 
148
+ const handleDownloadData = useCallback(async () => {
149
+ if (!oxyServices || !user) {
150
+ toast.error(t('accountOverview.items.downloadData.error') || 'Service not available');
151
+ return;
152
+ }
153
+
154
+ try {
155
+ Alert.alert(
156
+ t('accountOverview.items.downloadData.confirmTitle') || 'Download Account Data',
157
+ t('accountOverview.items.downloadData.confirmMessage') || 'Choose the format for your account data export:',
158
+ [
159
+ {
160
+ text: t('common.cancel') || 'Cancel',
161
+ style: 'cancel',
162
+ },
163
+ {
164
+ text: 'JSON',
165
+ onPress: async () => {
166
+ try {
167
+ toast.loading(t('accountOverview.items.downloadData.downloading') || 'Preparing download...');
168
+ const blob = await oxyServices.downloadAccountData('json');
169
+
170
+ // Create download link for web
171
+ if (Platform.OS === 'web') {
172
+ const url = URL.createObjectURL(blob);
173
+ const link = document.createElement('a');
174
+ link.href = url;
175
+ link.download = `account-data-${Date.now()}.json`;
176
+ document.body.appendChild(link);
177
+ link.click();
178
+ document.body.removeChild(link);
179
+ URL.revokeObjectURL(url);
180
+ toast.success(t('accountOverview.items.downloadData.success') || 'Data downloaded successfully');
181
+ } else {
182
+ // For React Native, you'd need to use a library like expo-file-system
183
+ toast.success(t('accountOverview.items.downloadData.success') || 'Data downloaded successfully');
184
+ }
185
+ } catch (error: any) {
186
+ console.error('Failed to download data:', error);
187
+ toast.error(error?.message || t('accountOverview.items.downloadData.error') || 'Failed to download data');
188
+ }
189
+ },
190
+ },
191
+ {
192
+ text: 'CSV',
193
+ onPress: async () => {
194
+ try {
195
+ toast.loading(t('accountOverview.items.downloadData.downloading') || 'Preparing download...');
196
+ const blob = await oxyServices.downloadAccountData('csv');
197
+
198
+ // Create download link for web
199
+ if (Platform.OS === 'web') {
200
+ const url = URL.createObjectURL(blob);
201
+ const link = document.createElement('a');
202
+ link.href = url;
203
+ link.download = `account-data-${Date.now()}.csv`;
204
+ document.body.appendChild(link);
205
+ link.click();
206
+ document.body.removeChild(link);
207
+ URL.revokeObjectURL(url);
208
+ toast.success(t('accountOverview.items.downloadData.success') || 'Data downloaded successfully');
209
+ } else {
210
+ // For React Native, you'd need to use a library like expo-file-system
211
+ toast.success(t('accountOverview.items.downloadData.success') || 'Data downloaded successfully');
212
+ }
213
+ } catch (error: any) {
214
+ console.error('Failed to download data:', error);
215
+ toast.error(error?.message || t('accountOverview.items.downloadData.error') || 'Failed to download data');
216
+ }
217
+ },
218
+ },
219
+ ]
220
+ );
221
+ } catch (error: any) {
222
+ console.error('Failed to initiate download:', error);
223
+ toast.error(error?.message || t('accountOverview.items.downloadData.error') || 'Failed to download data');
224
+ }
225
+ }, [oxyServices, user, t]);
226
+
227
+ const handleDeleteAccount = useCallback(() => {
228
+ if (!user) {
229
+ toast.error(t('accountOverview.items.deleteAccount.error') || 'User not available');
230
+ return;
231
+ }
232
+
233
+ confirmAction(
234
+ t('accountOverview.items.deleteAccount.confirmMessage') || `This action cannot be undone. This will permanently delete your account and all associated data.\n\nAre you sure you want to delete your account?`,
235
+ async () => {
236
+ // For React Native, we'd need a separate modal for password/confirmation input
237
+ // For now, we'll use a simplified confirmation
238
+ // In production, you'd want to create a modal with password and username confirmation fields
239
+ if (!oxyServices) {
240
+ toast.error(t('accountOverview.items.deleteAccount.error') || 'Service not available');
241
+ return;
242
+ }
243
+
244
+ Alert.alert(
245
+ t('accountOverview.items.deleteAccount.confirmTitle') || 'Delete Account',
246
+ t('accountOverview.items.deleteAccount.finalConfirm') || `This is your final warning. Your account will be permanently deleted and cannot be recovered. Type "${user.username}" to confirm.`,
247
+ [
248
+ {
249
+ text: t('common.cancel') || 'Cancel',
250
+ style: 'cancel',
251
+ },
252
+ {
253
+ text: t('accountOverview.items.deleteAccount.confirm') || 'Delete Forever',
254
+ style: 'destructive',
255
+ onPress: async () => {
256
+ try {
257
+ // Note: In a production app, you'd want to show a modal with password and username confirmation fields
258
+ // For now, we'll require the user to enter these via a custom modal or prompt
259
+ toast.error(t('accountOverview.items.deleteAccount.passwordRequired') || 'Password confirmation required. This feature needs a modal with password input.');
260
+ } catch (error: any) {
261
+ console.error('Failed to delete account:', error);
262
+ toast.error(error?.message || t('accountOverview.items.deleteAccount.error') || 'Failed to delete account');
263
+ }
264
+ },
265
+ },
266
+ ]
267
+ );
268
+ }
269
+ );
270
+ }, [user, oxyServices, logout, onClose, t]);
271
+
148
272
  if (!isAuthenticated) {
149
273
  return (
150
274
  <View style={[styles.container, { backgroundColor: themeStyles.backgroundColor }]}>
@@ -291,8 +415,6 @@ const AccountOverviewScreen: React.FC<BaseScreenProps> = ({
291
415
  subtitle: account.email || account.username,
292
416
  onPress: () => {
293
417
  toast.info(t('accountOverview.items.accountSwitcher.switchPrompt', { username: account.username }) || `Switch to ${account.username}?`);
294
- // TODO: Implement account switching logic
295
- // switchSession(account.sessionId);
296
418
  },
297
419
  customContent: (
298
420
  <>
@@ -377,13 +499,29 @@ const AccountOverviewScreen: React.FC<BaseScreenProps> = ({
377
499
  : t('accountOverview.items.accountSwitcher.subtitleManageMultiple'),
378
500
  onPress: () => setShowMoreAccounts(!showMoreAccounts),
379
501
  },
502
+ {
503
+ id: 'history-view',
504
+ icon: 'time',
505
+ iconColor: '#007AFF',
506
+ title: t('accountOverview.items.history.title') || 'History',
507
+ subtitle: t('accountOverview.items.history.subtitle') || 'View and manage your search history',
508
+ onPress: () => navigate?.('HistoryView'),
509
+ },
510
+ {
511
+ id: 'saves-collections',
512
+ icon: 'bookmark',
513
+ iconColor: '#FF9500',
514
+ title: t('accountOverview.items.saves.title') || 'Saves & Collections',
515
+ subtitle: t('accountOverview.items.saves.subtitle') || 'View your saved items and collections',
516
+ onPress: () => navigate?.('SavesCollections'),
517
+ },
380
518
  {
381
519
  id: 'download-data',
382
520
  icon: 'download',
383
521
  iconColor: '#34C759',
384
522
  title: t('accountOverview.items.downloadData.title'),
385
523
  subtitle: t('accountOverview.items.downloadData.subtitle'),
386
- onPress: () => toast.info(t('accountOverview.items.downloadData.coming')),
524
+ onPress: handleDownloadData,
387
525
  },
388
526
  {
389
527
  id: 'delete-account',
@@ -391,7 +529,7 @@ const AccountOverviewScreen: React.FC<BaseScreenProps> = ({
391
529
  iconColor: '#FF3B30',
392
530
  title: t('accountOverview.items.deleteAccount.title'),
393
531
  subtitle: t('accountOverview.items.deleteAccount.subtitle'),
394
- onPress: () => toast.info(t('accountOverview.items.deleteAccount.coming')),
532
+ onPress: handleDeleteAccount,
395
533
  },
396
534
  ]}
397
535
  theme={theme}
@@ -402,6 +540,22 @@ const AccountOverviewScreen: React.FC<BaseScreenProps> = ({
402
540
  <Section title={t('accountOverview.sections.support')} theme={theme}>
403
541
  <GroupedSection
404
542
  items={[
543
+ {
544
+ id: 'search-settings',
545
+ icon: 'search',
546
+ iconColor: '#007AFF',
547
+ title: t('accountOverview.items.searchSettings.title') || 'Search Settings',
548
+ subtitle: t('accountOverview.items.searchSettings.subtitle') || 'SafeSearch and personalization',
549
+ onPress: () => navigate?.('SearchSettings'),
550
+ },
551
+ {
552
+ id: 'language-settings',
553
+ icon: 'language',
554
+ iconColor: '#32D74B',
555
+ title: t('accountOverview.items.language.title') || 'Language',
556
+ subtitle: t('accountOverview.items.language.subtitle') || 'Choose your preferred language',
557
+ onPress: () => navigate?.('LanguageSelector'),
558
+ },
405
559
  {
406
560
  id: 'account-preferences',
407
561
  icon: 'settings',
@@ -416,7 +570,23 @@ const AccountOverviewScreen: React.FC<BaseScreenProps> = ({
416
570
  iconColor: '#007AFF',
417
571
  title: t('accountOverview.items.help.title'),
418
572
  subtitle: t('accountOverview.items.help.subtitle'),
419
- onPress: () => toast.info(t('accountOverview.items.help.coming')),
573
+ onPress: () => navigate?.('HelpSupport'),
574
+ },
575
+ {
576
+ id: 'privacy-policy',
577
+ icon: 'shield-checkmark',
578
+ iconColor: '#30D158',
579
+ title: t('accountOverview.items.privacyPolicy.title') || 'Privacy Policy',
580
+ subtitle: t('accountOverview.items.privacyPolicy.subtitle') || 'How we handle your data',
581
+ onPress: () => navigate?.('LegalDocuments', { initialStep: 1 }),
582
+ },
583
+ {
584
+ id: 'terms-of-service',
585
+ icon: 'document-text',
586
+ iconColor: '#007AFF',
587
+ title: t('accountOverview.items.termsOfService.title') || 'Terms of Service',
588
+ subtitle: t('accountOverview.items.termsOfService.subtitle') || 'Terms and conditions of use',
589
+ onPress: () => navigate?.('LegalDocuments', { initialStep: 2 }),
420
590
  },
421
591
  {
422
592
  id: 'connected-apps',