Files
CPLv4.0/components/common/DateRangePicker.tsx

124 lines
3.9 KiB
TypeScript

// /components/common/DateRangePicker.tsx
import React, { useEffect } from "react";
import DatePicker from "react-datepicker";
import { useSelector, useDispatch } from "react-redux";
import { RootState } from "@/redux/store";
import { setVonDatum, setBisDatum } from "@/redux/slices/dateRangePickerSlice";
import "react-datepicker/dist/react-datepicker.css";
interface DateRangePickerProps {
compact?: boolean; // reduziert horizontale Breite
className?: string;
}
const DateRangePicker: React.FC<DateRangePickerProps> = ({
compact = false,
className = "",
}) => {
const dispatch = useDispatch();
const reduxVonDatum = useSelector(
(state: RootState) => state.dateRangePicker.vonDatum
);
const reduxBisDatum = useSelector(
(state: RootState) => state.dateRangePicker.bisDatum
);
const today = new Date();
const thirtyDaysAgo = new Date();
thirtyDaysAgo.setDate(today.getDate() - 30);
const sixMonthsAgo = new Date();
sixMonthsAgo.setMonth(today.getMonth() - 6);
const parseISODate = (isoDate: string) => {
const [year, month, day] = isoDate.split("-").map(Number);
return new Date(year, month - 1, day);
};
const formatISO = (date: Date) => date.toLocaleDateString("sv-SE"); // = "YYYY-MM-DD"
// Nur beim ersten Rendern initiale Werte setzen
useEffect(() => {
if (!reduxVonDatum) dispatch(setVonDatum(formatISO(thirtyDaysAgo)));
if (!reduxBisDatum) dispatch(setBisDatum(formatISO(today)));
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [dispatch, reduxVonDatum, reduxBisDatum]);
const gapClass = compact ? "space-x-2" : "space-x-4";
const labelWidthClass = compact ? "w-6" : "w-auto";
const inputWidthClass = compact ? "w-32" : "w-44"; // ca. 128px vs 176px
return (
<div className={`flex ${gapClass} items-center ${className}`}>
<div
className={`flex items-center space-x-1 ${compact ? "text-xs" : ""}`}
>
<label
className={`block font-semibold ${
compact ? "text-xs" : "text-sm"
} ${labelWidthClass}`}
>
Von
</label>
<DatePicker
selected={reduxVonDatum ? parseISODate(reduxVonDatum) : thirtyDaysAgo}
onChange={(date) => {
if (date) {
dispatch(setVonDatum(formatISO(date)));
}
}}
selectsStart
startDate={
reduxVonDatum ? parseISODate(reduxVonDatum) : thirtyDaysAgo
}
endDate={reduxBisDatum ? parseISODate(reduxBisDatum) : today}
minDate={sixMonthsAgo}
maxDate={today}
dateFormat="dd.MM.yyyy"
portalId="root-portal"
popperClassName="custom-datepicker-popper"
className={`border px-2 py-1 rounded ${inputWidthClass} ${
compact ? "text-xs" : "text-sm"
}`}
/>
</div>
<div
className={`flex items-center space-x-1 ${compact ? "text-xs" : ""}`}
>
<label
className={`block font-semibold ${
compact ? "text-xs" : "text-sm"
} ${labelWidthClass}`}
>
Bis
</label>
<DatePicker
selected={reduxBisDatum ? parseISODate(reduxBisDatum) : today}
onChange={(date) => {
if (date) {
dispatch(setBisDatum(formatISO(date)));
}
}}
selectsEnd
startDate={
reduxVonDatum ? parseISODate(reduxVonDatum) : thirtyDaysAgo
}
endDate={reduxBisDatum ? parseISODate(reduxBisDatum) : today}
minDate={sixMonthsAgo}
maxDate={today}
dateFormat="dd.MM.yyyy"
portalId="root-portal"
popperClassName="custom-datepicker-popper"
className={`border px-2 py-1 rounded ${inputWidthClass} ${
compact ? "text-xs" : "text-sm"
}`}
/>
</div>
</div>
);
};
export default DateRangePicker;