SignUp and login
parent
7d3f457f0b
commit
1c232e86b7
Binary file not shown.
After Width: | Height: | Size: 12 KiB |
Binary file not shown.
After Width: | Height: | Size: 17 KiB |
Binary file not shown.
Before Width: | Height: | Size: 413 KiB After Width: | Height: | Size: 227 KiB |
|
@ -0,0 +1,92 @@
|
|||
import {View} from 'react-native';
|
||||
import {
|
||||
Image,
|
||||
ImageSourcePropType,
|
||||
ImageStyle,
|
||||
StyleProp,
|
||||
Text,
|
||||
TouchableOpacity,
|
||||
ViewStyle,
|
||||
} from 'react-native';
|
||||
import LinearGradient from 'react-native-linear-gradient';
|
||||
|
||||
interface MyIconButtonProps {
|
||||
image: ImageSourcePropType;
|
||||
imageStyle?: StyleProp<ImageStyle>;
|
||||
text: string;
|
||||
}
|
||||
|
||||
export function MyIconButton({image, imageStyle, text}: MyIconButtonProps) {
|
||||
return (
|
||||
<TouchableOpacity
|
||||
style={{
|
||||
backgroundColor: '#26263f',
|
||||
alignItems: 'center',
|
||||
padding: 10,
|
||||
flexDirection: 'row',
|
||||
borderRadius: 10,
|
||||
}}>
|
||||
<Image source={image} style={imageStyle} />
|
||||
<Text
|
||||
style={{
|
||||
flex: 1,
|
||||
textAlign: 'center',
|
||||
color: '#fff',
|
||||
fontSize: 18,
|
||||
fontWeight: 'bold',
|
||||
}}>
|
||||
{text}
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
);
|
||||
}
|
||||
|
||||
interface MyButtonProps {
|
||||
style?: StyleProp<ViewStyle>;
|
||||
type: 'primary' | 'secondary';
|
||||
text: string;
|
||||
onPress?: () => void;
|
||||
}
|
||||
|
||||
export function MyButton({style, type, text, onPress}: MyButtonProps) {
|
||||
const ButtonText = () => (
|
||||
<Text style={{color: '#fff', fontSize: 18, fontWeight: 'bold'}}>
|
||||
{text}
|
||||
</Text>
|
||||
);
|
||||
|
||||
return (
|
||||
<TouchableOpacity
|
||||
style={[
|
||||
style,
|
||||
{
|
||||
borderRadius: 10,
|
||||
},
|
||||
]}
|
||||
onPress={onPress}>
|
||||
{type === 'primary' ? (
|
||||
<LinearGradient
|
||||
colors={['#931278', '#6030da']}
|
||||
start={{x: 0, y: 1}}
|
||||
end={{x: 1, y: 0}}
|
||||
style={{
|
||||
alignItems: 'center',
|
||||
padding: 10,
|
||||
borderRadius: 10,
|
||||
}}>
|
||||
<ButtonText />
|
||||
</LinearGradient>
|
||||
) : (
|
||||
<View
|
||||
style={{
|
||||
backgroundColor: '#37375c',
|
||||
alignItems: 'center',
|
||||
padding: 10,
|
||||
borderRadius: 10,
|
||||
}}>
|
||||
<ButtonText />
|
||||
</View>
|
||||
)}
|
||||
</TouchableOpacity>
|
||||
);
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
import {StyleProp, Text, TextStyle} from 'react-native';
|
||||
import {TouchableOpacity} from 'react-native';
|
||||
|
||||
interface MyClickableTextProps {
|
||||
textStyle?: StyleProp<TextStyle>;
|
||||
text: string;
|
||||
onPress?: () => void;
|
||||
}
|
||||
|
||||
export function MyClickableText({textStyle, text, onPress}: MyClickableTextProps) {
|
||||
return (
|
||||
<TouchableOpacity onPress={onPress}>
|
||||
<Text style={textStyle}>{text}</Text>
|
||||
</TouchableOpacity>
|
||||
);
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
import {Text, View} from 'react-native';
|
||||
|
||||
export function MyDivider() {
|
||||
return <View style={{flex: 1, height: 1, backgroundColor: '#3b3b60'}} />;
|
||||
}
|
||||
|
||||
interface MyDividerWithTextProps {
|
||||
text?: string;
|
||||
}
|
||||
|
||||
export function MyDividerWithText({text}: MyDividerWithTextProps) {
|
||||
return (
|
||||
<View style={{flexDirection: 'row', alignItems: 'center'}}>
|
||||
<MyDivider />
|
||||
<Text style={{color: '#909090', marginHorizontal: 10}}>{text}</Text>
|
||||
<MyDivider />
|
||||
</View>
|
||||
);
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
import {ColorValue} from 'react-native';
|
||||
import MaterialIcon from 'react-native-vector-icons/MaterialIcons';
|
||||
|
||||
interface MyIconProps {
|
||||
name: string;
|
||||
size?: number | undefined;
|
||||
color?: number | ColorValue | undefined
|
||||
}
|
||||
|
||||
export function MyIcon({name, size, color}: MyIconProps) {
|
||||
return <MaterialIcon name={name} size={size} color={color} />;
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
import {KeyboardTypeOptions, Text, TextInput, View} from 'react-native';
|
||||
import {MyIcon} from './MyIcon';
|
||||
|
||||
interface MyIconInputProps {
|
||||
text: string;
|
||||
iconName: string;
|
||||
keyboardType?: KeyboardTypeOptions;
|
||||
secureTextEntry?: boolean | undefined;
|
||||
}
|
||||
|
||||
export function MyIconInput({text, iconName, keyboardType, secureTextEntry}: MyIconInputProps) {
|
||||
return (
|
||||
<View
|
||||
style={{
|
||||
backgroundColor: '#26263f',
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
borderRadius: 10,
|
||||
}}>
|
||||
<View style={{marginLeft: 12}}>
|
||||
<MyIcon name={iconName} size={32} />
|
||||
</View>
|
||||
|
||||
<View style={{flex: 1, margin: 12, gap: 2}}>
|
||||
<Text>{text}</Text>
|
||||
<TextInput
|
||||
style={{
|
||||
backgroundColor: '#212137',
|
||||
height: 40,
|
||||
borderRadius: 10,
|
||||
paddingLeft: 10,
|
||||
}}
|
||||
keyboardType={keyboardType}
|
||||
secureTextEntry={secureTextEntry}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
import {ReactNode} from 'react';
|
||||
import {StyleProp, View, ViewStyle} from 'react-native';
|
||||
|
||||
interface MyScreenContainerProps {
|
||||
children: ReactNode;
|
||||
style?: StyleProp<ViewStyle>;
|
||||
}
|
||||
|
||||
export function MyScreenContainer({children, style}: MyScreenContainerProps) {
|
||||
return (
|
||||
<View style={[style, {paddingLeft: 20, paddingRight: 20}]}>{children}</View>
|
||||
);
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
import {Linking} from 'react-native';
|
||||
|
||||
export function OpenURL(url: string) {
|
||||
const supported = Linking.canOpenURL(url);
|
||||
|
||||
if (!supported) {
|
||||
console.log("Can't handle url: " + url);
|
||||
} else {
|
||||
return Linking.openURL(url);
|
||||
}
|
||||
}
|
|
@ -4,8 +4,6 @@ import {
|
|||
BottomTabBarProps,
|
||||
createBottomTabNavigator,
|
||||
} from '@react-navigation/bottom-tabs';
|
||||
|
||||
import MaterialIcon from 'react-native-vector-icons/MaterialIcons';
|
||||
import CalendarTab from './tabs/main/CalendarTab';
|
||||
import ChatsTab from './tabs/main/ChatsTab';
|
||||
import MapTab from './tabs/main/MapTab';
|
||||
|
@ -15,20 +13,30 @@ import ProfileTab, {
|
|||
import {FadeInView, SlideFromLeftView} from '@helper/animations';
|
||||
import {Text, TouchableOpacity, View} from 'react-native';
|
||||
import LinearGradient from 'react-native-linear-gradient';
|
||||
import {
|
||||
RegistrationScreenAnim,
|
||||
RegistrationStackNavigatorParamList,
|
||||
} from './registration/registration';
|
||||
import {NativeStackNavigationProp} from '@react-navigation/native-stack';
|
||||
import { MyIcon } from '@components/MyIcon';
|
||||
|
||||
export type RootStackNavigatorParamList = {
|
||||
Home: NavigatorScreenParams<HomeStackNavigatorParamList>;
|
||||
//Register: NavigatorScreenParams<LoginStackNavigatorParamList>;
|
||||
Registration: NavigatorScreenParams<RegistrationStackNavigatorParamList>;
|
||||
};
|
||||
|
||||
export type RootScreenNavigationProp =
|
||||
NativeStackNavigationProp<RootStackNavigatorParamList>;
|
||||
|
||||
export default function Navigation() {
|
||||
return (
|
||||
<Stack.Navigator
|
||||
screenOptions={{
|
||||
headerShown: false,
|
||||
}}>
|
||||
}}
|
||||
initialRouteName="Registration">
|
||||
<Stack.Screen name="Home" component={HomeStack} />
|
||||
<Stack.Screen name="Register" component={RegisterStack} />
|
||||
<Stack.Screen name="Registration" component={RegistrationScreenAnim} />
|
||||
</Stack.Navigator>
|
||||
);
|
||||
}
|
||||
|
@ -143,11 +151,9 @@ function CustomTabBar(props: BottomTabBarProps) {
|
|||
width: '100%',
|
||||
alignItems: 'center',
|
||||
}}>
|
||||
<MaterialIcon
|
||||
name={tabBarIcons[index]}
|
||||
<MyIcon name={tabBarIcons[index]}
|
||||
color={isFocused ? '#fff' : '#ccc'}
|
||||
size={20}
|
||||
/>
|
||||
size={20} />
|
||||
{isFocused && (
|
||||
<Text style={{color: '#fff'}}>{label.toString()}</Text>
|
||||
)}
|
||||
|
@ -159,6 +165,8 @@ function CustomTabBar(props: BottomTabBarProps) {
|
|||
);
|
||||
}
|
||||
|
||||
const Tab = createBottomTabNavigator<HomeStackNavigatorParamList>();
|
||||
|
||||
function HomeStack() {
|
||||
return (
|
||||
<Tab.Navigator
|
||||
|
@ -171,9 +179,3 @@ function HomeStack() {
|
|||
</Tab.Navigator>
|
||||
);
|
||||
}
|
||||
|
||||
function RegisterStack() {
|
||||
return <></>;
|
||||
}
|
||||
|
||||
const Tab = createBottomTabNavigator<HomeStackNavigatorParamList>();
|
||||
|
|
|
@ -0,0 +1,518 @@
|
|||
import {MyScreenContainer} from '@components/MyScreenContainer';
|
||||
import {SlideFromLeftView} from '@helper/animations';
|
||||
import {RootScreenNavigationProp} from '@navigation/navigation';
|
||||
import {useNavigation} from '@react-navigation/native';
|
||||
import {
|
||||
createNativeStackNavigator,
|
||||
NativeStackNavigationOptions,
|
||||
} from '@react-navigation/native-stack';
|
||||
import {Image, StyleSheet, Text, TextInput, View} from 'react-native';
|
||||
|
||||
import GoogleLogo from '@assets/google-logo.png';
|
||||
import AppleLogo from '@assets/apple-logo.png';
|
||||
import Logo from '@assets/logo.png';
|
||||
|
||||
import {MyDividerWithText} from '@components/MyDivider';
|
||||
import {MyButton, MyIconButton} from '@components/MyButton';
|
||||
import {MyClickableText} from '@components/MyClickableText';
|
||||
import {OpenURL} from '@helper/linking';
|
||||
import {Constants} from '@utils/utils';
|
||||
import {MyIconInput} from '@components/MyInput';
|
||||
import {useRef, useState} from 'react';
|
||||
import {KeyboardAvoidingView} from 'react-native';
|
||||
|
||||
export type RegistrationStackNavigatorParamList = {
|
||||
SignUpPreview: undefined;
|
||||
SignUpStepUsername: undefined;
|
||||
SignUpStepPhoneNumber: undefined;
|
||||
SignUpStepVerifyPhoneNumber: undefined;
|
||||
SignUpStepPassword: undefined;
|
||||
SignUpStepAccountName: undefined;
|
||||
LoginPreview: undefined;
|
||||
Login: undefined;
|
||||
};
|
||||
|
||||
const RegistrationStack =
|
||||
createNativeStackNavigator<RegistrationStackNavigatorParamList>();
|
||||
|
||||
export function RegistrationScreenAnim(props: any) {
|
||||
return (
|
||||
<SlideFromLeftView>
|
||||
<RegistrationScreen {...props} />
|
||||
</SlideFromLeftView>
|
||||
);
|
||||
}
|
||||
|
||||
const headerStyle: NativeStackNavigationOptions = {
|
||||
headerShown: true,
|
||||
headerStyle: {backgroundColor: '#212137'},
|
||||
headerTitleAlign: 'center',
|
||||
headerTitle: '',
|
||||
};
|
||||
|
||||
export function RegistrationScreen() {
|
||||
return (
|
||||
<RegistrationStack.Navigator screenOptions={{headerShown: false}}>
|
||||
<RegistrationStack.Screen
|
||||
name="SignUpPreview"
|
||||
component={SignUpPreview}
|
||||
/>
|
||||
<RegistrationStack.Screen name="LoginPreview" component={LoginPreview} />
|
||||
<RegistrationStack.Screen
|
||||
name="Login"
|
||||
component={Login}
|
||||
options={{
|
||||
headerShown: true,
|
||||
headerStyle: {backgroundColor: '#212137'},
|
||||
headerTitleAlign: 'center',
|
||||
}}
|
||||
/>
|
||||
<RegistrationStack.Screen
|
||||
name="SignUpStepUsername"
|
||||
component={SignUpStepUsername}
|
||||
options={{...headerStyle}}
|
||||
/>
|
||||
<RegistrationStack.Screen
|
||||
name="SignUpStepPhoneNumber"
|
||||
component={SignUpStepPhoneNumber}
|
||||
options={{...headerStyle}}
|
||||
/>
|
||||
<RegistrationStack.Screen
|
||||
name="SignUpStepVerifyPhoneNumber"
|
||||
component={SignUpStepVerifyPhoneNumber}
|
||||
options={{...headerStyle}}
|
||||
/>
|
||||
<RegistrationStack.Screen
|
||||
name="SignUpStepPassword"
|
||||
component={SignUpStepPassword}
|
||||
options={{...headerStyle}}
|
||||
/>
|
||||
<RegistrationStack.Screen
|
||||
name="SignUpStepAccountName"
|
||||
component={SignUpStepAccountName}
|
||||
options={{...headerStyle}}
|
||||
/>
|
||||
</RegistrationStack.Navigator>
|
||||
);
|
||||
}
|
||||
|
||||
function SignUpPreview() {
|
||||
return <RegistrationPreview type="signup" />;
|
||||
}
|
||||
|
||||
function LoginPreview() {
|
||||
return <RegistrationPreview type="login" />;
|
||||
}
|
||||
|
||||
function ThirdAuthButtons() {
|
||||
return (
|
||||
<>
|
||||
<MyIconButton
|
||||
image={GoogleLogo}
|
||||
imageStyle={{left: 2, height: 35, width: 35}}
|
||||
text="Continue with Google"
|
||||
/>
|
||||
|
||||
<MyIconButton
|
||||
image={AppleLogo}
|
||||
imageStyle={{height: 40, width: 40}}
|
||||
text="Continue with Apple"
|
||||
/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
function RegistrationPreview({type}: {type: 'login' | 'signup'}) {
|
||||
const navigation = useNavigation<RootScreenNavigationProp>();
|
||||
|
||||
return (
|
||||
<MyScreenContainer
|
||||
style={{
|
||||
flex: 1,
|
||||
flexDirection: 'column',
|
||||
backgroundColor: '#212137',
|
||||
}}>
|
||||
<View style={{flex: 1, marginTop: 10, alignItems: 'center'}}>
|
||||
<Image source={Logo} style={{height: 60, width: 60}} />
|
||||
</View>
|
||||
|
||||
<View style={{flex: 2, justifyContent: 'center'}}>
|
||||
<Text
|
||||
style={{
|
||||
fontSize: 24,
|
||||
fontWeight: 'bold',
|
||||
textAlign: 'center',
|
||||
color: '#fff',
|
||||
padding: 20,
|
||||
}}>
|
||||
{type === 'login'
|
||||
? 'Time to get to know the next party'
|
||||
: 'Find the next party near you'}
|
||||
</Text>
|
||||
</View>
|
||||
|
||||
<View
|
||||
style={{
|
||||
gap: 10,
|
||||
flex: 3,
|
||||
justifyContent: 'flex-end',
|
||||
marginBottom: 20,
|
||||
}}>
|
||||
<ThirdAuthButtons />
|
||||
|
||||
<MyDividerWithText text="or" />
|
||||
|
||||
<MyButton
|
||||
type="secondary"
|
||||
text={type === 'login' ? 'Login' : 'Create account'}
|
||||
style={{marginBottom: 20}}
|
||||
onPress={() => {
|
||||
navigation.navigate(
|
||||
'Registration',
|
||||
type === 'login'
|
||||
? {screen: 'Login'}
|
||||
: {screen: 'SignUpStepUsername'},
|
||||
);
|
||||
}}
|
||||
/>
|
||||
|
||||
{type === 'login' && (
|
||||
<View style={{flexDirection: 'row', flexWrap: 'wrap'}}>
|
||||
<Text>By signing up, you agree to our </Text>
|
||||
<MyClickableText
|
||||
text="Terms"
|
||||
textStyle={{color: '#6030da'}}
|
||||
onPress={() => OpenURL(Constants.REGISTRATION.TERMS_URL)}
|
||||
/>
|
||||
<Text>, </Text>
|
||||
<MyClickableText
|
||||
text="Privacy Policy"
|
||||
textStyle={{color: '#6030da'}}
|
||||
onPress={() => OpenURL(Constants.REGISTRATION.PRIVACY_POLICY_URL)}
|
||||
/>
|
||||
<Text> and </Text>
|
||||
<MyClickableText
|
||||
text="Cookie Use"
|
||||
textStyle={{color: '#6030da'}}
|
||||
onPress={() => OpenURL(Constants.REGISTRATION.COOKIE_USE_URL)}
|
||||
/>
|
||||
<Text>.</Text>
|
||||
</View>
|
||||
)}
|
||||
|
||||
<View style={{flexDirection: 'row'}}>
|
||||
{type === 'login' ? (
|
||||
<Text>Don't have an account?</Text>
|
||||
) : (
|
||||
<Text>Have already an account?</Text>
|
||||
)}
|
||||
|
||||
<MyClickableText
|
||||
text={type === 'login' ? 'Sign up' : 'Login'}
|
||||
textStyle={{left: 2, color: '#931278', fontWeight: 'bold'}}
|
||||
onPress={() => {
|
||||
navigation.navigate(
|
||||
'Registration',
|
||||
type === 'login'
|
||||
? {screen: 'SignUpPreview'}
|
||||
: {screen: 'LoginPreview'},
|
||||
);
|
||||
}}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
</MyScreenContainer>
|
||||
);
|
||||
}
|
||||
|
||||
function ContentContainer({children}: {children: React.ReactNode}) {
|
||||
return (
|
||||
<>
|
||||
<View style={{flex: 1}} />
|
||||
<View style={{flex: 8}}>{children}</View>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
function Title({text}: {text: string}) {
|
||||
return (
|
||||
<Text
|
||||
style={{
|
||||
fontSize: 24,
|
||||
fontWeight: 'bold',
|
||||
textAlign: 'center',
|
||||
color: '#fff',
|
||||
padding: 20,
|
||||
}}>
|
||||
{text}
|
||||
</Text>
|
||||
);
|
||||
}
|
||||
|
||||
function Login() {
|
||||
const navigation = useNavigation<RootScreenNavigationProp>();
|
||||
|
||||
return (
|
||||
<MyScreenContainer
|
||||
style={{
|
||||
flex: 1,
|
||||
flexDirection: 'column',
|
||||
backgroundColor: '#212137',
|
||||
}}>
|
||||
<ContentContainer>
|
||||
<Title text="Welcome back!" />
|
||||
|
||||
<View style={{gap: 12}}>
|
||||
<MyIconInput text="PHONE NUMBER OR ACCOUNT NAME" iconName="person" />
|
||||
<MyIconInput text="PASSWORD" iconName="lock" secureTextEntry />
|
||||
|
||||
<MyButton
|
||||
type="secondary"
|
||||
text={'Login'}
|
||||
style={{marginBottom: 20}}
|
||||
onPress={() => {
|
||||
navigation.navigate('Home');
|
||||
}}
|
||||
/>
|
||||
</View>
|
||||
</ContentContainer>
|
||||
</MyScreenContainer>
|
||||
);
|
||||
}
|
||||
|
||||
function SignUpStepUsername() {
|
||||
const navigation = useNavigation<RootScreenNavigationProp>();
|
||||
|
||||
return (
|
||||
<MyScreenContainer
|
||||
style={{
|
||||
flex: 1,
|
||||
flexDirection: 'column',
|
||||
backgroundColor: '#212137',
|
||||
}}>
|
||||
<ContentContainer>
|
||||
<Title text="Let's get started, what's your name?" />
|
||||
<Text>The name will be displayed on your profil overview</Text>
|
||||
|
||||
<View style={{gap: 12, marginTop: 20}}>
|
||||
<MyIconInput text="Username" iconName="person" />
|
||||
|
||||
<MyButton
|
||||
type="secondary"
|
||||
text={'Next'}
|
||||
style={{marginBottom: 20}}
|
||||
onPress={() => {
|
||||
navigation.navigate('Registration', {
|
||||
screen: 'SignUpStepPhoneNumber',
|
||||
});
|
||||
}}
|
||||
/>
|
||||
</View>
|
||||
</ContentContainer>
|
||||
</MyScreenContainer>
|
||||
);
|
||||
}
|
||||
|
||||
function SignUpStepPhoneNumber() {
|
||||
const navigation = useNavigation<RootScreenNavigationProp>();
|
||||
|
||||
return (
|
||||
<MyScreenContainer
|
||||
style={{
|
||||
flex: 1,
|
||||
flexDirection: 'column',
|
||||
backgroundColor: '#212137',
|
||||
}}>
|
||||
<ContentContainer>
|
||||
<Title text="Create your account using your phone number" />
|
||||
|
||||
<View style={{gap: 12, marginTop: 20}}>
|
||||
<MyIconInput
|
||||
text="Phone"
|
||||
iconName="phone-iphone"
|
||||
keyboardType="phone-pad"
|
||||
/>
|
||||
|
||||
<MyButton
|
||||
type="secondary"
|
||||
text={'Next'}
|
||||
style={{marginBottom: 20}}
|
||||
onPress={() => {
|
||||
navigation.navigate('Registration', {
|
||||
screen: 'SignUpStepVerifyPhoneNumber',
|
||||
});
|
||||
}}
|
||||
/>
|
||||
</View>
|
||||
</ContentContainer>
|
||||
</MyScreenContainer>
|
||||
);
|
||||
}
|
||||
|
||||
interface ConfirmationCodeInputProps {
|
||||
// Zusätzliche Props für das ConfirmationCodeInput-Komponente hier hinzufügen
|
||||
}
|
||||
|
||||
const ConfirmationCodeInput: React.FC<ConfirmationCodeInputProps> = () => {
|
||||
const [confirmationCode, setConfirmationCode] = useState([
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
]);
|
||||
const inputRefs = useRef<TextInput[]>([]);
|
||||
|
||||
const focusInput = (index: number) => {
|
||||
if (inputRefs.current[index]) {
|
||||
inputRefs.current[index].focus();
|
||||
}
|
||||
};
|
||||
|
||||
const handleTextChange = (text: string, index: number) => {
|
||||
const newConfirmationCode = [...confirmationCode];
|
||||
newConfirmationCode[index] = text;
|
||||
|
||||
// Fokus zum nächsten Input verschieben, wenn der aktuelle Input nicht leer ist
|
||||
if (text !== '' && index < confirmationCode.length - 1) {
|
||||
focusInput(index + 1);
|
||||
}
|
||||
|
||||
setConfirmationCode(newConfirmationCode);
|
||||
};
|
||||
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
{confirmationCode.map((digit, index) => (
|
||||
<TextInput
|
||||
key={index}
|
||||
ref={ref => (inputRefs.current[index] = ref!)}
|
||||
style={styles.input}
|
||||
keyboardType="number-pad"
|
||||
maxLength={1}
|
||||
onChangeText={text => handleTextChange(text, index)}
|
||||
value={digit}
|
||||
/>
|
||||
))}
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'center',
|
||||
},
|
||||
input: {
|
||||
height: 40,
|
||||
width: 40,
|
||||
borderColor: 'gray',
|
||||
borderWidth: 1,
|
||||
textAlign: 'center',
|
||||
margin: 5,
|
||||
borderRadius: 5,
|
||||
},
|
||||
});
|
||||
|
||||
function SignUpStepVerifyPhoneNumber() {
|
||||
const navigation = useNavigation<RootScreenNavigationProp>();
|
||||
|
||||
return (
|
||||
<MyScreenContainer
|
||||
style={{
|
||||
flex: 1,
|
||||
flexDirection: 'column',
|
||||
backgroundColor: '#212137',
|
||||
}}>
|
||||
<ContentContainer>
|
||||
<Title text="We sent you a code" />
|
||||
<Text>Enter it below to verify +49 15** ******43 </Text>
|
||||
|
||||
<KeyboardAvoidingView style={{gap: 12, marginTop: 20}}>
|
||||
<ConfirmationCodeInput />
|
||||
|
||||
<MyButton
|
||||
type="secondary"
|
||||
text={'Next'}
|
||||
style={{marginBottom: 2}}
|
||||
onPress={() => {
|
||||
navigation.navigate('Registration', {
|
||||
screen: 'SignUpStepPassword',
|
||||
});
|
||||
}}
|
||||
/>
|
||||
<View style={{alignItems: 'center'}}>
|
||||
<MyClickableText text="Resend code" />
|
||||
</View>
|
||||
</KeyboardAvoidingView>
|
||||
</ContentContainer>
|
||||
</MyScreenContainer>
|
||||
);
|
||||
}
|
||||
|
||||
function SignUpStepPassword() {
|
||||
const navigation = useNavigation<RootScreenNavigationProp>();
|
||||
|
||||
return (
|
||||
<MyScreenContainer
|
||||
style={{
|
||||
flex: 1,
|
||||
flexDirection: 'column',
|
||||
backgroundColor: '#212137',
|
||||
}}>
|
||||
<ContentContainer>
|
||||
<Title text="You'll need a password" />
|
||||
<Text>Make sure it's 8 characters or more</Text>
|
||||
|
||||
<View style={{gap: 12, marginTop: 20}}>
|
||||
<MyIconInput text="PASSWORD" iconName="lock" secureTextEntry />
|
||||
|
||||
<MyButton
|
||||
type="secondary"
|
||||
text={'Next'}
|
||||
style={{marginBottom: 2}}
|
||||
onPress={() => {
|
||||
navigation.navigate('Registration', {
|
||||
screen: 'SignUpStepAccountName',
|
||||
});
|
||||
}}
|
||||
/>
|
||||
</View>
|
||||
</ContentContainer>
|
||||
</MyScreenContainer>
|
||||
);
|
||||
}
|
||||
|
||||
function SignUpStepAccountName() {
|
||||
const navigation = useNavigation<RootScreenNavigationProp>();
|
||||
|
||||
return (
|
||||
<MyScreenContainer
|
||||
style={{
|
||||
flex: 1,
|
||||
flexDirection: 'column',
|
||||
backgroundColor: '#212137',
|
||||
}}>
|
||||
<ContentContainer>
|
||||
<Title text="Next, create your account name" />
|
||||
<Text>
|
||||
Your account name is unique and is used for friends to find you.
|
||||
</Text>
|
||||
|
||||
<View style={{gap: 12, marginTop: 20}}>
|
||||
<MyIconInput text="ACCOUNT NAME" iconName="person" />
|
||||
|
||||
<MyButton
|
||||
type="primary"
|
||||
text={'Get Started'}
|
||||
style={{marginBottom: 2}}
|
||||
onPress={() => {
|
||||
navigation.navigate('Home');
|
||||
}}
|
||||
/>
|
||||
</View>
|
||||
</ContentContainer>
|
||||
</MyScreenContainer>
|
||||
);
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
export const Constants = {
|
||||
REGISTRATION: {
|
||||
TERMS_URL: 'https://www.google.com',
|
||||
PRIVACY_POLICY_URL: 'https://www.google.com',
|
||||
COOKIE_USE_URL: 'https://www.google.com',
|
||||
},
|
||||
};
|
|
@ -6,45 +6,19 @@
|
|||
"baseUrl": ".",
|
||||
"target": "ESNext",
|
||||
"paths": {
|
||||
"@redux/*": [
|
||||
"src/redux/*"
|
||||
],
|
||||
"@lang/*": [
|
||||
"src/lang/*"
|
||||
],
|
||||
"@pages/*": [
|
||||
"src/pages/*"
|
||||
],
|
||||
"@api/*": [
|
||||
"src/api/*"
|
||||
],
|
||||
"@assets/*": [
|
||||
"src/assets/*"
|
||||
],
|
||||
"@components/*": [
|
||||
"src/components/*"
|
||||
],
|
||||
"@scenes/*": [
|
||||
"src/scenes/*"
|
||||
],
|
||||
"@theme/*": [
|
||||
"src/theme/*"
|
||||
],
|
||||
"@utils/*": [
|
||||
"src/utils/*"
|
||||
],
|
||||
"@navigation/*": [
|
||||
"src/navigation/*"
|
||||
],
|
||||
"@configs/*": [
|
||||
"src/configs/*"
|
||||
],
|
||||
"@helper/*": [
|
||||
"src/helper/*"
|
||||
],
|
||||
"@user/*": [
|
||||
"src/user/*"
|
||||
],
|
||||
},
|
||||
"@redux/*": ["src/redux/*"],
|
||||
"@lang/*": ["src/lang/*"],
|
||||
"@pages/*": ["src/pages/*"],
|
||||
"@api/*": ["src/api/*"],
|
||||
"@assets/*": ["src/assets/*"],
|
||||
"@components/*": ["src/components/*"],
|
||||
"@scenes/*": ["src/scenes/*"],
|
||||
"@theme/*": ["src/theme/*"],
|
||||
"@utils/*": ["src/utils/*"],
|
||||
"@navigation/*": ["src/navigation/*"],
|
||||
"@configs/*": ["src/configs/*"],
|
||||
"@helper/*": ["src/helper/*"],
|
||||
"@user/*": ["src/user/*"]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Reference in New Issue