@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
@@ -1,15 +1,14 @@
1
1
  "use strict";
2
2
 
3
3
  import React, { useState, useEffect, useRef, useMemo, useCallback } from 'react';
4
- import { View, Text, TouchableOpacity, StyleSheet, ActivityIndicator, ScrollView, TextInput, Animated } from 'react-native';
4
+ import { View, Text, TouchableOpacity, StyleSheet, ActivityIndicator, ScrollView, TextInput, Animated, Platform, Image } from 'react-native';
5
5
  import { useOxy } from '../context/OxyContext';
6
- import Avatar from '../components/Avatar';
7
6
  import OxyIcon from '../components/icon/OxyIcon';
8
- import { Ionicons } from '@expo/vector-icons';
9
7
  import { toast } from '../../lib/sonner';
10
8
  import { fontFamilies } from '../styles/fonts';
11
9
  import { confirmAction } from '../utils/confirmAction';
12
10
  import { useAuthStore } from '../stores/authStore';
11
+ import { Header, GroupedSection } from '../components';
13
12
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
14
13
  const AccountSettingsScreen = ({
15
14
  onClose,
@@ -51,6 +50,17 @@ const AccountSettingsScreen = ({
51
50
  const [tempBio, setTempBio] = useState('');
52
51
  const [tempLocation, setTempLocation] = useState('');
53
52
  const [tempLinks, setTempLinks] = useState([]);
53
+ const [tempLinksWithMetadata, setTempLinksWithMetadata] = useState([]);
54
+ const [isAddingLink, setIsAddingLink] = useState(false);
55
+ const [newLinkUrl, setNewLinkUrl] = useState('');
56
+ const [isFetchingMetadata, setIsFetchingMetadata] = useState(false);
57
+
58
+ // Location management state
59
+ const [tempLocations, setTempLocations] = useState([]);
60
+ const [isAddingLocation, setIsAddingLocation] = useState(false);
61
+ const [newLocationQuery, setNewLocationQuery] = useState('');
62
+ const [locationSearchResults, setLocationSearchResults] = useState([]);
63
+ const [isSearchingLocations, setIsSearchingLocations] = useState(false);
54
64
 
55
65
  // Memoize theme-related calculations to prevent unnecessary recalculations
56
66
  const themeStyles = useMemo(() => {
@@ -66,7 +76,7 @@ const AccountSettingsScreen = ({
66
76
  const animateSaveButton = useCallback(toValue => {
67
77
  Animated.spring(saveButtonScale, {
68
78
  toValue,
69
- useNativeDriver: true,
79
+ useNativeDriver: Platform.OS !== 'web',
70
80
  tension: 150,
71
81
  friction: 8
72
82
  }).start();
@@ -83,7 +93,59 @@ const AccountSettingsScreen = ({
83
93
  setEmail(user.email || '');
84
94
  setBio(user.bio || '');
85
95
  setLocation(user.location || '');
86
- setLinks(Array.isArray(user.links) ? user.links.map(l => typeof l === 'string' ? l : l.link).filter(Boolean) : user.website ? [user.website] : []);
96
+
97
+ // Handle locations - convert single location to array format
98
+ if (user.locations && Array.isArray(user.locations)) {
99
+ setTempLocations(user.locations.map((loc, index) => ({
100
+ id: loc.id || `existing-${index}`,
101
+ name: loc.name,
102
+ label: loc.label,
103
+ coordinates: loc.coordinates
104
+ })));
105
+ } else if (user.location) {
106
+ // Convert single location string to array format
107
+ setTempLocations([{
108
+ id: 'existing-0',
109
+ name: user.location,
110
+ label: 'Location'
111
+ }]);
112
+ } else {
113
+ setTempLocations([]);
114
+ }
115
+
116
+ // Handle links - simple and direct like other fields
117
+ if (user.linksMetadata && Array.isArray(user.linksMetadata)) {
118
+ const urls = user.linksMetadata.map(l => l.url);
119
+ setLinks(urls);
120
+ const metadataWithIds = user.linksMetadata.map((link, index) => ({
121
+ ...link,
122
+ id: link.id || `existing-${index}`
123
+ }));
124
+ setTempLinksWithMetadata(metadataWithIds);
125
+ } else if (Array.isArray(user.links)) {
126
+ const simpleLinks = user.links.map(l => typeof l === 'string' ? l : l.link).filter(Boolean);
127
+ setLinks(simpleLinks);
128
+ const linksWithMetadata = simpleLinks.map((url, index) => ({
129
+ url,
130
+ title: url.replace(/^https?:\/\//, '').replace(/\/$/, ''),
131
+ description: `Link to ${url}`,
132
+ image: undefined,
133
+ id: `existing-${index}`
134
+ }));
135
+ setTempLinksWithMetadata(linksWithMetadata);
136
+ } else if (user.website) {
137
+ setLinks([user.website]);
138
+ setTempLinksWithMetadata([{
139
+ url: user.website,
140
+ title: user.website.replace(/^https?:\/\//, '').replace(/\/$/, ''),
141
+ description: `Link to ${user.website}`,
142
+ image: undefined,
143
+ id: 'existing-0'
144
+ }]);
145
+ } else {
146
+ setLinks([]);
147
+ setTempLinksWithMetadata([]);
148
+ }
87
149
  setAvatarUrl(user.avatar?.url || '');
88
150
  }
89
151
  }, [user]);
@@ -97,9 +159,14 @@ const AccountSettingsScreen = ({
97
159
  username,
98
160
  email,
99
161
  bio,
100
- location,
101
- links
162
+ location: tempLocations.length > 0 ? tempLocations[0].name : '',
163
+ // Keep backward compatibility
164
+ locations: tempLocations.length > 0 ? tempLocations : undefined,
165
+ links,
166
+ linksMetadata: tempLinksWithMetadata.length > 0 ? tempLinksWithMetadata : undefined
102
167
  };
168
+ console.log('Saving updates:', updates);
169
+ console.log('Links metadata being saved:', tempLinksWithMetadata);
103
170
 
104
171
  // Handle name field
105
172
  if (displayName || lastName) {
@@ -154,10 +221,11 @@ const AccountSettingsScreen = ({
154
221
  setTempBio(currentValue);
155
222
  break;
156
223
  case 'location':
157
- setTempLocation(currentValue);
224
+ // Don't reset the locations - keep the existing data
158
225
  break;
159
226
  case 'links':
160
- setTempLinks([...links]);
227
+ // Don't reset the metadata - keep the existing rich metadata
228
+ // The tempLinksWithMetadata should already contain the rich data from the database
161
229
  break;
162
230
  }
163
231
  setEditingField(type);
@@ -180,10 +248,13 @@ const AccountSettingsScreen = ({
180
248
  setBio(tempBio);
181
249
  break;
182
250
  case 'location':
183
- setLocation(tempLocation);
251
+ // Locations are handled in the main save function
184
252
  break;
185
253
  case 'links':
186
- setLinks(tempLinks);
254
+ // Save both URLs and metadata
255
+ setLinks(tempLinksWithMetadata.map(link => link.url));
256
+ // Store full metadata for database
257
+ setTempLinksWithMetadata(tempLinksWithMetadata);
187
258
  break;
188
259
  }
189
260
 
@@ -196,96 +267,444 @@ const AccountSettingsScreen = ({
196
267
  const cancelEditing = () => {
197
268
  setEditingField(null);
198
269
  };
199
- const getFieldLabel = type => {
200
- const labels = {
201
- displayName: 'Display Name',
202
- username: 'Username',
203
- email: 'Email',
204
- bio: 'Bio',
205
- location: 'Location',
206
- links: 'Links'
207
- };
208
- return labels[type] || 'Field';
270
+ const fetchLinkMetadata = async url => {
271
+ try {
272
+ setIsFetchingMetadata(true);
273
+ console.log('Fetching metadata for URL:', url);
274
+
275
+ // Use the backend API to fetch metadata
276
+ const metadata = await oxyServices.fetchLinkMetadata(url);
277
+ console.log('Received metadata:', metadata);
278
+ return {
279
+ ...metadata,
280
+ id: Date.now().toString()
281
+ };
282
+ } catch (error) {
283
+ console.error('Error fetching metadata:', error);
284
+ // Fallback to basic metadata
285
+ return {
286
+ url: url.startsWith('http') ? url : 'https://' + url,
287
+ title: url.replace(/^https?:\/\//, '').replace(/\/$/, ''),
288
+ description: 'Link',
289
+ image: undefined,
290
+ id: Date.now().toString()
291
+ };
292
+ } finally {
293
+ setIsFetchingMetadata(false);
294
+ }
209
295
  };
210
- const getFieldIcon = type => {
211
- const icons = {
212
- displayName: {
213
- name: 'person',
214
- color: '#007AFF'
215
- },
216
- username: {
217
- name: 'at',
218
- color: '#5856D6'
219
- },
220
- email: {
221
- name: 'mail',
222
- color: '#FF9500'
223
- },
224
- bio: {
225
- name: 'document-text',
226
- color: '#34C759'
227
- },
228
- location: {
229
- name: 'location',
230
- color: '#FF3B30'
231
- },
232
- links: {
233
- name: 'link',
234
- color: '#32D74B'
296
+ const searchLocations = async query => {
297
+ if (!query.trim() || query.length < 3) {
298
+ setLocationSearchResults([]);
299
+ return;
300
+ }
301
+ try {
302
+ setIsSearchingLocations(true);
303
+ const response = await fetch(`https://nominatim.openstreetmap.org/search?format=json&q=${encodeURIComponent(query)}&limit=5&addressdetails=1`);
304
+ const data = await response.json();
305
+ setLocationSearchResults(data);
306
+ } catch (error) {
307
+ console.error('Error searching locations:', error);
308
+ setLocationSearchResults([]);
309
+ } finally {
310
+ setIsSearchingLocations(false);
311
+ }
312
+ };
313
+ const addLocation = locationData => {
314
+ const newLocation = {
315
+ id: Date.now().toString(),
316
+ name: locationData.display_name,
317
+ label: locationData.type === 'city' ? 'City' : locationData.type === 'country' ? 'Country' : locationData.type === 'state' ? 'State' : 'Location',
318
+ coordinates: {
319
+ lat: parseFloat(locationData.lat),
320
+ lon: parseFloat(locationData.lon)
235
321
  }
236
322
  };
237
- return icons[type] || {
238
- name: 'person',
239
- color: '#007AFF'
240
- };
323
+ setTempLocations(prev => [...prev, newLocation]);
324
+ setNewLocationQuery('');
325
+ setLocationSearchResults([]);
326
+ setIsAddingLocation(false);
327
+ };
328
+ const removeLocation = id => {
329
+ setTempLocations(prev => prev.filter(loc => loc.id !== id));
330
+ };
331
+ const moveLocation = (fromIndex, toIndex) => {
332
+ setTempLocations(prev => {
333
+ const newLocations = [...prev];
334
+ const [movedLocation] = newLocations.splice(fromIndex, 1);
335
+ newLocations.splice(toIndex, 0, movedLocation);
336
+ return newLocations;
337
+ });
338
+ };
339
+ const addLink = async () => {
340
+ if (!newLinkUrl.trim()) return;
341
+ const url = newLinkUrl.trim();
342
+ console.log('Adding link:', url);
343
+ const metadata = await fetchLinkMetadata(url);
344
+ console.log('Final metadata for adding:', metadata);
345
+ setTempLinksWithMetadata(prev => [...prev, metadata]);
346
+ setNewLinkUrl('');
347
+ setIsAddingLink(false);
348
+ };
349
+ const removeLink = id => {
350
+ setTempLinksWithMetadata(prev => prev.filter(link => link.id !== id));
351
+ };
352
+ const moveLink = (fromIndex, toIndex) => {
353
+ setTempLinksWithMetadata(prev => {
354
+ const newLinks = [...prev];
355
+ const [movedLink] = newLinks.splice(fromIndex, 1);
356
+ newLinks.splice(toIndex, 0, movedLink);
357
+ return newLinks;
358
+ });
241
359
  };
242
360
  const renderEditingField = type => {
243
361
  if (type === 'displayName') {
244
362
  return /*#__PURE__*/_jsx(View, {
245
- style: styles.editingFieldContainer,
363
+ style: [styles.editingFieldContainer, {
364
+ backgroundColor: themeStyles.backgroundColor
365
+ }],
246
366
  children: /*#__PURE__*/_jsx(View, {
247
367
  style: styles.editingFieldContent,
248
368
  children: /*#__PURE__*/_jsxs(View, {
249
- style: [styles.newValueSection, {
250
- flexDirection: 'row',
251
- gap: 12
252
- }],
253
- children: [/*#__PURE__*/_jsxs(View, {
254
- style: {
255
- flex: 1
256
- },
257
- children: [/*#__PURE__*/_jsx(Text, {
258
- style: styles.editingFieldLabel,
259
- children: "First Name"
260
- }), /*#__PURE__*/_jsx(TextInput, {
261
- style: styles.editingFieldInput,
262
- value: tempDisplayName,
263
- onChangeText: setTempDisplayName,
264
- placeholder: "Enter your first name",
265
- placeholderTextColor: themeStyles.isDarkTheme ? '#aaa' : '#999',
266
- autoFocus: true,
267
- selectionColor: themeStyles.primaryColor
268
- })]
369
+ style: styles.newValueSection,
370
+ children: [/*#__PURE__*/_jsx(View, {
371
+ style: styles.editingFieldHeader,
372
+ children: /*#__PURE__*/_jsx(Text, {
373
+ style: [styles.editingFieldLabel, {
374
+ color: themeStyles.isDarkTheme ? '#FFFFFF' : '#1A1A1A'
375
+ }],
376
+ children: "Edit Display Name"
377
+ })
269
378
  }), /*#__PURE__*/_jsxs(View, {
270
379
  style: {
271
- flex: 1
380
+ flexDirection: 'row',
381
+ gap: 12
272
382
  },
273
- children: [/*#__PURE__*/_jsx(Text, {
274
- style: styles.editingFieldLabel,
275
- children: "Last Name"
276
- }), /*#__PURE__*/_jsx(TextInput, {
277
- style: styles.editingFieldInput,
278
- value: tempLastName,
279
- onChangeText: setTempLastName,
280
- placeholder: "Enter your last name",
281
- placeholderTextColor: themeStyles.isDarkTheme ? '#aaa' : '#999',
282
- selectionColor: themeStyles.primaryColor
383
+ children: [/*#__PURE__*/_jsxs(View, {
384
+ style: {
385
+ flex: 1
386
+ },
387
+ children: [/*#__PURE__*/_jsx(Text, {
388
+ style: styles.editingFieldLabel,
389
+ children: "First Name"
390
+ }), /*#__PURE__*/_jsx(TextInput, {
391
+ style: styles.editingFieldInput,
392
+ value: tempDisplayName,
393
+ onChangeText: setTempDisplayName,
394
+ placeholder: "Enter your first name",
395
+ placeholderTextColor: themeStyles.isDarkTheme ? '#aaa' : '#999',
396
+ autoFocus: true,
397
+ selectionColor: themeStyles.primaryColor
398
+ })]
399
+ }), /*#__PURE__*/_jsxs(View, {
400
+ style: {
401
+ flex: 1
402
+ },
403
+ children: [/*#__PURE__*/_jsx(Text, {
404
+ style: styles.editingFieldLabel,
405
+ children: "Last Name"
406
+ }), /*#__PURE__*/_jsx(TextInput, {
407
+ style: styles.editingFieldInput,
408
+ value: tempLastName,
409
+ onChangeText: setTempLastName,
410
+ placeholder: "Enter your last name",
411
+ placeholderTextColor: themeStyles.isDarkTheme ? '#aaa' : '#999',
412
+ selectionColor: themeStyles.primaryColor
413
+ })]
283
414
  })]
284
415
  })]
285
416
  })
286
417
  })
287
418
  });
288
419
  }
420
+ if (type === 'location') {
421
+ return /*#__PURE__*/_jsx(View, {
422
+ style: [styles.editingFieldContainer, {
423
+ backgroundColor: themeStyles.backgroundColor
424
+ }],
425
+ children: /*#__PURE__*/_jsx(View, {
426
+ style: styles.editingFieldContent,
427
+ children: /*#__PURE__*/_jsxs(View, {
428
+ style: styles.newValueSection,
429
+ children: [/*#__PURE__*/_jsx(View, {
430
+ style: styles.editingFieldHeader,
431
+ children: /*#__PURE__*/_jsx(Text, {
432
+ style: [styles.editingFieldLabel, {
433
+ color: themeStyles.isDarkTheme ? '#FFFFFF' : '#1A1A1A'
434
+ }],
435
+ children: "Manage Your Locations"
436
+ })
437
+ }), isAddingLocation ? /*#__PURE__*/_jsxs(View, {
438
+ style: styles.addLocationSection,
439
+ children: [/*#__PURE__*/_jsxs(Text, {
440
+ style: styles.addLocationLabel,
441
+ children: ["Add New Location", isSearchingLocations && /*#__PURE__*/_jsx(Text, {
442
+ style: styles.searchingText,
443
+ children: " \u2022 Searching..."
444
+ })]
445
+ }), /*#__PURE__*/_jsxs(View, {
446
+ style: styles.addLocationInputContainer,
447
+ children: [/*#__PURE__*/_jsx(TextInput, {
448
+ style: styles.addLocationInput,
449
+ value: newLocationQuery,
450
+ onChangeText: text => {
451
+ setNewLocationQuery(text);
452
+ searchLocations(text);
453
+ },
454
+ placeholder: "Search for a location...",
455
+ placeholderTextColor: themeStyles.isDarkTheme ? '#aaa' : '#999',
456
+ autoFocus: true,
457
+ selectionColor: themeStyles.primaryColor
458
+ }), /*#__PURE__*/_jsx(View, {
459
+ style: styles.addLocationButtons,
460
+ children: /*#__PURE__*/_jsx(TouchableOpacity, {
461
+ style: [styles.addLocationButton, styles.cancelButton],
462
+ onPress: () => {
463
+ setIsAddingLocation(false);
464
+ setNewLocationQuery('');
465
+ setLocationSearchResults([]);
466
+ },
467
+ children: /*#__PURE__*/_jsx(Text, {
468
+ style: styles.cancelButtonText,
469
+ children: "Cancel"
470
+ })
471
+ })
472
+ })]
473
+ }), locationSearchResults.length > 0 && /*#__PURE__*/_jsx(View, {
474
+ style: styles.searchResults,
475
+ children: locationSearchResults.map(result => /*#__PURE__*/_jsxs(TouchableOpacity, {
476
+ style: styles.searchResultItem,
477
+ onPress: () => addLocation(result),
478
+ children: [/*#__PURE__*/_jsx(Text, {
479
+ style: styles.searchResultName,
480
+ numberOfLines: 2,
481
+ children: result.display_name
482
+ }), /*#__PURE__*/_jsx(Text, {
483
+ style: styles.searchResultType,
484
+ children: result.type
485
+ })]
486
+ }, result.place_id))
487
+ })]
488
+ }) : /*#__PURE__*/_jsxs(TouchableOpacity, {
489
+ style: styles.addLocationTrigger,
490
+ onPress: () => setIsAddingLocation(true),
491
+ children: [/*#__PURE__*/_jsx(OxyIcon, {
492
+ name: "add",
493
+ size: 20,
494
+ color: themeStyles.primaryColor
495
+ }), /*#__PURE__*/_jsx(Text, {
496
+ style: styles.addLocationTriggerText,
497
+ children: "Add a new location"
498
+ })]
499
+ }), tempLocations.length > 0 && /*#__PURE__*/_jsxs(View, {
500
+ style: styles.locationsList,
501
+ children: [/*#__PURE__*/_jsxs(Text, {
502
+ style: styles.locationsListTitle,
503
+ children: ["Your Locations (", tempLocations.length, ")"]
504
+ }), tempLocations.map((location, index) => /*#__PURE__*/_jsxs(View, {
505
+ style: styles.locationItem,
506
+ children: [/*#__PURE__*/_jsxs(View, {
507
+ style: styles.locationItemContent,
508
+ children: [/*#__PURE__*/_jsx(View, {
509
+ style: styles.locationItemDragHandle,
510
+ children: /*#__PURE__*/_jsxs(View, {
511
+ style: styles.reorderButtons,
512
+ children: [/*#__PURE__*/_jsx(TouchableOpacity, {
513
+ style: [styles.reorderButton, index === 0 && styles.reorderButtonDisabled],
514
+ onPress: () => index > 0 && moveLocation(index, index - 1),
515
+ disabled: index === 0,
516
+ children: /*#__PURE__*/_jsx(OxyIcon, {
517
+ name: "chevron-up",
518
+ size: 12,
519
+ color: index === 0 ? "#ccc" : "#666"
520
+ })
521
+ }), /*#__PURE__*/_jsx(TouchableOpacity, {
522
+ style: [styles.reorderButton, index === tempLocations.length - 1 && styles.reorderButtonDisabled],
523
+ onPress: () => index < tempLocations.length - 1 && moveLocation(index, index + 1),
524
+ disabled: index === tempLocations.length - 1,
525
+ children: /*#__PURE__*/_jsx(OxyIcon, {
526
+ name: "chevron-down",
527
+ size: 12,
528
+ color: index === tempLocations.length - 1 ? "#ccc" : "#666"
529
+ })
530
+ })]
531
+ })
532
+ }), /*#__PURE__*/_jsxs(View, {
533
+ style: styles.locationItemInfo,
534
+ children: [/*#__PURE__*/_jsxs(View, {
535
+ style: styles.locationItemHeader,
536
+ children: [/*#__PURE__*/_jsx(Text, {
537
+ style: styles.locationItemName,
538
+ numberOfLines: 1,
539
+ children: location.name
540
+ }), location.label && /*#__PURE__*/_jsx(View, {
541
+ style: styles.locationLabel,
542
+ children: /*#__PURE__*/_jsx(Text, {
543
+ style: styles.locationLabelText,
544
+ children: location.label
545
+ })
546
+ })]
547
+ }), location.coordinates && /*#__PURE__*/_jsxs(Text, {
548
+ style: styles.locationCoordinates,
549
+ children: [location.coordinates.lat.toFixed(4), ", ", location.coordinates.lon.toFixed(4)]
550
+ })]
551
+ }), /*#__PURE__*/_jsx(View, {
552
+ style: styles.locationItemActions,
553
+ children: /*#__PURE__*/_jsx(TouchableOpacity, {
554
+ style: styles.locationItemButton,
555
+ onPress: () => removeLocation(location.id),
556
+ children: /*#__PURE__*/_jsx(OxyIcon, {
557
+ name: "trash",
558
+ size: 14,
559
+ color: "#FF3B30"
560
+ })
561
+ })
562
+ })]
563
+ }), index < tempLocations.length - 1 && /*#__PURE__*/_jsx(View, {
564
+ style: styles.locationItemDivider
565
+ })]
566
+ }, location.id)), /*#__PURE__*/_jsx(View, {
567
+ style: styles.reorderHint,
568
+ children: /*#__PURE__*/_jsx(Text, {
569
+ style: styles.reorderHintText,
570
+ children: "Use \u2191\u2193 buttons to reorder your locations"
571
+ })
572
+ })]
573
+ })]
574
+ })
575
+ })
576
+ });
577
+ }
578
+ if (type === 'links') {
579
+ return /*#__PURE__*/_jsx(View, {
580
+ style: [styles.editingFieldContainer, {
581
+ backgroundColor: themeStyles.backgroundColor
582
+ }],
583
+ children: /*#__PURE__*/_jsx(View, {
584
+ style: styles.editingFieldContent,
585
+ children: /*#__PURE__*/_jsxs(View, {
586
+ style: styles.newValueSection,
587
+ children: [/*#__PURE__*/_jsx(View, {
588
+ style: styles.editingFieldHeader,
589
+ children: /*#__PURE__*/_jsx(Text, {
590
+ style: [styles.editingFieldLabel, {
591
+ color: themeStyles.isDarkTheme ? '#FFFFFF' : '#1A1A1A'
592
+ }],
593
+ children: "Manage Your Links"
594
+ })
595
+ }), /*#__PURE__*/_jsx(GroupedSection, {
596
+ items: [
597
+ // Add new link item
598
+ ...(isAddingLink ? [{
599
+ id: 'add-link-input',
600
+ icon: 'add',
601
+ iconColor: '#32D74B',
602
+ title: 'Add New Link',
603
+ subtitle: isFetchingMetadata ? 'Fetching metadata...' : 'Enter URL to add a new link',
604
+ multiRow: true,
605
+ customContent: /*#__PURE__*/_jsxs(View, {
606
+ style: styles.addLinkInputContainer,
607
+ children: [/*#__PURE__*/_jsx(TextInput, {
608
+ style: styles.addLinkInput,
609
+ value: newLinkUrl,
610
+ onChangeText: setNewLinkUrl,
611
+ placeholder: "Enter URL (e.g., https://example.com)",
612
+ placeholderTextColor: themeStyles.isDarkTheme ? '#aaa' : '#999',
613
+ keyboardType: "url",
614
+ autoFocus: true,
615
+ selectionColor: themeStyles.primaryColor
616
+ }), /*#__PURE__*/_jsxs(View, {
617
+ style: styles.addLinkButtons,
618
+ children: [/*#__PURE__*/_jsx(TouchableOpacity, {
619
+ style: [styles.addLinkButton, styles.cancelButton],
620
+ onPress: () => {
621
+ setIsAddingLink(false);
622
+ setNewLinkUrl('');
623
+ },
624
+ children: /*#__PURE__*/_jsx(Text, {
625
+ style: styles.cancelButtonText,
626
+ children: "Cancel"
627
+ })
628
+ }), /*#__PURE__*/_jsx(TouchableOpacity, {
629
+ style: [styles.addLinkButton, styles.addButton, {
630
+ opacity: isFetchingMetadata ? 0.5 : 1
631
+ }],
632
+ onPress: addLink,
633
+ disabled: isFetchingMetadata,
634
+ children: isFetchingMetadata ? /*#__PURE__*/_jsx(ActivityIndicator, {
635
+ size: "small",
636
+ color: "#fff"
637
+ }) : /*#__PURE__*/_jsx(Text, {
638
+ style: styles.addButtonText,
639
+ children: "Add"
640
+ })
641
+ })]
642
+ })]
643
+ })
644
+ }] : [{
645
+ id: 'add-link-trigger',
646
+ icon: 'add',
647
+ iconColor: '#32D74B',
648
+ title: 'Add a new link',
649
+ subtitle: 'Tap to add a new link to your profile',
650
+ onPress: () => setIsAddingLink(true)
651
+ }]),
652
+ // Existing links
653
+ ...tempLinksWithMetadata.map((link, index) => ({
654
+ id: link.id,
655
+ image: link.image || undefined,
656
+ imageSize: 32,
657
+ icon: link.image ? undefined : 'link',
658
+ iconColor: '#32D74B',
659
+ title: link.title || link.url,
660
+ subtitle: link.description && link.description !== link.title ? link.description : link.url,
661
+ multiRow: true,
662
+ customContent: /*#__PURE__*/_jsxs(View, {
663
+ style: styles.linkItemActions,
664
+ children: [/*#__PURE__*/_jsxs(View, {
665
+ style: styles.reorderButtons,
666
+ children: [/*#__PURE__*/_jsx(TouchableOpacity, {
667
+ style: [styles.reorderButton, index === 0 && styles.reorderButtonDisabled],
668
+ onPress: () => index > 0 && moveLink(index, index - 1),
669
+ disabled: index === 0,
670
+ children: /*#__PURE__*/_jsx(OxyIcon, {
671
+ name: "chevron-up",
672
+ size: 12,
673
+ color: index === 0 ? "#ccc" : "#666"
674
+ })
675
+ }), /*#__PURE__*/_jsx(TouchableOpacity, {
676
+ style: [styles.reorderButton, index === tempLinksWithMetadata.length - 1 && styles.reorderButtonDisabled],
677
+ onPress: () => index < tempLinksWithMetadata.length - 1 && moveLink(index, index + 1),
678
+ disabled: index === tempLinksWithMetadata.length - 1,
679
+ children: /*#__PURE__*/_jsx(OxyIcon, {
680
+ name: "chevron-down",
681
+ size: 12,
682
+ color: index === tempLinksWithMetadata.length - 1 ? "#ccc" : "#666"
683
+ })
684
+ })]
685
+ }), /*#__PURE__*/_jsx(TouchableOpacity, {
686
+ style: styles.linkItemButton,
687
+ onPress: () => removeLink(link.id),
688
+ children: /*#__PURE__*/_jsx(OxyIcon, {
689
+ name: "trash",
690
+ size: 14,
691
+ color: "#FF3B30"
692
+ })
693
+ })]
694
+ })
695
+ }))],
696
+ theme: theme
697
+ }), tempLinksWithMetadata.length > 0 && /*#__PURE__*/_jsx(View, {
698
+ style: styles.reorderHint,
699
+ children: /*#__PURE__*/_jsx(Text, {
700
+ style: styles.reorderHintText,
701
+ children: "Use \u2191\u2193 buttons to reorder your links"
702
+ })
703
+ })]
704
+ })
705
+ })
706
+ });
707
+ }
289
708
  const fieldConfig = {
290
709
  displayName: {
291
710
  label: 'Display Name',
@@ -385,14 +804,21 @@ const AccountSettingsScreen = ({
385
804
  }
386
805
  };
387
806
  return /*#__PURE__*/_jsx(View, {
388
- style: styles.editingFieldContainer,
807
+ style: [styles.editingFieldContainer, {
808
+ backgroundColor: themeStyles.backgroundColor
809
+ }],
389
810
  children: /*#__PURE__*/_jsx(View, {
390
811
  style: styles.editingFieldContent,
391
812
  children: /*#__PURE__*/_jsxs(View, {
392
813
  style: styles.newValueSection,
393
- children: [/*#__PURE__*/_jsx(Text, {
394
- style: styles.editingFieldLabel,
395
- children: `Enter ${config.label.toLowerCase()}:`
814
+ children: [/*#__PURE__*/_jsx(View, {
815
+ style: styles.editingFieldHeader,
816
+ children: /*#__PURE__*/_jsx(Text, {
817
+ style: [styles.editingFieldLabel, {
818
+ color: themeStyles.isDarkTheme ? '#FFFFFF' : '#1A1A1A'
819
+ }],
820
+ children: `Enter ${config.label.toLowerCase()}:`
821
+ })
396
822
  }), /*#__PURE__*/_jsx(TextInput, {
397
823
  style: [config.multiline ? styles.editingFieldTextArea : styles.editingFieldInput, {
398
824
  backgroundColor: themeStyles.isDarkTheme ? '#333' : '#fff',
@@ -413,34 +839,6 @@ const AccountSettingsScreen = ({
413
839
  })
414
840
  });
415
841
  };
416
- const renderField = (type, label, value, placeholder, icon, iconColor, multiline = false, keyboardType = 'default', isFirst = false, isLast = false) => {
417
- const itemStyles = [styles.settingItem, isFirst && styles.firstSettingItem, isLast && styles.lastSettingItem];
418
- return /*#__PURE__*/_jsxs(TouchableOpacity, {
419
- style: itemStyles,
420
- onPress: () => startEditing(type, value),
421
- children: [/*#__PURE__*/_jsxs(View, {
422
- style: styles.settingInfo,
423
- children: [/*#__PURE__*/_jsx(OxyIcon, {
424
- name: icon,
425
- size: 20,
426
- color: iconColor,
427
- style: styles.settingIcon
428
- }), /*#__PURE__*/_jsxs(View, {
429
- children: [/*#__PURE__*/_jsx(Text, {
430
- style: styles.settingLabel,
431
- children: label
432
- }), /*#__PURE__*/_jsx(Text, {
433
- style: styles.settingDescription,
434
- children: value || placeholder
435
- })]
436
- })]
437
- }), /*#__PURE__*/_jsx(OxyIcon, {
438
- name: "chevron-forward",
439
- size: 16,
440
- color: "#ccc"
441
- })]
442
- });
443
- };
444
842
  if (authLoading || !isAuthenticated) {
445
843
  return /*#__PURE__*/_jsx(View, {
446
844
  style: [styles.container, {
@@ -457,93 +855,64 @@ const AccountSettingsScreen = ({
457
855
  style: [styles.container, {
458
856
  backgroundColor: themeStyles.backgroundColor
459
857
  }],
460
- children: [/*#__PURE__*/_jsx(View, {
461
- style: styles.header,
462
- children: editingField ? /*#__PURE__*/_jsxs(View, {
463
- style: styles.editingHeader,
464
- children: [/*#__PURE__*/_jsxs(View, {
465
- style: styles.editingHeaderTop,
466
- children: [/*#__PURE__*/_jsx(TouchableOpacity, {
467
- style: styles.cancelButton,
468
- onPress: cancelEditing,
469
- children: /*#__PURE__*/_jsx(Ionicons, {
470
- name: "close",
471
- size: 24,
472
- color: "#666"
473
- })
474
- }), /*#__PURE__*/_jsx(Animated.View, {
475
- style: {
476
- transform: [{
477
- scale: saveButtonScale
478
- }]
479
- },
480
- children: /*#__PURE__*/_jsx(TouchableOpacity, {
481
- style: [styles.saveHeaderButton, {
482
- opacity: isSaving ? 0.7 : 1,
483
- backgroundColor: editingField ? getFieldIcon(editingField).color : '#007AFF'
484
- }],
485
- onPress: () => saveField(editingField),
486
- disabled: isSaving,
487
- children: isSaving ? /*#__PURE__*/_jsx(ActivityIndicator, {
488
- size: "small",
489
- color: "#fff"
490
- }) : /*#__PURE__*/_jsx(Text, {
491
- style: styles.saveButtonText,
492
- children: "Save"
493
- })
494
- })
495
- })]
496
- }), /*#__PURE__*/_jsx(View, {
497
- style: styles.editingHeaderBottom,
498
- children: /*#__PURE__*/_jsxs(View, {
499
- style: styles.headerTitleWithIcon,
500
- children: [/*#__PURE__*/_jsx(OxyIcon, {
501
- name: getFieldIcon(editingField).name,
502
- size: 50,
503
- color: getFieldIcon(editingField).color,
504
- style: styles.headerIcon
505
- }), /*#__PURE__*/_jsx(Text, {
506
- style: styles.headerTitleLarge,
507
- children: getFieldLabel(editingField)
508
- })]
509
- })
510
- })]
511
- }) : /*#__PURE__*/_jsxs(View, {
512
- style: styles.normalHeader,
858
+ children: [editingField ? /*#__PURE__*/_jsxs(View, {
859
+ style: [styles.editingHeader, {
860
+ backgroundColor: '#FFFFFF',
861
+ borderBottomColor: themeStyles.isDarkTheme ? '#38383A' : '#E9ECEF'
862
+ }],
863
+ children: [/*#__PURE__*/_jsxs(View, {
864
+ style: styles.editingHeaderContent,
513
865
  children: [/*#__PURE__*/_jsx(TouchableOpacity, {
514
- style: styles.cancelButton,
515
- onPress: onClose || goBack,
516
- children: /*#__PURE__*/_jsx(Ionicons, {
517
- name: "close",
518
- size: 24,
519
- color: "#666"
866
+ style: styles.editingBackButton,
867
+ onPress: cancelEditing,
868
+ children: /*#__PURE__*/_jsx(OxyIcon, {
869
+ name: "chevron-back",
870
+ size: 20,
871
+ color: themeStyles.primaryColor
520
872
  })
521
- }), /*#__PURE__*/_jsx(Text, {
522
- style: styles.headerTitle,
523
- children: "Account Settings"
524
- }), /*#__PURE__*/_jsx(Animated.View, {
525
- style: {
526
- transform: [{
527
- scale: saveButtonScale
528
- }]
529
- },
530
- children: /*#__PURE__*/_jsx(TouchableOpacity, {
531
- style: [styles.saveIconButton, {
532
- opacity: isSaving ? 0.7 : 1
533
- }],
534
- onPress: handleSave,
535
- disabled: isSaving,
536
- children: isSaving ? /*#__PURE__*/_jsx(ActivityIndicator, {
537
- size: "small",
538
- color: themeStyles.primaryColor
539
- }) : /*#__PURE__*/_jsx(Ionicons, {
540
- name: "checkmark",
541
- size: 24,
873
+ }), /*#__PURE__*/_jsx(View, {
874
+ style: styles.editingTitleContainer
875
+ }), /*#__PURE__*/_jsx(TouchableOpacity, {
876
+ style: [styles.editingSaveButton, {
877
+ opacity: isSaving ? 0.5 : 1
878
+ }],
879
+ onPress: () => saveField(editingField),
880
+ disabled: isSaving,
881
+ children: isSaving ? /*#__PURE__*/_jsx(ActivityIndicator, {
882
+ size: "small",
883
+ color: themeStyles.primaryColor
884
+ }) : /*#__PURE__*/_jsx(Text, {
885
+ style: [styles.editingSaveButtonText, {
542
886
  color: themeStyles.primaryColor
543
- })
887
+ }],
888
+ children: "Save"
544
889
  })
545
890
  })]
546
- })
891
+ }), /*#__PURE__*/_jsxs(View, {
892
+ style: styles.editingHeaderBottom,
893
+ children: [/*#__PURE__*/_jsx(OxyIcon, {
894
+ name: editingField === 'displayName' ? 'person' : editingField === 'username' ? 'at' : editingField === 'email' ? 'mail' : editingField === 'bio' ? 'document-text' : editingField === 'location' ? 'location' : editingField === 'links' ? 'link' : 'person',
895
+ size: 56,
896
+ color: editingField === 'displayName' ? '#007AFF' : editingField === 'username' ? '#5856D6' : editingField === 'email' ? '#FF9500' : editingField === 'bio' ? '#34C759' : editingField === 'location' ? '#FF3B30' : editingField === 'links' ? '#32D74B' : '#007AFF',
897
+ style: styles.editingBottomIcon
898
+ }), /*#__PURE__*/_jsx(Text, {
899
+ style: [styles.editingBottomTitle, {
900
+ color: themeStyles.isDarkTheme ? '#FFFFFF' : '#1A1A1A'
901
+ }],
902
+ children: editingField === 'displayName' ? 'Display Name' : editingField === 'username' ? 'Username' : editingField === 'email' ? 'Email' : editingField === 'bio' ? 'Bio' : editingField === 'location' ? 'Location' : editingField === 'links' ? 'Links' : 'Field'
903
+ })]
904
+ })]
905
+ }) : /*#__PURE__*/_jsx(Header, {
906
+ title: "Edit Profile",
907
+ theme: theme,
908
+ onBack: goBack || onClose,
909
+ rightAction: {
910
+ icon: 'checkmark',
911
+ onPress: handleSave,
912
+ loading: isSaving,
913
+ disabled: isSaving
914
+ },
915
+ elevation: "subtle"
547
916
  }), /*#__PURE__*/_jsx(ScrollView, {
548
917
  style: editingField ? styles.contentEditing : styles.content,
549
918
  children: editingField ?
@@ -561,101 +930,153 @@ const AccountSettingsScreen = ({
561
930
  children: [/*#__PURE__*/_jsx(Text, {
562
931
  style: styles.sectionTitle,
563
932
  children: "Profile Picture"
564
- }), /*#__PURE__*/_jsxs(TouchableOpacity, {
565
- style: [styles.settingItem, styles.firstSettingItem, styles.lastSettingItem],
566
- onPress: handleAvatarUpdate,
567
- children: [/*#__PURE__*/_jsx(View, {
568
- style: styles.userIcon,
569
- children: /*#__PURE__*/_jsx(Avatar, {
570
- uri: avatarUrl,
571
- name: displayName || username,
572
- size: 50,
573
- theme: theme
574
- })
575
- }), /*#__PURE__*/_jsx(View, {
576
- style: styles.settingInfo,
577
- children: /*#__PURE__*/_jsxs(View, {
578
- children: [/*#__PURE__*/_jsx(Text, {
579
- style: styles.settingLabel,
580
- children: "Profile Photo"
581
- }), /*#__PURE__*/_jsx(Text, {
582
- style: styles.settingDescription,
583
- children: avatarUrl ? 'Tap to change your profile picture' : 'Tap to add a profile picture'
584
- })]
585
- })
586
- }), /*#__PURE__*/_jsx(OxyIcon, {
587
- name: "chevron-forward",
588
- size: 16,
589
- color: "#ccc"
590
- })]
933
+ }), /*#__PURE__*/_jsx(GroupedSection, {
934
+ items: [{
935
+ id: 'profile-photo',
936
+ icon: avatarUrl ? undefined : 'person',
937
+ iconColor: '#007AFF',
938
+ image: avatarUrl || undefined,
939
+ imageSize: 40,
940
+ title: 'Profile Photo',
941
+ subtitle: avatarUrl ? 'Tap to change your profile picture' : 'Tap to add a profile picture',
942
+ onPress: handleAvatarUpdate
943
+ }],
944
+ theme: theme
591
945
  })]
592
946
  }), /*#__PURE__*/_jsxs(View, {
593
947
  style: styles.section,
594
948
  children: [/*#__PURE__*/_jsx(Text, {
595
949
  style: styles.sectionTitle,
596
950
  children: "Basic Information"
597
- }), renderField('displayName', 'Display Name', [displayName, lastName].filter(Boolean).join(' '),
598
- // Show full name
599
- 'Add your display name', 'person', '#007AFF', false, 'default', true, false), renderField('username', 'Username', username, 'Choose a username', 'at', '#5856D6', false, 'default', false, false), renderField('email', 'Email', email, 'Add your email address', 'mail', '#FF9500', false, 'email-address', false, true)]
951
+ }), /*#__PURE__*/_jsx(GroupedSection, {
952
+ items: [{
953
+ id: 'display-name',
954
+ icon: 'person',
955
+ iconColor: '#007AFF',
956
+ title: 'Display Name',
957
+ subtitle: [displayName, lastName].filter(Boolean).join(' ') || 'Add your display name',
958
+ onPress: () => startEditing('displayName', '')
959
+ }, {
960
+ id: 'username',
961
+ icon: 'at',
962
+ iconColor: '#5856D6',
963
+ title: 'Username',
964
+ subtitle: username || 'Choose a username',
965
+ onPress: () => startEditing('username', username)
966
+ }, {
967
+ id: 'email',
968
+ icon: 'mail',
969
+ iconColor: '#FF9500',
970
+ title: 'Email',
971
+ subtitle: email || 'Add your email address',
972
+ onPress: () => startEditing('email', email)
973
+ }],
974
+ theme: theme
975
+ })]
600
976
  }), /*#__PURE__*/_jsxs(View, {
601
977
  style: styles.section,
602
978
  children: [/*#__PURE__*/_jsx(Text, {
603
979
  style: styles.sectionTitle,
604
980
  children: "About You"
605
- }), renderField('bio', 'Bio', bio, 'Tell people about yourself', 'document-text', '#34C759', true, 'default', true, false), renderField('location', 'Location', location, 'Add your location', 'location', '#FF3B30', false, 'default', false, false), renderField('links', 'Links', links.join(', '), 'Add your links', 'link', '#32D74B', false, 'url', false, true)]
981
+ }), /*#__PURE__*/_jsx(GroupedSection, {
982
+ items: [{
983
+ id: 'bio',
984
+ icon: 'document-text',
985
+ iconColor: '#34C759',
986
+ title: 'Bio',
987
+ subtitle: bio || 'Tell people about yourself',
988
+ onPress: () => startEditing('bio', bio)
989
+ }, {
990
+ id: 'locations',
991
+ icon: 'location',
992
+ iconColor: '#FF3B30',
993
+ title: 'Locations',
994
+ subtitle: tempLocations.length > 0 ? `${tempLocations.length} location${tempLocations.length !== 1 ? 's' : ''} added` : 'Add your locations',
995
+ onPress: () => startEditing('location', ''),
996
+ customContentBelow: tempLocations.length > 0 && /*#__PURE__*/_jsxs(View, {
997
+ style: styles.linksPreviewContainer,
998
+ children: [tempLocations.slice(0, 2).map((location, index) => /*#__PURE__*/_jsxs(View, {
999
+ style: styles.linkPreviewItem,
1000
+ children: [/*#__PURE__*/_jsx(View, {
1001
+ style: styles.linkPreviewImage,
1002
+ children: /*#__PURE__*/_jsx(Text, {
1003
+ style: styles.linkPreviewImageText,
1004
+ children: location.name.charAt(0).toUpperCase()
1005
+ })
1006
+ }), /*#__PURE__*/_jsxs(View, {
1007
+ style: styles.linkPreviewContent,
1008
+ children: [/*#__PURE__*/_jsx(Text, {
1009
+ style: styles.linkPreviewTitle,
1010
+ numberOfLines: 1,
1011
+ children: location.name
1012
+ }), location.label && /*#__PURE__*/_jsx(Text, {
1013
+ style: styles.linkPreviewSubtitle,
1014
+ children: location.label
1015
+ })]
1016
+ })]
1017
+ }, location.id || index)), tempLocations.length > 2 && /*#__PURE__*/_jsxs(Text, {
1018
+ style: styles.linkPreviewMore,
1019
+ children: ["+", tempLocations.length - 2, " more"]
1020
+ })]
1021
+ })
1022
+ }, {
1023
+ id: 'links',
1024
+ icon: 'link',
1025
+ iconColor: '#32D74B',
1026
+ title: 'Links',
1027
+ subtitle: tempLinksWithMetadata.length > 0 ? `${tempLinksWithMetadata.length} link${tempLinksWithMetadata.length !== 1 ? 's' : ''} added` : 'Add your links',
1028
+ onPress: () => startEditing('links', ''),
1029
+ multiRow: true,
1030
+ customContentBelow: tempLinksWithMetadata.length > 0 && /*#__PURE__*/_jsxs(View, {
1031
+ style: styles.linksPreviewContainer,
1032
+ children: [tempLinksWithMetadata.slice(0, 2).map((link, index) => /*#__PURE__*/_jsxs(View, {
1033
+ style: styles.linkPreviewItem,
1034
+ children: [link.image ? /*#__PURE__*/_jsx(Image, {
1035
+ source: {
1036
+ uri: link.image
1037
+ },
1038
+ style: styles.linkPreviewImage
1039
+ }) : /*#__PURE__*/_jsx(View, {
1040
+ style: styles.linkPreviewImage,
1041
+ children: /*#__PURE__*/_jsx(Text, {
1042
+ style: styles.linkPreviewImageText,
1043
+ children: link.title?.charAt(0).toUpperCase() || link.url.charAt(0).toUpperCase()
1044
+ })
1045
+ }), /*#__PURE__*/_jsx(Text, {
1046
+ style: styles.linkPreviewTitle,
1047
+ numberOfLines: 1,
1048
+ children: link.title || link.url
1049
+ })]
1050
+ }, link.id || index)), tempLinksWithMetadata.length > 2 && /*#__PURE__*/_jsxs(Text, {
1051
+ style: styles.linkPreviewMore,
1052
+ children: ["+", tempLinksWithMetadata.length - 2, " more"]
1053
+ })]
1054
+ })
1055
+ }],
1056
+ theme: theme
1057
+ })]
606
1058
  }), /*#__PURE__*/_jsxs(View, {
607
1059
  style: styles.section,
608
1060
  children: [/*#__PURE__*/_jsx(Text, {
609
1061
  style: styles.sectionTitle,
610
1062
  children: "Quick Actions"
611
- }), /*#__PURE__*/_jsxs(TouchableOpacity, {
612
- style: [styles.settingItem, styles.firstSettingItem],
613
- onPress: () => toast.info('Privacy settings coming soon!'),
614
- children: [/*#__PURE__*/_jsxs(View, {
615
- style: styles.settingInfo,
616
- children: [/*#__PURE__*/_jsx(OxyIcon, {
617
- name: "shield-checkmark",
618
- size: 20,
619
- color: "#8E8E93",
620
- style: styles.settingIcon
621
- }), /*#__PURE__*/_jsxs(View, {
622
- children: [/*#__PURE__*/_jsx(Text, {
623
- style: styles.settingLabel,
624
- children: "Privacy Settings"
625
- }), /*#__PURE__*/_jsx(Text, {
626
- style: styles.settingDescription,
627
- children: "Control who can see your profile"
628
- })]
629
- })]
630
- }), /*#__PURE__*/_jsx(OxyIcon, {
631
- name: "chevron-forward",
632
- size: 16,
633
- color: "#ccc"
634
- })]
635
- }), /*#__PURE__*/_jsxs(TouchableOpacity, {
636
- style: [styles.settingItem, styles.lastSettingItem],
637
- onPress: () => toast.info('Account verification coming soon!'),
638
- children: [/*#__PURE__*/_jsxs(View, {
639
- style: styles.settingInfo,
640
- children: [/*#__PURE__*/_jsx(OxyIcon, {
641
- name: "checkmark-circle",
642
- size: 20,
643
- color: "#30D158",
644
- style: styles.settingIcon
645
- }), /*#__PURE__*/_jsxs(View, {
646
- children: [/*#__PURE__*/_jsx(Text, {
647
- style: styles.settingLabel,
648
- children: "Verify Account"
649
- }), /*#__PURE__*/_jsx(Text, {
650
- style: styles.settingDescription,
651
- children: "Get a verified badge"
652
- })]
653
- })]
654
- }), /*#__PURE__*/_jsx(OxyIcon, {
655
- name: "chevron-forward",
656
- size: 16,
657
- color: "#ccc"
658
- })]
1063
+ }), /*#__PURE__*/_jsx(GroupedSection, {
1064
+ items: [{
1065
+ id: 'privacy-settings',
1066
+ icon: 'shield-checkmark',
1067
+ iconColor: '#8E8E93',
1068
+ title: 'Privacy Settings',
1069
+ subtitle: 'Control who can see your profile',
1070
+ onPress: () => toast.info('Privacy settings coming soon!')
1071
+ }, {
1072
+ id: 'verify-account',
1073
+ icon: 'checkmark-circle',
1074
+ iconColor: '#30D158',
1075
+ title: 'Verify Account',
1076
+ subtitle: 'Get a verified badge',
1077
+ onPress: () => toast.info('Account verification coming soon!')
1078
+ }],
1079
+ theme: theme
659
1080
  })]
660
1081
  })]
661
1082
  })
@@ -667,203 +1088,416 @@ const styles = StyleSheet.create({
667
1088
  flex: 1,
668
1089
  backgroundColor: '#f2f2f2'
669
1090
  },
670
- header: {
671
- paddingHorizontal: 20,
672
- paddingVertical: 10,
1091
+ content: {
1092
+ flex: 1,
1093
+ padding: 16
1094
+ },
1095
+ contentEditing: {
1096
+ flex: 1,
1097
+ padding: 0
1098
+ },
1099
+ section: {
1100
+ marginBottom: 24
1101
+ },
1102
+ sectionTitle: {
1103
+ fontSize: 16,
1104
+ fontWeight: '600',
1105
+ color: '#333',
1106
+ marginBottom: 12,
1107
+ fontFamily: fontFamilies.phuduSemiBold
1108
+ },
1109
+ userIcon: {
1110
+ marginRight: 12
1111
+ },
1112
+ // Editing-only mode styles
1113
+ editingOnlyContainer: {
1114
+ flex: 1
1115
+ },
1116
+ editingFieldContainer: {
673
1117
  backgroundColor: '#fff',
674
- borderBottomWidth: 1,
675
- borderBottomColor: '#e0e0e0'
1118
+ padding: 16,
1119
+ flex: 1
1120
+ },
1121
+ editingFieldHeader: {
1122
+ marginBottom: 8,
1123
+ flexDirection: 'row',
1124
+ alignItems: 'center'
676
1125
  },
677
- normalHeader: {
1126
+ editingFieldTitleContainer: {
678
1127
  flexDirection: 'row',
679
- justifyContent: 'space-between',
680
1128
  alignItems: 'center'
681
1129
  },
1130
+ editingFieldIcon: {
1131
+ marginRight: 12
1132
+ },
1133
+ editingFieldTitle: {
1134
+ fontSize: 20,
1135
+ fontWeight: '600',
1136
+ color: '#000'
1137
+ },
1138
+ editingFieldContent: {
1139
+ flex: 1
1140
+ },
1141
+ newValueSection: {
1142
+ flex: 1
1143
+ },
1144
+ editingFieldLabel: {
1145
+ fontSize: 16,
1146
+ fontWeight: '600',
1147
+ color: '#333',
1148
+ marginBottom: 12,
1149
+ fontFamily: fontFamilies.phuduSemiBold
1150
+ },
1151
+ editingFieldInput: {
1152
+ backgroundColor: '#fff',
1153
+ borderWidth: 2,
1154
+ borderColor: '#e0e0e0',
1155
+ borderRadius: 12,
1156
+ padding: 16,
1157
+ fontSize: 17,
1158
+ minHeight: 52,
1159
+ fontWeight: '400'
1160
+ },
1161
+ editingFieldTextArea: {
1162
+ backgroundColor: '#fff',
1163
+ borderWidth: 2,
1164
+ borderColor: '#e0e0e0',
1165
+ borderRadius: 12,
1166
+ padding: 16,
1167
+ fontSize: 17,
1168
+ minHeight: 120,
1169
+ textAlignVertical: 'top',
1170
+ fontWeight: '400'
1171
+ },
1172
+ // Custom editing header styles
682
1173
  editingHeader: {
683
- flexDirection: 'column'
1174
+ paddingTop: Platform.OS === 'ios' ? 50 : 16,
1175
+ paddingBottom: 0,
1176
+ borderBottomWidth: 1,
1177
+ backgroundColor: '#fff'
684
1178
  },
685
- editingHeaderTop: {
1179
+ editingHeaderContent: {
686
1180
  flexDirection: 'row',
687
- justifyContent: 'space-between',
688
1181
  alignItems: 'center',
689
- marginBottom: 16
1182
+ paddingHorizontal: 16,
1183
+ minHeight: 44
690
1184
  },
691
- editingHeaderBottom: {
692
- flexDirection: 'row',
1185
+ editingBackButton: {
1186
+ width: 32,
1187
+ height: 32,
1188
+ borderRadius: 16,
1189
+ backgroundColor: '#F8F9FA',
693
1190
  alignItems: 'center',
694
- justifyContent: 'flex-start'
695
- },
696
- headerTitle: {
697
- fontSize: 24,
698
- fontWeight: 'bold',
699
- color: '#000',
700
- fontFamily: fontFamilies.phuduBold
1191
+ justifyContent: 'center',
1192
+ marginRight: 12
701
1193
  },
702
- headerTitleWithIcon: {
1194
+ editingTitleContainer: {
1195
+ flex: 1,
703
1196
  flexDirection: 'column',
704
1197
  alignItems: 'flex-start',
705
- flex: 1,
706
- justifyContent: 'flex-start',
707
- maxWidth: '90%'
1198
+ justifyContent: 'flex-end',
1199
+ paddingBottom: 8
708
1200
  },
709
- headerTitleLarge: {
710
- fontSize: 48,
711
- fontWeight: '800',
712
- color: '#000',
713
- fontFamily: fontFamilies.phuduExtraBold,
714
- textAlign: 'left'
1201
+ editingTitleIcon: {
1202
+ marginBottom: 4,
1203
+ alignSelf: 'flex-start'
715
1204
  },
716
- headerIcon: {
717
- marginBottom: 2
718
- },
719
- cancelButton: {
720
- padding: 5
1205
+ editingTitle: {
1206
+ fontSize: 18,
1207
+ fontWeight: '700',
1208
+ fontFamily: fontFamilies.phuduBold,
1209
+ letterSpacing: -0.3,
1210
+ lineHeight: 22,
1211
+ textAlign: 'left',
1212
+ alignSelf: 'flex-start'
721
1213
  },
722
- saveHeaderButton: {
1214
+ editingSaveButton: {
723
1215
  paddingHorizontal: 16,
724
1216
  paddingVertical: 8,
725
- borderRadius: 20,
1217
+ borderRadius: 18,
1218
+ backgroundColor: '#F8F9FA',
726
1219
  minWidth: 60,
727
1220
  alignItems: 'center',
728
1221
  justifyContent: 'center'
729
1222
  },
730
- saveIconButton: {
731
- padding: 5
732
- },
733
- saveButtonText: {
734
- color: '#fff',
1223
+ editingSaveButtonText: {
735
1224
  fontSize: 16,
736
1225
  fontWeight: '600',
737
1226
  fontFamily: fontFamilies.phuduSemiBold
738
1227
  },
739
- content: {
740
- flex: 1,
741
- padding: 16
1228
+ editingHeaderBottom: {
1229
+ flexDirection: 'column',
1230
+ alignItems: 'flex-start',
1231
+ paddingHorizontal: 16,
1232
+ paddingBottom: 8,
1233
+ paddingTop: 8
742
1234
  },
743
- contentEditing: {
744
- flex: 1,
745
- padding: 0
1235
+ editingBottomIcon: {
1236
+ marginBottom: 8,
1237
+ alignSelf: 'flex-start'
746
1238
  },
747
- section: {
748
- marginBottom: 24
1239
+ editingBottomTitle: {
1240
+ fontSize: 32,
1241
+ fontWeight: '700',
1242
+ fontFamily: fontFamilies.phuduBold,
1243
+ letterSpacing: -0.5,
1244
+ lineHeight: 36,
1245
+ textAlign: 'left',
1246
+ alignSelf: 'flex-start'
749
1247
  },
750
- sectionTitle: {
751
- fontSize: 16,
1248
+ // Links management styles
1249
+ addLinkSection: {
1250
+ marginBottom: 16,
1251
+ padding: 12,
1252
+ backgroundColor: '#F8F9FA',
1253
+ borderRadius: 8,
1254
+ borderWidth: 1,
1255
+ borderColor: '#E9ECEF'
1256
+ },
1257
+ addLinkLabel: {
1258
+ fontSize: 14,
752
1259
  fontWeight: '600',
753
1260
  color: '#333',
754
- marginBottom: 12,
755
- fontFamily: fontFamilies.phuduSemiBold
1261
+ marginBottom: 8
1262
+ },
1263
+ addLinkInputContainer: {
1264
+ gap: 8
756
1265
  },
757
- settingItem: {
1266
+ addLinkInput: {
758
1267
  backgroundColor: '#fff',
759
- padding: 16,
1268
+ borderWidth: 1,
1269
+ borderColor: '#E9ECEF',
1270
+ borderRadius: 6,
1271
+ padding: 10,
1272
+ fontSize: 14,
1273
+ minHeight: 36
1274
+ },
1275
+ addLinkButtons: {
760
1276
  flexDirection: 'row',
1277
+ gap: 6
1278
+ },
1279
+ addLinkButton: {
1280
+ flex: 1,
1281
+ paddingVertical: 8,
1282
+ paddingHorizontal: 12,
1283
+ borderRadius: 6,
761
1284
  alignItems: 'center',
762
- justifyContent: 'space-between',
763
- marginBottom: 2
1285
+ justifyContent: 'center'
764
1286
  },
765
- firstSettingItem: {
766
- borderTopLeftRadius: 24,
767
- borderTopRightRadius: 24
1287
+ cancelButton: {
1288
+ backgroundColor: '#F8F9FA',
1289
+ borderWidth: 1,
1290
+ borderColor: '#E9ECEF'
768
1291
  },
769
- lastSettingItem: {
770
- borderBottomLeftRadius: 24,
771
- borderBottomRightRadius: 24,
772
- marginBottom: 8
1292
+ cancelButtonText: {
1293
+ fontSize: 14,
1294
+ fontWeight: '600',
1295
+ color: '#6C757D'
773
1296
  },
774
- settingInfo: {
1297
+ addButton: {
1298
+ backgroundColor: '#007AFF'
1299
+ },
1300
+ addButtonText: {
1301
+ fontSize: 14,
1302
+ fontWeight: '600',
1303
+ color: '#fff'
1304
+ },
1305
+ addLinkTrigger: {
775
1306
  flexDirection: 'row',
776
1307
  alignItems: 'center',
777
- flex: 1
1308
+ padding: 12,
1309
+ backgroundColor: '#F8F9FA',
1310
+ borderRadius: 8,
1311
+ borderWidth: 1,
1312
+ borderColor: '#E9ECEF',
1313
+ borderStyle: 'dashed',
1314
+ marginBottom: 16
778
1315
  },
779
- settingIcon: {
780
- marginRight: 12
1316
+ addLinkTriggerText: {
1317
+ fontSize: 14,
1318
+ fontWeight: '600',
1319
+ color: '#007AFF',
1320
+ marginLeft: 6
1321
+ },
1322
+ linksList: {
1323
+ gap: 8
781
1324
  },
782
- settingLabel: {
1325
+ linksListTitle: {
783
1326
  fontSize: 16,
784
- fontWeight: '500',
1327
+ fontWeight: '700',
785
1328
  color: '#333',
786
- marginBottom: 2
1329
+ marginBottom: 6
1330
+ },
1331
+ linkItem: {
1332
+ backgroundColor: '#fff',
1333
+ borderRadius: 8,
1334
+ borderWidth: 1,
1335
+ borderColor: '#E9ECEF',
1336
+ overflow: 'hidden'
1337
+ },
1338
+ linkItemContent: {
1339
+ flexDirection: 'row',
1340
+ padding: 12,
1341
+ alignItems: 'center'
1342
+ },
1343
+ linkItemDragHandle: {
1344
+ width: 24,
1345
+ height: 24,
1346
+ alignItems: 'center',
1347
+ justifyContent: 'center',
1348
+ marginRight: 8
787
1349
  },
788
- settingDescription: {
1350
+ linkItemInfo: {
1351
+ flex: 1,
1352
+ marginRight: 8
1353
+ },
1354
+ linkItemTitle: {
789
1355
  fontSize: 14,
790
- color: '#666'
1356
+ fontWeight: '600',
1357
+ color: '#333',
1358
+ marginBottom: 2
791
1359
  },
792
- userIcon: {
793
- marginRight: 12
1360
+ linkItemDescription: {
1361
+ fontSize: 12,
1362
+ color: '#666',
1363
+ marginBottom: 2
794
1364
  },
795
- // Inline editing styles
796
- editingContainer: {
797
- flex: 1
1365
+ linkItemUrl: {
1366
+ fontSize: 12,
1367
+ color: '#6C757D'
798
1368
  },
799
- editingActions: {
1369
+ linkItemActions: {
800
1370
  flexDirection: 'row',
1371
+ gap: 6
1372
+ },
1373
+ linkItemButton: {
1374
+ width: 28,
1375
+ height: 28,
1376
+ borderRadius: 14,
1377
+ backgroundColor: '#F8F9FA',
1378
+ alignItems: 'center',
1379
+ justifyContent: 'center'
1380
+ },
1381
+ linkItemDivider: {
1382
+ height: 1,
1383
+ backgroundColor: '#E9ECEF',
1384
+ marginHorizontal: 12
1385
+ },
1386
+ reorderHint: {
1387
+ padding: 8,
801
1388
  alignItems: 'center'
802
1389
  },
803
- editingButton: {
804
- padding: 8
1390
+ reorderHintText: {
1391
+ fontSize: 12,
1392
+ color: '#999',
1393
+ fontStyle: 'italic'
805
1394
  },
806
- editingButtonText: {
807
- fontSize: 16,
808
- fontWeight: '500'
1395
+ reorderButtons: {
1396
+ flexDirection: 'column',
1397
+ gap: 2
809
1398
  },
810
- inlineInput: {
811
- backgroundColor: '#f8f8f8',
1399
+ reorderButton: {
1400
+ width: 20,
1401
+ height: 16,
1402
+ borderRadius: 3,
1403
+ backgroundColor: '#F8F9FA',
1404
+ alignItems: 'center',
1405
+ justifyContent: 'center',
812
1406
  borderWidth: 1,
813
- borderColor: '#e0e0e0',
814
- borderRadius: 8,
815
- padding: 12,
816
- fontSize: 16,
817
- minHeight: 44
1407
+ borderColor: '#E9ECEF'
818
1408
  },
819
- inlineTextArea: {
820
- backgroundColor: '#f8f8f8',
821
- borderWidth: 1,
822
- borderColor: '#e0e0e0',
823
- borderRadius: 8,
824
- padding: 12,
825
- fontSize: 16,
826
- minHeight: 100,
827
- textAlignVertical: 'top'
1409
+ reorderButtonDisabled: {
1410
+ opacity: 0.3
828
1411
  },
829
- // Editing-only mode styles
830
- editingOnlyContainer: {
831
- flex: 1
1412
+ linkItemImage: {
1413
+ width: 32,
1414
+ height: 32,
1415
+ borderRadius: 16,
1416
+ backgroundColor: '#007AFF',
1417
+ alignItems: 'center',
1418
+ justifyContent: 'center',
1419
+ marginRight: 8
832
1420
  },
833
- editingFieldContainer: {
834
- backgroundColor: '#fff',
835
- padding: 16,
836
- flex: 1
1421
+ linkItemImageText: {
1422
+ fontSize: 12,
1423
+ fontWeight: '600',
1424
+ color: '#fff'
837
1425
  },
838
- editingFieldHeader: {
839
- marginBottom: 16
1426
+ fetchingText: {
1427
+ fontSize: 12,
1428
+ color: '#007AFF',
1429
+ fontStyle: 'italic'
840
1430
  },
841
- editingFieldTitleContainer: {
1431
+ linksFieldContent: {
1432
+ flex: 1,
1433
+ marginLeft: 12
1434
+ },
1435
+ linksPreview: {
1436
+ marginTop: 4,
1437
+ flexDirection: 'column'
1438
+ },
1439
+ linksPreviewContainer: {
1440
+ marginTop: 4,
1441
+ flexDirection: 'column',
1442
+ width: '100%'
1443
+ },
1444
+ linkPreviewItem: {
842
1445
  flexDirection: 'row',
843
- alignItems: 'center'
1446
+ alignItems: 'center',
1447
+ marginBottom: 4
844
1448
  },
845
- editingFieldIcon: {
846
- marginRight: 12
1449
+ linkPreviewImage: {
1450
+ width: 20,
1451
+ height: 20,
1452
+ borderRadius: 10,
1453
+ backgroundColor: '#007AFF',
1454
+ alignItems: 'center',
1455
+ justifyContent: 'center',
1456
+ marginRight: 6
847
1457
  },
848
- editingFieldTitle: {
849
- fontSize: 20,
1458
+ linkPreviewImageText: {
1459
+ fontSize: 10,
850
1460
  fontWeight: '600',
851
- color: '#000'
1461
+ color: '#fff'
852
1462
  },
853
- editingFieldContent: {
1463
+ linkPreviewTitle: {
1464
+ fontSize: 13,
1465
+ color: '#666',
854
1466
  flex: 1
855
1467
  },
856
- newValueSection: {
1468
+ linkPreviewContent: {
857
1469
  flex: 1
858
1470
  },
859
- editingFieldLabel: {
860
- fontSize: 16,
1471
+ linkPreviewSubtitle: {
1472
+ fontSize: 11,
1473
+ color: '#999',
1474
+ marginTop: 1
1475
+ },
1476
+ linkPreviewMore: {
1477
+ fontSize: 12,
1478
+ color: '#999',
1479
+ fontStyle: 'italic'
1480
+ },
1481
+ // Location management styles
1482
+ addLocationSection: {
1483
+ marginBottom: 16
1484
+ },
1485
+ addLocationLabel: {
1486
+ fontSize: 14,
861
1487
  fontWeight: '600',
862
1488
  color: '#333',
863
- marginBottom: 12,
1489
+ marginBottom: 8,
864
1490
  fontFamily: fontFamilies.phuduSemiBold
865
1491
  },
866
- editingFieldInput: {
1492
+ searchingText: {
1493
+ fontSize: 12,
1494
+ color: '#007AFF',
1495
+ fontStyle: 'italic'
1496
+ },
1497
+ addLocationInputContainer: {
1498
+ marginBottom: 8
1499
+ },
1500
+ addLocationInput: {
867
1501
  backgroundColor: '#fff',
868
1502
  borderWidth: 2,
869
1503
  borderColor: '#e0e0e0',
@@ -871,18 +1505,129 @@ const styles = StyleSheet.create({
871
1505
  padding: 16,
872
1506
  fontSize: 17,
873
1507
  minHeight: 52,
874
- fontWeight: '400'
1508
+ fontWeight: '400',
1509
+ marginBottom: 8
875
1510
  },
876
- editingFieldTextArea: {
1511
+ addLocationButtons: {
1512
+ flexDirection: 'row',
1513
+ gap: 8
1514
+ },
1515
+ addLocationButton: {
1516
+ flex: 1,
1517
+ paddingVertical: 12,
1518
+ paddingHorizontal: 16,
1519
+ borderRadius: 8,
1520
+ alignItems: 'center',
1521
+ justifyContent: 'center'
1522
+ },
1523
+ addLocationTrigger: {
1524
+ flexDirection: 'row',
1525
+ alignItems: 'center',
1526
+ paddingVertical: 12,
1527
+ paddingHorizontal: 16,
1528
+ backgroundColor: '#F8F9FA',
1529
+ borderRadius: 8,
1530
+ marginBottom: 16
1531
+ },
1532
+ addLocationTriggerText: {
1533
+ marginLeft: 8,
1534
+ fontSize: 16,
1535
+ color: '#007AFF',
1536
+ fontWeight: '500'
1537
+ },
1538
+ searchResults: {
877
1539
  backgroundColor: '#fff',
878
- borderWidth: 2,
1540
+ borderWidth: 1,
879
1541
  borderColor: '#e0e0e0',
880
- borderRadius: 12,
881
- padding: 16,
882
- fontSize: 17,
883
- minHeight: 120,
884
- textAlignVertical: 'top',
885
- fontWeight: '400'
1542
+ borderRadius: 8,
1543
+ maxHeight: 200
1544
+ },
1545
+ searchResultItem: {
1546
+ padding: 12,
1547
+ borderBottomWidth: 1,
1548
+ borderBottomColor: '#f0f0f0'
1549
+ },
1550
+ searchResultName: {
1551
+ fontSize: 14,
1552
+ fontWeight: '500',
1553
+ color: '#333',
1554
+ marginBottom: 2
1555
+ },
1556
+ searchResultType: {
1557
+ fontSize: 12,
1558
+ color: '#666',
1559
+ textTransform: 'capitalize'
1560
+ },
1561
+ locationsList: {
1562
+ marginTop: 8
1563
+ },
1564
+ locationsListTitle: {
1565
+ fontSize: 14,
1566
+ fontWeight: '600',
1567
+ color: '#333',
1568
+ marginBottom: 12,
1569
+ fontFamily: fontFamilies.phuduSemiBold
1570
+ },
1571
+ locationItem: {
1572
+ marginBottom: 8
1573
+ },
1574
+ locationItemContent: {
1575
+ flexDirection: 'row',
1576
+ alignItems: 'center',
1577
+ padding: 12,
1578
+ backgroundColor: '#F8F9FA',
1579
+ borderRadius: 8
1580
+ },
1581
+ locationItemDragHandle: {
1582
+ marginRight: 12
1583
+ },
1584
+ locationItemInfo: {
1585
+ flex: 1
1586
+ },
1587
+ locationItemHeader: {
1588
+ flexDirection: 'row',
1589
+ alignItems: 'center',
1590
+ marginBottom: 4
1591
+ },
1592
+ locationItemName: {
1593
+ fontSize: 14,
1594
+ fontWeight: '500',
1595
+ color: '#333',
1596
+ flex: 1
1597
+ },
1598
+ locationLabel: {
1599
+ backgroundColor: '#007AFF',
1600
+ paddingHorizontal: 6,
1601
+ paddingVertical: 2,
1602
+ borderRadius: 4,
1603
+ marginLeft: 8
1604
+ },
1605
+ locationLabelText: {
1606
+ fontSize: 10,
1607
+ fontWeight: '600',
1608
+ color: '#fff',
1609
+ textTransform: 'uppercase'
1610
+ },
1611
+ locationCoordinates: {
1612
+ fontSize: 12,
1613
+ color: '#666',
1614
+ fontFamily: 'monospace'
1615
+ },
1616
+ locationItemActions: {
1617
+ marginLeft: 8
1618
+ },
1619
+ locationItemButton: {
1620
+ width: 28,
1621
+ height: 28,
1622
+ borderRadius: 14,
1623
+ backgroundColor: '#F8F9FA',
1624
+ alignItems: 'center',
1625
+ justifyContent: 'center'
1626
+ },
1627
+ locationItemDivider: {
1628
+ height: 1,
1629
+ backgroundColor: '#E9ECEF',
1630
+ marginHorizontal: 12
886
1631
  }
887
1632
  });
888
1633
  export default /*#__PURE__*/React.memo(AccountSettingsScreen);