@oxyhq/services 5.3.11 → 5.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (213) hide show
  1. package/README.md +21 -0
  2. package/lib/commonjs/assets/assets/icons/OxyServices.tsx +67 -0
  3. package/lib/commonjs/assets/assets/icons/logo_OxyServices.svg +1 -0
  4. package/lib/commonjs/assets/icons/OxyServices.js +53 -0
  5. package/lib/commonjs/assets/icons/OxyServices.js.map +1 -0
  6. package/lib/commonjs/assets/icons/logo_OxyServices.svg +1 -0
  7. package/lib/commonjs/core/index.js +119 -23
  8. package/lib/commonjs/core/index.js.map +1 -1
  9. package/lib/commonjs/index.js +2 -0
  10. package/lib/commonjs/index.js.map +1 -1
  11. package/lib/commonjs/lib/sonner.js +15 -11
  12. package/lib/commonjs/lib/sonner.js.map +1 -1
  13. package/lib/commonjs/node/index.js +2 -0
  14. package/lib/commonjs/node/index.js.map +1 -1
  15. package/lib/commonjs/ui/components/GroupedItem.js +109 -0
  16. package/lib/commonjs/ui/components/GroupedItem.js.map +1 -0
  17. package/lib/commonjs/ui/components/GroupedSection.js +33 -0
  18. package/lib/commonjs/ui/components/GroupedSection.js.map +1 -0
  19. package/lib/commonjs/ui/components/OxyProvider.js +95 -112
  20. package/lib/commonjs/ui/components/OxyProvider.js.map +1 -1
  21. package/lib/commonjs/ui/components/ProfileCard.js +124 -0
  22. package/lib/commonjs/ui/components/ProfileCard.js.map +1 -0
  23. package/lib/commonjs/ui/components/QuickActions.js +87 -0
  24. package/lib/commonjs/ui/components/QuickActions.js.map +1 -0
  25. package/lib/commonjs/ui/components/Section.js +36 -0
  26. package/lib/commonjs/ui/components/Section.js.map +1 -0
  27. package/lib/commonjs/ui/components/SectionTitle.js +35 -0
  28. package/lib/commonjs/ui/components/SectionTitle.js.map +1 -0
  29. package/lib/commonjs/ui/components/bottomSheet/index.js +6 -6
  30. package/lib/commonjs/ui/components/index.js +97 -0
  31. package/lib/commonjs/ui/components/index.js.map +1 -0
  32. package/lib/commonjs/ui/navigation/OxyRouter.js +20 -3
  33. package/lib/commonjs/ui/navigation/OxyRouter.js.map +1 -1
  34. package/lib/commonjs/ui/screens/AccountCenterScreen.js +190 -207
  35. package/lib/commonjs/ui/screens/AccountCenterScreen.js.map +1 -1
  36. package/lib/commonjs/ui/screens/AccountManagementDemo.js +299 -0
  37. package/lib/commonjs/ui/screens/AccountManagementDemo.js.map +1 -0
  38. package/lib/commonjs/ui/screens/AccountOverviewScreen.js +669 -401
  39. package/lib/commonjs/ui/screens/AccountOverviewScreen.js.map +1 -1
  40. package/lib/commonjs/ui/screens/AccountSettingsScreen.js +695 -498
  41. package/lib/commonjs/ui/screens/AccountSettingsScreen.js.map +1 -1
  42. package/lib/commonjs/ui/screens/AccountSwitcherScreen.js +451 -488
  43. package/lib/commonjs/ui/screens/AccountSwitcherScreen.js.map +1 -1
  44. package/lib/commonjs/ui/screens/AppInfoScreen.js +498 -185
  45. package/lib/commonjs/ui/screens/AppInfoScreen.js.map +1 -1
  46. package/lib/commonjs/ui/screens/BillingManagementScreen.js +636 -0
  47. package/lib/commonjs/ui/screens/BillingManagementScreen.js.map +1 -0
  48. package/lib/commonjs/ui/screens/FileManagementScreen.js +2497 -0
  49. package/lib/commonjs/ui/screens/FileManagementScreen.js.map +1 -0
  50. package/lib/commonjs/ui/screens/PremiumSubscriptionScreen.js +1620 -0
  51. package/lib/commonjs/ui/screens/PremiumSubscriptionScreen.js.map +1 -0
  52. package/lib/commonjs/ui/screens/ProfileScreen.js +117 -13
  53. package/lib/commonjs/ui/screens/ProfileScreen.js.map +1 -1
  54. package/lib/commonjs/ui/screens/SessionManagementScreen.js.map +1 -1
  55. package/lib/commonjs/ui/screens/SignInScreen.js +1 -1
  56. package/lib/commonjs/ui/screens/SignUpScreen.js +1 -1
  57. package/lib/commonjs/utils/polyfills.js +42 -0
  58. package/lib/commonjs/utils/polyfills.js.map +1 -0
  59. package/lib/module/assets/assets/icons/OxyServices.tsx +67 -0
  60. package/lib/module/assets/assets/icons/logo_OxyServices.svg +1 -0
  61. package/lib/module/assets/icons/OxyServices.js +46 -0
  62. package/lib/module/assets/icons/OxyServices.js.map +1 -0
  63. package/lib/module/assets/icons/logo_OxyServices.svg +1 -0
  64. package/lib/module/core/index.js +119 -23
  65. package/lib/module/core/index.js.map +1 -1
  66. package/lib/module/index.js +3 -0
  67. package/lib/module/index.js.map +1 -1
  68. package/lib/module/lib/sonner.js +13 -1
  69. package/lib/module/lib/sonner.js.map +1 -1
  70. package/lib/module/node/index.js +3 -0
  71. package/lib/module/node/index.js.map +1 -1
  72. package/lib/module/ui/components/GroupedItem.js +104 -0
  73. package/lib/module/ui/components/GroupedItem.js.map +1 -0
  74. package/lib/module/ui/components/GroupedSection.js +28 -0
  75. package/lib/module/ui/components/GroupedSection.js.map +1 -0
  76. package/lib/module/ui/components/OxyProvider.js +97 -114
  77. package/lib/module/ui/components/OxyProvider.js.map +1 -1
  78. package/lib/module/ui/components/ProfileCard.js +119 -0
  79. package/lib/module/ui/components/ProfileCard.js.map +1 -0
  80. package/lib/module/ui/components/QuickActions.js +82 -0
  81. package/lib/module/ui/components/QuickActions.js.map +1 -0
  82. package/lib/module/ui/components/Section.js +31 -0
  83. package/lib/module/ui/components/Section.js.map +1 -0
  84. package/lib/module/ui/components/SectionTitle.js +30 -0
  85. package/lib/module/ui/components/SectionTitle.js.map +1 -0
  86. package/lib/module/ui/components/bottomSheet/index.js +2 -5
  87. package/lib/module/ui/components/bottomSheet/index.js.map +1 -1
  88. package/lib/module/ui/components/index.js +18 -0
  89. package/lib/module/ui/components/index.js.map +1 -0
  90. package/lib/module/ui/navigation/OxyRouter.js +20 -3
  91. package/lib/module/ui/navigation/OxyRouter.js.map +1 -1
  92. package/lib/module/ui/screens/AccountCenterScreen.js +191 -208
  93. package/lib/module/ui/screens/AccountCenterScreen.js.map +1 -1
  94. package/lib/module/ui/screens/AccountManagementDemo.js +296 -0
  95. package/lib/module/ui/screens/AccountManagementDemo.js.map +1 -0
  96. package/lib/module/ui/screens/AccountOverviewScreen.js +671 -403
  97. package/lib/module/ui/screens/AccountOverviewScreen.js.map +1 -1
  98. package/lib/module/ui/screens/AccountSettingsScreen.js +698 -501
  99. package/lib/module/ui/screens/AccountSettingsScreen.js.map +1 -1
  100. package/lib/module/ui/screens/AccountSwitcherScreen.js +450 -488
  101. package/lib/module/ui/screens/AccountSwitcherScreen.js.map +1 -1
  102. package/lib/module/ui/screens/AppInfoScreen.js +498 -186
  103. package/lib/module/ui/screens/AppInfoScreen.js.map +1 -1
  104. package/lib/module/ui/screens/BillingManagementScreen.js +631 -0
  105. package/lib/module/ui/screens/BillingManagementScreen.js.map +1 -0
  106. package/lib/module/ui/screens/FileManagementScreen.js +2492 -0
  107. package/lib/module/ui/screens/FileManagementScreen.js.map +1 -0
  108. package/lib/module/ui/screens/PremiumSubscriptionScreen.js +1615 -0
  109. package/lib/module/ui/screens/PremiumSubscriptionScreen.js.map +1 -0
  110. package/lib/module/ui/screens/ProfileScreen.js +118 -14
  111. package/lib/module/ui/screens/ProfileScreen.js.map +1 -1
  112. package/lib/module/ui/screens/SessionManagementScreen.js.map +1 -1
  113. package/lib/module/ui/screens/SignInScreen.js +1 -1
  114. package/lib/module/ui/screens/SignInScreen.js.map +1 -1
  115. package/lib/module/ui/screens/SignUpScreen.js +1 -1
  116. package/lib/module/ui/screens/SignUpScreen.js.map +1 -1
  117. package/lib/module/utils/polyfills.js +36 -0
  118. package/lib/module/utils/polyfills.js.map +1 -0
  119. package/lib/typescript/assets/icons/OxyServices.d.ts +29 -0
  120. package/lib/typescript/assets/icons/OxyServices.d.ts.map +1 -0
  121. package/lib/typescript/core/index.d.ts +26 -1
  122. package/lib/typescript/core/index.d.ts.map +1 -1
  123. package/lib/typescript/index.d.ts +1 -0
  124. package/lib/typescript/index.d.ts.map +1 -1
  125. package/lib/typescript/lib/sonner.d.ts +5 -1
  126. package/lib/typescript/lib/sonner.d.ts.map +1 -1
  127. package/lib/typescript/models/interfaces.d.ts +1 -2
  128. package/lib/typescript/models/interfaces.d.ts.map +1 -1
  129. package/lib/typescript/node/index.d.ts +1 -0
  130. package/lib/typescript/node/index.d.ts.map +1 -1
  131. package/lib/typescript/ui/components/GroupedItem.d.ts +17 -0
  132. package/lib/typescript/ui/components/GroupedItem.d.ts.map +1 -0
  133. package/lib/typescript/ui/components/GroupedSection.d.ts +19 -0
  134. package/lib/typescript/ui/components/GroupedSection.d.ts.map +1 -0
  135. package/lib/typescript/ui/components/OxyProvider.d.ts.map +1 -1
  136. package/lib/typescript/ui/components/ProfileCard.d.ts +20 -0
  137. package/lib/typescript/ui/components/ProfileCard.d.ts.map +1 -0
  138. package/lib/typescript/ui/components/QuickActions.d.ts +15 -0
  139. package/lib/typescript/ui/components/QuickActions.d.ts.map +1 -0
  140. package/lib/typescript/ui/components/Section.d.ts +11 -0
  141. package/lib/typescript/ui/components/Section.d.ts.map +1 -0
  142. package/lib/typescript/ui/components/SectionTitle.d.ts +9 -0
  143. package/lib/typescript/ui/components/SectionTitle.d.ts.map +1 -0
  144. package/lib/typescript/ui/components/bottomSheet/index.d.ts +3 -2
  145. package/lib/typescript/ui/components/bottomSheet/index.d.ts.map +1 -1
  146. package/lib/typescript/ui/components/index.d.ts +13 -0
  147. package/lib/typescript/ui/components/index.d.ts.map +1 -0
  148. package/lib/typescript/ui/navigation/OxyRouter.d.ts.map +1 -1
  149. package/lib/typescript/ui/navigation/types.d.ts +8 -0
  150. package/lib/typescript/ui/navigation/types.d.ts.map +1 -1
  151. package/lib/typescript/ui/screens/AccountCenterScreen.d.ts.map +1 -1
  152. package/lib/typescript/ui/screens/AccountManagementDemo.d.ts +8 -0
  153. package/lib/typescript/ui/screens/AccountManagementDemo.d.ts.map +1 -0
  154. package/lib/typescript/ui/screens/AccountOverviewScreen.d.ts.map +1 -1
  155. package/lib/typescript/ui/screens/AccountSettingsScreen.d.ts +1 -4
  156. package/lib/typescript/ui/screens/AccountSettingsScreen.d.ts.map +1 -1
  157. package/lib/typescript/ui/screens/AccountSwitcherScreen.d.ts.map +1 -1
  158. package/lib/typescript/ui/screens/AppInfoScreen.d.ts.map +1 -1
  159. package/lib/typescript/ui/screens/BillingManagementScreen.d.ts +5 -0
  160. package/lib/typescript/ui/screens/BillingManagementScreen.d.ts.map +1 -0
  161. package/lib/typescript/ui/screens/FileManagementScreen.d.ts +8 -0
  162. package/lib/typescript/ui/screens/FileManagementScreen.d.ts.map +1 -0
  163. package/lib/typescript/ui/screens/PremiumSubscriptionScreen.d.ts +5 -0
  164. package/lib/typescript/ui/screens/PremiumSubscriptionScreen.d.ts.map +1 -0
  165. package/lib/typescript/ui/screens/ProfileScreen.d.ts.map +1 -1
  166. package/lib/typescript/ui/screens/SessionManagementScreen.d.ts.map +1 -1
  167. package/lib/typescript/utils/polyfills.d.ts +6 -0
  168. package/lib/typescript/utils/polyfills.d.ts.map +1 -0
  169. package/package.json +11 -3
  170. package/src/__tests__/polyfills.test.ts +30 -0
  171. package/src/__tests__/setup.ts +43 -0
  172. package/src/__tests__/ui/screens/AccountSettingsScreen.test.tsx +8 -8
  173. package/src/assets/icons/OxyServices.tsx +67 -0
  174. package/src/assets/icons/logo_OxyServices.svg +1 -0
  175. package/src/core/index.ts +127 -19
  176. package/src/index.ts +3 -0
  177. package/src/lib/sonner.ts +10 -1
  178. package/src/models/interfaces.ts +1 -2
  179. package/src/node/index.ts +3 -0
  180. package/src/ui/components/GroupedItem.tsx +118 -0
  181. package/src/ui/components/GroupedSection.tsx +45 -0
  182. package/src/ui/components/OxyProvider.tsx +95 -120
  183. package/src/ui/components/ProfileCard.tsx +129 -0
  184. package/src/ui/components/QuickActions.tsx +90 -0
  185. package/src/ui/components/Section.tsx +37 -0
  186. package/src/ui/components/SectionTitle.tsx +31 -0
  187. package/src/ui/components/bottomSheet/index.tsx +13 -11
  188. package/src/ui/components/index.ts +15 -0
  189. package/src/ui/navigation/OxyRouter.tsx +20 -3
  190. package/src/ui/navigation/types.ts +10 -1
  191. package/src/ui/screens/AccountCenterScreen.tsx +188 -159
  192. package/src/ui/screens/AccountManagementDemo.tsx +297 -0
  193. package/src/ui/screens/AccountOverviewScreen.tsx +474 -310
  194. package/src/ui/screens/AccountSettingsScreen.tsx +648 -463
  195. package/src/ui/screens/AccountSwitcherScreen.tsx +385 -449
  196. package/src/ui/screens/AppInfoScreen.tsx +571 -140
  197. package/src/ui/screens/BillingManagementScreen.tsx +589 -0
  198. package/src/ui/screens/FileManagementScreen.tsx +2513 -0
  199. package/src/ui/screens/PremiumSubscriptionScreen.tsx +1628 -0
  200. package/src/ui/screens/ProfileScreen.tsx +101 -7
  201. package/src/ui/screens/SessionManagementScreen.tsx +1 -0
  202. package/src/ui/screens/SignInScreen.tsx +1 -1
  203. package/src/ui/screens/SignUpScreen.tsx +1 -1
  204. package/src/utils/polyfills.ts +34 -0
  205. package/lib/commonjs/lib/sonner.web.js +0 -17
  206. package/lib/commonjs/lib/sonner.web.js.map +0 -1
  207. package/lib/module/lib/sonner.web.js +0 -4
  208. package/lib/module/lib/sonner.web.js.map +0 -1
  209. package/lib/typescript/__tests__/ui/screens/AccountSettingsScreen.test.d.ts +0 -2
  210. package/lib/typescript/__tests__/ui/screens/AccountSettingsScreen.test.d.ts.map +0 -1
  211. package/lib/typescript/lib/sonner.web.d.ts +0 -2
  212. package/lib/typescript/lib/sonner.web.d.ts.map +0 -1
  213. package/src/lib/sonner.web.ts +0 -1
@@ -1,174 +1,389 @@
1
1
  "use strict";
2
2
 
3
- import React, { useEffect, useState } from 'react';
4
- import { View, Text, TextInput, TouchableOpacity, StyleSheet, ActivityIndicator, ScrollView, Alert, Switch } from 'react-native';
3
+ import React, { useState, useEffect, useRef } from 'react';
4
+ import { View, Text, TouchableOpacity, StyleSheet, ActivityIndicator, ScrollView, Alert, TextInput, Animated } from 'react-native';
5
5
  import { useOxy } from '../context/OxyContext';
6
6
  import Avatar from '../components/Avatar';
7
+ import OxyIcon from '../components/icon/OxyIcon';
8
+ import { Ionicons } from '@expo/vector-icons';
7
9
  import { toast } from '../../lib/sonner';
8
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
10
+ import { fontFamilies } from '../styles/fonts';
11
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
9
12
  const AccountSettingsScreen = ({
10
- goBack,
13
+ onClose,
11
14
  theme,
12
- activeTab = 'profile'
15
+ goBack,
16
+ navigate
13
17
  }) => {
14
18
  const {
15
19
  user,
16
20
  oxyServices,
17
21
  isLoading: authLoading
18
22
  } = useOxy();
19
- const [currentTab, setCurrentTab] = useState(activeTab);
20
23
  const [isLoading, setIsLoading] = useState(false);
21
- const [errorMessage, setErrorMessage] = useState('');
22
- const [successMessage, setSuccessMessage] = useState('');
24
+ const [isSaving, setIsSaving] = useState(false);
25
+
26
+ // Animation refs
27
+ const saveButtonScale = useRef(new Animated.Value(1)).current;
23
28
 
24
- // Profile form state
29
+ // Form state
30
+ const [displayName, setDisplayName] = useState('');
25
31
  const [username, setUsername] = useState('');
26
32
  const [email, setEmail] = useState('');
27
33
  const [bio, setBio] = useState('');
34
+ const [location, setLocation] = useState('');
35
+ const [website, setWebsite] = useState('');
28
36
  const [avatarUrl, setAvatarUrl] = useState('');
29
37
 
30
- // Password form state
31
- const [currentPassword, setCurrentPassword] = useState('');
32
- const [newPassword, setNewPassword] = useState('');
33
- const [confirmPassword, setConfirmPassword] = useState('');
38
+ // Editing states
39
+ const [editingField, setEditingField] = useState(null);
34
40
 
35
- // Notification preferences
36
- const [emailNotifications, setEmailNotifications] = useState(true);
37
- const [pushNotifications, setPushNotifications] = useState(true);
38
-
39
- // Theme and styling
41
+ // Temporary input states for inline editing
42
+ const [tempDisplayName, setTempDisplayName] = useState('');
43
+ const [tempUsername, setTempUsername] = useState('');
44
+ const [tempEmail, setTempEmail] = useState('');
45
+ const [tempBio, setTempBio] = useState('');
46
+ const [tempLocation, setTempLocation] = useState('');
47
+ const [tempWebsite, setTempWebsite] = useState('');
40
48
  const isDarkTheme = theme === 'dark';
41
- const textColor = isDarkTheme ? '#FFFFFF' : '#000000';
42
- const backgroundColor = isDarkTheme ? '#121212' : '#FFFFFF';
43
- const secondaryBackgroundColor = isDarkTheme ? '#222222' : '#F5F5F5';
44
- const inputBackgroundColor = isDarkTheme ? '#333333' : '#F5F5F5';
45
- const borderColor = isDarkTheme ? '#444444' : '#E0E0E0';
46
- const primaryColor = '#0066CC';
47
- const placeholderColor = isDarkTheme ? '#AAAAAA' : '#999999';
49
+ const backgroundColor = isDarkTheme ? '#121212' : '#f2f2f2';
50
+ const primaryColor = '#007AFF';
51
+
52
+ // Animation functions
53
+ const animateSaveButton = toValue => {
54
+ Animated.spring(saveButtonScale, {
55
+ toValue,
56
+ useNativeDriver: true,
57
+ tension: 150,
58
+ friction: 8
59
+ }).start();
60
+ };
48
61
 
49
62
  // Load user data
50
63
  useEffect(() => {
51
64
  if (user) {
65
+ const userDisplayName = typeof user.name === 'string' ? user.name : user.name?.full || user.name?.first || '';
66
+ setDisplayName(userDisplayName);
52
67
  setUsername(user.username || '');
53
68
  setEmail(user.email || '');
54
69
  setBio(user.bio || '');
70
+ setLocation(user.location || '');
71
+ setWebsite(user.website || '');
55
72
  setAvatarUrl(user.avatar?.url || '');
56
73
  }
57
74
  }, [user]);
58
- const validateEmail = email => {
59
- const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
60
- return emailRegex.test(email);
61
- };
62
- const handleSaveProfile = async () => {
63
- // Validate inputs
64
- if (!username) {
65
- setErrorMessage('Username is required');
66
- return;
67
- }
68
- if (email && !validateEmail(email)) {
69
- setErrorMessage('Please enter a valid email address');
70
- return;
71
- }
75
+ const handleSave = async () => {
76
+ if (!user) return;
72
77
  try {
73
- setIsLoading(true);
74
- setErrorMessage('');
75
- setSuccessMessage('');
78
+ setIsSaving(true);
79
+ animateSaveButton(0.95); // Scale down slightly for animation
76
80
 
77
- // Prepare updates object
78
81
  const updates = {
79
82
  username,
80
- bio
83
+ email,
84
+ bio,
85
+ location,
86
+ website
81
87
  };
82
- if (email) {
83
- updates.email = email;
88
+
89
+ // Handle name field
90
+ if (displayName) {
91
+ updates.name = displayName;
84
92
  }
85
93
 
86
- // Only include avatar if it's been changed
87
- if (avatarUrl !== user?.avatar?.url) {
94
+ // Handle avatar
95
+ if (avatarUrl !== user.avatar?.url) {
88
96
  updates.avatar = {
89
97
  url: avatarUrl
90
98
  };
91
99
  }
92
-
93
- // Call API to update user
94
- await oxyServices.updateUser(user.id, updates);
100
+ await oxyServices.updateProfile(updates);
95
101
  toast.success('Profile updated successfully');
96
- } catch (error) {
97
- toast.error(error.message || 'Failed to update profile');
98
- } finally {
99
- setIsLoading(false);
100
- }
101
- };
102
- const handleChangePassword = async () => {
103
- // Validate inputs
104
- if (!currentPassword || !newPassword || !confirmPassword) {
105
- toast.error('Please fill in all password fields');
106
- return;
107
- }
108
- if (newPassword !== confirmPassword) {
109
- toast.error('New passwords do not match');
110
- return;
111
- }
112
- if (newPassword.length < 8) {
113
- toast.error('Password must be at least 8 characters long');
114
- return;
115
- }
116
- try {
117
- setIsLoading(true);
118
- setErrorMessage('');
119
- setSuccessMessage('');
120
-
121
- // Call API to update password
122
- await oxyServices.updateUser(user.id, {
123
- currentPassword,
124
- password: newPassword
125
- });
102
+ animateSaveButton(1); // Scale back to normal
126
103
 
127
- // Clear form fields after successful update
128
- setCurrentPassword('');
129
- setNewPassword('');
130
- setConfirmPassword('');
131
- toast.success('Password updated successfully');
132
- } catch (error) {
133
- toast.error(error.message || 'Failed to update password');
134
- } finally {
135
- setIsLoading(false);
136
- }
137
- };
138
- const handleSaveNotifications = async () => {
139
- try {
140
- setIsLoading(true);
141
- setErrorMessage('');
142
- setSuccessMessage('');
143
-
144
- // Call API to update notification preferences
145
- await oxyServices.updateUser(user.id, {
146
- notificationPreferences: {
147
- email: emailNotifications,
148
- push: pushNotifications
149
- }
150
- });
151
- toast.success('Notification preferences updated successfully');
104
+ if (onClose) {
105
+ onClose();
106
+ } else if (goBack) {
107
+ goBack();
108
+ }
152
109
  } catch (error) {
153
- toast.error(error.message || 'Failed to update notification preferences');
110
+ toast.error(error.message || 'Failed to update profile');
111
+ animateSaveButton(1); // Scale back to normal on error
154
112
  } finally {
155
- setIsLoading(false);
113
+ setIsSaving(false);
156
114
  }
157
115
  };
158
116
  const handleAvatarUpdate = () => {
159
- // In a real app, this would open an image picker
160
- // For now, we'll use a mock URL to demonstrate the concept
161
- Alert.alert('Update Avatar', 'This would open an image picker in a real app. For now, we\'ll use a mock URL.', [{
117
+ Alert.alert('Update Avatar', 'Choose how you want to update your profile picture', [{
162
118
  text: 'Cancel',
163
119
  style: 'cancel'
164
120
  }, {
165
121
  text: 'Use Mock URL',
166
122
  onPress: () => {
167
- const mockUrl = `https://ui-avatars.com/api/?name=${username}&background=random`;
123
+ const mockUrl = `https://ui-avatars.com/api/?name=${displayName || username}&background=random`;
168
124
  setAvatarUrl(mockUrl);
169
125
  }
126
+ }, {
127
+ text: 'Remove Avatar',
128
+ onPress: () => setAvatarUrl(''),
129
+ style: 'destructive'
170
130
  }]);
171
131
  };
132
+ const startEditing = (type, currentValue) => {
133
+ switch (type) {
134
+ case 'displayName':
135
+ setTempDisplayName(currentValue);
136
+ break;
137
+ case 'username':
138
+ setTempUsername(currentValue);
139
+ break;
140
+ case 'email':
141
+ setTempEmail(currentValue);
142
+ break;
143
+ case 'bio':
144
+ setTempBio(currentValue);
145
+ break;
146
+ case 'location':
147
+ setTempLocation(currentValue);
148
+ break;
149
+ case 'website':
150
+ setTempWebsite(currentValue);
151
+ break;
152
+ }
153
+ setEditingField(type);
154
+ };
155
+ const saveField = type => {
156
+ animateSaveButton(0.95); // Scale down slightly for animation
157
+
158
+ switch (type) {
159
+ case 'displayName':
160
+ setDisplayName(tempDisplayName);
161
+ break;
162
+ case 'username':
163
+ setUsername(tempUsername);
164
+ break;
165
+ case 'email':
166
+ setEmail(tempEmail);
167
+ break;
168
+ case 'bio':
169
+ setBio(tempBio);
170
+ break;
171
+ case 'location':
172
+ setLocation(tempLocation);
173
+ break;
174
+ case 'website':
175
+ setWebsite(tempWebsite);
176
+ break;
177
+ }
178
+
179
+ // Brief delay for animation, then reset and close editing
180
+ setTimeout(() => {
181
+ animateSaveButton(1);
182
+ setEditingField(null);
183
+ }, 150);
184
+ };
185
+ const cancelEditing = () => {
186
+ setEditingField(null);
187
+ };
188
+ const getFieldLabel = type => {
189
+ const labels = {
190
+ displayName: 'Display Name',
191
+ username: 'Username',
192
+ email: 'Email',
193
+ bio: 'Bio',
194
+ location: 'Location',
195
+ website: 'Website'
196
+ };
197
+ return labels[type] || 'Field';
198
+ };
199
+ const getFieldIcon = type => {
200
+ const icons = {
201
+ displayName: {
202
+ name: 'person',
203
+ color: '#007AFF'
204
+ },
205
+ username: {
206
+ name: 'at',
207
+ color: '#5856D6'
208
+ },
209
+ email: {
210
+ name: 'mail',
211
+ color: '#FF9500'
212
+ },
213
+ bio: {
214
+ name: 'document-text',
215
+ color: '#34C759'
216
+ },
217
+ location: {
218
+ name: 'location',
219
+ color: '#FF3B30'
220
+ },
221
+ website: {
222
+ name: 'link',
223
+ color: '#32D74B'
224
+ }
225
+ };
226
+ return icons[type] || {
227
+ name: 'person',
228
+ color: '#007AFF'
229
+ };
230
+ };
231
+ const renderEditingField = type => {
232
+ const fieldConfig = {
233
+ displayName: {
234
+ label: 'Display Name',
235
+ value: displayName,
236
+ placeholder: 'Enter your display name',
237
+ icon: 'person',
238
+ color: '#007AFF',
239
+ multiline: false,
240
+ keyboardType: 'default'
241
+ },
242
+ username: {
243
+ label: 'Username',
244
+ value: username,
245
+ placeholder: 'Choose a username',
246
+ icon: 'at',
247
+ color: '#5856D6',
248
+ multiline: false,
249
+ keyboardType: 'default'
250
+ },
251
+ email: {
252
+ label: 'Email',
253
+ value: email,
254
+ placeholder: 'Enter your email address',
255
+ icon: 'mail',
256
+ color: '#FF9500',
257
+ multiline: false,
258
+ keyboardType: 'email-address'
259
+ },
260
+ bio: {
261
+ label: 'Bio',
262
+ value: bio,
263
+ placeholder: 'Tell people about yourself...',
264
+ icon: 'document-text',
265
+ color: '#34C759',
266
+ multiline: true,
267
+ keyboardType: 'default'
268
+ },
269
+ location: {
270
+ label: 'Location',
271
+ value: location,
272
+ placeholder: 'Enter your location',
273
+ icon: 'location',
274
+ color: '#FF3B30',
275
+ multiline: false,
276
+ keyboardType: 'default'
277
+ },
278
+ website: {
279
+ label: 'Website',
280
+ value: website,
281
+ placeholder: 'Enter your website URL',
282
+ icon: 'link',
283
+ color: '#32D74B',
284
+ multiline: false,
285
+ keyboardType: 'url'
286
+ }
287
+ };
288
+ const config = fieldConfig[type];
289
+ if (!config) return null;
290
+ const tempValue = (() => {
291
+ switch (type) {
292
+ case 'displayName':
293
+ return tempDisplayName;
294
+ case 'username':
295
+ return tempUsername;
296
+ case 'email':
297
+ return tempEmail;
298
+ case 'bio':
299
+ return tempBio;
300
+ case 'location':
301
+ return tempLocation;
302
+ case 'website':
303
+ return tempWebsite;
304
+ default:
305
+ return '';
306
+ }
307
+ })();
308
+ const setTempValue = text => {
309
+ switch (type) {
310
+ case 'displayName':
311
+ setTempDisplayName(text);
312
+ break;
313
+ case 'username':
314
+ setTempUsername(text);
315
+ break;
316
+ case 'email':
317
+ setTempEmail(text);
318
+ break;
319
+ case 'bio':
320
+ setTempBio(text);
321
+ break;
322
+ case 'location':
323
+ setTempLocation(text);
324
+ break;
325
+ case 'website':
326
+ setTempWebsite(text);
327
+ break;
328
+ }
329
+ };
330
+ return /*#__PURE__*/_jsx(View, {
331
+ style: styles.editingFieldContainer,
332
+ children: /*#__PURE__*/_jsx(View, {
333
+ style: styles.editingFieldContent,
334
+ children: /*#__PURE__*/_jsxs(View, {
335
+ style: styles.newValueSection,
336
+ children: [/*#__PURE__*/_jsx(Text, {
337
+ style: styles.editingFieldLabel,
338
+ children: `Enter ${config.label.toLowerCase()}:`
339
+ }), /*#__PURE__*/_jsx(TextInput, {
340
+ style: [config.multiline ? styles.editingFieldTextArea : styles.editingFieldInput, {
341
+ backgroundColor: isDarkTheme ? '#333' : '#fff',
342
+ color: isDarkTheme ? '#fff' : '#000',
343
+ borderColor: primaryColor
344
+ }],
345
+ value: tempValue,
346
+ onChangeText: setTempValue,
347
+ placeholder: config.placeholder,
348
+ placeholderTextColor: isDarkTheme ? '#aaa' : '#999',
349
+ multiline: config.multiline,
350
+ numberOfLines: config.multiline ? 6 : 1,
351
+ keyboardType: config.keyboardType,
352
+ autoFocus: true,
353
+ selectionColor: primaryColor
354
+ })]
355
+ })
356
+ })
357
+ });
358
+ };
359
+ const renderField = (type, label, value, placeholder, icon, iconColor, multiline = false, keyboardType = 'default', isFirst = false, isLast = false) => {
360
+ const itemStyles = [styles.settingItem, isFirst && styles.firstSettingItem, isLast && styles.lastSettingItem];
361
+ return /*#__PURE__*/_jsxs(TouchableOpacity, {
362
+ style: itemStyles,
363
+ onPress: () => startEditing(type, value),
364
+ children: [/*#__PURE__*/_jsxs(View, {
365
+ style: styles.settingInfo,
366
+ children: [/*#__PURE__*/_jsx(OxyIcon, {
367
+ name: icon,
368
+ size: 20,
369
+ color: iconColor,
370
+ style: styles.settingIcon
371
+ }), /*#__PURE__*/_jsxs(View, {
372
+ children: [/*#__PURE__*/_jsx(Text, {
373
+ style: styles.settingLabel,
374
+ children: label
375
+ }), /*#__PURE__*/_jsx(Text, {
376
+ style: styles.settingDescription,
377
+ children: value || placeholder
378
+ })]
379
+ })]
380
+ }), /*#__PURE__*/_jsx(OxyIcon, {
381
+ name: "chevron-forward",
382
+ size: 16,
383
+ color: "#ccc"
384
+ })]
385
+ });
386
+ };
172
387
  if (authLoading || !user) {
173
388
  return /*#__PURE__*/_jsx(View, {
174
389
  style: [styles.container, {
@@ -181,452 +396,434 @@ const AccountSettingsScreen = ({
181
396
  })
182
397
  });
183
398
  }
184
- const renderProfileTab = () => /*#__PURE__*/_jsxs(View, {
185
- style: styles.tabContent,
186
- children: [/*#__PURE__*/_jsxs(View, {
187
- style: styles.avatarSection,
188
- children: [/*#__PURE__*/_jsx(Avatar, {
189
- uri: avatarUrl,
190
- name: username,
191
- size: 100,
192
- theme: theme
193
- }), /*#__PURE__*/_jsx(TouchableOpacity, {
194
- style: [styles.changeAvatarButton, {
195
- backgroundColor: primaryColor
196
- }],
197
- onPress: handleAvatarUpdate,
198
- children: /*#__PURE__*/_jsx(Text, {
199
- style: styles.changeAvatarText,
200
- children: "Change Avatar"
201
- })
202
- })]
203
- }), /*#__PURE__*/_jsxs(View, {
204
- style: styles.inputContainer,
205
- children: [/*#__PURE__*/_jsx(Text, {
206
- style: [styles.label, {
207
- color: textColor
208
- }],
209
- children: "Username"
210
- }), /*#__PURE__*/_jsx(TextInput, {
211
- style: [styles.input, {
212
- backgroundColor: inputBackgroundColor,
213
- borderColor,
214
- color: textColor
215
- }],
216
- placeholder: "Enter your username",
217
- placeholderTextColor: placeholderColor,
218
- value: username,
219
- onChangeText: setUsername,
220
- testID: "username-input"
221
- })]
222
- }), /*#__PURE__*/_jsxs(View, {
223
- style: styles.inputContainer,
224
- children: [/*#__PURE__*/_jsx(Text, {
225
- style: [styles.label, {
226
- color: textColor
227
- }],
228
- children: "Email"
229
- }), /*#__PURE__*/_jsx(TextInput, {
230
- style: [styles.input, {
231
- backgroundColor: inputBackgroundColor,
232
- borderColor,
233
- color: textColor
234
- }],
235
- placeholder: "Enter your email",
236
- placeholderTextColor: placeholderColor,
237
- value: email,
238
- onChangeText: setEmail,
239
- keyboardType: "email-address",
240
- testID: "email-input"
241
- })]
242
- }), /*#__PURE__*/_jsxs(View, {
243
- style: styles.inputContainer,
244
- children: [/*#__PURE__*/_jsx(Text, {
245
- style: [styles.label, {
246
- color: textColor
247
- }],
248
- children: "Bio"
249
- }), /*#__PURE__*/_jsx(TextInput, {
250
- style: [styles.textArea, {
251
- backgroundColor: inputBackgroundColor,
252
- borderColor,
253
- color: textColor
254
- }],
255
- placeholder: "Tell us about yourself",
256
- placeholderTextColor: placeholderColor,
257
- value: bio,
258
- onChangeText: setBio,
259
- multiline: true,
260
- numberOfLines: 4,
261
- testID: "bio-input"
262
- })]
263
- }), /*#__PURE__*/_jsx(TouchableOpacity, {
264
- style: [styles.saveButton, {
265
- backgroundColor: primaryColor,
266
- opacity: isLoading ? 0.7 : 1
267
- }],
268
- onPress: handleSaveProfile,
269
- disabled: isLoading,
270
- testID: "save-profile-button",
271
- children: isLoading ? /*#__PURE__*/_jsx(ActivityIndicator, {
272
- color: "#FFFFFF",
273
- size: "small"
274
- }) : /*#__PURE__*/_jsx(Text, {
275
- style: styles.saveButtonText,
276
- children: "Save Profile"
277
- })
278
- })]
279
- });
280
- const renderPasswordTab = () => /*#__PURE__*/_jsxs(View, {
281
- style: styles.tabContent,
282
- children: [/*#__PURE__*/_jsxs(View, {
283
- style: styles.inputContainer,
284
- children: [/*#__PURE__*/_jsx(Text, {
285
- style: [styles.label, {
286
- color: textColor
287
- }],
288
- children: "Current Password"
289
- }), /*#__PURE__*/_jsx(TextInput, {
290
- style: [styles.input, {
291
- backgroundColor: inputBackgroundColor,
292
- borderColor,
293
- color: textColor
294
- }],
295
- placeholder: "Enter your current password",
296
- placeholderTextColor: placeholderColor,
297
- value: currentPassword,
298
- onChangeText: setCurrentPassword,
299
- secureTextEntry: true,
300
- testID: "current-password-input"
301
- })]
302
- }), /*#__PURE__*/_jsxs(View, {
303
- style: styles.inputContainer,
304
- children: [/*#__PURE__*/_jsx(Text, {
305
- style: [styles.label, {
306
- color: textColor
307
- }],
308
- children: "New Password"
309
- }), /*#__PURE__*/_jsx(TextInput, {
310
- style: [styles.input, {
311
- backgroundColor: inputBackgroundColor,
312
- borderColor,
313
- color: textColor
314
- }],
315
- placeholder: "Enter your new password",
316
- placeholderTextColor: placeholderColor,
317
- value: newPassword,
318
- onChangeText: setNewPassword,
319
- secureTextEntry: true,
320
- testID: "new-password-input"
321
- }), /*#__PURE__*/_jsx(Text, {
322
- style: [styles.passwordHint, {
323
- color: isDarkTheme ? '#AAAAAA' : '#666666'
324
- }],
325
- children: "Password must be at least 8 characters long"
326
- })]
327
- }), /*#__PURE__*/_jsxs(View, {
328
- style: styles.inputContainer,
329
- children: [/*#__PURE__*/_jsx(Text, {
330
- style: [styles.label, {
331
- color: textColor
332
- }],
333
- children: "Confirm New Password"
334
- }), /*#__PURE__*/_jsx(TextInput, {
335
- style: [styles.input, {
336
- backgroundColor: inputBackgroundColor,
337
- borderColor,
338
- color: textColor
339
- }],
340
- placeholder: "Confirm your new password",
341
- placeholderTextColor: placeholderColor,
342
- value: confirmPassword,
343
- onChangeText: setConfirmPassword,
344
- secureTextEntry: true,
345
- testID: "confirm-password-input"
346
- })]
347
- }), /*#__PURE__*/_jsx(TouchableOpacity, {
348
- style: [styles.saveButton, {
349
- backgroundColor: primaryColor,
350
- opacity: isLoading ? 0.7 : 1
351
- }],
352
- onPress: handleChangePassword,
353
- disabled: isLoading,
354
- testID: "change-password-button",
355
- children: isLoading ? /*#__PURE__*/_jsx(ActivityIndicator, {
356
- color: "#FFFFFF",
357
- size: "small"
358
- }) : /*#__PURE__*/_jsx(Text, {
359
- style: styles.saveButtonText,
360
- children: "Change Password"
361
- })
362
- })]
363
- });
364
- const renderNotificationsTab = () => /*#__PURE__*/_jsxs(View, {
365
- style: styles.tabContent,
366
- children: [/*#__PURE__*/_jsxs(View, {
367
- style: styles.settingRow,
368
- children: [/*#__PURE__*/_jsx(Text, {
369
- style: [styles.settingLabel, {
370
- color: textColor
371
- }],
372
- children: "Email Notifications"
373
- }), /*#__PURE__*/_jsx(Switch, {
374
- value: emailNotifications,
375
- onValueChange: setEmailNotifications,
376
- trackColor: {
377
- false: '#767577',
378
- true: primaryColor
379
- },
380
- thumbColor: "#f4f3f4",
381
- testID: "email-notifications-switch"
382
- })]
383
- }), /*#__PURE__*/_jsxs(View, {
384
- style: styles.settingRow,
385
- children: [/*#__PURE__*/_jsx(Text, {
386
- style: [styles.settingLabel, {
387
- color: textColor
388
- }],
389
- children: "Push Notifications"
390
- }), /*#__PURE__*/_jsx(Switch, {
391
- value: pushNotifications,
392
- onValueChange: setPushNotifications,
393
- trackColor: {
394
- false: '#767577',
395
- true: primaryColor
396
- },
397
- thumbColor: "#f4f3f4",
398
- testID: "push-notifications-switch"
399
- })]
400
- }), /*#__PURE__*/_jsx(TouchableOpacity, {
401
- style: [styles.saveButton, {
402
- backgroundColor: primaryColor,
403
- opacity: isLoading ? 0.7 : 1
404
- }],
405
- onPress: handleSaveNotifications,
406
- disabled: isLoading,
407
- testID: "save-notifications-button",
408
- children: isLoading ? /*#__PURE__*/_jsx(ActivityIndicator, {
409
- color: "#FFFFFF",
410
- size: "small"
411
- }) : /*#__PURE__*/_jsx(Text, {
412
- style: styles.saveButtonText,
413
- children: "Save Preferences"
414
- })
415
- })]
416
- });
417
- return /*#__PURE__*/_jsx(View, {
399
+ return /*#__PURE__*/_jsxs(View, {
418
400
  style: [styles.container, {
419
401
  backgroundColor
420
402
  }],
421
- children: /*#__PURE__*/_jsxs(ScrollView, {
422
- style: styles.scrollView,
423
- contentContainerStyle: styles.scrollContainer,
424
- children: [/*#__PURE__*/_jsxs(View, {
425
- style: styles.header,
426
- children: [/*#__PURE__*/_jsx(TouchableOpacity, {
427
- style: styles.backButton,
428
- onPress: goBack,
429
- children: /*#__PURE__*/_jsx(Text, {
430
- style: [styles.backButtonText, {
431
- color: primaryColor
432
- }],
433
- children: "Back"
434
- })
435
- }), /*#__PURE__*/_jsx(Text, {
436
- style: [styles.title, {
437
- color: textColor
438
- }],
439
- children: "Account Settings"
403
+ children: [/*#__PURE__*/_jsx(View, {
404
+ style: styles.header,
405
+ children: editingField ? /*#__PURE__*/_jsxs(View, {
406
+ style: styles.editingHeader,
407
+ children: [/*#__PURE__*/_jsxs(View, {
408
+ style: styles.editingHeaderTop,
409
+ children: [/*#__PURE__*/_jsx(TouchableOpacity, {
410
+ style: styles.cancelButton,
411
+ onPress: cancelEditing,
412
+ children: /*#__PURE__*/_jsx(Ionicons, {
413
+ name: "close",
414
+ size: 24,
415
+ color: "#666"
416
+ })
417
+ }), /*#__PURE__*/_jsx(Animated.View, {
418
+ style: {
419
+ transform: [{
420
+ scale: saveButtonScale
421
+ }]
422
+ },
423
+ children: /*#__PURE__*/_jsx(TouchableOpacity, {
424
+ style: [styles.saveHeaderButton, {
425
+ opacity: isSaving ? 0.7 : 1,
426
+ backgroundColor: editingField ? getFieldIcon(editingField).color : '#007AFF'
427
+ }],
428
+ onPress: () => saveField(editingField),
429
+ disabled: isSaving,
430
+ children: isSaving ? /*#__PURE__*/_jsx(ActivityIndicator, {
431
+ size: "small",
432
+ color: "#fff"
433
+ }) : /*#__PURE__*/_jsx(Text, {
434
+ style: styles.saveButtonText,
435
+ children: "Save"
436
+ })
437
+ })
438
+ })]
440
439
  }), /*#__PURE__*/_jsx(View, {
441
- style: styles.backButtonPlaceholder
440
+ style: styles.editingHeaderBottom,
441
+ children: /*#__PURE__*/_jsxs(View, {
442
+ style: styles.headerTitleWithIcon,
443
+ children: [/*#__PURE__*/_jsx(OxyIcon, {
444
+ name: getFieldIcon(editingField).name,
445
+ size: 50,
446
+ color: getFieldIcon(editingField).color,
447
+ style: styles.headerIcon
448
+ }), /*#__PURE__*/_jsx(Text, {
449
+ style: styles.headerTitleLarge,
450
+ children: getFieldLabel(editingField)
451
+ })]
452
+ })
442
453
  })]
443
- }), /*#__PURE__*/_jsxs(View, {
444
- style: [styles.tabsContainer, {
445
- borderColor
446
- }],
454
+ }) : /*#__PURE__*/_jsxs(View, {
455
+ style: styles.normalHeader,
447
456
  children: [/*#__PURE__*/_jsx(TouchableOpacity, {
448
- style: [styles.tabButton, currentTab === 'profile' && [styles.activeTabButton, {
449
- borderColor: primaryColor
450
- }]],
451
- onPress: () => setCurrentTab('profile'),
452
- children: /*#__PURE__*/_jsx(Text, {
453
- style: [styles.tabButtonText, {
454
- color: currentTab === 'profile' ? primaryColor : textColor
455
- }],
456
- children: "Profile"
457
- })
458
- }), /*#__PURE__*/_jsx(TouchableOpacity, {
459
- style: [styles.tabButton, currentTab === 'password' && [styles.activeTabButton, {
460
- borderColor: primaryColor
461
- }]],
462
- onPress: () => setCurrentTab('password'),
463
- children: /*#__PURE__*/_jsx(Text, {
464
- style: [styles.tabButtonText, {
465
- color: currentTab === 'password' ? primaryColor : textColor
466
- }],
467
- children: "Password"
457
+ style: styles.cancelButton,
458
+ onPress: onClose || goBack,
459
+ children: /*#__PURE__*/_jsx(Ionicons, {
460
+ name: "close",
461
+ size: 24,
462
+ color: "#666"
468
463
  })
469
- }), /*#__PURE__*/_jsx(TouchableOpacity, {
470
- style: [styles.tabButton, currentTab === 'notifications' && [styles.activeTabButton, {
471
- borderColor: primaryColor
472
- }]],
473
- onPress: () => setCurrentTab('notifications'),
474
- children: /*#__PURE__*/_jsx(Text, {
475
- style: [styles.tabButtonText, {
476
- color: currentTab === 'notifications' ? primaryColor : textColor
464
+ }), /*#__PURE__*/_jsx(Text, {
465
+ style: styles.headerTitle,
466
+ children: "Account Settings"
467
+ }), /*#__PURE__*/_jsx(Animated.View, {
468
+ style: {
469
+ transform: [{
470
+ scale: saveButtonScale
471
+ }]
472
+ },
473
+ children: /*#__PURE__*/_jsx(TouchableOpacity, {
474
+ style: [styles.saveIconButton, {
475
+ opacity: isSaving ? 0.7 : 1
477
476
  }],
478
- children: "Notifications"
477
+ onPress: handleSave,
478
+ disabled: isSaving,
479
+ children: isSaving ? /*#__PURE__*/_jsx(ActivityIndicator, {
480
+ size: "small",
481
+ color: primaryColor
482
+ }) : /*#__PURE__*/_jsx(Ionicons, {
483
+ name: "checkmark",
484
+ size: 24,
485
+ color: primaryColor
486
+ })
479
487
  })
480
488
  })]
481
- }), errorMessage ? /*#__PURE__*/_jsx(View, {
482
- style: styles.errorContainer,
483
- children: /*#__PURE__*/_jsx(Text, {
484
- style: styles.errorText,
485
- children: errorMessage
486
- })
487
- }) : null, successMessage ? /*#__PURE__*/_jsx(View, {
488
- style: styles.successContainer,
489
- children: /*#__PURE__*/_jsx(Text, {
490
- style: styles.successText,
491
- children: successMessage
492
- })
493
- }) : null, currentTab === 'profile' && renderProfileTab(), currentTab === 'password' && renderPasswordTab(), currentTab === 'notifications' && renderNotificationsTab()]
494
- })
489
+ })
490
+ }), /*#__PURE__*/_jsx(ScrollView, {
491
+ style: editingField ? styles.contentEditing : styles.content,
492
+ children: editingField ?
493
+ /*#__PURE__*/
494
+ // Show only the editing interface when editing
495
+ _jsx(View, {
496
+ style: styles.editingOnlyContainer,
497
+ children: renderEditingField(editingField)
498
+ }) :
499
+ /*#__PURE__*/
500
+ // Show all settings when not editing
501
+ _jsxs(_Fragment, {
502
+ children: [/*#__PURE__*/_jsxs(View, {
503
+ style: styles.section,
504
+ children: [/*#__PURE__*/_jsx(Text, {
505
+ style: styles.sectionTitle,
506
+ children: "Profile Picture"
507
+ }), /*#__PURE__*/_jsxs(TouchableOpacity, {
508
+ style: [styles.settingItem, styles.firstSettingItem, styles.lastSettingItem],
509
+ onPress: handleAvatarUpdate,
510
+ children: [/*#__PURE__*/_jsx(View, {
511
+ style: styles.userIcon,
512
+ children: /*#__PURE__*/_jsx(Avatar, {
513
+ uri: avatarUrl,
514
+ name: displayName || username,
515
+ size: 50,
516
+ theme: theme
517
+ })
518
+ }), /*#__PURE__*/_jsx(View, {
519
+ style: styles.settingInfo,
520
+ children: /*#__PURE__*/_jsxs(View, {
521
+ children: [/*#__PURE__*/_jsx(Text, {
522
+ style: styles.settingLabel,
523
+ children: "Profile Photo"
524
+ }), /*#__PURE__*/_jsx(Text, {
525
+ style: styles.settingDescription,
526
+ children: avatarUrl ? 'Tap to change your profile picture' : 'Tap to add a profile picture'
527
+ })]
528
+ })
529
+ }), /*#__PURE__*/_jsx(OxyIcon, {
530
+ name: "chevron-forward",
531
+ size: 16,
532
+ color: "#ccc"
533
+ })]
534
+ })]
535
+ }), /*#__PURE__*/_jsxs(View, {
536
+ style: styles.section,
537
+ children: [/*#__PURE__*/_jsx(Text, {
538
+ style: styles.sectionTitle,
539
+ children: "Basic Information"
540
+ }), renderField('displayName', 'Display Name', displayName, '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)]
541
+ }), /*#__PURE__*/_jsxs(View, {
542
+ style: styles.section,
543
+ children: [/*#__PURE__*/_jsx(Text, {
544
+ style: styles.sectionTitle,
545
+ children: "About You"
546
+ }), 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('website', 'Website', website, 'Add your website', 'link', '#32D74B', false, 'url', false, true)]
547
+ }), /*#__PURE__*/_jsxs(View, {
548
+ style: styles.section,
549
+ children: [/*#__PURE__*/_jsx(Text, {
550
+ style: styles.sectionTitle,
551
+ children: "Quick Actions"
552
+ }), /*#__PURE__*/_jsxs(TouchableOpacity, {
553
+ style: [styles.settingItem, styles.firstSettingItem],
554
+ onPress: () => toast.info('Privacy settings coming soon!'),
555
+ children: [/*#__PURE__*/_jsxs(View, {
556
+ style: styles.settingInfo,
557
+ children: [/*#__PURE__*/_jsx(OxyIcon, {
558
+ name: "shield-checkmark",
559
+ size: 20,
560
+ color: "#8E8E93",
561
+ style: styles.settingIcon
562
+ }), /*#__PURE__*/_jsxs(View, {
563
+ children: [/*#__PURE__*/_jsx(Text, {
564
+ style: styles.settingLabel,
565
+ children: "Privacy Settings"
566
+ }), /*#__PURE__*/_jsx(Text, {
567
+ style: styles.settingDescription,
568
+ children: "Control who can see your profile"
569
+ })]
570
+ })]
571
+ }), /*#__PURE__*/_jsx(OxyIcon, {
572
+ name: "chevron-forward",
573
+ size: 16,
574
+ color: "#ccc"
575
+ })]
576
+ }), /*#__PURE__*/_jsxs(TouchableOpacity, {
577
+ style: [styles.settingItem, styles.lastSettingItem],
578
+ onPress: () => toast.info('Account verification coming soon!'),
579
+ children: [/*#__PURE__*/_jsxs(View, {
580
+ style: styles.settingInfo,
581
+ children: [/*#__PURE__*/_jsx(OxyIcon, {
582
+ name: "checkmark-circle",
583
+ size: 20,
584
+ color: "#30D158",
585
+ style: styles.settingIcon
586
+ }), /*#__PURE__*/_jsxs(View, {
587
+ children: [/*#__PURE__*/_jsx(Text, {
588
+ style: styles.settingLabel,
589
+ children: "Verify Account"
590
+ }), /*#__PURE__*/_jsx(Text, {
591
+ style: styles.settingDescription,
592
+ children: "Get a verified badge"
593
+ })]
594
+ })]
595
+ }), /*#__PURE__*/_jsx(OxyIcon, {
596
+ name: "chevron-forward",
597
+ size: 16,
598
+ color: "#ccc"
599
+ })]
600
+ })]
601
+ })]
602
+ })
603
+ })]
495
604
  });
496
605
  };
497
606
  const styles = StyleSheet.create({
498
607
  container: {
499
- flex: 1
608
+ flex: 1,
609
+ backgroundColor: '#f2f2f2'
500
610
  },
501
- scrollView: {
502
- flex: 1
611
+ header: {
612
+ paddingHorizontal: 20,
613
+ paddingVertical: 10,
614
+ backgroundColor: '#fff',
615
+ borderBottomWidth: 1,
616
+ borderBottomColor: '#e0e0e0'
617
+ },
618
+ normalHeader: {
619
+ flexDirection: 'row',
620
+ justifyContent: 'space-between',
621
+ alignItems: 'center'
503
622
  },
504
- scrollContainer: {
505
- padding: 20
623
+ editingHeader: {
624
+ flexDirection: 'column'
506
625
  },
507
- header: {
626
+ editingHeaderTop: {
508
627
  flexDirection: 'row',
509
628
  justifyContent: 'space-between',
510
629
  alignItems: 'center',
511
- marginBottom: 24
630
+ marginBottom: 16
512
631
  },
513
- title: {
632
+ editingHeaderBottom: {
633
+ flexDirection: 'row',
634
+ alignItems: 'center',
635
+ justifyContent: 'flex-start'
636
+ },
637
+ headerTitle: {
514
638
  fontSize: 24,
515
- fontWeight: 'bold'
639
+ fontWeight: 'bold',
640
+ color: '#000',
641
+ fontFamily: fontFamilies.phuduBold
516
642
  },
517
- backButton: {
518
- padding: 10
643
+ headerTitleWithIcon: {
644
+ flexDirection: 'column',
645
+ alignItems: 'flex-start',
646
+ flex: 1,
647
+ justifyContent: 'flex-start',
648
+ maxWidth: '90%'
519
649
  },
520
- backButtonText: {
521
- fontSize: 16,
522
- fontWeight: '600'
650
+ headerTitleLarge: {
651
+ fontSize: 48,
652
+ fontWeight: '800',
653
+ color: '#000',
654
+ fontFamily: fontFamilies.phuduExtraBold,
655
+ textAlign: 'left'
523
656
  },
524
- backButtonPlaceholder: {
525
- width: 40
657
+ headerIcon: {
658
+ marginBottom: 2
526
659
  },
527
- tabsContainer: {
528
- flexDirection: 'row',
529
- marginBottom: 24,
530
- borderBottomWidth: 1
660
+ cancelButton: {
661
+ padding: 5
531
662
  },
532
- tabButton: {
533
- flex: 1,
663
+ saveHeaderButton: {
664
+ paddingHorizontal: 16,
665
+ paddingVertical: 8,
666
+ borderRadius: 20,
667
+ minWidth: 60,
534
668
  alignItems: 'center',
535
- paddingVertical: 12
669
+ justifyContent: 'center'
536
670
  },
537
- activeTabButton: {
538
- borderBottomWidth: 2
671
+ saveIconButton: {
672
+ padding: 5
539
673
  },
540
- tabButtonText: {
674
+ saveButtonText: {
675
+ color: '#fff',
541
676
  fontSize: 16,
542
- fontWeight: '500'
677
+ fontWeight: '600',
678
+ fontFamily: fontFamilies.phuduSemiBold
543
679
  },
544
- tabContent: {
680
+ content: {
681
+ flex: 1,
682
+ padding: 16
683
+ },
684
+ contentEditing: {
685
+ flex: 1,
686
+ padding: 0
687
+ },
688
+ section: {
545
689
  marginBottom: 24
546
690
  },
547
- avatarSection: {
691
+ sectionTitle: {
692
+ fontSize: 16,
693
+ fontWeight: '600',
694
+ color: '#333',
695
+ marginBottom: 12,
696
+ fontFamily: fontFamilies.phuduSemiBold
697
+ },
698
+ settingItem: {
699
+ backgroundColor: '#fff',
700
+ padding: 16,
701
+ flexDirection: 'row',
548
702
  alignItems: 'center',
549
- marginBottom: 24
703
+ justifyContent: 'space-between',
704
+ marginBottom: 2
550
705
  },
551
- changeAvatarButton: {
552
- marginTop: 12,
553
- paddingVertical: 8,
554
- paddingHorizontal: 16,
555
- borderRadius: 20
706
+ firstSettingItem: {
707
+ borderTopLeftRadius: 24,
708
+ borderTopRightRadius: 24
556
709
  },
557
- changeAvatarText: {
558
- color: '#FFFFFF',
559
- fontWeight: '600'
710
+ lastSettingItem: {
711
+ borderBottomLeftRadius: 24,
712
+ borderBottomRightRadius: 24,
713
+ marginBottom: 8
560
714
  },
561
- inputContainer: {
562
- marginBottom: 16
715
+ settingInfo: {
716
+ flexDirection: 'row',
717
+ alignItems: 'center',
718
+ flex: 1
563
719
  },
564
- label: {
720
+ settingIcon: {
721
+ marginRight: 12
722
+ },
723
+ settingLabel: {
565
724
  fontSize: 16,
566
- marginBottom: 8
725
+ fontWeight: '500',
726
+ color: '#333',
727
+ marginBottom: 2
567
728
  },
568
- input: {
569
- height: 50,
570
- borderRadius: 8,
571
- borderWidth: 1,
572
- paddingHorizontal: 12,
573
- fontSize: 16
729
+ settingDescription: {
730
+ fontSize: 14,
731
+ color: '#666'
574
732
  },
575
- textArea: {
576
- minHeight: 100,
733
+ userIcon: {
734
+ marginRight: 12
735
+ },
736
+ // Inline editing styles
737
+ editingContainer: {
738
+ flex: 1
739
+ },
740
+ editingActions: {
741
+ flexDirection: 'row',
742
+ alignItems: 'center'
743
+ },
744
+ editingButton: {
745
+ padding: 8
746
+ },
747
+ editingButtonText: {
748
+ fontSize: 16,
749
+ fontWeight: '500'
750
+ },
751
+ inlineInput: {
752
+ backgroundColor: '#f8f8f8',
753
+ borderWidth: 1,
754
+ borderColor: '#e0e0e0',
577
755
  borderRadius: 8,
756
+ padding: 12,
757
+ fontSize: 16,
758
+ minHeight: 44
759
+ },
760
+ inlineTextArea: {
761
+ backgroundColor: '#f8f8f8',
578
762
  borderWidth: 1,
579
- paddingHorizontal: 12,
580
- paddingTop: 12,
763
+ borderColor: '#e0e0e0',
764
+ borderRadius: 8,
765
+ padding: 12,
581
766
  fontSize: 16,
767
+ minHeight: 100,
582
768
  textAlignVertical: 'top'
583
769
  },
584
- passwordHint: {
585
- fontSize: 14,
586
- marginTop: 4
770
+ // Editing-only mode styles
771
+ editingOnlyContainer: {
772
+ flex: 1
587
773
  },
588
- saveButton: {
589
- height: 50,
590
- borderRadius: 25,
591
- alignItems: 'center',
592
- justifyContent: 'center',
593
- marginTop: 16
774
+ editingFieldContainer: {
775
+ backgroundColor: '#fff',
776
+ padding: 16,
777
+ flex: 1
594
778
  },
595
- saveButtonText: {
596
- color: '#FFFFFF',
597
- fontSize: 16,
598
- fontWeight: '600'
779
+ editingFieldHeader: {
780
+ marginBottom: 16
599
781
  },
600
- settingRow: {
782
+ editingFieldTitleContainer: {
601
783
  flexDirection: 'row',
602
- justifyContent: 'space-between',
603
- alignItems: 'center',
604
- paddingVertical: 16,
605
- borderBottomWidth: 1,
606
- borderBottomColor: '#E0E0E0'
784
+ alignItems: 'center'
607
785
  },
608
- settingLabel: {
609
- fontSize: 16
786
+ editingFieldIcon: {
787
+ marginRight: 12
610
788
  },
611
- errorContainer: {
612
- backgroundColor: '#FFEBEE',
613
- padding: 16,
614
- borderRadius: 8,
615
- marginBottom: 16
789
+ editingFieldTitle: {
790
+ fontSize: 20,
791
+ fontWeight: '600',
792
+ color: '#000'
616
793
  },
617
- errorText: {
618
- color: '#D32F2F',
619
- fontSize: 14
794
+ editingFieldContent: {
795
+ flex: 1
796
+ },
797
+ newValueSection: {
798
+ flex: 1
620
799
  },
621
- successContainer: {
622
- backgroundColor: '#E8F5E9',
800
+ editingFieldLabel: {
801
+ fontSize: 16,
802
+ fontWeight: '600',
803
+ color: '#333',
804
+ marginBottom: 12,
805
+ fontFamily: fontFamilies.phuduSemiBold
806
+ },
807
+ editingFieldInput: {
808
+ backgroundColor: '#fff',
809
+ borderWidth: 2,
810
+ borderColor: '#e0e0e0',
811
+ borderRadius: 12,
623
812
  padding: 16,
624
- borderRadius: 8,
625
- marginBottom: 16
813
+ fontSize: 17,
814
+ minHeight: 52,
815
+ fontWeight: '400'
626
816
  },
627
- successText: {
628
- color: '#2E7D32',
629
- fontSize: 14
817
+ editingFieldTextArea: {
818
+ backgroundColor: '#fff',
819
+ borderWidth: 2,
820
+ borderColor: '#e0e0e0',
821
+ borderRadius: 12,
822
+ padding: 16,
823
+ fontSize: 17,
824
+ minHeight: 120,
825
+ textAlignVertical: 'top',
826
+ fontWeight: '400'
630
827
  }
631
828
  });
632
829
  export default AccountSettingsScreen;