"use client" import * as React from "react" import { format, addDays, startOfDay, endOfDay, isSameDay, isWithinInterval, getMonth, getYear, setMonth, setYear } from "date-fns" import { Calendar as CalendarIcon, ChevronLeft, ChevronRight, X } from "lucide-react" import { DateRange } from "react-day-picker" import { cn } from "@/lib/utils/styles" import { Button } from "@/components/ui/button" import { Calendar } from "@/components/ui/calendar" import { Popover, PopoverContent, PopoverTrigger, } from "@/components/ui/popover" import { Badge } from "@/components/ui/badge" import { Input } from "@/components/ui/input" import { Label } from "@/components/ui/label" import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select" interface DatePickerProps { date?: Date onDateChange?: (date: Date | undefined) => void placeholder?: string className?: string } interface DateRangePickerProps { dateRange?: DateRange onDateRangeChange?: (range: DateRange | undefined) => void placeholder?: string className?: string showPresets?: boolean disabled?: boolean } interface MonthPickerProps { selectedMonth?: Date onMonthChange?: (date: Date | undefined) => void placeholder?: string className?: string disabled?: boolean } // Single Date Picker export function DatePicker({ date, onDateChange, placeholder = "Pick a date", className }: DatePickerProps) { return ( ) } // Month Picker Component export function MonthPicker({ selectedMonth, onMonthChange, placeholder = "Pick a month", className, disabled = false }: MonthPickerProps) { const [isOpen, setIsOpen] = React.useState(false) const [selectedYear, setSelectedYear] = React.useState(selectedMonth ? getYear(selectedMonth) : new Date().getFullYear()) const [selectedMonthIndex, setSelectedMonthIndex] = React.useState(selectedMonth ? getMonth(selectedMonth) : new Date().getMonth()) const months = [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ] const years = Array.from({ length: 10 }, (_, i) => new Date().getFullYear() - 5 + i) React.useEffect(() => { if (selectedMonth) { setSelectedYear(getYear(selectedMonth)) setSelectedMonthIndex(getMonth(selectedMonth)) } }, [selectedMonth]) const handleMonthSelect = (monthIndex: number) => { const newDate = new Date(selectedYear, monthIndex, 1) onMonthChange?.(newDate) setIsOpen(false) } const handleYearChange = (year: string) => { const newYear = parseInt(year) setSelectedYear(newYear) if (selectedMonth) { const newDate = new Date(newYear, selectedMonthIndex, 1) onMonthChange?.(newDate) } } const formatSelectedMonth = (date?: Date) => { if (!date) return placeholder return format(date, "MMMM yyyy") } return ( )}

Select Month

{months.map((month, index) => ( ))}
) } // Date Range Picker with Presets export function DateRangePicker({ dateRange, onDateRangeChange, placeholder = "Pick a date range", className, showPresets = true, disabled = false }: DateRangePickerProps) { const [isOpen, setIsOpen] = React.useState(false) const presets = [ { label: "Today", value: { from: startOfDay(new Date()), to: endOfDay(new Date()) } }, { label: "Yesterday", value: { from: startOfDay(addDays(new Date(), -1)), to: endOfDay(addDays(new Date(), -1)) } }, { label: "Last 7 days", value: { from: startOfDay(addDays(new Date(), -6)), to: endOfDay(new Date()) } }, { label: "Last 30 days", value: { from: startOfDay(addDays(new Date(), -29)), to: endOfDay(new Date()) } }, { label: "This month", value: { from: startOfDay(new Date(new Date().getFullYear(), new Date().getMonth(), 1)), to: endOfDay(new Date()) } }, { label: "Last month", value: { from: startOfDay(new Date(new Date().getFullYear(), new Date().getMonth() - 1, 1)), to: endOfDay(new Date(new Date().getFullYear(), new Date().getMonth(), 0)) } } ] const handlePresetClick = (preset: typeof presets[0]) => { onDateRangeChange?.(preset.value) setIsOpen(false) } const handleClear = () => { onDateRangeChange?.(undefined) setIsOpen(false) } const formatDateRange = (range: DateRange | undefined) => { if (!range?.from) return placeholder if (!range.to) { return format(range.from, "PPP") } if (isSameDay(range.from, range.to)) { return format(range.from, "PPP") } return `${format(range.from, "MMM dd")} - ${format(range.to, "MMM dd, yyyy")}` } return ( )}
{showPresets && (
{presets.map((preset) => ( ))}
)}
) } // Custom Date Range Input Component export function CustomDateRangeInput({ dateRange, onDateRangeChange, className }: DateRangePickerProps) { const [fromDate, setFromDate] = React.useState("") const [toDate, setToDate] = React.useState("") React.useEffect(() => { if (dateRange?.from) { setFromDate(format(dateRange.from, "yyyy-MM-dd")) } if (dateRange?.to) { setToDate(format(dateRange.to, "yyyy-MM-dd")) } }, [dateRange]) const handleFromDateChange = (value: string) => { setFromDate(value) const from = value ? new Date(value) : undefined const to = toDate ? new Date(toDate) : dateRange?.to if (from && to && from > to) { // If from date is after to date, adjust to date onDateRangeChange?.({ from, to: from }) setToDate(value) } else { onDateRangeChange?.({ from, to }) } } const handleToDateChange = (value: string) => { setToDate(value) const from = fromDate ? new Date(fromDate) : dateRange?.from const to = value ? new Date(value) : undefined if (from && to && from > to) { // If to date is before from date, adjust from date onDateRangeChange?.({ from: to, to }) setFromDate(value) } else { onDateRangeChange?.({ from, to }) } } return (
handleFromDateChange(e.target.value)} className="w-32" />
handleToDateChange(e.target.value)} className="w-32" />
) } // Date Range Display Component export function DateRangeDisplay({ dateRange }: { dateRange?: DateRange }) { if (!dateRange?.from) return null const daysDiff = dateRange.to ? Math.ceil((dateRange.to.getTime() - dateRange.from.getTime()) / (1000 * 60 * 60 * 24)) + 1 : 1 return (
{daysDiff} day{daysDiff !== 1 ? 's' : ''} {format(dateRange.from, "MMM dd")} {dateRange.to && !isSameDay(dateRange.from, dateRange.to) && ( <> - {format(dateRange.to, "MMM dd, yyyy")} )}
) }