import React, { useEffect, useState, useRef } from 'react'; import { View, Text, TouchableOpacity, ScrollView } from 'react-native'; import ReactModal from 'react-native-modal'; import { useNavigation } from '@react-navigation/native'; import { Picker as WheelPicker } from 'react-native-wheel-pick'; import moment from 'moment'; import ActionSheet from 'react-native-actions-sheet'; import { PageWrapper, Header, Input, WarningModal } from 'src/components'; import RegionItem from '../Components/RegionItem'; import RangeCalendar from 'src/components/Calendars/RangeCalendar'; import { StoreType, storage } from 'src/storage'; import { Colors } from 'src/theme'; import { NAVIGATION_PAGES } from 'src/types'; import { RegionAddData } from '../utils/types'; import { useGetTripQuery, usePostDeleteTripMutation, usePostUpdateTripMutation, usePostSetNewTripMutation } from '@api/trips'; import { qualityOptions } from '../utils/constants'; import { styles } from './styles'; import CalendarSvg from '../../../../../assets/icons/calendar.svg'; interface DateValue { year: number | null; month: number | null; day: number | null; } interface RegionWithDates extends RegionAddData { visitStartDate?: DateValue | null; visitEndDate?: DateValue | null; year_from?: number; year_to?: number; month_from?: number; month_to?: number; day_from?: number | null; day_to?: number | null; } interface DatePickerState { regionId: number; field: 'visitStartDate' | 'visitEndDate'; } const AddNewTripScreen = ({ route }: { route: any }) => { const editTripId = route.params?.editTripId ?? null; const token = storage.get('token', StoreType.STRING) as string; const { data: editData } = useGetTripQuery(token, editTripId, Boolean(editTripId)); const navigation = useNavigation(); const [calendarVisible, setCalendarVisible] = useState(false); const [selectedDates, setSelectedDates] = useState(null); const [description, setDescription] = useState(''); const [regions, setRegions] = useState(null); const [disabled, setDisabled] = useState(true); const [qualitySelectorVisible, setQualitySelectorVisible] = useState(false); const [selectedRegionId, setSelectedRegionId] = useState(null); const [isWarningModalVisible, setIsWarningModalVisible] = useState(false); const [showDatePicker, setShowDatePicker] = useState(null); const actionSheetRef = useRef(null); const [selectedYear, setSelectedYear] = useState(new Date().getFullYear()); const [selectedMonth, setSelectedMonth] = useState(new Date().getMonth() + 1); const [selectedDay, setSelectedDay] = useState(null); const { mutate: saveNewTrip } = usePostSetNewTripMutation(); const { mutate: updateTrip } = usePostUpdateTripMutation(); const { mutate: deleteTrip } = usePostDeleteTripMutation(); const fillRegionDatesFromSelectedDates = (regionsToUpdate: RegionWithDates[]) => { if (!selectedDates || !regionsToUpdate) return regionsToUpdate; const from = selectedDates.split(' - ')[0]; const to = selectedDates.split(' - ')[1]; const updatedRegions = regionsToUpdate.map((region) => { const hasEmptyStartDate = !region.visitStartDate?.year || !region.visitStartDate?.month; const hasEmptyEndDate = !region.visitEndDate?.year || !region.visitEndDate?.month; if (hasEmptyStartDate || hasEmptyEndDate) { const updatedRegion = { ...region }; if (hasEmptyStartDate) { updatedRegion.visitStartDate = { year: moment(from, 'YYYY-MM-DD').year(), month: moment(from, 'YYYY-MM-DD').month() + 1, day: null }; updatedRegion.year_from = moment(from, 'YYYY-MM-DD').year(); updatedRegion.month_from = moment(from, 'YYYY-MM-DD').month() + 1; } if (hasEmptyEndDate) { updatedRegion.visitEndDate = { year: moment(to, 'YYYY-MM-DD').year(), month: moment(to, 'YYYY-MM-DD').month() + 1, day: null }; updatedRegion.year_to = moment(to, 'YYYY-MM-DD').year(); updatedRegion.month_to = moment(to, 'YYYY-MM-DD').month() + 1; } return updatedRegion; } return region; }); return updatedRegions; }; useEffect(() => { if (route.params?.regionsToSave) { setRegions((currentRegions) => { const newRegionsIds = route.params.regionsToSave.map((region: RegionAddData) => region.id); const existingRegions = currentRegions?.filter((region) => newRegionsIds.includes(region.id) ); const updatedRegions = route.params.regionsToSave.map((newRegion: RegionAddData) => { const existingRegion = existingRegions?.find((region) => region.id === newRegion.id); return { ...newRegion, quality: existingRegion ? existingRegion.quality : 3, can_be_hidden: existingRegion ? existingRegion.can_be_hidden : newRegion.hidden, hidden: existingRegion ? existingRegion.hidden : false, visitStartDate: existingRegion?.visitStartDate || { year: null, month: null, day: null }, visitEndDate: existingRegion?.visitEndDate || { year: null, month: null, day: null } }; }); return fillRegionDatesFromSelectedDates(updatedRegions); }); } }, [route.params?.regionsToSave]); function extractNumberAndExtension(path: string | null) { if (!path) return null; const slashIndex = path.lastIndexOf('/'); return path.substring(slashIndex + 1); } useEffect(() => { if (editData && editData.trip) { setSelectedDates(editData.trip.date_from + ' - ' + editData.trip.date_to); setDescription(editData.trip.description); setRegions( editData.trip.regions.map((region: any) => { return { ...region, id: region.region, flag1: extractNumberAndExtension(region.flag1), flag2: extractNumberAndExtension(region.flag2), visitStartDate: { year: region.year_from || null, month: region.month_from || null, day: region.day_from || null }, visitEndDate: { year: region.year_to || null, month: region.month_to || null, day: region.day_to || null } }; }) ); } }, [editData]); useEffect(() => { if (regions?.length && selectedDates) { setRegions((currentRegions) => { if (!currentRegions) return null; return fillRegionDatesFromSelectedDates(currentRegions); }); setDisabled(false); } else { setDisabled(true); } }, [selectedDates]); useEffect(() => { setDisabled(!(regions?.length && selectedDates)); }, [regions, selectedDates]); const currentYear = new Date().getFullYear(); const years = Array.from({ length: 120 }, (_, i) => currentYear - 80 + i); const getAvailableMonths = (year: number) => { const allMonths = [ { label: 'Jan', value: 1 }, { label: 'Feb', value: 2 }, { label: 'Mar', value: 3 }, { label: 'Apr', value: 4 }, { label: 'May', value: 5 }, { label: 'Jun', value: 6 }, { label: 'Jul', value: 7 }, { label: 'Aug', value: 8 }, { label: 'Sep', value: 9 }, { label: 'Oct', value: 10 }, { label: 'Nov', value: 11 }, { label: 'Dec', value: 12 } ]; return allMonths; }; const months = getAvailableMonths(selectedYear); const getDaysInMonth = ( year: number, month: number | null ): Array<{ label: string; value: number | null }> => { if (!month) return [{ label: '-', value: null }]; const daysCount = moment(`${year}-${month}`, 'YYYY-M').daysInMonth(); const days = [{ label: '-', value: null }]; for (let i = 1; i <= daysCount; i++) { days.push({ label: i.toString(), value: i as never }); } return days; }; const days = getDaysInMonth(selectedYear, selectedMonth); const openDatePicker = ( regionId: number, field: 'visitStartDate' | 'visitEndDate', initialDate?: DateValue | null ) => { setShowDatePicker({ regionId, field }); if (initialDate && initialDate.year && initialDate.month) { setSelectedYear(initialDate.year); setSelectedMonth(initialDate.month); setSelectedDay(initialDate.day || null); } else { const today = new Date(); setSelectedYear(today.getFullYear()); setSelectedMonth(today.getMonth() + 1); setSelectedDay(today.getDate()); } actionSheetRef.current?.show(); }; const handleDateConfirm = () => { if (showDatePicker && selectedMonth) { const dateValue: DateValue = { year: selectedYear, month: selectedMonth, day: selectedDay }; setRegions( (prevRegions) => prevRegions?.map((region) => region.id === showDatePicker.regionId ? { ...region, [showDatePicker.field]: dateValue } : region ) || null ); setShowDatePicker(null); actionSheetRef.current?.hide(); } }; const handleDateCancel = () => { setShowDatePicker(null); actionSheetRef.current?.hide(); }; const changeQualityForRegion = (regionId: number | null, newQuality: number) => { regions && setRegions( regions.map((region) => { if (region.id === regionId) { return { ...region, quality: newQuality }; } return region; }) ); }; const changeHiddenForRegion = (regionId: number | null) => { regions && setRegions( regions.map((region) => { if (region.id === regionId) { return { ...region, hidden: !region.hidden }; } return region; }) ); }; const handleDeleteRegion = (regionId: number) => { regions && setRegions(regions.filter((region) => region.id !== regionId)); }; const handleDeleteTrip = () => { setIsWarningModalVisible(false); deleteTrip( { token, trip_id: editTripId }, { onSuccess: () => { navigation.navigate(...([NAVIGATION_PAGES.TRIPS, { deleted: true }] as never)); } } ); }; const handleSaveNewTrip = () => { if (regions && selectedDates) { const regionsData = regions.map((region) => { return { id: region.id, quality: region.quality ?? 3, hidden: region.hidden, year_from: region.visitStartDate?.year || new Date().getFullYear(), year_to: region.visitEndDate?.year || new Date().getFullYear(), month_from: region.visitStartDate?.month || new Date().getMonth() + 1, month_to: region.visitEndDate?.month || new Date().getMonth() + 1, day_from: region.visitStartDate?.day || null, day_to: region.visitEndDate?.day || null }; }); saveNewTrip( { token, date_from: selectedDates.split(' - ')[0], date_to: selectedDates.split(' - ')[1], description, regions: regionsData }, { onSuccess: () => { navigation.navigate(...([NAVIGATION_PAGES.TRIPS, { saved: true }] as never)); } } ); } }; const handleUpdateTrip = () => { if (regions && selectedDates) { const isStartDateInFuture = selectedDates.split(' - ')[0] > new Date().toISOString().split('T')[0]; const regionsData = regions.map((region) => { return { id: region.id, quality: region.quality ?? 3, hidden: region.hidden, year_from: region.visitStartDate?.year || new Date().getFullYear(), year_to: region.visitEndDate?.year || new Date().getFullYear(), month_from: region.visitStartDate?.month || new Date().getMonth() + 1, month_to: region.visitEndDate?.month || new Date().getMonth() + 1, day_from: region.visitStartDate?.day || null, day_to: region.visitEndDate?.day || null }; }); updateTrip( { token, trip_id: editTripId, date_from: selectedDates.split(' - ')[0], date_to: selectedDates.split(' - ')[1], description, regions: regionsData }, { onSuccess: (res) => { navigation.navigate(...([NAVIGATION_PAGES.TRIPS, { updated: true }] as never)); } } ); } }; return (
setCalendarVisible(true)}> {selectedDates ?? 'Add dates'} setDescription(text)} value={description} header="Description" height={54} multiline={true} /> Regions navigation.navigate( ...([ NAVIGATION_PAGES.ADD_REGIONS, { regionsParams: regions, editId: editTripId } ] as never) ) } > Add Region {regions && regions.length ? ( {regions.map((region) => { return ( handleDeleteRegion(region.id)} onQualityChange={() => { setSelectedRegionId(region.id); setQualitySelectorVisible(true); }} onHiddenChange={() => changeHiddenForRegion(region.id)} openDatePicker={openDatePicker} visitStartDate={region.visitStartDate} visitEndDate={region.visitEndDate} /> ); })} ) : ( No regions at the moment )} {editTripId ? ( <> setIsWarningModalVisible(true)} > Delete Trip Save Trip ) : ( Add New Trip )} Cancel Select Date Done } > Day d.label)} selectedValue={days?.find((d) => d.value === selectedDay)?.label || '-'} onValueChange={(value: string) => { const day = days?.find((d) => d.label === value); setSelectedDay(day?.value || null); }} /> Month m.label) : []} selectedValue={months?.find((m) => m.value === selectedMonth)?.label || 'Jan'} onValueChange={(value: string) => { const month = months?.find((m) => m.label === value); setSelectedMonth(month?.value || null); }} /> Year { setSelectedYear(value); }} /> { startDate && setSelectedDates( startDate.toString() + ' - ' + (endDate ? endDate?.toString() : startDate?.toString()) ); setCalendarVisible(false); }} /> setQualitySelectorVisible(false)} style={styles.modal} statusBarTranslucent={true} presentationStyle="overFullScreen" > {qualityOptions.map((option) => ( { setQualitySelectorVisible(false); changeQualityForRegion(selectedRegionId, option.id); }} > {option.name} ))} setIsWarningModalVisible(false)} title="Delete Trip" message="Are you sure you want to delete your trip?" action={handleDeleteTrip} /> ); }; export default AddNewTripScreen;