diff --git a/src/components/PricingView.tsx b/src/components/PricingView.tsx index 6a7ca02..6d74548 100644 --- a/src/components/PricingView.tsx +++ b/src/components/PricingView.tsx @@ -50,6 +50,7 @@ function findCol(headers: string[], ...keywords: string[]): number { export function PricingView({ data, headers, onSaveRow, onCaptureState, onEdit, rowStatuses }: PricingViewProps) { const [filterMode, setFilterMode] = useState('all_errors'); const [search, setSearch] = useState(''); + const [searchMode, setSearchMode] = useState<'all' | 'selected'>('all'); const [editingCell, setEditingCell] = useState(null); const [savingCell, setSavingCell] = useState<{ rowIndex: number; colIndex: number } | null>(null); const inputRef = useRef(null); @@ -64,6 +65,7 @@ export function PricingView({ data, headers, onSaveRow, onCaptureState, onEdit, const [dynamicColFilters, setDynamicColFilters] = useState>({}); const [isSearchOpen, setIsSearchOpen] = useState(false); + const [selectedSearchItems, setSelectedSearchItems] = useState>(new Set()); const searchDropdownRef = useRef(null); // Close search dropdown on click outside @@ -78,13 +80,36 @@ export function PricingView({ data, headers, onSaveRow, onCaptureState, onEdit, }, []); const searchSuggestions = useMemo(() => { - if (!search) return data.slice(0, 50); // Show first 50 as default + if (!search && selectedSearchItems.size === 0) return data.slice(0, 50); + if (!search) return []; const s = search.toLowerCase(); return data.filter(r => String(r[COLUMNS.ARTICLE_NO] || '').toLowerCase().includes(s) || String(r[COLUMNS.ARTICLE_NAME] || '').toLowerCase().includes(s) ).slice(0, 50); - }, [data, search]); + }, [data, search, selectedSearchItems]); + + const handleSearchItemClick = (index: number) => { + const newSelected = new Set(selectedSearchItems); + if (newSelected.has(index)) { + newSelected.delete(index); + } else { + newSelected.add(index); + } + setSelectedSearchItems(newSelected); + }; + + const handleApplySearch = () => { + if (selectedSearchItems.size > 0) { + setSearchMode('selected'); + } + setIsSearchOpen(false); + }; + + const handleClearSearch = () => { + setSelectedSearchItems(new Set()); + setSearchMode('all'); + }; // ── Dynamic column detection ────────────────────────────────────────────── const { uvpIdx, srpCols, containerCols } = useMemo(() => { @@ -211,6 +236,14 @@ export function PricingView({ data, headers, onSaveRow, onCaptureState, onEdit, ); } + // Selected items from search dropdown + if (searchMode === 'selected' && selectedSearchItems.size > 0) { + result = result.filter(r => { + const articleNo = String(r.row[COLUMNS.ARTICLE_NO] || ''); + return selectedSearchItems.has(articleNo); + }); + } + // Column filters if (nameColFilter) { const s = nameColFilter.toLowerCase(); @@ -444,9 +477,18 @@ export function PricingView({ data, headers, onSaveRow, onCaptureState, onEdit, onFocus={() => setIsSearchOpen(true)} className="w-full pl-4 pr-10 py-2 bg-slate-800 border border-slate-700 rounded-lg text-sm text-white focus:outline-none focus:border-blue-500 focus:ring-1 focus:ring-blue-500 transition-all" /> - {search ? ( + {selectedSearchItems.size > 0 ? ( + ) : search ? ( + - ))} + {searchSuggestions.map((row, idx) => { + return ( + + ); + })} + +
+ +
{searchSuggestions.length === 50 && (
@@ -813,15 +890,17 @@ export function PricingView({ data, headers, onSaveRow, onCaptureState, onEdit, key={dataIndex} className={cn( 'border-b border-slate-700/50 transition-colors hover:bg-slate-700/20', - saveStatus === 'error' - ? 'bg-red-400/20 border-l-4 border-l-red-500' - : saveStatus === 'pending' - ? 'bg-yellow-400/20 border-l-4 border-l-yellow-400' - : isCritical - ? 'bg-red-950/20' - : pricingErrors.length > 0 - ? 'bg-amber-950/10' - : '' + isValidated + ? 'bg-emerald-500/5' + : saveStatus === 'error' + ? 'bg-red-400/20 border-l-4 border-l-red-500' + : saveStatus === 'pending' + ? 'bg-yellow-400/20 border-l-4 border-l-yellow-400' + : isCritical + ? 'bg-red-950/20' + : pricingErrors.length > 0 + ? 'bg-amber-950/10' + : '' )} > {/* Art. No. */} @@ -953,8 +1032,11 @@ export function PricingView({ data, headers, onSaveRow, onCaptureState, onEdit, ))} - {/* Actions sticky */} - +