@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,14 +6,12 @@ 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 _styles = require("../styles");
11
- var _OxyLogo = _interopRequireDefault(require("../components/OxyLogo"));
12
- var _Avatar = _interopRequireDefault(require("../components/Avatar"));
13
- var _bottomSheet = require("../components/bottomSheet");
9
+ var _OxyContext = require("../context/OxyContext.js");
10
+ var _index = require("../styles/index.js");
11
+ var _Avatar = _interopRequireDefault(require("../components/Avatar.js"));
14
12
  var _vectorIcons = require("@expo/vector-icons");
15
13
  var _reactNativeSvg = _interopRequireWildcard(require("react-native-svg"));
16
- var _sonner = require("../../lib/sonner");
14
+ var _sonner = require("../../lib/sonner.js");
17
15
  var _jsxRuntime = require("react/jsx-runtime");
18
16
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
19
17
  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); }
@@ -27,10 +25,16 @@ const SignInScreen = ({
27
25
  const [password, setPassword] = (0, _react.useState)('');
28
26
  const [errorMessage, setErrorMessage] = (0, _react.useState)('');
29
27
  const [userProfile, setUserProfile] = (0, _react.useState)(null);
28
+ const [showPassword, setShowPassword] = (0, _react.useState)(false);
30
29
 
31
30
  // Multi-step form states
32
31
  const [currentStep, setCurrentStep] = (0, _react.useState)(0);
33
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 to prevent repeated API calls
37
+ const validationCache = (0, _react.useRef)(new Map());
34
38
  const fadeAnim = (0, _react.useRef)(new _reactNative.Animated.Value(1)).current;
35
39
  const slideAnim = (0, _react.useRef)(new _reactNative.Animated.Value(0)).current;
36
40
  const scaleAnim = (0, _react.useRef)(new _reactNative.Animated.Value(1)).current;
@@ -42,13 +46,17 @@ const SignInScreen = ({
42
46
  isLoading,
43
47
  user,
44
48
  isAuthenticated,
45
- sessions
49
+ sessions,
50
+ oxyServices
46
51
  } = (0, _OxyContext.useOxy)();
47
- const colors = (0, _styles.useThemeColors)(theme);
48
- const commonStyles = (0, _styles.createCommonStyles)(theme);
52
+ const colors = (0, _index.useThemeColors)(theme);
53
+ const commonStyles = (0, _index.createCommonStyles)(theme);
49
54
 
50
55
  // Check if this should be treated as "Add Account" mode
51
- const isAddAccountMode = user && isAuthenticated && sessions && sessions.length > 0;
56
+ const isAddAccountMode = (0, _react.useMemo)(() => user && isAuthenticated && sessions && sessions.length > 0, [user, isAuthenticated, sessions]);
57
+
58
+ // Memoized styles to prevent rerenders
59
+ const styles = (0, _react.useMemo)(() => createStyles(colors, theme), [colors, theme]);
52
60
 
53
61
  // Initialize logo animation
54
62
  (0, _react.useEffect)(() => {
@@ -58,26 +66,153 @@ const SignInScreen = ({
58
66
  friction: 8,
59
67
  useNativeDriver: true
60
68
  }).start();
61
- }, []);
69
+ }, [logoAnim]);
62
70
 
63
71
  // Input focus animations
64
- const handleInputFocus = () => {
72
+ const handleInputFocus = (0, _react.useCallback)(() => {
65
73
  setIsInputFocused(true);
66
74
  _reactNative.Animated.spring(inputScaleAnim, {
67
75
  toValue: 1.02,
68
76
  useNativeDriver: true
69
77
  }).start();
70
- };
71
- const handleInputBlur = () => {
78
+ }, [inputScaleAnim]);
79
+ const handleInputBlur = (0, _react.useCallback)(() => {
72
80
  setIsInputFocused(false);
73
81
  _reactNative.Animated.spring(inputScaleAnim, {
74
82
  toValue: 1,
75
83
  useNativeDriver: true
76
84
  }).start();
77
- };
85
+ }, [inputScaleAnim]);
86
+
87
+ // Memoized input change handlers to prevent re-renders
88
+ const handleUsernameChange = (0, _react.useCallback)(text => {
89
+ setUsername(text);
90
+ // Only clear error if we're changing from an invalid state
91
+ if (validationStatus === 'invalid') {
92
+ setErrorMessage('');
93
+ setValidationStatus('idle');
94
+ }
95
+ }, [validationStatus]);
96
+ const handlePasswordChange = (0, _react.useCallback)(text => {
97
+ setPassword(text);
98
+ setErrorMessage(''); // Clear error when user types
99
+ }, []);
100
+
101
+ // Username validation using core services with caching
102
+ const validateUsername = (0, _react.useCallback)(async usernameToValidate => {
103
+ if (!usernameToValidate || usernameToValidate.length < 3) {
104
+ setValidationStatus('invalid');
105
+ return false;
106
+ }
107
+
108
+ // Check cache first (cache valid for 5 minutes)
109
+ const cached = validationCache.current.get(usernameToValidate);
110
+ const now = Date.now();
111
+ if (cached && now - cached.timestamp < 5 * 60 * 1000) {
112
+ setUserProfile(cached.profile);
113
+ setValidationStatus('valid');
114
+ setErrorMessage('');
115
+ return true;
116
+ }
117
+ setIsValidating(true);
118
+ setValidationStatus('validating');
119
+ try {
120
+ // First check if username exists by trying to get profile
121
+ const profile = await oxyServices.getUserProfileByUsername(usernameToValidate);
122
+ if (profile) {
123
+ const profileData = {
124
+ displayName: profile.name?.full || profile.name?.first || profile.username,
125
+ name: profile.username,
126
+ avatar: profile.avatar,
127
+ id: profile.id
128
+ };
129
+ setUserProfile(profileData);
130
+ setValidationStatus('valid');
131
+ setErrorMessage(''); // Clear any previous errors
132
+
133
+ // Cache the result
134
+ validationCache.current.set(usernameToValidate, {
135
+ profile: profileData,
136
+ timestamp: now
137
+ });
138
+ return true;
139
+ } else {
140
+ setValidationStatus('invalid');
141
+ setErrorMessage('Username not found. Please check your username or sign up.');
142
+ return false;
143
+ }
144
+ } catch (error) {
145
+ // If user not found (404), username doesn't exist
146
+ if (error.status === 404 || error.code === 'USER_NOT_FOUND') {
147
+ setValidationStatus('invalid');
148
+ setErrorMessage('Username not found. Please check your username or sign up.');
149
+ return false;
150
+ }
151
+
152
+ // For other errors, show generic message
153
+ console.error('Username validation error:', error);
154
+ setValidationStatus('invalid');
155
+ setErrorMessage('Unable to validate username. Please try again.');
156
+ return false;
157
+ } finally {
158
+ setIsValidating(false);
159
+ }
160
+ }, [oxyServices]);
161
+
162
+ // Debounced username validation - increased debounce time and added better conditions
163
+ (0, _react.useEffect)(() => {
164
+ if (!username || username.length < 3) {
165
+ setValidationStatus('idle');
166
+ setUserProfile(null);
167
+ setErrorMessage(''); // Clear error when input is too short
168
+ return;
169
+ }
170
+
171
+ // Only validate if we haven't already validated this exact username
172
+ if (validationStatus === 'valid' && userProfile?.name === username) {
173
+ return;
174
+ }
175
+ const timeoutId = setTimeout(() => {
176
+ validateUsername(username);
177
+ }, 800); // Increased debounce to 800ms
178
+
179
+ return () => clearTimeout(timeoutId);
180
+ }, [username, validateUsername, validationStatus, userProfile?.name]);
181
+
182
+ // Cleanup cache on unmount and limit cache size
183
+ (0, _react.useEffect)(() => {
184
+ return () => {
185
+ // Clear cache on unmount
186
+ validationCache.current.clear();
187
+ };
188
+ }, []);
189
+
190
+ // Clean up old cache entries periodically (older than 10 minutes)
191
+ (0, _react.useEffect)(() => {
192
+ const cleanupInterval = setInterval(() => {
193
+ const now = Date.now();
194
+ const maxAge = 10 * 60 * 1000; // 10 minutes
195
+
196
+ for (const [key, value] of validationCache.current.entries()) {
197
+ if (now - value.timestamp > maxAge) {
198
+ validationCache.current.delete(key);
199
+ }
200
+ }
201
+
202
+ // Limit cache size to 50 entries
203
+ if (validationCache.current.size > 50) {
204
+ const entries = Array.from(validationCache.current.entries());
205
+ entries.sort((a, b) => a[1].timestamp - b[1].timestamp);
206
+ const toDelete = entries.slice(0, entries.length - 50);
207
+ toDelete.forEach(([key]) => validationCache.current.delete(key));
208
+ }
209
+ }, 5 * 60 * 1000); // Clean up every 5 minutes
210
+
211
+ return () => clearInterval(cleanupInterval);
212
+ }, []);
78
213
 
79
214
  // Animation functions
80
- const animateTransition = nextStep => {
215
+ const animateTransition = (0, _react.useCallback)(nextStep => {
81
216
  // Scale down current content
82
217
  _reactNative.Animated.timing(scaleAnim, {
83
218
  toValue: 0.95,
@@ -114,8 +249,8 @@ const SignInScreen = ({
114
249
  useNativeDriver: true
115
250
  })]).start();
116
251
  });
117
- };
118
- const nextStep = () => {
252
+ }, [fadeAnim, slideAnim, scaleAnim]);
253
+ const nextStep = (0, _react.useCallback)(() => {
119
254
  if (currentStep < 1) {
120
255
  // Animate progress bar
121
256
  _reactNative.Animated.timing(progressAnim, {
@@ -125,8 +260,8 @@ const SignInScreen = ({
125
260
  }).start();
126
261
  animateTransition(currentStep + 1);
127
262
  }
128
- };
129
- const prevStep = () => {
263
+ }, [currentStep, progressAnim, animateTransition]);
264
+ const prevStep = (0, _react.useCallback)(() => {
130
265
  if (currentStep > 0) {
131
266
  // Animate progress bar
132
267
  _reactNative.Animated.timing(progressAnim, {
@@ -136,37 +271,31 @@ const SignInScreen = ({
136
271
  }).start();
137
272
  animateTransition(currentStep - 1);
138
273
  }
139
- };
140
-
141
- // Fetch user profile when username is entered
142
- (0, _react.useEffect)(() => {
143
- const fetchUserProfile = async () => {
144
- if (username.length >= 3 && currentStep === 1) {
145
- try {
146
- // For now, we'll create a mock profile based on username
147
- // In a real app, you'd fetch this from your API
148
- setUserProfile({
149
- displayName: username,
150
- name: username,
151
- avatar: null // Could be fetched from API
152
- });
153
- } catch (error) {
154
- // If user not found, we'll show a generic avatar
155
- setUserProfile(null);
156
- }
157
- }
158
- };
159
- fetchUserProfile();
160
- }, [username, currentStep]);
161
- const handleUsernameNext = () => {
274
+ }, [currentStep, progressAnim, animateTransition]);
275
+ const handleUsernameNext = (0, _react.useCallback)(() => {
162
276
  if (!username) {
163
277
  _sonner.toast.error('Please enter your username');
164
278
  return;
165
279
  }
166
- setErrorMessage('');
167
- nextStep();
168
- };
169
- const handleLogin = async () => {
280
+ if (validationStatus === 'invalid') {
281
+ // Don't show toast if we already have an error message displayed
282
+ if (!errorMessage) {
283
+ _sonner.toast.error('Please enter a valid username');
284
+ }
285
+ return;
286
+ }
287
+ if (validationStatus === 'validating') {
288
+ _sonner.toast.error('Please wait while we validate your username');
289
+ return;
290
+ }
291
+ if (validationStatus === 'valid' && userProfile) {
292
+ setErrorMessage('');
293
+ nextStep();
294
+ } else {
295
+ _sonner.toast.error('Please enter a valid username');
296
+ }
297
+ }, [username, validationStatus, userProfile, errorMessage, nextStep]);
298
+ const handleLogin = (0, _react.useCallback)(async () => {
170
299
  if (!username || !password) {
171
300
  _sonner.toast.error('Please enter both username and password');
172
301
  return;
@@ -178,10 +307,10 @@ const SignInScreen = ({
178
307
  } catch (error) {
179
308
  _sonner.toast.error(error.message || 'Login failed');
180
309
  }
181
- };
310
+ }, [username, password, login]);
182
311
 
183
- // Step components
184
- const renderUsernameStep = () => /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Animated.View, {
312
+ // Memoized step components
313
+ const renderUsernameStep = (0, _react.useMemo)(() => /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Animated.View, {
185
314
  style: [styles.stepContainer, {
186
315
  opacity: fadeAnim,
187
316
  transform: [{
@@ -332,15 +461,15 @@ const SignInScreen = ({
332
461
  }],
333
462
  children: errorMessage
334
463
  })]
335
- }) : null, /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Animated.View, {
464
+ }) : null, /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Animated.View, {
336
465
  style: [styles.modernInputContainer, {
337
466
  transform: [{
338
467
  scale: inputScaleAnim
339
468
  }]
340
469
  }],
341
- children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
470
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
342
471
  style: [styles.inputWrapper, {
343
- borderColor: isInputFocused ? colors.primary : colors.border
472
+ borderColor: validationStatus === 'valid' ? colors.success : validationStatus === 'invalid' ? colors.error : isInputFocused ? colors.primary : colors.border
344
473
  }],
345
474
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_vectorIcons.Ionicons, {
346
475
  name: "person-outline",
@@ -354,31 +483,78 @@ const SignInScreen = ({
354
483
  placeholder: "Enter your username",
355
484
  placeholderTextColor: colors.placeholder,
356
485
  value: username,
357
- onChangeText: setUsername,
486
+ onChangeText: handleUsernameChange,
358
487
  onFocus: handleInputFocus,
359
488
  onBlur: handleInputBlur,
360
489
  autoCapitalize: "none",
361
490
  testID: "username-input"
491
+ }), validationStatus === 'validating' && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.ActivityIndicator, {
492
+ size: "small",
493
+ color: colors.primary,
494
+ style: styles.validationIndicator
495
+ }), validationStatus === 'valid' && /*#__PURE__*/(0, _jsxRuntime.jsx)(_vectorIcons.Ionicons, {
496
+ name: "checkmark-circle",
497
+ size: 20,
498
+ color: colors.success,
499
+ style: styles.validationIndicator
500
+ }), validationStatus === 'invalid' && username.length >= 3 && /*#__PURE__*/(0, _jsxRuntime.jsx)(_vectorIcons.Ionicons, {
501
+ name: "close-circle",
502
+ size: 20,
503
+ color: colors.error,
504
+ style: styles.validationIndicator
362
505
  })]
363
- })
364
- }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.TouchableOpacity, {
506
+ }), validationStatus === 'valid' && userProfile && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
507
+ style: [styles.validationSuccessCard, {
508
+ backgroundColor: colors.success + '15'
509
+ }],
510
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_vectorIcons.Ionicons, {
511
+ name: "checkmark-circle",
512
+ size: 16,
513
+ color: colors.success
514
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Text, {
515
+ style: [styles.validationText, {
516
+ color: colors.success
517
+ }],
518
+ children: ["Found user: ", userProfile.displayName]
519
+ })]
520
+ }), validationStatus === 'invalid' && username.length >= 3 && !errorMessage && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
521
+ style: [styles.validationErrorCard, {
522
+ backgroundColor: colors.error + '15'
523
+ }],
524
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_vectorIcons.Ionicons, {
525
+ name: "alert-circle",
526
+ size: 16,
527
+ color: colors.error
528
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
529
+ style: [styles.validationText, {
530
+ color: colors.error
531
+ }],
532
+ children: "Username not found"
533
+ })]
534
+ })]
535
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
365
536
  style: [styles.modernButton, {
366
537
  backgroundColor: colors.primary,
367
- opacity: !username ? 0.5 : 1,
538
+ opacity: !username || validationStatus !== 'valid' ? 0.5 : 1,
368
539
  shadowColor: colors.primary
369
540
  }],
370
541
  onPress: handleUsernameNext,
371
- disabled: !username,
542
+ disabled: !username || validationStatus !== 'valid' || isValidating,
372
543
  testID: "username-next-button",
373
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
374
- style: styles.modernButtonText,
375
- children: "Continue"
376
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_vectorIcons.Ionicons, {
377
- name: "arrow-forward",
378
- size: 20,
544
+ children: isValidating ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.ActivityIndicator, {
379
545
  color: "#FFFFFF",
380
- style: styles.buttonIcon
381
- })]
546
+ size: "small"
547
+ }) : /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
548
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
549
+ style: styles.modernButtonText,
550
+ children: "Continue"
551
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_vectorIcons.Ionicons, {
552
+ name: "arrow-forward",
553
+ size: 20,
554
+ color: "#FFFFFF",
555
+ style: styles.buttonIcon
556
+ })]
557
+ })
382
558
  }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
383
559
  style: styles.footerTextContainer,
384
560
  children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Text, {
@@ -396,8 +572,8 @@ const SignInScreen = ({
396
572
  })
397
573
  })]
398
574
  })]
399
- });
400
- const renderPasswordStep = () => /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Animated.View, {
575
+ }), [fadeAnim, slideAnim, scaleAnim, colors, isAddAccountMode, user?.username, errorMessage, inputScaleAnim, isInputFocused, username, validationStatus, userProfile, isValidating, handleInputFocus, handleInputBlur, handleUsernameChange, handleUsernameNext, navigate, styles]);
576
+ const renderPasswordStep = (0, _react.useMemo)(() => /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Animated.View, {
401
577
  style: [styles.stepContainer, {
402
578
  opacity: fadeAnim,
403
579
  transform: [{
@@ -486,21 +662,30 @@ const SignInScreen = ({
486
662
  placeholder: "Enter your password",
487
663
  placeholderTextColor: colors.placeholder,
488
664
  value: password,
489
- onChangeText: setPassword,
665
+ onChangeText: handlePasswordChange,
490
666
  onFocus: handleInputFocus,
491
667
  onBlur: handleInputBlur,
492
- secureTextEntry: true,
668
+ secureTextEntry: !showPassword,
669
+ autoCapitalize: "none",
493
670
  testID: "password-input"
671
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
672
+ style: styles.passwordToggle,
673
+ onPress: () => setShowPassword(!showPassword),
674
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_vectorIcons.Ionicons, {
675
+ name: showPassword ? "eye-off" : "eye",
676
+ size: 20,
677
+ color: colors.secondaryText
678
+ })
494
679
  })]
495
680
  })
496
681
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
497
682
  style: [styles.modernButton, {
498
683
  backgroundColor: colors.primary,
499
- opacity: isLoading ? 0.8 : 1,
684
+ opacity: !password ? 0.5 : 1,
500
685
  shadowColor: colors.primary
501
686
  }],
502
687
  onPress: handleLogin,
503
- disabled: isLoading,
688
+ disabled: !password || isLoading,
504
689
  testID: "login-button",
505
690
  children: isLoading ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.ActivityIndicator, {
506
691
  color: "#FFFFFF",
@@ -508,9 +693,9 @@ const SignInScreen = ({
508
693
  }) : /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
509
694
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
510
695
  style: styles.modernButtonText,
511
- children: isAddAccountMode ? 'Add Account' : 'Sign In'
696
+ children: "Sign In"
512
697
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_vectorIcons.Ionicons, {
513
- name: "arrow-forward",
698
+ name: "log-in",
514
699
  size: 20,
515
700
  color: "#FFFFFF",
516
701
  style: styles.buttonIcon
@@ -524,8 +709,8 @@ const SignInScreen = ({
524
709
  }],
525
710
  onPress: prevStep,
526
711
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_vectorIcons.Ionicons, {
527
- name: "chevron-back",
528
- size: 20,
712
+ name: "arrow-back",
713
+ size: 18,
529
714
  color: colors.text
530
715
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
531
716
  style: [styles.modernBackButtonText, {
@@ -538,216 +723,123 @@ const SignInScreen = ({
538
723
  style: styles.securityNotice,
539
724
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_vectorIcons.Ionicons, {
540
725
  name: "shield-checkmark",
541
- size: 16,
726
+ size: 14,
542
727
  color: colors.secondaryText
543
728
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
544
729
  style: [styles.securityText, {
545
730
  color: colors.secondaryText
546
731
  }],
547
- children: "Your connection is secure and encrypted"
732
+ children: "Your data is encrypted and secure"
548
733
  })]
549
734
  })]
550
- });
551
- const renderCurrentStep = () => {
735
+ }), [fadeAnim, slideAnim, scaleAnim, colors, userProfile, username, theme, logoAnim, errorMessage, inputScaleAnim, isInputFocused, password, showPassword, handleInputFocus, handleInputBlur, handlePasswordChange, handleLogin, isLoading, prevStep, styles]);
736
+ const renderCurrentStep = (0, _react.useCallback)(() => {
552
737
  switch (currentStep) {
553
738
  case 0:
554
- return renderUsernameStep();
739
+ return renderUsernameStep;
555
740
  case 1:
556
- return renderPasswordStep();
741
+ return renderPasswordStep;
557
742
  default:
558
- return renderUsernameStep();
743
+ return renderUsernameStep;
559
744
  }
560
- };
561
- return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_bottomSheet.BottomSheetScrollView, {
562
- contentContainerStyle: commonStyles.scrollContainer,
563
- keyboardShouldPersistTaps: "handled",
564
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Animated.View, {
565
- style: [styles.logoContainer, {
566
- transform: [{
567
- scale: logoAnim
568
- }]
569
- }],
570
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_OxyLogo.default, {
571
- style: {
572
- marginBottom: 24
573
- },
574
- width: 50,
575
- height: 50
576
- })
577
- }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
578
- style: styles.modernProgressContainer,
579
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
580
- style: styles.progressTrack,
581
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Animated.View, {
582
- style: [styles.progressFill, {
583
- backgroundColor: colors.primary,
584
- width: progressAnim.interpolate({
585
- inputRange: [0, 1],
586
- outputRange: ['50%', '100%']
587
- })
588
- }]
589
- })
590
- }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Text, {
591
- style: [styles.progressText, {
592
- color: colors.secondaryText
593
- }],
594
- children: ["Step ", currentStep + 1, " of 2"]
595
- })]
596
- }), renderCurrentStep()]
745
+ }, [currentStep, renderUsernameStep, renderPasswordStep]);
746
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.KeyboardAvoidingView, {
747
+ style: [styles.container, {
748
+ backgroundColor: colors.background
749
+ }],
750
+ behavior: _reactNative.Platform.OS === 'ios' ? 'padding' : 'height',
751
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.StatusBar, {
752
+ barStyle: theme === 'dark' ? 'light-content' : 'dark-content',
753
+ backgroundColor: colors.background
754
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.ScrollView, {
755
+ contentContainerStyle: styles.scrollContent,
756
+ showsVerticalScrollIndicator: false,
757
+ keyboardShouldPersistTaps: "handled",
758
+ children: renderCurrentStep()
759
+ })]
597
760
  });
598
761
  };
599
- const styles = _reactNative.StyleSheet.create({
600
- // Legacy styles (keeping for compatibility)
601
- title: {
602
- fontFamily: _reactNative.Platform.OS === 'web' ? 'Phudu' : 'Phudu-Bold',
603
- fontWeight: _reactNative.Platform.OS === 'web' ? 'bold' : undefined,
604
- fontSize: 54,
605
- marginBottom: 24
606
- },
607
- formContainer: {
608
- width: '100%'
609
- },
610
- inputContainer: {
611
- marginBottom: 16
762
+
763
+ // Memoized styles creation
764
+ const createStyles = (colors, theme) => _reactNative.StyleSheet.create({
765
+ container: {
766
+ flex: 1
612
767
  },
613
- label: {
614
- fontSize: 14,
615
- fontWeight: '500',
616
- marginBottom: 8
768
+ scrollContent: {
769
+ flexGrow: 1,
770
+ paddingHorizontal: 24,
771
+ paddingTop: 40,
772
+ paddingBottom: 40
617
773
  },
618
- footerTextContainer: {
619
- flexDirection: 'row',
774
+ stepContainer: {
775
+ flex: 1,
620
776
  justifyContent: 'center',
621
- marginTop: 24
622
- },
623
- footerText: {
624
- fontSize: 14,
625
- lineHeight: 20
626
- },
627
- linkText: {
628
- fontSize: 14,
629
- lineHeight: 20,
630
- fontWeight: '600'
631
- },
632
- userInfoContainer: {
633
- padding: 20,
634
- marginVertical: 20,
635
- borderRadius: 35,
636
- alignItems: 'center'
637
- },
638
- userInfoText: {
639
- fontSize: 16,
640
- lineHeight: 24,
641
- textAlign: 'center'
642
- },
643
- actionButtonsContainer: {
644
- marginTop: 20
645
- },
646
- infoContainer: {
647
- padding: 16,
648
- marginVertical: 16,
649
- borderRadius: 8,
650
- alignItems: 'center'
651
- },
652
- infoText: {
653
- fontSize: 14,
654
- lineHeight: 20,
655
- textAlign: 'center'
656
- },
657
- // Modern UI Styles
658
- logoContainer: {
659
- alignItems: 'center',
660
- marginBottom: 16
661
- },
662
- modernProgressContainer: {
663
777
  alignItems: 'center',
664
- marginBottom: 40,
665
- paddingHorizontal: 20
666
- },
667
- progressTrack: {
668
- width: '100%',
669
- height: 4,
670
- backgroundColor: '#E5E5E5',
671
- borderRadius: 2,
672
- marginBottom: 8,
673
- overflow: 'hidden'
674
- },
675
- progressFill: {
676
- height: '100%',
677
- borderRadius: 2
778
+ minHeight: 600
678
779
  },
679
- progressText: {
680
- fontSize: 12,
681
- fontWeight: '500'
682
- },
683
- stepContainer: {
684
- width: '100%',
685
- minHeight: 450,
686
- paddingHorizontal: 20
687
- },
688
- // Modern Image Container
689
780
  modernImageContainer: {
690
781
  alignItems: 'center',
691
- marginBottom: 40,
692
- paddingVertical: 20
782
+ marginBottom: 40
693
783
  },
694
784
  modernHeader: {
695
- alignItems: 'center',
696
- marginBottom: 24
785
+ alignItems: 'flex-start',
786
+ width: '100%',
787
+ marginBottom: 32
697
788
  },
698
789
  modernTitle: {
699
790
  fontFamily: _reactNative.Platform.OS === 'web' ? 'Phudu' : 'Phudu-Bold',
700
791
  fontWeight: _reactNative.Platform.OS === 'web' ? 'bold' : undefined,
701
- fontSize: 54,
702
- textAlign: 'center',
703
- marginBottom: 8,
704
- letterSpacing: -0.5
792
+ fontSize: 42,
793
+ lineHeight: 48,
794
+ marginBottom: 12,
795
+ textAlign: 'left',
796
+ letterSpacing: -1
705
797
  },
706
798
  modernSubtitle: {
707
- fontSize: 16,
708
- lineHeight: 22,
709
- textAlign: 'center',
799
+ fontSize: 18,
800
+ lineHeight: 24,
801
+ textAlign: 'left',
710
802
  opacity: 0.8
711
803
  },
712
- // Modern Cards
713
804
  modernInfoCard: {
714
805
  flexDirection: 'row',
715
806
  alignItems: 'center',
716
807
  padding: 16,
717
- marginVertical: 16,
718
- borderRadius: 12,
719
- gap: 12
808
+ borderRadius: 16,
809
+ marginBottom: 24,
810
+ gap: 12,
811
+ width: '100%'
720
812
  },
721
813
  modernInfoText: {
722
814
  fontSize: 14,
723
- lineHeight: 20,
724
815
  flex: 1
725
816
  },
726
817
  modernErrorCard: {
727
818
  flexDirection: 'row',
728
819
  alignItems: 'center',
729
820
  padding: 16,
730
- marginVertical: 16,
731
- borderRadius: 12,
732
- gap: 12
821
+ borderRadius: 16,
822
+ marginBottom: 24,
823
+ gap: 12,
824
+ width: '100%'
733
825
  },
734
826
  errorText: {
735
827
  fontSize: 14,
736
- lineHeight: 20,
828
+ fontWeight: '500',
737
829
  flex: 1
738
830
  },
739
- // Modern Input Styles
740
831
  modernInputContainer: {
832
+ width: '100%',
741
833
  marginBottom: 24
742
834
  },
743
835
  inputWrapper: {
744
836
  flexDirection: 'row',
745
837
  alignItems: 'center',
746
- borderWidth: 2,
838
+ height: 56,
747
839
  borderRadius: 16,
748
- paddingHorizontal: 16,
749
- paddingVertical: 4,
750
- backgroundColor: 'rgba(0,0,0,0.02)'
840
+ paddingHorizontal: 20,
841
+ borderWidth: 2,
842
+ backgroundColor: colors.inputBackground
751
843
  },
752
844
  inputIcon: {
753
845
  marginRight: 12
@@ -755,10 +847,34 @@ const styles = _reactNative.StyleSheet.create({
755
847
  modernInput: {
756
848
  flex: 1,
757
849
  fontSize: 16,
758
- paddingVertical: 16,
850
+ height: '100%'
851
+ },
852
+ passwordToggle: {
853
+ padding: 4
854
+ },
855
+ validationIndicator: {
856
+ marginLeft: 8
857
+ },
858
+ validationSuccessCard: {
859
+ flexDirection: 'row',
860
+ alignItems: 'center',
861
+ padding: 12,
862
+ borderRadius: 12,
863
+ marginTop: 8,
864
+ gap: 8
865
+ },
866
+ validationErrorCard: {
867
+ flexDirection: 'row',
868
+ alignItems: 'center',
869
+ padding: 12,
870
+ borderRadius: 12,
871
+ marginTop: 8,
872
+ gap: 8
873
+ },
874
+ validationText: {
875
+ fontSize: 12,
759
876
  fontWeight: '500'
760
877
  },
761
- // Modern Button Styles
762
878
  modernButton: {
763
879
  flexDirection: 'row',
764
880
  alignItems: 'center',
@@ -774,7 +890,8 @@ const styles = _reactNative.StyleSheet.create({
774
890
  shadowOpacity: 0.3,
775
891
  shadowRadius: 8,
776
892
  elevation: 6,
777
- gap: 8
893
+ gap: 8,
894
+ width: '100%'
778
895
  },
779
896
  modernButtonText: {
780
897
  color: '#FFFFFF',
@@ -791,6 +908,14 @@ const styles = _reactNative.StyleSheet.create({
791
908
  fontWeight: '600',
792
909
  textDecorationLine: 'underline'
793
910
  },
911
+ footerTextContainer: {
912
+ flexDirection: 'row',
913
+ justifyContent: 'center',
914
+ marginTop: 28
915
+ },
916
+ footerText: {
917
+ fontSize: 15
918
+ },
794
919
  // Modern User Profile Styles
795
920
  modernUserProfileContainer: {
796
921
  alignItems: 'center',
@@ -873,83 +998,6 @@ const styles = _reactNative.StyleSheet.create({
873
998
  securityText: {
874
999
  fontSize: 12,
875
1000
  fontWeight: '500'
876
- },
877
- // Legacy compatibility styles
878
- progressContainer: {
879
- flexDirection: 'row',
880
- alignItems: 'center',
881
- justifyContent: 'center',
882
- marginBottom: 32,
883
- paddingHorizontal: 40
884
- },
885
- progressDot: {
886
- width: 12,
887
- height: 12,
888
- borderRadius: 6,
889
- marginHorizontal: 4
890
- },
891
- progressLine: {
892
- flex: 1,
893
- height: 2,
894
- marginHorizontal: 8
895
- },
896
- welcomeImageContainer: {
897
- alignItems: 'center',
898
- marginBottom: 32
899
- },
900
- header: {
901
- alignItems: 'center',
902
- marginBottom: 16
903
- },
904
- welcomeTitle: {
905
- fontFamily: _reactNative.Platform.OS === 'web' ? 'Phudu' : 'Phudu-Bold',
906
- fontWeight: _reactNative.Platform.OS === 'web' ? 'bold' : undefined,
907
- fontSize: 32,
908
- textAlign: 'center',
909
- marginBottom: 8
910
- },
911
- welcomeText: {
912
- fontSize: 16,
913
- lineHeight: 24,
914
- textAlign: 'center',
915
- marginBottom: 32,
916
- paddingHorizontal: 20
917
- },
918
- userProfileContainer: {
919
- alignItems: 'center',
920
- marginBottom: 32,
921
- paddingVertical: 20
922
- },
923
- userAvatar: {
924
- marginBottom: 16
925
- },
926
- userDisplayName: {
927
- fontSize: 24,
928
- fontWeight: 'bold',
929
- marginBottom: 4,
930
- textAlign: 'center'
931
- },
932
- usernameSubtext: {
933
- fontSize: 16,
934
- textAlign: 'center'
935
- },
936
- navigationButtons: {
937
- flexDirection: 'row',
938
- justifyContent: 'center',
939
- marginTop: 24
940
- },
941
- backButton: {
942
- flexDirection: 'row',
943
- alignItems: 'center',
944
- paddingVertical: 12,
945
- paddingHorizontal: 20,
946
- borderRadius: 12,
947
- borderWidth: 1
948
- },
949
- backButtonText: {
950
- fontSize: 16,
951
- fontWeight: '500',
952
- marginLeft: 8
953
1001
  }
954
1002
  });
955
1003
  var _default = exports.default = SignInScreen;