import { Input, Button, Select, Tag, Segmented, DatePicker } from "antd"; import { BarsOutlined, AppstoreOutlined, SearchOutlined, ReloadOutlined, } from "@ant-design/icons"; import { useEffect, useState } from "react"; interface FilterOption { key: string; label: string; mode?: "tags" | "multiple"; options: { label: string; value: string }[]; } interface SearchControlsProps { searchTerm: string; onSearchChange: (value: string) => void; searchPlaceholder?: string; // Filter props filters?: FilterOption[]; selectedFilters?: Record; onFiltersChange?: (filters: Record) => void; onClearFilters?: () => void; // Date range props dateRange?: [Date | null, Date | null] | null; onDateChange?: (dates: [Date | null, Date | null] | null) => void; // Reload props onReload?: () => void; // View props viewMode?: "card" | "list"; onViewModeChange?: (mode: "card" | "list") => void; // Control visibility showFilters?: boolean; showSort?: boolean; showViewToggle?: boolean; showReload?: boolean; showDatePicker?: boolean; // Styling className?: string; } export function SearchControls({ viewMode, className, searchTerm, showFilters = true, showViewToggle = true, searchPlaceholder = "搜索...", filters = [], dateRange, showDatePicker = false, showReload = true, onReload, onDateChange, onSearchChange, onFiltersChange, onViewModeChange, onClearFilters, }: SearchControlsProps) { const [selectedFilters, setSelectedFilters] = useState<{ [key: string]: string[]; }>({}); const filtersMap: Record = filters.reduce( (prev, cur) => ({ ...prev, [cur.key]: cur }), {} ); // select change const handleFilterChange = (filterKey: string, value: string) => { const filteredValues = { ...selectedFilters, [filterKey]: !value ? [] : [value], }; setSelectedFilters(filteredValues); }; // 清除已选筛选 const handleClearFilter = (filterKey: string, value: string | string[]) => { const isMultiple = filtersMap[filterKey]?.mode === "multiple"; if (!isMultiple) { setSelectedFilters({ ...selectedFilters, [filterKey]: [], }); } else { const currentValues = selectedFilters[filterKey]?.[0] || []; const newValues = currentValues.filter((v) => v !== value); setSelectedFilters({ ...selectedFilters, [filterKey]: [newValues], }); } }; const handleClearAllFilters = () => { setSelectedFilters({}); onClearFilters?.(); }; const hasActiveFilters = Object.values(selectedFilters).some( (values) => values?.[0]?.length > 0 ); useEffect(() => { if (Object.keys(selectedFilters).length === 0) return; onFiltersChange?.(selectedFilters); }, [selectedFilters]); return (
{/* Left side - Search and Filters */}
{/* Search */}
onSearchChange(e.target.value)} prefix={} />
{/* Filters */} {showFilters && filters.length > 0 && (
{filters.map((filter: FilterOption) => ( ))}
)}
{showDatePicker && ( )} {/* Right side */}
{showViewToggle && onViewModeChange && ( }, { value: "card", icon: }, ]} value={viewMode} onChange={(value) => onViewModeChange(value as "list" | "card")} /> )} {showReload && ( )}
{/* Active Filters Display */} {hasActiveFilters && (
已选筛选: {Object.entries(selectedFilters).map(([filterKey, values]) => values.map((value) => { const filter = filtersMap[filterKey]; const getLabeledValue = (item: string) => { const option = filter?.options.find( (o) => o.value === item ); return ( handleClearFilter(filterKey, item)} color="blue" > {filter?.label}: {option?.label || item} ); }; return Array.isArray(value) ? value.map((item) => getLabeledValue(item)) : getLabeledValue(value); }) )}
{/* Clear all filters button on the right */}
)}
); }