Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 | 117x 5x 5x 5x 5x 5x 117x 2x 2x 20x 20x 20x 20x 20x 20x 1x 1x 20x 20x 2x 2x 2x 2x 2x 2x 2x 20x 20x | import { useRef, useState } from "react";
import moment from "moment";
import FilterItem from "./FilterItem";
import GiveDateRangePicker from "@shared/DateRangePicker/GiveDateRangePicker";
import { RangeValue } from "@shared/DateRangePicker/DateRangePicker.types";
import { formatForInput } from "@shared/DateRangePicker/utils";
import { DateValue } from "../types";
import { useCustomThemeV2 } from "@theme/hooks/useCustomThemeV2";
interface IDateSelectorProps {
selectedDate: DateValue | undefined;
onChange: (date: DateValue | undefined) => void;
}
const formatDateLabel = (date: DateValue): string => {
const format = "MMM D, YYYY";
const start = date.startDate ? moment(date.startDate).format(format) : "";
const end = date.endDate ? moment(date.endDate).format(format) : "";
Iif (start && end && start === end) return start;
Eif (start && end) return `${start} - ${end}`;
if (start) return start;
return "";
};
const parseRangeToDateValue = (value: RangeValue): DateValue => {
const { startDate: formattedStart, endDate: formattedEnd } = formatForInput(
value,
true,
);
return {
startDate: moment(formattedStart, "MM/DD/YYYY").toDate(),
endDate: moment(formattedEnd, "MM/DD/YYYY").toDate(),
};
};
export default function DateSelector({
selectedDate,
onChange,
}: IDateSelectorProps) {
const { isMobileView } = useCustomThemeV2();
const [anchorEl, setAnchorEl] = useState<HTMLDivElement | null>(null);
const clickCountRef = useRef(0);
const isSelected = !!selectedDate;
const label = isSelected ? formatDateLabel(selectedDate) : "Date";
const handleOpen = (e: React.MouseEvent<HTMLElement>) => {
clickCountRef.current = 0;
setAnchorEl(e.currentTarget as HTMLDivElement);
};
const handleClear = (e: React.MouseEvent) => {
e.stopPropagation();
onChange(undefined);
};
const handleChange = (value: RangeValue | string) => {
Iif (typeof value === "string") return;
Iif (!value.startDate || !value.endDate) return;
Iif (isMobileView) {
// Mobile: don't apply here; apply only when user taps Apply (onApply)
return;
}
clickCountRef.current += 1;
Eif (
clickCountRef.current >= 2 ||
(value.startDate?.toString() !== value.endDate?.toString() &&
value.endDate)
) {
onChange(parseRangeToDateValue(value));
setAnchorEl(null);
}
};
const handleMobileApply = (range: RangeValue) => {
if (!range.startDate || !range.endDate) return;
onChange(parseRangeToDateValue(range));
};
return (
<>
<FilterItem
isSelected={isSelected}
title={label}
onClick={handleOpen}
onCancel={handleClear}
isOpen={Boolean(anchorEl)}
/>
{/* High z-index to ensure popover appears above GiveDraggableModal */}
<GiveDateRangePicker
value={selectedDate || { startDate: undefined, endDate: undefined }}
onChange={handleChange}
maxDate={new Date()}
customAnchorEl={anchorEl}
onClose={() => setAnchorEl(null)}
popoverZIndex={1000000}
useUTCMoment
onApply={isMobileView ? handleMobileApply : undefined}
/>
</>
);
}
|