diff options
Diffstat (limited to 'src/screens')
-rw-r--r-- | src/screens/badge/BadgeItem.tsx | 55 | ||||
-rw-r--r-- | src/screens/badge/BadgeSelection.tsx | 115 | ||||
-rw-r--r-- | src/screens/onboarding/Login.tsx | 1 | ||||
-rw-r--r-- | src/screens/onboarding/OnboardingStepTwo.tsx | 2 | ||||
-rw-r--r-- | src/screens/suggestedPeopleOnboarding/SuggestedPeopleUploadPictureScreen.tsx | 131 |
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; |