@oxyhq/services 5.3.10 → 5.3.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (93) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +63 -571
  3. package/lib/commonjs/core/index.js +103 -34
  4. package/lib/commonjs/core/index.js.map +1 -1
  5. package/lib/commonjs/lib/sonner.js +17 -0
  6. package/lib/commonjs/lib/sonner.js.map +1 -0
  7. package/lib/commonjs/lib/sonner.web.js +17 -0
  8. package/lib/commonjs/lib/sonner.web.js.map +1 -0
  9. package/lib/commonjs/ui/components/FollowButton.js +54 -4
  10. package/lib/commonjs/ui/components/FollowButton.js.map +1 -1
  11. package/lib/commonjs/ui/components/OxyProvider.js +22 -3
  12. package/lib/commonjs/ui/components/OxyProvider.js.map +1 -1
  13. package/lib/commonjs/ui/screens/AccountCenterScreen.js +4 -3
  14. package/lib/commonjs/ui/screens/AccountCenterScreen.js.map +1 -1
  15. package/lib/commonjs/ui/screens/AccountOverviewScreen.js +15 -14
  16. package/lib/commonjs/ui/screens/AccountOverviewScreen.js.map +1 -1
  17. package/lib/commonjs/ui/screens/AccountSettingsScreen.js +10 -9
  18. package/lib/commonjs/ui/screens/AccountSettingsScreen.js.map +1 -1
  19. package/lib/commonjs/ui/screens/AccountSwitcherScreen.js +17 -16
  20. package/lib/commonjs/ui/screens/AccountSwitcherScreen.js.map +1 -1
  21. package/lib/commonjs/ui/screens/AppInfoScreen.js +4 -5
  22. package/lib/commonjs/ui/screens/AppInfoScreen.js.map +1 -1
  23. package/lib/commonjs/ui/screens/SessionManagementScreen.js +7 -6
  24. package/lib/commonjs/ui/screens/SessionManagementScreen.js.map +1 -1
  25. package/lib/commonjs/ui/screens/SignInScreen.js +821 -74
  26. package/lib/commonjs/ui/screens/SignInScreen.js.map +1 -1
  27. package/lib/commonjs/ui/screens/SignUpScreen.js +7 -5
  28. package/lib/commonjs/ui/screens/SignUpScreen.js.map +1 -1
  29. package/lib/commonjs/ui/styles/theme.js +1 -1
  30. package/lib/module/core/index.js +103 -34
  31. package/lib/module/core/index.js.map +1 -1
  32. package/lib/module/lib/sonner.js +4 -0
  33. package/lib/module/lib/sonner.js.map +1 -0
  34. package/lib/module/lib/sonner.web.js +4 -0
  35. package/lib/module/lib/sonner.web.js.map +1 -0
  36. package/lib/module/ui/components/FollowButton.js +54 -4
  37. package/lib/module/ui/components/FollowButton.js.map +1 -1
  38. package/lib/module/ui/components/OxyProvider.js +22 -3
  39. package/lib/module/ui/components/OxyProvider.js.map +1 -1
  40. package/lib/module/ui/screens/AccountCenterScreen.js +4 -3
  41. package/lib/module/ui/screens/AccountCenterScreen.js.map +1 -1
  42. package/lib/module/ui/screens/AccountOverviewScreen.js +15 -14
  43. package/lib/module/ui/screens/AccountOverviewScreen.js.map +1 -1
  44. package/lib/module/ui/screens/AccountSettingsScreen.js +10 -9
  45. package/lib/module/ui/screens/AccountSettingsScreen.js.map +1 -1
  46. package/lib/module/ui/screens/AccountSwitcherScreen.js +17 -16
  47. package/lib/module/ui/screens/AccountSwitcherScreen.js.map +1 -1
  48. package/lib/module/ui/screens/AppInfoScreen.js +5 -6
  49. package/lib/module/ui/screens/AppInfoScreen.js.map +1 -1
  50. package/lib/module/ui/screens/SessionManagementScreen.js +7 -6
  51. package/lib/module/ui/screens/SessionManagementScreen.js.map +1 -1
  52. package/lib/module/ui/screens/SignInScreen.js +824 -77
  53. package/lib/module/ui/screens/SignInScreen.js.map +1 -1
  54. package/lib/module/ui/screens/SignUpScreen.js +7 -5
  55. package/lib/module/ui/screens/SignUpScreen.js.map +1 -1
  56. package/lib/module/ui/styles/theme.js +1 -1
  57. package/lib/typescript/core/index.d.ts +44 -23
  58. package/lib/typescript/core/index.d.ts.map +1 -1
  59. package/lib/typescript/lib/sonner.d.ts +2 -0
  60. package/lib/typescript/lib/sonner.d.ts.map +1 -0
  61. package/lib/typescript/lib/sonner.web.d.ts +2 -0
  62. package/lib/typescript/lib/sonner.web.d.ts.map +1 -0
  63. package/lib/typescript/models/interfaces.d.ts +24 -0
  64. package/lib/typescript/models/interfaces.d.ts.map +1 -1
  65. package/lib/typescript/ui/components/FollowButton.d.ts +32 -1
  66. package/lib/typescript/ui/components/FollowButton.d.ts.map +1 -1
  67. package/lib/typescript/ui/components/OxyProvider.d.ts.map +1 -1
  68. package/lib/typescript/ui/screens/AccountCenterScreen.d.ts.map +1 -1
  69. package/lib/typescript/ui/screens/AccountOverviewScreen.d.ts.map +1 -1
  70. package/lib/typescript/ui/screens/AccountSettingsScreen.d.ts.map +1 -1
  71. package/lib/typescript/ui/screens/AccountSwitcherScreen.d.ts.map +1 -1
  72. package/lib/typescript/ui/screens/AppInfoScreen.d.ts.map +1 -1
  73. package/lib/typescript/ui/screens/SessionManagementScreen.d.ts.map +1 -1
  74. package/lib/typescript/ui/screens/SignInScreen.d.ts.map +1 -1
  75. package/lib/typescript/ui/screens/SignUpScreen.d.ts.map +1 -1
  76. package/package.json +5 -3
  77. package/src/core/index.ts +104 -36
  78. package/src/lib/sonner.ts +1 -0
  79. package/src/lib/sonner.web.ts +1 -0
  80. package/src/models/interfaces.ts +29 -0
  81. package/src/ui/components/FollowButton.tsx +67 -3
  82. package/src/ui/components/OxyProvider.tsx +15 -0
  83. package/src/ui/screens/AccountCenterScreen.tsx +4 -3
  84. package/src/ui/screens/AccountOverviewScreen.tsx +15 -14
  85. package/src/ui/screens/AccountSettingsScreen.tsx +10 -9
  86. package/src/ui/screens/AccountSwitcherScreen.tsx +17 -16
  87. package/src/ui/screens/AppInfoScreen.tsx +4 -7
  88. package/src/ui/screens/SessionManagementScreen.tsx +7 -15
  89. package/src/ui/screens/SignInScreen.tsx +729 -52
  90. package/src/ui/screens/SignUpScreen.tsx +7 -5
  91. package/src/ui/styles/theme.ts +1 -1
  92. package/CHANGELOG.md +0 -97
  93. package/UI_COMPONENTS.md +0 -462
@@ -1,19 +1,36 @@
1
1
  "use strict";
2
2
 
3
- import React, { useState } from 'react';
4
- import { View, Text, TextInput, TouchableOpacity, StyleSheet, ActivityIndicator, Platform } from 'react-native';
3
+ import React, { useState, useRef, useEffect } from 'react';
4
+ import { View, Text, TextInput, TouchableOpacity, StyleSheet, ActivityIndicator, Platform, Animated } from 'react-native';
5
5
  import { useOxy } from '../context/OxyContext';
6
6
  import { useThemeColors, createCommonStyles } from '../styles';
7
7
  import OxyLogo from '../components/OxyLogo';
8
+ import Avatar from '../components/Avatar';
8
9
  import { BottomSheetScrollView } from '@gorhom/bottom-sheet';
9
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
10
+ import { Ionicons } from '@expo/vector-icons';
11
+ import Svg, { Path, Circle, Defs, LinearGradient, Stop } from 'react-native-svg';
12
+ import { toast } from '../../lib/sonner';
13
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
10
14
  const SignInScreen = ({
11
15
  navigate,
16
+ goBack,
12
17
  theme
13
18
  }) => {
19
+ // Form data states
14
20
  const [username, setUsername] = useState('');
15
21
  const [password, setPassword] = useState('');
16
22
  const [errorMessage, setErrorMessage] = useState('');
23
+ const [userProfile, setUserProfile] = useState(null);
24
+
25
+ // Multi-step form states
26
+ const [currentStep, setCurrentStep] = useState(0);
27
+ const [isInputFocused, setIsInputFocused] = useState(false);
28
+ const fadeAnim = useRef(new Animated.Value(1)).current;
29
+ const slideAnim = useRef(new Animated.Value(0)).current;
30
+ const scaleAnim = useRef(new Animated.Value(1)).current;
31
+ const inputScaleAnim = useRef(new Animated.Value(1)).current;
32
+ const logoAnim = useRef(new Animated.Value(0)).current;
33
+ const progressAnim = useRef(new Animated.Value(0.5)).current;
17
34
  const {
18
35
  login,
19
36
  isLoading,
@@ -26,9 +43,126 @@ const SignInScreen = ({
26
43
 
27
44
  // Check if this should be treated as "Add Account" mode
28
45
  const isAddAccountMode = user && isAuthenticated && sessions && sessions.length > 0;
46
+
47
+ // Initialize logo animation
48
+ useEffect(() => {
49
+ Animated.spring(logoAnim, {
50
+ toValue: 1,
51
+ tension: 50,
52
+ friction: 8,
53
+ useNativeDriver: true
54
+ }).start();
55
+ }, []);
56
+
57
+ // Input focus animations
58
+ const handleInputFocus = () => {
59
+ setIsInputFocused(true);
60
+ Animated.spring(inputScaleAnim, {
61
+ toValue: 1.02,
62
+ useNativeDriver: true
63
+ }).start();
64
+ };
65
+ const handleInputBlur = () => {
66
+ setIsInputFocused(false);
67
+ Animated.spring(inputScaleAnim, {
68
+ toValue: 1,
69
+ useNativeDriver: true
70
+ }).start();
71
+ };
72
+
73
+ // Animation functions
74
+ const animateTransition = nextStep => {
75
+ // Scale down current content
76
+ Animated.timing(scaleAnim, {
77
+ toValue: 0.95,
78
+ duration: 150,
79
+ useNativeDriver: true
80
+ }).start();
81
+
82
+ // Fade out
83
+ Animated.timing(fadeAnim, {
84
+ toValue: 0,
85
+ duration: 200,
86
+ useNativeDriver: true
87
+ }).start(() => {
88
+ setCurrentStep(nextStep);
89
+
90
+ // Reset animations
91
+ slideAnim.setValue(-50);
92
+ scaleAnim.setValue(0.95);
93
+
94
+ // Animate in new content
95
+ Animated.parallel([Animated.timing(fadeAnim, {
96
+ toValue: 1,
97
+ duration: 300,
98
+ useNativeDriver: true
99
+ }), Animated.spring(slideAnim, {
100
+ toValue: 0,
101
+ tension: 80,
102
+ friction: 8,
103
+ useNativeDriver: true
104
+ }), Animated.spring(scaleAnim, {
105
+ toValue: 1,
106
+ tension: 80,
107
+ friction: 8,
108
+ useNativeDriver: true
109
+ })]).start();
110
+ });
111
+ };
112
+ const nextStep = () => {
113
+ if (currentStep < 1) {
114
+ // Animate progress bar
115
+ Animated.timing(progressAnim, {
116
+ toValue: 1.0,
117
+ duration: 300,
118
+ useNativeDriver: false
119
+ }).start();
120
+ animateTransition(currentStep + 1);
121
+ }
122
+ };
123
+ const prevStep = () => {
124
+ if (currentStep > 0) {
125
+ // Animate progress bar
126
+ Animated.timing(progressAnim, {
127
+ toValue: 0.5,
128
+ duration: 300,
129
+ useNativeDriver: false
130
+ }).start();
131
+ animateTransition(currentStep - 1);
132
+ }
133
+ };
134
+
135
+ // Fetch user profile when username is entered
136
+ useEffect(() => {
137
+ const fetchUserProfile = async () => {
138
+ if (username.length >= 3 && currentStep === 1) {
139
+ try {
140
+ // For now, we'll create a mock profile based on username
141
+ // In a real app, you'd fetch this from your API
142
+ setUserProfile({
143
+ displayName: username,
144
+ name: username,
145
+ avatar: null // Could be fetched from API
146
+ });
147
+ } catch (error) {
148
+ // If user not found, we'll show a generic avatar
149
+ setUserProfile(null);
150
+ }
151
+ }
152
+ };
153
+ fetchUserProfile();
154
+ }, [username, currentStep]);
155
+ const handleUsernameNext = () => {
156
+ if (!username) {
157
+ toast.error('Please enter your username');
158
+ return;
159
+ }
160
+ setErrorMessage('');
161
+ nextStep();
162
+ };
29
163
  const handleLogin = async () => {
30
164
  if (!username || !password) {
31
- setErrorMessage('Please enter both username and password');
165
+ toast.error('Please enter both username and password');
32
166
  return;
33
167
  }
34
168
  try {
@@ -36,114 +170,431 @@ const SignInScreen = ({
36
170
  await login(username, password);
37
171
  // The authentication state change will be handled through context
38
172
  } catch (error) {
39
- setErrorMessage(error.message || 'Login failed');
173
+ toast.error(error.message || 'Login failed');
40
174
  }
41
175
  };
42
- return /*#__PURE__*/_jsxs(BottomSheetScrollView, {
43
- contentContainerStyle: commonStyles.scrollContainer,
44
- keyboardShouldPersistTaps: "handled",
45
- children: [/*#__PURE__*/_jsx(OxyLogo, {
46
- style: {
47
- marginBottom: 24
48
- },
49
- width: 50,
50
- height: 50
51
- }), /*#__PURE__*/_jsx(Text, {
52
- style: [styles.title, {
53
- color: colors.text
54
- }],
55
- children: isAddAccountMode ? 'Add Another Account' : 'Sign In'
56
- }), isAddAccountMode && /*#__PURE__*/_jsx(View, {
57
- style: [styles.infoContainer, {
176
+
177
+ // Step components
178
+ const renderUsernameStep = () => /*#__PURE__*/_jsxs(Animated.View, {
179
+ style: [styles.stepContainer, {
180
+ opacity: fadeAnim,
181
+ transform: [{
182
+ translateX: slideAnim
183
+ }, {
184
+ scale: scaleAnim
185
+ }]
186
+ }],
187
+ children: [/*#__PURE__*/_jsx(View, {
188
+ style: styles.modernImageContainer,
189
+ children: /*#__PURE__*/_jsxs(Svg, {
190
+ width: 280,
191
+ height: 160,
192
+ viewBox: "0 0 280 160",
193
+ children: [/*#__PURE__*/_jsxs(Defs, {
194
+ children: [/*#__PURE__*/_jsxs(LinearGradient, {
195
+ id: "primaryGradient",
196
+ x1: "0%",
197
+ y1: "0%",
198
+ x2: "100%",
199
+ y2: "100%",
200
+ children: [/*#__PURE__*/_jsx(Stop, {
201
+ offset: "0%",
202
+ stopColor: colors.primary,
203
+ stopOpacity: "0.8"
204
+ }), /*#__PURE__*/_jsx(Stop, {
205
+ offset: "100%",
206
+ stopColor: colors.primary,
207
+ stopOpacity: "0.2"
208
+ })]
209
+ }), /*#__PURE__*/_jsxs(LinearGradient, {
210
+ id: "secondaryGradient",
211
+ x1: "0%",
212
+ y1: "0%",
213
+ x2: "100%",
214
+ y2: "100%",
215
+ children: [/*#__PURE__*/_jsx(Stop, {
216
+ offset: "0%",
217
+ stopColor: colors.primary,
218
+ stopOpacity: "0.1"
219
+ }), /*#__PURE__*/_jsx(Stop, {
220
+ offset: "100%",
221
+ stopColor: colors.primary,
222
+ stopOpacity: "0.3"
223
+ })]
224
+ })]
225
+ }), /*#__PURE__*/_jsx(Circle, {
226
+ cx: "80",
227
+ cy: "80",
228
+ r: "45",
229
+ fill: "url(#primaryGradient)"
230
+ }), /*#__PURE__*/_jsx(Circle, {
231
+ cx: "200",
232
+ cy: "80",
233
+ r: "35",
234
+ fill: "url(#secondaryGradient)"
235
+ }), /*#__PURE__*/_jsx(Path, {
236
+ d: "M40 120 Q80 40 140 80 Q200 120 240 60",
237
+ stroke: colors.primary,
238
+ strokeWidth: "4",
239
+ fill: "none",
240
+ strokeLinecap: "round"
241
+ }), /*#__PURE__*/_jsx(Circle, {
242
+ cx: "60",
243
+ cy: "50",
244
+ r: "8",
245
+ fill: colors.primary,
246
+ opacity: "0.6"
247
+ }), /*#__PURE__*/_jsx(Circle, {
248
+ cx: "220",
249
+ cy: "120",
250
+ r: "6",
251
+ fill: colors.primary,
252
+ opacity: "0.4"
253
+ }), /*#__PURE__*/_jsx(Circle, {
254
+ cx: "250",
255
+ cy: "40",
256
+ r: "4",
257
+ fill: colors.primary,
258
+ opacity: "0.8"
259
+ }), /*#__PURE__*/_jsx(Circle, {
260
+ cx: "140",
261
+ cy: "80",
262
+ r: "25",
263
+ fill: colors.background,
264
+ opacity: "0.9"
265
+ }), /*#__PURE__*/_jsx(Circle, {
266
+ cx: "135",
267
+ cy: "75",
268
+ r: "3",
269
+ fill: colors.primary
270
+ }), /*#__PURE__*/_jsx(Circle, {
271
+ cx: "145",
272
+ cy: "75",
273
+ r: "3",
274
+ fill: colors.primary
275
+ }), /*#__PURE__*/_jsx(Path, {
276
+ d: "M132 85 Q140 92 148 85",
277
+ stroke: colors.primary,
278
+ strokeWidth: "2",
279
+ fill: "none",
280
+ strokeLinecap: "round"
281
+ })]
282
+ })
283
+ }), /*#__PURE__*/_jsxs(View, {
284
+ style: styles.modernHeader,
285
+ children: [/*#__PURE__*/_jsx(Text, {
286
+ style: [styles.modernTitle, {
287
+ color: colors.text
288
+ }],
289
+ children: isAddAccountMode ? 'Add Account' : 'Welcome Back'
290
+ }), /*#__PURE__*/_jsx(Text, {
291
+ style: [styles.modernSubtitle, {
292
+ color: colors.secondaryText
293
+ }],
294
+ children: isAddAccountMode ? 'Sign in with another account' : 'Sign in to continue your journey'
295
+ })]
296
+ }), isAddAccountMode && /*#__PURE__*/_jsxs(View, {
297
+ style: [styles.modernInfoCard, {
58
298
  backgroundColor: colors.inputBackground
59
299
  }],
60
- children: /*#__PURE__*/_jsxs(Text, {
61
- style: [styles.infoText, {
62
- color: colors.secondaryText
300
+ children: [/*#__PURE__*/_jsx(Ionicons, {
301
+ name: "information-circle",
302
+ size: 20,
303
+ color: colors.primary
304
+ }), /*#__PURE__*/_jsxs(Text, {
305
+ style: [styles.modernInfoText, {
306
+ color: colors.text
307
+ }],
308
+ children: ["Currently signed in as ", /*#__PURE__*/_jsx(Text, {
309
+ style: {
310
+ fontWeight: 'bold'
311
+ },
312
+ children: user?.username
313
+ })]
314
+ })]
315
+ }), errorMessage ? /*#__PURE__*/_jsxs(Animated.View, {
316
+ style: [styles.modernErrorCard, {
317
+ backgroundColor: '#FF6B6B20'
318
+ }],
319
+ children: [/*#__PURE__*/_jsx(Ionicons, {
320
+ name: "alert-circle",
321
+ size: 20,
322
+ color: "#FF6B6B"
323
+ }), /*#__PURE__*/_jsx(Text, {
324
+ style: [styles.errorText, {
325
+ color: '#FF6B6B'
63
326
  }],
64
- children: ["Currently signed in as ", user?.username, ". Sign in with another account to add it to this device."]
65
- })
66
- }), errorMessage ? /*#__PURE__*/_jsx(View, {
67
- style: commonStyles.errorContainer,
68
- children: /*#__PURE__*/_jsx(Text, {
69
- style: commonStyles.errorText,
70
327
  children: errorMessage
71
- })
72
- }) : null, /*#__PURE__*/_jsxs(View, {
73
- style: styles.formContainer,
74
- children: [/*#__PURE__*/_jsxs(View, {
75
- style: styles.inputContainer,
76
- children: [/*#__PURE__*/_jsx(Text, {
77
- style: [styles.label, {
328
+ })]
329
+ }) : null, /*#__PURE__*/_jsx(Animated.View, {
330
+ style: [styles.modernInputContainer, {
331
+ transform: [{
332
+ scale: inputScaleAnim
333
+ }]
334
+ }],
335
+ children: /*#__PURE__*/_jsxs(View, {
336
+ style: [styles.inputWrapper, {
337
+ borderColor: isInputFocused ? colors.primary : colors.border
338
+ }],
339
+ children: [/*#__PURE__*/_jsx(Ionicons, {
340
+ name: "person-outline",
341
+ size: 20,
342
+ color: isInputFocused ? colors.primary : colors.secondaryText,
343
+ style: styles.inputIcon
344
+ }), /*#__PURE__*/_jsx(TextInput, {
345
+ style: [styles.modernInput, {
78
346
  color: colors.text
79
347
  }],
80
- children: "Username"
81
- }), /*#__PURE__*/_jsx(TextInput, {
82
- style: commonStyles.input,
83
348
  placeholder: "Enter your username",
84
349
  placeholderTextColor: colors.placeholder,
85
350
  value: username,
86
351
  onChangeText: setUsername,
352
+ onFocus: handleInputFocus,
353
+ onBlur: handleInputBlur,
87
354
  autoCapitalize: "none",
88
355
  testID: "username-input"
89
356
  })]
357
+ })
358
+ }), /*#__PURE__*/_jsxs(TouchableOpacity, {
359
+ style: [styles.modernButton, {
360
+ backgroundColor: colors.primary,
361
+ opacity: !username ? 0.5 : 1,
362
+ shadowColor: colors.primary
363
+ }],
364
+ onPress: handleUsernameNext,
365
+ disabled: !username,
366
+ testID: "username-next-button",
367
+ children: [/*#__PURE__*/_jsx(Text, {
368
+ style: styles.modernButtonText,
369
+ children: "Continue"
370
+ }), /*#__PURE__*/_jsx(Ionicons, {
371
+ name: "arrow-forward",
372
+ size: 20,
373
+ color: "#FFFFFF",
374
+ style: styles.buttonIcon
375
+ })]
376
+ }), /*#__PURE__*/_jsxs(View, {
377
+ style: styles.footerTextContainer,
378
+ children: [/*#__PURE__*/_jsxs(Text, {
379
+ style: [styles.footerText, {
380
+ color: colors.secondaryText
381
+ }],
382
+ children: ["Don't have an account?", ' ']
383
+ }), /*#__PURE__*/_jsx(TouchableOpacity, {
384
+ onPress: () => navigate('SignUp'),
385
+ children: /*#__PURE__*/_jsx(Text, {
386
+ style: [styles.modernLinkText, {
387
+ color: colors.primary
388
+ }],
389
+ children: "Sign Up"
390
+ })
391
+ })]
392
+ })]
393
+ });
394
+ const renderPasswordStep = () => /*#__PURE__*/_jsxs(Animated.View, {
395
+ style: [styles.stepContainer, {
396
+ opacity: fadeAnim,
397
+ transform: [{
398
+ translateX: slideAnim
399
+ }, {
400
+ scale: scaleAnim
401
+ }]
402
+ }],
403
+ children: [/*#__PURE__*/_jsxs(View, {
404
+ style: styles.modernUserProfileContainer,
405
+ children: [/*#__PURE__*/_jsxs(Animated.View, {
406
+ style: [styles.avatarContainer, {
407
+ transform: [{
408
+ scale: logoAnim
409
+ }]
410
+ }],
411
+ children: [/*#__PURE__*/_jsx(Avatar, {
412
+ uri: userProfile?.avatar,
413
+ name: userProfile?.displayName || userProfile?.name || username,
414
+ size: 100,
415
+ theme: theme,
416
+ style: styles.modernUserAvatar
417
+ }), /*#__PURE__*/_jsx(View, {
418
+ style: [styles.statusIndicator, {
419
+ backgroundColor: colors.primary
420
+ }]
421
+ })]
422
+ }), /*#__PURE__*/_jsx(Text, {
423
+ style: [styles.modernUserDisplayName, {
424
+ color: colors.text
425
+ }],
426
+ children: userProfile?.displayName || userProfile?.name || username
427
+ }), /*#__PURE__*/_jsxs(Text, {
428
+ style: [styles.modernUsernameSubtext, {
429
+ color: colors.secondaryText
430
+ }],
431
+ children: ["@", username]
90
432
  }), /*#__PURE__*/_jsxs(View, {
91
- style: styles.inputContainer,
92
- children: [/*#__PURE__*/_jsx(Text, {
93
- style: [styles.label, {
94
- color: colors.text
433
+ style: [styles.welcomeBackBadge, {
434
+ backgroundColor: colors.primary + '15'
435
+ }],
436
+ children: [/*#__PURE__*/_jsx(Ionicons, {
437
+ name: "checkmark-circle",
438
+ size: 16,
439
+ color: colors.primary
440
+ }), /*#__PURE__*/_jsx(Text, {
441
+ style: [styles.welcomeBackText, {
442
+ color: colors.primary
95
443
  }],
96
- children: "Password"
444
+ children: "Welcome back!"
445
+ })]
446
+ })]
447
+ }), errorMessage ? /*#__PURE__*/_jsxs(Animated.View, {
448
+ style: [styles.modernErrorCard, {
449
+ backgroundColor: '#FF6B6B20'
450
+ }],
451
+ children: [/*#__PURE__*/_jsx(Ionicons, {
452
+ name: "alert-circle",
453
+ size: 20,
454
+ color: "#FF6B6B"
455
+ }), /*#__PURE__*/_jsx(Text, {
456
+ style: [styles.errorText, {
457
+ color: '#FF6B6B'
458
+ }],
459
+ children: errorMessage
460
+ })]
461
+ }) : null, /*#__PURE__*/_jsx(Animated.View, {
462
+ style: [styles.modernInputContainer, {
463
+ transform: [{
464
+ scale: inputScaleAnim
465
+ }]
466
+ }],
467
+ children: /*#__PURE__*/_jsxs(View, {
468
+ style: [styles.inputWrapper, {
469
+ borderColor: isInputFocused ? colors.primary : colors.border
470
+ }],
471
+ children: [/*#__PURE__*/_jsx(Ionicons, {
472
+ name: "lock-closed-outline",
473
+ size: 20,
474
+ color: isInputFocused ? colors.primary : colors.secondaryText,
475
+ style: styles.inputIcon
97
476
  }), /*#__PURE__*/_jsx(TextInput, {
98
- style: commonStyles.input,
477
+ style: [styles.modernInput, {
478
+ color: colors.text
479
+ }],
99
480
  placeholder: "Enter your password",
100
481
  placeholderTextColor: colors.placeholder,
101
482
  value: password,
102
483
  onChangeText: setPassword,
484
+ onFocus: handleInputFocus,
485
+ onBlur: handleInputBlur,
103
486
  secureTextEntry: true,
104
487
  testID: "password-input"
105
488
  })]
106
- }), /*#__PURE__*/_jsx(TouchableOpacity, {
107
- style: [commonStyles.button, {
108
- opacity: isLoading ? 0.8 : 1
109
- }],
110
- onPress: handleLogin,
111
- disabled: isLoading,
112
- testID: "login-button",
113
- children: isLoading ? /*#__PURE__*/_jsx(ActivityIndicator, {
114
- color: "#FFFFFF",
115
- size: "small"
116
- }) : /*#__PURE__*/_jsx(Text, {
117
- style: commonStyles.buttonText,
489
+ })
490
+ }), /*#__PURE__*/_jsx(TouchableOpacity, {
491
+ style: [styles.modernButton, {
492
+ backgroundColor: colors.primary,
493
+ opacity: isLoading ? 0.8 : 1,
494
+ shadowColor: colors.primary
495
+ }],
496
+ onPress: handleLogin,
497
+ disabled: isLoading,
498
+ testID: "login-button",
499
+ children: isLoading ? /*#__PURE__*/_jsx(ActivityIndicator, {
500
+ color: "#FFFFFF",
501
+ size: "small"
502
+ }) : /*#__PURE__*/_jsxs(_Fragment, {
503
+ children: [/*#__PURE__*/_jsx(Text, {
504
+ style: styles.modernButtonText,
118
505
  children: isAddAccountMode ? 'Add Account' : 'Sign In'
119
- })
120
- }), /*#__PURE__*/_jsxs(View, {
121
- style: styles.footerTextContainer,
122
- children: [/*#__PURE__*/_jsxs(Text, {
123
- style: [styles.footerText, {
506
+ }), /*#__PURE__*/_jsx(Ionicons, {
507
+ name: "arrow-forward",
508
+ size: 20,
509
+ color: "#FFFFFF",
510
+ style: styles.buttonIcon
511
+ })]
512
+ })
513
+ }), /*#__PURE__*/_jsx(View, {
514
+ style: styles.modernNavigationButtons,
515
+ children: /*#__PURE__*/_jsxs(TouchableOpacity, {
516
+ style: [styles.modernBackButton, {
517
+ borderColor: colors.border
518
+ }],
519
+ onPress: prevStep,
520
+ children: [/*#__PURE__*/_jsx(Ionicons, {
521
+ name: "chevron-back",
522
+ size: 20,
523
+ color: colors.text
524
+ }), /*#__PURE__*/_jsx(Text, {
525
+ style: [styles.modernBackButtonText, {
124
526
  color: colors.text
125
527
  }],
126
- children: ["Don't have an account?", ' ']
127
- }), /*#__PURE__*/_jsx(TouchableOpacity, {
128
- onPress: () => navigate('SignUp'),
129
- children: /*#__PURE__*/_jsx(Text, {
130
- style: [styles.linkText, {
131
- color: colors.primary
132
- }],
133
- children: "Sign Up"
134
- })
528
+ children: "Back"
135
529
  })]
530
+ })
531
+ }), /*#__PURE__*/_jsxs(View, {
532
+ style: styles.securityNotice,
533
+ children: [/*#__PURE__*/_jsx(Ionicons, {
534
+ name: "shield-checkmark",
535
+ size: 16,
536
+ color: colors.secondaryText
537
+ }), /*#__PURE__*/_jsx(Text, {
538
+ style: [styles.securityText, {
539
+ color: colors.secondaryText
540
+ }],
541
+ children: "Your connection is secure and encrypted"
136
542
  })]
137
543
  })]
138
544
  });
545
+ const renderCurrentStep = () => {
546
+ switch (currentStep) {
547
+ case 0:
548
+ return renderUsernameStep();
549
+ case 1:
550
+ return renderPasswordStep();
551
+ default:
552
+ return renderUsernameStep();
553
+ }
554
+ };
555
+ return /*#__PURE__*/_jsxs(BottomSheetScrollView, {
556
+ contentContainerStyle: commonStyles.scrollContainer,
557
+ keyboardShouldPersistTaps: "handled",
558
+ children: [/*#__PURE__*/_jsx(Animated.View, {
559
+ style: [styles.logoContainer, {
560
+ transform: [{
561
+ scale: logoAnim
562
+ }]
563
+ }],
564
+ children: /*#__PURE__*/_jsx(OxyLogo, {
565
+ style: {
566
+ marginBottom: 24
567
+ },
568
+ width: 50,
569
+ height: 50
570
+ })
571
+ }), /*#__PURE__*/_jsxs(View, {
572
+ style: styles.modernProgressContainer,
573
+ children: [/*#__PURE__*/_jsx(View, {
574
+ style: styles.progressTrack,
575
+ children: /*#__PURE__*/_jsx(Animated.View, {
576
+ style: [styles.progressFill, {
577
+ backgroundColor: colors.primary,
578
+ width: progressAnim.interpolate({
579
+ inputRange: [0, 1],
580
+ outputRange: ['50%', '100%']
581
+ })
582
+ }]
583
+ })
584
+ }), /*#__PURE__*/_jsxs(Text, {
585
+ style: [styles.progressText, {
586
+ color: colors.secondaryText
587
+ }],
588
+ children: ["Step ", currentStep + 1, " of 2"]
589
+ })]
590
+ }), renderCurrentStep()]
591
+ });
139
592
  };
140
593
  const styles = StyleSheet.create({
594
+ // Legacy styles (keeping for compatibility)
141
595
  title: {
142
- fontFamily: Platform.OS === 'web' ? 'Phudu' // Use CSS font name directly for web
143
- : 'Phudu-Bold',
144
- // Use exact font name as registered with Font.loadAsync
596
+ fontFamily: Platform.OS === 'web' ? 'Phudu' : 'Phudu-Bold',
145
597
  fontWeight: Platform.OS === 'web' ? 'bold' : undefined,
146
- // Only apply fontWeight on web
147
598
  fontSize: 54,
148
599
  marginBottom: 24
149
600
  },
@@ -172,7 +623,6 @@ const styles = StyleSheet.create({
172
623
  lineHeight: 20,
173
624
  fontWeight: '600'
174
625
  },
175
- // New styles for authenticated user view
176
626
  userInfoContainer: {
177
627
  padding: 20,
178
628
  marginVertical: 20,
@@ -197,6 +647,303 @@ const styles = StyleSheet.create({
197
647
  fontSize: 14,
198
648
  lineHeight: 20,
199
649
  textAlign: 'center'
650
+ },
651
+ // Modern UI Styles
652
+ logoContainer: {
653
+ alignItems: 'center',
654
+ marginBottom: 16
655
+ },
656
+ modernProgressContainer: {
657
+ alignItems: 'center',
658
+ marginBottom: 40,
659
+ paddingHorizontal: 20
660
+ },
661
+ progressTrack: {
662
+ width: '100%',
663
+ height: 4,
664
+ backgroundColor: '#E5E5E5',
665
+ borderRadius: 2,
666
+ marginBottom: 8,
667
+ overflow: 'hidden'
668
+ },
669
+ progressFill: {
670
+ height: '100%',
671
+ borderRadius: 2
672
+ },
673
+ progressText: {
674
+ fontSize: 12,
675
+ fontWeight: '500'
676
+ },
677
+ stepContainer: {
678
+ width: '100%',
679
+ minHeight: 450,
680
+ paddingHorizontal: 20
681
+ },
682
+ // Modern Image Container
683
+ modernImageContainer: {
684
+ alignItems: 'center',
685
+ marginBottom: 40,
686
+ paddingVertical: 20
687
+ },
688
+ modernHeader: {
689
+ alignItems: 'center',
690
+ marginBottom: 24
691
+ },
692
+ modernTitle: {
693
+ fontFamily: Platform.OS === 'web' ? 'Phudu' : 'Phudu-Bold',
694
+ fontWeight: Platform.OS === 'web' ? 'bold' : undefined,
695
+ fontSize: 54,
696
+ textAlign: 'center',
697
+ marginBottom: 8,
698
+ letterSpacing: -0.5
699
+ },
700
+ modernSubtitle: {
701
+ fontSize: 16,
702
+ lineHeight: 22,
703
+ textAlign: 'center',
704
+ opacity: 0.8
705
+ },
706
+ // Modern Cards
707
+ modernInfoCard: {
708
+ flexDirection: 'row',
709
+ alignItems: 'center',
710
+ padding: 16,
711
+ marginVertical: 16,
712
+ borderRadius: 12,
713
+ gap: 12
714
+ },
715
+ modernInfoText: {
716
+ fontSize: 14,
717
+ lineHeight: 20,
718
+ flex: 1
719
+ },
720
+ modernErrorCard: {
721
+ flexDirection: 'row',
722
+ alignItems: 'center',
723
+ padding: 16,
724
+ marginVertical: 16,
725
+ borderRadius: 12,
726
+ gap: 12
727
+ },
728
+ errorText: {
729
+ fontSize: 14,
730
+ lineHeight: 20,
731
+ flex: 1
732
+ },
733
+ // Modern Input Styles
734
+ modernInputContainer: {
735
+ marginBottom: 24
736
+ },
737
+ inputWrapper: {
738
+ flexDirection: 'row',
739
+ alignItems: 'center',
740
+ borderWidth: 2,
741
+ borderRadius: 16,
742
+ paddingHorizontal: 16,
743
+ paddingVertical: 4,
744
+ backgroundColor: 'rgba(0,0,0,0.02)'
745
+ },
746
+ inputIcon: {
747
+ marginRight: 12
748
+ },
749
+ modernInput: {
750
+ flex: 1,
751
+ fontSize: 16,
752
+ paddingVertical: 16,
753
+ fontWeight: '500'
754
+ },
755
+ // Modern Button Styles
756
+ modernButton: {
757
+ flexDirection: 'row',
758
+ alignItems: 'center',
759
+ justifyContent: 'center',
760
+ paddingVertical: 18,
761
+ paddingHorizontal: 32,
762
+ borderRadius: 16,
763
+ marginVertical: 8,
764
+ shadowOffset: {
765
+ width: 0,
766
+ height: 4
767
+ },
768
+ shadowOpacity: 0.3,
769
+ shadowRadius: 8,
770
+ elevation: 6,
771
+ gap: 8
772
+ },
773
+ modernButtonText: {
774
+ color: '#FFFFFF',
775
+ fontSize: 16,
776
+ fontWeight: '600',
777
+ letterSpacing: 0.5
778
+ },
779
+ buttonIcon: {
780
+ marginLeft: 4
781
+ },
782
+ modernLinkText: {
783
+ fontSize: 14,
784
+ lineHeight: 20,
785
+ fontWeight: '600',
786
+ textDecorationLine: 'underline'
787
+ },
788
+ // Modern User Profile Styles
789
+ modernUserProfileContainer: {
790
+ alignItems: 'center',
791
+ marginBottom: 32,
792
+ paddingVertical: 24
793
+ },
794
+ avatarContainer: {
795
+ position: 'relative',
796
+ marginBottom: 20
797
+ },
798
+ modernUserAvatar: {
799
+ borderWidth: 4,
800
+ borderColor: 'rgba(209, 105, 229, 0.2)'
801
+ },
802
+ statusIndicator: {
803
+ position: 'absolute',
804
+ bottom: 4,
805
+ right: 4,
806
+ width: 20,
807
+ height: 20,
808
+ borderRadius: 10,
809
+ borderWidth: 3,
810
+ borderColor: '#FFFFFF'
811
+ },
812
+ modernUserDisplayName: {
813
+ fontSize: 26,
814
+ fontWeight: '700',
815
+ marginBottom: 4,
816
+ textAlign: 'center',
817
+ letterSpacing: -0.5
818
+ },
819
+ modernUsernameSubtext: {
820
+ fontSize: 16,
821
+ textAlign: 'center',
822
+ marginBottom: 16,
823
+ opacity: 0.7
824
+ },
825
+ welcomeBackBadge: {
826
+ flexDirection: 'row',
827
+ alignItems: 'center',
828
+ paddingHorizontal: 12,
829
+ paddingVertical: 6,
830
+ borderRadius: 20,
831
+ gap: 6
832
+ },
833
+ welcomeBackText: {
834
+ fontSize: 12,
835
+ fontWeight: '600',
836
+ textTransform: 'uppercase',
837
+ letterSpacing: 0.5
838
+ },
839
+ // Modern Navigation
840
+ modernNavigationButtons: {
841
+ flexDirection: 'row',
842
+ justifyContent: 'center',
843
+ marginTop: 24,
844
+ marginBottom: 16
845
+ },
846
+ modernBackButton: {
847
+ flexDirection: 'row',
848
+ alignItems: 'center',
849
+ paddingVertical: 12,
850
+ paddingHorizontal: 20,
851
+ borderRadius: 12,
852
+ borderWidth: 1,
853
+ gap: 8
854
+ },
855
+ modernBackButtonText: {
856
+ fontSize: 16,
857
+ fontWeight: '500'
858
+ },
859
+ // Security Notice
860
+ securityNotice: {
861
+ flexDirection: 'row',
862
+ alignItems: 'center',
863
+ justifyContent: 'center',
864
+ marginTop: 20,
865
+ gap: 6
866
+ },
867
+ securityText: {
868
+ fontSize: 12,
869
+ fontWeight: '500'
870
+ },
871
+ // Legacy compatibility styles
872
+ progressContainer: {
873
+ flexDirection: 'row',
874
+ alignItems: 'center',
875
+ justifyContent: 'center',
876
+ marginBottom: 32,
877
+ paddingHorizontal: 40
878
+ },
879
+ progressDot: {
880
+ width: 12,
881
+ height: 12,
882
+ borderRadius: 6,
883
+ marginHorizontal: 4
884
+ },
885
+ progressLine: {
886
+ flex: 1,
887
+ height: 2,
888
+ marginHorizontal: 8
889
+ },
890
+ welcomeImageContainer: {
891
+ alignItems: 'center',
892
+ marginBottom: 32
893
+ },
894
+ header: {
895
+ alignItems: 'center',
896
+ marginBottom: 16
897
+ },
898
+ welcomeTitle: {
899
+ fontFamily: Platform.OS === 'web' ? 'Phudu' : 'Phudu-Bold',
900
+ fontWeight: Platform.OS === 'web' ? 'bold' : undefined,
901
+ fontSize: 32,
902
+ textAlign: 'center',
903
+ marginBottom: 8
904
+ },
905
+ welcomeText: {
906
+ fontSize: 16,
907
+ lineHeight: 24,
908
+ textAlign: 'center',
909
+ marginBottom: 32,
910
+ paddingHorizontal: 20
911
+ },
912
+ userProfileContainer: {
913
+ alignItems: 'center',
914
+ marginBottom: 32,
915
+ paddingVertical: 20
916
+ },
917
+ userAvatar: {
918
+ marginBottom: 16
919
+ },
920
+ userDisplayName: {
921
+ fontSize: 24,
922
+ fontWeight: 'bold',
923
+ marginBottom: 4,
924
+ textAlign: 'center'
925
+ },
926
+ usernameSubtext: {
927
+ fontSize: 16,
928
+ textAlign: 'center'
929
+ },
930
+ navigationButtons: {
931
+ flexDirection: 'row',
932
+ justifyContent: 'center',
933
+ marginTop: 24
934
+ },
935
+ backButton: {
936
+ flexDirection: 'row',
937
+ alignItems: 'center',
938
+ paddingVertical: 12,
939
+ paddingHorizontal: 20,
940
+ borderRadius: 12,
941
+ borderWidth: 1
942
+ },
943
+ backButtonText: {
944
+ fontSize: 16,
945
+ fontWeight: '500',
946
+ marginLeft: 8
200
947
  }
201
948
  });
202
949
  export default SignInScreen;