diff options
author | Ivan Chen <ivan@thetaggid.com> | 2021-02-20 12:12:04 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-02-20 12:12:04 -0500 |
commit | fbda685fe7eaa1acc5f80a4c748d4253da9e11e0 (patch) | |
tree | 2078369aa878324088e62b998de76e0a5e487819 /src | |
parent | f4d8c3058ac601b0652f28e4ac5e3a6360b7bbd7 (diff) | |
parent | 8357cea9e510c97ba8816cb6850541509c5d764e (diff) |
Merge pull request #253 from shravyaramesh/tma644-edit-suggested
Tma644 edit suggested
Diffstat (limited to 'src')
-rw-r--r-- | src/assets/ionicons/suggested-outline.svg | 1 | ||||
-rw-r--r-- | src/assets/ionicons/suggested-outlined.png | bin | 0 -> 178994 bytes | |||
-rw-r--r-- | src/components/common/GenericMoreInfoDrawer.tsx | 8 | ||||
-rw-r--r-- | src/components/profile/ProfileMoreInfoDrawer.tsx | 27 | ||||
-rw-r--r-- | src/constants/api.ts | 1 | ||||
-rw-r--r-- | src/constants/strings.ts | 1 | ||||
-rw-r--r-- | src/routes/main/MainStackNavigator.tsx | 3 | ||||
-rw-r--r-- | src/routes/main/MainStackScreen.tsx | 9 | ||||
-rw-r--r-- | src/routes/suggestedPeopleOnboarding/SuggestedPeopleOnboardingStackNavigator.tsx | 4 | ||||
-rw-r--r-- | src/routes/suggestedPeopleOnboarding/SuggestedPeopleOnboardingStackScreen.tsx | 1 | ||||
-rw-r--r-- | src/screens/suggestedPeopleOnboarding/SuggestedPeopleUploadPictureScreen.tsx | 41 | ||||
-rw-r--r-- | src/services/SuggestedPeopleService.ts | 32 | ||||
-rw-r--r-- | src/store/actions/user.ts | 4 | ||||
-rw-r--r-- | src/store/reducers/userReducer.ts | 3 | ||||
-rw-r--r-- | src/types/types.ts | 15 |
15 files changed, 134 insertions, 16 deletions
diff --git a/src/assets/ionicons/suggested-outline.svg b/src/assets/ionicons/suggested-outline.svg new file mode 100644 index 00000000..05a957f7 --- /dev/null +++ b/src/assets/ionicons/suggested-outline.svg @@ -0,0 +1 @@ +<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><defs><style>.cls-1{fill:none;stroke:#000;stroke-miterlimit:10;stroke-width:1.41px;}</style></defs><circle class="cls-1" cx="10" cy="10" r="9.18"/><path d="M16.7,10a6.71,6.71,0,0,1-.09,1.1,3.76,3.76,0,0,1-.9,2,2.84,2.84,0,0,1-3.06.6,2.15,2.15,0,0,1-1.32-1.39c-.15-.65.1-1.36-.16-2a1.29,1.29,0,1,0-2.33,1.08,1.34,1.34,0,0,0,1.78.54v1.69a2.89,2.89,0,0,1-2.91-4.6,3,3,0,0,1,3.2-1,3,3,0,0,1,2,2.69A2.62,2.62,0,0,0,13,12a1,1,0,0,0,1.39.09,3.09,3.09,0,0,0,.63-2.68,5.24,5.24,0,0,0-1.15-2.7,5.11,5.11,0,0,0-.45-.48,5.22,5.22,0,0,0-5-1.12A5.21,5.21,0,0,0,5,8.87a5.11,5.11,0,0,0,6.52,6v1.66a6.87,6.87,0,0,1-6.77-2.35A6.85,6.85,0,0,1,3.41,8.72,6.66,6.66,0,0,1,6.59,4.21a6.86,6.86,0,0,1,2.29-.84,6.85,6.85,0,0,1,5.85,1.87A6.89,6.89,0,0,1,16.7,10Z"/><path d="M10,5.4a1.11,1.11,0,1,0,1.11,1.11A1.11,1.11,0,0,0,10,5.4ZM10,7a.51.51,0,1,1,.51-.51A.51.51,0,0,1,10,7Z"/></svg>
\ No newline at end of file diff --git a/src/assets/ionicons/suggested-outlined.png b/src/assets/ionicons/suggested-outlined.png Binary files differnew file mode 100644 index 00000000..f0ab5297 --- /dev/null +++ b/src/assets/ionicons/suggested-outlined.png diff --git a/src/components/common/GenericMoreInfoDrawer.tsx b/src/components/common/GenericMoreInfoDrawer.tsx index a23d7736..ff32a464 100644 --- a/src/components/common/GenericMoreInfoDrawer.tsx +++ b/src/components/common/GenericMoreInfoDrawer.tsx @@ -11,7 +11,7 @@ import { import {useSafeAreaInsets} from 'react-native-safe-area-context'; import {BottomDrawer} from '.'; import {TAGG_LIGHT_BLUE} from '../../constants'; -import {SCREEN_HEIGHT, SCREEN_WIDTH} from '../../utils'; +import {normalize, SCREEN_HEIGHT, SCREEN_WIDTH} from '../../utils'; // conforms the JSX onPress attribute type type OnPressHandler = (event: GestureResponderEvent) => void; @@ -75,8 +75,10 @@ const styles = StyleSheet.create({ borderTopRightRadius: 20, }, panelButtonTitle: { - fontSize: 18, - fontWeight: 'bold', + fontSize: 17, + fontWeight: '600', + lineHeight: normalize(20), + letterSpacing: normalize(0.1), }, icon: { height: 25, diff --git a/src/components/profile/ProfileMoreInfoDrawer.tsx b/src/components/profile/ProfileMoreInfoDrawer.tsx index daa83eb3..90f5da48 100644 --- a/src/components/profile/ProfileMoreInfoDrawer.tsx +++ b/src/components/profile/ProfileMoreInfoDrawer.tsx @@ -1,10 +1,11 @@ import {useNavigation} from '@react-navigation/native'; import React from 'react'; -import {StyleSheet, TouchableOpacity} from 'react-native'; +import {Alert, Image, StyleSheet, TouchableOpacity} from 'react-native'; import {useSelector} from 'react-redux'; import MoreIcon from '../../assets/icons/more_horiz-24px.svg'; import PersonOutline from '../../assets/ionicons/person-outline.svg'; import {TAGG_DARK_BLUE, TAGG_LIGHT_BLUE} from '../../constants'; +import {ERROR_ATTEMPT_EDIT_SP} from '../../constants/strings'; import {RootState} from '../../store/rootreducer'; import {SCREEN_HEIGHT, SCREEN_WIDTH} from '../../utils'; import {GenericMoreInfoDrawer} from '../common'; @@ -25,6 +26,9 @@ const ProfileMoreInfoDrawer: React.FC<ProfileMoreInfoDrawerProps> = (props) => { user: {userId, username}, } = useSelector((state: RootState) => state.user); const isOwnProfile = !userXId || userXName === username; + const {suggested_people_linked} = useSelector( + (state: RootState) => state.user.profile, + ); const goToEditProfile = () => { navigation.push('EditProfile', { @@ -34,6 +38,15 @@ const ProfileMoreInfoDrawer: React.FC<ProfileMoreInfoDrawerProps> = (props) => { setIsOpen(false); }; + const goToUpdateSPProfile = () => { + if (suggested_people_linked === 0) { + Alert.alert(ERROR_ATTEMPT_EDIT_SP); + } else { + navigation.push('UpdateSPPicture'); + setIsOpen(false); + } + }; + const onBlockUnblock = () => { handleBlockUnblock(() => setIsOpen(false)); }; @@ -66,6 +79,14 @@ const ProfileMoreInfoDrawer: React.FC<ProfileMoreInfoDrawerProps> = (props) => { showIcons={true} textColor={'black'} buttons={[ + [ + 'Edit Suggested', + goToUpdateSPProfile, + <Image + source={require('../../assets/ionicons/suggested-outlined.png')} + style={styles.image} + />, + ], ['Edit Profile', goToEditProfile, <PersonOutline color="black" />], ]} /> @@ -109,6 +130,10 @@ const styles = StyleSheet.create({ right: '5%', zIndex: 1, }, + image: { + width: 25, + height: 25, + }, }); export default ProfileMoreInfoDrawer; diff --git a/src/constants/api.ts b/src/constants/api.ts index 215dadc0..6e2b28ec 100644 --- a/src/constants/api.ts +++ b/src/constants/api.ts @@ -35,6 +35,7 @@ export const COMMENT_THREAD_ENDPOINT: string = API_URL + 'reply/'; // Suggested People export const SP_UPDATE_PICTURE: string = API_URL + 'suggested_people/update_picture/'; +export const SP_BASE_ENDPOINT: string = API_URL + 'suggested_people/'; // Register as FCM device export const FCM_ENDPOINT: string = API_URL + 'fcm/'; diff --git a/src/constants/strings.ts b/src/constants/strings.ts index 0965bad0..5ae19e9c 100644 --- a/src/constants/strings.ts +++ b/src/constants/strings.ts @@ -4,6 +4,7 @@ // replace with: $1\t$3 export const ADD_COMMENT_TEXT = (username?: string) => username ? `Reply to ${username}` : 'Add a comment...' export const COMING_SOON_MSG = 'Creating more fun things for you, surprises coming soon 😉'; +export const ERROR_ATTEMPT_EDIT_SP = 'Can\'t let you do that yet! Please onboard Suggested People first!'; export const ERROR_AUTHENTICATION = 'An error occurred during authentication. Please login again!'; export const ERROR_CATEGORY_CREATION = 'There was a problem creating your categories. Please refresh and try again.'; export const ERROR_CATEGORY_UPDATE = 'There was a problem updating your categories. Please refresh and try again'; diff --git a/src/routes/main/MainStackNavigator.tsx b/src/routes/main/MainStackNavigator.tsx index 9771c1e6..901dd993 100644 --- a/src/routes/main/MainStackNavigator.tsx +++ b/src/routes/main/MainStackNavigator.tsx @@ -69,6 +69,9 @@ export type MainStackParams = { AnimatedTutorial: { screenType: ScreenType; }; + UpdateSPPicture: { + goTo: string; + }; }; export const MainStack = createStackNavigator<MainStackParams>(); diff --git a/src/routes/main/MainStackScreen.tsx b/src/routes/main/MainStackScreen.tsx index 0b762dff..aec860f2 100644 --- a/src/routes/main/MainStackScreen.tsx +++ b/src/routes/main/MainStackScreen.tsx @@ -21,6 +21,7 @@ import { SearchScreen, SocialMediaTaggs, SuggestedPeopleScreen, + SuggestedPeopleUploadPictureScreen, } from '../../screens'; import {ScreenType} from '../../types'; import {AvatarHeaderHeight, SCREEN_WIDTH} from '../../utils'; @@ -222,6 +223,14 @@ const MainStackScreen: React.FC<MainStackProps> = ({route}) => { ...headerBarOptions('white', 'Edit Profile'), }} /> + <MainStack.Screen + name="UpdateSPPicture" + component={SuggestedPeopleUploadPictureScreen} + initialParams={{goTo: 'Profile'}} + options={{ + ...headerBarOptions('white', ''), + }} + /> </MainStack.Navigator> ); }; diff --git a/src/routes/suggestedPeopleOnboarding/SuggestedPeopleOnboardingStackNavigator.tsx b/src/routes/suggestedPeopleOnboarding/SuggestedPeopleOnboardingStackNavigator.tsx index e957e48c..85249034 100644 --- a/src/routes/suggestedPeopleOnboarding/SuggestedPeopleOnboardingStackNavigator.tsx +++ b/src/routes/suggestedPeopleOnboarding/SuggestedPeopleOnboardingStackNavigator.tsx @@ -2,7 +2,9 @@ import {createStackNavigator} from '@react-navigation/stack'; export type SuggestedPeopleOnboardingStackParams = { WelcomeScreen: undefined; - UploadPicture: undefined; + UploadPicture: { + goTo: string; + }; }; export const SuggestedPeopleOnboardingStack = createStackNavigator<SuggestedPeopleOnboardingStackParams>(); diff --git a/src/routes/suggestedPeopleOnboarding/SuggestedPeopleOnboardingStackScreen.tsx b/src/routes/suggestedPeopleOnboarding/SuggestedPeopleOnboardingStackScreen.tsx index 970982c4..75764a15 100644 --- a/src/routes/suggestedPeopleOnboarding/SuggestedPeopleOnboardingStackScreen.tsx +++ b/src/routes/suggestedPeopleOnboarding/SuggestedPeopleOnboardingStackScreen.tsx @@ -25,6 +25,7 @@ const SuggestedPeopleOnboardingStackScreen: React.FC = () => { <SuggestedPeopleOnboardingStack.Screen name="UploadPicture" component={SuggestedPeopleUploadPictureScreen} + initialParams={{goTo: 'SP Preview'}} options={{ ...headerBarOptions('white', ''), }} diff --git a/src/screens/suggestedPeopleOnboarding/SuggestedPeopleUploadPictureScreen.tsx b/src/screens/suggestedPeopleOnboarding/SuggestedPeopleUploadPictureScreen.tsx index 1b30c72f..b49761a0 100644 --- a/src/screens/suggestedPeopleOnboarding/SuggestedPeopleUploadPictureScreen.tsx +++ b/src/screens/suggestedPeopleOnboarding/SuggestedPeopleUploadPictureScreen.tsx @@ -1,4 +1,5 @@ -import React, {useState} from 'react'; +import {useNavigation} from '@react-navigation/native'; +import React, {useEffect, useState} from 'react'; import { Alert, Image, @@ -10,19 +11,41 @@ import {Text} from 'react-native-animatable'; import {TouchableOpacity} from 'react-native-gesture-handler'; import ImagePicker from 'react-native-image-crop-picker'; import {SafeAreaView} from 'react-native-safe-area-context'; -import {useDispatch} from 'react-redux'; +import {useDispatch, useSelector} from 'react-redux'; import {TaggSquareButton} from '../../components'; import TaggLoadingIndicator from '../../components/common/TaggLoadingIndicator'; import {SP_HEIGHT, SP_WIDTH} from '../../constants'; -import {ERROR_UPLOAD} from '../../constants/strings'; -import {sendSuggestedPeoplePhoto} from '../../services'; +import {ERROR_UPLOAD, SUCCESS_PIC_UPLOAD} from '../../constants/strings'; +import { + getSuggestedPeopleProfile, + sendSuggestedPeoplePhoto, +} from '../../services'; import {uploadedSuggestedPeoplePhoto} from '../../store/actions'; +import {RootState} from '../../store/rootReducer'; import {normalize, SCREEN_HEIGHT, SCREEN_WIDTH} from '../../utils'; -const SuggestedPeopleUploadPictureScreen: React.FC = () => { +const SuggestedPeopleUploadPictureScreen: React.FC = ({route}) => { + const {goTo} = route.params; const [image, setImage] = useState<string | undefined>(undefined); const [loading, setLoading] = useState(false); const dispatch = useDispatch(); + const navigation = useNavigation(); + const {userId: loggedInUserId} = useSelector( + (state: RootState) => state.user.user, + ); + + useEffect(() => { + const loadData = async () => { + const response = await getSuggestedPeopleProfile(loggedInUserId); + if (response) { + setImage(response.suggested_people_url); + } + }; + // if we're in edit SP, attempt to load current sp image + if (goTo === 'Profile') { + loadData(); + } + }, []); const openImagePicker = () => { ImagePicker.openPicker({ @@ -58,6 +81,14 @@ const SuggestedPeopleUploadPictureScreen: React.FC = () => { } } setLoading(false); + + // Navigated back to Profile if user is editing their Suggested People Picture + if (goTo === 'Profile') { + navigation.goBack(); + setTimeout(() => { + Alert.alert(SUCCESS_PIC_UPLOAD); + }, 500); + } }; return ( diff --git a/src/services/SuggestedPeopleService.ts b/src/services/SuggestedPeopleService.ts index 7e43c3b6..525c68b1 100644 --- a/src/services/SuggestedPeopleService.ts +++ b/src/services/SuggestedPeopleService.ts @@ -1,13 +1,18 @@ import AsyncStorage from '@react-native-community/async-storage'; -import {EDIT_PROFILE_ENDPOINT, SP_UPDATE_PICTURE} from '../constants'; +import { + EDIT_PROFILE_ENDPOINT, + SP_BASE_ENDPOINT, + SP_UPDATE_PICTURE, +} from '../constants'; +import {SuggestedPeopleDataType} from '../types'; export const sendSuggestedPeopleLinked = async ( userId: string, - stage: number, + suggested_people_linked: number, ) => { try { const request = new FormData(); - request.append('suggested_people_linked', stage); + request.append('suggested_people_linked', suggested_people_linked); const endpoint = EDIT_PROFILE_ENDPOINT + `${userId}/`; const token = await AsyncStorage.getItem('token'); let response = await fetch(endpoint, { @@ -48,3 +53,24 @@ export const sendSuggestedPeoplePhoto = async (photoUri: string) => { return false; } }; + +export const getSuggestedPeopleProfile = async (userId: string) => { + try { + const token = await AsyncStorage.getItem('token'); + const response = await fetch(SP_BASE_ENDPOINT + userId + '/', { + method: 'GET', + headers: { + Authorization: 'Token ' + token, + }, + }); + if (response.status === 200) { + const data: SuggestedPeopleDataType = await response.json(); + return data; + } else { + return undefined; + } + } catch (error) { + console.log('Error retrieving SP info'); + return undefined; + } +}; diff --git a/src/store/actions/user.ts b/src/store/actions/user.ts index ef134dc5..3511dcf3 100644 --- a/src/store/actions/user.ts +++ b/src/store/actions/user.ts @@ -172,7 +172,7 @@ export const uploadedSuggestedPeoplePhoto = (): ThunkAction< try { dispatch({ type: setSuggestedPeopleLinked.type, - payload: {stage: 1}, + payload: {suggested_people_linked: 1}, }); } catch (error) { console.log(error); @@ -191,7 +191,7 @@ export const suggestedPeopleAnimatedTutorialFinished = ( // update store first, assume request is successful dispatch({ type: setSuggestedPeopleLinked.type, - payload: {stage: 2}, + payload: {suggested_people_linked: 2}, }); // need to tell the server that the stage is now 2 return await sendSuggestedPeopleLinked(userId, 2); diff --git a/src/store/reducers/userReducer.ts b/src/store/reducers/userReducer.ts index 5203fa3c..ea9294ec 100644 --- a/src/store/reducers/userReducer.ts +++ b/src/store/reducers/userReducer.ts @@ -47,7 +47,8 @@ const userDataSlice = createSlice({ }, setSuggestedPeopleLinked: (state, action) => { - state.profile.suggested_people_linked = action.payload.stage; + state.profile.suggested_people_linked = + action.payload.suggested_people_linked; }, setIsOnboardedUser: (state, action) => { diff --git a/src/types/types.ts b/src/types/types.ts index 3c17cfa4..8e9e8a60 100644 --- a/src/types/types.ts +++ b/src/types/types.ts @@ -222,3 +222,18 @@ export type TypeOfNotification = | 'MOM_3+' // notification_object is MomentType | 'MOM_FRIEND'; + +export type UniversityBadge = { + id: string; + name: string; + university: string; + category: string; +}; + +export type SuggestedPeopleDataType = { + user: ProfilePreviewType; + mutual_friends: ProfilePreviewType[]; + badges: UniversityBadge[]; + social_links: string[]; + suggested_people_url: string; +}; |