diff --git a/src/App.tsx b/src/App.tsx index e970986..fe185c6 100644 --- a/src/App.tsx +++ b/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 ( - - - {lang.account.registration.stepTwo.resendError[401]} - - - ); -} */ +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 ( - // - - + + @@ -78,11 +65,11 @@ const MainComponent = () => { ); return ( - + - {/**/} + {currentAppStatus === appStatus.APP_RUNNING ? : null} - + ); }; diff --git a/src/components/MyButton.tsx b/src/components/MyButton.tsx index d5cb5f1..04f3381 100644 --- a/src/components/MyButton.tsx +++ b/src/components/MyButton.tsx @@ -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 ( - {text} - + ); } @@ -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} ); return ( - {type === 'primary' ? ( ) : ( )} - + ); } @@ -112,12 +124,12 @@ interface MyIconButtonProps { export function MyIconButton({onPress, MyIconProps}: MyIconButtonProps) { return ( - + - + ); } diff --git a/src/components/MyClickableText.tsx b/src/components/MyClickableText.tsx index 5706f80..e80d699 100644 --- a/src/components/MyClickableText.tsx +++ b/src/components/MyClickableText.tsx @@ -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; text: string; onPress?: () => void; + color?: string; } -export function MyClickableText({textStyle, text, onPress}: MyClickableTextProps) { +export function MyClickableText({textStyle, text, onPress, color}: MyClickableTextProps) { return ( - - {text} - + + {text} + ); } diff --git a/src/components/MyDivider.tsx b/src/components/MyDivider.tsx index b670fc0..742c608 100644 --- a/src/components/MyDivider.tsx +++ b/src/components/MyDivider.tsx @@ -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 ( diff --git a/src/components/MyInput.tsx b/src/components/MyInput.tsx index 1b0f032..25bf403 100644 --- a/src/components/MyInput.tsx +++ b/src/components/MyInput.tsx @@ -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({ }, ]}> - + - {text} + {text} ); } + +export interface ConfirmationCodeInputProps {} + +export const ConfirmationCodeInput: React.FC< + ConfirmationCodeInputProps +> = () => { + const [confirmationCode, setConfirmationCode] = useState([ + '', + '', + '', + '', + '', + '', + ]); + const inputRefs = useRef([]); + + 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 ( + + {confirmationCode.map((digit, index) => ( + (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} + /> + ))} + + ); +}; diff --git a/src/components/MyScreenContainer.tsx b/src/components/MyScreenContainer.tsx index e2d3a57..accf695 100644 --- a/src/components/MyScreenContainer.tsx +++ b/src/components/MyScreenContainer.tsx @@ -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 = { diff --git a/src/components/MyStatusBar.tsx b/src/components/MyStatusBar.tsx new file mode 100644 index 0000000..323361c --- /dev/null +++ b/src/components/MyStatusBar.tsx @@ -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 ( + + ); +} diff --git a/src/components/MyTitle.tsx b/src/components/MyTitle.tsx index 2eb5e57..9d60730 100644 --- a/src/components/MyTitle.tsx +++ b/src/components/MyTitle.tsx @@ -1,15 +1,21 @@ -import { Text } from "@gluestack-ui/themed"; +import {Text} from '@gluestack-ui/themed'; -export function MyTitle({text}: {text: string}) { - return ( - - {text} - - ); - } \ No newline at end of file +interface MyTitleProps { + text: string; + textAlign?: 'left' | 'center' | 'right'; + paddingBottom?: number; +} + +export function MyTitle({text, textAlign, paddingBottom}: MyTitleProps) { + return ( + + {text} + + ); +} diff --git a/src/components/MyTouchableOpacity.tsx b/src/components/MyTouchableOpacity.tsx new file mode 100644 index 0000000..81d8044 --- /dev/null +++ b/src/components/MyTouchableOpacity.tsx @@ -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; + 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 ( + + {children} + + ); +} diff --git a/src/configs/appNonSaveVar.ts b/src/configs/appNonSaveVar.ts index fd83c9b..39a7218 100644 --- a/src/configs/appNonSaveVar.ts +++ b/src/configs/appNonSaveVar.ts @@ -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, }; diff --git a/src/configs/appNonSaveVarReducer.ts b/src/configs/appNonSaveVarReducer.ts index d38897d..faf6617 100644 --- a/src/configs/appNonSaveVarReducer.ts +++ b/src/configs/appNonSaveVarReducer.ts @@ -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) => { state.appStatus = action.payload; }, - setThemeColors: (state, action: PayloadAction) => { - state.themeColors = action.payload; + setTheme: (state, action: PayloadAction) => { + state.theme = action.payload; }, }, }); diff --git a/src/configs/colors.ts b/src/configs/colors.ts index 88bfee3..faf1f40 100644 --- a/src/configs/colors.ts +++ b/src/configs/colors.ts @@ -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 { diff --git a/src/configs/gluestack-ui.config.ts b/src/configs/gluestack-ui.config.ts index 72ebbc1..423b7da 100644 --- a/src/configs/gluestack-ui.config.ts +++ b/src/configs/gluestack-ui.config.ts @@ -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', diff --git a/src/navigation/navigation.tsx b/src/navigation/navigation.tsx index 4cd9b9c..cad8d15 100644 --- a/src/navigation/navigation.tsx +++ b/src/navigation/navigation.tsx @@ -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; @@ -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 ( - - {isFocused && ( - {tabNames[index]} - )} + {isFocused && {tabNames[index]}} - + ); })} diff --git a/src/navigation/registration/registration.tsx b/src/navigation/registration/registration.tsx index c4dda51..476875b 100644 --- a/src/navigation/registration/registration.tsx +++ b/src/navigation/registration/registration.tsx @@ -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 ( state.appVariables.lang.registration, ); + const currentTheme = useSelector( + (state: RootState) => state.nonSaveVariables.theme.colors, + ); const navigation = useNavigation(); return ( @@ -188,25 +190,31 @@ function RegistrationPreview({type}: {type: 'login' | 'signup'}) { {type === 'signup' && ( - {`${lang.previewSignup.agreeToTerms} `} + {`${lang.previewSignup.agreeToTerms} `} OpenURL(Constants.REGISTRATION.TERMS_URL)} /> - , + , OpenURL(Constants.REGISTRATION.PRIVACY_POLICY_URL)} /> - {` ${lang.previewSignup.agreeToTermsAnd} `} + {` ${lang.previewSignup.agreeToTermsAnd} `} OpenURL(Constants.REGISTRATION.COOKIE_USE_URL)} /> - . + . )} @@ -214,12 +222,18 @@ function RegistrationPreview({type}: {type: 'login' | 'signup'}) { {type === 'login' ? ( {lang.previewLogin.dontHaveAccount} ) : ( - {lang.previewSignup.alreadyHaveAccount} + + {lang.previewSignup.alreadyHaveAccount} + )} { 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 ( <> @@ -244,297 +258,10 @@ function ContentContainer({children}: {children: React.ReactNode}) { ); } -function Login() { - const lang = useSelector( - (state: RootState) => state.appVariables.lang.registration, - ); - const navigation = useNavigation(); - - return ( - - - - - - - - - navigateToHome(navigation)} - /> - - - - ); -} - -function SignUpStepUsername() { - const lang = useSelector( - (state: RootState) => state.appVariables.lang.registration, - ); - const navigation = useNavigation(); - - return ( - - - - {lang.signUpStepUsername.description} - - - - - { - navigation.navigate('Registration', { - screen: 'SignUpStepPhoneNumber', - }); - }} - /> - - - - ); -} - -function SignUpStepPhoneNumber() { - const lang = useSelector( - (state: RootState) => state.appVariables.lang.registration, - ); - const navigation = useNavigation(); - - return ( - - - - - - - - { - navigation.navigate('Registration', { - screen: 'SignUpStepVerifyPhoneNumber', - }); - }} - /> - - - - ); -} - -interface ConfirmationCodeInputProps {} - -const ConfirmationCodeInput: React.FC = () => { - const [confirmationCode, setConfirmationCode] = useState([ - '', - '', - '', - '', - '', - '', - ]); - const inputRefs = useRef([]); - - 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 ( - - {confirmationCode.map((digit, index) => ( - (inputRefs.current[index] = ref!)} - style={styles.input} - keyboardType="number-pad" - maxLength={1} - onChangeText={text => handleTextChange(text, index)} - value={digit} - /> - ))} - - ); -}; - -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(); - - return ( - - - - {`${lang.signUpStepVerifyPhoneNumber.description} +49 15** ******43`} - - - - - { - navigation.navigate('Registration', { - screen: 'SignUpStepPassword', - }); - }} - /> - - - - - - - ); -} - -function SignUpStepPassword() { - const lang = useSelector( - (state: RootState) => state.appVariables.lang.registration, - ); - const navigation = useNavigation(); - - return ( - - - - {lang.signUpStepPassword.description} - - - - - - navigation.navigate('Registration', { - screen: 'SignUpStepAccountName', - }) - } - /> - - - - ); -} - -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(); - - return ( - - - - - {lang.signUpStepAccountName.description} - - - - - navigateToHome(navigation)} - /> - - - - - ); -} diff --git a/src/navigation/tabs/main/CalendarTab.tsx b/src/navigation/tabs/main/CalendarTab.tsx index 119f804..5a4d6b8 100644 --- a/src/navigation/tabs/main/CalendarTab.tsx +++ b/src/navigation/tabs/main/CalendarTab.tsx @@ -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(); @@ -31,6 +38,8 @@ function CalendarTab() { options={{ title: lang.tabName, headerShown: true, + headerShadowVisible: false, + headerStyle: headerStyle, }} component={CalendarScreen} /> diff --git a/src/navigation/tabs/main/ChatsTab.tsx b/src/navigation/tabs/main/ChatsTab.tsx index c6ea69a..ef0ff20 100644 --- a/src/navigation/tabs/main/ChatsTab.tsx +++ b/src/navigation/tabs/main/ChatsTab.tsx @@ -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 ( @@ -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 ( - Chats + Part of the next phase ); } diff --git a/src/navigation/tabs/main/MapTab.tsx b/src/navigation/tabs/main/MapTab.tsx index c6268f4..c5bcc0e 100644 --- a/src/navigation/tabs/main/MapTab.tsx +++ b/src/navigation/tabs/main/MapTab.tsx @@ -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(); 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 ( - Map + Jan dein Part ); } diff --git a/src/navigation/tabs/main/ProfileTab.tsx b/src/navigation/tabs/main/ProfileTab.tsx index d1cd1fb..2471880 100644 --- a/src/navigation/tabs/main/ProfileTab.tsx +++ b/src/navigation/tabs/main/ProfileTab.tsx @@ -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 ( @@ -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: () => ( 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 ( - +
{lang.appName} - +
diff --git a/src/pages/profile/help.tsx b/src/pages/profile/help.tsx index fb4ca9d..012f23c 100644 --- a/src/pages/profile/help.tsx +++ b/src/pages/profile/help.tsx @@ -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 ( - {title} - - {value} - + {value} ) : ( - - {title} - + {title} )}
- + ); } diff --git a/src/pages/profile/profile.tsx b/src/pages/profile/profile.tsx index 767bc71..2bb4c61 100644 --- a/src/pages/profile/profile.tsx +++ b/src/pages/profile/profile.tsx @@ -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 ( - + {value} {title} - + ); } @@ -161,14 +167,18 @@ interface SettingsItemContainerProps { } function SettingsItemContainer({children, title}: SettingsItemContainerProps) { + const currentTheme = useSelector( + (state: RootState) => state.nonSaveVariables.theme.colors, + ); + return ( - {title} + {title} @@ -187,7 +197,7 @@ interface SettingsItemProps { function SettingsItem({icon, title, value, onPress}: SettingsItemProps) { return ( - - + {value ? ( <> - {title} - - {value} - + {title} + {value} ) : ( - - {title} - + {title} )} - + ); } @@ -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(); // TODO: get username from current logged in user @@ -232,9 +241,13 @@ export function UpdateUsername() { navigation.setOptions({ headerRight: () => changed ? ( - navigation.goBack()}> - - + navigation.goBack()}> + + ) : ( <> ), @@ -251,15 +264,19 @@ export function UpdateUsername() { setNewUsername(text); }} /> - {lang.changeUsername.info} - {lang.changeUsername.info2} + {lang.changeUsername.info} + {lang.changeUsername.info2} ); } 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(); @@ -277,12 +294,12 @@ export function UpdatePassword() { navigation.setOptions({ headerRight: () => passwordChanged ? ( - navigation.navigate('Registration', {screen: 'LoginPreview'}) }> - - + + ) : ( <> ), @@ -294,7 +311,7 @@ export function UpdatePassword() { - - {lang.info} - - {lang.info2} + {lang.info} + {lang.info2} ); } diff --git a/src/pages/welcome/login/login.tsx b/src/pages/welcome/login/login.tsx new file mode 100644 index 0000000..62e4645 --- /dev/null +++ b/src/pages/welcome/login/login.tsx @@ -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(); + + const [username, setUsername] = useState(''); + const [password, setPassword] = useState(''); + + const loginEnabled = username.length > 0 && password.length > 0; + + return ( + + + + + + setUsername(text)} + /> + setPassword(text)} + /> + + navigateToHome(navigation)} + disabled={!loginEnabled} + /> + + + + ); + } \ No newline at end of file diff --git a/src/pages/welcome/signUp/signUp.tsx b/src/pages/welcome/signUp/signUp.tsx new file mode 100644 index 0000000..cd82b64 --- /dev/null +++ b/src/pages/welcome/signUp/signUp.tsx @@ -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 ( + <> + + {description && {description}} + + ); +} + +export function SignUpStepUsername() { + const lang = useSelector( + (state: RootState) => state.appVariables.lang.registration, + ); + const navigation = useNavigation(); + + return ( + + + + + <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> + ); +}