import React, { useCallback, useEffect, useRef, useState } from 'react'; import { View, Text, Image, TouchableOpacity, ScrollView, KeyboardAvoidingView, Platform, TouchableWithoutFeedback, Keyboard } from 'react-native'; import { Formik } from 'formik'; import * as yup from 'yup'; import { useNavigation } from '@react-navigation/native'; import { styles } from '../CreateEvent/styles'; import { ButtonVariants } from 'src/types/components'; import ImageView from 'better-react-native-image-viewing'; import { StoreType, storage } from 'src/storage'; import AddImgSvg from 'assets/icons/travels-screens/add-img.svg'; import { Button, CheckBox, Header, Input, PageWrapper, WarningModal } from 'src/components'; import { Colors } from 'src/theme'; import { getFontSize } from 'src/utils'; import { RichEditor, RichToolbar, actions } from 'react-native-pell-rich-editor'; import CalendarSvg from '../../../../../assets/icons/calendar.svg'; import RangeCalendar from 'src/components/Calendars/RangeCalendar'; import { usePostAddSharedTripMutation, usePostCancelEventMutation, usePostGetPhotosForRegionMutation, usePostSetFullMutation, usePostUpdateEventMutation, usePostUpdateSharedTripMutation } from '@api/events'; import { SheetManager } from 'react-native-actions-sheet'; import PhotosForRegionModal from '../Components/PhotosForRegionModal/PhotosForRegionModal'; import { API_HOST } from 'src/constants'; import AddMapPinModal from '../Components/AddMapPinModal'; import { NAVIGATION_PAGES } from 'src/types'; import TrashSvg from 'assets/icons/travels-screens/trash-solid.svg'; import { useGetRegionsWithFlagQuery } from '@api/regions'; const EventSchema = yup.object({ title: yup.string().required().min(3), start_date: yup.date().nullable().required(), end_date: yup.date().nullable().required(), tentative: yup.number().optional(), photo: yup.number().nullable().optional(), details: yup.string().required() }); const CreateSharedTripScreen = ({ route }: { route: any }) => { const eventId = route.params?.eventId; const eventData = route.params?.event; const token = (storage.get('token', StoreType.STRING) as string) ?? null; const navigation = useNavigation(); const scrollRef = useRef(null); const richText = useRef(null); const { mutateAsync: getPhotosForRegion } = usePostGetPhotosForRegionMutation(); const { mutateAsync: addSharedTrip } = usePostAddSharedTripMutation(); const { mutateAsync: updateEvent } = usePostUpdateSharedTripMutation(); const { mutateAsync: cancelEvent } = usePostCancelEventMutation(); const { mutateAsync: setFull } = usePostSetFullMutation(); const { data: regionslist } = useGetRegionsWithFlagQuery(true); const [isSubmitting, setIsSubmitting] = useState(false); const [calendarVisible, setCalendarVisible] = useState<'start_date' | 'end_date' | null>(null); const [isViewerVisible, setIsViewerVisible] = useState(false); const [photos, setPhotos] = useState([]); const [regions, setRegions] = useState(route.params?.regionsToSave ?? []); const [regionsError, setRegionsError] = useState(null); const [photosError, setPhotosError] = useState(null); useEffect(() => { if (route.params?.regionsToSave) { setRegions(route.params.regionsToSave); } }, [route.params?.regionsToSave]); useEffect(() => { if (regions && regions.length > 0) { handleGetPhotosForAllRegions(regions); } else { setPhotos([]); } }, [regions]); const handleGetPhotosForAllRegions = useCallback( async (regionsArray: any[]) => { if (!regionsArray || regionsArray.length === 0) { setPhotos([]); return; } const allPhotos: any[] = []; try { for (const region of regionsArray) { await getPhotosForRegion( { region_id: region.id }, { onSuccess: (res) => { if (res.photos && res.photos.length > 0) { allPhotos.push(...res.photos); } }, onError: (error) => { console.log(`Error loading photos for region ${region.id}:`, error); } } ); } setPhotos(allPhotos); } catch (error) { setPhotos([]); } }, [getPhotosForRegion, token] ); const initialData: any = { title: eventData?.title ?? '', start_date: eventData?.date_from ?? '', end_date: eventData?.date_to ?? '', tentative: eventData?.date_tentative ?? 0, photo: null, details: eventData?.details ?? '' }; const [modalInfo, setModalInfo] = useState({ visible: false, type: 'success', title: '', message: '', buttonTitle: 'OK', action: () => {} }); useEffect(() => { if (eventData && eventData.regions && regionslist && regionslist.data) { const parsedRegions = JSON.parse(eventData.regions); let regionsData: any = []; parsedRegions.forEach((region: any) => { const regionWithFlag = regionslist.data?.find((r: any) => r.id === +region); regionsData.push({ flag1: regionWithFlag?.flag ?? '', flag2: null, region_name: regionWithFlag?.name ?? '', id: regionWithFlag?.id ?? region.id }); }); setRegions(regionsData); } }, [eventData, regionslist]); const handleCancelTrip = () => { setModalInfo({ visible: true, type: 'delete', title: 'Cancel trip', buttonTitle: 'Cancel', message: `Are you sure you want to cancel this trip?`, action: () => { cancelEvent( { token, event_id: eventId }, { onSuccess: (res) => { navigation.navigate(NAVIGATION_PAGES.EVENTS as never); } } ); } }); }; const handleDeleteRegion = (regionId: number) => { regions && setRegions(regions.filter((region) => region.id !== regionId)); }; return (
{ if (regions.length === 0) { return; } if (photos.length > 0 && !values.photo) { return; } setIsSubmitting(true); const regionsToSave = regions.map((region) => region.id); const newTrip: any = { title: values.title, start_date: values.start_date, end_date: values.end_date, tentative: values.tentative, regions: regionsToSave, details: values.details }; if (values.photo) { newTrip.photo = values.photo; } if (eventId) { await updateEvent( { token, trip_id: eventId, trip: JSON.stringify(newTrip) }, { onSuccess: (res) => { setIsSubmitting(false); navigation.goBack(); }, onError: (err) => { setIsSubmitting(false); } } ); } else { await addSharedTrip( { token, trip: JSON.stringify(newTrip) }, { onSuccess: (res) => { setIsSubmitting(false); setModalInfo({ visible: true, type: 'success', title: 'Success', buttonTitle: 'OK', message: `Thank you for adding this new trip. It will undergo review soon. You'll be notified via email once it is approved.`, action: () => {} }); }, onError: (err) => { setIsSubmitting(false); } } ); } }} > {(props) => ( setCalendarVisible('start_date')} formikError={ props.touched.start_date && (props.errors.start_date as string) } icon={} /> setCalendarVisible('end_date')} formikError={props.touched.end_date && (props.errors.end_date as string)} icon={} /> { props.setFieldValue('tentative', props.values.tentative === 1 ? 0 : 1); }} style={styles.optionBtn} hitSlop={{ top: 10, bottom: 10, left: 10, right: 10 }} > Tentative dates { props.setFieldValue('tentative', props.values.tentative === 1 ? 0 : 1); }} value={props.values.tentative === 1} color={Colors.DARK_BLUE} /> NomadMania regions navigation.navigate( ...([ NAVIGATION_PAGES.ADD_REGIONS, { regionsParams: regions, editId: eventId, isSharedTrip: true } ] as never) ) } > Add Region {regions && regions.length ? ( {regions.map((region) => { const [name, ...rest] = region.region_name?.split(/ – | - /); const subname = rest?.join(' - '); return ( {region.flag2 && ( )} {name} {subname} handleDeleteRegion(region.id)} > ); })} ) : regionsError ? ( {regionsError} ) : ( No regions at the moment )} {regions && regions.length > 0 && photos.length > 0 ? ( SheetManager.show('photos-for-region-modal', { payload: { photos, selectPhoto: (photo: any) => { props.setFieldValue('photo', photo); setPhotosError(null); } } as any }) } formikError={props.touched.photo && (props.errors.photo as string)} icon={} /> ) : null} {props.values.photo ? ( setIsViewerVisible(true)} > ) : null} {photosError ? ( {photosError} ) : null} Details { scrollRef.current?.scrollTo({ y: 650, animated: true }); }} placeholder="Add trip details" initialContentHTML={props.values.details} onChange={props.handleChange('details')} editorStyle={{ contentCSSText: 'font-size: 14px; padding: 12px; color: #C8C8C8;', backgroundColor: Colors.FILL_LIGHT, color: Colors.DARK_BLUE }} style={[ { minHeight: 100, borderBottomLeftRadius: 4, borderBottomRightRadius: 4 }, props.touched.details && props.errors.details ? { borderBottomColor: Colors.RED, borderLeftColor: Colors.RED, borderRightColor: Colors.RED, borderWidth: 1, borderTopWidth: 0 } : {} ]} onBlur={() => props.handleBlur('details')} /> {props.touched.details && props.errors.details ? ( {props.errors.details as string} ) : null} {eventId ? ( ) : ( )} { startDate && props.handleChange(calendarVisible)(startDate.toString()); setCalendarVisible(null); }} allowRangeSelection={false} selectedDate={props.values[calendarVisible ?? 'start_date']} disablePastDates={true} /> index.toString()} imageIndex={0} visible={isViewerVisible} onRequestClose={() => setIsViewerVisible(false)} swipeToCloseEnabled={false} backgroundColor={Colors.DARK_BLUE} /> )} { if (modalInfo.type === 'success') { navigation.goBack(); setModalInfo({ ...modalInfo, visible: false }); } else { setModalInfo({ ...modalInfo, visible: false }); } }} title={modalInfo.title} /> ); }; export default CreateSharedTripScreen;