master
Netcup Gituser 2023-12-02 02:01:47 +01:00
parent 1c232e86b7
commit dbb5950426
15 changed files with 661 additions and 183 deletions

BIN
src/assets/profile.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 181 KiB

View File

@ -9,14 +9,15 @@ import {
ViewStyle, ViewStyle,
} from 'react-native'; } from 'react-native';
import LinearGradient from 'react-native-linear-gradient'; import LinearGradient from 'react-native-linear-gradient';
import {MyIcon} from './MyIcon';
interface MyIconButtonProps { interface MyImageButtonProps {
image: ImageSourcePropType; image: ImageSourcePropType;
imageStyle?: StyleProp<ImageStyle>; imageStyle?: StyleProp<ImageStyle>;
text: string; text: string;
} }
export function MyIconButton({image, imageStyle, text}: MyIconButtonProps) { export function MyImageButton({image, imageStyle, text}: MyImageButtonProps) {
return ( return (
<TouchableOpacity <TouchableOpacity
style={{ style={{
@ -90,3 +91,24 @@ export function MyButton({style, type, text, onPress}: MyButtonProps) {
</TouchableOpacity> </TouchableOpacity>
); );
} }
interface MyIconButtonProps {
onPress?: () => void;
MyIconProps: {
name: string;
color?: string;
size?: number;
};
}
export function MyIconButton({onPress, MyIconProps}: MyIconButtonProps) {
return (
<TouchableOpacity onPress={onPress}>
<MyIcon
name={MyIconProps.name}
size={MyIconProps.size}
color={MyIconProps.color}
/>
</TouchableOpacity>
);
}

View File

@ -17,3 +17,8 @@ export function MyDividerWithText({text}: MyDividerWithTextProps) {
</View> </View>
); );
} }
export function MyVerticalDivider(){
return <View style={{height: 44, marginTop: 2, backgroundColor: "#444444", width: 1}} />
}

View File

@ -6,17 +6,18 @@ interface MyIconInputProps {
iconName: string; iconName: string;
keyboardType?: KeyboardTypeOptions; keyboardType?: KeyboardTypeOptions;
secureTextEntry?: boolean | undefined; secureTextEntry?: boolean | undefined;
value?: string;
onChangeText?: (text: string) => void;
disableContainer?: boolean;
} }
export function MyIconInput({text, iconName, keyboardType, secureTextEntry}: MyIconInputProps) { export function MyIconInput({text, iconName, keyboardType, secureTextEntry, value, onChangeText, disableContainer}: MyIconInputProps) {
return ( return (
<View <View
style={{ style={[{
backgroundColor: '#26263f',
flexDirection: 'row', flexDirection: 'row',
alignItems: 'center', alignItems: 'center',
borderRadius: 10, }, !disableContainer && { backgroundColor: '#26263f', borderRadius: 10}]}>
}}>
<View style={{marginLeft: 12}}> <View style={{marginLeft: 12}}>
<MyIcon name={iconName} size={32} /> <MyIcon name={iconName} size={32} />
</View> </View>
@ -32,6 +33,9 @@ export function MyIconInput({text, iconName, keyboardType, secureTextEntry}: MyI
}} }}
keyboardType={keyboardType} keyboardType={keyboardType}
secureTextEntry={secureTextEntry} secureTextEntry={secureTextEntry}
value={value}
onChangeText={onChangeText}
/> />
</View> </View>
</View> </View>

View File

@ -1,13 +1,41 @@
import {ReactNode} from 'react'; import {ReactNode} from 'react';
import {StyleProp, View, ViewStyle} from 'react-native'; import {ScrollView, StyleProp, View, ViewStyle} from 'react-native';
interface MyScreenContainerProps { interface MyScreenContainerProps {
children: ReactNode; children: ReactNode;
style?: StyleProp<ViewStyle>; style?: StyleProp<ViewStyle>;
scrollView?: boolean;
} }
export function MyScreenContainer({children, style}: MyScreenContainerProps) { export function MyScreenContainer({
children,
style,
scrollView,
}: MyScreenContainerProps) {
const containerStyle = {
backgroundColor: '#212137',
flex: 1,
paddingLeft: 20,
paddingRight: 20,
}
const ScreenView = () => (
<View
style={[
style,
!scrollView && containerStyle,
]}>
{children}
</View>
);
if (scrollView) {
return ( return (
<View style={[style, {paddingLeft: 20, paddingRight: 20}]}>{children}</View> <ScrollView style={containerStyle}>
<ScreenView />
</ScrollView>
); );
} }
return <ScreenView />;
}

View File

@ -0,0 +1,16 @@
import { Text } from "react-native";
export function MyTitle({text}: {text: string}) {
return (
<Text
style={{
fontSize: 24,
fontWeight: 'bold',
textAlign: 'center',
color: '#fff',
padding: 20,
}}>
{text}
</Text>
);
}

View File

@ -83,6 +83,7 @@ function CustomTabBar(props: BottomTabBarProps) {
const {state, descriptors, navigation} = props; const {state, descriptors, navigation} = props;
return ( return (
<View style={{backgroundColor: '#212137'}}>
<View <View
style={{ style={{
flexDirection: 'row', flexDirection: 'row',
@ -151,9 +152,11 @@ function CustomTabBar(props: BottomTabBarProps) {
width: '100%', width: '100%',
alignItems: 'center', alignItems: 'center',
}}> }}>
<MyIcon name={tabBarIcons[index]} <MyIcon
name={tabBarIcons[index]}
color={isFocused ? '#fff' : '#ccc'} color={isFocused ? '#fff' : '#ccc'}
size={20} /> size={20}
/>
{isFocused && ( {isFocused && (
<Text style={{color: '#fff'}}>{label.toString()}</Text> <Text style={{color: '#fff'}}>{label.toString()}</Text>
)} )}
@ -162,6 +165,7 @@ function CustomTabBar(props: BottomTabBarProps) {
); );
})} })}
</View> </View>
</View>
); );
} }

View File

@ -6,20 +6,28 @@ import {
createNativeStackNavigator, createNativeStackNavigator,
NativeStackNavigationOptions, NativeStackNavigationOptions,
} from '@react-navigation/native-stack'; } from '@react-navigation/native-stack';
import {Image, StyleSheet, Text, TextInput, View} from 'react-native'; import {
Image,
ScrollView,
StyleSheet,
Text,
TextInput,
View,
} from 'react-native';
import GoogleLogo from '@assets/google-logo.png'; import GoogleLogo from '@assets/google-logo.png';
import AppleLogo from '@assets/apple-logo.png'; import AppleLogo from '@assets/apple-logo.png';
import Logo from '@assets/logo.png'; import Logo from '@assets/logo.png';
import {MyDividerWithText} from '@components/MyDivider'; import {MyDividerWithText} from '@components/MyDivider';
import {MyButton, MyIconButton} from '@components/MyButton'; import {MyButton, MyImageButton} from '@components/MyButton';
import {MyClickableText} from '@components/MyClickableText'; import {MyClickableText} from '@components/MyClickableText';
import {OpenURL} from '@helper/linking'; import {OpenURL} from '@helper/linking';
import {Constants} from '@utils/utils'; import {Constants} from '@utils/utils';
import {MyIconInput} from '@components/MyInput'; import {MyIconInput} from '@components/MyInput';
import {useRef, useState} from 'react'; import {useRef, useState} from 'react';
import {KeyboardAvoidingView} from 'react-native'; import {KeyboardAvoidingView} from 'react-native';
import {MyTitle} from '@components/MyTitle';
export type RegistrationStackNavigatorParamList = { export type RegistrationStackNavigatorParamList = {
SignUpPreview: undefined; SignUpPreview: undefined;
@ -107,13 +115,13 @@ function LoginPreview() {
function ThirdAuthButtons() { function ThirdAuthButtons() {
return ( return (
<> <>
<MyIconButton <MyImageButton
image={GoogleLogo} image={GoogleLogo}
imageStyle={{left: 2, height: 35, width: 35}} imageStyle={{left: 2, height: 35, width: 35}}
text="Continue with Google" text="Continue with Google"
/> />
<MyIconButton <MyImageButton
image={AppleLogo} image={AppleLogo}
imageStyle={{height: 40, width: 40}} imageStyle={{height: 40, width: 40}}
text="Continue with Apple" text="Continue with Apple"
@ -128,27 +136,20 @@ function RegistrationPreview({type}: {type: 'login' | 'signup'}) {
return ( return (
<MyScreenContainer <MyScreenContainer
style={{ style={{
flex: 1,
flexDirection: 'column', flexDirection: 'column',
backgroundColor: '#212137',
}}> }}>
<View style={{flex: 1, marginTop: 10, alignItems: 'center'}}> <View style={{flex: 1, marginTop: 10, alignItems: 'center'}}>
<Image source={Logo} style={{height: 60, width: 60}} /> <Image source={Logo} style={{height: 60, width: 60}} />
</View> </View>
<View style={{flex: 2, justifyContent: 'center'}}> <View style={{flex: 2, justifyContent: 'center'}}>
<Text <MyTitle
style={{ text={
fontSize: 24, type === 'login'
fontWeight: 'bold',
textAlign: 'center',
color: '#fff',
padding: 20,
}}>
{type === 'login'
? 'Time to get to know the next party' ? 'Time to get to know the next party'
: 'Find the next party near you'} : 'Find the next party near you'
</Text> }
/>
</View> </View>
<View <View
@ -234,33 +235,16 @@ function ContentContainer({children}: {children: React.ReactNode}) {
); );
} }
function Title({text}: {text: string}) {
return (
<Text
style={{
fontSize: 24,
fontWeight: 'bold',
textAlign: 'center',
color: '#fff',
padding: 20,
}}>
{text}
</Text>
);
}
function Login() { function Login() {
const navigation = useNavigation<RootScreenNavigationProp>(); const navigation = useNavigation<RootScreenNavigationProp>();
return ( return (
<MyScreenContainer <MyScreenContainer
style={{ style={{
flex: 1,
flexDirection: 'column', flexDirection: 'column',
backgroundColor: '#212137',
}}> }}>
<ContentContainer> <ContentContainer>
<Title text="Welcome back!" /> <MyTitle text="Welcome back!" />
<View style={{gap: 12}}> <View style={{gap: 12}}>
<MyIconInput text="PHONE NUMBER OR ACCOUNT NAME" iconName="person" /> <MyIconInput text="PHONE NUMBER OR ACCOUNT NAME" iconName="person" />
@ -286,12 +270,10 @@ function SignUpStepUsername() {
return ( return (
<MyScreenContainer <MyScreenContainer
style={{ style={{
flex: 1,
flexDirection: 'column', flexDirection: 'column',
backgroundColor: '#212137',
}}> }}>
<ContentContainer> <ContentContainer>
<Title text="Let's get started, what's your name?" /> <MyTitle text="Let's get started, what's your name?" />
<Text>The name will be displayed on your profil overview</Text> <Text>The name will be displayed on your profil overview</Text>
<View style={{gap: 12, marginTop: 20}}> <View style={{gap: 12, marginTop: 20}}>
@ -319,12 +301,10 @@ function SignUpStepPhoneNumber() {
return ( return (
<MyScreenContainer <MyScreenContainer
style={{ style={{
flex: 1,
flexDirection: 'column', flexDirection: 'column',
backgroundColor: '#212137',
}}> }}>
<ContentContainer> <ContentContainer>
<Title text="Create your account using your phone number" /> <MyTitle text="Create your account using your phone number" />
<View style={{gap: 12, marginTop: 20}}> <View style={{gap: 12, marginTop: 20}}>
<MyIconInput <MyIconInput
@ -421,12 +401,10 @@ function SignUpStepVerifyPhoneNumber() {
return ( return (
<MyScreenContainer <MyScreenContainer
style={{ style={{
flex: 1,
flexDirection: 'column', flexDirection: 'column',
backgroundColor: '#212137',
}}> }}>
<ContentContainer> <ContentContainer>
<Title text="We sent you a code" /> <MyTitle text="We sent you a code" />
<Text>Enter it below to verify +49 15** ******43 </Text> <Text>Enter it below to verify +49 15** ******43 </Text>
<KeyboardAvoidingView style={{gap: 12, marginTop: 20}}> <KeyboardAvoidingView style={{gap: 12, marginTop: 20}}>
@ -457,12 +435,10 @@ function SignUpStepPassword() {
return ( return (
<MyScreenContainer <MyScreenContainer
style={{ style={{
flex: 1,
flexDirection: 'column', flexDirection: 'column',
backgroundColor: '#212137',
}}> }}>
<ContentContainer> <ContentContainer>
<Title text="You'll need a password" /> <MyTitle text="You'll need a password" />
<Text>Make sure it's 8 characters or more</Text> <Text>Make sure it's 8 characters or more</Text>
<View style={{gap: 12, marginTop: 20}}> <View style={{gap: 12, marginTop: 20}}>
@ -490,12 +466,11 @@ function SignUpStepAccountName() {
return ( return (
<MyScreenContainer <MyScreenContainer
style={{ style={{
flex: 1,
flexDirection: 'column', flexDirection: 'column',
backgroundColor: '#212137',
}}> }}>
<ScrollView>
<ContentContainer> <ContentContainer>
<Title text="Next, create your account name" /> <MyTitle text="Next, create your account name" />
<Text> <Text>
Your account name is unique and is used for friends to find you. Your account name is unique and is used for friends to find you.
</Text> </Text>
@ -513,6 +488,7 @@ function SignUpStepAccountName() {
/> />
</View> </View>
</ContentContainer> </ContentContainer>
</ScrollView>
</MyScreenContainer> </MyScreenContainer>
); );
} }

View File

@ -1,3 +1,4 @@
import { MyScreenContainer } from '@components/MyScreenContainer';
import {Center} from '@gluestack-ui/themed/build/components/Center'; import {Center} from '@gluestack-ui/themed/build/components/Center';
import { import {
createNativeStackNavigator, createNativeStackNavigator,
@ -40,9 +41,9 @@ function CalendarTab() {
function CalendarScreen() { function CalendarScreen() {
return ( return (
<Center> <MyScreenContainer>
<Text>Calendar</Text> <Text>Calendar</Text>
</Center> </MyScreenContainer>
); );
} }

View File

@ -1,3 +1,4 @@
import { MyScreenContainer } from '@components/MyScreenContainer';
import {Center} from '@gluestack-ui/themed/build/components/Center'; import {Center} from '@gluestack-ui/themed/build/components/Center';
import {useNavigation} from '@react-navigation/native'; import {useNavigation} from '@react-navigation/native';
import { import {
@ -41,9 +42,9 @@ function ChatsTab() {
function ChatsScreen() { function ChatsScreen() {
return ( return (
<Center> <MyScreenContainer>
<Text>Chats</Text> <Text>Chats</Text>
</Center> </MyScreenContainer>
); );
} }

View File

@ -1,3 +1,4 @@
import { MyScreenContainer } from '@components/MyScreenContainer';
import {Center} from '@gluestack-ui/themed/build/components/Center'; import {Center} from '@gluestack-ui/themed/build/components/Center';
import { import {
createNativeStackNavigator, createNativeStackNavigator,
@ -39,9 +40,9 @@ function MapTab() {
function MapScreen() { function MapScreen() {
return ( return (
<Center> <MyScreenContainer>
<Text>Map</Text> <Text>Map</Text>
</Center> </MyScreenContainer>
); );
} }

View File

@ -4,14 +4,28 @@ import {
} from '@react-navigation/native-stack'; } from '@react-navigation/native-stack';
import {useSelector} from 'react-redux'; import {useSelector} from 'react-redux';
import {RootState} from '@redux/store'; import {RootState} from '@redux/store';
import {Box} from '@gluestack-ui/themed/build/components/Box'; import {MyIconButton} from '@components/MyButton';
import {ThemeMode} from '@configs/colors'; import {useNavigation} from '@react-navigation/native';
import {Text} from 'react-native'; import {
ProfileOverview,
ProfileSettings,
UpdatePassword,
UpdateUsername,
} from '@pages/profile/profile';
import {Help} from '@pages/profile/help';
import { About } from '@pages/profile/about';
export const ProfileTabName = 'Profile'; export const ProfileTabName = 'Profile';
export type ProfileStackNavigatorParamList = { export type ProfileStackNavigatorParamList = {
Overview: undefined; Overview: undefined;
Settings: undefined;
UpdateUsername: undefined;
UpdatePhoneNumber: undefined;
VerifyUpdatedPhoneNumber: undefined;
UpdatePassword: undefined;
Help: undefined;
About: undefined;
}; };
const ProfileStack = const ProfileStack =
@ -20,7 +34,8 @@ const ProfileStack =
export type ProfileScreenNavigationProp = export type ProfileScreenNavigationProp =
NativeStackNavigationProp<ProfileStackNavigatorParamList>; NativeStackNavigationProp<ProfileStackNavigatorParamList>;
function ProfileTab() { export default function ProfileTab() {
const navigation = useNavigation<ProfileScreenNavigationProp>();
const lang = useSelector((state: RootState) => state.appVariables.lang); const lang = useSelector((state: RootState) => state.appVariables.lang);
return ( return (
@ -31,33 +46,77 @@ function ProfileTab() {
animation: 'slide_from_left', animation: 'slide_from_left',
title: lang.navigation.home.profile, title: lang.navigation.home.profile,
headerShown: true, headerShown: true,
headerStyle: {backgroundColor: '#212137'},
headerTitle: '',
headerRight: () => (
<MyIconButton
MyIconProps={{name: 'settings', size: 24}}
onPress={() => navigation.navigate('Settings')}
/>
),
}} }}
component={ProfileScreen} component={ProfileOverview}
/>
<ProfileStack.Screen
name="Settings"
options={{
animation: 'slide_from_right',
title: 'Profile Settings',
headerShown: true,
headerStyle: {backgroundColor: '#212137'},
headerTitleAlign: 'center',
}}
component={ProfileSettings}
/>
<ProfileStack.Screen
name="UpdateUsername"
options={{
animation: 'slide_from_right',
title: 'Update Account Name',
headerShown: true,
headerStyle: {backgroundColor: '#212137'},
headerTitleAlign: 'center',
}}
component={UpdateUsername}
/>
<ProfileStack.Screen
name="UpdatePassword"
options={{
animation: 'slide_from_right',
title: 'Update Password',
headerShown: true,
headerStyle: {backgroundColor: '#212137'},
headerTitleAlign: 'center',
}}
component={UpdatePassword}
/>
<ProfileStack.Screen
name="Help"
options={{
animation: 'slide_from_right',
title: 'Help',
headerShown: true,
headerStyle: {backgroundColor: '#212137'},
headerTitleAlign: 'center',
}}
component={Help}
/>
<ProfileStack.Screen
name="About"
options={{
animation: 'slide_from_right',
title: 'About',
headerShown: true,
headerStyle: {backgroundColor: '#212137'},
headerTitleAlign: 'center',
}}
component={About}
/> />
</ProfileStack.Navigator> </ProfileStack.Navigator>
); );
} }
function ProfileScreen() {
const theme = useSelector(
(state: RootState) => state.appVariables.preferences.theme,
);
return (
<>
<Box
bg="blackBG.400"
{...(theme === ThemeMode.Darkest
? {borderBottomWidth: 1, borderColor: 'white.900'}
: {})}
style={{
width: '100%',
paddingVertical: 20,
borderBottomLeftRadius: 20,
}}>
<Text>Test</Text>
</Box>
</>
);
}
export default ProfileTab;

View File

@ -0,0 +1,17 @@
import {MyScreenContainer} from '@components/MyScreenContainer';
import {Item} from './help';
export function About() {
return (
<MyScreenContainer>
<Item icon="person" title="About your account" onPress={() => {}} />
<Item icon="privacy-tip" title="Privacy Policy" onPress={() => {}} />
<Item icon="description" title="Terms and Imprint" onPress={() => {}} />
<Item
icon="library-books"
title="Open source libraries"
onPress={() => {}}
/>
</MyScreenContainer>
);
}

View File

@ -0,0 +1,54 @@
import {MyIcon} from '@components/MyIcon';
import {MyScreenContainer} from '@components/MyScreenContainer';
import {View} from 'react-native';
import {Text, TouchableOpacity} from 'react-native';
export function Help() {
return (
<MyScreenContainer>
<Item icon="bug-report" title="Report a problem" onPress={() => {}} />
<Item icon="contact-support" title="Help Center" onPress={() => {}} />
</MyScreenContainer>
);
}
export interface ItemProps {
icon: string;
title: string;
value?: string;
onPress?: () => void;
}
export function Item({icon, title, value, onPress}: ItemProps) {
return (
<TouchableOpacity
style={{
flexDirection: 'row',
alignItems: 'center',
backgroundColor: '#26263f',
borderRadius: 10,
padding: 12,
marginTop: 12,
}}
disabled={!onPress}
onPress={onPress}>
<View style={{flexDirection: 'row', gap: 12, alignItems: 'center'}}>
<MyIcon name={icon} size={36} />
<View>
{value ? (
<>
<Text>{title}</Text>
<Text style={{color: '#fff', fontWeight: 'bold', fontSize: 16}}>
{value}
</Text>
</>
) : (
<Text style={{color: '#fff', fontWeight: 'bold', fontSize: 16}}>
{title}
</Text>
)}
</View>
</View>
</TouchableOpacity>
);
}

View File

@ -0,0 +1,290 @@
import {MyScreenContainer} from '@components/MyScreenContainer';
import {Image, ScrollView, TouchableOpacity} from 'react-native';
import {Text, View} from 'react-native';
import Avatar from '@assets/profile.png';
import {MyTitle} from '@components/MyTitle';
import {MyVerticalDivider} from '@components/MyDivider';
import {MyIcon} from '@components/MyIcon';
import {useNavigation} from '@react-navigation/native';
import {ProfileScreenNavigationProp} from '@navigation/tabs/main/ProfileTab';
import {MyIconInput} from '@components/MyInput';
import {useEffect, useState} from 'react';
import {RootScreenNavigationProp} from '@navigation/navigation';
function UserAvatar() {
return (
<Image
source={Avatar}
style={{height: 120, width: 120}}
borderRadius={100}
/>
);
}
export function ProfileOverview() {
return (
<MyScreenContainer
style={{
flexDirection: 'column',
alignItems: 'center',
paddingTop: 10,
}}>
<UserAvatar />
<MyTitle text="Max Mustermann" />
<View style={{flexDirection: 'row', gap: 12}}>
<Statistic title="FOLLOWER" value="400.3k" />
<MyVerticalDivider />
<Statistic title="FOLLOWING" value="40.3k" />
<MyVerticalDivider />
<Statistic title="VISITED" value="2k" />
</View>
</MyScreenContainer>
);
}
interface StatisticProps {
value: string;
title: string;
}
function Statistic({value, title}: StatisticProps) {
return (
<TouchableOpacity>
<View>
<Text
style={{
fontSize: 24,
fontWeight: 'bold',
color: '#931278',
textAlign: 'center',
}}>
{value}
</Text>
<Text
style={{
fontSize: 14,
fontWeight: 'bold',
color: '#ccc',
textAlign: 'center',
}}>
{title}
</Text>
</View>
</TouchableOpacity>
);
}
export function ProfileSettings() {
const navigation = useNavigation<ProfileScreenNavigationProp>();
return (
<ScrollView>
<MyScreenContainer
style={{
paddingTop: 10,
}}>
<View style={{alignItems: 'center'}}>
<UserAvatar />
</View>
<SettingsItemContainer title="ACCOUNT DATA">
<SettingsItem
icon="person"
title="ACCOUNT NAME"
value="max_mustermann"
/>
<SettingsItem
icon="person"
title="USERNAME"
value="Max Mustermann"
onPress={() => navigation.navigate('UpdateUsername')}
/>
<SettingsItem
icon="phone-iphone"
title="PHONE NUMBER"
value="+49 1510 21334143"
/>
</SettingsItemContainer>
<SettingsItemContainer title="CHANGE PASSWORD">
<SettingsItem
icon="lock"
title="PASSWORD"
value="Tap to change"
onPress={() => navigation.navigate('UpdatePassword')}
/>
</SettingsItemContainer>
<SettingsItemContainer title="MORE INFO">
<SettingsItem
icon="help"
title="Help"
onPress={() => navigation.navigate('Help')}
/>
<SettingsItem
icon="info"
title="About"
onPress={() => navigation.navigate('About')}
/>
<SettingsItem icon="logout" title="Logout" />
</SettingsItemContainer>
</MyScreenContainer>
</ScrollView>
);
}
interface SettingsItemContainerProps {
children: React.ReactNode;
title: string;
}
function SettingsItemContainer({children, title}: SettingsItemContainerProps) {
return (
<View style={{marginTop: 12}}>
<Text style={{fontSize: 12}}>{title}</Text>
<View
style={{
padding: 12,
borderRadius: 10,
backgroundColor: '#26263f',
marginTop: 4,
gap: 16,
}}>
{children}
</View>
</View>
);
}
interface SettingsItemProps {
icon: string;
title: string;
value?: string;
onPress?: () => void;
}
function SettingsItem({icon, title, value, onPress}: SettingsItemProps) {
return (
<TouchableOpacity
style={{
flexDirection: 'row',
alignItems: 'center',
}}
disabled={!onPress}
onPress={onPress}>
<View style={{flexDirection: 'row', gap: 12, alignItems: 'center'}}>
<MyIcon name={icon} size={36} />
<View>
{value ? (
<>
<Text>{title}</Text>
<Text style={{color: '#fff', fontWeight: 'bold', fontSize: 16}}>
{value}
</Text>
</>
) : (
<Text style={{color: '#fff', fontWeight: 'bold', fontSize: 16}}>
{title}
</Text>
)}
</View>
</View>
</TouchableOpacity>
);
}
export function UpdateUsername() {
// TODO: get username from current logged in user
const username = 'Max Mustermann';
const navigation = useNavigation<ProfileScreenNavigationProp>();
const [newUsername, setNewUsername] = useState(username);
useEffect(() => {
const changed = username === newUsername;
navigation.setOptions({
headerRight: () => (
<TouchableOpacity
onPress={() => navigation.goBack()}
disabled={changed}>
<MyIcon name="done" size={24} color={!changed ? '#fff' : '#ccc'} />
</TouchableOpacity>
),
});
}, [navigation, newUsername]);
return (
<MyScreenContainer style={{paddingTop: 20}}>
<MyIconInput
iconName="person"
text="USERNAME"
value={newUsername}
onChangeText={text => setNewUsername(text)}
/>
<Text style={{marginTop: 12}}>You can use a-z, 0-9 and underscores.</Text>
<Text>Minimum length is 5 characters.</Text>
</MyScreenContainer>
);
}
export function UpdatePassword() {
const navigation = useNavigation<RootScreenNavigationProp>();
useEffect(() => {
navigation.setOptions({
headerRight: () => (
<TouchableOpacity
onPress={() =>
navigation.navigate('Registration', {screen: 'LoginPreview'})
}>
<MyIcon name="done" size={24} color="#fff" />
</TouchableOpacity>
),
});
}, [navigation]);
return (
<MyScreenContainer style={{paddingTop: 20}} scrollView>
<View
style={{
borderRadius: 10,
backgroundColor: '#26263f',
marginTop: 4,
}}>
<MyIconInput
iconName="lock"
text="CURRENT PASSWORD"
secureTextEntry={true}
value="123456"
disableContainer
/>
<MyIconInput
iconName="lock"
text="NEW PASSWORD"
secureTextEntry={true}
value="123456"
disableContainer
/>
<MyIconInput
iconName="lock"
text="REPEAT NEW PASSWORD"
secureTextEntry={true}
value="123456"
disableContainer
/>
</View>
<Text style={{marginTop: 12}}>
You will be logged out after changing your password.
</Text>
</MyScreenContainer>
);
}