theme
parent
dde6178c8f
commit
e455b52085
53
src/App.tsx
53
src/App.tsx
|
@ -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>
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
@ -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>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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 (
|
||||
|
|
|
@ -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>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -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 = {
|
||||
|
|
|
@ -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'
|
||||
}
|
||||
/>
|
||||
);
|
||||
}
|
|
@ -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>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
);
|
||||
}
|
|
@ -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,
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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}
|
||||
/>
|
||||
|
|
|
@ -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>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
);
|
||||
}
|
|
@ -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>
|
||||
);
|
||||
}
|
Reference in New Issue