@oxyhq/services 5.4.1 → 5.4.3

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 (154) hide show
  1. package/lib/commonjs/assets/icons/OxyServices.js +1 -1
  2. package/lib/commonjs/core/index.js +84 -2
  3. package/lib/commonjs/core/index.js.map +1 -1
  4. package/lib/commonjs/index.js +22 -22
  5. package/lib/commonjs/index.js.map +1 -1
  6. package/lib/commonjs/node/index.js +6 -6
  7. package/lib/commonjs/node/index.js.map +1 -1
  8. package/lib/commonjs/ui/components/Avatar.js +3 -3
  9. package/lib/commonjs/ui/components/Avatar.js.map +1 -1
  10. package/lib/commonjs/ui/components/FollowButton.js +3 -3
  11. package/lib/commonjs/ui/components/GroupedSection.js +1 -1
  12. package/lib/commonjs/ui/components/OxyLogo.js +1 -1
  13. package/lib/commonjs/ui/components/OxyProvider.js +13 -13
  14. package/lib/commonjs/ui/components/OxyProvider.js.map +1 -1
  15. package/lib/commonjs/ui/components/OxySignInButton.js +2 -2
  16. package/lib/commonjs/ui/components/ProfileCard.js +2 -2
  17. package/lib/commonjs/ui/components/Section.js +1 -1
  18. package/lib/commonjs/ui/components/SectionTitle.js +1 -1
  19. package/lib/commonjs/ui/components/icon/index.js +1 -1
  20. package/lib/commonjs/ui/components/index.js +12 -12
  21. package/lib/commonjs/ui/context/OxyContext.js +20 -4
  22. package/lib/commonjs/ui/context/OxyContext.js.map +1 -1
  23. package/lib/commonjs/ui/index.js +11 -11
  24. package/lib/commonjs/ui/index.js.map +1 -1
  25. package/lib/commonjs/ui/navigation/OxyRouter.js +18 -18
  26. package/lib/commonjs/ui/screens/AccountCenterScreen.js +18 -18
  27. package/lib/commonjs/ui/screens/AccountCenterScreen.js.map +1 -1
  28. package/lib/commonjs/ui/screens/AccountManagementDemo.js +3 -3
  29. package/lib/commonjs/ui/screens/AccountManagementDemo.js.map +1 -1
  30. package/lib/commonjs/ui/screens/AccountOverviewScreen.js +45 -27
  31. package/lib/commonjs/ui/screens/AccountOverviewScreen.js.map +1 -1
  32. package/lib/commonjs/ui/screens/AccountSettingsScreen.js +29 -22
  33. package/lib/commonjs/ui/screens/AccountSettingsScreen.js.map +1 -1
  34. package/lib/commonjs/ui/screens/AccountSwitcherScreen.js +3 -3
  35. package/lib/commonjs/ui/screens/AppInfoScreen.js +6 -6
  36. package/lib/commonjs/ui/screens/BillingManagementScreen.js +3 -3
  37. package/lib/commonjs/ui/screens/FileManagementScreen.js +324 -306
  38. package/lib/commonjs/ui/screens/FileManagementScreen.js.map +1 -1
  39. package/lib/commonjs/ui/screens/PremiumSubscriptionScreen.js +3 -3
  40. package/lib/commonjs/ui/screens/ProfileScreen.js +2 -2
  41. package/lib/commonjs/ui/screens/SessionManagementScreen.js +2 -2
  42. package/lib/commonjs/ui/screens/SignInScreen.js +358 -310
  43. package/lib/commonjs/ui/screens/SignInScreen.js.map +1 -1
  44. package/lib/commonjs/ui/screens/SignUpScreen.js +483 -308
  45. package/lib/commonjs/ui/screens/SignUpScreen.js.map +1 -1
  46. package/lib/commonjs/ui/screens/karma/KarmaCenterScreen.js +3 -3
  47. package/lib/commonjs/ui/screens/karma/KarmaFAQScreen.js +51 -26
  48. package/lib/commonjs/ui/screens/karma/KarmaFAQScreen.js.map +1 -1
  49. package/lib/commonjs/ui/screens/karma/KarmaLeaderboardScreen.js +2 -2
  50. package/lib/commonjs/ui/screens/karma/KarmaRulesScreen.js +1 -1
  51. package/lib/commonjs/ui/styles/index.js +2 -2
  52. package/lib/commonjs/ui/styles/theme.js +1 -1
  53. package/lib/commonjs/utils/index.js +1 -1
  54. package/lib/module/assets/icons/OxyServices.js +1 -1
  55. package/lib/module/assets/icons/OxyServices.js.map +1 -1
  56. package/lib/module/core/index.js +84 -2
  57. package/lib/module/core/index.js.map +1 -1
  58. package/lib/module/index.js +10 -10
  59. package/lib/module/index.js.map +1 -1
  60. package/lib/module/node/index.js +4 -4
  61. package/lib/module/node/index.js.map +1 -1
  62. package/lib/module/ui/components/Avatar.js +2 -2
  63. package/lib/module/ui/components/Avatar.js.map +1 -1
  64. package/lib/module/ui/components/FollowButton.js +3 -3
  65. package/lib/module/ui/components/FollowButton.js.map +1 -1
  66. package/lib/module/ui/components/GroupedSection.js +1 -1
  67. package/lib/module/ui/components/GroupedSection.js.map +1 -1
  68. package/lib/module/ui/components/OxyLogo.js +1 -1
  69. package/lib/module/ui/components/OxyLogo.js.map +1 -1
  70. package/lib/module/ui/components/OxyProvider.js +10 -10
  71. package/lib/module/ui/components/OxyProvider.js.map +1 -1
  72. package/lib/module/ui/components/OxySignInButton.js +2 -2
  73. package/lib/module/ui/components/OxySignInButton.js.map +1 -1
  74. package/lib/module/ui/components/ProfileCard.js +2 -2
  75. package/lib/module/ui/components/ProfileCard.js.map +1 -1
  76. package/lib/module/ui/components/Section.js +1 -1
  77. package/lib/module/ui/components/Section.js.map +1 -1
  78. package/lib/module/ui/components/SectionTitle.js +1 -1
  79. package/lib/module/ui/components/SectionTitle.js.map +1 -1
  80. package/lib/module/ui/components/icon/index.js +1 -1
  81. package/lib/module/ui/components/icon/index.js.map +1 -1
  82. package/lib/module/ui/components/index.js +12 -12
  83. package/lib/module/ui/components/index.js.map +1 -1
  84. package/lib/module/ui/context/OxyContext.js +20 -4
  85. package/lib/module/ui/context/OxyContext.js.map +1 -1
  86. package/lib/module/ui/index.js +10 -10
  87. package/lib/module/ui/index.js.map +1 -1
  88. package/lib/module/ui/navigation/OxyRouter.js +18 -18
  89. package/lib/module/ui/navigation/OxyRouter.js.map +1 -1
  90. package/lib/module/ui/screens/AccountCenterScreen.js +5 -5
  91. package/lib/module/ui/screens/AccountCenterScreen.js.map +1 -1
  92. package/lib/module/ui/screens/AccountManagementDemo.js +2 -2
  93. package/lib/module/ui/screens/AccountManagementDemo.js.map +1 -1
  94. package/lib/module/ui/screens/AccountOverviewScreen.js +46 -28
  95. package/lib/module/ui/screens/AccountOverviewScreen.js.map +1 -1
  96. package/lib/module/ui/screens/AccountSettingsScreen.js +30 -23
  97. package/lib/module/ui/screens/AccountSettingsScreen.js.map +1 -1
  98. package/lib/module/ui/screens/AccountSwitcherScreen.js +3 -3
  99. package/lib/module/ui/screens/AccountSwitcherScreen.js.map +1 -1
  100. package/lib/module/ui/screens/AppInfoScreen.js +6 -6
  101. package/lib/module/ui/screens/AppInfoScreen.js.map +1 -1
  102. package/lib/module/ui/screens/BillingManagementScreen.js +3 -3
  103. package/lib/module/ui/screens/BillingManagementScreen.js.map +1 -1
  104. package/lib/module/ui/screens/FileManagementScreen.js +325 -307
  105. package/lib/module/ui/screens/FileManagementScreen.js.map +1 -1
  106. package/lib/module/ui/screens/PremiumSubscriptionScreen.js +3 -3
  107. package/lib/module/ui/screens/PremiumSubscriptionScreen.js.map +1 -1
  108. package/lib/module/ui/screens/ProfileScreen.js +2 -2
  109. package/lib/module/ui/screens/ProfileScreen.js.map +1 -1
  110. package/lib/module/ui/screens/SessionManagementScreen.js +2 -2
  111. package/lib/module/ui/screens/SessionManagementScreen.js.map +1 -1
  112. package/lib/module/ui/screens/SignInScreen.js +358 -310
  113. package/lib/module/ui/screens/SignInScreen.js.map +1 -1
  114. package/lib/module/ui/screens/SignUpScreen.js +486 -309
  115. package/lib/module/ui/screens/SignUpScreen.js.map +1 -1
  116. package/lib/module/ui/screens/karma/KarmaCenterScreen.js +3 -3
  117. package/lib/module/ui/screens/karma/KarmaCenterScreen.js.map +1 -1
  118. package/lib/module/ui/screens/karma/KarmaFAQScreen.js +52 -27
  119. package/lib/module/ui/screens/karma/KarmaFAQScreen.js.map +1 -1
  120. package/lib/module/ui/screens/karma/KarmaLeaderboardScreen.js +2 -2
  121. package/lib/module/ui/screens/karma/KarmaLeaderboardScreen.js.map +1 -1
  122. package/lib/module/ui/screens/karma/KarmaRulesScreen.js +1 -1
  123. package/lib/module/ui/screens/karma/KarmaRulesScreen.js.map +1 -1
  124. package/lib/module/ui/styles/index.js +2 -2
  125. package/lib/module/ui/styles/index.js.map +1 -1
  126. package/lib/module/ui/styles/theme.js +1 -1
  127. package/lib/module/ui/styles/theme.js.map +1 -1
  128. package/lib/module/utils/index.js +1 -1
  129. package/lib/module/utils/index.js.map +1 -1
  130. package/lib/typescript/core/index.d.ts +24 -0
  131. package/lib/typescript/core/index.d.ts.map +1 -1
  132. package/lib/typescript/ui/components/OxyProvider.d.ts.map +1 -1
  133. package/lib/typescript/ui/context/OxyContext.d.ts.map +1 -1
  134. package/lib/typescript/ui/screens/AccountOverviewScreen.d.ts +2 -2
  135. package/lib/typescript/ui/screens/AccountOverviewScreen.d.ts.map +1 -1
  136. package/lib/typescript/ui/screens/AccountSettingsScreen.d.ts +2 -2
  137. package/lib/typescript/ui/screens/AccountSettingsScreen.d.ts.map +1 -1
  138. package/lib/typescript/ui/screens/FileManagementScreen.d.ts.map +1 -1
  139. package/lib/typescript/ui/screens/SignInScreen.d.ts.map +1 -1
  140. package/lib/typescript/ui/screens/SignUpScreen.d.ts.map +1 -1
  141. package/lib/typescript/ui/screens/karma/KarmaFAQScreen.d.ts +2 -2
  142. package/lib/typescript/ui/screens/karma/KarmaFAQScreen.d.ts.map +1 -1
  143. package/package.json +21 -5
  144. package/src/core/index.ts +68 -0
  145. package/src/ui/components/OxyProvider.tsx +5 -5
  146. package/src/ui/context/OxyContext.tsx +61 -41
  147. package/src/ui/screens/AccountOverviewScreen.tsx +44 -26
  148. package/src/ui/screens/AccountSettingsScreen.tsx +24 -18
  149. package/src/ui/screens/FileManagementScreen.tsx +246 -211
  150. package/src/ui/screens/SignInScreen.tsx +382 -326
  151. package/src/ui/screens/SignUpScreen.tsx +443 -273
  152. package/src/ui/screens/karma/KarmaFAQScreen.tsx +50 -29
  153. package/lib/commonjs/package.json +0 -1
  154. package/lib/module/package.json +0 -1
@@ -6,16 +6,13 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.default = void 0;
7
7
  var _react = _interopRequireWildcard(require("react"));
8
8
  var _reactNative = require("react-native");
9
- var _OxyContext = require("../context/OxyContext");
10
- var _OxyLogo = _interopRequireDefault(require("../components/OxyLogo"));
11
- var _bottomSheet = require("../components/bottomSheet");
9
+ var _OxyContext = require("../context/OxyContext.js");
10
+ var _index = require("../styles/index.js");
11
+ var _vectorIcons = require("@expo/vector-icons");
12
12
  var _reactNativeSvg = _interopRequireWildcard(require("react-native-svg"));
13
- var _sonner = require("../../lib/sonner");
13
+ var _sonner = require("../../lib/sonner.js");
14
14
  var _jsxRuntime = require("react/jsx-runtime");
15
- function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
16
15
  function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
17
- // Add icon import
18
-
19
16
  const SignUpScreen = ({
20
17
  navigate,
21
18
  goBack,
@@ -26,44 +23,143 @@ const SignUpScreen = ({
26
23
  const [email, setEmail] = (0, _react.useState)('');
27
24
  const [password, setPassword] = (0, _react.useState)('');
28
25
  const [confirmPassword, setConfirmPassword] = (0, _react.useState)('');
26
+ const [showPassword, setShowPassword] = (0, _react.useState)(false);
27
+ const [showConfirmPassword, setShowConfirmPassword] = (0, _react.useState)(false);
29
28
  const [errorMessage, setErrorMessage] = (0, _react.useState)('');
30
29
 
31
30
  // Multi-step form states
32
31
  const [currentStep, setCurrentStep] = (0, _react.useState)(0);
32
+ const [isInputFocused, setIsInputFocused] = (0, _react.useState)(false);
33
+ const [isValidating, setIsValidating] = (0, _react.useState)(false);
34
+ const [validationStatus, setValidationStatus] = (0, _react.useState)('idle');
35
+
36
+ // Cache for validation results
37
+ const validationCache = (0, _react.useRef)(new Map());
33
38
  const fadeAnim = (0, _react.useRef)(new _reactNative.Animated.Value(1)).current;
34
39
  const slideAnim = (0, _react.useRef)(new _reactNative.Animated.Value(0)).current;
35
- const heightAnim = (0, _react.useRef)(new _reactNative.Animated.Value(400)).current; // Initial height value
36
- const [containerHeight, setContainerHeight] = (0, _react.useState)(400); // Default height
37
-
40
+ const heightAnim = (0, _react.useRef)(new _reactNative.Animated.Value(400)).current;
41
+ const [containerHeight, setContainerHeight] = (0, _react.useState)(400);
38
42
  const {
39
43
  signUp,
40
44
  isLoading,
41
45
  user,
42
- isAuthenticated
46
+ isAuthenticated,
47
+ oxyServices
43
48
  } = (0, _OxyContext.useOxy)();
44
- const isDarkTheme = theme === 'dark';
45
- const textColor = isDarkTheme ? '#FFFFFF' : '#000000';
46
- const backgroundColor = isDarkTheme ? '#121212' : '#FFFFFF';
47
- const inputBackgroundColor = isDarkTheme ? '#333333' : '#F5F5F5';
48
- const placeholderColor = isDarkTheme ? '#AAAAAA' : '#999999';
49
- const primaryColor = '#d169e5';
50
- const borderColor = isDarkTheme ? '#444444' : '#E0E0E0';
49
+ const colors = (0, _index.useThemeColors)(theme);
50
+ const commonStyles = (0, _index.createCommonStyles)(theme);
51
+
52
+ // Memoized styles to prevent rerenders
53
+ const styles = (0, _react.useMemo)(() => createStyles(colors, theme), [colors, theme]);
54
+
55
+ // Input focus animations
56
+ const handleInputFocus = (0, _react.useCallback)(() => {
57
+ setIsInputFocused(true);
58
+ }, []);
59
+ const handleInputBlur = (0, _react.useCallback)(() => {
60
+ setIsInputFocused(false);
61
+ }, []);
62
+
63
+ // Memoized input change handlers
64
+ const handleUsernameChange = (0, _react.useCallback)(text => {
65
+ setUsername(text);
66
+ if (validationStatus === 'invalid') {
67
+ setErrorMessage('');
68
+ setValidationStatus('idle');
69
+ }
70
+ }, [validationStatus]);
71
+ const handleEmailChange = (0, _react.useCallback)(text => {
72
+ setEmail(text);
73
+ setErrorMessage('');
74
+ }, []);
75
+ const handlePasswordChange = (0, _react.useCallback)(text => {
76
+ setPassword(text);
77
+ setErrorMessage('');
78
+ }, []);
79
+ const handleConfirmPasswordChange = (0, _react.useCallback)(text => {
80
+ setConfirmPassword(text);
81
+ setErrorMessage('');
82
+ }, []);
83
+
84
+ // Username availability validation using core services
85
+ const validateUsername = (0, _react.useCallback)(async usernameToValidate => {
86
+ if (!usernameToValidate || usernameToValidate.length < 3) {
87
+ setValidationStatus('invalid');
88
+ return false;
89
+ }
90
+
91
+ // Check cache first (cache valid for 5 minutes)
92
+ const cached = validationCache.current.get(usernameToValidate);
93
+ const now = Date.now();
94
+ if (cached && now - cached.timestamp < 5 * 60 * 1000) {
95
+ setValidationStatus(cached.available ? 'valid' : 'invalid');
96
+ setErrorMessage(cached.available ? '' : 'Username is already taken');
97
+ return cached.available;
98
+ }
99
+ setIsValidating(true);
100
+ setValidationStatus('validating');
101
+ try {
102
+ const result = await oxyServices.checkUsernameAvailability(usernameToValidate);
103
+ if (result.available) {
104
+ setValidationStatus('valid');
105
+ setErrorMessage('');
106
+
107
+ // Cache the result
108
+ validationCache.current.set(usernameToValidate, {
109
+ available: true,
110
+ timestamp: now
111
+ });
112
+ return true;
113
+ } else {
114
+ setValidationStatus('invalid');
115
+ setErrorMessage(result.message || 'Username is already taken');
116
+
117
+ // Cache the result
118
+ validationCache.current.set(usernameToValidate, {
119
+ available: false,
120
+ timestamp: now
121
+ });
122
+ return false;
123
+ }
124
+ } catch (error) {
125
+ console.error('Username validation error:', error);
126
+ setValidationStatus('invalid');
127
+ setErrorMessage('Unable to validate username. Please try again.');
128
+ return false;
129
+ } finally {
130
+ setIsValidating(false);
131
+ }
132
+ }, [oxyServices]);
133
+
134
+ // Debounced username validation
135
+ (0, _react.useEffect)(() => {
136
+ if (!username || username.length < 3) {
137
+ setValidationStatus('idle');
138
+ setErrorMessage('');
139
+ return;
140
+ }
141
+ const timeoutId = setTimeout(() => {
142
+ validateUsername(username);
143
+ }, 800);
144
+ return () => clearTimeout(timeoutId);
145
+ }, [username, validateUsername]);
146
+
147
+ // Cleanup cache on unmount
148
+ (0, _react.useEffect)(() => {
149
+ return () => {
150
+ validationCache.current.clear();
151
+ };
152
+ }, []);
51
153
 
52
- // If user is already authenticated, show user info and account center option
53
154
  // Animation functions
54
- const animateTransition = nextStep => {
55
- // Fade out
155
+ const animateTransition = (0, _react.useCallback)(nextStep => {
56
156
  _reactNative.Animated.timing(fadeAnim, {
57
157
  toValue: 0,
58
158
  duration: 250,
59
159
  useNativeDriver: true
60
160
  }).start(() => {
61
161
  setCurrentStep(nextStep);
62
-
63
- // Reset slide position
64
162
  slideAnim.setValue(-100);
65
-
66
- // Fade in and slide
67
163
  _reactNative.Animated.parallel([_reactNative.Animated.timing(fadeAnim, {
68
164
  toValue: 1,
69
165
  duration: 250,
@@ -74,63 +170,22 @@ const SignUpScreen = ({
74
170
  useNativeDriver: true
75
171
  })]).start();
76
172
  });
77
- };
78
- const nextStep = () => {
173
+ }, [fadeAnim, slideAnim]);
174
+ const nextStep = (0, _react.useCallback)(() => {
79
175
  if (currentStep < 3) {
80
176
  animateTransition(currentStep + 1);
81
177
  }
82
- };
83
- const prevStep = () => {
178
+ }, [currentStep, animateTransition]);
179
+ const prevStep = (0, _react.useCallback)(() => {
84
180
  if (currentStep > 0) {
85
181
  animateTransition(currentStep - 1);
86
182
  }
87
- };
88
- if (user && isAuthenticated) {
89
- return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_bottomSheet.BottomSheetScrollView, {
90
- style: [styles.scrollContainer, {
91
- backgroundColor,
92
- padding: 20
93
- }],
94
- children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Text, {
95
- style: [styles.welcomeTitle, {
96
- color: textColor,
97
- textAlign: 'center'
98
- }],
99
- children: ["Welcome, ", user.username, "!"]
100
- }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
101
- style: styles.userInfoContainer,
102
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
103
- style: [styles.userInfoText, {
104
- color: textColor
105
- }],
106
- children: "You are already signed in."
107
- }), user.email && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Text, {
108
- style: [styles.userInfoText, {
109
- color: isDarkTheme ? '#BBBBBB' : '#666666'
110
- }],
111
- children: ["Email: ", user.email]
112
- })]
113
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
114
- style: styles.actionButtonsContainer,
115
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
116
- style: [styles.button, {
117
- backgroundColor: primaryColor
118
- }],
119
- onPress: () => navigate('AccountCenter'),
120
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
121
- style: styles.buttonText,
122
- children: "Go to Account Center"
123
- })
124
- })
125
- })]
126
- });
127
- }
128
- const validateEmail = email => {
183
+ }, [currentStep, animateTransition]);
184
+ const validateEmail = (0, _react.useCallback)(email => {
129
185
  const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
130
186
  return emailRegex.test(email);
131
- };
132
- const handleSignUp = async () => {
133
- // Validate inputs
187
+ }, []);
188
+ const handleSignUp = (0, _react.useCallback)(async () => {
134
189
  if (!username || !email || !password || !confirmPassword) {
135
190
  _sonner.toast.error('Please fill in all fields');
136
191
  return;
@@ -139,6 +194,10 @@ const SignUpScreen = ({
139
194
  _sonner.toast.error('Please enter a valid email address');
140
195
  return;
141
196
  }
197
+ if (validationStatus !== 'valid') {
198
+ _sonner.toast.error('Please enter a valid username');
199
+ return;
200
+ }
142
201
  if (password !== confirmPassword) {
143
202
  _sonner.toast.error('Passwords do not match');
144
203
  return;
@@ -151,14 +210,13 @@ const SignUpScreen = ({
151
210
  setErrorMessage('');
152
211
  await signUp(username, email, password);
153
212
  _sonner.toast.success('Account created successfully! Welcome to Oxy!');
154
- // The authentication state change will be handled through context
155
213
  } catch (error) {
156
214
  _sonner.toast.error(error.message || 'Sign up failed');
157
215
  }
158
- };
216
+ }, [username, email, password, confirmPassword, validationStatus, validateEmail, signUp]);
159
217
 
160
218
  // Step components
161
- const renderWelcomeStep = () => /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Animated.View, {
219
+ const renderWelcomeStep = (0, _react.useMemo)(() => /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Animated.View, {
162
220
  style: [styles.stepContainer, {
163
221
  opacity: fadeAnim,
164
222
  transform: [{
@@ -173,26 +231,26 @@ const SignUpScreen = ({
173
231
  viewBox: "0 0 220 120",
174
232
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeSvg.Path, {
175
233
  d: "M30 100 Q60 20 110 60 Q160 100 190 40",
176
- stroke: "#d169e5",
234
+ stroke: colors.primary,
177
235
  strokeWidth: "8",
178
236
  fill: "none"
179
237
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeSvg.Circle, {
180
238
  cx: "60",
181
239
  cy: "60",
182
240
  r: "18",
183
- fill: "#d169e5",
241
+ fill: colors.primary,
184
242
  opacity: "0.18"
185
243
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeSvg.Circle, {
186
244
  cx: "110",
187
245
  cy: "60",
188
246
  r: "24",
189
- fill: "#d169e5",
247
+ fill: colors.primary,
190
248
  opacity: "0.25"
191
249
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeSvg.Circle, {
192
250
  cx: "170",
193
251
  cy: "50",
194
252
  r: "14",
195
- fill: "#d169e5",
253
+ fill: colors.primary,
196
254
  opacity: "0.15"
197
255
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeSvg.Circle, {
198
256
  cx: "110",
@@ -204,36 +262,28 @@ const SignUpScreen = ({
204
262
  cx: "100",
205
263
  cy: "55",
206
264
  r: "4",
207
- fill: "#d169e5"
265
+ fill: colors.primary
208
266
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeSvg.Circle, {
209
267
  cx: "120",
210
268
  cy: "55",
211
269
  r: "4",
212
- fill: "#d169e5"
270
+ fill: colors.primary
213
271
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeSvg.Path, {
214
272
  d: "M104 68 Q110 75 116 68",
215
- stroke: "#d169e5",
273
+ stroke: colors.primary,
216
274
  strokeWidth: "2",
217
275
  fill: "none",
218
276
  strokeLinecap: "round"
219
277
  })]
220
278
  })
221
- }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
222
- style: styles.header,
223
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
224
- style: [styles.welcomeTitle],
225
- children: "Create a Oxy Account"
226
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
227
- style: styles.placeholder
228
- })]
229
279
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
230
280
  style: [styles.welcomeText, {
231
- color: textColor
281
+ color: colors.text
232
282
  }],
233
283
  children: "We're excited to have you join us. Let's get your account set up in just a few easy steps."
234
284
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
235
285
  style: [styles.button, {
236
- backgroundColor: primaryColor
286
+ backgroundColor: colors.primary
237
287
  }],
238
288
  onPress: nextStep,
239
289
  testID: "welcome-next-button",
@@ -245,21 +295,21 @@ const SignUpScreen = ({
245
295
  style: styles.footerTextContainer,
246
296
  children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Text, {
247
297
  style: [styles.footerText, {
248
- color: textColor
298
+ color: colors.text
249
299
  }],
250
300
  children: ["Already have an account?", ' ']
251
301
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
252
302
  onPress: () => navigate('SignIn'),
253
303
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
254
304
  style: [styles.linkText, {
255
- color: primaryColor
305
+ color: colors.primary
256
306
  }],
257
307
  children: "Sign In"
258
308
  })
259
309
  })]
260
310
  })]
261
- });
262
- const renderIdentityStep = () => /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Animated.View, {
311
+ }), [fadeAnim, slideAnim, colors, nextStep, navigate, styles]);
312
+ const renderIdentityStep = (0, _react.useMemo)(() => /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Animated.View, {
263
313
  style: [styles.stepContainer, {
264
314
  opacity: fadeAnim,
265
315
  transform: [{
@@ -268,46 +318,93 @@ const SignUpScreen = ({
268
318
  }],
269
319
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
270
320
  style: [styles.stepTitle, {
271
- color: textColor
321
+ color: colors.text
272
322
  }],
273
323
  children: "Who are you?"
274
324
  }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
275
325
  style: styles.inputContainer,
276
326
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
277
327
  style: [styles.label, {
278
- color: textColor
328
+ color: colors.text
279
329
  }],
280
330
  children: "Username"
281
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TextInput, {
282
- style: [styles.input, {
283
- backgroundColor: inputBackgroundColor,
284
- borderColor,
285
- color: textColor
331
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
332
+ style: {
333
+ position: 'relative'
334
+ },
335
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TextInput, {
336
+ style: [styles.input, {
337
+ backgroundColor: colors.inputBackground,
338
+ borderColor: colors.border,
339
+ color: colors.text
340
+ }],
341
+ placeholder: "Choose a username",
342
+ placeholderTextColor: colors.placeholder,
343
+ value: username,
344
+ onChangeText: handleUsernameChange,
345
+ autoCapitalize: "none",
346
+ testID: "username-input"
347
+ }), validationStatus === 'validating' && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.ActivityIndicator, {
348
+ size: "small",
349
+ color: colors.primary,
350
+ style: styles.validationIndicator
351
+ }), validationStatus === 'valid' && /*#__PURE__*/(0, _jsxRuntime.jsx)(_vectorIcons.Ionicons, {
352
+ name: "checkmark-circle",
353
+ size: 20,
354
+ color: colors.success,
355
+ style: styles.validationIndicator
356
+ }), validationStatus === 'invalid' && username.length >= 3 && /*#__PURE__*/(0, _jsxRuntime.jsx)(_vectorIcons.Ionicons, {
357
+ name: "close-circle",
358
+ size: 20,
359
+ color: colors.error,
360
+ style: styles.validationIndicator
361
+ })]
362
+ }), validationStatus === 'valid' && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
363
+ style: [styles.validationSuccessCard, {
364
+ backgroundColor: colors.success + '15'
286
365
  }],
287
- placeholder: "Choose a username",
288
- placeholderTextColor: placeholderColor,
289
- value: username,
290
- onChangeText: setUsername,
291
- autoCapitalize: "none",
292
- testID: "username-input"
366
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_vectorIcons.Ionicons, {
367
+ name: "checkmark-circle",
368
+ size: 16,
369
+ color: colors.success
370
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
371
+ style: [styles.validationText, {
372
+ color: colors.success
373
+ }],
374
+ children: "Username is available"
375
+ })]
376
+ }), validationStatus === 'invalid' && username.length >= 3 && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
377
+ style: [styles.validationErrorCard, {
378
+ backgroundColor: colors.error + '15'
379
+ }],
380
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_vectorIcons.Ionicons, {
381
+ name: "alert-circle",
382
+ size: 16,
383
+ color: colors.error
384
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
385
+ style: [styles.validationText, {
386
+ color: colors.error
387
+ }],
388
+ children: errorMessage || 'Username is already taken'
389
+ })]
293
390
  })]
294
391
  }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
295
392
  style: styles.inputContainer,
296
393
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
297
394
  style: [styles.label, {
298
- color: textColor
395
+ color: colors.text
299
396
  }],
300
397
  children: "Email"
301
398
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TextInput, {
302
399
  style: [styles.input, {
303
- backgroundColor: inputBackgroundColor,
304
- borderColor,
305
- color: textColor
400
+ backgroundColor: colors.inputBackground,
401
+ borderColor: colors.border,
402
+ color: colors.text
306
403
  }],
307
404
  placeholder: "Enter your email",
308
- placeholderTextColor: placeholderColor,
405
+ placeholderTextColor: colors.placeholder,
309
406
  value: email,
310
- onChangeText: setEmail,
407
+ onChangeText: handleEmailChange,
311
408
  autoCapitalize: "none",
312
409
  keyboardType: "email-address",
313
410
  testID: "email-input"
@@ -315,28 +412,32 @@ const SignUpScreen = ({
315
412
  }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
316
413
  style: styles.navigationButtons,
317
414
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
318
- style: [styles.navButton, styles.backButton],
415
+ style: [styles.navButton, styles.backButton, {
416
+ borderColor: colors.border
417
+ }],
319
418
  onPress: prevStep,
320
419
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
321
420
  style: [styles.navButtonText, {
322
- color: textColor
421
+ color: colors.text
323
422
  }],
324
423
  children: "Back"
325
424
  })
326
425
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
327
426
  style: [styles.navButton, styles.nextButton, {
328
- backgroundColor: primaryColor
427
+ backgroundColor: colors.primary
329
428
  }],
330
429
  onPress: nextStep,
331
- disabled: !username || !email || !validateEmail(email),
430
+ disabled: !username || !email || !validateEmail(email) || validationStatus !== 'valid',
332
431
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
333
- style: styles.navButtonText,
432
+ style: [styles.navButtonText, {
433
+ color: '#FFFFFF'
434
+ }],
334
435
  children: "Next"
335
436
  })
336
437
  })]
337
438
  })]
338
- });
339
- const renderSecurityStep = () => /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Animated.View, {
439
+ }), [fadeAnim, slideAnim, colors, username, email, validationStatus, errorMessage, handleUsernameChange, handleEmailChange, validateEmail, prevStep, nextStep, styles]);
440
+ const renderSecurityStep = (0, _react.useMemo)(() => /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Animated.View, {
340
441
  style: [styles.stepContainer, {
341
442
  opacity: fadeAnim,
342
443
  transform: [{
@@ -345,31 +446,44 @@ const SignUpScreen = ({
345
446
  }],
346
447
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
347
448
  style: [styles.stepTitle, {
348
- color: textColor
449
+ color: colors.text
349
450
  }],
350
451
  children: "Secure your account"
351
452
  }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
352
453
  style: styles.inputContainer,
353
454
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
354
455
  style: [styles.label, {
355
- color: textColor
456
+ color: colors.text
356
457
  }],
357
458
  children: "Password"
358
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TextInput, {
359
- style: [styles.input, {
360
- backgroundColor: inputBackgroundColor,
361
- borderColor,
362
- color: textColor
363
- }],
364
- placeholder: "Create a password",
365
- placeholderTextColor: placeholderColor,
366
- value: password,
367
- onChangeText: setPassword,
368
- secureTextEntry: true,
369
- testID: "password-input"
459
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
460
+ style: {
461
+ position: 'relative'
462
+ },
463
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TextInput, {
464
+ style: [styles.input, {
465
+ backgroundColor: colors.inputBackground,
466
+ borderColor: colors.border,
467
+ color: colors.text
468
+ }],
469
+ placeholder: "Create a password",
470
+ placeholderTextColor: colors.placeholder,
471
+ value: password,
472
+ onChangeText: handlePasswordChange,
473
+ secureTextEntry: !showPassword,
474
+ testID: "password-input"
475
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
476
+ style: styles.passwordToggle,
477
+ onPress: () => setShowPassword(!showPassword),
478
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_vectorIcons.Ionicons, {
479
+ name: showPassword ? 'eye-off' : 'eye',
480
+ size: 20,
481
+ color: colors.placeholder
482
+ })
483
+ })]
370
484
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
371
485
  style: [styles.passwordHint, {
372
- color: isDarkTheme ? '#AAAAAA' : '#666666'
486
+ color: colors.secondaryText
373
487
  }],
374
488
  children: "Password must be at least 8 characters long"
375
489
  })]
@@ -377,47 +491,64 @@ const SignUpScreen = ({
377
491
  style: styles.inputContainer,
378
492
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
379
493
  style: [styles.label, {
380
- color: textColor
494
+ color: colors.text
381
495
  }],
382
496
  children: "Confirm Password"
383
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TextInput, {
384
- style: [styles.input, {
385
- backgroundColor: inputBackgroundColor,
386
- borderColor,
387
- color: textColor
388
- }],
389
- placeholder: "Confirm your password",
390
- placeholderTextColor: placeholderColor,
391
- value: confirmPassword,
392
- onChangeText: setConfirmPassword,
393
- secureTextEntry: true,
394
- testID: "confirm-password-input"
497
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
498
+ style: {
499
+ position: 'relative'
500
+ },
501
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TextInput, {
502
+ style: [styles.input, {
503
+ backgroundColor: colors.inputBackground,
504
+ borderColor: colors.border,
505
+ color: colors.text
506
+ }],
507
+ placeholder: "Confirm your password",
508
+ placeholderTextColor: colors.placeholder,
509
+ value: confirmPassword,
510
+ onChangeText: handleConfirmPasswordChange,
511
+ secureTextEntry: !showConfirmPassword,
512
+ testID: "confirm-password-input"
513
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
514
+ style: styles.passwordToggle,
515
+ onPress: () => setShowConfirmPassword(!showConfirmPassword),
516
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_vectorIcons.Ionicons, {
517
+ name: showConfirmPassword ? 'eye-off' : 'eye',
518
+ size: 20,
519
+ color: colors.placeholder
520
+ })
521
+ })]
395
522
  })]
396
523
  }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
397
524
  style: styles.navigationButtons,
398
525
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
399
- style: [styles.navButton, styles.backButton],
526
+ style: [styles.navButton, styles.backButton, {
527
+ borderColor: colors.border
528
+ }],
400
529
  onPress: prevStep,
401
530
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
402
531
  style: [styles.navButtonText, {
403
- color: textColor
532
+ color: colors.text
404
533
  }],
405
534
  children: "Back"
406
535
  })
407
536
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
408
537
  style: [styles.navButton, styles.nextButton, {
409
- backgroundColor: primaryColor
538
+ backgroundColor: colors.primary
410
539
  }],
411
540
  onPress: nextStep,
412
541
  disabled: !password || password.length < 8 || password !== confirmPassword,
413
542
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
414
- style: styles.navButtonText,
543
+ style: [styles.navButtonText, {
544
+ color: '#FFFFFF'
545
+ }],
415
546
  children: "Next"
416
547
  })
417
548
  })]
418
549
  })]
419
- });
420
- const renderSummaryStep = () => /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Animated.View, {
550
+ }), [fadeAnim, slideAnim, colors, password, confirmPassword, showPassword, showConfirmPassword, handlePasswordChange, handleConfirmPasswordChange, prevStep, nextStep, styles]);
551
+ const renderSummaryStep = (0, _react.useMemo)(() => /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Animated.View, {
421
552
  style: [styles.stepContainer, {
422
553
  opacity: fadeAnim,
423
554
  transform: [{
@@ -426,7 +557,7 @@ const SignUpScreen = ({
426
557
  }],
427
558
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
428
559
  style: [styles.stepTitle, {
429
- color: textColor
560
+ color: colors.text
430
561
  }],
431
562
  children: "Ready to join"
432
563
  }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
@@ -435,12 +566,12 @@ const SignUpScreen = ({
435
566
  style: styles.summaryRow,
436
567
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
437
568
  style: [styles.summaryLabel, {
438
- color: isDarkTheme ? '#AAAAAA' : '#666666'
569
+ color: colors.secondaryText
439
570
  }],
440
571
  children: "Username:"
441
572
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
442
573
  style: [styles.summaryValue, {
443
- color: textColor
574
+ color: colors.text
444
575
  }],
445
576
  children: username
446
577
  })]
@@ -448,118 +579,187 @@ const SignUpScreen = ({
448
579
  style: styles.summaryRow,
449
580
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
450
581
  style: [styles.summaryLabel, {
451
- color: isDarkTheme ? '#AAAAAA' : '#666666'
582
+ color: colors.secondaryText
452
583
  }],
453
584
  children: "Email:"
454
585
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
455
586
  style: [styles.summaryValue, {
456
- color: textColor
587
+ color: colors.text
457
588
  }],
458
589
  children: email
459
590
  })]
460
591
  })]
461
- }), errorMessage ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
462
- style: styles.errorContainer,
463
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
464
- style: styles.errorText,
465
- children: errorMessage
592
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
593
+ style: [styles.button, {
594
+ backgroundColor: colors.primary
595
+ }],
596
+ onPress: handleSignUp,
597
+ disabled: isLoading,
598
+ testID: "signup-button",
599
+ children: isLoading ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.ActivityIndicator, {
600
+ color: "#FFFFFF",
601
+ size: "small"
602
+ }) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
603
+ style: styles.buttonText,
604
+ children: "Create Account"
466
605
  })
467
- }) : null, /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
606
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
468
607
  style: styles.navigationButtons,
469
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
470
- style: [styles.navButton, styles.backButton],
608
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
609
+ style: [styles.navButton, styles.backButton, {
610
+ borderColor: colors.border
611
+ }],
471
612
  onPress: prevStep,
472
613
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
473
614
  style: [styles.navButtonText, {
474
- color: textColor
615
+ color: colors.text
475
616
  }],
476
617
  children: "Back"
477
618
  })
478
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
479
- style: [styles.button, {
480
- opacity: isLoading ? 0.8 : 1
481
- }],
482
- onPress: handleSignUp,
483
- disabled: isLoading,
484
- testID: "signup-button",
485
- children: isLoading ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.ActivityIndicator, {
486
- color: "#FFFFFF",
487
- size: "small"
488
- }) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
489
- style: styles.buttonText,
490
- children: "Create Account"
491
- })
492
- })]
619
+ })
493
620
  })]
494
- });
495
-
496
- // Progress indicators
497
- const renderProgressIndicators = () => /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
621
+ }), [fadeAnim, slideAnim, colors, username, email, isLoading, handleSignUp, prevStep, styles]);
622
+ const renderProgressIndicators = (0, _react.useMemo)(() => /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
498
623
  style: styles.progressContainer,
499
624
  children: [0, 1, 2, 3].map(step => /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
500
625
  style: [styles.progressDot, currentStep === step ? {
501
- backgroundColor: primaryColor,
626
+ backgroundColor: colors.primary,
502
627
  width: 24
503
628
  } : {
504
- backgroundColor: isDarkTheme ? '#444444' : '#E0E0E0'
629
+ backgroundColor: colors.border
505
630
  }]
506
631
  }, step))
507
- });
508
-
509
- // Render step based on current step value
510
- const renderCurrentStep = () => {
632
+ }), [currentStep, colors, styles]);
633
+ const renderCurrentStep = (0, _react.useCallback)(() => {
511
634
  switch (currentStep) {
512
635
  case 0:
513
- return renderWelcomeStep();
636
+ return renderWelcomeStep;
514
637
  case 1:
515
- return renderIdentityStep();
638
+ return renderIdentityStep;
516
639
  case 2:
517
- return renderSecurityStep();
640
+ return renderSecurityStep;
518
641
  case 3:
519
- return renderSummaryStep();
642
+ return renderSummaryStep;
520
643
  default:
521
- return null;
644
+ return renderWelcomeStep;
522
645
  }
523
- };
524
- return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_bottomSheet.BottomSheetScrollView, {
525
- contentContainerStyle: styles.scrollContainer,
526
- keyboardShouldPersistTaps: "handled",
527
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_OxyLogo.default, {
528
- style: {
529
- marginBottom: 24
530
- },
531
- width: 50,
532
- height: 50
533
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
534
- style: styles.formContainer,
535
- children: renderCurrentStep()
536
- }), currentStep > 0 && renderProgressIndicators()]
646
+ }, [currentStep, renderWelcomeStep, renderIdentityStep, renderSecurityStep, renderSummaryStep]);
647
+
648
+ // If user is already authenticated, show user info and account center option
649
+ if (user && isAuthenticated) {
650
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.KeyboardAvoidingView, {
651
+ style: [styles.container, {
652
+ backgroundColor: colors.background
653
+ }],
654
+ behavior: _reactNative.Platform.OS === 'ios' ? 'padding' : 'height',
655
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.StatusBar, {
656
+ barStyle: theme === 'dark' ? 'light-content' : 'dark-content',
657
+ backgroundColor: colors.background
658
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.ScrollView, {
659
+ contentContainerStyle: styles.scrollContent,
660
+ showsVerticalScrollIndicator: false,
661
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Text, {
662
+ style: [styles.welcomeTitle, {
663
+ color: colors.text
664
+ }],
665
+ children: ["Welcome, ", user.username, "!"]
666
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
667
+ style: [styles.userInfoContainer, {
668
+ backgroundColor: colors.inputBackground
669
+ }],
670
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
671
+ style: [styles.userInfoText, {
672
+ color: colors.text
673
+ }],
674
+ children: "You are already signed in."
675
+ }), user.email && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Text, {
676
+ style: [styles.userInfoText, {
677
+ color: colors.secondaryText
678
+ }],
679
+ children: ["Email: ", user.email]
680
+ })]
681
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
682
+ style: styles.actionButtonsContainer,
683
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
684
+ style: [styles.button, {
685
+ backgroundColor: colors.primary
686
+ }],
687
+ onPress: () => navigate('AccountCenter'),
688
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
689
+ style: styles.buttonText,
690
+ children: "Go to Account Center"
691
+ })
692
+ })
693
+ })]
694
+ })]
695
+ });
696
+ }
697
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.KeyboardAvoidingView, {
698
+ style: [styles.container, {
699
+ backgroundColor: colors.background
700
+ }],
701
+ behavior: _reactNative.Platform.OS === 'ios' ? 'padding' : 'height',
702
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.StatusBar, {
703
+ barStyle: theme === 'dark' ? 'light-content' : 'dark-content',
704
+ backgroundColor: colors.background
705
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.ScrollView, {
706
+ contentContainerStyle: styles.scrollContent,
707
+ showsVerticalScrollIndicator: false,
708
+ keyboardShouldPersistTaps: "handled",
709
+ children: [renderProgressIndicators, renderCurrentStep()]
710
+ })]
537
711
  });
538
712
  };
539
- const styles = _reactNative.StyleSheet.create({
540
- scrollContainer: {
541
- padding: 20
713
+
714
+ // Memoized styles creation
715
+ const createStyles = (colors, theme) => _reactNative.StyleSheet.create({
716
+ container: {
717
+ flex: 1
542
718
  },
543
- header: {
544
- flexDirection: 'row',
719
+ scrollContent: {
720
+ flexGrow: 1,
721
+ paddingHorizontal: 24,
722
+ paddingTop: 40,
723
+ paddingBottom: 40
724
+ },
725
+ stepContainer: {
726
+ flex: 1,
727
+ justifyContent: 'center',
545
728
  alignItems: 'center',
546
- justifyContent: 'space-between'
729
+ minHeight: 500
547
730
  },
548
- placeholder: {
549
- width: 40
731
+ welcomeImageContainer: {
732
+ alignItems: 'center',
733
+ justifyContent: 'center',
734
+ marginVertical: 30
550
735
  },
551
- formContainer: {
552
- width: '100%',
553
- marginTop: 8
736
+ welcomeTitle: {
737
+ fontFamily: _reactNative.Platform.OS === 'web' ? 'Phudu' : 'Phudu-Bold',
738
+ fontWeight: _reactNative.Platform.OS === 'web' ? 'bold' : undefined,
739
+ fontSize: 42,
740
+ lineHeight: 48,
741
+ marginBottom: 24,
742
+ textAlign: 'left',
743
+ letterSpacing: -1
554
744
  },
555
- stepContainer: {
556
- width: '100%',
557
- paddingVertical: 8,
558
- paddingHorizontal: 0,
559
- marginBottom: 8
745
+ welcomeText: {
746
+ fontSize: 16,
747
+ textAlign: 'left',
748
+ marginBottom: 30,
749
+ lineHeight: 24
750
+ },
751
+ stepTitle: {
752
+ fontFamily: _reactNative.Platform.OS === 'web' ? 'Phudu' : 'Phudu-Bold',
753
+ fontWeight: _reactNative.Platform.OS === 'web' ? 'bold' : undefined,
754
+ fontSize: 34,
755
+ marginBottom: 20,
756
+ color: colors.primary,
757
+ maxWidth: '90%',
758
+ textAlign: 'left'
560
759
  },
561
760
  inputContainer: {
562
- marginBottom: 18
761
+ marginBottom: 18,
762
+ width: '100%'
563
763
  },
564
764
  label: {
565
765
  fontSize: 15,
@@ -573,25 +773,58 @@ const styles = _reactNative.StyleSheet.create({
573
773
  paddingHorizontal: 16,
574
774
  borderWidth: 1,
575
775
  fontSize: 16,
576
- backgroundColor: '#F5F5F5',
577
- borderColor: '#E0E0E0',
578
776
  marginBottom: 2
579
777
  },
778
+ validationIndicator: {
779
+ position: 'absolute',
780
+ right: 16,
781
+ top: 14
782
+ },
783
+ validationSuccessCard: {
784
+ flexDirection: 'row',
785
+ alignItems: 'center',
786
+ padding: 12,
787
+ borderRadius: 12,
788
+ marginTop: 8,
789
+ gap: 8
790
+ },
791
+ validationErrorCard: {
792
+ flexDirection: 'row',
793
+ alignItems: 'center',
794
+ padding: 12,
795
+ borderRadius: 12,
796
+ marginTop: 8,
797
+ gap: 8
798
+ },
799
+ validationText: {
800
+ fontSize: 12,
801
+ fontWeight: '500'
802
+ },
803
+ passwordToggle: {
804
+ position: 'absolute',
805
+ right: 16,
806
+ top: 14,
807
+ padding: 4
808
+ },
809
+ passwordHint: {
810
+ fontSize: 12,
811
+ marginTop: 4
812
+ },
580
813
  button: {
581
- backgroundColor: '#d169e5',
582
814
  height: 48,
583
815
  borderRadius: 24,
584
816
  alignItems: 'center',
585
817
  justifyContent: 'center',
586
818
  marginTop: 24,
587
- shadowColor: '#d169e5',
819
+ shadowColor: colors.primary,
588
820
  shadowOpacity: 0.12,
589
821
  shadowOffset: {
590
822
  width: 0,
591
823
  height: 2
592
824
  },
593
825
  shadowRadius: 8,
594
- elevation: 2
826
+ elevation: 2,
827
+ width: '100%'
595
828
  },
596
829
  buttonText: {
597
830
  color: '#FFFFFF',
@@ -605,31 +838,15 @@ const styles = _reactNative.StyleSheet.create({
605
838
  marginTop: 28
606
839
  },
607
840
  footerText: {
608
- fontSize: 15,
609
- color: '#888'
841
+ fontSize: 15
610
842
  },
611
843
  linkText: {
612
844
  fontSize: 15,
613
- fontWeight: '700',
614
- color: '#d169e5'
615
- },
616
- errorContainer: {
617
- backgroundColor: '#FFE4EC',
618
- padding: 14,
619
- borderRadius: 18,
620
- marginBottom: 16,
621
- borderWidth: 1,
622
- borderColor: '#F8BBD0'
623
- },
624
- errorText: {
625
- color: '#D32F2F',
626
- fontSize: 15,
627
- fontWeight: '500'
845
+ fontWeight: '700'
628
846
  },
629
847
  userInfoContainer: {
630
848
  padding: 20,
631
849
  marginVertical: 20,
632
- backgroundColor: '#F5F5F5',
633
850
  borderRadius: 24,
634
851
  alignItems: 'center',
635
852
  shadowColor: '#000',
@@ -649,44 +866,12 @@ const styles = _reactNative.StyleSheet.create({
649
866
  actionButtonsContainer: {
650
867
  marginTop: 24
651
868
  },
652
- // Multi-step form styles
653
- welcomeTitle: {
654
- fontFamily: _reactNative.Platform.OS === 'web' ? 'Phudu' // Use CSS font name directly for web
655
- : 'Phudu-Bold',
656
- // Use exact font name as registered with Font.loadAsync
657
- fontWeight: _reactNative.Platform.OS === 'web' ? 'bold' : undefined,
658
- // Only apply fontWeight on web
659
- fontSize: 54,
660
- marginBottom: 24
661
- },
662
- welcomeText: {
663
- fontSize: 16,
664
- textAlign: 'left',
665
- marginBottom: 30,
666
- lineHeight: 24,
667
- color: '#444'
668
- },
669
- welcomeImageContainer: {
670
- alignItems: 'center',
671
- justifyContent: 'center',
672
- marginVertical: 30
673
- },
674
- stepTitle: {
675
- fontFamily: _reactNative.Platform.OS === 'web' ? 'Phudu' // Use CSS font name directly for web
676
- : 'Phudu-Bold',
677
- // Use exact font name as registered with Font.loadAsync
678
- fontWeight: _reactNative.Platform.OS === 'web' ? 'bold' : undefined,
679
- // Only apply fontWeight on web
680
- fontSize: 34,
681
- marginBottom: 20,
682
- color: '#d169e5',
683
- maxWidth: '90%'
684
- },
685
869
  navigationButtons: {
686
870
  flexDirection: 'row',
687
871
  justifyContent: 'space-between',
688
872
  alignItems: 'center',
689
- marginTop: 28
873
+ marginTop: 28,
874
+ width: '100%'
690
875
  },
691
876
  navButton: {
692
877
  borderRadius: 24,
@@ -698,22 +883,14 @@ const styles = _reactNative.StyleSheet.create({
698
883
  },
699
884
  backButton: {
700
885
  backgroundColor: 'transparent',
701
- borderWidth: 1,
702
- borderColor: '#E0E0E0'
886
+ borderWidth: 1
703
887
  },
704
888
  nextButton: {
705
- minWidth: 100,
706
- backgroundColor: '#d169e5'
889
+ minWidth: 100
707
890
  },
708
891
  navButtonText: {
709
892
  fontSize: 16,
710
- fontWeight: '700',
711
- color: '#d169e5'
712
- },
713
- passwordHint: {
714
- fontSize: 12,
715
- marginTop: 4,
716
- color: '#888'
893
+ fontWeight: '700'
717
894
  },
718
895
  progressContainer: {
719
896
  flexDirection: 'row',
@@ -726,10 +903,9 @@ const styles = _reactNative.StyleSheet.create({
726
903
  width: 10,
727
904
  borderRadius: 5,
728
905
  marginHorizontal: 6,
729
- backgroundColor: '#E0E0E0',
730
906
  borderWidth: 2,
731
907
  borderColor: '#fff',
732
- shadowColor: '#d169e5',
908
+ shadowColor: colors.primary,
733
909
  shadowOpacity: 0.08,
734
910
  shadowOffset: {
735
911
  width: 0,
@@ -740,7 +916,8 @@ const styles = _reactNative.StyleSheet.create({
740
916
  },
741
917
  summaryContainer: {
742
918
  padding: 0,
743
- marginBottom: 24
919
+ marginBottom: 24,
920
+ width: '100%'
744
921
  },
745
922
  summaryRow: {
746
923
  flexDirection: 'row',
@@ -748,14 +925,12 @@ const styles = _reactNative.StyleSheet.create({
748
925
  },
749
926
  summaryLabel: {
750
927
  fontSize: 15,
751
- width: 90,
752
- color: '#888'
928
+ width: 90
753
929
  },
754
930
  summaryValue: {
755
931
  fontSize: 15,
756
932
  fontWeight: '600',
757
- flex: 1,
758
- color: '#222'
933
+ flex: 1
759
934
  }
760
935
  });
761
936
  var _default = exports.default = SignUpScreen;