로그인 화면 UI를 작성하기 이전에 공통으로 사용될 컴포넌트들을 만들어 보도록 하겠습니다.
import React from 'react';
import { Text, TouchableOpacity } from 'react-native';
import styles from './styles/styled.border.button';
const BorderButton = ({
text,
onPress
}) => {
return(
<TouchableOpacity style={ styles.button }
onPress={ onPress }
>
<Text style={ styles.text }>{ text }</Text>
</TouchableOpacity>
);
};
export default BorderButton;
import { StyleSheet } from "react-native";
import palette from "../../../utils/palette";
const styles = StyleSheet.create({
button: {
width: 300,
height: 40,
borderRadius: 30,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: palette.white[0],
borderColor: palette.sky[0],
borderWidth: 2,
margin: 10,
},
text: {
fontSize: 15,
color: palette.sky[0],
}
});
export default styles;
import React from 'react';
import { Text, TouchableOpacity } from 'react-native';
import styles from './styles/styled.full.button';
const FullButton = ({
onPress,
text
}) => {
return(
<TouchableOpacity style={ styles.button }
onPress={ onPress }
>
<Text style={ styles.text }>
{ text }
</Text>
</TouchableOpacity>
);
};
export default FullButton;
import { StyleSheet } from "react-native";
import palette from "../../../utils/palette";
const styles = StyleSheet.create({
button: {
width: 300,
height: 40,
borderRadius: 30,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: palette.sky[0],
margin: 10,
},
text: {
fontSize: 15,
color: palette.white[0],
},
});
export default styles;
import React from 'react';
import { TextInput } from 'react-native';
import styles from './styles/styled.bottomline.input';
const BottomlineInput = ({
inputAccessoryViewID,
placeholder,
placeholderTextColor,
onChange,
value
}) => {
return <TextInput style={ styles.input }
inputAccessoryViewID={ inputAccessoryViewID }
placeholder={ placeholder }
placeholderTextColor={ placeholderTextColor }
onChange={ onChange }
value={ value }
/>;
};
export default BottomlineInput;
import { StyleSheet } from "react-native";
import palette from "../../../utils/palette";
const styles = StyleSheet.create({
input: {
width: 300,
height: 40,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: palette.white[0],
borderBottomColor: palette.sky[0],
borderBottomWidth: 1,
fontSize: 15,
margin: 10,
},
});
export default styles;
앞으로 사용할 공통 버튼, 인풋 컴포넌트를 작성했습니다. 그러면 이 컴포넌트들을 가지고 로그인화면을 작성해보도록 하겠습니다.
위의 화면을 토대로 작성을 진행하겠습니다.
import React from 'react';
import { CommonActions, useNavigation } from '@react-navigation/native';
import { View } from 'react-native';
import palette from '../../../utils/palette';
import FullButton from '../../common/FullButton';
import BorderButton from '../../common/BorderButton';
import BottomlineInput from '../../common/BottomlineInput';
import styles from '../styles/login';
const LoginForm = () => {
const navigation = useNavigation();
const toMainScreen = e => {
navigation.dispatch(CommonActions.reset({
routes: [{ name: 'BottomNavigator' }]
}));
};
const toSignupScreen = e => {
navigation.navigate('SignupScreen');
};
return (
<View style={ styles.login_form }>
<BottomlineInput inputAccessoryViewID="email"
placeholder="E-mail"
placeholderTextColor={ palette.gray[4] }
/>
<BottomlineInput inputAccessoryViewID="password"
placeholder="Password"
placeholderTextColor={ palette.gray[4] }
/>
<FullButton text="Signin"
onPress={ toMainScreen }
/>
<BorderButton text="Signup"
onPress={ toSignupScreen }
/>
</View>
);
};
export default LoginForm;
import React from 'react';
import { View } from 'react-native';
import LoginForm from './components/LoginForm';
import styles from './styles/login';
const LoginScreen = () => {
return(
<View style={ styles.login_screen }>
<LoginForm />
</View>
);
};
export default LoginScreen;
import { StyleSheet } from "react-native";
import palette from "../../../utils/palette";
const styles = StyleSheet.create({
login_screen: {
flex: 1,
backgroundColor: palette.white[0]
},
login_form: {
flex: 1,
justifyContent: 'center',
alignItems: 'center'
}
});
export default styles;
로그인 스큰린를 완성했습니다. 이어서 회원가입 화면을 구현하도록 하겠습니다.
위의 화면을 토대로 회원가입 화면을 작성하기 이전에 회원가입 상단 문구 컴포넌트를 작성하도록 하겠습니다.
import React from 'react';
import { Text, View } from 'react-native';
import styles from '../styles/register';
const NoticeText = ({ text }) => {
return (
<Text style={ styles.normal_font_18 }>
{ text }
</Text>
);
};
export default NoticeText;
문구를 작성했으니 회원가입 폼을 작성하도록 하겠습니다.
import React from 'react';
import { View } from 'react-native';
import BottomlineInput from '../../common/BottomlineInput';
import palette from '../../../utils/palette';
import styles from '../styles/register';
const RegisterForm = () => {
return(
<View style={ styles.register_form }>
<BottomlineInput inputAccessoryViewID="email"
placeholder="E-mail"
placeholderTextColor={ palette.gray[5] }
/>
<BottomlineInput inputAccessoryViewID="password"
placeholder="Password"
placeholderTextColor={ palette.gray[5] }
/>
<BottomlineInput inputAccessoryViewID="passwordConfirm"
placeholder="Re-password"
placeholderTextColor={ palette.gray[5] }
/>
<BottomlineInput inputAccessoryViewID="nickname"
placeholder="Nickname"
placeholderTextColor={ palette.gray[5] }
/>
</View>
);
};
export default RegisterForm;
import React from 'react';
import { View } from 'react-native';
import styles from '../styles/register';
import NoticeText from './NoticeText';
const RegisterHeader = () => {
return (
<View style={ styles.register_header }>
<NoticeText text={ "회원가입을 위한 \n기본정보를 입력해주세요!" }/>
</View>
);
};
export default RegisterHeader;
import { useNavigation } from '@react-navigation/native';
import React from 'react';
import { View } from 'react-native';
import FullButton from '../../common/FullButton';
import styles from '../styles/register';
const RegisterFooter = () => {
const navigation = useNavigation();
const toLicenseScreen = e => {
navigation.navigate('LicenseScreen');
};
return (
<View style={ styles.register_footer }>
<FullButton onPress={ toLicenseScreen }
text="Next"
/>
</View>
)
};
export default RegisterFooter;
Footer에 버튼을 배치한 이유는 추후에 Input state을 관리할 리듀서를 만들어 사용하기 위함입니다.
import React from 'react';
import { View } from 'react-native';
import RegisterFooter from './components/RegisterFooter';
import RegisterForm from './components/RegisterForm';
import RegisterHeader from './components/RegisterHeader';
import styles from './styles/register';
const RegisterScreen = () => {
return(
<View style={ styles.register_screen }>
<RegisterHeader />
<RegisterForm />
<RegisterFooter />
</View>
);
};
export default RegisterScreen;
import { StyleSheet } from "react-native";
import palette from "../../../utils/palette";
const styles = StyleSheet.create({
register_screen: {
flex: 1,
backgroundColor: palette.white[0]
},
register_header: {
flex: 0.2,
paddingLeft: 45,
justifyContent: 'flex-end',
alignItems: 'flex-start',
},
register_form: {
flex: 0.5,
justifyContent: 'center',
alignItems: 'center',
},
register_footer: {
flex: 0.1,
justifyContent: 'center',
alignItems: 'center'
},
});
export default styles;
이 부분까지는 기본 회원 가입에 필요한 내용이고 이 후에 작성될 컴포넌트는 운전자 등록을 할 경우 필요한 컴포넌트입니다.
import React from 'react';
import { View } from 'react-native';
import BottomlineInput from '../../common/BottomlineInput';
import styles from '../styles/register';
import FullButton from '../../common/FullButton';
import NoticeText from './NoticeText';
import { CommonActions, useNavigation } from '@react-navigation/native';
import palette from '../../../utils/palette';
const LicenseForm = () => {
const navigation = useNavigation();
const toSigninScreen = e => {
navigation.dispatch(CommonActions.reset({
routes: [{ name: 'SigninScreen' }]
}));
};
return (
<View style={ styles.license_form }>
<NoticeText text={ "운전자 등록 화면입니다. \n등록을 하시려면 사항들을 기입해주세요. \n미등록의 경우 가입 버튼을 눌러주세요!" } />
<BottomlineInput inputAccessoryViewID="birthDate"
placeholder="Birth Date"
placeholderTextColor={ palette.gray[5] }
/>
<BottomlineInput inputAccessoryViewID="name"
placeholder="Name"
placeholderTextColor={ palette.gray[5] }
/>
<BottomlineInput inputAccessoryViewID="licNumber"
placeholder="License Number"
placeholderTextColor={ palette.gray[5] }
/>
<FullButton text="Signup"
onPress={ toSigninScreen }
/>
</View>
);
};
export default LicenseForm;
import React from 'react';
import { View } from 'react-native';
import styles from '../styles/register';
import NoticeText from './NoticeText';
const LicenseHeader = () => {
return (
<View style={ styles.license_header }>
<NoticeText text={ "운전자 등록 화면입니다. \n등록을 하시려면 사항들을 기입해주세요. \n미등록의 경우 가입 버튼을 눌러주세요!" } />
</View>
);
};
export default LicenseHeader;
import { CommonActions, useNavigation } from '@react-navigation/native';
import React from 'react';
import { View } from 'react-native';
import BorderButton from '../../common/BorderButton';
import FullButton from '../../common/FullButton';
import styles from '../styles/register';
const LicenseFooter = () => {
const navigation = useNavigation();
const onDriverRegister = e => {
navigation.dispatch(CommonActions.reset({
routes: [{ name: 'SigninScreen' }]
}));
};
const onPassengerRegister = e => {
navigation.dispatch(CommonActions.reset({
routes: [{ name: 'SigninScreen' }]
}));
};
return (
<View style={ styles.license_footer }>
<FullButton text="For Driver"
onPress={ onDriverRegister }
/>
<BorderButton text="For Passenger"
onPress={ onPassengerRegister }
/>
</View>
);
};
export default LicenseFooter;
License 스크린도 마찬가지로 회원가입의 state로써 input값들을 관리합니다.
import React from 'react';
import { View } from 'react-native';
import styles from './styles/register';
import LicenseForm from './components/LicenseForm';
import LicenseHeader from './components/LicenseHeader';
import LicenseFooter from './components/LicenseFooter';
const LicenseScreen = () => {
return (
<View style={ styles.license_screen }>
<LicenseHeader />
<LicenseForm />
<LicenseFooter />
</View>
);
};
export default LicenseScreen;
import { StyleSheet } from "react-native";
import palette from "../../../utils/palette";
const styles = StyleSheet.create({
...
license_screen: {
flex: 1,
backgroundColor: palette.white[0]
},
license_header: {
flex: 0.2,
paddingLeft: 45,
justifyContent: 'flex-end',
alignItems: 'flex-start',
},
license_form: {
flex: 0.5,
justifyContent: 'center',
alignItems: 'center',
},
license_footer: {
flex: 0.1,
justifyContent: 'center',
alignItems: 'center'
},
normal_font_18: {
fontSize: 18,
},
});
export default styles;
로그인, 회원가입 관련 페이지를 첫 화면으로 설정하기 위해 MainNavigator에 컴포넌트를 추가하도록 하겠습니다.
import React from 'react';
import { createStackNavigator } from '@react-navigation/stack';
import { NavigationContainer } from '@react-navigation/native';
import BottomNavigator from './BottomNavigator';
import LoginScreen from '../screens/auth/LoginScreen';
import RegisterScreen from '../screens/auth/RegisterScreen';
import LicenseScreen from '../screens/auth/LicenseScreen';
const Stack = createStackNavigator();
const MainNavigator = () => {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="SigninScreen"
component={ LoginScreen }
options={{ headerShown: false }}
/>
<Stack.Screen name="SignupScreen"
component={ RegisterScreen }
/>
<Stack.Screen name="LicenseScreen"
component={ LicenseScreen }
/>
<Stack.Screen name="BottomNavigator"
component={ BottomNavigator }
options={{ headerShown: false }}
/>
</Stack.Navigator>
</NavigationContainer>
);
};
export default MainNavigator;
MainNavigator에 앞서 작성한 스크린들을 추가했으니 테스트를 진행해보도록 하겠습니다.
테스트 결과 화면이 잘 나오는 모습을 볼 수 있습니다. 다음 포스트에서는 백엔드 auth-service를 작성하도록 하겠습니다.