aboutsummaryrefslogtreecommitdiff
path: root/src/screens
diff options
context:
space:
mode:
Diffstat (limited to 'src/screens')
-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
5 files changed, 204 insertions, 100 deletions
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;