import AsyncStorage from '@react-native-community/async-storage'; import {RouteProp} from '@react-navigation/native'; import {StackNavigationProp} from '@react-navigation/stack'; import moment from 'moment'; import React from 'react'; import { Alert, Image, StatusBar, StyleSheet, Text, TouchableOpacity, View, } from 'react-native'; import ImagePicker from 'react-native-image-crop-picker'; import Animated from 'react-native-reanimated'; import { Background, BirthDatePicker, RegistrationWizard, TaggDropDown, TaggInput, } from '../../components'; import { CLASS_YEAR_LIST, EDIT_PROFILE_ENDPOINT, genderRegex, TAGG_PURPLE, } from '../../constants'; import { ERROR_DOUBLE_CHECK_CONNECTION, ERROR_PROFILE_CREATION_SHORT, ERROR_SELECT_BIRTHDAY, ERROR_SELECT_CLASS_YEAR, ERROR_SELECT_GENDER, ERROR_SOMETHING_WENT_WRONG_REFRESH, ERROR_UPLOAD_SMALL_PROFILE_PIC, } from '../../constants/strings'; import {OnboardingStackParams} from '../../routes/onboarding'; import {BackgroundGradientType} from '../../types'; import {normalize, SCREEN_HEIGHT, SCREEN_WIDTH} from '../../utils'; type OnboardingStepThreeRouteProp = RouteProp< OnboardingStackParams, 'OnboardingStepThree' >; type OnboardingStepThreeNavigationProp = StackNavigationProp< OnboardingStackParams, 'OnboardingStepThree' >; interface OnboardingStepThreeProps { route: OnboardingStepThreeRouteProp; navigation: OnboardingStepThreeNavigationProp; } const OnboardingStepThree: React.FC = ({ route, navigation, }) => { const {userId, username} = route.params; let emptyDate: string | undefined; const [form, setForm] = React.useState({ smallPic: '', birthdate: emptyDate, gender: '', isValidGender: true, classYear: -1, attemptedSubmit: false, }); const [customGender, setCustomGender] = React.useState(false); const classYearList = CLASS_YEAR_LIST.map((value) => ({ label: value, value, })); /** * Profile screen "Add profile picture" button */ const SmallProfilePic = () => ( {form.smallPic ? ( ) : ( ADD PROFILE PICTURE )} ); const goToGallerySmallPic = () => { ImagePicker.openPicker({ smartAlbums: [ 'Favorites', 'RecentlyAdded', 'SelfPortraits', 'Screenshots', 'UserLibrary', ], width: 580, height: 580, cropping: true, cropperToolbarTitle: 'Select Profile Picture', mediaType: 'photo', cropperCircleOverlay: true, }).then((picture) => { if ('path' in picture) { setForm({ ...form, smallPic: picture.path, }); } }); }; const handleGenderUpdate = (gender: string) => { if (gender === 'custom') { setCustomGender(true); } else { setCustomGender(false); let isValidGender: boolean = true; setForm({ ...form, gender, isValidGender, }); } }; const handleClassYearUpdate = (value: string) => { const classYear = Number.parseInt(value); setForm({ ...form, classYear, }); }; const handleCustomGenderUpdate = (gender: string) => { let isValidGender: boolean = genderRegex.test(gender); gender = gender.replace(' ', '-'); setForm({ ...form, gender, isValidGender, }); }; const handleBirthdateUpdate = (birthdate: Date) => { setForm({ ...form, birthdate: birthdate && moment(birthdate).format('YYYY-MM-DD'), }); }; const handleSubmit = async () => { if (!form.smallPic) { Alert.alert(ERROR_UPLOAD_SMALL_PROFILE_PIC); return; } if (form.classYear === -1) { Alert.alert(ERROR_SELECT_CLASS_YEAR); return; } if (form.birthdate === emptyDate) { Alert.alert(ERROR_SELECT_BIRTHDAY); return; } if (form.gender === '') { Alert.alert(ERROR_SELECT_GENDER); return; } if (!form.attemptedSubmit) { setForm({ ...form, attemptedSubmit: true, }); } let invalidFields: boolean = false; const request = new FormData(); if (form.smallPic) { request.append('smallProfilePicture', { uri: form.smallPic, name: 'small_profile_pic.jpg', type: 'image/jpg', }); } if (form.birthdate) { request.append('birthday', form.birthdate); } if (customGender) { if (form.isValidGender) { request.append('gender', form.gender); } else { setForm({...form, attemptedSubmit: false}); setTimeout(() => setForm({...form, attemptedSubmit: true})); invalidFields = true; } } else { if (form.isValidGender) { request.append('gender', form.gender); } } if (form.classYear !== -1) { request.append('university_class', form.classYear); } if (invalidFields) { return; } const endpoint = EDIT_PROFILE_ENDPOINT + `${userId}/`; try { const token = await AsyncStorage.getItem('token'); let response = await fetch(endpoint, { method: 'PATCH', headers: { 'Content-Type': 'multipart/form-data', Authorization: 'Token ' + token, }, body: request, }); let statusCode = response.status; let data = await response.json(); if (statusCode === 200) { navigation.navigate('InvitationCodeVerification', { userId: route.params.userId, username: username, }); } else if (statusCode === 400) { Alert.alert( 'Profile update failed. 😔', data.error || 'Something went wrong! 😭', ); } else { Alert.alert(ERROR_SOMETHING_WENT_WRONG_REFRESH); } } catch (error) { Alert.alert(ERROR_PROFILE_CREATION_SHORT, ERROR_DOUBLE_CHECK_CONNECTION); return { name: 'Profile creation error', description: error, }; } }; return ( handleClassYearUpdate(value)} items={classYearList} placeholder={{ label: 'Class Year', value: null, color: '#ddd', }} /> {customGender && ( handleSubmit()} valid={form.isValidGender} attemptedSubmit={form.attemptedSubmit} invalidWarning={ 'Custom field can only contain letters and hyphens' } width={280} /> )} handleGenderUpdate(value)} items={[ {label: 'Male', value: 'male'}, {label: 'Female', value: 'female'}, {label: 'Custom', value: 'custom'}, ]} placeholder={{ label: 'Gender', value: null, color: '#ddd', }} /> Let's start! ); }; const styles = StyleSheet.create({ container: { flex: 1, alignItems: 'center', justifyContent: 'center', height: SCREEN_HEIGHT, }, profile: { marginTop: '10%', marginBottom: '5%', }, contentContainer: { position: 'relative', width: 280, }, smallProfileUploader: { justifyContent: 'center', alignItems: 'center', padding: 20, backgroundColor: '#E1F0FF', height: normalize(150), width: normalize(150), borderRadius: normalize(150), }, smallProfileText: { textAlign: 'center', fontSize: 14, fontWeight: 'bold', color: '#806DF4', }, smallProfilePic: { height: normalize(150), width: normalize(150), borderRadius: normalize(150), borderWidth: 2, borderColor: 'white', }, submitBtn: { backgroundColor: TAGG_PURPLE, justifyContent: 'center', alignItems: 'center', width: SCREEN_WIDTH / 2.5, height: SCREEN_WIDTH / 10, borderRadius: 5, marginTop: '5%', alignSelf: 'center', }, submitBtnLabel: { fontSize: 16, fontWeight: '500', color: '#fff', }, goBack: { textDecorationLine: 'underline', color: '#fff', fontSize: 15, fontWeight: '600', }, footer: { marginTop: '3%', alignItems: 'center', justifyContent: 'space-around', height: SCREEN_HEIGHT * 0.15, }, wizard: { position: 'absolute', top: SCREEN_HEIGHT * 0.1, }, purplePlus: { position: 'absolute', height: normalize(40), width: normalize(40), bottom: 0, right: 0, }, }); export default OnboardingStepThree;