1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015 |
- import React, { useState, useEffect, useCallback, useRef } from 'react';
- import {
- View,
- Text,
- StyleSheet,
- TouchableOpacity,
- ScrollView,
- Alert,
- Animated,
- Easing
- } from 'react-native';
- import { SafeAreaView } from 'react-native-safe-area-context';
- import DateTimePicker from '@react-native-community/datetimepicker';
- import { Picker } from '@react-native-picker/picker';
- import { MaterialCommunityIcons } from '@expo/vector-icons';
- import { Picker as WheelPicker } from 'react-native-wheel-pick';
- import moment from 'moment';
- import { Button, Header, PageWrapper, WarningModal } from 'src/components';
- import { Colors } from 'src/theme';
- import { Dropdown } from 'react-native-searchable-dropdown-kj';
- import { qualityOptions } from '../utils/constants';
- import { getFontSize } from 'src/utils';
- import TrashSVG from 'assets/icons/travels-screens/trash-solid.svg';
- import { storage, StoreType } from 'src/storage';
- import {
- useGetVisitsQuery,
- usePostAddVisitMutation,
- usePostDeleteVisitMutation,
- usePostGetSingleRegionMutation,
- usePostUpdateVisitMutation
- } from '@api/myRegions';
- import ActionSheet from 'react-native-actions-sheet';
- import { ButtonVariants } from 'src/types/components';
- import EditSvg from 'assets/icons/travels-screens/pen-to-square.svg';
- import TripIcon from 'assets/icons/travels-section/trip.svg';
- import { useRegion } from 'src/contexts/RegionContext';
- import { NmRegion } from '../utils/types';
- type DateMode = 'year' | 'month' | 'full';
- type QualityType = {
- id: number;
- name: string;
- };
- interface DateValue {
- year: number | null;
- month: number | null;
- day: number | null;
- }
- interface Visit {
- id: number;
- trip_id?: number | null;
- startDate: DateValue | null;
- endDate: DateValue | null;
- quality: QualityType;
- isExisting: boolean;
- isEditing?: boolean;
- animatedValue: Animated.Value;
- }
- interface ExistingVisit {
- id: number;
- startDate: DateValue;
- endDate: DateValue;
- quality: QualityType;
- }
- interface RouteParams {
- existingVisits?: ExistingVisit[];
- }
- interface DatePickerState {
- visitId: number;
- field: 'startDate' | 'endDate';
- }
- const EditNmDataScreen = ({ navigation, route }: { navigation: any; route: any }) => {
- const id = route.params?.regionId;
- const isFromRegionsList = route.params?.regionsList ?? false;
- const token = storage.get('token', StoreType.STRING) as string;
- const { data: existingVisits } = useGetVisitsQuery(id, token, token ? true : false);
- const { mutateAsync: addVisit } = usePostAddVisitMutation();
- const { mutateAsync: updateVisitAsync } = usePostUpdateVisitMutation();
- const { mutateAsync: deleteVisitAsync } = usePostDeleteVisitMutation();
- const { mutateAsync: getRegion } = usePostGetSingleRegionMutation();
- const [visits, setVisits] = useState<Visit[]>([]);
- const [showDatePicker, setShowDatePicker] = useState<DatePickerState | null>(null);
- const [isLoading, setIsLoading] = useState<boolean>(false);
- const actionSheetRef = useRef<any>(null);
- const [selectedYear, setSelectedYear] = useState<number>(new Date().getFullYear());
- const [selectedMonth, setSelectedMonth] = useState<number | null>(null);
- const [selectedDay, setSelectedDay] = useState<number | null>(null);
- const { userData, setUserData, nmRegions, setNmRegions } = useRegion();
- const [modalState, setModalState] = useState({
- isWarningVisible: false,
- type: 'success',
- title: '',
- buttonTitle: '',
- message: '',
- action: () => {}
- });
- const createEmptyVisit = useCallback(
- (): Visit => ({
- id: Date.now() + Math.random(),
- startDate: null,
- endDate: null,
- quality: qualityOptions[2],
- isExisting: false,
- animatedValue: new Animated.Value(0)
- }),
- []
- );
- useEffect(() => {
- if (existingVisits && existingVisits.data && existingVisits.data?.length > 0) {
- const mappedVisits = existingVisits.data.map(
- (visit): Visit => ({
- ...visit,
- isExisting: true,
- isEditing: false,
- animatedValue: new Animated.Value(1),
- startDate: {
- year: visit.year_from || null,
- month: visit.month_from || null,
- day: visit.day_from || null
- },
- endDate: {
- year: visit.year_to || null,
- month: visit.month_to || null,
- day: visit.day_to || null
- },
- quality: qualityOptions.find((q) => q.id === visit.quality) || qualityOptions[2]
- })
- );
- setVisits(mappedVisits);
- }
- }, [existingVisits]);
- const renderOption = (name: string) => (
- <View style={styles.dropdownOption}>
- <Text style={styles.placeholderStyle}>{name}</Text>
- </View>
- );
- const addNewVisit = useCallback((): void => {
- const hasEmptyVisit = visits.some(
- (visit: Visit) => !visit.startDate || !visit.endDate || !visit.quality
- );
- if (hasEmptyVisit) {
- Alert.alert('Please fill all fields in existing visits before adding a new one.');
- return;
- }
- const newVisit = createEmptyVisit();
- setVisits((prev) => [newVisit, ...prev]);
- Animated.timing(newVisit.animatedValue, {
- toValue: 1,
- duration: 300,
- easing: Easing.out(Easing.quad),
- useNativeDriver: false
- }).start();
- }, [visits, createEmptyVisit]);
- const updateVisit = useCallback((id: number, field: keyof Visit, value: any): void => {
- setVisits((prevVisits) =>
- prevVisits.map((visit) => (visit.id === id ? { ...visit, [field]: value } : visit))
- );
- }, []);
- const toggleEditVisit = useCallback(
- async (visitId: number): Promise<void> => {
- const visit = visits.find((v) => v.id === visitId);
- if (visit && visit.isEditing) {
- if (!compareDates(visit.startDate, visit.endDate)) {
- Alert.alert('Start date cannot be after end date.');
- return;
- }
- await updateVisitAsync(
- {
- token,
- region: id,
- id: visitId,
- quality: visit.quality.id,
- year_from: visit.startDate?.year || null,
- month_from: visit.startDate?.month || null,
- day_from: visit.startDate?.day || null,
- year_to: visit.endDate?.year || null,
- month_to: visit.endDate?.month || null,
- day_to: visit.endDate?.day || null,
- // completed: 1,
- hidden: 0
- },
- {
- onSuccess: async (data) => {
- await getRegion(
- { token, id },
- {
- onSuccess: (res) => {
- if (isFromRegionsList && res.region) {
- const updatedNM = nmRegions.map((item: NmRegion) => {
- if (item.id === id) {
- return {
- ...item,
- year: res.region?.first_visited_in_year,
- last: res.region?.last_visited_in_year,
- quality: res.region?.best_visit_quality,
- visits: res.region?.no_of_visits
- };
- }
- return item;
- });
- setNmRegions(updatedNM);
- return;
- }
- if (res.region) {
- const updatedNM = {
- ...userData,
- first_visit_year: res.region.first_visited_in_year,
- last_visit_year: res.region.last_visited_in_year,
- best_visit_quality: res.region.best_visit_quality,
- no_of_visits: res.region.no_of_visits,
- visited: true
- };
- setUserData(updatedNM);
- }
- },
- onError: (err) => {
- console.log('err', err);
- }
- }
- );
- Alert.alert('Success', 'Visit updated successfully!', [
- { text: 'OK', onPress: () => navigation.goBack() }
- ]);
- },
- onError: (error) => {
- console.log('updateVisitAsync error', error);
- }
- }
- );
- }
- setVisits((prevVisits) =>
- prevVisits.map((visit) =>
- visit.id === visitId ? { ...visit, isEditing: !visit.isEditing } : visit
- )
- );
- },
- [visits]
- );
- const deleteVisit = useCallback(
- async (visitId: number): Promise<void> => {
- const visitToDelete = visits.find((visit: Visit) => visit.id === visitId);
- if (!visitToDelete) return;
- if (visitToDelete.isExisting) {
- setModalState({
- type: 'delete',
- title: `Delete visit`,
- message: `Are you sure you want to delete this visit?`,
- action: async () => {
- await deleteVisitAsync(
- {
- token,
- id: visitToDelete.id
- },
- {
- onSuccess: async (res) => {
- Animated.timing(visitToDelete.animatedValue, {
- toValue: 0,
- duration: 300,
- easing: Easing.in(Easing.quad),
- useNativeDriver: false
- }).start(() => {
- setVisits((prevVisits) => prevVisits.filter((visit) => visit.id !== visitId));
- });
- getRegion(
- { token, id },
- {
- onSuccess: (res) => {
- if (isFromRegionsList && res.not_visited) {
- const updatedNM = nmRegions.map((item: NmRegion) => {
- if (item.id === id) {
- return {
- ...item,
- year: 0,
- last: 0,
- quality: 3,
- visits: 0
- };
- }
- return item;
- });
- setNmRegions(updatedNM);
- return;
- } else if (isFromRegionsList && res.region) {
- const updatedNM = nmRegions.map((item: NmRegion) => {
- if (item.id === id) {
- return {
- ...item,
- year: res.region?.first_visited_in_year,
- last: res.region?.last_visited_in_year,
- quality: res.region?.best_visit_quality,
- visits: res.region?.no_of_visits
- };
- }
- return item;
- });
- setNmRegions(updatedNM);
- return;
- }
- if (res.not_visited) {
- const updatedNM = {
- ...userData,
- first_visit_year: 0,
- last_visit_year: 0,
- best_visit_quality: 3,
- no_of_visits: 0,
- visited: false
- };
- setUserData(updatedNM);
- return;
- }
- if (res.region) {
- const updatedNM = {
- ...userData,
- first_visit_year: res.region.first_visited_in_year,
- last_visit_year: res.region.last_visited_in_year,
- best_visit_quality: res.region.best_visit_quality,
- no_of_visits: res.region.no_of_visits,
- visited: true
- };
- setUserData(updatedNM);
- }
- },
- onError: (err) => {
- console.log('err', err);
- }
- }
- );
- },
- onError: (err) => {
- console.log('delete err', err);
- }
- }
- );
- },
- buttonTitle: 'Delete',
- isWarningVisible: true
- });
- } else {
- Animated.timing(visitToDelete.animatedValue, {
- toValue: 0,
- duration: 300,
- easing: Easing.in(Easing.quad),
- useNativeDriver: false
- }).start(() => {
- setVisits((prevVisits) => prevVisits.filter((visit) => visit.id !== visitId));
- });
- }
- },
- [visits]
- );
- const formatDateForDisplay = useCallback((dateValue: DateValue | null): string => {
- if (!dateValue || !dateValue.year) return 'Select date';
- let result = dateValue.year.toString();
- if (dateValue.month) {
- result = `${dateValue.month.toString().padStart(2, '0')}.${result}`;
- if (dateValue.day) {
- result = `${dateValue.day.toString().padStart(2, '0')}.${result}`;
- }
- }
- return result;
- }, []);
- const isDateValid = useCallback((dateValue: DateValue | null): boolean => {
- return dateValue !== null && dateValue.year !== null;
- }, []);
- const compareDates = useCallback(
- (startDate: DateValue | null, endDate: DateValue | null): boolean => {
- if (!startDate || !endDate || !startDate.year || !endDate.year) return true;
- const maxEndDay = moment(`${endDate.year}-${endDate.month ?? 12}`, 'YYYY-M').daysInMonth();
- const start = moment({
- year: startDate.year,
- month: (startDate.month || 1) - 1,
- day: startDate.day || 1
- });
- const end = moment({
- year: endDate.year,
- month: (endDate.month || 12) - 1,
- day: endDate.day || maxEndDay
- });
- if (!start || !end) return true;
- return start.isSameOrBefore(end);
- },
- []
- );
- const validateVisits = useCallback((): boolean => {
- const newVisits = visits.filter((visit: Visit) => !visit.isExisting);
- for (const visit of newVisits) {
- if (!isDateValid(visit.startDate) || !isDateValid(visit.endDate) || !visit.quality) {
- Alert.alert('Please fill all fields for each visit.');
- return false;
- }
- if (!compareDates(visit.startDate, visit.endDate)) {
- Alert.alert('Start date cannot be after end date.');
- return false;
- }
- }
- return true;
- }, [visits, isDateValid, compareDates]);
- const handleSave = useCallback(async (): Promise<void> => {
- if (!validateVisits()) return;
- setIsLoading(true);
- try {
- const newVisits = visits.filter((visit: Visit) => !visit.isExisting);
- if (newVisits.length === 0) {
- // Alert.alert('No new visits to save.');
- return;
- }
- newVisits.forEach(async (v) => {
- await addVisit(
- {
- token,
- region: id,
- quality: v.quality.id,
- year_from: v.startDate?.year || null,
- month_from: v.startDate?.month || null,
- day_from: v.startDate?.day || null,
- year_to: v.endDate?.year || null,
- month_to: v.endDate?.month || null,
- day_to: v.endDate?.day || null,
- // completed: 1,
- hidden: 0
- },
- {
- onSuccess: async (data) => {
- await getRegion(
- { token, id },
- {
- onSuccess: (res) => {
- if (isFromRegionsList && res.region) {
- const updatedNM = nmRegions.map((item: NmRegion) => {
- if (item.id === id) {
- return {
- ...item,
- year: res.region?.first_visited_in_year,
- last: res.region?.last_visited_in_year,
- quality: res.region?.best_visit_quality,
- visits: res.region?.no_of_visits
- };
- }
- return item;
- });
- setNmRegions(updatedNM);
- return;
- }
- if (res.region) {
- const updatedNM = {
- ...userData,
- first_visit_year: res.region.first_visited_in_year,
- last_visit_year: res.region.last_visited_in_year,
- best_visit_quality: res.region.best_visit_quality,
- no_of_visits: res.region.no_of_visits,
- visited: true
- };
- setUserData(updatedNM);
- }
- },
- onError: (err) => {
- console.log('err', err);
- }
- }
- );
- },
- onError: (error) => {
- console.log('addVisit error', error);
- }
- }
- );
- });
- Alert.alert('Success', 'Visits saved successfully!', [
- { text: 'OK', onPress: () => navigation.goBack() }
- ]);
- } catch (error) {
- console.log('Error saving visits:', error);
- } finally {
- setIsLoading(false);
- }
- }, [validateVisits, visits, navigation]);
- const currentYear = new Date().getFullYear();
- const years = Array.from({ length: 120 }, (_, i) => currentYear - 80 + i);
- const getAvailableMonths = (year: number) => {
- const allMonths = [
- { label: '-', value: null },
- { 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 = (
- visitId: number,
- field: 'startDate' | 'endDate',
- initialDate?: DateValue | null
- ) => {
- setShowDatePicker({ visitId, field });
- if (initialDate && initialDate.year) {
- setSelectedYear(initialDate.year);
- setSelectedMonth(initialDate.month || null);
- 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) {
- const dateValue: DateValue = {
- year: selectedYear,
- month: selectedMonth,
- day: selectedDay
- };
- updateVisit(showDatePicker.visitId, showDatePicker.field, dateValue);
- setShowDatePicker(null);
- actionSheetRef.current?.hide();
- }
- };
- const handleDateCancel = () => {
- setShowDatePicker(null);
- actionSheetRef.current?.hide();
- };
- const renderDatePicker = useCallback(
- (
- visitId: number,
- field: 'startDate' | 'endDate',
- currentDate: DateValue | null
- ): JSX.Element => (
- <TouchableOpacity
- style={styles.dateInput}
- onPress={() => openDatePicker(visitId, field, currentDate)}
- >
- <Text style={[styles.dateText, !isDateValid(currentDate) && styles.placeholderText]}>
- {formatDateForDisplay(currentDate)}
- </Text>
- <MaterialCommunityIcons name="chevron-down" size={20} color="#666" />
- </TouchableOpacity>
- ),
- [formatDateForDisplay, isDateValid]
- );
- const renderVisitItem = useCallback(
- (visit: Visit, index: number): JSX.Element => {
- const isEditable = !visit.isExisting || visit.isEditing;
- return (
- <Animated.View
- key={visit.id}
- style={[
- styles.visitItem,
- !isEditable && styles.existingVisitItem,
- {
- // opacity: visit.animatedValue
- }
- ]}
- >
- <View style={styles.visitContent}>
- {visit.trip_id ? <TripIcon width={18} height={18} fill={Colors.DARK_BLUE} /> : null}
- <View style={{ flex: 1, gap: 12 }}>
- <View style={styles.dateRow}>
- <View style={styles.column}>
- <Text style={styles.label}>Start of visit</Text>
- {isEditable ? (
- renderDatePicker(visit.id, 'startDate', visit.startDate)
- ) : (
- <View style={[styles.dateInput]}>
- <Text style={styles.dateText}>{formatDateForDisplay(visit.startDate)}</Text>
- </View>
- )}
- </View>
- <View style={styles.column}>
- <Text style={styles.label}>End of visit</Text>
- {isEditable ? (
- renderDatePicker(visit.id, 'endDate', visit.endDate)
- ) : (
- <View style={[styles.dateInput]}>
- <Text style={styles.dateText}>{formatDateForDisplay(visit.endDate)}</Text>
- </View>
- )}
- </View>
- </View>
- <View style={styles.qualityRow}>
- <View style={styles.qualityColumn}>
- <Text style={styles.label}>Quality</Text>
- {isEditable ? (
- <Dropdown
- style={styles.dropdown}
- placeholderStyle={styles.placeholderStyle}
- containerStyle={{ borderRadius: 4 }}
- selectedTextStyle={styles.placeholderStyle}
- data={qualityOptions}
- labelField="name"
- valueField="id"
- value={visit.quality.id}
- placeholder="Best visit quality"
- onChange={(item) =>
- updateVisit(visit.id, 'quality', { id: item.id, name: item.name })
- }
- renderItem={(item) => renderOption(item.name)}
- />
- ) : (
- <View style={[styles.dropdown, styles.readOnlyInput]}>
- <Text style={styles.placeholderStyle}>{visit.quality.name}</Text>
- </View>
- )}
- </View>
- </View>
- </View>
- <View style={styles.actionButtons}>
- {visit.isExisting && (
- <TouchableOpacity
- style={[styles.editButton, visit.isEditing && styles.saveEditButton]}
- onPress={() => toggleEditVisit(visit.id)}
- >
- {visit.isEditing ? (
- <MaterialCommunityIcons name={'check'} size={16} color={Colors.WHITE} />
- ) : (
- <EditSvg width={14} height={14} />
- )}
- </TouchableOpacity>
- )}
- <TouchableOpacity style={styles.deleteButton} onPress={() => deleteVisit(visit.id)}>
- <TrashSVG height={16} fill={Colors.WHITE} />
- </TouchableOpacity>
- </View>
- </View>
- </Animated.View>
- );
- },
- [
- renderDatePicker,
- deleteVisit,
- toggleEditVisit,
- updateVisit,
- formatDateForDisplay,
- renderOption,
- visits
- ]
- );
- return (
- <PageWrapper>
- <Header label={'Add visits'} />
- <ScrollView style={styles.scrollView} showsVerticalScrollIndicator={false}>
- <TouchableOpacity style={styles.addRegionBtn} onPress={addNewVisit}>
- <MaterialCommunityIcons name="plus-circle" size={20} color={Colors.DARK_BLUE} />
- <Text style={styles.addRegionBtntext}>Add new visit</Text>
- </TouchableOpacity>
- {visits.map(renderVisitItem)}
- </ScrollView>
- <View style={[styles.buttonContainer, { marginBottom: 20 }]}>
- <Button onPress={handleSave} disabled={isLoading}>
- {isLoading ? 'Saving...' : 'Save'}
- </Button>
- <Button
- variant={ButtonVariants.OPACITY}
- containerStyles={{
- backgroundColor: Colors.WHITE,
- borderColor: Colors.BORDER_LIGHT
- }}
- textStyles={{ color: Colors.DARK_BLUE }}
- onPress={() => navigation.goBack()}
- >
- Close
- </Button>
- </View>
- <ActionSheet
- ref={actionSheetRef}
- gestureEnabled={false}
- headerAlwaysVisible={true}
- onTouchBackdrop={handleDateConfirm}
- 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 || '-'}
- onValueChange={(value: string) => {
- const month = months?.find((m) => m.label === value);
- setSelectedMonth(month?.value || null);
- if (!month?.value) {
- setSelectedDay(null);
- }
- }}
- />
- </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.toString()}
- onValueChange={(value: number) => {
- setSelectedYear(value);
- }}
- />
- </View>
- </View>
- </ActionSheet>
- <WarningModal
- type={modalState.type}
- isVisible={modalState.isWarningVisible}
- buttonTitle={modalState.buttonTitle}
- message={modalState.message}
- action={modalState.action}
- onClose={() => setModalState({ ...modalState, isWarningVisible: false })}
- title={modalState.title}
- />
- </PageWrapper>
- );
- };
- const styles = StyleSheet.create({
- scrollView: {
- flex: 1
- },
- visitItem: {
- backgroundColor: Colors.WHITE,
- borderRadius: 8,
- padding: 12,
- marginBottom: 12,
- borderWidth: 0.5,
- borderColor: Colors.LIGHT_GRAY
- },
- existingVisitItem: {},
- visitContent: {
- gap: 12,
- flexDirection: 'row',
- justifyContent: 'space-between',
- alignItems: 'center'
- },
- dateRow: {
- flexDirection: 'row',
- alignItems: 'flex-start',
- gap: 12
- },
- qualityRow: {
- flexDirection: 'row'
- },
- qualityColumn: {
- flex: 1
- },
- column: {
- flex: 1
- },
- actionButtons: {
- flexDirection: 'column',
- alignItems: 'center',
- gap: 8
- },
- editButton: {
- width: 30,
- height: 30,
- borderRadius: 15,
- justifyContent: 'center',
- alignItems: 'center',
- borderWidth: 1,
- borderColor: Colors.LIGHT_GRAY
- },
- saveEditButton: {
- borderColor: Colors.ORANGE,
- backgroundColor: Colors.ORANGE
- },
- label: {
- fontSize: getFontSize(12),
- color: Colors.DARK_BLUE,
- marginBottom: 4,
- fontWeight: '600'
- },
- dateInput: {
- borderRadius: 6,
- paddingHorizontal: 8,
- paddingVertical: 6,
- flexDirection: 'row',
- alignItems: 'center',
- justifyContent: 'space-between',
- backgroundColor: Colors.FILL_LIGHT,
- height: 36
- },
- readOnlyInput: {
- justifyContent: 'center'
- },
- dateText: {
- fontSize: getFontSize(12),
- color: Colors.DARK_BLUE,
- fontWeight: '500'
- },
- placeholderText: {
- color: Colors.TEXT_GRAY,
- flexWrap: 'wrap'
- },
- deleteButton: {
- width: 30,
- height: 30,
- borderRadius: 15,
- backgroundColor: Colors.RED,
- alignItems: 'center',
- justifyContent: 'center'
- },
- buttonContainer: {
- marginBottom: 32,
- gap: 12
- },
- datePickerHeader: {
- flexDirection: 'row',
- justifyContent: 'space-between',
- alignItems: 'center',
- paddingHorizontal: 20,
- paddingVertical: 16,
- borderBottomWidth: 1,
- borderBottomColor: '#eee'
- },
- datePickerTitle: {
- fontSize: 18,
- fontWeight: '600',
- color: Colors.DARK_BLUE
- },
- datePickerCancel: {
- fontSize: 16,
- color: '#666'
- },
- datePickerConfirm: {
- fontSize: 16,
- color: Colors.DARK_BLUE,
- fontWeight: '600'
- },
- wheelContainer: {
- flexDirection: 'row',
- paddingHorizontal: 14,
- paddingTop: 16,
- paddingBottom: 24
- },
- wheelColumn: {
- flex: 1,
- alignItems: 'center'
- },
- wheelLabel: {
- fontSize: 14,
- color: Colors.DARK_BLUE,
- marginBottom: 8,
- fontWeight: '600'
- },
- wheelPicker: {
- height: 210,
- width: '100%',
- backgroundColor: 'white'
- },
- dropdown: {
- height: 36,
- backgroundColor: '#F4F4F4',
- borderRadius: 4,
- paddingHorizontal: 8
- },
- dropdownOption: {
- paddingVertical: 12,
- paddingHorizontal: 16
- },
- placeholderStyle: {
- fontSize: 12,
- color: Colors.DARK_BLUE,
- fontWeight: '500'
- },
- addRegionBtn: {
- display: 'flex',
- justifyContent: 'center',
- alignItems: 'center',
- flexDirection: 'row',
- borderRadius: 4,
- gap: 10,
- padding: 10,
- borderColor: Colors.DARK_BLUE,
- borderWidth: 1,
- borderStyle: 'solid',
- marginBottom: 12
- },
- addRegionBtntext: {
- color: Colors.DARK_BLUE,
- fontSize: getFontSize(14),
- fontFamily: 'redhat-700'
- }
- });
- export default EditNmDataScreen;
|