diff --git a/frontend/src/components/contacts/FilterPanel.tsx b/frontend/src/components/contacts/FilterPanel.tsx index dc9a019..ead1a9d 100644 --- a/frontend/src/components/contacts/FilterPanel.tsx +++ b/frontend/src/components/contacts/FilterPanel.tsx @@ -4,7 +4,7 @@ */ import React, { useState, useRef, useEffect, useMemo } from 'react'; -import { Filter, Plus, X, ChevronDown } from 'lucide-react'; +import { Filter, Plus, X, ChevronDown, Bookmark } from 'lucide-react'; import type { UnifiedContact } from '@/api/unifiedContacts'; // ─── Field definitions ─────────────────────────────────────────────────────── @@ -215,10 +215,20 @@ function getOrderedFields(contactType?: 'company' | 'person' | undefined): Filte // ─── Component ──────────────────────────────────────────────────────────────── +export interface SavedFilter { + id: string; + name: string; + filterState: FilterState; +} + interface FilterPanelProps { filters: FilterState; onFiltersChange: (filters: FilterState) => void; contactType?: 'company' | 'person' | undefined; + savedFilters?: SavedFilter[]; + onSaveFilter?: (name: string, filterState: FilterState) => void; + onLoadFilter?: (filterState: FilterState) => void; + onDeleteFilter?: (id: string) => void; } let condIdCounter = 0; @@ -226,7 +236,7 @@ function newConditionId() { return `cond-${Date.now()}-${++condIdCounter}`; } -export function FilterPanel({ filters, onFiltersChange, contactType }: FilterPanelProps) { +export function FilterPanel({ filters, onFiltersChange, contactType, savedFilters = [], onSaveFilter, onLoadFilter, onDeleteFilter }: FilterPanelProps) { const [open, setOpen] = useState(false); const btnRef = useRef(null); const panelRef = useRef(null); @@ -290,6 +300,14 @@ export function FilterPanel({ filters, onFiltersChange, contactType }: FilterPan onFiltersChange({ ...filters, logic: filters.logic === 'AND' ? 'OR' : 'AND' }); }; + const handleSaveFilter = () => { + if (!onSaveFilter) return; + if (filters.conditions.length === 0) return; + const name = window.prompt('Name für diesen Filter:', 'Mein Filter'); + if (!name) return; + onSaveFilter(name, { ...filters, conditions: filters.conditions.map((c) => ({ ...c })) }); + }; + // Group fields by group for the dropdown const groupedFields = useMemo(() => { const groups: Record = {}; @@ -423,6 +441,32 @@ export function FilterPanel({ filters, onFiltersChange, contactType }: FilterPan )} + {/* Saved filters */} + {savedFilters.length > 0 && ( +
+
Gespeicherte Filter
+
+ {savedFilters.map((sf) => ( +
+ + +
+ ))} +
+
+ )} + {/* Filter rows */}
{filters.conditions.length === 0 && ( @@ -526,13 +570,24 @@ export function FilterPanel({ filters, onFiltersChange, contactType }: FilterPan {/* Footer */}
- +
+ + {activeCount > 0 && onSaveFilter && ( + + )} +