11import React , { useState , useRef } from 'react' ;
2- import { View , Text , StyleSheet , TextInput , KeyboardAvoidingView , Platform , ScrollView } from 'react-native' ;
2+ import {
3+ View ,
4+ Text ,
5+ StyleSheet ,
6+ TextInput ,
7+ KeyboardAvoidingView ,
8+ Platform ,
9+ ScrollView ,
10+ } from 'react-native' ;
311import RNPickerSelect from 'react-native-picker-select' ;
412import { Button } from '@/components/ui/Button' ;
513import { router } from 'expo-router' ;
614
715export default function SignUpStep2 ( ) {
816 const [ gender , setGender ] = useState ( '' ) ;
9-
17+
1018 // DOB parts
1119 const [ dobMM , setDobMM ] = useState ( '' ) ;
1220 const [ dobDD , setDobDD ] = useState ( '' ) ;
1321 const [ dobYYYY , setDobYYYY ] = useState ( '' ) ;
14-
22+
1523 // Weight + units
1624 const [ weight , setWeight ] = useState ( '' ) ;
1725 const [ weightUnit , setWeightUnit ] = useState ( 'lbs' ) ;
18-
26+
1927 // Height + units
2028 const [ height , setHeight ] = useState ( '' ) ;
2129 const [ heightUnit , setHeightUnit ] = useState ( 'ft/in' ) ;
30+ const [ heightFeet , setHeightFeet ] = useState ( '' ) ;
31+ const [ heightInches , setHeightInches ] = useState ( '' ) ;
32+
2233
23- // refs for DOB inputs to auto-focus next field
2434 const ddRef = useRef < TextInput > ( null ) ;
2535 const yyyyRef = useRef < TextInput > ( null ) ;
2636
27- // Handle DOB input with auto-advance
2837 const onChangeDobMM = ( text : string ) => {
29- // Allow only digits, max 2 chars
3038 const cleanText = text . replace ( / [ ^ 0 - 9 ] / g, '' ) . slice ( 0 , 2 ) ;
3139 setDobMM ( cleanText ) ;
3240 if ( cleanText . length === 2 ) {
@@ -47,26 +55,24 @@ export default function SignUpStep2() {
4755 setDobYYYY ( cleanText ) ;
4856 } ;
4957
50- // Submit handler
5158 const handleNext = ( ) => {
52- // Add your validation & submit logic here
5359 if ( ! gender || ! dobMM || ! dobDD || ! dobYYYY || ! weight || ! height ) {
5460 alert ( 'Please fill out all fields' ) ;
5561 return ;
5662 }
57- // Proceed to next screen or API call
5863 router . replace ( '/home' ) ;
5964 } ;
6065
6166 return (
6267 < KeyboardAvoidingView
6368 style = { styles . container }
6469 behavior = { Platform . OS === 'ios' ? 'padding' : undefined }
65- keyboardVerticalOffset = { Platform . OS === 'ios' ? 64 : 0 }
70+ keyboardVerticalOffset = { 64 }
6671 >
6772 < ScrollView contentContainerStyle = { styles . contentContainer } >
6873 < Text style = { styles . title } > Additional Info</ Text >
6974
75+ { /* Gender */ }
7076 < Text style = { styles . label } > Gender</ Text >
7177 < RNPickerSelect
7278 onValueChange = { setGender }
@@ -81,7 +87,9 @@ export default function SignUpStep2() {
8187 style = { pickerSelectStyles }
8288 />
8389
84- < Text style = { styles . label } > Date of Birth (MM/DD/YYYY)</ Text >
90+ { /* DOB */ }
91+ < Text style = { styles . label } > Date of Birth</ Text >
92+ < Text style = { styles . subLabel } > MM / DD / YYYY</ Text >
8593 < View style = { styles . dobRow } >
8694 < TextInput
8795 style = { [ styles . dobInput , styles . dobPart ] }
@@ -93,6 +101,7 @@ export default function SignUpStep2() {
93101 returnKeyType = "next"
94102 blurOnSubmit = { false }
95103 onSubmitEditing = { ( ) => ddRef . current ?. focus ( ) }
104+ placeholderTextColor = "#999"
96105 />
97106 < Text style = { styles . slash } > /</ Text >
98107 < TextInput
@@ -106,6 +115,7 @@ export default function SignUpStep2() {
106115 returnKeyType = "next"
107116 blurOnSubmit = { false }
108117 onSubmitEditing = { ( ) => yyyyRef . current ?. focus ( ) }
118+ placeholderTextColor = "#999"
109119 />
110120 < Text style = { styles . slash } > /</ Text >
111121 < TextInput
@@ -117,49 +127,95 @@ export default function SignUpStep2() {
117127 maxLength = { 4 }
118128 placeholder = "YYYY"
119129 returnKeyType = "done"
130+ placeholderTextColor = "#999"
120131 />
121132 </ View >
122133
123- < Text style = { styles . label } > Weight</ Text >
124- < View style = { styles . row } >
125- < TextInput
126- style = { [ styles . textInput , { flex : 1 } ] }
127- value = { weight }
128- onChangeText = { setWeight }
129- keyboardType = "numeric"
130- placeholder = "Enter weight"
131- />
132- < RNPickerSelect
133- onValueChange = { setWeightUnit }
134- value = { weightUnit }
135- items = { [
136- { label : 'lbs' , value : 'lbs' } ,
137- { label : 'kg' , value : 'kg' } ,
138- ] }
139- style = { pickerSelectStylesSmall }
140- />
141- </ View >
134+ { /* Weight */ }
135+ < Text style = { styles . label } > Weight</ Text >
136+ < View style = { styles . row } >
137+ < TextInput
138+ style = { [ styles . textInput , { flex : 1 , backgroundColor : 'white' } ] }
139+ value = { weight }
140+ onChangeText = { ( text ) => {
141+ const clean = text . replace ( / [ ^ 0 - 9 ] / g, '' ) ;
142+ setWeight ( clean ) ;
143+ } }
144+ keyboardType = "numeric"
145+ placeholder = "Enter weight"
146+ placeholderTextColor = "#888"
147+ />
148+ < RNPickerSelect
149+ onValueChange = { setWeightUnit }
150+ value = { weightUnit }
151+ items = { [
152+ { label : 'lbs' , value : 'lbs' } ,
153+ { label : 'kg' , value : 'kg' } ,
154+ ] }
155+ style = { pickerSelectStylesSmall }
156+ />
157+ </ View >
142158
143- < Text style = { styles . label } > Height</ Text >
144- < View style = { styles . row } >
159+ { /* Height */ }
160+ < Text style = { styles . label } > Height</ Text >
161+ < View style = { styles . row } >
162+ { heightUnit === 'ft/in' ? (
163+ < >
164+ < TextInput
165+ style = { [ styles . textInput , { flex : 1 , backgroundColor : 'white' } ] }
166+ value = { heightFeet }
167+ onChangeText = { ( text ) => {
168+ const clean = text . replace ( / [ ^ 0 - 9 ] / g, '' ) ;
169+ setHeightFeet ( clean ) ;
170+ } }
171+ keyboardType = "numeric"
172+ placeholder = "Feet"
173+ placeholderTextColor = "#888"
174+ />
175+ < TextInput
176+ style = { [ styles . textInput , { flex : 1 , marginLeft : 10 , backgroundColor : 'white' } ] }
177+ value = { heightInches }
178+ onChangeText = { ( text ) => {
179+ const clean = text . replace ( / [ ^ 0 - 9 ] / g, '' ) ;
180+ setHeightInches ( clean ) ;
181+ } }
182+ keyboardType = "numeric"
183+ placeholder = "Inches"
184+ placeholderTextColor = "#888"
185+ />
186+ </ >
187+ ) : (
145188 < TextInput
146- style = { [ styles . textInput , { flex : 1 } ] }
189+ style = { [ styles . textInput , { flex : 1 , backgroundColor : 'white' } ] }
147190 value = { height }
148- onChangeText = { setHeight }
191+ onChangeText = { ( text ) => {
192+ const clean = text . replace ( / [ ^ 0 - 9 ] / g, '' ) ;
193+ setHeight ( clean ) ;
194+ } }
149195 keyboardType = "numeric"
150- placeholder = { `Enter height in ${ heightUnit === 'ft/in' ? 'feet/inches' : 'cm' } ` }
151- />
152- < RNPickerSelect
153- onValueChange = { setHeightUnit }
154- value = { heightUnit }
155- items = { [
156- { label : 'ft/in' , value : 'ft/in' } ,
157- { label : 'cm' , value : 'cm' } ,
158- ] }
159- style = { pickerSelectStylesSmall }
196+ placeholder = "Height in cm"
197+ placeholderTextColor = "#888"
160198 />
161- </ View >
199+ ) }
200+ < RNPickerSelect
201+ onValueChange = { ( val ) => {
202+ setHeightUnit ( val ) ;
203+ // Reset fields on switch
204+ setHeight ( '' ) ;
205+ setHeightFeet ( '' ) ;
206+ setHeightInches ( '' ) ;
207+ } }
208+ value = { heightUnit }
209+ items = { [
210+ { label : 'ft/in' , value : 'ft/in' } ,
211+ { label : 'cm' , value : 'cm' } ,
212+ ] }
213+ style = { pickerSelectStylesSmall }
214+ />
215+ </ View >
216+
162217
218+ { /* Submit */ }
163219 < Button title = "Next" onPress = { handleNext } fullWidth style = { { marginTop : 30 } } />
164220 </ ScrollView >
165221 </ KeyboardAvoidingView >
@@ -172,16 +228,36 @@ const styles = StyleSheet.create({
172228 padding : 24 ,
173229 justifyContent : 'center' ,
174230 } ,
175- title : { fontSize : 24 , fontWeight : 'bold' , marginBottom : 24 , textAlign : 'center' } ,
176- label : { fontSize : 16 , marginBottom : 8 , marginTop : 16 } ,
177- dobRow : { flexDirection : 'row' , alignItems : 'center' } ,
231+ title : {
232+ fontSize : 24 ,
233+ fontWeight : 'bold' ,
234+ marginBottom : 24 ,
235+ textAlign : 'center' ,
236+ } ,
237+ label : {
238+ fontSize : 16 ,
239+ marginBottom : 4 ,
240+ marginTop : 16 ,
241+ color : 'white' ,
242+ } ,
243+ subLabel : {
244+ fontSize : 14 ,
245+ marginBottom : 8 ,
246+ color : '#aaa' ,
247+ } ,
248+ dobRow : {
249+ flexDirection : 'row' ,
250+ alignItems : 'center' ,
251+ } ,
178252 dobInput : {
179253 borderWidth : 1 ,
180254 borderColor : '#ccc' ,
255+ backgroundColor : 'white' ,
181256 padding : 10 ,
182257 borderRadius : 6 ,
183258 fontSize : 16 ,
184259 textAlign : 'center' ,
260+ color : 'black' ,
185261 } ,
186262 dobPart : {
187263 width : 50 ,
@@ -192,6 +268,7 @@ const styles = StyleSheet.create({
192268 slash : {
193269 fontSize : 18 ,
194270 marginHorizontal : 5 ,
271+ color : 'white' ,
195272 } ,
196273 row : {
197274 flexDirection : 'row' ,
@@ -203,6 +280,8 @@ const styles = StyleSheet.create({
203280 borderRadius : 6 ,
204281 padding : 10 ,
205282 fontSize : 16 ,
283+ backgroundColor : 'white' ,
284+ color : 'black' ,
206285 } ,
207286} ) ;
208287
@@ -215,7 +294,8 @@ const pickerSelectStyles = {
215294 borderColor : '#ccc' ,
216295 borderRadius : 6 ,
217296 color : 'black' ,
218- paddingRight : 30 , // to ensure the text is never behind the icon
297+ backgroundColor : 'white' ,
298+ paddingRight : 30 ,
219299 marginBottom : 8 ,
220300 } ,
221301 inputAndroid : {
@@ -226,6 +306,7 @@ const pickerSelectStyles = {
226306 borderColor : '#ccc' ,
227307 borderRadius : 6 ,
228308 color : 'black' ,
309+ backgroundColor : 'white' ,
229310 paddingRight : 30 ,
230311 marginBottom : 8 ,
231312 } ,
@@ -240,6 +321,7 @@ const pickerSelectStylesSmall = {
240321 borderColor : '#ccc' ,
241322 borderRadius : 6 ,
242323 color : 'black' ,
324+ backgroundColor : 'white' ,
243325 paddingRight : 30 ,
244326 marginLeft : 10 ,
245327 minWidth : 80 ,
@@ -252,6 +334,7 @@ const pickerSelectStylesSmall = {
252334 borderColor : '#ccc' ,
253335 borderRadius : 6 ,
254336 color : 'black' ,
337+ backgroundColor : 'white' ,
255338 paddingRight : 30 ,
256339 marginLeft : 10 ,
257340 minWidth : 80 ,
0 commit comments