diff --git a/src/components/DateFilterPopover.tsx b/src/components/DateFilterPopover.tsx
new file mode 100644
index 0000000..f935700
--- /dev/null
+++ b/src/components/DateFilterPopover.tsx
@@ -0,0 +1,85 @@
+import React, { useState } from 'react';
+import { Calendar } from 'lucide-react';
+import { cn } from '../lib/utils';
+
+interface DateFilterPopoverProps {
+ selectedRange: { start: string; end: string };
+ onRangeChange: (range: { start: string; end: string }) => void;
+ onClose: () => void;
+}
+
+export function DateFilterPopover({ selectedRange, onRangeChange, onClose }: DateFilterPopoverProps) {
+ const [startDate, setStartDate] = useState(selectedRange.start);
+ const [endDate, setEndDate] = useState(selectedRange.end);
+
+ const handleApply = () => {
+ onRangeChange({ start: startDate, end: endDate });
+ onClose();
+ };
+
+ const handleClear = () => {
+ setStartDate('');
+ setEndDate('');
+ onRangeChange({ start: '', end: '' });
+ onClose();
+ };
+
+ const hasValue = startDate || endDate;
+
+ return (
+
e.stopPropagation()}
+ >
+
+
+ Filter by Date Range
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
\ No newline at end of file
diff --git a/src/components/MissingDataView.tsx b/src/components/MissingDataView.tsx
index da24857..2ebf3e8 100644
--- a/src/components/MissingDataView.tsx
+++ b/src/components/MissingDataView.tsx
@@ -3,6 +3,7 @@ import { ExcelRow, COLUMNS } from '../types';
import { Search, ChevronDown, ChevronUp, X, Edit2, Save } from 'lucide-react';
import { cn } from '../lib/utils';
import { ColumnFilterPopover } from './ColumnFilterPopover';
+import { DateFilterPopover } from './DateFilterPopover';
interface MissingDataViewProps {
data: ExcelRow[];
@@ -72,6 +73,7 @@ export function MissingDataView({ data, headers, onSaveRow, onCaptureState }: Mi
const [page, setPage] = useState(1);
const [editing, setEditing] = useState(null);
const [columnFilters, setColumnFilters] = useState>({});
+ const [dateFilters, setDateFilters] = useState>({});
const [openFilter, setOpenFilter] = useState(null);
const pageSize = 100;
@@ -137,6 +139,7 @@ export function MissingDataView({ data, headers, onSaveRow, onCaptureState }: Mi
(Object.entries(columnFilters) as [string, string[]][]).forEach(([colIdx, filterValues]) => {
if (!filterValues || filterValues.length === 0) return;
const colIdxNum = parseInt(colIdx);
+ if (colIdxNum === launchDateCol || colIdxNum === readyToOrderCol) return;
result = result.filter(r => {
const val: any = r.row[colIdxNum];
const displayVal = colIdxNum === launchDateCol || colIdxNum === readyToOrderCol
@@ -146,6 +149,29 @@ export function MissingDataView({ data, headers, onSaveRow, onCaptureState }: Mi
});
});
+ (Object.entries(dateFilters) as [string, { start: string; end: string }][]).forEach(([colIdx, range]) => {
+ if (!range.start && !range.end) return;
+ const colIdxNum = parseInt(colIdx);
+ result = result.filter(r => {
+ const val = r.row[colIdxNum];
+ const dateStr = formatDateValue(val) || String(val ?? '');
+ if (!dateStr) return false;
+ const parts = dateStr.split('/');
+ if (parts.length !== 3) return false;
+ const rowDate = new Date(`${parts[2]}-${parts[1]}-${parts[0]}`);
+ if (isNaN(rowDate.getTime())) return false;
+ if (range.start) {
+ const startDate = new Date(range.start);
+ if (rowDate < startDate) return false;
+ }
+ if (range.end) {
+ const endDate = new Date(range.end);
+ if (rowDate > endDate) return false;
+ }
+ return true;
+ });
+ });
+
if (sortCol !== null) {
result.sort((a, b) => {
const valA = a.row[sortCol];
@@ -269,31 +295,61 @@ export function MissingDataView({ data, headers, onSaveRow, onCaptureState }: Mi
)}
-
- {openFilter === col && (
- setColumnFilters(prev => {
- const current = prev[col] || [];
- if (current.includes(val)) {
- return { ...prev, [col]: current.filter(v => v !== val) };
- }
- return { ...prev, [col]: [...current, val] };
- })}
- onSelectAll={(vals) => setColumnFilters(prev => ({ ...prev, [col]: vals }))}
- onClear={() => { setColumnFilters(prev => { const n = { ...prev }; delete n[col]; return n; }); }}
- onClose={() => setOpenFilter(null)}
- />
+ {col === launchDateCol || col === readyToOrderCol ? (
+ <>
+
+ {openFilter === col && (
+ setDateFilters(prev => ({ ...prev, [col]: range }))}
+ onClose={() => setOpenFilter(null)}
+ />
+ )}
+ >
+ ) : (
+ <>
+
+ {openFilter === col && (
+ setColumnFilters(prev => {
+ const current = prev[col] || [];
+ if (current.includes(val)) {
+ return { ...prev, [col]: current.filter(v => v !== val) };
+ }
+ return { ...prev, [col]: [...current, val] };
+ })}
+ onSelectAll={(vals) => setColumnFilters(prev => ({ ...prev, [col]: vals }))}
+ onClear={() => { setColumnFilters(prev => { const n = { ...prev }; delete n[col]; return n; }); }}
+ onClose={() => setOpenFilter(null)}
+ />
+ )}
+ >
)}