diff --git a/src/components/PricingView.tsx b/src/components/PricingView.tsx index 825c77d..dba301d 100644 --- a/src/components/PricingView.tsx +++ b/src/components/PricingView.tsx @@ -15,6 +15,7 @@ import { Check, Search, MessageSquare, + Maximize2, } from 'lucide-react'; import { cn } from '../lib/utils'; import { ColumnFilterPopover } from './ColumnFilterPopover'; @@ -78,6 +79,7 @@ export function PricingView({ data, headers, onSaveRow, onCaptureState, onEdit, const inputRef = useRef(null); const [lineMultiFilter, setLineMultiFilter] = useState([]); const [classificationFilter, setClassificationFilter] = useState([]); + const [productTypeFilter, setProductTypeFilter] = useState([]); const [nameColFilter, setNameColFilter] = useState(''); const [openFilter, setOpenFilter] = useState(null); const [unitsOuterFilter, setUnitsOuterFilter] = useState([]); @@ -92,6 +94,7 @@ export function PricingView({ data, headers, onSaveRow, onCaptureState, onEdit, const typeInputRef = useRef(null); const logisticInputRef = useRef(null); const [sortConfig, setSortConfig] = useState<{ key: string | number; direction: 'asc' | 'desc' | null }>({ key: null, direction: null }); + const [isFullscreen, setIsFullscreen] = useState(false); const [isSearchOpen, setIsSearchOpen] = useState(false); const [selectedSearchItems, setSelectedSearchItems] = useState>(new Set()); @@ -276,6 +279,10 @@ export function PricingView({ data, headers, onSaveRow, onCaptureState, onEdit, Array.from(new Set(data.map(r => String(r[COLUMNS.CLASSIFICATION] || '')))).sort(), [data]); + const uniqueProductTypes = useMemo(() => + Array.from(new Set(data.map(r => String(r[COLUMNS.PRODUCT_TYPE] || '')).filter(Boolean))).sort(), + [data]); + const uniqueUnitsOuter = useMemo(() => Array.from(new Set(data.map(r => String(r[unitsOuterIdx] || '')))).filter(v => v).sort(), [data, unitsOuterIdx]); @@ -331,6 +338,9 @@ export function PricingView({ data, headers, onSaveRow, onCaptureState, onEdit, if (classificationFilter.length > 0) { result = result.filter(r => classificationFilter.includes(String(r.row[COLUMNS.CLASSIFICATION] || ''))); } + if (productTypeFilter.length > 0) { + result = result.filter(r => productTypeFilter.includes(String(r.row[COLUMNS.PRODUCT_TYPE] || ''))); + } if (unitsOuterFilter.length > 0) { result = result.filter(r => unitsOuterFilter.includes(String(r.row[unitsOuterIdx] || ''))); } @@ -361,7 +371,7 @@ export function PricingView({ data, headers, onSaveRow, onCaptureState, onEdit, } return result; - }, [analyzedRows, filterMode, search, nameColFilter, lineMultiFilter, classificationFilter, unitsOuterFilter, outerWFilter, outerLFilter, outerHFilter, dynamicColFilters, weightIssueFilter]); + }, [analyzedRows, filterMode, search, nameColFilter, lineMultiFilter, classificationFilter, productTypeFilter, unitsOuterFilter, outerWFilter, outerLFilter, outerHFilter, dynamicColFilters, weightIssueFilter]); // ── Sorted rows ────────────────────────────────────────────────────────── const sortedRows = useMemo(() => { @@ -646,7 +656,16 @@ export function PricingView({ data, headers, onSaveRow, onCaptureState, onEdit, ]; return ( -
+
+ {isFullscreen && ( + + )} {/* ── Anna Note Editor Modal ── */} {annaEditor && (
@@ -857,6 +876,13 @@ export function PricingView({ data, headers, onSaveRow, onCaptureState, onEdit, } color="amber" /> } color="red" /> } color="emerald" /> +
{/* ── Table ── */} @@ -951,7 +977,25 @@ export function PricingView({ data, headers, onSaveRow, onCaptureState, onEdit, handleSort('productType')}> - Type + + Type + + + {openFilter === 'productType' && ( + setProductTypeFilter((prev: string[]) => prev.includes(val) ? prev.filter((v: string) => v !== val) : [...prev, val])} + onSelectAll={vals => setProductTypeFilter(vals)} + onClear={() => { setProductTypeFilter([]); setOpenFilter(null); }} + onClose={() => setOpenFilter(null)} + /> + )} { e.stopPropagation(); handleResizeStart(e, 'productType', columnWidths.productType); }} />