aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorIvan Chen <ivan@tagg.id>2021-03-12 18:22:52 -0500
committerGitHub <noreply@github.com>2021-03-12 18:22:52 -0500
commit813e9982bed74a9ccbc3b50b7e553ed1b456c93c (patch)
tree5a8d13256be83dd955d2a66a9dc9eebd26ee25c5 /src
parent8bb3a254e8971428274568acdc969e4df0777409 (diff)
parent82f0448edfee2d1803098085f6710ac1eb7dcb91 (diff)
Merge pull request #292 from IvanIFChen/tma694-edit-badges
[TMA-694] Edit Badges
Diffstat (limited to 'src')
-rw-r--r--src/assets/icons/front-arrow.svg1
-rw-r--r--src/components/common/TaggSquareButton.tsx11
-rw-r--r--src/components/profile/ProfileMoreInfoDrawer.tsx5
-rw-r--r--src/components/search/SearchCategories.tsx2
-rw-r--r--src/components/suggestedPeople/BadgesDropdown.tsx2
-rw-r--r--src/constants/api.ts5
-rw-r--r--src/constants/strings.ts4
-rw-r--r--src/routes/main/MainStackNavigator.tsx5
-rw-r--r--src/routes/main/MainStackScreen.tsx11
-rw-r--r--src/routes/suggestedPeopleOnboarding/SuggestedPeopleOnboardingStackNavigator.tsx10
-rw-r--r--src/routes/suggestedPeopleOnboarding/SuggestedPeopleOnboardingStackScreen.tsx3
-rw-r--r--src/screens/badge/BadgeItem.tsx55
-rw-r--r--src/screens/badge/BadgeSelection.tsx115
-rw-r--r--src/screens/onboarding/Login.tsx1
-rw-r--r--src/screens/onboarding/OnboardingStepTwo.tsx2
-rw-r--r--src/screens/suggestedPeopleOnboarding/SuggestedPeopleUploadPictureScreen.tsx131
-rw-r--r--src/services/SuggestedPeopleService.ts62
-rw-r--r--src/services/WaitlistUserService.tsx1
18 files changed, 307 insertions, 119 deletions
diff --git a/src/assets/icons/front-arrow.svg b/src/assets/icons/front-arrow.svg
new file mode 100644
index 00000000..7beeb83e
--- /dev/null
+++ b/src/assets/icons/front-arrow.svg
@@ -0,0 +1 @@
+<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 720 720"><defs><style>.cls-1{fill:none;stroke:#fff;stroke-linecap:round;stroke-linejoin:round;stroke-width:77.17px;}</style></defs><polyline class="cls-1" points="205.65 669.79 514.35 356.69 205.65 50.2"/></svg> \ No newline at end of file
diff --git a/src/components/common/TaggSquareButton.tsx b/src/components/common/TaggSquareButton.tsx
index 817a2690..1a1c33b3 100644
--- a/src/components/common/TaggSquareButton.tsx
+++ b/src/components/common/TaggSquareButton.tsx
@@ -9,14 +9,17 @@ import {
ViewStyle,
} from 'react-native';
import LinearGradient from 'react-native-linear-gradient';
-import {BACKGROUND_GRADIENT_MAP, TAGG_PURPLE} from '../../constants';
+import {
+ BACKGROUND_GRADIENT_MAP,
+ TAGG_LIGHT_BLUE,
+ TAGG_PURPLE,
+} from '../../constants';
import {normalize, SCREEN_WIDTH} from '../../utils';
-
interface TaggSquareButtonProps extends ViewProps {
onPress: (event: GestureResponderEvent) => void;
title: string;
buttonStyle: 'normal' | 'large' | 'gradient';
- buttonColor: 'purple' | 'white';
+ buttonColor: 'purple' | 'white' | 'blue';
labelColor: 'white' | 'blue';
style?: ViewStyle;
labelStyle?: TextStyle;
@@ -27,6 +30,8 @@ const TaggSquareButton: React.FC<TaggSquareButtonProps> = (props) => {
switch (props.buttonColor) {
case 'purple':
return {backgroundColor: TAGG_PURPLE};
+ case 'blue':
+ return {backgroundColor: TAGG_LIGHT_BLUE};
case 'white':
default:
return {backgroundColor: 'white'};
diff --git a/src/components/profile/ProfileMoreInfoDrawer.tsx b/src/components/profile/ProfileMoreInfoDrawer.tsx
index 90f5da48..2fec5cca 100644
--- a/src/components/profile/ProfileMoreInfoDrawer.tsx
+++ b/src/components/profile/ProfileMoreInfoDrawer.tsx
@@ -42,7 +42,10 @@ const ProfileMoreInfoDrawer: React.FC<ProfileMoreInfoDrawerProps> = (props) => {
if (suggested_people_linked === 0) {
Alert.alert(ERROR_ATTEMPT_EDIT_SP);
} else {
- navigation.push('UpdateSPPicture');
+ // Sending undefined for updatedSelectedBadges to mark that there was no update yet
+ navigation.push('UpdateSPPicture', {
+ editing: true,
+ });
setIsOpen(false);
}
};
diff --git a/src/components/search/SearchCategories.tsx b/src/components/search/SearchCategories.tsx
index a71befe6..4bae27c2 100644
--- a/src/components/search/SearchCategories.tsx
+++ b/src/components/search/SearchCategories.tsx
@@ -1,10 +1,10 @@
import {useNavigation} from '@react-navigation/native';
import React, {useEffect, useState} from 'react';
import {StyleSheet, View} from 'react-native';
-import {GradientBorderButton} from '..';
import {getSuggestedSearchBubbleSuggestions} from '../../services/ExploreService';
import {SearchCategoryType} from '../../types';
import {SCREEN_WIDTH} from '../../utils';
+import GradientBorderButton from '../common/GradientBorderButton';
interface SearchCategoriesProps {
darkStyle?: boolean;
diff --git a/src/components/suggestedPeople/BadgesDropdown.tsx b/src/components/suggestedPeople/BadgesDropdown.tsx
index 70c70e47..76e8e46f 100644
--- a/src/components/suggestedPeople/BadgesDropdown.tsx
+++ b/src/components/suggestedPeople/BadgesDropdown.tsx
@@ -71,7 +71,7 @@ const BadgesDropdown: React.FC<BadgesDropdownProps> = ({
<TouchableOpacity
activeOpacity={1}
onPress={() => {
- const updatedBadges = !displayBadges
+ const updatedBadges = !displayBadges;
setDisplayBadges(updatedBadges);
if (updatedBadges) {
animate();
diff --git a/src/constants/api.ts b/src/constants/api.ts
index 127ef432..34ef9a1c 100644
--- a/src/constants/api.ts
+++ b/src/constants/api.ts
@@ -33,12 +33,13 @@ export const DISCOVER_ENDPOINT: string = API_URL + 'discover/';
export const SEARCH_BUTTONS_ENDPOPINT: string = DISCOVER_ENDPOINT + 'search_buttons/';
export const WAITLIST_USER_ENDPOINT: string = API_URL + 'waitlist-user/';
export const COMMENT_THREAD_ENDPOINT: string = API_URL + 'reply/';
-export const ADD_USER_BADGES: string = API_URL + 'suggested_people/add_badges/';
// Suggested People
export const SP_USERS_ENDPOINT: string = API_URL + 'suggested_people/';
-export const SP_UPDATE_PICTURE_ENDPOINT: string = API_URL + 'suggested_people/update_picture/';
+export const SP_UPDATE_PICTURE_ENDPOINT: string = SP_USERS_ENDPOINT + 'update_picture/';
export const SP_MUTUAL_BADGE_HOLDERS_ENDPOINT: string = SP_USERS_ENDPOINT + 'get_mutual_badge_holders/';
+export const ADD_BADGES_ENDPOINT: string = SP_USERS_ENDPOINT + 'add_badges/';
+export const UPDATE_BADGES_ENDPOINT: string = SP_USERS_ENDPOINT + 'update_badges/';
// 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 93da6e59..f289cfc1 100644
--- a/src/constants/strings.ts
+++ b/src/constants/strings.ts
@@ -43,10 +43,11 @@ export const ERROR_TWILIO_SERVER_ERROR = 'mhm, looks like that is an invalid pho
export const ERROR_UNABLE_TO_FIND_PROFILE = 'We were unable to find this profile. Please check username and try again';
export const ERROR_UNABLE_TO_VIEW_PROFILE = 'Unable to view this profile';
export const ERROR_UPLOAD = 'An error occurred while uploading. Please try again!';
-export const ERROR_UPLOAD_BADGES = 'Unable to upload your badges. Please retry';
+export const ERROR_UPLOAD_BADGES = 'Unable to upload your badges. Please retry!';
export const ERROR_BADGES_EXCEED_LIMIT = 'You can\'t have more than 5 badges!';
export const ERROR_UPLOAD_LARGE_PROFILE_PIC = "Can't have the first image seen on the profile be blank, please upload a large picture";
export const ERROR_UPLOAD_MOMENT = 'Unable to upload moment. Please retry';
+export const ERROR_UPLOAD_SP_PHOTO = 'Unable to update suggested people photo. Please retry!';
export const ERROR_UPLOAD_SMALL_PROFILE_PIC = "Can't have a profile without a pic to represent you, please upload a small profile picture";
export const ERROR_VERIFICATION_FAILED_SHORT = 'Verification failed 😓';
export const MARKED_AS_MSG = (str: string) => `Marked as ${str}`;
@@ -57,6 +58,7 @@ export const SUCCESS_CATEGORY_DELETE = 'Category successfully deleted, but its m
export const SUCCESS_INVITATION_CODE = 'Perfect! You entered a valid invitation code, you are now able to login and explore Tagg!';
export const SUCCESS_LINK = (str: string) => `Successfully linked ${str} 🎉`;
export const SUCCESS_PIC_UPLOAD = 'Beautiful, the picture was uploaded successfully!';
+export const SUCCESS_BADGES_UPDATE = 'Badges updated successfully!'
export const SUCCESS_PWD_RESET = 'Your password was reset successfully!';
export const SUCCESS_VERIFICATION_CODE_SENT = 'New verification code sent! Check your phone messages for your code';
export const UP_TO_DATE = 'Up-to-Date!';
diff --git a/src/routes/main/MainStackNavigator.tsx b/src/routes/main/MainStackNavigator.tsx
index 8953cfe0..f7404f27 100644
--- a/src/routes/main/MainStackNavigator.tsx
+++ b/src/routes/main/MainStackNavigator.tsx
@@ -74,7 +74,10 @@ export type MainStackParams = {
screenType: ScreenType;
};
UpdateSPPicture: {
- goTo: string;
+ editing: boolean;
+ };
+ BadgeSelection: {
+ editing: boolean;
};
MutualBadgeHolders: {
badge_id: string;
diff --git a/src/routes/main/MainStackScreen.tsx b/src/routes/main/MainStackScreen.tsx
index cb232297..95d45d32 100644
--- a/src/routes/main/MainStackScreen.tsx
+++ b/src/routes/main/MainStackScreen.tsx
@@ -7,6 +7,7 @@ import {normalize} from 'react-native-elements';
import BackIcon from '../../assets/icons/back-arrow.svg';
import {
AnimatedTutorial,
+ BadgeSelection,
CaptionScreen,
CategorySelection,
CreateCustomCategory,
@@ -229,7 +230,15 @@ const MainStackScreen: React.FC<MainStackProps> = ({route}) => {
<MainStack.Screen
name="UpdateSPPicture"
component={SuggestedPeopleUploadPictureScreen}
- initialParams={{goTo: 'Profile'}}
+ initialParams={{editing: true}}
+ options={{
+ ...headerBarOptions('white', ''),
+ }}
+ />
+ <MainStack.Screen
+ name="BadgeSelection"
+ component={BadgeSelection}
+ initialParams={{editing: true}}
options={{
...headerBarOptions('white', ''),
}}
diff --git a/src/routes/suggestedPeopleOnboarding/SuggestedPeopleOnboardingStackNavigator.tsx b/src/routes/suggestedPeopleOnboarding/SuggestedPeopleOnboardingStackNavigator.tsx
index 63547acb..30a83200 100644
--- a/src/routes/suggestedPeopleOnboarding/SuggestedPeopleOnboardingStackNavigator.tsx
+++ b/src/routes/suggestedPeopleOnboarding/SuggestedPeopleOnboardingStackNavigator.tsx
@@ -3,11 +3,11 @@ import {createStackNavigator} from '@react-navigation/stack';
export type SuggestedPeopleOnboardingStackParams = {
WelcomeScreen: undefined;
UploadPicture: {
- goTo: string;
+ editing: boolean;
+ };
+ BadgeSelection: {
+ editing: boolean;
};
- BadgeSelection: undefined;
};
-export const SuggestedPeopleOnboardingStack = createStackNavigator<
- SuggestedPeopleOnboardingStackParams
->();
+export const SuggestedPeopleOnboardingStack = createStackNavigator<SuggestedPeopleOnboardingStackParams>();
diff --git a/src/routes/suggestedPeopleOnboarding/SuggestedPeopleOnboardingStackScreen.tsx b/src/routes/suggestedPeopleOnboarding/SuggestedPeopleOnboardingStackScreen.tsx
index d1a6e5e1..a02e8373 100644
--- a/src/routes/suggestedPeopleOnboarding/SuggestedPeopleOnboardingStackScreen.tsx
+++ b/src/routes/suggestedPeopleOnboarding/SuggestedPeopleOnboardingStackScreen.tsx
@@ -26,7 +26,7 @@ const SuggestedPeopleOnboardingStackScreen: React.FC = () => {
<SuggestedPeopleOnboardingStack.Screen
name="UploadPicture"
component={SuggestedPeopleUploadPictureScreen}
- initialParams={{goTo: 'SP Preview'}}
+ initialParams={{editing: false}}
options={{
...headerBarOptions('white', ''),
}}
@@ -34,6 +34,7 @@ const SuggestedPeopleOnboardingStackScreen: React.FC = () => {
<SuggestedPeopleOnboardingStack.Screen
name="BadgeSelection"
component={BadgeSelection}
+ initialParams={{editing: false}}
options={{
...headerBarOptions('white', ''),
}}
diff --git a/src/screens/badge/BadgeItem.tsx b/src/screens/badge/BadgeItem.tsx
index adf74026..3141e662 100644
--- a/src/screens/badge/BadgeItem.tsx
+++ b/src/screens/badge/BadgeItem.tsx
@@ -2,7 +2,11 @@ import React from 'react';
import {View, Text, StyleSheet, Image, ImageSourcePropType} from 'react-native';
import {SCREEN_WIDTH, normalize} from '../../utils';
import LinearGradient from 'react-native-linear-gradient';
-import {BADGE_GRADIENT_FIRST, BADGE_GRADIENT_REST} from '../../constants';
+import {
+ BACKGROUND_GRADIENT_MAP,
+ BADGE_GRADIENT_FIRST,
+ BADGE_GRADIENT_REST,
+} from '../../constants';
import {TouchableOpacity} from 'react-native-gesture-handler';
interface BadgeItemProps {
@@ -21,32 +25,45 @@ const BadgeItem: React.FC<BadgeItemProps> = ({
onSelection,
}) => {
return (
- <TouchableOpacity onPress={() => onSelection(title)}>
- <LinearGradient
- colors={index === 0 ? BADGE_GRADIENT_FIRST : BADGE_GRADIENT_REST}
- useAngle={true}
- angle={136.69}
- style={styles.item}>
- <View
- style={
- selected ? styles.selectedDetailContainer : styles.detailContainer
- }>
- <Image source={resourcePath} style={styles.imageStyles} />
- <View style={styles.textContainer}>
- <Text style={styles.title}>{title}</Text>
+ <LinearGradient
+ colors={
+ selected ? BACKGROUND_GRADIENT_MAP[0] : ['transparent', 'transparent']
+ }
+ useAngle={true}
+ angle={136.69}
+ style={styles.border}>
+ <TouchableOpacity
+ onPress={() => onSelection(title)}
+ style={{alignSelf: 'center', marginTop: 3}}>
+ <LinearGradient
+ colors={index === 0 ? BADGE_GRADIENT_FIRST : BADGE_GRADIENT_REST}
+ // BACKGROUND_GRADIENT_MAP
+ useAngle={true}
+ angle={136.69}
+ style={styles.item}>
+ <View style={styles.detailContainer}>
+ <Image source={resourcePath} style={styles.imageStyles} />
+ <View style={styles.textContainer}>
+ <Text style={styles.title}>{title}</Text>
+ </View>
</View>
- </View>
- </LinearGradient>
- </TouchableOpacity>
+ </LinearGradient>
+ </TouchableOpacity>
+ </LinearGradient>
);
};
const styles = StyleSheet.create({
+ border: {
+ width: SCREEN_WIDTH / 3 - 20 + 6,
+ height: 146,
+ marginLeft: 10,
+ marginBottom: 12,
+ borderRadius: 8,
+ },
item: {
width: SCREEN_WIDTH / 3 - 20,
height: 140,
- marginLeft: 15,
- marginBottom: 12,
borderRadius: 8,
},
detailContainer: {
diff --git a/src/screens/badge/BadgeSelection.tsx b/src/screens/badge/BadgeSelection.tsx
index f1cd000c..cbd7dd88 100644
--- a/src/screens/badge/BadgeSelection.tsx
+++ b/src/screens/badge/BadgeSelection.tsx
@@ -1,59 +1,92 @@
-import AsyncStorage from '@react-native-community/async-storage';
-import {StackNavigationProp} from '@react-navigation/stack';
+import {RouteProp} from '@react-navigation/core';
import React, {useEffect, useState} from 'react';
import {Alert, SafeAreaView, StatusBar, StyleSheet, View} from 'react-native';
import {Text} from 'react-native-animatable';
import {TouchableOpacity} from 'react-native-gesture-handler';
import LinearGradient from 'react-native-linear-gradient';
-import {useDispatch} from 'react-redux';
-import {ADD_USER_BADGES, BACKGROUND_GRADIENT_MAP} from '../../constants';
-import {BADGE_DATA} from '../../constants/badges';
+import {useDispatch, useSelector} from 'react-redux';
+import {MainStackParams} from '../../routes';
import {
- ERROR_BADGES_EXCEED_LIMIT,
- ERROR_UPLOAD_BADGES,
-} from '../../constants/strings';
+ addBadgesService,
+ getSuggestedPeopleProfile,
+ updateBadgesService,
+} from '../../services';
+import {BACKGROUND_GRADIENT_MAP} from '../../constants';
+import {BADGE_DATA} from '../../constants/badges';
+import {ERROR_BADGES_EXCEED_LIMIT} from '../../constants/strings';
import {suggestedPeopleBadgesFinished} from '../../store/actions';
import {BackgroundGradientType} from '../../types';
import {SCREEN_HEIGHT, StatusBarHeight} from '../../utils';
import BadgeList from './BadgeList';
import BadgeScreenHeader from './BadgeScreenHeader';
+import {useNavigation} from '@react-navigation/native';
+import {RootState} from '../../store/rootReducer';
/**
* Home Screen for displaying Tagg Badge Selections
**/
-type BadgeSelectionParamList = {
- BadgeList: any[];
-};
-
-type BadgeSelectionScreenNavigationProp = StackNavigationProp<
- BadgeSelectionParamList,
- 'BadgeList'
->;
+type BadgeSelectionRouteProp = RouteProp<MainStackParams, 'BadgeSelection'>;
type BadgeSelectionProps = {
- navigation: BadgeSelectionScreenNavigationProp;
+ route: BadgeSelectionRouteProp;
};
-const BadgeSelection: React.FC<BadgeSelectionProps> = ({navigation}) => {
- const [canSubmit, setCanSubmit] = useState(false);
+const BadgeSelection: React.FC<BadgeSelectionProps> = ({route}) => {
+ const {editing} = route.params;
+ const {userId: loggedInUserId} = useSelector(
+ (state: RootState) => state.user.user,
+ );
+ const [selectedBadges, setSelectedBadges] = useState<string[]>([]);
+ const dispatch = useDispatch();
+ const navigation = useNavigation();
+
+ // Loading badges data and extracting into a string []
+ useEffect(() => {
+ const loadData = async () => {
+ const response = await getSuggestedPeopleProfile(loggedInUserId);
+ if (response) {
+ const data = response.badges;
+ let extractedBadgeNames: string[] = [];
+ data.forEach((badge) => {
+ extractedBadgeNames.push(badge.name);
+ });
+ setSelectedBadges(extractedBadgeNames);
+ }
+ };
+ if (editing) {
+ loadData();
+ }
+ }, []);
+
navigation.setOptions({
headerRight: () => (
<TouchableOpacity
style={styles.rightButtonContainer}
- onPress={() => {
- if (canSubmit) {
- uploadUserSelection();
+ onPress={async () => {
+ if (editing) {
+ updateBadgesService(selectedBadges);
+ navigation.navigate('UpdateSPPicture', {
+ editing: true,
+ });
} else {
- dispatch(suggestedPeopleBadgesFinished());
+ if (selectedBadges.length !== 0) {
+ const success = await addBadgesService(selectedBadges);
+ if (success) {
+ dispatch(suggestedPeopleBadgesFinished());
+ }
+ } else {
+ dispatch(suggestedPeopleBadgesFinished());
+ }
}
}}>
- <Text style={styles.rightButton}>{canSubmit ? 'Done' : 'Skip'}</Text>
+ <Text style={styles.rightButton}>
+ {selectedBadges.length !== 0 || editing ? 'Done' : 'Skip'}
+ </Text>
</TouchableOpacity>
),
});
- const [selectedBadges, setSelectedBadges] = useState<string[]>([]);
const selectKey = (key: string) => {
if (selectedBadges.includes(key)) {
const selectedBadgesArray = [...selectedBadges];
@@ -63,36 +96,12 @@ const BadgeSelection: React.FC<BadgeSelectionProps> = ({navigation}) => {
}
setSelectedBadges(selectedBadgesArray);
} else {
- const selectedBadgesArray = [...selectedBadges, key];
- setSelectedBadges(selectedBadgesArray);
- }
- };
- const dispatch = useDispatch();
- useEffect(() => {
- setCanSubmit(selectedBadges.length !== 0);
- }, [selectedBadges]);
-
- const uploadUserSelection = async () => {
- try {
- const token = await AsyncStorage.getItem('token');
- const form = new FormData();
- form.append('badges', JSON.stringify(selectedBadges));
- const response = await fetch(ADD_USER_BADGES, {
- method: 'POST',
- headers: {
- 'Content-Type': 'multipart/form-data',
- Authorization: 'Token ' + token,
- },
- body: form,
- });
- if (response.status === 400) {
+ if (selectedBadges.length < 5) {
+ const selectedBadgesArray = [...selectedBadges, key];
+ setSelectedBadges(selectedBadgesArray);
+ } else {
Alert.alert(ERROR_BADGES_EXCEED_LIMIT);
- return;
}
- dispatch(suggestedPeopleBadgesFinished());
- } catch (error) {
- console.log(error);
- Alert.alert(ERROR_UPLOAD_BADGES);
}
};
diff --git a/src/screens/onboarding/Login.tsx b/src/screens/onboarding/Login.tsx
index 2ca4172b..cfa39dbd 100644
--- a/src/screens/onboarding/Login.tsx
+++ b/src/screens/onboarding/Login.tsx
@@ -165,7 +165,6 @@ const Login: React.FC<LoginProps> = ({navigation}: LoginProps) => {
userLogin(dispatch, {userId: data.UserID, username});
fcmService.sendFcmTokenToServer();
} catch (err) {
- console.log(data);
Alert.alert(ERROR_INVALID_LOGIN);
}
} else if (statusCode === 200 && !data.isOnboarded) {
diff --git a/src/screens/onboarding/OnboardingStepTwo.tsx b/src/screens/onboarding/OnboardingStepTwo.tsx
index de869c99..93342c3f 100644
--- a/src/screens/onboarding/OnboardingStepTwo.tsx
+++ b/src/screens/onboarding/OnboardingStepTwo.tsx
@@ -173,12 +173,10 @@ const OnboardingStepTwo: React.FC<OnboardingStepTwoProps> = ({
Alert.alert(ERROR_REGISTRATION(Object.values(data)));
break;
default:
- console.log('fooo');
Alert.alert(ERROR_SOMETHING_WENT_WRONG_REFRESH);
break;
}
} else {
- console.log('barrr');
Alert.alert(ERROR_SOMETHING_WENT_WRONG_REFRESH);
}
} else {
diff --git a/src/screens/suggestedPeopleOnboarding/SuggestedPeopleUploadPictureScreen.tsx b/src/screens/suggestedPeopleOnboarding/SuggestedPeopleUploadPictureScreen.tsx
index 92f862c4..87e22d9e 100644
--- a/src/screens/suggestedPeopleOnboarding/SuggestedPeopleUploadPictureScreen.tsx
+++ b/src/screens/suggestedPeopleOnboarding/SuggestedPeopleUploadPictureScreen.tsx
@@ -1,4 +1,4 @@
-import {useNavigation} from '@react-navigation/native';
+import {RouteProp, useNavigation} from '@react-navigation/native';
import React, {useEffect, useState} from 'react';
import {
Alert,
@@ -6,16 +6,23 @@ import {
ImageBackground,
StatusBar,
StyleSheet,
+ View,
} from 'react-native';
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, useSelector} from 'react-redux';
-import {TaggSquareButton} from '../../components';
+import {MainStackParams} from 'src/routes';
+import FrontArrow from '../../assets/icons/front-arrow.svg';
+import {TaggSquareButton, UniversityIcon} from '../../components';
import TaggLoadingIndicator from '../../components/common/TaggLoadingIndicator';
import {SP_HEIGHT, SP_WIDTH} from '../../constants';
-import {ERROR_UPLOAD, SUCCESS_PIC_UPLOAD} from '../../constants/strings';
+import {
+ ERROR_UPLOAD,
+ ERROR_UPLOAD_SP_PHOTO,
+ SUCCESS_PIC_UPLOAD,
+} from '../../constants/strings';
import {
getSuggestedPeopleProfile,
sendSuggestedPeoplePhoto,
@@ -24,9 +31,21 @@ import {uploadedSuggestedPeoplePhoto} from '../../store/actions';
import {RootState} from '../../store/rootReducer';
import {normalize, SCREEN_HEIGHT, SCREEN_WIDTH} from '../../utils';
-const SuggestedPeopleUploadPictureScreen: React.FC = ({route}) => {
- const {goTo} = route.params;
+type SuggestedPeopleUploadPictureScreenRouteProp = RouteProp<
+ MainStackParams,
+ 'UpdateSPPicture'
+>;
+
+type SuggestedPeopleUploadPictureScreenProps = {
+ route: SuggestedPeopleUploadPictureScreenRouteProp;
+};
+
+const SuggestedPeopleUploadPictureScreen: React.FC<SuggestedPeopleUploadPictureScreenProps> = ({
+ route,
+}) => {
+ const {editing} = route.params;
const [image, setImage] = useState<string | undefined>(undefined);
+ const [oldImage, setOldImage] = useState<string | undefined>(undefined);
const [loading, setLoading] = useState(false);
const dispatch = useDispatch();
const navigation = useNavigation();
@@ -39,10 +58,11 @@ const SuggestedPeopleUploadPictureScreen: React.FC = ({route}) => {
const response = await getSuggestedPeopleProfile(loggedInUserId);
if (response) {
setImage(response.suggested_people_url);
+ setOldImage(response.suggested_people_url);
}
};
// if we're in edit SP, attempt to load current sp image
- if (goTo === 'Profile') {
+ if (editing) {
loadData();
}
}, []);
@@ -71,27 +91,27 @@ const SuggestedPeopleUploadPictureScreen: React.FC = ({route}) => {
};
const uploadImage = async () => {
- setLoading(true);
- if (image) {
+ // Uploading image only if initially loaded image is not the same as the image being uploaded
+ if (image && oldImage !== image) {
+ setLoading(true);
const success = await sendSuggestedPeoplePhoto(image);
if (success) {
dispatch(uploadedSuggestedPeoplePhoto(image));
- if (goTo !== 'Profile') {
- navigation.push('BadgeSelection');
+ if (!editing) {
+ navigation.push('BadgeSelection', {editing: false});
}
} else {
Alert.alert(ERROR_UPLOAD);
}
+ setLoading(false);
+ // Navigated back to Profile if user is editing their Suggested People Picture
+ if (editing) {
+ setTimeout(() => {
+ Alert.alert(success ? SUCCESS_PIC_UPLOAD : ERROR_UPLOAD_SP_PHOTO);
+ }, 500);
+ }
}
- 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);
- }
+ navigation.goBack();
};
return (
@@ -99,9 +119,15 @@ const SuggestedPeopleUploadPictureScreen: React.FC = ({route}) => {
{loading && <TaggLoadingIndicator fullscreen />}
<StatusBar barStyle={'light-content'} />
<SafeAreaView style={styles.container}>
- <Text style={styles.title}>PHOTO</Text>
+ <Text style={editing ? styles.titleEditSuggested : styles.titlePHOTO}>
+ {editing ? 'Edit Suggested' : 'PHOTO'}
+ </Text>
{image ? (
- <Text style={styles.body}>Tap again to choose another photo</Text>
+ <Text style={styles.body}>
+ {editing
+ ? 'Tap to upload new photo'
+ : 'Tap again to choose another photo'}
+ </Text>
) : (
<Text style={styles.body}>
Upload a photo, this is what other users will see
@@ -110,7 +136,7 @@ const SuggestedPeopleUploadPictureScreen: React.FC = ({route}) => {
{image ? (
<TouchableOpacity onPress={openImagePicker}>
<ImageBackground
- source={{uri: image}}
+ source={{uri: image, cache: 'reload'}}
style={[styles.imageContainer, styles.overlay]}
borderRadius={30}>
<Image
@@ -132,12 +158,29 @@ const SuggestedPeopleUploadPictureScreen: React.FC = ({route}) => {
</ImageBackground>
</TouchableOpacity>
)}
+ {editing && (
+ <TouchableOpacity
+ onPress={() => {
+ navigation.push('BadgeSelection', {editing: true});
+ }}>
+ <View style={styles.editBadgesMainContainer}>
+ <View style={styles.editBadgesSubContainer}>
+ <UniversityIcon
+ university="brown"
+ imageStyle={{width: normalize(16), height: normalize(20)}}
+ />
+ <Text style={styles.editBadgesText}>Edit Badges</Text>
+ </View>
+ <FrontArrow style={styles.rightArrow} />
+ </View>
+ </TouchableOpacity>
+ )}
{image && (
<TaggSquareButton
onPress={uploadImage}
title={'Done'}
buttonStyle={'normal'}
- buttonColor={'purple'}
+ buttonColor={editing ? 'blue' : 'purple'}
labelColor={'white'}
style={styles.buttonStyle}
labelStyle={styles.buttonLabel}
@@ -155,20 +198,28 @@ const styles = StyleSheet.create({
backgroundColor: '#878787',
alignItems: 'center',
},
- title: {
+ titlePHOTO: {
marginTop: '5%',
fontSize: normalize(25),
lineHeight: normalize(30),
fontWeight: '600',
color: 'white',
},
+ titleEditSuggested: {
+ marginTop: '5%',
+ fontSize: normalize(19),
+ lineHeight: normalize(22.7),
+ letterSpacing: normalize(0.1),
+ fontWeight: '600',
+ color: 'white',
+ },
body: {
fontSize: normalize(15),
lineHeight: normalize(18),
textAlign: 'center',
fontWeight: '600',
color: 'white',
- marginTop: '5%',
+ marginTop: '2%',
width: SCREEN_WIDTH * 0.7,
},
buttonLabel: {
@@ -194,5 +245,35 @@ const styles = StyleSheet.create({
marginTop: '30%',
marginBottom: '10%',
},
+ rightButtonContainer: {marginRight: 24},
+ rightButton: {
+ color: '#FFFFFF',
+ fontWeight: 'bold',
+ fontSize: 15,
+ lineHeight: 18,
+ },
+ editBadgesMainContainer: {
+ height: 30,
+ flexDirection: 'row',
+ width: SCREEN_WIDTH * 0.6,
+ justifyContent: 'space-between',
+ alignItems: 'center',
+ marginBottom: '4%',
+ marginTop: '0.8%',
+ },
+ editBadgesSubContainer: {flexDirection: 'row', alignItems: 'center'},
+ editBadgesText: {
+ color: 'white',
+ fontWeight: '600',
+ fontSize: normalize(14),
+ lineHeight: normalize(16.71),
+ textAlign: 'left',
+ marginLeft: 18,
+ },
+ rightArrow: {
+ width: 20,
+ height: 20,
+ alignSelf: 'center',
+ },
});
export default SuggestedPeopleUploadPictureScreen;
diff --git a/src/services/SuggestedPeopleService.ts b/src/services/SuggestedPeopleService.ts
index d0032458..a65b91ef 100644
--- a/src/services/SuggestedPeopleService.ts
+++ b/src/services/SuggestedPeopleService.ts
@@ -1,11 +1,19 @@
import AsyncStorage from '@react-native-community/async-storage';
import {
+ ERROR_BADGES_EXCEED_LIMIT,
+ ERROR_UPLOAD_BADGES,
+ SUCCESS_BADGES_UPDATE,
+} from '../constants/strings';
+import {
+ ADD_BADGES_ENDPOINT,
EDIT_PROFILE_ENDPOINT,
SP_MUTUAL_BADGE_HOLDERS_ENDPOINT,
SP_UPDATE_PICTURE_ENDPOINT,
SP_USERS_ENDPOINT,
-} from '../constants';
+ UPDATE_BADGES_ENDPOINT,
+} from '../constants/api';
import {ProfilePreviewType, SuggestedPeopleDataType} from '../types';
+import { Alert } from 'react-native';
export const sendSuggestedPeopleLinked = async (
userId: string,
@@ -119,3 +127,55 @@ export const getMutualBadgeHolders = async () => {
return undefined;
}
};
+
+export const addBadgesService = async (selectedBadges: string[]) => {
+ try {
+ const token = await AsyncStorage.getItem('token');
+ const form = new FormData();
+ form.append('badges', JSON.stringify(selectedBadges));
+ const response = await fetch(ADD_BADGES_ENDPOINT, {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'multipart/form-data',
+ Authorization: 'Token ' + token,
+ },
+ body: form,
+ });
+ if (response.status === 400) {
+ Alert.alert(ERROR_BADGES_EXCEED_LIMIT);
+ return false;
+ }
+ return true;
+ } catch (error) {
+ console.log(error);
+ Alert.alert(ERROR_UPLOAD_BADGES);
+ return false;
+ }
+};
+
+export const updateBadgesService = async (selectedBadges: string[]) => {
+ try {
+ const token = await AsyncStorage.getItem('token');
+ const form = new FormData();
+ form.append('badges', JSON.stringify(selectedBadges));
+ const response = await fetch(UPDATE_BADGES_ENDPOINT, {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'multipart/form-data',
+ Authorization: 'Token ' + token,
+ },
+ body: form,
+ });
+ if (response.status === 400) {
+ Alert.alert(ERROR_BADGES_EXCEED_LIMIT);
+ return;
+ }
+ if (response.status === 200) {
+ Alert.alert(SUCCESS_BADGES_UPDATE);
+ return;
+ }
+ } catch (error) {
+ console.log(error);
+ Alert.alert(ERROR_UPLOAD_BADGES);
+ }
+};
diff --git a/src/services/WaitlistUserService.tsx b/src/services/WaitlistUserService.tsx
index 516affe3..f50b7f39 100644
--- a/src/services/WaitlistUserService.tsx
+++ b/src/services/WaitlistUserService.tsx
@@ -7,7 +7,6 @@ export const adduserToWaitlist: (
last_name: string,
) => Promise<boolean> = async (phone_number, first_name, last_name) => {
try {
- console.log(phone_number, first_name, last_name);
const response = await fetch(WAITLIST_USER_ENDPOINT, {
method: 'POST',
headers: {