|
@@ -1,7 +1,10 @@
|
|
|
-import React, { useEffect, useState } from 'react';
|
|
|
+import React, { useEffect, useState, useCallback, 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';
|
|
@@ -22,6 +25,28 @@ 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;
|
|
@@ -30,22 +55,24 @@ const AddNewTripScreen = ({ route }: { route: any }) => {
|
|
|
const [calendarVisible, setCalendarVisible] = useState(false);
|
|
|
const [selectedDates, setSelectedDates] = useState<string | null>(null);
|
|
|
const [description, setDescription] = useState<string>('');
|
|
|
- const [regions, setRegions] = useState<RegionAddData[] | null>(null);
|
|
|
+ const [regions, setRegions] = useState<RegionWithDates[] | null>(null);
|
|
|
const [disabled, setDisabled] = useState(true);
|
|
|
const [qualitySelectorVisible, setQualitySelectorVisible] = useState(false);
|
|
|
const [selectedRegionId, setSelectedRegionId] = useState<number | null>(null);
|
|
|
const [isWarningModalVisible, setIsWarningModalVisible] = useState(false);
|
|
|
|
|
|
+ const [showDatePicker, setShowDatePicker] = useState<DatePickerState | null>(null);
|
|
|
+ const actionSheetRef = useRef<any>(null);
|
|
|
+ const [selectedYear, setSelectedYear] = useState<number>(new Date().getFullYear());
|
|
|
+ const [selectedMonth, setSelectedMonth] = useState<number | null>(new Date().getMonth() + 1);
|
|
|
+ const [selectedDay, setSelectedDay] = useState<number | null>(null);
|
|
|
+
|
|
|
const { mutate: saveNewTrip } = usePostSetNewTripMutation();
|
|
|
const { mutate: updateTrip } = usePostUpdateTripMutation();
|
|
|
const { mutate: deleteTrip } = usePostDeleteTripMutation();
|
|
|
|
|
|
useEffect(() => {
|
|
|
if (route.params?.regionsToSave) {
|
|
|
- const isStartDateInFuture = selectedDates && editTripId
|
|
|
- ? selectedDates.split(' - ')[0] > new Date().toISOString().split('T')[0]
|
|
|
- : true;
|
|
|
-
|
|
|
setRegions((currentRegions) => {
|
|
|
const newRegionsIds = route.params.regionsToSave.map((region: RegionAddData) => region.id);
|
|
|
const existingRegions = currentRegions?.filter((region) =>
|
|
@@ -58,9 +85,18 @@ const AddNewTripScreen = ({ route }: { route: any }) => {
|
|
|
return {
|
|
|
...newRegion,
|
|
|
quality: existingRegion ? existingRegion.quality : 3,
|
|
|
- status: existingRegion ? existingRegion.status : !isStartDateInFuture ? 1 : 0,
|
|
|
can_be_hidden: existingRegion ? existingRegion.can_be_hidden : newRegion.hidden,
|
|
|
- hidden: existingRegion ? existingRegion.hidden : false
|
|
|
+ hidden: existingRegion ? existingRegion.hidden : false,
|
|
|
+ visitStartDate: existingRegion?.visitStartDate || {
|
|
|
+ year: null,
|
|
|
+ month: null,
|
|
|
+ day: null
|
|
|
+ },
|
|
|
+ visitEndDate: existingRegion?.visitEndDate || {
|
|
|
+ year: null,
|
|
|
+ month: null,
|
|
|
+ day: null
|
|
|
+ }
|
|
|
};
|
|
|
});
|
|
|
|
|
@@ -83,8 +119,19 @@ const AddNewTripScreen = ({ route }: { route: any }) => {
|
|
|
editData.trip.regions.map((region: any) => {
|
|
|
return {
|
|
|
...region,
|
|
|
+ id: region.region,
|
|
|
flag1: extractNumberAndExtension(region.flag1),
|
|
|
- flag2: extractNumberAndExtension(region.flag2)
|
|
|
+ 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
|
|
|
+ }
|
|
|
};
|
|
|
})
|
|
|
);
|
|
@@ -99,24 +146,103 @@ const AddNewTripScreen = ({ route }: { route: any }) => {
|
|
|
}
|
|
|
}, [regions, selectedDates]);
|
|
|
|
|
|
- const changeQualityForRegion = (regionId: number | null, newQuality: number) => {
|
|
|
- regions &&
|
|
|
+ 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(
|
|
|
- regions.map((region) => {
|
|
|
- if (region.id === regionId) {
|
|
|
- return { ...region, quality: newQuality };
|
|
|
- }
|
|
|
- return region;
|
|
|
- })
|
|
|
+ (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 changeStatusForRegion = (regionId: number | null) => {
|
|
|
+ const changeQualityForRegion = (regionId: number | null, newQuality: number) => {
|
|
|
regions &&
|
|
|
setRegions(
|
|
|
regions.map((region) => {
|
|
|
if (region.id === regionId) {
|
|
|
- return { ...region, status: region.status === 1 ? 0 : 1 };
|
|
|
+ return { ...region, quality: newQuality };
|
|
|
}
|
|
|
return region;
|
|
|
})
|
|
@@ -156,14 +282,17 @@ const AddNewTripScreen = ({ route }: { route: any }) => {
|
|
|
|
|
|
const handleSaveNewTrip = () => {
|
|
|
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,
|
|
|
- status: isStartDateInFuture ? 0 : (Number(region.status) as 0 | 1),
|
|
|
- hidden: region.hidden
|
|
|
+ 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
|
|
|
};
|
|
|
});
|
|
|
|
|
@@ -192,8 +321,13 @@ const AddNewTripScreen = ({ route }: { route: any }) => {
|
|
|
return {
|
|
|
id: region.id,
|
|
|
quality: region.quality ?? 3,
|
|
|
- status: isStartDateInFuture ? 0 : (Number(region.status) as 0 | 1),
|
|
|
- hidden: region.hidden
|
|
|
+ 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
|
|
|
};
|
|
|
});
|
|
|
|
|
@@ -260,15 +394,14 @@ const AddNewTripScreen = ({ route }: { route: any }) => {
|
|
|
key={region.id}
|
|
|
region={region}
|
|
|
onDelete={() => handleDeleteRegion(region.id)}
|
|
|
- onToggleStatus={() => changeStatusForRegion(region.id)}
|
|
|
onQualityChange={() => {
|
|
|
setSelectedRegionId(region.id);
|
|
|
setQualitySelectorVisible(true);
|
|
|
}}
|
|
|
onHiddenChange={() => changeHiddenForRegion(region.id)}
|
|
|
- startDate={selectedDates ? selectedDates.split(' - ')[0] : null}
|
|
|
- endDate={selectedDates ? selectedDates.split(' - ')[1] : null}
|
|
|
- isEditing={editTripId}
|
|
|
+ openDatePicker={openDatePicker}
|
|
|
+ visitStartDate={region.visitStartDate}
|
|
|
+ visitEndDate={region.visitEndDate}
|
|
|
/>
|
|
|
);
|
|
|
})}
|
|
@@ -316,6 +449,93 @@ const AddNewTripScreen = ({ route }: { route: any }) => {
|
|
|
)}
|
|
|
</View>
|
|
|
|
|
|
+ <ActionSheet
|
|
|
+ ref={actionSheetRef}
|
|
|
+ gestureEnabled={false}
|
|
|
+ headerAlwaysVisible={true}
|
|
|
+ CustomHeaderComponent={
|
|
|
+ <View style={styles.datePickerHeader}>
|
|
|
+ <TouchableOpacity onPress={handleDateCancel}>
|
|
|
+ <Text style={styles.datePickerCancel}>Cancel</Text>
|
|
|
+ </TouchableOpacity>
|
|
|
+ <Text style={styles.datePickerTitle}>Select Date</Text>
|
|
|
+ <TouchableOpacity onPress={handleDateConfirm}>
|
|
|
+ <Text style={styles.datePickerConfirm}>Done</Text>
|
|
|
+ </TouchableOpacity>
|
|
|
+ </View>
|
|
|
+ }
|
|
|
+ >
|
|
|
+ <View style={styles.wheelContainer}>
|
|
|
+ <View style={styles.wheelColumn}>
|
|
|
+ <Text style={styles.wheelLabel}>Day</Text>
|
|
|
+ <WheelPicker
|
|
|
+ style={styles.wheelPicker}
|
|
|
+ textColor={Colors.DARK_BLUE}
|
|
|
+ itemStyle={{ fontSize: 16, fontFamily: 'montserrat-600', padding: 0 }}
|
|
|
+ pickerData={days?.map((d) => 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);
|
|
|
+ }}
|
|
|
+ />
|
|
|
+ </View>
|
|
|
+
|
|
|
+ <View style={styles.wheelColumn}>
|
|
|
+ <Text style={styles.wheelLabel}>Month</Text>
|
|
|
+ <WheelPicker
|
|
|
+ style={styles.wheelPicker}
|
|
|
+ textColor={Colors.DARK_BLUE}
|
|
|
+ itemStyle={{
|
|
|
+ fontSize: 16,
|
|
|
+ fontFamily: 'montserrat-600'
|
|
|
+ }}
|
|
|
+ pickerData={months ? months?.map((m) => 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);
|
|
|
+
|
|
|
+ if (selectedDay && month?.value) {
|
|
|
+ const maxDaysInMonth = moment(
|
|
|
+ `${selectedYear}-${month.value}`,
|
|
|
+ 'YYYY-M'
|
|
|
+ ).daysInMonth();
|
|
|
+ if (selectedDay > maxDaysInMonth) {
|
|
|
+ setSelectedDay(maxDaysInMonth);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }}
|
|
|
+ />
|
|
|
+ </View>
|
|
|
+
|
|
|
+ <View style={styles.wheelColumn}>
|
|
|
+ <Text style={styles.wheelLabel}>Year</Text>
|
|
|
+ <WheelPicker
|
|
|
+ style={styles.wheelPicker}
|
|
|
+ textColor={Colors.DARK_BLUE}
|
|
|
+ itemStyle={{ fontSize: 16, fontFamily: 'montserrat-600' }}
|
|
|
+ isCyclic={true}
|
|
|
+ pickerData={years}
|
|
|
+ selectedValue={selectedYear}
|
|
|
+ onValueChange={(value: number) => {
|
|
|
+ setSelectedYear(value);
|
|
|
+
|
|
|
+ if (selectedMonth) {
|
|
|
+ const maxDaysInMonth = moment(
|
|
|
+ `${value}-${selectedMonth}`,
|
|
|
+ 'YYYY-M'
|
|
|
+ ).daysInMonth();
|
|
|
+ if (selectedDay && selectedDay > maxDaysInMonth) {
|
|
|
+ setSelectedDay(maxDaysInMonth);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }}
|
|
|
+ />
|
|
|
+ </View>
|
|
|
+ </View>
|
|
|
+ </ActionSheet>
|
|
|
+
|
|
|
<RangeCalendar
|
|
|
isModalVisible={calendarVisible}
|
|
|
closeModal={(startDate?: string | null, endDate?: string | null) => {
|