| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163 |
- import { View, Row } from 'app/design/view'
- import Dropdown from 'app/ui/atoms/dropdown'
- import { useState, useReducer, useMemo, useEffect } from 'react';
- import { Modal } from 'app/design/controls'
- import { NeoButton } from 'app/design/controls';
- import { Text } from 'app/design/typography';
- import { Icon } from 'app/ui/atoms/icon';
- import { useTheme } from 'app/design/theme';
- import { BlockWrapper } from 'app/components/block-wrapper'
- import i18n from 'i18next'
- import { useTranslation } from 'react-i18next'
- const formatValueDate = (v) => {
- const date = new Date(v.dt);
- const localDate = new Date(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate());
- return localDate.toLocaleDateString();
- }
- const formatValue = (v, bIsTime) => {
- if (v.dt != '') {
- let v3 = formatValueDate(v);
- if (bIsTime)
- return `${v3} ${v.h}:${v.m}`
- else
- return v3;
- }
- else {
- return bIsTime ? i18n.t('Select date/time') : i18n.t('Select date');
- }
- }
- const setdValue_ = (state, action) => {
- return { ...state, [action.type]: action.value };
- }
- const loadCalendar = async (setDynamicCalendar) => {
- const Calendars = await import('react-native-calendars');
- setDynamicCalendar(() => Calendars.Calendar);
- };
- const CalendarHeader = (dValue, addMonth) => {
-
- if (dValue.dt == ''){
- return (<Row className='w-full justify-center mb-4 items-center mt-2'><Text className=" font-medium text-muted-foreground text-lg">{i18n.t('Select date')}</Text></Row>)
- }
- return (<Row className='w-full justify-between gap-2 mb-4 items-center mt-2'>
- <NeoButton controlSize="small" borderShape="circle" image="ChevronsLeft" accessibilityLabel={i18n.t('Previous year')} classNames={{ root: 'self-center' }} onPress={() => addMonth('y', -1)} />
- <NeoButton controlSize="small" borderShape="circle" image="ChevronLeft" accessibilityLabel={i18n.t('Previous month')} classNames={{ root: 'self-center' }} onPress={() => addMonth('m', -1)} />
- <Text className=" font-medium text-muted-foreground text-lg">{formatValueDate(dValue)}</Text>
- <NeoButton controlSize="small" borderShape="circle" image="ChevronRight" accessibilityLabel={i18n.t('Next month')} classNames={{ root: 'self-center' }} onPress={() => addMonth('m', 1)} />
- <NeoButton controlSize="small" borderShape="circle" image="ChevronsRight" accessibilityLabel={i18n.t('Next year')} classNames={{ root: 'self-center' }} onPress={() => addMonth('y', 1)} />
- </Row>)
- };
- const generateValues = range => Array.from({ length: range }, (_, i) => ({ label: i.toString().padStart(2, '0'), value: i.toString().padStart(2, '0') }));
- export default function ({ name, value = '', type, onChange, blockWrapperProps }) {
- const { t } = useTranslation();
- const { colors } = useTheme();
- const bIsTime = type === 'datetime';
- const [showModal, setShowModal] = useState(false);
- const [DynamicCalendar, setDynamicCalendar] = useState(null);
-
- const [date, hour = '00', minute = '00'] = value.split(/[: ]/);
- const [dValue, setdValue] = useReducer(setdValue_, { dt: date, h: hour, m: minute });
- const [cValue, setcValue] = useState({ dt: date, h: hour, m: minute });
- useEffect(() => {
- let isMounted = true;
- loadCalendar(setDynamicCalendar).catch(console.error).then(() => {
- if (!isMounted) setDynamicCalendar(null);
- });
- return () => { isMounted = false; };
- }, []);
- const setFieldValue = (val, hide = true) => {
- setcValue(val)
- onChange((new Date(`${val.dt} ${val.h}:${val.m}`).getTime()) / 1000)
- if (hide)
- setShowModal(false);
- }
- const setValueDay = (day, hide = true) => {
- setdValue({ type: 'dt', value: day.dateString })
- if (!bIsTime) {
- setFieldValue({ dt: day.dateString, h: dValue.h, m: dValue.m }, hide);
- }
- };
- const addMonth = (type, val) => {
- let newDate = new Date(dValue.dt);
- if (type === 'y')
- newDate.setFullYear(newDate.getFullYear() + val);
- if (type === 'm')
- newDate.setMonth(newDate.getMonth() + val);
- setValueDay({ dateString: newDate.toISOString().slice(0, 10) }, false)
- };
- const hours = useMemo(() => generateValues(24), []);
- const minutes = useMemo(() => generateValues(60), []);
- return (
- <BlockWrapper {...blockWrapperProps}>
- <Modal onVisible={!!showModal} onClose={() => { setShowModal(false) }} transparent={false}>
- <View className=' max-w-sm w-full mx-auto'>
- <View className=' max-w-sm w-full mx-auto '>
- {DynamicCalendar && <DynamicCalendar
- className=' bg-card'
- theme={{
- calendarBackground: colors.background2,
- dayTextColor: colors.text,
- textDisabledColor: colors.text,
- monthTextColor: colors.text,
- }}
- renderArrow={direction => { return <View className="text-secondary-foreground "><Icon icon={direction == 'left' ? 'ArrowLeft' : 'ArrowRight'} width={24} height={24} /></View> }}
- initialDate={dValue.dt}
- customHeader={() => CalendarHeader(dValue, addMonth)}
- onDayPress={day => {
- setValueDay(day)
- }}
- markedDates={{
- [dValue.dt]: { selected: true, selectedColor: colors.primary }
- }}
- />}
- </View>
- {
- bIsTime && (<View className='w-full justify-center items-center gap-y-4'><Row className='justify-center items-center w-64 mt-2'>
- <Text className=" text-base justify-center items-center text-popover-foreground "> {t('Time')} </Text>
- <View>
- <Dropdown
- labelField="label"
- valueField="value"
- onChange={(v) => setdValue({ type: 'h', value: v })}
- value={dValue.h}
- data={hours}
- />
- </View>
- <Text className=" text-base justify-center items-center text-popover-foreground "> : </Text>
- <View>
- <Dropdown
- labelField="label"
- valueField="value"
- onChange={(v) => setdValue({ type: 'm', value: v })}
- value={dValue.m}
- data={minutes}
- />
- </View>
- </Row>
- <NeoButton label={t('Apply')} classNames={{ root: 'self-center' }} onPress={() => { setFieldValue(dValue) }} />
- </View>
- )
- }
- </View>
- </Modal>
- <Row>
- <NeoButton label={formatValue(cValue, bIsTime)} image="Calendar" imagePlacement="trailing" onPress={() => { setShowModal(true) }} />
- </Row>
- </BlockWrapper>
- );
- }
|