master
Netcup Gituser 2023-12-03 12:23:28 +01:00
parent dde6178c8f
commit e455b52085
24 changed files with 698 additions and 483 deletions

View File

@ -1,31 +1,16 @@
import React, {useEffect, Fragment} from 'react';
import React, {useEffect} from 'react';
import {NavigationContainer} from '@react-navigation/native';
import {Provider, useSelector} from 'react-redux';
import {RootState, store} from '@redux/store';
import {appStatus} from '@configs/appNonSaveVar';
import {appNonSaveVarActions} from '@configs/appNonSaveVarReducer';
import {ThemeMode} from '@configs/colors';
import {ThemeMode, ThemeType} from '@configs/colors';
import StartHelper from '@pages/appStart/StartHelper';
import {GluestackUIProvider} from '@gluestack-ui/themed';
import configDarkTheme, {ThemeType} from '@configs/colors';
import configDarkTheme from '@configs/colors';
import Navigation from '@navigation/navigation';
/*
function Test() {
const lang = useSelector((state: RootState) => state.appVariables.lang);
return (
<View style={{flex: 1, alignItems: 'center', justifyContent: 'center'}}>
<Text style={{color: '#f00'}}>
{lang.account.registration.stepTwo.resendError[401]}
</Text>
</View>
);
} */
import {MyStatusBar} from '@components/MyStatusBar';
import {SafeAreaView} from 'react-native';
const App = () => {
useEffect(() => {
@ -43,29 +28,31 @@ const OtherProviders = () => {
const globalTheme = useSelector(
(state: RootState) => state.appVariables.preferences.theme,
);
const currentTheme = useSelector(
(state: RootState) => state.nonSaveVariables.theme.colors,
);
const navigationTheme = {
dark: globalTheme !== ThemeMode.Light,
colors: {
primary: '#ff7d4f',
background: '#222',
card: '#222',
text: '#fff',
border: '#ff7d4f',
notification: '#fff',
// primary: '#ff7d4f',
background: currentTheme.backgroundDark400, // color of deep screen background
//card: '#222',
text: '#fff', // color of header text
//border: '#ff7d4f',
//notification: '#fff',
},
};
const themeConfig: ThemeType = configDarkTheme;
useEffect(() => {
appNonSaveVarActions.setThemeColors(themeConfig.tokens.colors);
appNonSaveVarActions.setTheme(themeConfig.tokens);
});
return (
// <NativeBaseProvider theme={theme(globalTheme)}>
<NavigationContainer theme={navigationTheme} /*linking={linking}*/>
<GluestackUIProvider config={themeConfig}>
<NavigationContainer theme={navigationTheme}>
<GluestackUIProvider config={configDarkTheme}>
<MainComponent />
</GluestackUIProvider>
</NavigationContainer>
@ -78,11 +65,11 @@ const MainComponent = () => {
);
return (
<Fragment>
<SafeAreaView style={{flex: 1}}>
<StartHelper />
{/*<StatusBar />*/}
<MyStatusBar />
{currentAppStatus === appStatus.APP_RUNNING ? <Navigation /> : null}
</Fragment>
</SafeAreaView>
);
};

View File

@ -4,14 +4,14 @@ import {
ImageSourcePropType,
ImageStyle,
StyleProp,
TouchableOpacity,
ViewStyle,
} from 'react-native';
import LinearGradient from 'react-native-linear-gradient';
import {MyIcon} from './MyIcon';
import {useSelector} from 'react-redux';
import {RootState} from '@redux/store';
import { Text } from '@gluestack-ui/themed';
import {Text} from '@gluestack-ui/themed';
import {MyTouchableOpacity} from './MyTouchableOpacity';
interface MyImageButtonProps {
image: ImageSourcePropType;
@ -21,11 +21,11 @@ interface MyImageButtonProps {
export function MyImageButton({image, imageStyle, text}: MyImageButtonProps) {
const currentTheme = useSelector(
(state: RootState) => state.nonSaveVariables.themeColors,
(state: RootState) => state.nonSaveVariables.theme.colors,
);
return (
<TouchableOpacity
<MyTouchableOpacity
style={{
backgroundColor: currentTheme.backgroundDark300,
alignItems: 'center',
@ -35,15 +35,15 @@ export function MyImageButton({image, imageStyle, text}: MyImageButtonProps) {
}}>
<Image source={image} style={imageStyle} />
<Text
bold
size="lg"
style={{
flex: 1,
textAlign: 'center',
fontSize: 18,
fontWeight: 'bold',
}}>
{text}
</Text>
</TouchableOpacity>
</MyTouchableOpacity>
);
}
@ -52,44 +52,56 @@ interface MyButtonProps {
type: 'primary' | 'secondary';
text: string;
onPress?: () => void;
disabled?: boolean;
}
export function MyButton({style, type, text, onPress}: MyButtonProps) {
export function MyButton({
style,
type,
text,
onPress,
disabled,
}: MyButtonProps) {
const currentTheme = useSelector(
(state: RootState) => state.nonSaveVariables.themeColors,
(state: RootState) => state.nonSaveVariables.theme,
);
const ButtonText = () => (
<Text style={{color: currentTheme.white, fontSize: 18, fontWeight: 'bold'}}>
<Text color={currentTheme.colors.white} bold size="lg">
{text}
</Text>
);
return (
<TouchableOpacity
<MyTouchableOpacity
style={[
style,
{
borderRadius: 10,
},
]}
disabled={disabled}
onPress={onPress}>
{type === 'primary' ? (
<LinearGradient
colors={[currentTheme.secondary, currentTheme.primary]}
colors={[
currentTheme.colors.secondary200,
currentTheme.colors.primary400,
]}
start={{x: 0, y: 1}}
end={{x: 1, y: 0}}
style={{
alignItems: 'center',
padding: 10,
borderRadius: 10,
opacity: disabled ? currentTheme.opacity[60] : 1,
}}>
<ButtonText />
</LinearGradient>
) : (
<View
style={{
backgroundColor: currentTheme.backgroundDark200,
backgroundColor: currentTheme.colors.backgroundDark200,
alignItems: 'center',
padding: 10,
borderRadius: 10,
@ -97,7 +109,7 @@ export function MyButton({style, type, text, onPress}: MyButtonProps) {
<ButtonText />
</View>
)}
</TouchableOpacity>
</MyTouchableOpacity>
);
}
@ -112,12 +124,12 @@ interface MyIconButtonProps {
export function MyIconButton({onPress, MyIconProps}: MyIconButtonProps) {
return (
<TouchableOpacity onPress={onPress}>
<MyTouchableOpacity onPress={onPress}>
<MyIcon
name={MyIconProps.name}
size={MyIconProps.size}
color={MyIconProps.color}
/>
</TouchableOpacity>
</MyTouchableOpacity>
);
}

View File

@ -1,17 +1,18 @@
import { Text } from '@gluestack-ui/themed';
import {StyleProp, TextStyle} from 'react-native';
import {TouchableOpacity} from 'react-native';
import { MyTouchableOpacity } from './MyTouchableOpacity';
interface MyClickableTextProps {
textStyle?: StyleProp<TextStyle>;
text: string;
onPress?: () => void;
color?: string;
}
export function MyClickableText({textStyle, text, onPress}: MyClickableTextProps) {
export function MyClickableText({textStyle, text, onPress, color}: MyClickableTextProps) {
return (
<TouchableOpacity onPress={onPress}>
<Text style={textStyle}>{text}</Text>
</TouchableOpacity>
<MyTouchableOpacity onPress={onPress}>
<Text color={color} style={textStyle}>{text}</Text>
</MyTouchableOpacity>
);
}

View File

@ -5,7 +5,7 @@ import {useSelector} from 'react-redux';
export function MyDivider() {
const currentTheme = useSelector(
(state: RootState) => state.nonSaveVariables.themeColors,
(state: RootState) => state.nonSaveVariables.theme.colors,
);
return (
@ -25,7 +25,7 @@ interface MyDividerWithTextProps {
export function MyDividerWithText({text}: MyDividerWithTextProps) {
const currentTheme = useSelector(
(state: RootState) => state.nonSaveVariables.themeColors,
(state: RootState) => state.nonSaveVariables.theme.colors,
);
return (
@ -41,7 +41,7 @@ export function MyDividerWithText({text}: MyDividerWithTextProps) {
export function MyVerticalDivider() {
const currentTheme = useSelector(
(state: RootState) => state.nonSaveVariables.themeColors,
(state: RootState) => state.nonSaveVariables.theme.colors,
);
return (

View File

@ -2,7 +2,8 @@ import {KeyboardTypeOptions, TextInput, View} from 'react-native';
import {MyIcon} from './MyIcon';
import {useSelector} from 'react-redux';
import {RootState} from '@redux/store';
import { Text } from '@gluestack-ui/themed';
import {Text} from '@gluestack-ui/themed';
import {useRef, useState} from 'react';
interface MyIconInputProps {
text: string;
@ -24,7 +25,7 @@ export function MyIconInput({
disableContainer,
}: MyIconInputProps) {
const currentTheme = useSelector(
(state: RootState) => state.nonSaveVariables.themeColors,
(state: RootState) => state.nonSaveVariables.theme.colors,
);
return (
@ -40,11 +41,11 @@ export function MyIconInput({
},
]}>
<View style={{marginLeft: 12}}>
<MyIcon name={iconName} size={32} />
<MyIcon name={iconName} size={30} />
</View>
<View style={{flex: 1, margin: 12, gap: 2}}>
<Text>{text}</Text>
<Text size='sm' color={currentTheme.textLight200}>{text}</Text>
<TextInput
style={{
backgroundColor: currentTheme.backgroundDark400,
@ -61,3 +62,65 @@ export function MyIconInput({
</View>
);
}
export interface ConfirmationCodeInputProps {}
export 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={{
flexDirection: 'row',
justifyContent: 'center',
}}>
{confirmationCode.map((digit, index) => (
<TextInput
key={index}
ref={ref => (inputRefs.current[index] = ref!)}
style={{
height: 40,
width: 40,
borderColor: 'gray',
borderWidth: 1,
textAlign: 'center',
margin: 5,
borderRadius: 5,
}}
keyboardType="number-pad"
maxLength={1}
onChangeText={text => handleTextChange(text, index)}
value={digit}
/>
))}
</View>
);
};

View File

@ -17,7 +17,7 @@ export function MyScreenContainer({
scrollView,
}: MyScreenContainerProps) {
const currentTheme = useSelector(
(state: RootState) => state.nonSaveVariables.themeColors,
(state: RootState) => state.nonSaveVariables.theme.colors,
);
const containerStyle = {

View File

@ -0,0 +1,23 @@
import {ThemeMode} from '@configs/colors';
import {RootState} from '@redux/store';
import { StatusBar } from 'react-native';
import {useSelector} from 'react-redux';
export function MyStatusBar() {
const globalTheme = useSelector(
(state: RootState) => state.appVariables.preferences.theme,
);
const currentTheme = useSelector(
(state: RootState) => state.nonSaveVariables.theme.colors,
);
return (
<StatusBar
backgroundColor={currentTheme.backgroundDark400}
barStyle={
globalTheme === ThemeMode.Light ? 'dark-content' : 'light-content'
}
/>
);
}

View File

@ -1,15 +1,21 @@
import { Text } from "@gluestack-ui/themed";
import {Text} from '@gluestack-ui/themed';
export function MyTitle({text}: {text: string}) {
return (
<Text
style={{
fontSize: 24,
fontWeight: 'bold',
textAlign: 'center',
padding: 20,
}}>
{text}
</Text>
);
}
interface MyTitleProps {
text: string;
textAlign?: 'left' | 'center' | 'right';
paddingBottom?: number;
}
export function MyTitle({text, textAlign, paddingBottom}: MyTitleProps) {
return (
<Text
size="2xl"
bold
style={{
textAlign: textAlign ?? 'center',
paddingBottom: paddingBottom ?? 20,
}}>
{text}
</Text>
);
}

View File

@ -0,0 +1,44 @@
import {RootState} from '@redux/store';
import {ReactNode} from 'react';
import {
AccessibilityRole,
GestureResponderEvent,
StyleProp,
TouchableOpacity,
ViewStyle,
} from 'react-native';
import {useSelector} from 'react-redux';
interface CustomTouchableProps {
children?: ReactNode;
onPress?: () => void;
onLongPress?: ((event: GestureResponderEvent) => void) | undefined;
style?: StyleProp<ViewStyle>;
disabled?: boolean;
accessibilityRole?: AccessibilityRole | undefined;
}
export function MyTouchableOpacity({
children,
onPress,
onLongPress,
style,
disabled,
accessibilityRole,
}: CustomTouchableProps) {
const currentTheme = useSelector(
(state: RootState) => state.nonSaveVariables.theme.opacity,
);
return (
<TouchableOpacity
disabled={disabled}
onPress={onPress}
onLongPress={onLongPress}
style={style}
activeOpacity={currentTheme[80]}
accessibilityRole={accessibilityRole}>
{children}
</TouchableOpacity>
);
}

View File

@ -1,7 +1,7 @@
//these variables should not changed by the user and will not be saved in storage
import {getVersionByNum, VersionType} from '@helper/version';
import configDarkTheme, {ThemeColorsType} from '@configs/colors';
import configDarkTheme, {ThemeTokensType} from '@configs/colors';
export const APP_VERSION = getVersionByNum(1);
export const AppVarMaxBackups: number = 10;
@ -22,12 +22,12 @@ export interface NON_SAVE_VARS {
currentAppVersion: VersionType;
appStatus: appStatus;
connectionStatus: connectionStatus;
themeColors: ThemeColorsType;
theme: ThemeTokensType;
}
export const non_save_vars: NON_SAVE_VARS = {
currentAppVersion: APP_VERSION,
appStatus: appStatus.IS_LOADING,
connectionStatus: connectionStatus.UNKNOWN,
themeColors: configDarkTheme.tokens.colors,
theme: configDarkTheme.tokens,
};

View File

@ -3,7 +3,7 @@ import type {PayloadAction} from '@reduxjs/toolkit';
import {appStatus, non_save_vars} from './appNonSaveVar';
import {ThemeColorsType} from '@configs/colors';
import {ThemeTokensType} from '@configs/colors';
export const appNonSaveVariablesSlice = createSlice({
name: 'non_save_vars',
@ -12,8 +12,8 @@ export const appNonSaveVariablesSlice = createSlice({
setAppStatus: (state, action: PayloadAction<appStatus>) => {
state.appStatus = action.payload;
},
setThemeColors: (state, action: PayloadAction<ThemeColorsType>) => {
state.themeColors = action.payload;
setTheme: (state, action: PayloadAction<ThemeTokensType>) => {
state.theme = action.payload;
},
},
});

View File

@ -1,9 +1,9 @@
import {config} from '@configs/gluestack-ui.config'; // default dark theme
type ThemeType = typeof config;
type ThemeColorsType = typeof config.tokens.colors;
type ThemeTokensType = typeof config.tokens;
export type {ThemeType, ThemeColorsType};
export type {ThemeType, ThemeTokensType};
export default config;
export enum ThemeMode {

View File

@ -311,7 +311,16 @@ export const gluestackUIConfig = createConfig({
light700: '#44403c',
light800: '#292524',
light900: '#1c1917',
primary: '#6030da',
primary50: '#b9a0f8',
primary100: '#a283f2',
primary200: '#8c67ea',
primary300: '#774de0',
primary400: '#6030da', // primary
primary500: '#582bc9',
primary600: '#532db1',
primary700: '#4d2f9b',
primary800: '#472f86',
primary900: '#412d72',
/*
primary0: '#E5F1FB',
primary50: '#CCE9FF',
@ -337,10 +346,19 @@ export const gluestackUIConfig = createConfig({
secondary800: '#262626',
secondary900: '#171717',
secondary950: '#0C0C0C', */
secondary: '#931278',
secondary50: '#f939d0',
secondary100: '#f21dc4',
secondary200: '#d713ad',
secondary300: '#b1168f',
secondary400: '#931278', // secondary
secondary500: '#7b1364',
secondary600: '#651453',
secondary700: '#511343',
secondary800: '#3d1134',
secondary900: '#2b0e25',
textLight0: '#FCFCFC',
textLight50: '#F5F5F5',
textLight100: '#E5E5E5',
textLight100: '#E5E5E5', // secondary text
textLight200: '#DBDBDB',
textLight300: '#D4D4D4',
textLight400: '#A3A3A3',

View File

@ -13,7 +13,7 @@ import ProfileTab, {
ProfileStackNavigatorParamList,
} from './tabs/main/ProfileTab';
import {FadeInView} from '@helper/animations';
import {TouchableOpacity, View} from 'react-native';
import {View} from 'react-native';
import LinearGradient from 'react-native-linear-gradient';
import {
RegistrationScreenAnim,
@ -23,7 +23,8 @@ import {NativeStackNavigationProp} from '@react-navigation/native-stack';
import {MyIcon} from '@components/MyIcon';
import {useSelector} from 'react-redux';
import {RootState, store as reduxStore} from '@redux/store';
import { Text } from '@gluestack-ui/themed';
import {Text} from '@gluestack-ui/themed';
import {MyTouchableOpacity} from '@components/MyTouchableOpacity';
export type RootStackNavigatorParamList = {
Home: NavigatorScreenParams<HomeStackNavigatorParamList>;
@ -98,7 +99,7 @@ function CustomTabBar(props: BottomTabBarProps) {
);
const currentTheme = useSelector(
(state: RootState) => state.nonSaveVariables.themeColors,
(state: RootState) => state.nonSaveVariables.theme.colors,
);
const tabNames = [
@ -139,13 +140,12 @@ function CustomTabBar(props: BottomTabBarProps) {
});
};
// TODO: retrieve colors from theme
const gradientColors = isFocused
? [currentTheme.secondary, currentTheme.primary]
? [currentTheme.secondary200, currentTheme.primary400]
: [currentTheme.backgroundDark300, currentTheme.backgroundDark300];
return (
<TouchableOpacity
<MyTouchableOpacity
key={route.key}
accessibilityRole="button"
onPress={onPress}
@ -170,14 +170,14 @@ function CustomTabBar(props: BottomTabBarProps) {
}}>
<MyIcon
name={tabBarIcons[index]}
color={isFocused ? currentTheme.white : '#ccc'}
color={
isFocused ? currentTheme.white : currentTheme.textLight100
}
size={20}
/>
{isFocused && (
<Text>{tabNames[index]}</Text>
)}
{isFocused && <Text>{tabNames[index]}</Text>}
</LinearGradient>
</TouchableOpacity>
</MyTouchableOpacity>
);
})}
</View>

View File

@ -6,13 +6,7 @@ import {
createNativeStackNavigator,
NativeStackNavigationOptions,
} from '@react-navigation/native-stack';
import {
Image,
ScrollView,
StyleSheet,
TextInput,
View,
} from 'react-native';
import {Image, View} from 'react-native';
import GoogleLogo from '@assets/google-logo.png';
import AppleLogo from '@assets/apple-logo.png';
@ -23,13 +17,18 @@ import {MyButton, MyImageButton} 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';
import {MyTitle} from '@components/MyTitle';
import {useSelector} from 'react-redux';
import {RootState} from '@redux/store';
import { Text } from '@gluestack-ui/themed';
import {Text} from '@gluestack-ui/themed';
import {Login} from '@pages/welcome/login/login';
import {
SignUpStepAccountName,
SignUpStepPassword,
SignUpStepPhoneNumber,
SignUpStepUsername,
SignUpStepVerifyPhoneNumber,
} from '@pages/welcome/signUp/signUp';
export type RegistrationStackNavigatorParamList = {
SignUpPreview: undefined;
@ -53,14 +52,18 @@ export function RegistrationScreenAnim(props: any) {
);
}
const headerStyle: NativeStackNavigationOptions = {
headerShown: true,
headerStyle: {backgroundColor: '#212137'},
headerTitleAlign: 'center',
headerTitle: '',
};
export function RegistrationScreen() {
const currentTheme = useSelector(
(state: RootState) => state.nonSaveVariables.theme.colors,
);
const headerStyle: NativeStackNavigationOptions = {
headerShown: true,
headerStyle: {backgroundColor: currentTheme.backgroundDark400},
headerTitleAlign: 'center',
headerTitle: '',
};
return (
<RegistrationStack.Navigator screenOptions={{headerShown: false}}>
<RegistrationStack.Screen
@ -71,11 +74,7 @@ export function RegistrationScreen() {
<RegistrationStack.Screen
name="Login"
component={Login}
options={{
headerShown: true,
headerStyle: {backgroundColor: '#212137'},
headerTitleAlign: 'center',
}}
options={{...headerStyle}}
/>
<RegistrationStack.Screen
name="SignUpStepUsername"
@ -140,6 +139,9 @@ function RegistrationPreview({type}: {type: 'login' | 'signup'}) {
const lang = useSelector(
(state: RootState) => state.appVariables.lang.registration,
);
const currentTheme = useSelector(
(state: RootState) => state.nonSaveVariables.theme.colors,
);
const navigation = useNavigation<RootScreenNavigationProp>();
return (
@ -188,25 +190,31 @@ function RegistrationPreview({type}: {type: 'login' | 'signup'}) {
{type === 'signup' && (
<View style={{flexDirection: 'row', flexWrap: 'wrap'}}>
<Text>{`${lang.previewSignup.agreeToTerms} `}</Text>
<Text
color={
currentTheme.textLight100
}>{`${lang.previewSignup.agreeToTerms} `}</Text>
<MyClickableText
text={lang.previewSignup.terms}
textStyle={{color: '#6030da'}}
textStyle={{color: currentTheme.primary300}}
onPress={() => OpenURL(Constants.REGISTRATION.TERMS_URL)}
/>
<Text>, </Text>
<Text color={currentTheme.textLight100}>, </Text>
<MyClickableText
text={lang.previewSignup.privacyPolicy}
textStyle={{color: '#6030da'}}
textStyle={{color: currentTheme.primary300}}
onPress={() => OpenURL(Constants.REGISTRATION.PRIVACY_POLICY_URL)}
/>
<Text>{` ${lang.previewSignup.agreeToTermsAnd} `}</Text>
<Text
color={
currentTheme.textLight100
}>{` ${lang.previewSignup.agreeToTermsAnd} `}</Text>
<MyClickableText
text={lang.previewSignup.cookieUse}
textStyle={{color: '#6030da'}}
textStyle={{color: currentTheme.primary300}}
onPress={() => OpenURL(Constants.REGISTRATION.COOKIE_USE_URL)}
/>
<Text>.</Text>
<Text color={currentTheme.textLight100}>.</Text>
</View>
)}
@ -214,12 +222,18 @@ function RegistrationPreview({type}: {type: 'login' | 'signup'}) {
{type === 'login' ? (
<Text>{lang.previewLogin.dontHaveAccount}</Text>
) : (
<Text>{lang.previewSignup.alreadyHaveAccount}</Text>
<Text color={currentTheme.textLight100}>
{lang.previewSignup.alreadyHaveAccount}
</Text>
)}
<MyClickableText
text={type === 'login' ? lang.buttonSignUp : lang.buttonLogin}
textStyle={{left: 2, color: '#931278', fontWeight: 'bold'}}
textStyle={{
left: 2,
color: currentTheme.secondary300,
fontWeight: 'bold',
}}
onPress={() => {
navigation.navigate(
'Registration',
@ -235,7 +249,7 @@ function RegistrationPreview({type}: {type: 'login' | 'signup'}) {
);
}
function ContentContainer({children}: {children: React.ReactNode}) {
export function ContentContainer({children}: {children: React.ReactNode}) {
return (
<>
<View style={{flex: 1}} />
@ -244,297 +258,10 @@ function ContentContainer({children}: {children: React.ReactNode}) {
);
}
function Login() {
const lang = useSelector(
(state: RootState) => state.appVariables.lang.registration,
);
const navigation = useNavigation<RootScreenNavigationProp>();
return (
<MyScreenContainer
style={{
flexDirection: 'column',
}}>
<ContentContainer>
<MyTitle text={lang.login.title} />
<View style={{gap: 12}}>
<MyIconInput
text={lang.login.inputPhoneNumberOrAccountName}
iconName="person"
/>
<MyIconInput
text={lang.login.inputPassword}
iconName="lock"
secureTextEntry
/>
<MyButton
type="secondary"
text={lang.buttonLogin}
style={{marginBottom: 20}}
onPress={() => navigateToHome(navigation)}
/>
</View>
</ContentContainer>
</MyScreenContainer>
);
}
function SignUpStepUsername() {
const lang = useSelector(
(state: RootState) => state.appVariables.lang.registration,
);
const navigation = useNavigation<RootScreenNavigationProp>();
return (
<MyScreenContainer
style={{
flexDirection: 'column',
}}>
<ContentContainer>
<MyTitle text={lang.signUpStepUsername.title} />
<Text>{lang.signUpStepUsername.description}</Text>
<View style={{gap: 12, marginTop: 20}}>
<MyIconInput
text={lang.signUpStepUsername.inputUsername}
iconName="person"
/>
<MyButton
type="secondary"
text={lang.buttonNext}
style={{marginBottom: 20}}
onPress={() => {
navigation.navigate('Registration', {
screen: 'SignUpStepPhoneNumber',
});
}}
/>
</View>
</ContentContainer>
</MyScreenContainer>
);
}
function SignUpStepPhoneNumber() {
const lang = useSelector(
(state: RootState) => state.appVariables.lang.registration,
);
const navigation = useNavigation<RootScreenNavigationProp>();
return (
<MyScreenContainer
style={{
flexDirection: 'column',
}}>
<ContentContainer>
<MyTitle text={lang.signUpStepPhoneNumber.title} />
<View style={{gap: 12, marginTop: 20}}>
<MyIconInput
text={lang.signUpStepPhoneNumber.inputPhoneNumber}
iconName="phone-iphone"
keyboardType="phone-pad"
/>
<MyButton
type="secondary"
text={lang.buttonNext}
style={{marginBottom: 20}}
onPress={() => {
navigation.navigate('Registration', {
screen: 'SignUpStepVerifyPhoneNumber',
});
}}
/>
</View>
</ContentContainer>
</MyScreenContainer>
);
}
interface ConfirmationCodeInputProps {}
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 lang = useSelector(
(state: RootState) => state.appVariables.lang.registration,
);
const navigation = useNavigation<RootScreenNavigationProp>();
return (
<MyScreenContainer
style={{
flexDirection: 'column',
}}>
<ContentContainer>
<MyTitle text={lang.signUpStepVerifyPhoneNumber.title} />
<Text>{`${lang.signUpStepVerifyPhoneNumber.description} +49 15** ******43`}</Text>
<KeyboardAvoidingView style={{gap: 12, marginTop: 20}}>
<ConfirmationCodeInput />
<MyButton
type="secondary"
text={lang.buttonNext}
style={{marginBottom: 2}}
onPress={() => {
navigation.navigate('Registration', {
screen: 'SignUpStepPassword',
});
}}
/>
<View style={{alignItems: 'center'}}>
<MyClickableText
text={lang.signUpStepVerifyPhoneNumber.clickableTextResendCode}
/>
</View>
</KeyboardAvoidingView>
</ContentContainer>
</MyScreenContainer>
);
}
function SignUpStepPassword() {
const lang = useSelector(
(state: RootState) => state.appVariables.lang.registration,
);
const navigation = useNavigation<RootScreenNavigationProp>();
return (
<MyScreenContainer
style={{
flexDirection: 'column',
}}>
<ContentContainer>
<MyTitle text={lang.signUpStepPassword.title} />
<Text>{lang.signUpStepPassword.description}</Text>
<View style={{gap: 12, marginTop: 20}}>
<MyIconInput
text={lang.signUpStepPassword.inputPassword}
iconName="lock"
secureTextEntry
/>
<MyButton
type="secondary"
text={lang.buttonNext}
style={{marginBottom: 2}}
onPress={() =>
navigation.navigate('Registration', {
screen: 'SignUpStepAccountName',
})
}
/>
</View>
</ContentContainer>
</MyScreenContainer>
);
}
function navigateToHome(navigation: RootScreenNavigationProp) {
export function navigateToHome(navigation: RootScreenNavigationProp) {
navigation.navigate('Home', {screen: 'Map', params: {screen: 'Overview'}});
navigation.reset({
index: 0,
routes: [{name: 'Home'}],
});
}
function SignUpStepAccountName() {
const lang = useSelector(
(state: RootState) => state.appVariables.lang.registration,
);
const navigation = useNavigation<RootScreenNavigationProp>();
return (
<MyScreenContainer
style={{
flexDirection: 'column',
}}>
<ScrollView>
<ContentContainer>
<MyTitle text={lang.signUpStepAccountName.title} />
<Text>{lang.signUpStepAccountName.description}</Text>
<View style={{gap: 12, marginTop: 20}}>
<MyIconInput
text={lang.signUpStepAccountName.inputAccountName}
iconName="person"
/>
<MyButton
type="primary"
text={lang.signUpStepAccountName.buttonGetStarted}
style={{marginBottom: 2}}
onPress={() => navigateToHome(navigation)}
/>
</View>
</ContentContainer>
</ScrollView>
</MyScreenContainer>
);
}

View File

@ -1,10 +1,10 @@
import { MyScreenContainer } from '@components/MyScreenContainer';
import { Text } from '@gluestack-ui/themed';
import {
createNativeStackNavigator,
NativeStackNavigationProp,
} from '@react-navigation/native-stack';
import {RootState} from '@redux/store';
import {Text} from 'react-native';
import {useSelector} from 'react-redux';
export const CalendarTabName = 'Calendar';
@ -21,6 +21,13 @@ export type CalendarScreenNavigationProp =
function CalendarTab() {
const lang = useSelector((state: RootState) => state.appVariables.lang.navigation.home.calendar);
const currentTheme = useSelector(
(state: RootState) => state.nonSaveVariables.theme.colors,
);
const headerStyle = {
backgroundColor: currentTheme.backgroundDark400,
};
//const navigation = useNavigation<CalendarScreenNavigationProp>();
@ -31,6 +38,8 @@ function CalendarTab() {
options={{
title: lang.tabName,
headerShown: true,
headerShadowVisible: false,
headerStyle: headerStyle,
}}
component={CalendarScreen}
/>

View File

@ -23,6 +23,13 @@ function ChatsTab() {
const lang = useSelector(
(state: RootState) => state.appVariables.lang.navigation.home.chats,
);
const currentTheme = useSelector(
(state: RootState) => state.nonSaveVariables.theme.colors,
);
const headerStyle = {
backgroundColor: currentTheme.backgroundDark400,
};
return (
<ChatsStack.Navigator initialRouteName="Overview">
@ -31,6 +38,8 @@ function ChatsTab() {
options={{
title: lang.tabName,
headerShown: true,
headerShadowVisible: false,
headerStyle: headerStyle,
}}
component={ChatsScreen}
/>
@ -41,7 +50,7 @@ function ChatsTab() {
function ChatsScreen() {
return (
<MyScreenContainer>
<Text>Chats</Text>
<Text>Part of the next phase</Text>
</MyScreenContainer>
);
}

View File

@ -20,7 +20,13 @@ export type MapScreenNavigationProp =
function MapTab() {
const lang = useSelector((state: RootState) => state.appVariables.lang.navigation.home.map);
const currentTheme = useSelector(
(state: RootState) => state.nonSaveVariables.theme.colors,
);
const headerStyle = {
backgroundColor: currentTheme.backgroundDark400,
};
//const navigation = useNavigation<MapScreenNavigationProp>();
return (
@ -30,6 +36,8 @@ function MapTab() {
options={{
title: lang.tabName,
headerShown: true,
headerShadowVisible: false,
headerStyle: headerStyle,
}}
component={MapScreen}
/>
@ -40,7 +48,7 @@ function MapTab() {
function MapScreen() {
return (
<MyScreenContainer>
<Text>Map</Text>
<Text>Jan dein Part</Text>
</MyScreenContainer>
);
}

View File

@ -39,6 +39,13 @@ export default function ProfileTab() {
const lang = useSelector(
(state: RootState) => state.appVariables.lang.navigation.home.profile,
);
const currentTheme = useSelector(
(state: RootState) => state.nonSaveVariables.theme.colors,
);
const headerStyle = {
backgroundColor: currentTheme.backgroundDark400
};
return (
<ProfileStack.Navigator>
@ -48,7 +55,8 @@ export default function ProfileTab() {
animation: 'slide_from_left',
title: lang.overview,
headerShown: true,
headerStyle: {backgroundColor: '#212137'},
headerStyle: headerStyle,
headerShadowVisible: false,
headerRight: () => (
<MyIconButton
MyIconProps={{name: 'settings', size: 24}}
@ -65,7 +73,8 @@ export default function ProfileTab() {
animation: 'slide_from_right',
title: lang.settings,
headerShown: true,
headerStyle: {backgroundColor: '#212137'},
headerStyle: headerStyle,
headerShadowVisible: false,
headerTitleAlign: 'center',
}}
component={ProfileSettings}
@ -77,7 +86,8 @@ export default function ProfileTab() {
animation: 'slide_from_right',
title: lang.updateUsername,
headerShown: true,
headerStyle: {backgroundColor: '#212137'},
headerStyle: headerStyle,
headerShadowVisible: false,
headerTitleAlign: 'center',
}}
component={UpdateUsername}
@ -89,7 +99,8 @@ export default function ProfileTab() {
animation: 'slide_from_right',
title: lang.updatePassword,
headerShown: true,
headerStyle: {backgroundColor: '#212137'},
headerStyle: headerStyle,
headerShadowVisible: false,
headerTitleAlign: 'center',
}}
component={UpdatePassword}
@ -101,7 +112,8 @@ export default function ProfileTab() {
animation: 'slide_from_right',
title: lang.help,
headerShown: true,
headerStyle: {backgroundColor: '#212137'},
headerStyle: headerStyle,
headerShadowVisible: false,
headerTitleAlign: 'center',
}}
component={Help}
@ -113,7 +125,8 @@ export default function ProfileTab() {
animation: 'slide_from_right',
title: lang.about,
headerShown: true,
headerStyle: {backgroundColor: '#212137'},
headerStyle: headerStyle,
headerShadowVisible: false,
headerTitleAlign: 'center',
}}
component={About}

View File

@ -38,8 +38,9 @@ function StartHelper() {
);
const lang = useSelector((state: RootState) => state.appVariables.lang);
const theme = useSelector(
(state: RootState) => state.appVariables.preferences.theme,
const currentTheme = useSelector(
(state: RootState) => state.nonSaveVariables.theme.colors,
);
const [motionProps, api] = useSpring(
@ -76,16 +77,14 @@ function StartHelper() {
if (currentAppStatus === appStatus.APP_RUNNING) return null;
return (
<SafeAreaView style={[{flex: 1, backgroundColor: '#26263f'}]}>
<SafeAreaView style={[{flex: 1, backgroundColor: currentTheme.backgroundDark400}]}>
<Center height={'100%'}>
<AnimationView
style={{
height: 100,
position: 'absolute',
backgroundColor: '#931278',
backgroundColor: currentTheme.secondary400,
borderRadius: 8,
width: motionProps.width,
opacity: motionProps.opacity,
transform: [{translateX: motionProps.translateX}, {translateY: 5}],
@ -94,7 +93,7 @@ function StartHelper() {
<Heading style={{color: '#fff'}}>{lang.appName}</Heading>
<HStack marginTop={5} justifyContent="center">
<Spinner color="#931278" size="large" />
<Spinner color={currentTheme.secondary400} size="large" />
</HStack>
</Center>
</SafeAreaView>

View File

@ -1,9 +1,10 @@
import {MyIcon} from '@components/MyIcon';
import {MyScreenContainer} from '@components/MyScreenContainer';
import { RootState } from '@redux/store';
import { MyTouchableOpacity } from '@components/MyTouchableOpacity';
import {Text} from '@gluestack-ui/themed';
import {RootState} from '@redux/store';
import {View} from 'react-native';
import {Text, TouchableOpacity} from 'react-native';
import { useSelector } from 'react-redux';
import {useSelector} from 'react-redux';
export function Help() {
const lang = useSelector(
@ -26,12 +27,16 @@ export interface ItemProps {
}
export function Item({icon, title, value, onPress}: ItemProps) {
const currentTheme = useSelector(
(state: RootState) => state.nonSaveVariables.theme.colors,
);
return (
<TouchableOpacity
<MyTouchableOpacity
style={{
flexDirection: 'row',
alignItems: 'center',
backgroundColor: '#26263f',
backgroundColor: currentTheme.backgroundDark300,
borderRadius: 10,
padding: 12,
marginTop: 12,
@ -44,17 +49,13 @@ export function Item({icon, title, value, onPress}: ItemProps) {
{value ? (
<>
<Text>{title}</Text>
<Text style={{color: '#fff', fontWeight: 'bold', fontSize: 16}}>
{value}
</Text>
<Text bold>{value}</Text>
</>
) : (
<Text style={{color: '#fff', fontWeight: 'bold', fontSize: 16}}>
{title}
</Text>
<Text bold>{title}</Text>
)}
</View>
</View>
</TouchableOpacity>
</MyTouchableOpacity>
);
}

View File

@ -1,6 +1,6 @@
import {MyScreenContainer} from '@components/MyScreenContainer';
import {Image, ScrollView, TouchableOpacity} from 'react-native';
import {Text, View} from 'react-native';
import {Image, ScrollView} from 'react-native';
import {View} from 'react-native';
import Avatar from '@assets/profile.png';
import {MyTitle} from '@components/MyTitle';
import {MyVerticalDivider} from '@components/MyDivider';
@ -12,6 +12,8 @@ import {useEffect, useState} from 'react';
import {RootScreenNavigationProp} from '@navigation/navigation';
import {useSelector} from 'react-redux';
import {RootState} from '@redux/store';
import {Text} from '@gluestack-ui/themed';
import {MyTouchableOpacity} from '@components/MyTouchableOpacity';
function UserAvatar() {
return (
@ -56,29 +58,33 @@ interface StatisticProps {
}
function Statistic({value, title}: StatisticProps) {
const currentTheme = useSelector(
(state: RootState) => state.nonSaveVariables.theme.colors,
);
return (
<TouchableOpacity>
<MyTouchableOpacity>
<View>
<Text
size="2xl"
bold
style={{
fontSize: 24,
fontWeight: 'bold',
color: '#931278',
color: currentTheme.secondary400,
textAlign: 'center',
}}>
{value}
</Text>
<Text
bold
size="sm"
style={{
fontSize: 14,
fontWeight: 'bold',
color: '#ccc',
color: currentTheme.textLight100,
textAlign: 'center',
}}>
{title}
</Text>
</View>
</TouchableOpacity>
</MyTouchableOpacity>
);
}
@ -161,14 +167,18 @@ interface SettingsItemContainerProps {
}
function SettingsItemContainer({children, title}: SettingsItemContainerProps) {
const currentTheme = useSelector(
(state: RootState) => state.nonSaveVariables.theme.colors,
);
return (
<View style={{marginTop: 12}}>
<Text style={{fontSize: 12}}>{title}</Text>
<Text size="xs">{title}</Text>
<View
style={{
padding: 12,
borderRadius: 10,
backgroundColor: '#26263f',
backgroundColor: currentTheme.backgroundDark300,
marginTop: 4,
gap: 16,
}}>
@ -187,7 +197,7 @@ interface SettingsItemProps {
function SettingsItem({icon, title, value, onPress}: SettingsItemProps) {
return (
<TouchableOpacity
<MyTouchableOpacity
style={{
flexDirection: 'row',
alignItems: 'center',
@ -195,23 +205,19 @@ function SettingsItem({icon, title, value, onPress}: SettingsItemProps) {
disabled={!onPress}
onPress={onPress}>
<View style={{flexDirection: 'row', gap: 12, alignItems: 'center'}}>
<MyIcon name={icon} size={36} />
<MyIcon name={icon} size={32} />
<View>
{value ? (
<>
<Text style={{fontSize: 14}}>{title}</Text>
<Text style={{color: '#fff', fontWeight: 'bold', fontSize: 16}}>
{value}
</Text>
<Text size="sm">{title}</Text>
<Text bold>{value}</Text>
</>
) : (
<Text style={{color: '#fff', fontWeight: 'bold', fontSize: 16}}>
{title}
</Text>
<Text bold>{title}</Text>
)}
</View>
</View>
</TouchableOpacity>
</MyTouchableOpacity>
);
}
@ -219,6 +225,9 @@ export function UpdateUsername() {
const lang = useSelector(
(state: RootState) => state.appVariables.lang.profile.settings,
);
const currentTheme = useSelector(
(state: RootState) => state.nonSaveVariables.theme.colors,
);
const navigation = useNavigation<ProfileScreenNavigationProp>();
// TODO: get username from current logged in user
@ -232,9 +241,13 @@ export function UpdateUsername() {
navigation.setOptions({
headerRight: () =>
changed ? (
<TouchableOpacity onPress={() => navigation.goBack()}>
<MyIcon name="done" size={24} color={!changed ? '#fff' : '#ccc'} />
</TouchableOpacity>
<MyTouchableOpacity onPress={() => navigation.goBack()}>
<MyIcon
name="done"
size={24}
color={!changed ? currentTheme.white : currentTheme.textLight100}
/>
</MyTouchableOpacity>
) : (
<></>
),
@ -251,15 +264,19 @@ export function UpdateUsername() {
setNewUsername(text);
}}
/>
<Text style={{marginTop: 12}}>{lang.changeUsername.info}</Text>
<Text>{lang.changeUsername.info2}</Text>
<Text color={currentTheme.textLight100} style={{marginTop: 12}}>{lang.changeUsername.info}</Text>
<Text color={currentTheme.textLight100} >{lang.changeUsername.info2}</Text>
</MyScreenContainer>
);
}
export function UpdatePassword() {
const lang = useSelector(
(state: RootState) => state.appVariables.lang.profile.settings.changePassword,
(state: RootState) =>
state.appVariables.lang.profile.settings.changePassword,
);
const currentTheme = useSelector(
(state: RootState) => state.nonSaveVariables.theme.colors,
);
const navigation = useNavigation<RootScreenNavigationProp>();
@ -277,12 +294,12 @@ export function UpdatePassword() {
navigation.setOptions({
headerRight: () =>
passwordChanged ? (
<TouchableOpacity
<MyTouchableOpacity
onPress={() =>
navigation.navigate('Registration', {screen: 'LoginPreview'})
}>
<MyIcon name="done" size={24} color="#fff" />
</TouchableOpacity>
<MyIcon name="done" size={24} color={currentTheme.white} />
</MyTouchableOpacity>
) : (
<></>
),
@ -294,7 +311,7 @@ export function UpdatePassword() {
<View
style={{
borderRadius: 10,
backgroundColor: '#26263f',
backgroundColor: currentTheme.backgroundDark300,
marginTop: 4,
}}>
<MyIconInput
@ -323,10 +340,8 @@ export function UpdatePassword() {
/>
</View>
<Text style={{marginTop: 12}}>
{lang.info}
</Text>
<Text>{lang.info2}</Text>
<Text color={currentTheme.textLight100} style={{marginTop: 12}}>{lang.info}</Text>
<Text color={currentTheme.textLight100}>{lang.info2}</Text>
</MyScreenContainer>
);
}

View File

@ -0,0 +1,58 @@
import { MyButton } from "@components/MyButton";
import { MyIconInput } from "@components/MyInput";
import { MyScreenContainer } from "@components/MyScreenContainer";
import { MyTitle } from "@components/MyTitle";
import { RootScreenNavigationProp } from "@navigation/navigation";
import { ContentContainer, navigateToHome } from "@navigation/registration/registration";
import { useNavigation } from "@react-navigation/native";
import { RootState } from "@redux/store";
import { useState } from "react";
import { View } from "react-native";
import { useSelector } from "react-redux";
export function Login() {
const lang = useSelector(
(state: RootState) => state.appVariables.lang.registration,
);
const navigation = useNavigation<RootScreenNavigationProp>();
const [username, setUsername] = useState('');
const [password, setPassword] = useState('');
const loginEnabled = username.length > 0 && password.length > 0;
return (
<MyScreenContainer
style={{
flexDirection: 'column',
}}>
<ContentContainer>
<MyTitle text={lang.login.title} />
<View style={{gap: 12}}>
<MyIconInput
text={lang.login.inputPhoneNumberOrAccountName}
iconName="person"
value={username}
onChangeText={text => setUsername(text)}
/>
<MyIconInput
text={lang.login.inputPassword}
iconName="lock"
secureTextEntry
value={password}
onChangeText={text => setPassword(text)}
/>
<MyButton
type="primary"
text={lang.buttonLogin}
style={{marginBottom: 20}}
onPress={() => navigateToHome(navigation)}
disabled={!loginEnabled}
/>
</View>
</ContentContainer>
</MyScreenContainer>
);
}

View File

@ -0,0 +1,222 @@
import {MyButton} from '@components/MyButton';
import {MyClickableText} from '@components/MyClickableText';
import {ConfirmationCodeInput, MyIconInput} from '@components/MyInput';
import {MyScreenContainer} from '@components/MyScreenContainer';
import {MyTitle} from '@components/MyTitle';
import {RootScreenNavigationProp} from '@navigation/navigation';
import {
ContentContainer,
navigateToHome,
} from '@navigation/registration/registration';
import {useNavigation} from '@react-navigation/native';
import {RootState} from '@redux/store';
import {Text} from 'react-native';
import {KeyboardAvoidingView, ScrollView, View} from 'react-native';
import {useSelector} from 'react-redux';
function Title({text, description}: {text: string; description?: string}) {
return (
<>
<MyTitle text={text} textAlign="left" paddingBottom={0} />
{description && <Text>{description}</Text>}
</>
);
}
export function SignUpStepUsername() {
const lang = useSelector(
(state: RootState) => state.appVariables.lang.registration,
);
const navigation = useNavigation<RootScreenNavigationProp>();
return (
<MyScreenContainer
style={{
flexDirection: 'column',
}}>
<ContentContainer>
<Title
text={lang.signUpStepUsername.title}
description={lang.signUpStepUsername.description}
/>
<View style={{gap: 12, marginTop: 20}}>
<MyIconInput
text={lang.signUpStepUsername.inputUsername}
iconName="person"
/>
<MyButton
type="secondary"
text={lang.buttonNext}
style={{marginBottom: 20}}
onPress={() => {
navigation.navigate('Registration', {
screen: 'SignUpStepPhoneNumber',
});
}}
/>
</View>
</ContentContainer>
</MyScreenContainer>
);
}
export function SignUpStepPhoneNumber() {
const lang = useSelector(
(state: RootState) => state.appVariables.lang.registration,
);
const navigation = useNavigation<RootScreenNavigationProp>();
return (
<MyScreenContainer
style={{
flexDirection: 'column',
}}>
<ContentContainer>
<Title text={lang.signUpStepPhoneNumber.title} />
<View style={{gap: 12, marginTop: 20}}>
<MyIconInput
text={lang.signUpStepPhoneNumber.inputPhoneNumber}
iconName="phone-iphone"
keyboardType="phone-pad"
/>
<MyButton
type="secondary"
text={lang.buttonNext}
style={{marginBottom: 20}}
onPress={() => {
navigation.navigate('Registration', {
screen: 'SignUpStepVerifyPhoneNumber',
});
}}
/>
</View>
</ContentContainer>
</MyScreenContainer>
);
}
export function SignUpStepVerifyPhoneNumber() {
const lang = useSelector(
(state: RootState) => state.appVariables.lang.registration,
);
const currentTheme = useSelector(
(state: RootState) => state.nonSaveVariables.theme.colors,
);
const navigation = useNavigation<RootScreenNavigationProp>();
return (
<MyScreenContainer
style={{
flexDirection: 'column',
}}>
<ContentContainer>
<Title
text={lang.signUpStepVerifyPhoneNumber.title}
description={`${lang.signUpStepVerifyPhoneNumber.description} +49 15** ******43`}
/>
<KeyboardAvoidingView style={{gap: 12, marginTop: 20}}>
<ConfirmationCodeInput />
<MyButton
type="secondary"
text={lang.buttonNext}
style={{marginBottom: 2}}
onPress={() => {
navigation.navigate('Registration', {
screen: 'SignUpStepPassword',
});
}}
/>
<View style={{alignItems: 'center'}}>
<MyClickableText
text={lang.signUpStepVerifyPhoneNumber.clickableTextResendCode}
color={currentTheme.textLight400}
/>
</View>
</KeyboardAvoidingView>
</ContentContainer>
</MyScreenContainer>
);
}
export function SignUpStepPassword() {
const lang = useSelector(
(state: RootState) => state.appVariables.lang.registration,
);
const navigation = useNavigation<RootScreenNavigationProp>();
return (
<MyScreenContainer
style={{
flexDirection: 'column',
}}>
<ContentContainer>
<Title
text={lang.signUpStepPassword.title}
description={lang.signUpStepPassword.description}
/>
<View style={{gap: 12, marginTop: 20}}>
<MyIconInput
text={lang.signUpStepPassword.inputPassword}
iconName="lock"
secureTextEntry
/>
<MyButton
type="secondary"
text={lang.buttonNext}
style={{marginBottom: 2}}
onPress={() =>
navigation.navigate('Registration', {
screen: 'SignUpStepAccountName',
})
}
/>
</View>
</ContentContainer>
</MyScreenContainer>
);
}
export function SignUpStepAccountName() {
const lang = useSelector(
(state: RootState) => state.appVariables.lang.registration,
);
const navigation = useNavigation<RootScreenNavigationProp>();
return (
<MyScreenContainer
style={{
flexDirection: 'column',
}}>
<ScrollView>
<ContentContainer>
<Title
text={lang.signUpStepAccountName.title}
description={lang.signUpStepAccountName.description}
/>
<View style={{gap: 12, marginTop: 20}}>
<MyIconInput
text={lang.signUpStepAccountName.inputAccountName}
iconName="person"
/>
<MyButton
type="primary"
text={lang.signUpStepAccountName.buttonGetStarted}
style={{marginBottom: 2}}
onPress={() => navigateToHome(navigation)}
/>
</View>
</ContentContainer>
</ScrollView>
</MyScreenContainer>
);
}