diff options
Diffstat (limited to 'src/screens/onboarding/ProfileOnboarding.tsx')
| -rw-r--r-- | src/screens/onboarding/ProfileOnboarding.tsx | 256 |
1 files changed, 256 insertions, 0 deletions
diff --git a/src/screens/onboarding/ProfileOnboarding.tsx b/src/screens/onboarding/ProfileOnboarding.tsx new file mode 100644 index 00000000..191d62b2 --- /dev/null +++ b/src/screens/onboarding/ProfileOnboarding.tsx @@ -0,0 +1,256 @@ +import React from 'react'; +import {RouteProp} from '@react-navigation/native'; +import {StackNavigationProp} from '@react-navigation/stack'; +import { + Text, + StatusBar, + StyleSheet, + Image, + TouchableOpacity, + Alert, + View, +} from 'react-native'; +import {RootStackParamList} from '../../routes'; +import {Background} from '../../components'; +import ImagePicker from 'react-native-image-crop-picker'; +import {REGISTER_ENDPOINT} from '../../constants'; + +type ProfileOnboardingScreenRouteProp = RouteProp< + RootStackParamList, + 'ProfileOnboarding' +>; +type ProfileOnboardingScreenNavigationProp = StackNavigationProp< + RootStackParamList, + 'ProfileOnboarding' +>; +interface ProfileOnboardingProps { + route: ProfileOnboardingScreenRouteProp; + navigation: ProfileOnboardingScreenNavigationProp; +} + +/** + * Create profile screen for onboarding. + * @param navigation react-navigation navigation object + */ + +const ProfileOnboarding: React.FC<ProfileOnboardingProps> = ({route}) => { + const {userId, username} = route.params; + const [largePic, setLargePic] = React.useState(''); + const [smallPic, setSmallPic] = React.useState(''); + + /** + * Profile screen "Add Large Profile Pic Here" button + */ + const LargeProfilePic = () => ( + <TouchableOpacity + accessible={true} + accessibilityLabel="ADD LARGE PROFILE PIC HERE" + onPress={goToGalleryLargePic} + style={styles.largeProfile}> + {largePic ? ( + <Image + source={{uri: largePic}} + style={[styles.largeProfile, styles.profilePic]} + /> + ) : ( + <Text style={styles.largeProfileText}>ADD LARGE PROFILE PIC HERE</Text> + )} + </TouchableOpacity> + ); + + /** + * Profile screen "Add Smaller Profile Pic Here" button + */ + const SmallProfilePic = () => ( + <TouchableOpacity + accessible={true} + accessibilityLabel="ADD SMALLER PIC" + onPress={goToGallerySmallPic} + style={styles.smallProfile}> + {smallPic ? ( + <Image + source={{uri: smallPic}} + style={[styles.smallProfile, styles.profilePic]} + /> + ) : ( + <Text style={styles.smallProfileText}>ADD SMALLER PIC</Text> + )} + </TouchableOpacity> + ); + + /* + * Handles tap on add profile picture buttons by navigating to camera access + * and selecting a picture from gallery for large profile picture + */ + const goToGalleryLargePic = () => { + ImagePicker.openPicker({ + width: 580, + height: 580, + cropping: true, + cropperToolbarTitle: 'Large profile picture', + mediaType: 'photo', + }) + .then((picture) => { + if ('path' in picture) { + setLargePic(picture.path); + } + }) + .catch(() => {}); + }; + + /* + * Handles tap on add profile picture buttons by navigating to camera access + * and selecting a picture from gallery for small profile picture + */ + const goToGallerySmallPic = () => { + ImagePicker.openPicker({ + width: 580, + height: 580, + cropping: true, + cropperToolbarTitle: 'Small profile picture', + mediaType: 'photo', + cropperCircleOverlay: true, + }) + .then((picture) => { + if ('path' in picture) { + setSmallPic(picture.path); + } + }) + .catch(() => {}); + }; + + const handleSubmit = async () => { + const form = new FormData(); + if (largePic) { + form.append('largeProfilePicture', { + uri: largePic, + name: 'large_profile_pic.jpg', + type: 'image/jpg', + }); + } + if (smallPic) { + form.append('smallProfilePicture', { + uri: smallPic, + name: 'small_profile_pic.jpg', + type: 'image/jpg', + }); + } + const endpoint = REGISTER_ENDPOINT + `${userId}/`; + try { + let response = await fetch(endpoint, { + method: 'PATCH', + headers: { + 'Content-Type': 'multipart/form-data', + }, + body: form, + }); + let data = await response.json(); + let statusCode = response.status; + if (statusCode === 200) { + Alert.alert( + 'Profile successfully created! 🥳', + `Welcome to Tagg, ${username}!`, + ); + } else if (statusCode === 400) { + Alert.alert('Profile update failed. 😔', `${data}`); + } else { + Alert.alert( + 'Something went wrong! ðŸ˜', + "Would you believe me if I told you that I don't know what happened?", + ); + } + } catch (error) { + Alert.alert( + 'Profile creation failed 😓', + 'Please double-check your network connection and retry.', + ); + return { + name: 'Profile creation error', + description: error, + }; + } + }; + + return ( + <Background centered> + <StatusBar barStyle="light-content" /> + <LargeProfilePic /> + <SmallProfilePic /> + <View style={styles.dummyField}> + <Text>DUMMY WEBSITE</Text> + </View> + <View style={styles.dummyField}> + <Text>DUMMY BIO</Text> + </View> + <TouchableOpacity onPress={handleSubmit} style={styles.submitBtn}> + <Text style={styles.submitBtnLabel}>Let's start!</Text> + </TouchableOpacity> + </Background> + ); +}; + +const styles = StyleSheet.create({ + largeProfile: { + justifyContent: 'center', + alignItems: 'center', + padding: 15, + height: 230, + width: 230, + borderRadius: 23, + backgroundColor: '#fff', + marginRight: '6%', + }, + largeProfileText: { + textAlign: 'center', + fontSize: 14, + fontWeight: 'bold', + color: '#863FF9', + }, + smallProfile: { + justifyContent: 'center', + alignItems: 'center', + padding: 20, + height: 110, + width: 110, + borderRadius: 55, + backgroundColor: '#E1F0FF', + marginLeft: '45%', + bottom: '7%', + }, + smallProfileText: { + textAlign: 'center', + fontSize: 14, + fontWeight: 'bold', + color: '#806DF4', + }, + profilePic: { + marginRight: 0, + marginLeft: 0, + bottom: 0, + }, + dummyField: { + height: '10%', + width: '80%', + justifyContent: 'center', + alignItems: 'center', + borderColor: '#fff', + borderWidth: 1, + borderRadius: 8, + marginBottom: '10%', + }, + submitBtn: { + backgroundColor: '#8F01FF', + justifyContent: 'center', + alignItems: 'center', + width: 150, + height: 40, + borderRadius: 5, + }, + submitBtnLabel: { + fontSize: 16, + fontWeight: '500', + color: '#fff', + }, +}); + +export default ProfileOnboarding; |
