Setup/tones init #4

Merged
mattdimegs merged 10 commits from setup/tones-init into main 2024-08-15 22:04:55 +00:00
7 changed files with 187 additions and 174 deletions
Showing only changes of commit 3bdf905ba7 - Show all commits

View file

@ -1,4 +1,4 @@
import React, { useEffect } from 'react'; import React, { useState, useEffect } from 'react';
import { router, Stack } from 'expo-router'; import { router, Stack } from 'expo-router';
export const unstable_settings = { export const unstable_settings = {
@ -8,10 +8,24 @@ export const unstable_settings = {
export default function App() { export default function App() {
const [auth, setAuth] = useState(false);
useEffect(() => { useEffect(() => {
router.replace('/login'); if (auth) {
router.replace('/explore');
} else {
router.replace('/login');
}
}, []); }, []);
useEffect(() => {
if (auth) {
router.replace('/explore');
} else {
router.replace('/login');
}
}, [auth]);
return ( return (
<Stack <Stack
screenOptions={{ screenOptions={{
@ -20,6 +34,7 @@ export default function App() {
> >
<Stack.Screen name="login" /> <Stack.Screen name="login" />
<Stack.Screen name="register" /> <Stack.Screen name="register" />
<Stack.Screen name="explore" />
</Stack> </Stack>
); );
} }

View file

@ -3,13 +3,13 @@ import Constants from 'expo-constants';
import { View, Text, Image, TextInput, TouchableOpacity } from 'react-native'; import { View, Text, Image, TextInput, TouchableOpacity } from 'react-native';
import { Ionicons } from '@expo/vector-icons'; import { Ionicons } from '@expo/vector-icons';
import { Picker } from '@react-native-picker/picker'; import { Picker } from '@react-native-picker/picker';
import { Children } from 'react';
const StatusBarHeight = Constants.statusBarHeight; const StatusBarHeight = Constants.statusBarHeight;
export const StyledContainer = styled.View` export const StyledContainer = styled.View`
flex: 1; flex: 1;
padding: 25px; padding: 25px;
padding-top: ${StatusBarHeight + 10}px;
`; `;
export const InnerContainer = styled.View` export const InnerContainer = styled.View`
@ -117,6 +117,18 @@ export const TextLinkContent = styled.Text`
font-size: 15px; font-size: 15px;
` `
export const PageHeader = ({
children
}) => {
return (
<View style={{ position: 'sticky', top: 0, backgroundColor: '#ECEDEE', zIndex: 1, marginBottom: -80 }}>
<View style={{ flexDirection: 'row', height: 80, alignItems: 'flex-end' }}>
{children}
</View>
</View>
)
}
export const LoginTextInput = ({ export const LoginTextInput = ({
label, label,
icon, icon,

View file

@ -1,10 +1,12 @@
import React, { useState, useEffect } from 'react'; import React, { useState, useEffect } from 'react';
import { router } from 'expo-router';
import { StatusBar } from 'expo-status-bar'; import { StatusBar } from 'expo-status-bar';
import { useFormik } from 'formik'; import { useFormik } from 'formik';
import { SafeAreaView } from 'react-native-safe-area-context'; import { SafeAreaView } from 'react-native-safe-area-context';
import { Tabs, Link } from 'expo-router'; import { Tabs, Link } from 'expo-router';
import { useColorScheme } from '@/hooks/useColorScheme'; import { useColorScheme } from '@/hooks/useColorScheme';
import { import {
PageHeader,
StyledContainer, StyledContainer,
InnerContainer, InnerContainer,
StyledFormArea, StyledFormArea,
@ -23,6 +25,8 @@ import {
export default function TabLayout() { export default function TabLayout() {
const colorScheme = useColorScheme(); const colorScheme = useColorScheme();
const [hidePassword, setHidePassword] = useState(true);
const [loginButtonDisabled, setLoginButtonDisabled] = useState(true);
const formik = useFormik({ const formik = useFormik({
initialValues: { initialValues: {
@ -37,10 +41,6 @@ export default function TabLayout() {
const formValues = formik.values; const formValues = formik.values;
const [login, setLogin] = useState(false);
const [hidePassword, setHidePassword] = useState(true);
const [loginButtonDisabled, setLoginButtonDisabled] = useState(true);
useEffect(() => { useEffect(() => {
if (formValues) { if (formValues) {
if (formValues.number.length === 14 && formValues.password) { if (formValues.number.length === 14 && formValues.password) {
@ -53,78 +53,53 @@ export default function TabLayout() {
return ( return (
<React.Fragment> <React.Fragment>
{login ? ( <PageHeader />
<Tabs <StyledContainer>
screenOptions={{ <StatusBar style="dark" />
tabBarActiveTintColor: Colors[colorScheme ?? 'light'].tint <SafeAreaView />
}}> <InnerContainer>
<Tabs.Screen <PageImage resizeMode="cover" source={require('./../assets/images/tones-logo.png')} />
name="index" <Title>Tones</Title>
options={{ <SubTitle>Account Login</SubTitle>
title: 'Home', <StyledFormArea>
tabBarIcon: ({ color, focused }) => ( <LoginTextInput
<TabBarIcon name={focused ? 'home' : 'home-outline'} color={color} /> label="Phone Number"
), icon="call-outline"
}} placeholder="123-456-7890"
/> placeholderTextColor="gray"
<Tabs.Screen onChangeText={formik.handleChange('number')}
name="explore" onBlur={formik.handleBlur('number')}
options={{ value={formik.values.number.replace(/^(\d{3})(\d{3})(\d+)$/, "($1) $2-$3")}
title: 'Explore', keyboardType="number-pad"
tabBarIcon: ({ color, focused }) => ( maxLength={14}
<TabBarIcon name={focused ? 'code-slash' : 'code-slash-outline'} color={color} /> />
), <LoginTextInput
}} label="Password"
/> icon="lock-closed-outline"
</Tabs> placeholder="* * * * * *"
) : ( placeholderTextColor="gray"
<StyledContainer> onChangeText={formik.handleChange('password')}
<StatusBar style="dark" /> onBlur={formik.handleBlur('password')}
<SafeAreaView /> value={formik.values.password}
<InnerContainer> secureTextEntry={hidePassword}
<PageImage resizeMode="cover" source={require('./../assets/images/tones-logo.png')} /> isPassword
<Title>Tones</Title> hidePassword={hidePassword}
<SubTitle>Account Login</SubTitle> setHidePassword={setHidePassword}
<StyledFormArea> />
<LoginTextInput <MessageBox>...</MessageBox>
label="Phone Number" <StyledButton onPress={formik.handleSubmit} disabled={loginButtonDisabled} style={loginButtonDisabled ? {backgroundColor: 'grey'} : {}}>
icon="call-outline" <ButtonText>Login</ButtonText>
placeholder="123-456-7890" </StyledButton>
placeholderTextColor="gray" <Line />
onChangeText={formik.handleChange('number')} <ExtraView>
onBlur={formik.handleBlur('number')} <ExtraText>Don't have an account already? </ExtraText>
value={formik.values.number.replace(/^(\d{3})(\d{3})(\d+)$/, "($1) $2-$3")} <Link href='./register'>
keyboardType="number-pad" <TextLinkContent>Register</TextLinkContent>
maxLength={14} </Link>
/> </ExtraView>
<LoginTextInput </StyledFormArea>
label="Password" </InnerContainer>
icon="lock-closed-outline" </StyledContainer>
placeholder="* * * * * *"
placeholderTextColor="gray"
onChangeText={formik.handleChange('password')}
onBlur={formik.handleBlur('password')}
value={formik.values.password}
secureTextEntry={hidePassword}
isPassword
hidePassword={hidePassword}
setHidePassword={setHidePassword}
/>
<MessageBox>...</MessageBox>
<StyledButton onPress={formik.handleSubmit} disabled={loginButtonDisabled} style={loginButtonDisabled ? {backgroundColor: 'grey'} : {}}>
<ButtonText>Login</ButtonText>
</StyledButton>
<Line />
<ExtraView>
<ExtraText>Don't have an account already? </ExtraText>
<Link href='./register'>
<TextLinkContent>Register</TextLinkContent>
</Link>
</ExtraView>
</StyledFormArea>
</InnerContainer>
</StyledContainer>
)}
</React.Fragment> </React.Fragment>
); );
} }

View file

@ -1,9 +1,12 @@
import React, { useState, useEffect } from 'react'; import React, { useState, useEffect } from 'react';
import { ScrollView } from 'react-native'; import { router } from 'expo-router';
import { View, ScrollView, Text, TouchableOpacity } from 'react-native';
import { StatusBar } from 'expo-status-bar'; import { StatusBar } from 'expo-status-bar';
import { useFormik, Formik } from 'formik'; import { useFormik } from 'formik';
import { SafeAreaView } from 'react-native-safe-area-context'; import { SafeAreaView } from 'react-native-safe-area-context';
import { Ionicons } from '@expo/vector-icons';
import { import {
PageHeader,
StyledContainer, StyledContainer,
InnerContainer, InnerContainer,
StyledFormArea, StyledFormArea,
@ -64,93 +67,101 @@ export default function Register() {
}, [formValues]) }, [formValues])
return ( return (
<ScrollView> <View>
<StyledContainer> <PageHeader>
<StatusBar style="dark" /> <TouchableOpacity onPress={router.back} style={{ flexDirection: 'row', alignItems: 'center' }}>
<SafeAreaView /> <Ionicons name="arrow-back-outline" size={30} color="red" style={{ paddingLeft: 20 }} />
<InnerContainer> <Text style={{ color: 'red', fontWeight: 600 }}>Back to Login</Text>
<PageImage resizeMode="cover" source={require('./../assets/images/tones-logo.png')} /> </TouchableOpacity>
<Title>Tones</Title> </PageHeader>
<SubTitle>Account Register</SubTitle> <ScrollView>
<StyledFormArea> <StyledContainer>
<LoginTextInput <StatusBar style="dark" />
label="First Name" <SafeAreaView />
icon="person-outline" <InnerContainer>
placeholder="Bud" <PageImage resizeMode="cover" source={require('./../assets/images/tones-logo.png')} />
placeholderTextColor="gray" <Title>Tones</Title>
onChangeText={formik.handleChange('firstName')} <SubTitle>Account Register</SubTitle>
onBlur={formik.handleBlur('firstName')} <StyledFormArea>
value={formik.values.firstName} <LoginTextInput
/> label="First Name"
<LoginTextInput icon="person-outline"
label="Last Name" placeholder="Bud"
icon="people-outline" placeholderTextColor="gray"
placeholder="Doble" onChangeText={formik.handleChange('firstName')}
placeholderTextColor="gray" onBlur={formik.handleBlur('firstName')}
onChangeText={formik.handleChange('lastName')} value={formik.values.firstName}
onBlur={formik.handleBlur('lastName')} />
value={formik.values.lastName} <LoginTextInput
/> label="Last Name"
<LoginTextInput icon="people-outline"
label="Phone Number" placeholder="Doble"
icon="call-outline" placeholderTextColor="gray"
placeholder="123-456-7890" onChangeText={formik.handleChange('lastName')}
placeholderTextColor="gray" onBlur={formik.handleBlur('lastName')}
onChangeText={formik.handleChange('number')} value={formik.values.lastName}
onBlur={formik.handleBlur('number')} />
value={formik.values.number.replace(/^(\d{3})(\d{3})(\d+)$/, "($1) $2-$3")} <LoginTextInput
keyboardType="number-pad" label="Phone Number"
maxLength={14} icon="call-outline"
/> placeholder="123-456-7890"
<LoginDropdownInput placeholderTextColor="gray"
label="Cellular Provider" onChangeText={formik.handleChange('number')}
selectedValue={formik.values.provider} onBlur={formik.handleBlur('number')}
onValueChange={formik.handleChange('provider')} value={formik.values.number.replace(/^(\d{3})(\d{3})(\d+)$/, "($1) $2-$3")}
items={providers} keyboardType="number-pad"
/> maxLength={14}
<LoginTextInput />
label="Email Address" <LoginDropdownInput
icon="mail-outline" label="Cellular Provider"
placeholder="test@organization.com" selectedValue={formik.values.provider}
placeholderTextColor="gray" onValueChange={formik.handleChange('provider')}
onChangeText={formik.handleChange('email')} items={providers}
onBlur={formik.handleBlur('email')} />
value={formik.values.email} <LoginTextInput
keyboardType="email-address" label="Email Address"
/> icon="mail-outline"
<LoginTextInput placeholder="test@organization.com"
label="Password" placeholderTextColor="gray"
icon="lock-closed-outline" onChangeText={formik.handleChange('email')}
placeholder="* * * * * *" onBlur={formik.handleBlur('email')}
placeholderTextColor="gray" value={formik.values.email}
onChangeText={formik.handleChange('password')} keyboardType="email-address"
onBlur={formik.handleBlur('password')} />
value={formik.values.password} <LoginTextInput
secureTextEntry={hidePassword} label="Password"
isPassword icon="lock-closed-outline"
hidePassword={hidePassword} placeholder="* * * * * *"
setHidePassword={setHidePassword} placeholderTextColor="gray"
/> onChangeText={formik.handleChange('password')}
<LoginTextInput onBlur={formik.handleBlur('password')}
label="Confirm Password" value={formik.values.password}
icon="shield-checkmark-outline" secureTextEntry={hidePassword}
placeholder="* * * * * *" isPassword
placeholderTextColor="gray" hidePassword={hidePassword}
onChangeText={formik.handleChange('passwordConfirmation')} setHidePassword={setHidePassword}
onBlur={formik.handleBlur('passwordConfirmation')} />
value={formik.values.passwordConfirmation} <LoginTextInput
secureTextEntry={hidePassword} label="Confirm Password"
isPassword icon="shield-checkmark-outline"
hidePassword={hidePassword} placeholder="* * * * * *"
setHidePassword={setHidePassword} placeholderTextColor="gray"
/> onChangeText={formik.handleChange('passwordConfirmation')}
<MessageBox>...</MessageBox> onBlur={formik.handleBlur('passwordConfirmation')}
<StyledButton onPress={formik.handleSubmit} style={registerButtonDisabled ? {backgroundColor: 'grey'} : {}}> value={formik.values.passwordConfirmation}
<ButtonText>Register</ButtonText> secureTextEntry={hidePassword}
</StyledButton> isPassword
</StyledFormArea> hidePassword={hidePassword}
</InnerContainer> setHidePassword={setHidePassword}
</StyledContainer> />
</ScrollView> <MessageBox>...</MessageBox>
<StyledButton onPress={formik.handleSubmit} style={registerButtonDisabled ? {backgroundColor: 'grey'} : {}}>
<ButtonText>Register</ButtonText>
</StyledButton>
</StyledFormArea>
</InnerContainer>
</StyledContainer>
</ScrollView>
</View>
) )
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 231 KiB

8
package-lock.json generated
View file

@ -9,7 +9,7 @@
"version": "1.0.1", "version": "1.0.1",
"dependencies": { "dependencies": {
"@expo/vector-icons": "^14.0.2", "@expo/vector-icons": "^14.0.2",
"@react-native-picker/picker": "^2.7.7", "@react-native-picker/picker": "2.7.5",
"@react-navigation/native": "^6.0.2", "@react-navigation/native": "^6.0.2",
"expo": "~51.0.24", "expo": "~51.0.24",
"expo-constants": "~16.0.2", "expo-constants": "~16.0.2",
@ -5866,9 +5866,9 @@
} }
}, },
"node_modules/@react-native-picker/picker": { "node_modules/@react-native-picker/picker": {
"version": "2.7.7", "version": "2.7.5",
"resolved": "https://registry.npmjs.org/@react-native-picker/picker/-/picker-2.7.7.tgz", "resolved": "https://registry.npmjs.org/@react-native-picker/picker/-/picker-2.7.5.tgz",
"integrity": "sha512-CTHthVmx8ujlH/u5AnxLQfsheh/DoEbo+Kbx0HGTlbKVLC1eZ4Kr9jXIIUcwB7JEgOXifdZIPQCsoTc/7GQ0ag==", "integrity": "sha512-vhMaOLkXSUb+YKVbukMJToU4g+89VMhBG2U9+cLYF8X8HtFRidrHjohGqT8/OyesDuKIXeLIP+UFYI9Q9CRA9Q==",
"peerDependencies": { "peerDependencies": {
"react": "*", "react": "*",
"react-native": "*" "react-native": "*"

View file

@ -16,7 +16,7 @@
}, },
"dependencies": { "dependencies": {
"@expo/vector-icons": "^14.0.2", "@expo/vector-icons": "^14.0.2",
"@react-native-picker/picker": "^2.7.7", "@react-native-picker/picker": "2.7.5",
"@react-navigation/native": "^6.0.2", "@react-navigation/native": "^6.0.2",
"expo": "~51.0.24", "expo": "~51.0.24",
"expo-constants": "~16.0.2", "expo-constants": "~16.0.2",