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, TaggDropDown, TaggInput, UniversitySelection, } from '../../components'; import {CLASS_YEAR_LIST, genderRegex, TAGG_PURPLE} from '../../constants'; import { ERROR_SELECT_BIRTHDAY, ERROR_SELECT_CLASS_YEAR, ERROR_SELECT_GENDER, ERROR_SELECT_UNIVERSITY, } from '../../constants/strings'; import {OnboardingStackParams} from '../../routes/onboarding'; import {patchEditProfile} from '../../services'; import {BackgroundGradientType, UniversityType} from '../../types'; import {normalize, SCREEN_HEIGHT, SCREEN_WIDTH} from '../../utils'; type ProfileInfoOnboardingRouteProp = RouteProp< OnboardingStackParams, 'ProfileInfoOnboarding' >; type ProfileInfoOnboardingNavigationProp = StackNavigationProp< OnboardingStackParams, 'ProfileInfoOnboarding' >; interface ProfileInfoOnboardingProps { route: ProfileInfoOnboardingRouteProp; navigation: ProfileInfoOnboardingNavigationProp; } type FormType = { smallPic: string; university: UniversityType; birthdate: string | undefined; gender: string; isValidGender: boolean; classYear: number; attemptedSubmit: boolean; }; const ProfileInfoOnboarding: React.FC = ({ route, navigation, }) => { const {userId} = route.params; const [form, setForm] = React.useState({ smallPic: '', university: UniversityType.Empty, birthdate: undefined, 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 = parseInt(value, 10); 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.classYear === -1) { Alert.alert(ERROR_SELECT_CLASS_YEAR); return; } if (form.university === UniversityType.Empty) { Alert.alert(ERROR_SELECT_UNIVERSITY); return; } if (!form.birthdate) { Alert.alert(ERROR_SELECT_BIRTHDAY); return; } if (form.gender === '') { Alert.alert(ERROR_SELECT_GENDER); return; } if (!form.attemptedSubmit) { setForm({ ...form, attemptedSubmit: true, }); } const request = new FormData(); if (form.smallPic) { request.append('smallProfilePicture', { uri: form.smallPic, name: 'small_profile_pic.jpg', type: 'image/jpg', }); } if (customGender) { if (form.isValidGender) { request.append('gender', form.gender); } else { setForm({...form, attemptedSubmit: false}); setTimeout(() => setForm({...form, attemptedSubmit: true})); return; } } else { if (form.isValidGender) { request.append('gender', form.gender); } } request.append('birthday', form.birthdate); request.append('university_class', form.classYear); request.append('university', form.university); patchEditProfile(request, userId) .then((_) => navigation.navigate('InvitationCodeVerification', route.params), ) .catch((error) => { Alert.alert(error); }); }; return ( { setForm({ ...form, university: selected, }); }} /> 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 ProfileInfoOnboarding;