182 lines
4.8 KiB
JavaScript
182 lines
4.8 KiB
JavaScript
import React, { useEffect, useRef } from "react";
|
|
import { useController, useFormContext, useWatch } from "react-hook-form";
|
|
const DateRangePicker = ({
|
|
md,
|
|
sm,
|
|
onRangeChange,
|
|
DateDifference = 7,
|
|
endDateMode = "yesterday",
|
|
}) => {
|
|
const inputRef = useRef(null);
|
|
|
|
useEffect(() => {
|
|
const endDate = new Date();
|
|
if (endDateMode === "yesterday") {
|
|
endDate.setDate(endDate.getDate() - 1);
|
|
}
|
|
|
|
endDate.setHours(0, 0, 0, 0);
|
|
|
|
const startDate = new Date(endDate);
|
|
startDate.setDate(endDate.getDate() - (DateDifference - 1));
|
|
startDate.setHours(0, 0, 0, 0);
|
|
|
|
const fp = flatpickr(inputRef.current, {
|
|
mode: "range",
|
|
dateFormat: "Y-m-d",
|
|
altInput: true,
|
|
altFormat: "d-m-Y",
|
|
defaultDate: [startDate, endDate],
|
|
static: true,
|
|
clickOpens: true,
|
|
maxDate: endDate,
|
|
onChange: (selectedDates, dateStr) => {
|
|
const [startDateString, endDateString] = dateStr.split(" to ");
|
|
onRangeChange?.({ startDate: startDateString, endDate: endDateString });
|
|
},
|
|
});
|
|
|
|
onRangeChange?.({
|
|
startDate: startDate.toLocaleDateString("en-CA"),
|
|
endDate: endDate.toLocaleDateString("en-CA"),
|
|
});
|
|
|
|
return () => {
|
|
fp.destroy();
|
|
};
|
|
}, [onRangeChange, DateDifference, endDateMode]);
|
|
|
|
const handleIconClick = () => {
|
|
if (inputRef.current) {
|
|
inputRef.current._flatpickr.open(); // directly opens flatpickr
|
|
}
|
|
};
|
|
|
|
return (
|
|
<div className={`col-${sm} col-sm-${md} px-1`}>
|
|
<input
|
|
type="text"
|
|
className="form-control form-control-sm ps-2 pe-5 me-4"
|
|
placeholder="From to End"
|
|
id="flatpickr-range"
|
|
ref={inputRef}
|
|
/>
|
|
|
|
<i
|
|
className="bx bx-calendar calendar-icon cursor-pointer position-relative top-50 translate-middle-y " onClick={handleIconClick}
|
|
style={{ right: "22px", bottom: "-8px" }}
|
|
></i>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default DateRangePicker;
|
|
|
|
|
|
|
|
|
|
|
|
export const DateRangePicker1 = ({
|
|
startField = "startDate",
|
|
endField = "endDate",
|
|
placeholder = "Select date range",
|
|
className = "",
|
|
allowText = false,
|
|
resetSignal,
|
|
defaultRange = true,
|
|
...rest
|
|
}) => {
|
|
const inputRef = useRef(null);
|
|
const { control, setValue, getValues } = useFormContext();
|
|
|
|
const {
|
|
field: { ref },
|
|
} = useController({ name: startField, control });
|
|
|
|
const applyDefaultDates = () => {
|
|
const today = new Date();
|
|
const past = new Date();
|
|
past.setDate(today.getDate() - 6);
|
|
|
|
const format = (d) => flatpickr.formatDate(d, "d-m-Y");
|
|
const formattedStart = format(past);
|
|
const formattedEnd = format(today);
|
|
|
|
setValue(startField, formattedStart, { shouldValidate: true });
|
|
setValue(endField, formattedEnd, { shouldValidate: true });
|
|
|
|
if (inputRef.current?._flatpickr) {
|
|
inputRef.current._flatpickr.setDate([past, today]);
|
|
}
|
|
};
|
|
|
|
useEffect(() => {
|
|
if (!inputRef.current || inputRef.current._flatpickr) return;
|
|
|
|
const instance = flatpickr(inputRef.current, {
|
|
mode: "range",
|
|
dateFormat: "d-m-Y",
|
|
allowInput: allowText,
|
|
onChange: (selectedDates) => {
|
|
if (selectedDates.length === 2) {
|
|
const [start, end] = selectedDates;
|
|
const format = (d) => flatpickr.formatDate(d, "d-m-Y");
|
|
setValue(startField, format(start), { shouldValidate: true });
|
|
setValue(endField, format(end), { shouldValidate: true });
|
|
} else {
|
|
setValue(startField, "", { shouldValidate: true });
|
|
setValue(endField, "", { shouldValidate: true });
|
|
}
|
|
},
|
|
...rest,
|
|
});
|
|
|
|
const currentStart = getValues(startField);
|
|
const currentEnd = getValues(endField);
|
|
if (defaultRange && !currentStart && !currentEnd) {
|
|
applyDefaultDates();
|
|
} else if (currentStart && currentEnd) {
|
|
instance.setDate([
|
|
flatpickr.parseDate(currentStart, "d-m-Y"),
|
|
flatpickr.parseDate(currentEnd, "d-m-Y"),
|
|
]);
|
|
}
|
|
|
|
return () => instance.destroy();
|
|
}, []);
|
|
|
|
useEffect(() => {
|
|
if (defaultRange && resetSignal !== undefined) {
|
|
applyDefaultDates();
|
|
}
|
|
}, [resetSignal, defaultRange]);
|
|
|
|
const start = getValues(startField);
|
|
const end = getValues(endField);
|
|
const formattedValue = start && end ? `${start} To ${end}` : "";
|
|
|
|
return (
|
|
<div className={`position-relative ${className}`}>
|
|
<input
|
|
type="text"
|
|
className="form-control form-control-sm"
|
|
placeholder={placeholder}
|
|
defaultValue={formattedValue}
|
|
ref={(el) => {
|
|
inputRef.current = el;
|
|
ref(el);
|
|
}}
|
|
readOnly={!allowText}
|
|
autoComplete="off"
|
|
/>
|
|
<span
|
|
className="position-absolute top-50 end-0 pe-1 translate-middle-y cursor-pointer"
|
|
onClick={() => inputRef.current?._flatpickr?.open()}
|
|
>
|
|
<i className="bx bx-calendar bx-sm fs-5 text-muted"></i>
|
|
</span>
|
|
</div>
|
|
);
|
|
};
|
|
|