import { useState } from "react";
import { Calendar as CalendarIcon, X } from "lucide-react";
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
import { Calendar } from "@/components/ui/calendar";
import { Button } from "@/components/ui/button";
import { useMoney } from "@/hooks/useMoney";
import { toDateString } from "@/lib/format";
import { parseLocalDate, cn } from "@/lib/utils";
interface Props {
/** "YYYY-MM-DD", or null/"" for no date picked. */
value: string | null;
onChange: (value: string | null) => void;
/** No date after this one is selectable. */
maxDate?: Date;
/** No date before this one is selectable. */
minDate?: Date;
placeholder?: string;
/** Shows a small clear button once a date is picked - for optional dates
* (a todo's due date, an asset's purchase date). Omit for a date that's
* always required (a report range's start/end). */
clearable?: boolean;
className?: string;
"aria-label"?: string;
}
/**
* The app's own calendar popover in place of the browser's native
* ``, whose chrome (icon, dropdown styling, light/dark
* behavior) is entirely OS/browser-drawn and can't be made to match the
* rest of the UI. Every other date-pickable field already used this
* Popover+Calendar pattern inline (AddTransactionDialog, Reports' own
* previous picker, GoalsTracker, the investment dialogs); this pulls it
* into one place instead of a sixth copy.
*/
export function DatePicker({
value, onChange, maxDate, minDate, placeholder = "Pick a date", clearable, className, "aria-label": ariaLabel,
}: Props) {
const [open, setOpen] = useState(false);
const { date: fmt } = useMoney();
const selected = value ? parseLocalDate(value) : undefined;
return (
{ if (d) onChange(toDateString(d)); setOpen(false); }}
disabled={(d) => (maxDate != null && d > maxDate) || (minDate != null && d < minDate)}
defaultMonth={selected ?? maxDate}
initialFocus
/>
);
}