@oxyhq/services 5.4.3 → 5.4.5

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 (233) hide show
  1. package/README.md +14 -0
  2. package/lib/commonjs/assets/assets/illustrations/HighFive.tsx +41 -0
  3. package/lib/commonjs/assets/icons/OxyServices.js +1 -1
  4. package/lib/commonjs/assets/illustrations/HighFive.js +61 -0
  5. package/lib/commonjs/assets/illustrations/HighFive.js.map +1 -0
  6. package/lib/commonjs/core/index.js +24 -5
  7. package/lib/commonjs/core/index.js.map +1 -1
  8. package/lib/commonjs/index.js +72 -23
  9. package/lib/commonjs/index.js.map +1 -1
  10. package/lib/commonjs/node/createAuth.js +95 -0
  11. package/lib/commonjs/node/createAuth.js.map +1 -0
  12. package/lib/commonjs/node/index.js +15 -6
  13. package/lib/commonjs/node/index.js.map +1 -1
  14. package/lib/commonjs/package.json +1 -0
  15. package/lib/commonjs/ui/components/Avatar.js +3 -3
  16. package/lib/commonjs/ui/components/Avatar.js.map +1 -1
  17. package/lib/commonjs/ui/components/FollowButton.js +82 -34
  18. package/lib/commonjs/ui/components/FollowButton.js.map +1 -1
  19. package/lib/commonjs/ui/components/GroupedSection.js +1 -1
  20. package/lib/commonjs/ui/components/OxyLogo.js +1 -1
  21. package/lib/commonjs/ui/components/OxyProvider.js +146 -141
  22. package/lib/commonjs/ui/components/OxyProvider.js.map +1 -1
  23. package/lib/commonjs/ui/components/OxySignInButton.js +4 -4
  24. package/lib/commonjs/ui/components/OxySignInButton.js.map +1 -1
  25. package/lib/commonjs/ui/components/ProfileCard.js +2 -2
  26. package/lib/commonjs/ui/components/Section.js +1 -1
  27. package/lib/commonjs/ui/components/SectionTitle.js +1 -1
  28. package/lib/commonjs/ui/components/icon/index.js +1 -1
  29. package/lib/commonjs/ui/components/index.js +12 -12
  30. package/lib/commonjs/ui/components/internal/GroupedPillButtons.js +213 -0
  31. package/lib/commonjs/ui/components/internal/GroupedPillButtons.js.map +1 -0
  32. package/lib/commonjs/ui/components/internal/TextField.js +576 -0
  33. package/lib/commonjs/ui/components/internal/TextField.js.map +1 -0
  34. package/lib/commonjs/ui/context/OxyContext.js +12 -2
  35. package/lib/commonjs/ui/context/OxyContext.js.map +1 -1
  36. package/lib/commonjs/ui/hooks/index.js +13 -0
  37. package/lib/commonjs/ui/hooks/index.js.map +1 -0
  38. package/lib/commonjs/ui/hooks/useFollow.js +184 -0
  39. package/lib/commonjs/ui/hooks/useFollow.js.map +1 -0
  40. package/lib/commonjs/ui/index.js +44 -12
  41. package/lib/commonjs/ui/index.js.map +1 -1
  42. package/lib/commonjs/ui/navigation/OxyRouter.js +23 -18
  43. package/lib/commonjs/ui/navigation/OxyRouter.js.map +1 -1
  44. package/lib/commonjs/ui/screens/AccountCenterScreen.js +21 -20
  45. package/lib/commonjs/ui/screens/AccountCenterScreen.js.map +1 -1
  46. package/lib/commonjs/ui/screens/AccountManagementDemo.js +3 -3
  47. package/lib/commonjs/ui/screens/AccountManagementDemo.js.map +1 -1
  48. package/lib/commonjs/ui/screens/AccountOverviewScreen.js +11 -10
  49. package/lib/commonjs/ui/screens/AccountOverviewScreen.js.map +1 -1
  50. package/lib/commonjs/ui/screens/AccountSettingsScreen.js +8 -7
  51. package/lib/commonjs/ui/screens/AccountSettingsScreen.js.map +1 -1
  52. package/lib/commonjs/ui/screens/AccountSwitcherScreen.js +6 -5
  53. package/lib/commonjs/ui/screens/AccountSwitcherScreen.js.map +1 -1
  54. package/lib/commonjs/ui/screens/AppInfoScreen.js +12 -14
  55. package/lib/commonjs/ui/screens/AppInfoScreen.js.map +1 -1
  56. package/lib/commonjs/ui/screens/BillingManagementScreen.js +3 -3
  57. package/lib/commonjs/ui/screens/FeedbackScreen.js +1169 -0
  58. package/lib/commonjs/ui/screens/FeedbackScreen.js.map +1 -0
  59. package/lib/commonjs/ui/screens/FileManagementScreen.js +3 -3
  60. package/lib/commonjs/ui/screens/PremiumSubscriptionScreen.js +3 -3
  61. package/lib/commonjs/ui/screens/ProfileScreen.js +2 -2
  62. package/lib/commonjs/ui/screens/SessionManagementScreen.js +2 -2
  63. package/lib/commonjs/ui/screens/SignInScreen.js +183 -305
  64. package/lib/commonjs/ui/screens/SignInScreen.js.map +1 -1
  65. package/lib/commonjs/ui/screens/SignUpScreen.js +811 -712
  66. package/lib/commonjs/ui/screens/SignUpScreen.js.map +1 -1
  67. package/lib/commonjs/ui/screens/karma/KarmaCenterScreen.js +8 -7
  68. package/lib/commonjs/ui/screens/karma/KarmaCenterScreen.js.map +1 -1
  69. package/lib/commonjs/ui/screens/karma/KarmaLeaderboardScreen.js +2 -2
  70. package/lib/commonjs/ui/screens/karma/KarmaRulesScreen.js +1 -1
  71. package/lib/commonjs/ui/store/index.js +267 -0
  72. package/lib/commonjs/ui/store/index.js.map +1 -0
  73. package/lib/commonjs/ui/styles/index.js +2 -2
  74. package/lib/commonjs/ui/styles/theme.js +1 -1
  75. package/lib/commonjs/utils/index.js +1 -1
  76. package/lib/module/assets/assets/illustrations/HighFive.tsx +41 -0
  77. package/lib/module/assets/icons/OxyServices.js +1 -1
  78. package/lib/module/assets/icons/OxyServices.js.map +1 -1
  79. package/lib/module/assets/illustrations/HighFive.js +55 -0
  80. package/lib/module/assets/illustrations/HighFive.js.map +1 -0
  81. package/lib/module/core/index.js +24 -5
  82. package/lib/module/core/index.js.map +1 -1
  83. package/lib/module/index.js +15 -11
  84. package/lib/module/index.js.map +1 -1
  85. package/lib/module/node/createAuth.js +90 -0
  86. package/lib/module/node/createAuth.js.map +1 -0
  87. package/lib/module/node/index.js +8 -4
  88. package/lib/module/node/index.js.map +1 -1
  89. package/lib/module/package.json +1 -0
  90. package/lib/module/ui/components/Avatar.js +2 -2
  91. package/lib/module/ui/components/Avatar.js.map +1 -1
  92. package/lib/module/ui/components/FollowButton.js +83 -35
  93. package/lib/module/ui/components/FollowButton.js.map +1 -1
  94. package/lib/module/ui/components/GroupedSection.js +1 -1
  95. package/lib/module/ui/components/GroupedSection.js.map +1 -1
  96. package/lib/module/ui/components/OxyLogo.js +1 -1
  97. package/lib/module/ui/components/OxyLogo.js.map +1 -1
  98. package/lib/module/ui/components/OxyProvider.js +143 -138
  99. package/lib/module/ui/components/OxyProvider.js.map +1 -1
  100. package/lib/module/ui/components/OxySignInButton.js +4 -4
  101. package/lib/module/ui/components/OxySignInButton.js.map +1 -1
  102. package/lib/module/ui/components/ProfileCard.js +2 -2
  103. package/lib/module/ui/components/ProfileCard.js.map +1 -1
  104. package/lib/module/ui/components/Section.js +1 -1
  105. package/lib/module/ui/components/Section.js.map +1 -1
  106. package/lib/module/ui/components/SectionTitle.js +1 -1
  107. package/lib/module/ui/components/SectionTitle.js.map +1 -1
  108. package/lib/module/ui/components/icon/index.js +1 -1
  109. package/lib/module/ui/components/icon/index.js.map +1 -1
  110. package/lib/module/ui/components/index.js +12 -12
  111. package/lib/module/ui/components/index.js.map +1 -1
  112. package/lib/module/ui/components/internal/GroupedPillButtons.js +208 -0
  113. package/lib/module/ui/components/internal/GroupedPillButtons.js.map +1 -0
  114. package/lib/module/ui/components/internal/TextField.js +571 -0
  115. package/lib/module/ui/components/internal/TextField.js.map +1 -0
  116. package/lib/module/ui/context/OxyContext.js +12 -2
  117. package/lib/module/ui/context/OxyContext.js.map +1 -1
  118. package/lib/module/ui/hooks/index.js +4 -0
  119. package/lib/module/ui/hooks/index.js.map +1 -0
  120. package/lib/module/ui/hooks/useFollow.js +180 -0
  121. package/lib/module/ui/hooks/useFollow.js.map +1 -0
  122. package/lib/module/ui/index.js +21 -10
  123. package/lib/module/ui/index.js.map +1 -1
  124. package/lib/module/ui/navigation/OxyRouter.js +23 -18
  125. package/lib/module/ui/navigation/OxyRouter.js.map +1 -1
  126. package/lib/module/ui/screens/AccountCenterScreen.js +9 -8
  127. package/lib/module/ui/screens/AccountCenterScreen.js.map +1 -1
  128. package/lib/module/ui/screens/AccountManagementDemo.js +2 -2
  129. package/lib/module/ui/screens/AccountManagementDemo.js.map +1 -1
  130. package/lib/module/ui/screens/AccountOverviewScreen.js +11 -10
  131. package/lib/module/ui/screens/AccountOverviewScreen.js.map +1 -1
  132. package/lib/module/ui/screens/AccountSettingsScreen.js +8 -7
  133. package/lib/module/ui/screens/AccountSettingsScreen.js.map +1 -1
  134. package/lib/module/ui/screens/AccountSwitcherScreen.js +6 -5
  135. package/lib/module/ui/screens/AccountSwitcherScreen.js.map +1 -1
  136. package/lib/module/ui/screens/AppInfoScreen.js +12 -14
  137. package/lib/module/ui/screens/AppInfoScreen.js.map +1 -1
  138. package/lib/module/ui/screens/BillingManagementScreen.js +3 -3
  139. package/lib/module/ui/screens/BillingManagementScreen.js.map +1 -1
  140. package/lib/module/ui/screens/FeedbackScreen.js +1164 -0
  141. package/lib/module/ui/screens/FeedbackScreen.js.map +1 -0
  142. package/lib/module/ui/screens/FileManagementScreen.js +3 -3
  143. package/lib/module/ui/screens/FileManagementScreen.js.map +1 -1
  144. package/lib/module/ui/screens/PremiumSubscriptionScreen.js +3 -3
  145. package/lib/module/ui/screens/PremiumSubscriptionScreen.js.map +1 -1
  146. package/lib/module/ui/screens/ProfileScreen.js +2 -2
  147. package/lib/module/ui/screens/ProfileScreen.js.map +1 -1
  148. package/lib/module/ui/screens/SessionManagementScreen.js +2 -2
  149. package/lib/module/ui/screens/SessionManagementScreen.js.map +1 -1
  150. package/lib/module/ui/screens/SignInScreen.js +183 -305
  151. package/lib/module/ui/screens/SignInScreen.js.map +1 -1
  152. package/lib/module/ui/screens/SignUpScreen.js +810 -712
  153. package/lib/module/ui/screens/SignUpScreen.js.map +1 -1
  154. package/lib/module/ui/screens/karma/KarmaCenterScreen.js +8 -7
  155. package/lib/module/ui/screens/karma/KarmaCenterScreen.js.map +1 -1
  156. package/lib/module/ui/screens/karma/KarmaLeaderboardScreen.js +2 -2
  157. package/lib/module/ui/screens/karma/KarmaLeaderboardScreen.js.map +1 -1
  158. package/lib/module/ui/screens/karma/KarmaRulesScreen.js +1 -1
  159. package/lib/module/ui/screens/karma/KarmaRulesScreen.js.map +1 -1
  160. package/lib/module/ui/store/index.js +255 -0
  161. package/lib/module/ui/store/index.js.map +1 -0
  162. package/lib/module/ui/styles/index.js +2 -2
  163. package/lib/module/ui/styles/index.js.map +1 -1
  164. package/lib/module/ui/styles/theme.js +1 -1
  165. package/lib/module/ui/styles/theme.js.map +1 -1
  166. package/lib/module/utils/index.js +1 -1
  167. package/lib/module/utils/index.js.map +1 -1
  168. package/lib/typescript/assets/illustrations/HighFive.d.ts +9 -0
  169. package/lib/typescript/assets/illustrations/HighFive.d.ts.map +1 -0
  170. package/lib/typescript/core/index.d.ts +16 -3
  171. package/lib/typescript/core/index.d.ts.map +1 -1
  172. package/lib/typescript/index.d.ts +4 -2
  173. package/lib/typescript/index.d.ts.map +1 -1
  174. package/lib/typescript/node/createAuth.d.ts +7 -0
  175. package/lib/typescript/node/createAuth.d.ts.map +1 -0
  176. package/lib/typescript/node/index.d.ts +2 -0
  177. package/lib/typescript/node/index.d.ts.map +1 -1
  178. package/lib/typescript/types/expo-vector-icons.d.ts +3 -0
  179. package/lib/typescript/types/express.d.ts +5 -0
  180. package/lib/typescript/types/react-redux.d.ts +5 -0
  181. package/lib/typescript/ui/components/FollowButton.d.ts +1 -0
  182. package/lib/typescript/ui/components/FollowButton.d.ts.map +1 -1
  183. package/lib/typescript/ui/components/OxyProvider.d.ts.map +1 -1
  184. package/lib/typescript/ui/components/internal/GroupedPillButtons.d.ts +18 -0
  185. package/lib/typescript/ui/components/internal/GroupedPillButtons.d.ts.map +1 -0
  186. package/lib/typescript/ui/components/internal/TextField.d.ts +25 -0
  187. package/lib/typescript/ui/components/internal/TextField.d.ts.map +1 -0
  188. package/lib/typescript/ui/context/OxyContext.d.ts.map +1 -1
  189. package/lib/typescript/ui/hooks/index.d.ts +2 -0
  190. package/lib/typescript/ui/hooks/index.d.ts.map +1 -0
  191. package/lib/typescript/ui/hooks/useFollow.d.ts +43 -0
  192. package/lib/typescript/ui/hooks/useFollow.d.ts.map +1 -0
  193. package/lib/typescript/ui/index.d.ts +5 -0
  194. package/lib/typescript/ui/index.d.ts.map +1 -1
  195. package/lib/typescript/ui/navigation/OxyRouter.d.ts.map +1 -1
  196. package/lib/typescript/ui/screens/AccountCenterScreen.d.ts.map +1 -1
  197. package/lib/typescript/ui/screens/AccountSwitcherScreen.d.ts.map +1 -1
  198. package/lib/typescript/ui/screens/AppInfoScreen.d.ts.map +1 -1
  199. package/lib/typescript/ui/screens/FeedbackScreen.d.ts +5 -0
  200. package/lib/typescript/ui/screens/FeedbackScreen.d.ts.map +1 -0
  201. package/lib/typescript/ui/screens/SignInScreen.d.ts.map +1 -1
  202. package/lib/typescript/ui/screens/SignUpScreen.d.ts.map +1 -1
  203. package/lib/typescript/ui/store/index.d.ts +66 -0
  204. package/lib/typescript/ui/store/index.d.ts.map +1 -0
  205. package/package.json +10 -25
  206. package/src/assets/illustrations/HighFive.tsx +41 -0
  207. package/src/core/index.ts +88 -3
  208. package/src/index.ts +19 -3
  209. package/src/node/createAuth.ts +116 -0
  210. package/src/node/index.ts +4 -0
  211. package/src/types/expo-vector-icons.d.ts +3 -0
  212. package/src/types/express.d.ts +5 -0
  213. package/src/types/react-redux.d.ts +5 -0
  214. package/src/ui/components/FollowButton.tsx +114 -56
  215. package/src/ui/components/OxyProvider.tsx +136 -135
  216. package/src/ui/components/OxySignInButton.tsx +2 -2
  217. package/src/ui/components/internal/GroupedPillButtons.tsx +253 -0
  218. package/src/ui/components/internal/TextField.tsx +694 -0
  219. package/src/ui/context/OxyContext.tsx +12 -2
  220. package/src/ui/hooks/index.ts +1 -0
  221. package/src/ui/hooks/useFollow.ts +173 -0
  222. package/src/ui/index.ts +15 -2
  223. package/src/ui/navigation/OxyRouter.tsx +8 -3
  224. package/src/ui/screens/AccountCenterScreen.tsx +17 -15
  225. package/src/ui/screens/AccountOverviewScreen.tsx +25 -25
  226. package/src/ui/screens/AccountSettingsScreen.tsx +30 -30
  227. package/src/ui/screens/AccountSwitcherScreen.tsx +34 -33
  228. package/src/ui/screens/AppInfoScreen.tsx +153 -155
  229. package/src/ui/screens/FeedbackScreen.tsx +1042 -0
  230. package/src/ui/screens/SignInScreen.tsx +181 -224
  231. package/src/ui/screens/SignUpScreen.tsx +772 -608
  232. package/src/ui/screens/karma/KarmaCenterScreen.tsx +4 -4
  233. package/src/ui/store/index.ts +245 -0
@@ -1,39 +1,583 @@
1
1
  "use strict";
2
2
 
3
- import React, { useState, useRef, useEffect, useMemo, useCallback } from 'react';
3
+ import React, { useState, useRef, useEffect, useCallback, useMemo } from 'react';
4
4
  import { View, Text, TextInput, TouchableOpacity, StyleSheet, ActivityIndicator, Platform, KeyboardAvoidingView, ScrollView, Animated, StatusBar } from 'react-native';
5
- import { useOxy } from "../context/OxyContext.js";
6
- import { useThemeColors, createCommonStyles } from "../styles/index.js";
5
+ import { useOxy } from '../context/OxyContext';
6
+ import { useThemeColors } from '../styles';
7
7
  import { Ionicons } from '@expo/vector-icons';
8
- import Svg, { Path, Circle } from 'react-native-svg';
9
- import { toast } from "../../lib/sonner.js";
8
+ import { toast } from '../../lib/sonner';
9
+ import HighFive from '../../assets/illustrations/HighFive';
10
+ import GroupedPillButtons from '../components/internal/GroupedPillButtons';
11
+ import TextField from '../components/internal/TextField';
12
+
13
+ // Types for better type safety
10
14
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
15
+ // Constants
16
+ const USERNAME_MIN_LENGTH = 3;
17
+ const PASSWORD_MIN_LENGTH = 8;
18
+ const VALIDATION_DEBOUNCE_MS = 800;
19
+ const CACHE_DURATION_MS = 5 * 60 * 1000; // 5 minutes
20
+
21
+ // Email validation regex
22
+ const EMAIL_REGEX = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
23
+
24
+ // Styles factory function
25
+ const createStyles = (colors, theme) => StyleSheet.create({
26
+ container: {
27
+ flex: 1
28
+ },
29
+ scrollContent: {
30
+ flexGrow: 1,
31
+ paddingHorizontal: 24,
32
+ paddingTop: 4,
33
+ paddingBottom: 20
34
+ },
35
+ stepContainer: {
36
+ flex: 1,
37
+ justifyContent: 'flex-start',
38
+ alignItems: 'flex-start'
39
+ },
40
+ modernHeader: {
41
+ alignItems: 'flex-start',
42
+ width: '100%',
43
+ marginBottom: 24
44
+ },
45
+ modernTitle: {
46
+ fontFamily: Platform.OS === 'web' ? 'Phudu' : 'Phudu-Bold',
47
+ fontWeight: Platform.OS === 'web' ? 'bold' : undefined,
48
+ fontSize: 42,
49
+ lineHeight: 48,
50
+ marginBottom: 12,
51
+ textAlign: 'left',
52
+ letterSpacing: -1
53
+ },
54
+ modernSubtitle: {
55
+ fontSize: 18,
56
+ lineHeight: 24,
57
+ textAlign: 'left',
58
+ opacity: 0.8,
59
+ marginBottom: 24
60
+ },
61
+ welcomeImageContainer: {
62
+ alignItems: 'center',
63
+ justifyContent: 'center',
64
+ marginVertical: 20
65
+ },
66
+ welcomeTitle: {
67
+ fontFamily: Platform.OS === 'web' ? 'Phudu' : 'Phudu-Bold',
68
+ fontWeight: Platform.OS === 'web' ? 'bold' : undefined,
69
+ fontSize: 42,
70
+ lineHeight: 48,
71
+ marginBottom: 12,
72
+ textAlign: 'left',
73
+ letterSpacing: -1
74
+ },
75
+ welcomeText: {
76
+ fontSize: 18,
77
+ lineHeight: 24,
78
+ textAlign: 'left',
79
+ opacity: 0.8,
80
+ marginBottom: 24
81
+ },
82
+ stepTitle: {
83
+ fontFamily: Platform.OS === 'web' ? 'Phudu' : 'Phudu-Bold',
84
+ fontWeight: Platform.OS === 'web' ? 'bold' : undefined,
85
+ fontSize: 42,
86
+ lineHeight: 48,
87
+ marginBottom: 12,
88
+ textAlign: 'left',
89
+ letterSpacing: -1
90
+ },
91
+ inputContainer: {
92
+ width: '100%',
93
+ marginBottom: 24
94
+ },
95
+ premiumInputWrapper: {
96
+ flexDirection: 'row',
97
+ alignItems: 'center',
98
+ height: 56,
99
+ borderRadius: 16,
100
+ paddingHorizontal: 20,
101
+ borderWidth: 2,
102
+ backgroundColor: colors.inputBackground
103
+ },
104
+ inputIcon: {
105
+ marginRight: 12
106
+ },
107
+ inputContent: {
108
+ flex: 1
109
+ },
110
+ modernLabel: {
111
+ fontSize: 12,
112
+ fontWeight: '500',
113
+ marginBottom: 2
114
+ },
115
+ modernInput: {
116
+ flex: 1,
117
+ fontSize: 16,
118
+ height: '100%'
119
+ },
120
+ validationIndicator: {
121
+ marginLeft: 8
122
+ },
123
+ validationCard: {
124
+ flexDirection: 'row',
125
+ alignItems: 'center',
126
+ padding: 12,
127
+ borderRadius: 12,
128
+ marginTop: 8,
129
+ gap: 8
130
+ },
131
+ validationIconContainer: {
132
+ width: 32,
133
+ height: 32,
134
+ borderRadius: 16,
135
+ justifyContent: 'center',
136
+ alignItems: 'center',
137
+ marginRight: 12
138
+ },
139
+ validationTextContainer: {
140
+ flex: 1
141
+ },
142
+ validationTitle: {
143
+ fontSize: 12,
144
+ fontWeight: '600',
145
+ marginBottom: 2
146
+ },
147
+ validationSubtitle: {
148
+ fontSize: 11,
149
+ opacity: 0.8
150
+ },
151
+ passwordToggle: {
152
+ padding: 4
153
+ },
154
+ passwordHint: {
155
+ fontSize: 12,
156
+ marginTop: 4
157
+ },
158
+ button: {
159
+ flexDirection: 'row',
160
+ alignItems: 'center',
161
+ justifyContent: 'center',
162
+ paddingVertical: 18,
163
+ paddingHorizontal: 32,
164
+ borderRadius: 16,
165
+ marginVertical: 8,
166
+ shadowOffset: {
167
+ width: 0,
168
+ height: 4
169
+ },
170
+ shadowOpacity: 0.3,
171
+ shadowRadius: 8,
172
+ elevation: 6,
173
+ gap: 8,
174
+ width: '100%'
175
+ },
176
+ buttonText: {
177
+ color: '#FFFFFF',
178
+ fontSize: 16,
179
+ fontWeight: '600',
180
+ letterSpacing: 0.5
181
+ },
182
+ footerTextContainer: {
183
+ flexDirection: 'row',
184
+ justifyContent: 'center',
185
+ marginTop: 16
186
+ },
187
+ footerText: {
188
+ fontSize: 15
189
+ },
190
+ linkText: {
191
+ fontSize: 14,
192
+ lineHeight: 20,
193
+ fontWeight: '600',
194
+ textDecorationLine: 'underline'
195
+ },
196
+ userInfoContainer: {
197
+ padding: 20,
198
+ marginVertical: 20,
199
+ borderRadius: 24,
200
+ alignItems: 'center',
201
+ shadowColor: '#000',
202
+ shadowOpacity: 0.04,
203
+ shadowOffset: {
204
+ width: 0,
205
+ height: 1
206
+ },
207
+ shadowRadius: 4,
208
+ elevation: 1
209
+ },
210
+ userInfoText: {
211
+ fontSize: 16,
212
+ marginBottom: 8,
213
+ textAlign: 'center'
214
+ },
215
+ actionButtonsContainer: {
216
+ marginTop: 24
217
+ },
218
+ navigationButtons: {
219
+ flexDirection: 'row',
220
+ justifyContent: 'center',
221
+ marginTop: 16,
222
+ marginBottom: 8,
223
+ width: '100%',
224
+ gap: 8
225
+ },
226
+ navButton: {
227
+ flexDirection: 'row',
228
+ alignItems: 'center',
229
+ paddingVertical: 6,
230
+ paddingHorizontal: 12,
231
+ gap: 6,
232
+ minWidth: 70,
233
+ borderWidth: 1,
234
+ shadowOffset: {
235
+ width: 0,
236
+ height: 2
237
+ },
238
+ shadowOpacity: 0.1,
239
+ shadowRadius: 4,
240
+ elevation: 2
241
+ },
242
+ backButton: {
243
+ backgroundColor: 'transparent',
244
+ borderTopLeftRadius: 35,
245
+ borderBottomLeftRadius: 35,
246
+ borderTopRightRadius: 12,
247
+ borderBottomRightRadius: 12
248
+ },
249
+ nextButton: {
250
+ backgroundColor: 'transparent',
251
+ borderTopRightRadius: 35,
252
+ borderBottomRightRadius: 35,
253
+ borderTopLeftRadius: 12,
254
+ borderBottomLeftRadius: 12
255
+ },
256
+ navButtonText: {
257
+ fontSize: 13,
258
+ fontWeight: '500'
259
+ },
260
+ progressContainer: {
261
+ flexDirection: 'row',
262
+ justifyContent: 'center',
263
+ marginBottom: 20,
264
+ marginTop: 8
265
+ },
266
+ progressDot: {
267
+ height: 10,
268
+ width: 10,
269
+ borderRadius: 5,
270
+ marginHorizontal: 6,
271
+ borderWidth: 2,
272
+ borderColor: '#fff',
273
+ shadowColor: colors.primary,
274
+ shadowOpacity: 0.08,
275
+ shadowOffset: {
276
+ width: 0,
277
+ height: 1
278
+ },
279
+ shadowRadius: 2,
280
+ elevation: 1
281
+ },
282
+ summaryContainer: {
283
+ padding: 0,
284
+ marginBottom: 24,
285
+ width: '100%'
286
+ },
287
+ summaryRow: {
288
+ flexDirection: 'row',
289
+ marginBottom: 10
290
+ },
291
+ summaryLabel: {
292
+ fontSize: 15,
293
+ width: 90
294
+ },
295
+ summaryValue: {
296
+ fontSize: 15,
297
+ fontWeight: '600',
298
+ flex: 1
299
+ }
300
+ });
301
+
302
+ // Custom hooks for better separation of concerns
303
+ const useFormValidation = oxyServices => {
304
+ const [validationState, setValidationState] = useState({
305
+ status: 'idle',
306
+ message: ''
307
+ });
308
+ const validationCache = useRef(new Map());
309
+ const validateUsername = useCallback(async username => {
310
+ if (!username || username.length < USERNAME_MIN_LENGTH) {
311
+ setValidationState({
312
+ status: 'invalid',
313
+ message: ''
314
+ });
315
+ return false;
316
+ }
317
+
318
+ // Check cache first
319
+ const cached = validationCache.current.get(username);
320
+ const now = Date.now();
321
+ if (cached && now - cached.timestamp < CACHE_DURATION_MS) {
322
+ const isValid = cached.available;
323
+ setValidationState({
324
+ status: isValid ? 'valid' : 'invalid',
325
+ message: isValid ? '' : 'Username is already taken'
326
+ });
327
+ return isValid;
328
+ }
329
+ setValidationState({
330
+ status: 'validating',
331
+ message: ''
332
+ });
333
+ try {
334
+ const result = await oxyServices.checkUsernameAvailability(username);
335
+ const isValid = result.available;
336
+
337
+ // Cache the result
338
+ validationCache.current.set(username, {
339
+ available: isValid,
340
+ timestamp: now
341
+ });
342
+ setValidationState({
343
+ status: isValid ? 'valid' : 'invalid',
344
+ message: isValid ? '' : result.message || 'Username is already taken'
345
+ });
346
+ return isValid;
347
+ } catch (error) {
348
+ console.error('Username validation error:', error);
349
+ setValidationState({
350
+ status: 'invalid',
351
+ message: 'Unable to validate username. Please try again.'
352
+ });
353
+ return false;
354
+ }
355
+ }, [oxyServices]);
356
+ const validateEmail = useCallback(email => {
357
+ return EMAIL_REGEX.test(email);
358
+ }, []);
359
+ const validatePassword = useCallback(password => {
360
+ return password.length >= PASSWORD_MIN_LENGTH;
361
+ }, []);
362
+ const validatePasswordsMatch = useCallback((password, confirmPassword) => {
363
+ return password === confirmPassword;
364
+ }, []);
365
+
366
+ // Cleanup cache on unmount
367
+ useEffect(() => {
368
+ return () => {
369
+ validationCache.current.clear();
370
+ };
371
+ }, []);
372
+ return {
373
+ validationState,
374
+ validateUsername,
375
+ validateEmail,
376
+ validatePassword,
377
+ validatePasswordsMatch
378
+ };
379
+ };
380
+ const useFormData = () => {
381
+ const [formData, setFormData] = useState({
382
+ username: '',
383
+ email: '',
384
+ password: '',
385
+ confirmPassword: ''
386
+ });
387
+ const [passwordVisibility, setPasswordVisibility] = useState({
388
+ password: false,
389
+ confirmPassword: false
390
+ });
391
+ const updateField = useCallback((field, value) => {
392
+ setFormData(prev => ({
393
+ ...prev,
394
+ [field]: value
395
+ }));
396
+ }, []);
397
+ const togglePasswordVisibility = useCallback(field => {
398
+ setPasswordVisibility(prev => ({
399
+ ...prev,
400
+ [field]: !prev[field]
401
+ }));
402
+ }, []);
403
+ const resetForm = useCallback(() => {
404
+ setFormData({
405
+ username: '',
406
+ email: '',
407
+ password: '',
408
+ confirmPassword: ''
409
+ });
410
+ setPasswordVisibility({
411
+ password: false,
412
+ confirmPassword: false
413
+ });
414
+ }, []);
415
+ return {
416
+ formData,
417
+ passwordVisibility,
418
+ updateField,
419
+ togglePasswordVisibility,
420
+ resetForm
421
+ };
422
+ };
423
+
424
+ // Reusable components
425
+ const ValidationIndicator = /*#__PURE__*/React.memo(({
426
+ status,
427
+ colors,
428
+ styles
429
+ }) => {
430
+ if (status === 'validating') {
431
+ return /*#__PURE__*/_jsx(ActivityIndicator, {
432
+ size: "small",
433
+ color: colors.primary,
434
+ style: styles.validationIndicator
435
+ });
436
+ }
437
+ if (status === 'valid') {
438
+ return /*#__PURE__*/_jsx(Ionicons, {
439
+ name: "checkmark-circle",
440
+ size: 22,
441
+ color: colors.success,
442
+ style: styles.validationIndicator
443
+ });
444
+ }
445
+ if (status === 'invalid') {
446
+ return /*#__PURE__*/_jsx(Ionicons, {
447
+ name: "close-circle",
448
+ size: 22,
449
+ color: colors.error,
450
+ style: styles.validationIndicator
451
+ });
452
+ }
453
+ return null;
454
+ });
455
+ const ValidationMessage = /*#__PURE__*/React.memo(({
456
+ validationState,
457
+ colors,
458
+ styles
459
+ }) => {
460
+ if (validationState.status === 'idle' || !validationState.message) return null;
461
+ const isSuccess = validationState.status === 'valid';
462
+ const backgroundColor = isSuccess ? colors.success + '10' : colors.error + '10';
463
+ const borderColor = isSuccess ? colors.success + '30' : colors.error + '30';
464
+ const iconColor = isSuccess ? colors.success : colors.error;
465
+ const iconName = isSuccess ? 'checkmark-circle' : 'alert-circle';
466
+ const title = isSuccess ? 'Username Available' : 'Username Taken';
467
+ const subtitle = isSuccess ? 'Good choice! This username is available' : validationState.message;
468
+ return /*#__PURE__*/_jsxs(View, {
469
+ style: [styles.validationCard, {
470
+ backgroundColor,
471
+ borderColor
472
+ }],
473
+ children: [/*#__PURE__*/_jsx(View, {
474
+ style: [styles.validationIconContainer, {
475
+ backgroundColor: iconColor + '20'
476
+ }],
477
+ children: /*#__PURE__*/_jsx(Ionicons, {
478
+ name: iconName,
479
+ size: 16,
480
+ color: iconColor
481
+ })
482
+ }), /*#__PURE__*/_jsxs(View, {
483
+ style: styles.validationTextContainer,
484
+ children: [/*#__PURE__*/_jsx(Text, {
485
+ style: [styles.validationTitle, {
486
+ color: iconColor
487
+ }],
488
+ children: title
489
+ }), /*#__PURE__*/_jsx(Text, {
490
+ style: [styles.validationSubtitle, {
491
+ color: colors.secondaryText
492
+ }],
493
+ children: subtitle
494
+ })]
495
+ })]
496
+ });
497
+ });
498
+ const FormInput = /*#__PURE__*/React.memo(({
499
+ icon,
500
+ label,
501
+ value,
502
+ onChangeText,
503
+ secureTextEntry = false,
504
+ keyboardType = 'default',
505
+ autoCapitalize = 'sentences',
506
+ autoCorrect = true,
507
+ testID,
508
+ colors,
509
+ styles,
510
+ borderColor,
511
+ rightComponent
512
+ }) => /*#__PURE__*/_jsx(View, {
513
+ style: styles.inputContainer,
514
+ children: /*#__PURE__*/_jsxs(View, {
515
+ style: [styles.premiumInputWrapper, {
516
+ borderColor: borderColor || colors.border,
517
+ backgroundColor: colors.inputBackground,
518
+ shadowColor: colors.primary,
519
+ shadowOffset: {
520
+ width: 0,
521
+ height: 4
522
+ },
523
+ shadowOpacity: 0.1,
524
+ shadowRadius: 12,
525
+ elevation: 3
526
+ }],
527
+ children: [/*#__PURE__*/_jsx(Ionicons, {
528
+ name: icon,
529
+ size: 22,
530
+ color: colors.secondaryText,
531
+ style: styles.inputIcon
532
+ }), /*#__PURE__*/_jsxs(View, {
533
+ style: styles.inputContent,
534
+ children: [/*#__PURE__*/_jsx(Text, {
535
+ style: [styles.modernLabel, {
536
+ color: colors.secondaryText
537
+ }],
538
+ children: label
539
+ }), /*#__PURE__*/_jsx(TextInput, {
540
+ style: [styles.modernInput, {
541
+ color: colors.text
542
+ }],
543
+ value: value,
544
+ onChangeText: onChangeText,
545
+ secureTextEntry: secureTextEntry,
546
+ keyboardType: keyboardType,
547
+ autoCapitalize: autoCapitalize,
548
+ autoCorrect: autoCorrect,
549
+ testID: testID,
550
+ placeholderTextColor: "transparent"
551
+ })]
552
+ }), rightComponent]
553
+ })
554
+ }));
555
+ const ProgressIndicator = /*#__PURE__*/React.memo(({
556
+ currentStep,
557
+ totalSteps,
558
+ colors,
559
+ styles
560
+ }) => /*#__PURE__*/_jsx(View, {
561
+ style: styles.progressContainer,
562
+ children: Array.from({
563
+ length: totalSteps
564
+ }, (_, index) => /*#__PURE__*/_jsx(View, {
565
+ style: [styles.progressDot, currentStep === index ? {
566
+ backgroundColor: colors.primary,
567
+ width: 24
568
+ } : {
569
+ backgroundColor: colors.border
570
+ }]
571
+ }, index))
572
+ }));
573
+
574
+ // Main component
11
575
  const SignUpScreen = ({
12
576
  navigate,
13
577
  goBack,
578
+ onAuthenticated,
14
579
  theme
15
580
  }) => {
16
- // Form data states
17
- const [username, setUsername] = useState('');
18
- const [email, setEmail] = useState('');
19
- const [password, setPassword] = useState('');
20
- const [confirmPassword, setConfirmPassword] = useState('');
21
- const [showPassword, setShowPassword] = useState(false);
22
- const [showConfirmPassword, setShowConfirmPassword] = useState(false);
23
- const [errorMessage, setErrorMessage] = useState('');
24
-
25
- // Multi-step form states
26
- const [currentStep, setCurrentStep] = useState(0);
27
- const [isInputFocused, setIsInputFocused] = useState(false);
28
- const [isValidating, setIsValidating] = useState(false);
29
- const [validationStatus, setValidationStatus] = useState('idle');
30
-
31
- // Cache for validation results
32
- const validationCache = useRef(new Map());
33
- const fadeAnim = useRef(new Animated.Value(1)).current;
34
- const slideAnim = useRef(new Animated.Value(0)).current;
35
- const heightAnim = useRef(new Animated.Value(400)).current;
36
- const [containerHeight, setContainerHeight] = useState(400);
37
581
  const {
38
582
  signUp,
39
583
  isLoading,
@@ -42,109 +586,44 @@ const SignUpScreen = ({
42
586
  oxyServices
43
587
  } = useOxy();
44
588
  const colors = useThemeColors(theme);
45
- const commonStyles = createCommonStyles(theme);
46
-
47
- // Memoized styles to prevent rerenders
48
- const styles = useMemo(() => createStyles(colors, theme), [colors, theme]);
49
-
50
- // Input focus animations
51
- const handleInputFocus = useCallback(() => {
52
- setIsInputFocused(true);
53
- }, []);
54
- const handleInputBlur = useCallback(() => {
55
- setIsInputFocused(false);
56
- }, []);
57
-
58
- // Memoized input change handlers
59
- const handleUsernameChange = useCallback(text => {
60
- setUsername(text);
61
- if (validationStatus === 'invalid') {
62
- setErrorMessage('');
63
- setValidationStatus('idle');
64
- }
65
- }, [validationStatus]);
66
- const handleEmailChange = useCallback(text => {
67
- setEmail(text);
68
- setErrorMessage('');
69
- }, []);
70
- const handlePasswordChange = useCallback(text => {
71
- setPassword(text);
72
- setErrorMessage('');
73
- }, []);
74
- const handleConfirmPasswordChange = useCallback(text => {
75
- setConfirmPassword(text);
76
- setErrorMessage('');
77
- }, []);
78
589
 
79
- // Username availability validation using core services
80
- const validateUsername = useCallback(async usernameToValidate => {
81
- if (!usernameToValidate || usernameToValidate.length < 3) {
82
- setValidationStatus('invalid');
83
- return false;
84
- }
590
+ // Form state
591
+ const {
592
+ formData,
593
+ passwordVisibility,
594
+ updateField,
595
+ togglePasswordVisibility,
596
+ resetForm
597
+ } = useFormData();
598
+ const {
599
+ validationState,
600
+ validateUsername,
601
+ validateEmail,
602
+ validatePassword,
603
+ validatePasswordsMatch
604
+ } = useFormValidation(oxyServices);
85
605
 
86
- // Check cache first (cache valid for 5 minutes)
87
- const cached = validationCache.current.get(usernameToValidate);
88
- const now = Date.now();
89
- if (cached && now - cached.timestamp < 5 * 60 * 1000) {
90
- setValidationStatus(cached.available ? 'valid' : 'invalid');
91
- setErrorMessage(cached.available ? '' : 'Username is already taken');
92
- return cached.available;
93
- }
94
- setIsValidating(true);
95
- setValidationStatus('validating');
96
- try {
97
- const result = await oxyServices.checkUsernameAvailability(usernameToValidate);
98
- if (result.available) {
99
- setValidationStatus('valid');
100
- setErrorMessage('');
606
+ // UI state
607
+ const [currentStep, setCurrentStep] = useState(0);
608
+ const [errorMessage, setErrorMessage] = useState('');
101
609
 
102
- // Cache the result
103
- validationCache.current.set(usernameToValidate, {
104
- available: true,
105
- timestamp: now
106
- });
107
- return true;
108
- } else {
109
- setValidationStatus('invalid');
110
- setErrorMessage(result.message || 'Username is already taken');
610
+ // Animation refs
611
+ const fadeAnim = useRef(new Animated.Value(1)).current;
612
+ const slideAnim = useRef(new Animated.Value(0)).current;
111
613
 
112
- // Cache the result
113
- validationCache.current.set(usernameToValidate, {
114
- available: false,
115
- timestamp: now
116
- });
117
- return false;
118
- }
119
- } catch (error) {
120
- console.error('Username validation error:', error);
121
- setValidationStatus('invalid');
122
- setErrorMessage('Unable to validate username. Please try again.');
123
- return false;
124
- } finally {
125
- setIsValidating(false);
126
- }
127
- }, [oxyServices]);
614
+ // Memoized styles
615
+ const styles = useMemo(() => createStyles(colors, theme), [colors, theme]);
128
616
 
129
617
  // Debounced username validation
130
618
  useEffect(() => {
131
- if (!username || username.length < 3) {
132
- setValidationStatus('idle');
133
- setErrorMessage('');
619
+ if (!formData.username || formData.username.length < USERNAME_MIN_LENGTH) {
134
620
  return;
135
621
  }
136
622
  const timeoutId = setTimeout(() => {
137
- validateUsername(username);
138
- }, 800);
623
+ validateUsername(formData.username);
624
+ }, VALIDATION_DEBOUNCE_MS);
139
625
  return () => clearTimeout(timeoutId);
140
- }, [username, validateUsername]);
141
-
142
- // Cleanup cache on unmount
143
- useEffect(() => {
144
- return () => {
145
- validationCache.current.clear();
146
- };
147
- }, []);
626
+ }, [formData.username, validateUsername]);
148
627
 
149
628
  // Animation functions
150
629
  const animateTransition = useCallback(nextStep => {
@@ -176,116 +655,83 @@ const SignUpScreen = ({
176
655
  animateTransition(currentStep - 1);
177
656
  }
178
657
  }, [currentStep, animateTransition]);
179
- const validateEmail = useCallback(email => {
180
- const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
181
- return emailRegex.test(email);
182
- }, []);
183
- const handleSignUp = useCallback(async () => {
184
- if (!username || !email || !password || !confirmPassword) {
185
- toast.error('Please fill in all fields');
186
- return;
187
- }
188
- if (!validateEmail(email)) {
189
- toast.error('Please enter a valid email address');
190
- return;
191
- }
192
- if (validationStatus !== 'valid') {
193
- toast.error('Please enter a valid username');
658
+
659
+ // Form validation helpers
660
+ const isIdentityStepValid = useCallback(() => {
661
+ return formData.username && formData.email && validateEmail(formData.email) && validationState.status === 'valid';
662
+ }, [formData.username, formData.email, validateEmail, validationState.status]);
663
+ const isSecurityStepValid = useCallback(() => {
664
+ return formData.password && validatePassword(formData.password) && validatePasswordsMatch(formData.password, formData.confirmPassword);
665
+ }, [formData.password, formData.confirmPassword, validatePassword, validatePasswordsMatch]);
666
+
667
+ // Custom next handlers for validation
668
+ const handleIdentityNext = useCallback(() => {
669
+ if (!isIdentityStepValid()) {
670
+ toast.error('Please enter a valid username and email.');
194
671
  return;
195
672
  }
196
- if (password !== confirmPassword) {
197
- toast.error('Passwords do not match');
673
+ nextStep();
674
+ }, [isIdentityStepValid, nextStep]);
675
+ const handleSecurityNext = useCallback(() => {
676
+ if (!isSecurityStepValid()) {
677
+ toast.error('Please enter a valid password and confirm it.');
198
678
  return;
199
679
  }
200
- if (password.length < 8) {
201
- toast.error('Password must be at least 8 characters long');
680
+ nextStep();
681
+ }, [isSecurityStepValid, nextStep]);
682
+
683
+ // Sign up handler
684
+ const handleSignUp = useCallback(async () => {
685
+ if (!isIdentityStepValid() || !isSecurityStepValid()) {
686
+ toast.error('Please fill in all fields correctly');
202
687
  return;
203
688
  }
204
689
  try {
205
690
  setErrorMessage('');
206
- await signUp(username, email, password);
691
+ const user = await signUp(formData.username, formData.email, formData.password);
207
692
  toast.success('Account created successfully! Welcome to Oxy!');
693
+ if (onAuthenticated) {
694
+ onAuthenticated(user);
695
+ }
696
+ resetForm();
208
697
  } catch (error) {
209
698
  toast.error(error.message || 'Sign up failed');
210
699
  }
211
- }, [username, email, password, confirmPassword, validationStatus, validateEmail, signUp]);
700
+ }, [formData, isIdentityStepValid, isSecurityStepValid, signUp, onAuthenticated, resetForm]);
212
701
 
213
702
  // Step components
214
- const renderWelcomeStep = useMemo(() => /*#__PURE__*/_jsxs(Animated.View, {
703
+ const renderWelcomeStep = useCallback(() => /*#__PURE__*/_jsxs(Animated.View, {
215
704
  style: [styles.stepContainer, {
216
705
  opacity: fadeAnim,
217
706
  transform: [{
218
707
  translateX: slideAnim
219
708
  }]
220
709
  }],
221
- children: [/*#__PURE__*/_jsx(View, {
222
- style: styles.welcomeImageContainer,
223
- children: /*#__PURE__*/_jsxs(Svg, {
224
- width: 220,
225
- height: 120,
226
- viewBox: "0 0 220 120",
227
- children: [/*#__PURE__*/_jsx(Path, {
228
- d: "M30 100 Q60 20 110 60 Q160 100 190 40",
229
- stroke: colors.primary,
230
- strokeWidth: "8",
231
- fill: "none"
232
- }), /*#__PURE__*/_jsx(Circle, {
233
- cx: "60",
234
- cy: "60",
235
- r: "18",
236
- fill: colors.primary,
237
- opacity: "0.18"
238
- }), /*#__PURE__*/_jsx(Circle, {
239
- cx: "110",
240
- cy: "60",
241
- r: "24",
242
- fill: colors.primary,
243
- opacity: "0.25"
244
- }), /*#__PURE__*/_jsx(Circle, {
245
- cx: "170",
246
- cy: "50",
247
- r: "14",
248
- fill: colors.primary,
249
- opacity: "0.15"
250
- }), /*#__PURE__*/_jsx(Circle, {
251
- cx: "110",
252
- cy: "60",
253
- r: "32",
254
- fill: "#fff",
255
- opacity: "0.7"
256
- }), /*#__PURE__*/_jsx(Circle, {
257
- cx: "100",
258
- cy: "55",
259
- r: "4",
260
- fill: colors.primary
261
- }), /*#__PURE__*/_jsx(Circle, {
262
- cx: "120",
263
- cy: "55",
264
- r: "4",
265
- fill: colors.primary
266
- }), /*#__PURE__*/_jsx(Path, {
267
- d: "M104 68 Q110 75 116 68",
268
- stroke: colors.primary,
269
- strokeWidth: "2",
270
- fill: "none",
271
- strokeLinecap: "round"
272
- })]
273
- })
274
- }), /*#__PURE__*/_jsx(Text, {
275
- style: [styles.welcomeText, {
276
- color: colors.text
277
- }],
278
- children: "We're excited to have you join us. Let's get your account set up in just a few easy steps."
279
- }), /*#__PURE__*/_jsx(TouchableOpacity, {
280
- style: [styles.button, {
281
- backgroundColor: colors.primary
710
+ children: [/*#__PURE__*/_jsx(HighFive, {
711
+ width: 100,
712
+ height: 100
713
+ }), /*#__PURE__*/_jsxs(View, {
714
+ style: styles.modernHeader,
715
+ children: [/*#__PURE__*/_jsx(Text, {
716
+ style: [styles.modernTitle, {
717
+ color: colors.text
718
+ }],
719
+ children: "Welcome to Oxy"
720
+ }), /*#__PURE__*/_jsx(Text, {
721
+ style: [styles.modernSubtitle, {
722
+ color: colors.secondaryText
723
+ }],
724
+ children: "We're excited to have you join us. Let's get your account set up in just a few easy steps."
725
+ })]
726
+ }), /*#__PURE__*/_jsx(GroupedPillButtons, {
727
+ buttons: [{
728
+ text: 'Get Started',
729
+ onPress: nextStep,
730
+ icon: 'arrow-forward',
731
+ variant: 'primary',
732
+ testID: 'welcome-next-button'
282
733
  }],
283
- onPress: nextStep,
284
- testID: "welcome-next-button",
285
- children: /*#__PURE__*/_jsx(Text, {
286
- style: styles.buttonText,
287
- children: "Get Started"
288
- })
734
+ colors: colors
289
735
  }), /*#__PURE__*/_jsxs(View, {
290
736
  style: styles.footerTextContainer,
291
737
  children: [/*#__PURE__*/_jsxs(Text, {
@@ -304,257 +750,148 @@ const SignUpScreen = ({
304
750
  })]
305
751
  })]
306
752
  }), [fadeAnim, slideAnim, colors, nextStep, navigate, styles]);
307
- const renderIdentityStep = useMemo(() => /*#__PURE__*/_jsxs(Animated.View, {
753
+ const renderIdentityStep = useCallback(() => /*#__PURE__*/_jsxs(Animated.View, {
308
754
  style: [styles.stepContainer, {
309
755
  opacity: fadeAnim,
310
756
  transform: [{
311
757
  translateX: slideAnim
312
758
  }]
313
759
  }],
314
- children: [/*#__PURE__*/_jsx(Text, {
315
- style: [styles.stepTitle, {
316
- color: colors.text
317
- }],
318
- children: "Who are you?"
319
- }), /*#__PURE__*/_jsxs(View, {
320
- style: styles.inputContainer,
321
- children: [/*#__PURE__*/_jsx(Text, {
322
- style: [styles.label, {
323
- color: colors.text
324
- }],
325
- children: "Username"
326
- }), /*#__PURE__*/_jsxs(View, {
327
- style: {
328
- position: 'relative'
329
- },
330
- children: [/*#__PURE__*/_jsx(TextInput, {
331
- style: [styles.input, {
332
- backgroundColor: colors.inputBackground,
333
- borderColor: colors.border,
334
- color: colors.text
335
- }],
336
- placeholder: "Choose a username",
337
- placeholderTextColor: colors.placeholder,
338
- value: username,
339
- onChangeText: handleUsernameChange,
340
- autoCapitalize: "none",
341
- testID: "username-input"
342
- }), validationStatus === 'validating' && /*#__PURE__*/_jsx(ActivityIndicator, {
343
- size: "small",
344
- color: colors.primary,
345
- style: styles.validationIndicator
346
- }), validationStatus === 'valid' && /*#__PURE__*/_jsx(Ionicons, {
347
- name: "checkmark-circle",
348
- size: 20,
349
- color: colors.success,
350
- style: styles.validationIndicator
351
- }), validationStatus === 'invalid' && username.length >= 3 && /*#__PURE__*/_jsx(Ionicons, {
352
- name: "close-circle",
353
- size: 20,
354
- color: colors.error,
355
- style: styles.validationIndicator
356
- })]
357
- }), validationStatus === 'valid' && /*#__PURE__*/_jsxs(View, {
358
- style: [styles.validationSuccessCard, {
359
- backgroundColor: colors.success + '15'
360
- }],
361
- children: [/*#__PURE__*/_jsx(Ionicons, {
362
- name: "checkmark-circle",
363
- size: 16,
364
- color: colors.success
365
- }), /*#__PURE__*/_jsx(Text, {
366
- style: [styles.validationText, {
367
- color: colors.success
368
- }],
369
- children: "Username is available"
370
- })]
371
- }), validationStatus === 'invalid' && username.length >= 3 && /*#__PURE__*/_jsxs(View, {
372
- style: [styles.validationErrorCard, {
373
- backgroundColor: colors.error + '15'
374
- }],
375
- children: [/*#__PURE__*/_jsx(Ionicons, {
376
- name: "alert-circle",
377
- size: 16,
378
- color: colors.error
379
- }), /*#__PURE__*/_jsx(Text, {
380
- style: [styles.validationText, {
381
- color: colors.error
382
- }],
383
- children: errorMessage || 'Username is already taken'
384
- })]
385
- })]
386
- }), /*#__PURE__*/_jsxs(View, {
387
- style: styles.inputContainer,
388
- children: [/*#__PURE__*/_jsx(Text, {
389
- style: [styles.label, {
390
- color: colors.text
391
- }],
392
- children: "Email"
393
- }), /*#__PURE__*/_jsx(TextInput, {
394
- style: [styles.input, {
395
- backgroundColor: colors.inputBackground,
396
- borderColor: colors.border,
760
+ children: [/*#__PURE__*/_jsx(View, {
761
+ style: styles.modernHeader,
762
+ children: /*#__PURE__*/_jsx(Text, {
763
+ style: [styles.stepTitle, {
397
764
  color: colors.text
398
765
  }],
399
- placeholder: "Enter your email",
400
- placeholderTextColor: colors.placeholder,
401
- value: email,
402
- onChangeText: handleEmailChange,
403
- autoCapitalize: "none",
404
- keyboardType: "email-address",
405
- testID: "email-input"
406
- })]
407
- }), /*#__PURE__*/_jsxs(View, {
408
- style: styles.navigationButtons,
409
- children: [/*#__PURE__*/_jsx(TouchableOpacity, {
410
- style: [styles.navButton, styles.backButton, {
411
- borderColor: colors.border
412
- }],
766
+ children: "Who are you?"
767
+ })
768
+ }), /*#__PURE__*/_jsx(TextField, {
769
+ icon: "person-outline",
770
+ label: "Username",
771
+ value: formData.username,
772
+ onChangeText: text => {
773
+ updateField('username', text);
774
+ setErrorMessage('');
775
+ },
776
+ autoCapitalize: "none",
777
+ autoCorrect: false,
778
+ testID: "username-input",
779
+ colors: colors,
780
+ variant: "filled",
781
+ error: validationState.status === 'invalid' ? validationState.message : undefined,
782
+ loading: validationState.status === 'validating',
783
+ success: validationState.status === 'valid'
784
+ }), /*#__PURE__*/_jsx(ValidationMessage, {
785
+ validationState: validationState,
786
+ colors: colors,
787
+ styles: styles
788
+ }), /*#__PURE__*/_jsx(TextField, {
789
+ icon: "mail-outline",
790
+ label: "Email",
791
+ value: formData.email,
792
+ onChangeText: text => {
793
+ updateField('email', text);
794
+ },
795
+ keyboardType: "email-address",
796
+ autoCapitalize: "none",
797
+ autoCorrect: false,
798
+ testID: "email-input",
799
+ colors: colors,
800
+ variant: "filled",
801
+ error: formData.email && !validateEmail(formData.email) ? 'Please enter a valid email address' : undefined
802
+ }), /*#__PURE__*/_jsx(GroupedPillButtons, {
803
+ buttons: [{
804
+ text: 'Back',
413
805
  onPress: prevStep,
414
- children: /*#__PURE__*/_jsx(Text, {
415
- style: [styles.navButtonText, {
416
- color: colors.text
417
- }],
418
- children: "Back"
419
- })
420
- }), /*#__PURE__*/_jsx(TouchableOpacity, {
421
- style: [styles.navButton, styles.nextButton, {
422
- backgroundColor: colors.primary
423
- }],
424
- onPress: nextStep,
425
- disabled: !username || !email || !validateEmail(email) || validationStatus !== 'valid',
426
- children: /*#__PURE__*/_jsx(Text, {
427
- style: [styles.navButtonText, {
428
- color: '#FFFFFF'
429
- }],
430
- children: "Next"
431
- })
432
- })]
806
+ icon: 'arrow-back',
807
+ variant: 'transparent'
808
+ }, {
809
+ text: 'Next',
810
+ onPress: handleIdentityNext,
811
+ icon: 'arrow-forward',
812
+ variant: 'primary'
813
+ }],
814
+ colors: colors
433
815
  })]
434
- }), [fadeAnim, slideAnim, colors, username, email, validationStatus, errorMessage, handleUsernameChange, handleEmailChange, validateEmail, prevStep, nextStep, styles]);
435
- const renderSecurityStep = useMemo(() => /*#__PURE__*/_jsxs(Animated.View, {
816
+ }), [fadeAnim, slideAnim, colors, formData, validationState, updateField, setErrorMessage, prevStep, handleIdentityNext, styles]);
817
+ const renderSecurityStep = useCallback(() => /*#__PURE__*/_jsxs(Animated.View, {
436
818
  style: [styles.stepContainer, {
437
819
  opacity: fadeAnim,
438
820
  transform: [{
439
821
  translateX: slideAnim
440
822
  }]
441
823
  }],
442
- children: [/*#__PURE__*/_jsx(Text, {
443
- style: [styles.stepTitle, {
444
- color: colors.text
445
- }],
446
- children: "Secure your account"
447
- }), /*#__PURE__*/_jsxs(View, {
448
- style: styles.inputContainer,
449
- children: [/*#__PURE__*/_jsx(Text, {
450
- style: [styles.label, {
451
- color: colors.text
452
- }],
453
- children: "Password"
454
- }), /*#__PURE__*/_jsxs(View, {
455
- style: {
456
- position: 'relative'
457
- },
458
- children: [/*#__PURE__*/_jsx(TextInput, {
459
- style: [styles.input, {
460
- backgroundColor: colors.inputBackground,
461
- borderColor: colors.border,
462
- color: colors.text
463
- }],
464
- placeholder: "Create a password",
465
- placeholderTextColor: colors.placeholder,
466
- value: password,
467
- onChangeText: handlePasswordChange,
468
- secureTextEntry: !showPassword,
469
- testID: "password-input"
470
- }), /*#__PURE__*/_jsx(TouchableOpacity, {
471
- style: styles.passwordToggle,
472
- onPress: () => setShowPassword(!showPassword),
473
- children: /*#__PURE__*/_jsx(Ionicons, {
474
- name: showPassword ? 'eye-off' : 'eye',
475
- size: 20,
476
- color: colors.placeholder
477
- })
478
- })]
479
- }), /*#__PURE__*/_jsx(Text, {
480
- style: [styles.passwordHint, {
481
- color: colors.secondaryText
482
- }],
483
- children: "Password must be at least 8 characters long"
484
- })]
485
- }), /*#__PURE__*/_jsxs(View, {
486
- style: styles.inputContainer,
487
- children: [/*#__PURE__*/_jsx(Text, {
488
- style: [styles.label, {
824
+ children: [/*#__PURE__*/_jsx(View, {
825
+ style: styles.modernHeader,
826
+ children: /*#__PURE__*/_jsx(Text, {
827
+ style: [styles.stepTitle, {
489
828
  color: colors.text
490
829
  }],
491
- children: "Confirm Password"
492
- }), /*#__PURE__*/_jsxs(View, {
493
- style: {
494
- position: 'relative'
495
- },
496
- children: [/*#__PURE__*/_jsx(TextInput, {
497
- style: [styles.input, {
498
- backgroundColor: colors.inputBackground,
499
- borderColor: colors.border,
500
- color: colors.text
501
- }],
502
- placeholder: "Confirm your password",
503
- placeholderTextColor: colors.placeholder,
504
- value: confirmPassword,
505
- onChangeText: handleConfirmPasswordChange,
506
- secureTextEntry: !showConfirmPassword,
507
- testID: "confirm-password-input"
508
- }), /*#__PURE__*/_jsx(TouchableOpacity, {
509
- style: styles.passwordToggle,
510
- onPress: () => setShowConfirmPassword(!showConfirmPassword),
511
- children: /*#__PURE__*/_jsx(Ionicons, {
512
- name: showConfirmPassword ? 'eye-off' : 'eye',
513
- size: 20,
514
- color: colors.placeholder
515
- })
516
- })]
517
- })]
518
- }), /*#__PURE__*/_jsxs(View, {
519
- style: styles.navigationButtons,
520
- children: [/*#__PURE__*/_jsx(TouchableOpacity, {
521
- style: [styles.navButton, styles.backButton, {
522
- borderColor: colors.border
523
- }],
830
+ children: "Secure your account"
831
+ })
832
+ }), /*#__PURE__*/_jsx(TextField, {
833
+ icon: "lock-closed-outline",
834
+ label: "Password",
835
+ value: formData.password,
836
+ onChangeText: text => {
837
+ updateField('password', text);
838
+ },
839
+ secureTextEntry: !passwordVisibility.password,
840
+ autoCapitalize: "none",
841
+ autoCorrect: false,
842
+ testID: "password-input",
843
+ colors: colors,
844
+ variant: "filled",
845
+ error: formData.password && !validatePassword(formData.password) ? `Password must be at least ${PASSWORD_MIN_LENGTH} characters` : undefined
846
+ }), /*#__PURE__*/_jsxs(Text, {
847
+ style: [styles.passwordHint, {
848
+ color: colors.secondaryText
849
+ }],
850
+ children: ["Password must be at least ", PASSWORD_MIN_LENGTH, " characters long"]
851
+ }), /*#__PURE__*/_jsx(TextField, {
852
+ icon: "lock-closed-outline",
853
+ label: "Confirm Password",
854
+ value: formData.confirmPassword,
855
+ onChangeText: text => {
856
+ updateField('confirmPassword', text);
857
+ },
858
+ secureTextEntry: !passwordVisibility.confirmPassword,
859
+ autoCapitalize: "none",
860
+ autoCorrect: false,
861
+ testID: "confirm-password-input",
862
+ colors: colors,
863
+ variant: "filled",
864
+ error: formData.confirmPassword && !validatePasswordsMatch(formData.password, formData.confirmPassword) ? 'Passwords do not match' : undefined
865
+ }), /*#__PURE__*/_jsx(GroupedPillButtons, {
866
+ buttons: [{
867
+ text: 'Back',
524
868
  onPress: prevStep,
525
- children: /*#__PURE__*/_jsx(Text, {
526
- style: [styles.navButtonText, {
527
- color: colors.text
528
- }],
529
- children: "Back"
530
- })
531
- }), /*#__PURE__*/_jsx(TouchableOpacity, {
532
- style: [styles.navButton, styles.nextButton, {
533
- backgroundColor: colors.primary
534
- }],
535
- onPress: nextStep,
536
- disabled: !password || password.length < 8 || password !== confirmPassword,
537
- children: /*#__PURE__*/_jsx(Text, {
538
- style: [styles.navButtonText, {
539
- color: '#FFFFFF'
540
- }],
541
- children: "Next"
542
- })
543
- })]
869
+ icon: 'arrow-back',
870
+ variant: 'transparent'
871
+ }, {
872
+ text: 'Next',
873
+ onPress: handleSecurityNext,
874
+ icon: 'arrow-forward',
875
+ variant: 'primary'
876
+ }],
877
+ colors: colors
544
878
  })]
545
- }), [fadeAnim, slideAnim, colors, password, confirmPassword, showPassword, showConfirmPassword, handlePasswordChange, handleConfirmPasswordChange, prevStep, nextStep, styles]);
546
- const renderSummaryStep = useMemo(() => /*#__PURE__*/_jsxs(Animated.View, {
879
+ }), [fadeAnim, slideAnim, colors, formData, passwordVisibility, updateField, setErrorMessage, togglePasswordVisibility, prevStep, handleSecurityNext, styles]);
880
+ const renderSummaryStep = useCallback(() => /*#__PURE__*/_jsxs(Animated.View, {
547
881
  style: [styles.stepContainer, {
548
882
  opacity: fadeAnim,
549
883
  transform: [{
550
884
  translateX: slideAnim
551
885
  }]
552
886
  }],
553
- children: [/*#__PURE__*/_jsx(Text, {
554
- style: [styles.stepTitle, {
555
- color: colors.text
556
- }],
557
- children: "Ready to join"
887
+ children: [/*#__PURE__*/_jsx(View, {
888
+ style: styles.modernHeader,
889
+ children: /*#__PURE__*/_jsx(Text, {
890
+ style: [styles.stepTitle, {
891
+ color: colors.text
892
+ }],
893
+ children: "Ready to join"
894
+ })
558
895
  }), /*#__PURE__*/_jsxs(View, {
559
896
  style: styles.summaryContainer,
560
897
  children: [/*#__PURE__*/_jsxs(View, {
@@ -568,7 +905,7 @@ const SignUpScreen = ({
568
905
  style: [styles.summaryValue, {
569
906
  color: colors.text
570
907
  }],
571
- children: username
908
+ children: formData.username
572
909
  })]
573
910
  }), /*#__PURE__*/_jsxs(View, {
574
911
  style: styles.summaryRow,
@@ -581,66 +918,29 @@ const SignUpScreen = ({
581
918
  style: [styles.summaryValue, {
582
919
  color: colors.text
583
920
  }],
584
- children: email
921
+ children: formData.email
585
922
  })]
586
923
  })]
587
- }), /*#__PURE__*/_jsx(TouchableOpacity, {
588
- style: [styles.button, {
589
- backgroundColor: colors.primary
590
- }],
591
- onPress: handleSignUp,
592
- disabled: isLoading,
593
- testID: "signup-button",
594
- children: isLoading ? /*#__PURE__*/_jsx(ActivityIndicator, {
595
- color: "#FFFFFF",
596
- size: "small"
597
- }) : /*#__PURE__*/_jsx(Text, {
598
- style: styles.buttonText,
599
- children: "Create Account"
600
- })
601
- }), /*#__PURE__*/_jsx(View, {
602
- style: styles.navigationButtons,
603
- children: /*#__PURE__*/_jsx(TouchableOpacity, {
604
- style: [styles.navButton, styles.backButton, {
605
- borderColor: colors.border
606
- }],
924
+ }), /*#__PURE__*/_jsx(GroupedPillButtons, {
925
+ buttons: [{
926
+ text: 'Back',
607
927
  onPress: prevStep,
608
- children: /*#__PURE__*/_jsx(Text, {
609
- style: [styles.navButtonText, {
610
- color: colors.text
611
- }],
612
- children: "Back"
613
- })
614
- })
928
+ icon: 'arrow-back',
929
+ variant: 'transparent'
930
+ }, {
931
+ text: 'Create Account',
932
+ onPress: handleSignUp,
933
+ icon: 'checkmark',
934
+ variant: 'primary',
935
+ disabled: isLoading,
936
+ loading: isLoading,
937
+ testID: 'signup-button'
938
+ }],
939
+ colors: colors
615
940
  })]
616
- }), [fadeAnim, slideAnim, colors, username, email, isLoading, handleSignUp, prevStep, styles]);
617
- const renderProgressIndicators = useMemo(() => /*#__PURE__*/_jsx(View, {
618
- style: styles.progressContainer,
619
- children: [0, 1, 2, 3].map(step => /*#__PURE__*/_jsx(View, {
620
- style: [styles.progressDot, currentStep === step ? {
621
- backgroundColor: colors.primary,
622
- width: 24
623
- } : {
624
- backgroundColor: colors.border
625
- }]
626
- }, step))
627
- }), [currentStep, colors, styles]);
628
- const renderCurrentStep = useCallback(() => {
629
- switch (currentStep) {
630
- case 0:
631
- return renderWelcomeStep;
632
- case 1:
633
- return renderIdentityStep;
634
- case 2:
635
- return renderSecurityStep;
636
- case 3:
637
- return renderSummaryStep;
638
- default:
639
- return renderWelcomeStep;
640
- }
641
- }, [currentStep, renderWelcomeStep, renderIdentityStep, renderSecurityStep, renderSummaryStep]);
941
+ }), [fadeAnim, slideAnim, colors, formData, isLoading, handleSignUp, prevStep, styles]);
642
942
 
643
- // If user is already authenticated, show user info and account center option
943
+ // If user is already authenticated, show user info
644
944
  if (user && isAuthenticated) {
645
945
  return /*#__PURE__*/_jsxs(KeyboardAvoidingView, {
646
946
  style: [styles.container, {
@@ -689,6 +989,22 @@ const SignUpScreen = ({
689
989
  })]
690
990
  });
691
991
  }
992
+
993
+ // Render current step
994
+ const renderCurrentStep = useCallback(() => {
995
+ switch (currentStep) {
996
+ case 0:
997
+ return renderWelcomeStep();
998
+ case 1:
999
+ return renderIdentityStep();
1000
+ case 2:
1001
+ return renderSecurityStep();
1002
+ case 3:
1003
+ return renderSummaryStep();
1004
+ default:
1005
+ return renderWelcomeStep();
1006
+ }
1007
+ }, [currentStep, renderWelcomeStep, renderIdentityStep, renderSecurityStep, renderSummaryStep]);
692
1008
  return /*#__PURE__*/_jsxs(KeyboardAvoidingView, {
693
1009
  style: [styles.container, {
694
1010
  backgroundColor: colors.background
@@ -701,232 +1017,14 @@ const SignUpScreen = ({
701
1017
  contentContainerStyle: styles.scrollContent,
702
1018
  showsVerticalScrollIndicator: false,
703
1019
  keyboardShouldPersistTaps: "handled",
704
- children: [renderProgressIndicators, renderCurrentStep()]
1020
+ children: [/*#__PURE__*/_jsx(ProgressIndicator, {
1021
+ currentStep: currentStep,
1022
+ totalSteps: 4,
1023
+ colors: colors,
1024
+ styles: styles
1025
+ }), renderCurrentStep()]
705
1026
  })]
706
1027
  });
707
1028
  };
708
-
709
- // Memoized styles creation
710
- const createStyles = (colors, theme) => StyleSheet.create({
711
- container: {
712
- flex: 1
713
- },
714
- scrollContent: {
715
- flexGrow: 1,
716
- paddingHorizontal: 24,
717
- paddingTop: 40,
718
- paddingBottom: 40
719
- },
720
- stepContainer: {
721
- flex: 1,
722
- justifyContent: 'center',
723
- alignItems: 'center',
724
- minHeight: 500
725
- },
726
- welcomeImageContainer: {
727
- alignItems: 'center',
728
- justifyContent: 'center',
729
- marginVertical: 30
730
- },
731
- welcomeTitle: {
732
- fontFamily: Platform.OS === 'web' ? 'Phudu' : 'Phudu-Bold',
733
- fontWeight: Platform.OS === 'web' ? 'bold' : undefined,
734
- fontSize: 42,
735
- lineHeight: 48,
736
- marginBottom: 24,
737
- textAlign: 'left',
738
- letterSpacing: -1
739
- },
740
- welcomeText: {
741
- fontSize: 16,
742
- textAlign: 'left',
743
- marginBottom: 30,
744
- lineHeight: 24
745
- },
746
- stepTitle: {
747
- fontFamily: Platform.OS === 'web' ? 'Phudu' : 'Phudu-Bold',
748
- fontWeight: Platform.OS === 'web' ? 'bold' : undefined,
749
- fontSize: 34,
750
- marginBottom: 20,
751
- color: colors.primary,
752
- maxWidth: '90%',
753
- textAlign: 'left'
754
- },
755
- inputContainer: {
756
- marginBottom: 18,
757
- width: '100%'
758
- },
759
- label: {
760
- fontSize: 15,
761
- marginBottom: 8,
762
- fontWeight: '500',
763
- letterSpacing: 0.1
764
- },
765
- input: {
766
- height: 48,
767
- borderRadius: 16,
768
- paddingHorizontal: 16,
769
- borderWidth: 1,
770
- fontSize: 16,
771
- marginBottom: 2
772
- },
773
- validationIndicator: {
774
- position: 'absolute',
775
- right: 16,
776
- top: 14
777
- },
778
- validationSuccessCard: {
779
- flexDirection: 'row',
780
- alignItems: 'center',
781
- padding: 12,
782
- borderRadius: 12,
783
- marginTop: 8,
784
- gap: 8
785
- },
786
- validationErrorCard: {
787
- flexDirection: 'row',
788
- alignItems: 'center',
789
- padding: 12,
790
- borderRadius: 12,
791
- marginTop: 8,
792
- gap: 8
793
- },
794
- validationText: {
795
- fontSize: 12,
796
- fontWeight: '500'
797
- },
798
- passwordToggle: {
799
- position: 'absolute',
800
- right: 16,
801
- top: 14,
802
- padding: 4
803
- },
804
- passwordHint: {
805
- fontSize: 12,
806
- marginTop: 4
807
- },
808
- button: {
809
- height: 48,
810
- borderRadius: 24,
811
- alignItems: 'center',
812
- justifyContent: 'center',
813
- marginTop: 24,
814
- shadowColor: colors.primary,
815
- shadowOpacity: 0.12,
816
- shadowOffset: {
817
- width: 0,
818
- height: 2
819
- },
820
- shadowRadius: 8,
821
- elevation: 2,
822
- width: '100%'
823
- },
824
- buttonText: {
825
- color: '#FFFFFF',
826
- fontSize: 17,
827
- fontWeight: '700',
828
- letterSpacing: 0.2
829
- },
830
- footerTextContainer: {
831
- flexDirection: 'row',
832
- justifyContent: 'center',
833
- marginTop: 28
834
- },
835
- footerText: {
836
- fontSize: 15
837
- },
838
- linkText: {
839
- fontSize: 15,
840
- fontWeight: '700'
841
- },
842
- userInfoContainer: {
843
- padding: 20,
844
- marginVertical: 20,
845
- borderRadius: 24,
846
- alignItems: 'center',
847
- shadowColor: '#000',
848
- shadowOpacity: 0.04,
849
- shadowOffset: {
850
- width: 0,
851
- height: 1
852
- },
853
- shadowRadius: 4,
854
- elevation: 1
855
- },
856
- userInfoText: {
857
- fontSize: 16,
858
- marginBottom: 8,
859
- textAlign: 'center'
860
- },
861
- actionButtonsContainer: {
862
- marginTop: 24
863
- },
864
- navigationButtons: {
865
- flexDirection: 'row',
866
- justifyContent: 'space-between',
867
- alignItems: 'center',
868
- marginTop: 28,
869
- width: '100%'
870
- },
871
- navButton: {
872
- borderRadius: 24,
873
- height: 44,
874
- alignItems: 'center',
875
- justifyContent: 'center',
876
- paddingHorizontal: 28,
877
- backgroundColor: '#F3E5F5'
878
- },
879
- backButton: {
880
- backgroundColor: 'transparent',
881
- borderWidth: 1
882
- },
883
- nextButton: {
884
- minWidth: 100
885
- },
886
- navButtonText: {
887
- fontSize: 16,
888
- fontWeight: '700'
889
- },
890
- progressContainer: {
891
- flexDirection: 'row',
892
- justifyContent: 'center',
893
- marginBottom: 20,
894
- marginTop: 8
895
- },
896
- progressDot: {
897
- height: 10,
898
- width: 10,
899
- borderRadius: 5,
900
- marginHorizontal: 6,
901
- borderWidth: 2,
902
- borderColor: '#fff',
903
- shadowColor: colors.primary,
904
- shadowOpacity: 0.08,
905
- shadowOffset: {
906
- width: 0,
907
- height: 1
908
- },
909
- shadowRadius: 2,
910
- elevation: 1
911
- },
912
- summaryContainer: {
913
- padding: 0,
914
- marginBottom: 24,
915
- width: '100%'
916
- },
917
- summaryRow: {
918
- flexDirection: 'row',
919
- marginBottom: 10
920
- },
921
- summaryLabel: {
922
- fontSize: 15,
923
- width: 90
924
- },
925
- summaryValue: {
926
- fontSize: 15,
927
- fontWeight: '600',
928
- flex: 1
929
- }
930
- });
931
1029
  export default SignUpScreen;
932
1030
  //# sourceMappingURL=SignUpScreen.js.map