feat([2fd88f42]): redesign filter panel with modern checkbox UI

This commit is contained in:
2026-02-04 12:38:10 +00:00
parent f492da5ae1
commit 2151a612a2

View File

@@ -14,61 +14,80 @@ interface FilterPanelProps {
const FilterPanel: React.FC<FilterPanelProps> = ({ filters, onFilterChange, isLoading }) => { const FilterPanel: React.FC<FilterPanelProps> = ({ filters, onFilterChange, isLoading }) => {
const [selectedFilters, setSelectedFilters] = useState<FilterOptions>({}); const [selectedFilters, setSelectedFilters] = useState<FilterOptions>({});
// Reset selected filters when a new file is uploaded (filters prop changes)
useEffect(() => { useEffect(() => {
setSelectedFilters({}); setSelectedFilters({});
}, [filters]); }, [filters]);
const handleSelectionChange = (category: string, values: string[]) => { const handleCheckboxChange = (category: string, value: string) => {
setSelectedFilters(prev => ({ setSelectedFilters(prev => {
...prev, const currentSelection = prev[category] || [];
[category]: values, const newSelection = currentSelection.includes(value)
})); ? currentSelection.filter(item => item !== value)
// Ensure "N/A" is not sorted to the top if that's not desired
: [...currentSelection, value].sort((a, b) => a === 'N/A' ? 1 : b === 'N/A' ? -1 : a.localeCompare(b));
return { ...prev, [category]: newSelection };
});
}; };
const handleApplyClick = () => { const handleApplyClick = () => {
onFilterChange(selectedFilters); onFilterChange(selectedFilters);
} };
const handleResetClick = () => { const handleResetClick = () => {
setSelectedFilters({}); setSelectedFilters({});
onFilterChange({}); onFilterChange({});
} };
if (Object.keys(filters).length === 0) { if (Object.keys(filters).length === 0) {
return <div>Upload a file to see filter options.</div>; return <div>Upload a file to see filter options.</div>;
} }
return ( return (
<div className="filter-panel"> <>
<h3>Filters</h3> <style>{`
{Object.entries(filters).map(([category, options]) => ( .filter-panel { padding-top: 20px; }
<div key={category} className="filter-group"> .filter-group { margin-bottom: 15px; }
<label>{category}</label> .filter-group summary { font-weight: bold; cursor: pointer; padding: 5px; background-color: #444; border-radius: 4px; }
<select .filter-options { max-height: 200px; overflow-y: auto; padding: 10px; background-color: #2a2a2a; border-radius: 4px; margin-top: 5px;}
multiple .filter-option { display: flex; align-items: center; margin-bottom: 5px; }
value={selectedFilters[category] || []} .filter-option input { margin-right: 10px; }
onChange={(e) => .filter-buttons { margin-top: 20px; display: flex; justify-content: space-between; }
handleSelectionChange(category, Array.from(e.target.selectedOptions, option => option.value)) .filter-buttons button { width: 48%; padding: 10px; border: none; border-radius: 4px; cursor: pointer; }
} .apply-button { background-color: #4CAF50; color: white; }
> .reset-button { background-color: #f44336; color: white; }
{options.map(option => ( .filter-buttons button:disabled { background-color: #555; cursor: not-allowed; }
<option key={option} value={option}> `}</style>
{option} <div className="filter-panel">
</option> <h3>Filters</h3>
))} {Object.entries(filters).map(([category, options]) => (
</select> <details key={category} className="filter-group" open>
<summary>{category}</summary>
<div className="filter-options">
{options.map(option => (
<div key={option} className="filter-option">
<input
type="checkbox"
id={`${category}-${option}`}
value={option}
checked={(selectedFilters[category] || []).includes(option)}
onChange={() => handleCheckboxChange(category, option)}
/>
<label htmlFor={`${category}-${option}`}>{option}</label>
</div>
))}
</div>
</details>
))}
<div className="filter-buttons">
<button onClick={handleApplyClick} disabled={isLoading} className="apply-button">
{isLoading ? 'Loading...' : 'Apply Filters'}
</button>
<button onClick={handleResetClick} disabled={isLoading} className="reset-button">
Reset
</button>
</div> </div>
))}
<div className="filter-buttons">
<button onClick={handleApplyClick} disabled={isLoading}>
{isLoading ? 'Loading...' : 'Apply Filters'}
</button>
<button onClick={handleResetClick} disabled={isLoading}>
Reset Filters
</button>
</div> </div>
</div> </>
); );
}; };