diff options
-rw-r--r-- | src/constants/constants.ts | 52 | ||||
-rw-r--r-- | src/screens/profile/AccountType.tsx | 70 | ||||
-rw-r--r-- | src/screens/profile/PrivacyScreen.tsx | 124 | ||||
-rw-r--r-- | src/screens/profile/SettingsCell.tsx | 113 | ||||
-rw-r--r-- | src/screens/profile/SettingsScreen.tsx | 158 | ||||
-rw-r--r-- | src/services/UserProfileService.ts | 7 |
6 files changed, 253 insertions, 271 deletions
diff --git a/src/constants/constants.ts b/src/constants/constants.ts index d24e352e..91029b3a 100644 --- a/src/constants/constants.ts +++ b/src/constants/constants.ts @@ -186,3 +186,55 @@ export const SP_WIDTH = 375; export const SP_HEIGHT = 812; export const SP_PAGE_SIZE = 5; + +export const SETTINGS_DATA = { + SettingsAndPrivacy: [ + { + title: 'ACCOUNT', + data: [ + { + title: 'Suggested People Profile', + preimage: require('../assets/images/tagg-logo.png'), + postimage: require('../assets/images/settings/white-arrow.png'), + }, + { + title: 'Privacy', + preimage: require('../assets/images/settings/settings-white.png'), + postimage: require('../assets/images/settings/white-arrow.png'), + }, + ], + }, + { + title: 'GENERAL', + data: [ + { + title: 'Terms of use', + preimage: require('../assets/images/settings/termsofuse.png'), + postimage: require('../assets/images/settings/white-arrow.png'), + }, + { + title: 'Privacy Policy', + preimage: require('../assets/images/settings/privacypolicy.png'), + postimage: require('../assets/images/settings/white-arrow.png'), + }, + ], + }, + ], + PrivacyScreen: [ + { + title: '', + data: [ + { + title: 'Account Type', + preimage: require('../assets/images/settings/lock-white.png'), + postimage: require('../assets/images/settings/white-arrow.png'), + }, + { + title: 'Blocked Accounts', + preimage: require('../assets/images/settings/blocked-white.png'), + postimage: require('../assets/images/settings/white-arrow.png'), + }, + ], + }, + ], +}; diff --git a/src/screens/profile/AccountType.tsx b/src/screens/profile/AccountType.tsx index e1e19389..8c700cef 100644 --- a/src/screens/profile/AccountType.tsx +++ b/src/screens/profile/AccountType.tsx @@ -1,5 +1,12 @@ import React, {useState} from 'react'; -import {StatusBar, StyleSheet, Switch, Text, View} from 'react-native'; +import { + ActivityIndicator, + StatusBar, + StyleSheet, + Switch, + Text, + View, +} from 'react-native'; import {SafeAreaView} from 'react-native-safe-area-context'; import {useDispatch, useSelector} from 'react-redux'; import {Background} from '../../components'; @@ -12,6 +19,7 @@ import {normalize} from '../../utils/layouts'; const AccountType: React.FC = () => { const [isPrivateAccount, setIsPrivateAccount] = useState(false); + const [isLoading, setIsLoading] = useState(false); const { user: {userId, username}, profile: {is_private} = NO_PROFILE, @@ -20,10 +28,17 @@ const AccountType: React.FC = () => { const dispatch = useDispatch(); const updateAccountVisibility = async () => { + setIsLoading(true); const isPrivate = !isPrivateAccount; setIsPrivateAccount(isPrivate); const token = await getTokenOrLogout(dispatch); - updateProfileVisibility(token, {userId, username}, isPrivate, dispatch); + await updateProfileVisibility( + token, + {userId, username}, + isPrivate, + dispatch, + ); + setIsLoading(false); }; const getAccountText = () => { @@ -35,24 +50,29 @@ const AccountType: React.FC = () => { <StatusBar barStyle="light-content" /> <Background gradientType={BackgroundGradientType.Light}> <SafeAreaView> - <View style={{marginLeft: 28, marginRight: 43, marginTop: '20%'}}> - <View style={{flexDirection: 'row', alignItems: 'center'}}> + <View style={styles.container}> + <View> <Text style={styles.title}>{getAccountText()}</Text> - <Switch - trackColor={{false: 'red', true: '#6EE7E7'}} - thumbColor={'white'} - ios_backgroundColor="transparent" - style={{ - position: 'absolute', - right: 0, - borderWidth: 2, - borderColor: 'white', - }} - value={is_private} - onValueChange={updateAccountVisibility}></Switch> + <View style={styles.switchContainerStyle}> + <ActivityIndicator + animating={isLoading} + size="small" + color="black" + /> + {!isLoading && ( + <Switch + trackColor={{false: 'red', true: '#6EE7E7'}} + thumbColor={'white'} + ios_backgroundColor="transparent" + style={styles.switchStyles} + value={is_private} + onValueChange={updateAccountVisibility} + /> + )} + </View> </View> - <View style={{marginTop: '40%'}}> + <View style={styles.detailContainerStyle}> <Text style={styles.detailTitleStyle}> Enabling a public account will: </Text> @@ -71,16 +91,20 @@ const AccountType: React.FC = () => { }; const styles = StyleSheet.create({ - container: { - flex: 1, - }, + container: {marginHorizontal: '8%', marginTop: '20%'}, title: { fontSize: normalize(18), fontWeight: '600', lineHeight: normalize(17.9), color: 'white', }, - + switchContainerStyle: { + flexDirection: 'row', + alignItems: 'center', + position: 'absolute', + right: 0, + }, + detailContainerStyle: {marginTop: '40%'}, detailTitleStyle: { fontSize: normalize(19), fontWeight: '700', @@ -93,6 +117,10 @@ const styles = StyleSheet.create({ lineHeight: normalize(16.71), color: 'white', }, + switchStyles: { + borderWidth: 2, + borderColor: 'white', + }, }); export default AccountType; diff --git a/src/screens/profile/PrivacyScreen.tsx b/src/screens/profile/PrivacyScreen.tsx index 37f042af..d91c7841 100644 --- a/src/screens/profile/PrivacyScreen.tsx +++ b/src/screens/profile/PrivacyScreen.tsx @@ -1,114 +1,40 @@ import {useNavigation} from '@react-navigation/core'; import React from 'react'; import { - Image, SectionList, StatusBar, StyleSheet, - Text, - TouchableOpacity, View, + SafeAreaView, } from 'react-native'; -import {SafeAreaView} from 'react-native-safe-area-context'; import {useSelector} from 'react-redux'; import {RootState} from 'src/store/rootReducer'; import {Background} from '../../components'; import {NO_PROFILE} from '../../store/initialStates'; import {BackgroundGradientType} from '../../types'; -import {normalize, SCREEN_WIDTH} from '../../utils/layouts'; - -const DATA = [ - { - title: '', - data: [ - { - title: 'Account Type', - preimage: require('../../assets/images/settings/lock-white.png'), - postimage: require('../../assets/images/settings/white-arrow.png'), - }, - { - title: 'Blocked Accounts', - preimage: require('../../assets/images/settings/blocked-white.png'), - postimage: require('../../assets/images/settings/white-arrow.png'), - }, - ], - }, -]; +import {normalize} from '../../utils/layouts'; +import SettingsCell from './SettingsCell'; +import {SETTINGS_DATA} from '../../constants/constants'; const PrivacyScreen: React.FC = () => { - const navigation = useNavigation(); const {profile: {is_private} = NO_PROFILE} = useSelector( (state: RootState) => state.user, ); - const getActions = (type: string) => { - switch (type) { - case 'Account Type': - navigateTo('AccountTypeScreen', {}); - break; - case 'Blocked Accounts': - navigateTo('Blocked Accounts', {}); - break; - default: - break; - } - }; - - const navigateTo = (screen: string, options: object) => { - navigation.navigate(screen, options); - }; - - const Item = ({ - title, - preimage, - postimage, - }: { - title: string; - preimage: number; - postimage: number; - }) => ( - <TouchableOpacity onPress={() => getActions(title)} style={styles.item}> - <Image - resizeMode={'cover'} - style={{width: SCREEN_WIDTH * 0.05, height: SCREEN_WIDTH * 0.05}} - source={preimage} - /> - <View style={{marginLeft: 40}}> - <Text style={styles.title}>{title}</Text> - </View> - <View style={[styles.item, {position: 'absolute', right: 0}]}> - {title === 'Account Type' && ( - <Text style={[styles.title, {color: '#C4C4C4', marginRight: 13}]}> - {is_private ? 'Private' : 'Public'} - </Text> - )} - <Image style={{width: 15, height: 15}} source={postimage} /> - </View> - </TouchableOpacity> - ); - return ( <> <StatusBar barStyle="light-content" /> <Background gradientType={BackgroundGradientType.Light}> <SafeAreaView> - <View style={{marginLeft: 28, marginRight: 43}}> + <View style={styles.container}> <SectionList - sections={DATA} + sections={SETTINGS_DATA.PrivacyScreen} keyExtractor={(item, index) => item.title + index} - renderItem={({item: {title, preimage, postimage}}) => { - return <Item {...{title, preimage, postimage}} />; - }} - renderSectionHeader={({section: {title}}) => { - if (title.length === 0) { - return null; - } - return ( - <View style={{marginTop: 46}}> - <Text style={styles.header}>{title}</Text> - </View> - ); - }} + renderItem={({item: {title, preimage, postimage}}) => ( + <SettingsCell + {...{title, preimage, postimage, isPrivate: is_private}} + /> + )} /> </View> </SafeAreaView> @@ -118,33 +44,7 @@ const PrivacyScreen: React.FC = () => { }; const styles = StyleSheet.create({ - container: { - flex: 1, - }, - item: { - marginTop: 36, - flexDirection: 'row', - justifyContent: 'flex-start', - alignItems: 'center', - }, - header: { - fontSize: normalize(18), - fontWeight: '600', - lineHeight: normalize(21.48), - color: '#E9E9E9', - }, - title: { - fontSize: normalize(15), - fontWeight: '600', - lineHeight: normalize(17.9), - color: 'white', - }, - logoutStyle: { - fontSize: normalize(20), - fontWeight: '600', - lineHeight: normalize(23.87), - color: 'white', - }, + container: {marginHorizontal: '8%', marginTop: '8%'}, }); export default PrivacyScreen; diff --git a/src/screens/profile/SettingsCell.tsx b/src/screens/profile/SettingsCell.tsx new file mode 100644 index 00000000..29dcc691 --- /dev/null +++ b/src/screens/profile/SettingsCell.tsx @@ -0,0 +1,113 @@ +import {useNavigation} from '@react-navigation/core'; +import React from 'react'; +import { + Alert, + Image, + StyleSheet, + Text, + TouchableOpacity, + View, +} from 'react-native'; +import {ERROR_ATTEMPT_EDIT_SP} from '../../constants/strings'; +import {normalize, SCREEN_WIDTH} from '../../utils/layouts'; + +type SettingsCellProps = { + title: string; + preimage: number; + postimage: number; + isPrivate?: boolean; + suggested_people_linked?: number; +}; + +const SettingsCell: React.FC<SettingsCellProps> = ({ + title, + preimage, + postimage, + isPrivate, + suggested_people_linked, +}) => { + const navigation = useNavigation(); + const goToUpdateSPProfile = () => { + if (suggested_people_linked === 0) { + Alert.alert(ERROR_ATTEMPT_EDIT_SP); + } else { + // Sending undefined for updatedSelectedBadges to mark that there was no update yet + navigateTo('UpdateSPPicture', { + editing: true, + }); + } + }; + const getActions = (type: string) => { + switch (type) { + case 'Account Type': + navigateTo('AccountTypeScreen', {}); + break; + case 'Blocked Accounts': + navigateTo('Blocked Accounts', {}); + break; + case 'Suggested People Profile': + goToUpdateSPProfile(); + break; + case 'Privacy': + navigateTo('PrivacyScreen', {}); + break; + case 'Terms of use': + //TODO: + break; + case 'Privacy Policy': + //TODO: + break; + default: + break; + } + }; + + const navigateTo = (screen: string, options: object) => { + navigation.navigate(screen, options); + }; + return ( + <TouchableOpacity + onPress={() => getActions(title)} + style={styles.itemStyles}> + <Image + resizeMode={'cover'} + style={styles.preImageStyles} + source={preimage} + /> + <View style={styles.titleContainerStyles}> + <Text style={styles.titleStyles}>{title}</Text> + </View> + <View style={[styles.itemStyles, styles.subItemStyles]}> + {title === 'Account Type' && ( + <Text style={[styles.titleStyles, styles.subtitleStyles]}> + {isPrivate ? 'Private' : 'Public'} + </Text> + )} + <Image style={styles.postImageStyles} source={postimage} /> + </View> + </TouchableOpacity> + ); +}; + +const styles = StyleSheet.create({ + container: {marginHorizontal: '8%'}, + itemStyles: { + marginTop: 36, + flexDirection: 'row', + justifyContent: 'flex-start', + alignItems: 'center', + }, + subItemStyles: {position: 'absolute', right: 0}, + preImageStyles: {width: SCREEN_WIDTH * 0.05, height: SCREEN_WIDTH * 0.05}, + postImageStyles: {width: 15, height: 15}, + titleContainerStyles: {marginLeft: '12%'}, + titleStyles: { + fontSize: normalize(15), + fontWeight: '600', + lineHeight: normalize(17.9), + color: 'white', + }, + subtitleStyles: {color: '#C4C4C4', marginRight: 13}, +}); + +export default SettingsCell; diff --git a/src/screens/profile/SettingsScreen.tsx b/src/screens/profile/SettingsScreen.tsx index f9d437d0..cb049a96 100644 --- a/src/screens/profile/SettingsScreen.tsx +++ b/src/screens/profile/SettingsScreen.tsx @@ -1,150 +1,50 @@ import React from 'react'; import { - Alert, - Image, SectionList, StatusBar, StyleSheet, Text, TouchableOpacity, + SafeAreaView, View, } from 'react-native'; -import {SafeAreaView} from 'react-native-safe-area-context'; -import {normalize, SCREEN_WIDTH} from '../../utils/layouts'; +import {useSelector} from 'react-redux'; +import {RootState} from 'src/store/rootReducer'; import {Background} from '../../components'; import {BackgroundGradientType} from '../../types'; -import {logout} from '../../store/actions'; -import {useDispatch, useSelector} from 'react-redux'; -import {useNavigation} from '@react-navigation/core'; -import {RootState} from 'src/store/rootReducer'; -import {ERROR_ATTEMPT_EDIT_SP} from '../../constants/strings'; - -const DATA = [ - { - title: 'ACCOUNT', - data: [ - { - title: 'Suggested People Profile', - preimage: require('../../assets/images/tagg-logo.png'), - postimage: require('../../assets/images/settings/white-arrow.png'), - }, - { - title: 'Privacy', - preimage: require('../../assets/images/settings/settings-white.png'), - postimage: require('../../assets/images/settings/white-arrow.png'), - }, - ], - }, - { - title: 'GENERAL', - data: [ - { - title: 'Terms of use', - preimage: require('../../assets/images/settings/termsofuse.png'), - postimage: require('../../assets/images/settings/white-arrow.png'), - }, - { - title: 'Privacy Policy', - preimage: require('../../assets/images/settings/privacypolicy.png'), - postimage: require('../../assets/images/settings/white-arrow.png'), - }, - ], - }, -]; +import {normalize} from '../../utils/layouts'; +import SettingsCell from './SettingsCell'; +import {SETTINGS_DATA} from '../../constants/constants'; const SettingsScreen: React.FC = () => { - const dispatch = useDispatch(); - const navigation = useNavigation(); const {suggested_people_linked} = useSelector( (state: RootState) => state.user.profile, ); - const goToUpdateSPProfile = () => { - if (suggested_people_linked === 0) { - Alert.alert(ERROR_ATTEMPT_EDIT_SP); - } else { - // Sending undefined for updatedSelectedBadges to mark that there was no update yet - navigateTo('UpdateSPPicture', { - editing: true, - }); - } - }; - - const navigateTo = (screen: string, options: object) => { - navigation.navigate(screen, options); - }; - - const getActions = (type: string) => { - switch (type) { - case 'Suggested People Profile': - goToUpdateSPProfile(); - break; - case 'Privacy': - navigateTo('PrivacyScreen', {}); - break; - case 'Terms of use': - //TODO: - break; - case 'Privacy Policy': - //TODO: - break; - default: - break; - } - }; - - const Item = ({ - title, - preimage, - postimage, - }: { - title: string; - preimage: number; - postimage: number; - }) => ( - <TouchableOpacity onPress={() => getActions(title)} style={styles.item}> - <Image - resizeMode={'cover'} - style={{width: SCREEN_WIDTH * 0.05, height: SCREEN_WIDTH * 0.05}} - source={preimage} - /> - <View style={{marginLeft: 40}}> - <Text style={styles.title}>{title}</Text> - </View> - <Image - style={{width: 15, height: 15, position: 'absolute', right: 0}} - source={postimage} - /> - </TouchableOpacity> - ); return ( <> <StatusBar barStyle="light-content" /> <Background gradientType={BackgroundGradientType.Light}> <SafeAreaView> - <View style={{marginLeft: 28, marginRight: 43}}> + <View style={styles.container}> <SectionList - sections={DATA} + sections={SETTINGS_DATA.SettingsAndPrivacy} keyExtractor={(item, index) => item.title + index} - renderItem={({item: {title, preimage, postimage}}) => { - return <Item {...{title, preimage, postimage}} />; - }} + renderItem={({item: {title, preimage, postimage}}) => ( + <SettingsCell + {...{title, preimage, postimage, suggested_people_linked}} + /> + )} renderSectionHeader={({section: {title}}) => ( - <View style={{marginTop: 46}}> - <Text style={styles.header}>{title}</Text> + <View style={styles.headerContainerStyles}> + <Text style={styles.headerTextStyles}>{title}</Text> </View> )} ListFooterComponent={() => ( <TouchableOpacity - style={{marginTop: '20%', marginLeft: '12%'}} - onPress={() => { - navigation.reset({ - index: 0, - routes: [{name: 'SuggestedPeople'}], - }); - dispatch(logout()); - }}> - <Text style={styles.logoutStyle}>Logout</Text> + style={styles.logoutContainerStyles} + onPress={() => {}}> + <Text style={styles.logoutTextStyles}>Logout</Text> </TouchableOpacity> )} /> @@ -156,28 +56,16 @@ const SettingsScreen: React.FC = () => { }; const styles = StyleSheet.create({ - container: { - flex: 1, - }, - item: { - marginTop: 36, - flexDirection: 'row', - justifyContent: 'flex-start', - alignItems: 'center', - }, - header: { + container: {marginHorizontal: '8%', marginTop: '8%'}, + headerContainerStyles: {marginTop: '14%'}, + headerTextStyles: { fontSize: normalize(18), fontWeight: '600', lineHeight: normalize(21.48), color: '#E9E9E9', }, - title: { - fontSize: normalize(15), - fontWeight: '600', - lineHeight: normalize(17.9), - color: 'white', - }, - logoutStyle: { + logoutContainerStyles: {marginTop: '20%', marginLeft: '12%'}, + logoutTextStyles: { fontSize: normalize(20), fontWeight: '600', lineHeight: normalize(23.87), diff --git a/src/services/UserProfileService.ts b/src/services/UserProfileService.ts index c1901be1..1ce1d0b5 100644 --- a/src/services/UserProfileService.ts +++ b/src/services/UserProfileService.ts @@ -92,11 +92,11 @@ export const updateProfileVisibility = async ( try { const url = EDIT_PROFILE_ENDPOINT + `${user.userId}/`; const request = new FormData(); - request.append('is_private', isPrivateAccount); + request.append('is_private', isPrivateAccount ? 'True' : 'False'); let response = await fetch(url, { method: 'PATCH', headers: { - 'Content-Type': 'application/json', + 'Content-Type': 'multipart/form-data', Authorization: 'Token ' + token, }, body: request, @@ -104,7 +104,7 @@ export const updateProfileVisibility = async ( const {status} = response; let data = await response.json(); if (status === 200) { - dispatch(loadUserData(user)); + await dispatch(loadUserData(user)); } else if (status >= 400) { Alert.alert( ERROR_PROFILE_UPDATE_SHORT, @@ -112,6 +112,7 @@ export const updateProfileVisibility = async ( ); } } catch (error) { + debugger; Alert.alert(ERROR_PROFILE_UPDATE_SHORT, ERROR_DOUBLE_CHECK_CONNECTION); return { name: 'Profile update error', |