// components/ui/date-range-picker.tsx import * as React from 'react'; import { View, Pressable } from 'react-native'; import { cva, type VariantProps } from 'class-variance-authority'; import { cn } from '@/lib/utils'; import { Text } from './text'; import { Button } from './button'; import { Dialog, DialogContent } from './dialog'; import { Calendar } from './calendar'; import { CalendarDays } from 'lucide-react-native'; import { useThemeColors } from '@/hooks/useThemeColors'; import dayjs from 'dayjs'; // Date Range Picker Trigger Variants const dateRangePickerTriggerVariants = cva( 'flex-row items-center justify-between rounded-lg border', { variants: { variant: { default: 'border-input bg-background', outline: 'border-input bg-transparent', filled: 'border-transparent bg-muted', }, size: { sm: 'px-3 py-2', md: 'px-4 py-3', lg: 'px-5 py-4', }, }, defaultVariants: { variant: 'default', size: 'md', }, } ); interface DateRangePickerProps extends VariantProps { startDate?: Date; endDate?: Date; onRangeChange?: (startDate: Date | undefined, endDate: Date | undefined) => void; children: React.ReactNode; minDate?: Date; maxDate?: Date; maxDays?: number; } interface DateRangePickerTriggerProps { className?: string; children: React.ReactNode; } interface DateRangePickerContentProps { className?: string; } const DateRangePickerContext = React.createContext<{ startDate?: Date; endDate?: Date; onRangeChange?: (startDate: Date | undefined, endDate: Date | undefined) => void; open: boolean; setOpen: (open: boolean) => void; minDate?: Date; maxDate?: Date; maxDays?: number; variant: 'default' | 'outline' | 'filled'; size: 'sm' | 'md' | 'lg'; } | null>(null); function useDateRangePicker() { const context = React.useContext(DateRangePickerContext); if (!context) { throw new Error('DateRangePicker components must be used within DateRangePicker'); } return context; } export function DateRangePicker({ startDate, endDate, onRangeChange, children, minDate, maxDate, maxDays, variant = 'default', size = 'md', }: DateRangePickerProps) { const [open, setOpen] = React.useState(false); return ( {children} ); } export function DateRangePickerTrigger({ className, children }: DateRangePickerTriggerProps) { const { setOpen, variant, size } = useDateRangePicker(); return ( setOpen(true)} className={cn( dateRangePickerTriggerVariants({ variant, size }), className )} > {children} ); } export function DateRangePickerContent({ className }: DateRangePickerContentProps) { const { startDate, endDate, onRangeChange, setOpen, minDate, maxDate, maxDays } = useDateRangePicker(); const [tempStartDate, setTempStartDate] = React.useState(startDate); const [tempEndDate, setTempEndDate] = React.useState(endDate); const handleRangeChange = (start: Date | undefined, end: Date | undefined) => { setTempStartDate(start); setTempEndDate(end); }; const handleApply = () => { if (tempStartDate && tempEndDate) { onRangeChange?.(tempStartDate, tempEndDate); setOpen(false); } }; const handleClear = () => { setTempStartDate(undefined); setTempEndDate(undefined); onRangeChange?.(undefined, undefined); }; const handleCancel = () => { setTempStartDate(startDate); setTempEndDate(endDate); setOpen(false); }; return ( {/* Calendar with range mode */} {/* Selected Range Info */} {tempStartDate && ( {tempEndDate ? `${dayjs(tempStartDate).format('MMM DD, YYYY')} - ${dayjs(tempEndDate).format('MMM DD, YYYY')}` : `Start: ${dayjs(tempStartDate).format('MMM DD, YYYY')} (Select end date)`} {tempStartDate && tempEndDate && ( {dayjs(tempEndDate).diff(dayjs(tempStartDate), 'day') + 1} days )} )} {/* Action Buttons */} ); } export function DateRangePickerValue({ placeholder = 'Select date range', format = 'MMM DD, YYYY', className, showIcon = true, }: { placeholder?: string; format?: string; className?: string; showIcon?: boolean; }) { const { startDate, endDate } = useDateRangePicker(); const { colors } = useThemeColors(); const hasValue = startDate && endDate; return ( <> {hasValue ? `${dayjs(startDate).format(format)} - ${dayjs(endDate).format(format)}` : placeholder} {showIcon && ( )} ); }