'use client'; /** * DateRangeFilter — Date range filter with preset buttons and custom date picker. * * Features: * - Preset buttons: Last 7 Days, Last 30 Days, Last 90 Days, Last 12 Months, Year to Date * - Custom date range picker with start/end date inputs * - Displays currently selected range as text (e.g., "Jan 1, 2025 – Jun 30, 2025") * - Defaults to "Last 12 Months" * - Validation: start date must be before end date * - Uses the filter store to manage state * - Uses date utilities for preset calculations * * Requirements: 15.1, 15.2, 15.3, 15.4, 15.5, 15.6 */ import { useState } from 'react'; import { useFilterStore } from '@/lib/stores/filter-store'; import { datePresets, buildCustomDateRange, formatDateRange, type DateRange, } from '@/lib/utils/date'; interface DateRangeFilterProps { onRangeChange?: (range: DateRange) => void; } export default function DateRangeFilter({ onRangeChange }: DateRangeFilterProps) { const { dateRange, setDateRange } = useFilterStore(); const [showCustom, setShowCustom] = useState(false); const [customStart, setCustomStart] = useState(''); const [customEnd, setCustomEnd] = useState(''); const [validationError, setValidationError] = useState(null); const handlePresetClick = (preset: (typeof datePresets)[number]) => { const range = preset.buildRange(); setDateRange(range); onRangeChange?.(range); setShowCustom(false); setValidationError(null); }; const handleCustomApply = () => { setValidationError(null); if (!customStart || !customEnd) { setValidationError('Please select both start and end dates.'); return; } const start = new Date(customStart + 'T00:00:00'); const end = new Date(customEnd + 'T00:00:00'); if (isNaN(start.getTime()) || isNaN(end.getTime())) { setValidationError('Invalid date format.'); return; } if (start >= end) { setValidationError('Start date must be before end date.'); return; } try { const range = buildCustomDateRange(start, end); setDateRange(range); onRangeChange?.(range); setShowCustom(false); } catch { setValidationError('Start date must be before end date.'); } }; return (
{/* Current range display */}

{dateRange.label || formatDateRange(dateRange)}

{/* Preset buttons */}
{datePresets.map((preset) => ( ))}
{/* Custom date picker */} {showCustom && (
{ setCustomStart(e.target.value); setValidationError(null); }} className="px-3 py-1.5 text-xs rounded-lg bg-divisi-bg border border-divisi-border text-divisi-text-primary focus:outline-none focus:border-divisi-accent" />
{ setCustomEnd(e.target.value); setValidationError(null); }} className="px-3 py-1.5 text-xs rounded-lg bg-divisi-bg border border-divisi-border text-divisi-text-primary focus:outline-none focus:border-divisi-accent" />
)} {/* Validation error */} {validationError && (

{validationError}

)}
); }