// components/ui/date-range-picker.tsx
import * as React from 'react';
import { View, Text, Pressable } from 'react-native';
import { cn } from '@/lib/utils';
import { Dialog, DialogContent } from './dialog';
import { Calendar } from './calendar';
import dayjs from 'dayjs';
interface DateRangePickerProps {
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;
} | 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,
}: DateRangePickerProps) {
const [open, setOpen] = React.useState(false);
return (
);
}
export function DateRangePickerTrigger({ className, children }: DateRangePickerTriggerProps) {
const { setOpen } = useDateRangePicker();
return (
setOpen(true)}
className={cn(
'flex-row items-center justify-between px-4 py-3 border border-slate-300 rounded-lg bg-white',
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 */}
Clear
Cancel
Apply
);
}
export function DateRangePickerValue({
placeholder = 'Select date range',
format = 'MMM DD, YYYY',
className,
}: {
placeholder?: string;
format?: string;
className?: string;
}) {
const { startDate, endDate } = useDateRangePicker();
return (
{startDate && endDate
? `${dayjs(startDate).format(format)} - ${dayjs(endDate).format(format)}`
: placeholder}
);
}