feat([2fd88f42]): redesign filter panel with modern checkbox UI
This commit is contained in:
@@ -14,61 +14,80 @@ interface FilterPanelProps {
|
||||
const FilterPanel: React.FC<FilterPanelProps> = ({ filters, onFilterChange, isLoading }) => {
|
||||
const [selectedFilters, setSelectedFilters] = useState<FilterOptions>({});
|
||||
|
||||
// Reset selected filters when a new file is uploaded (filters prop changes)
|
||||
useEffect(() => {
|
||||
setSelectedFilters({});
|
||||
}, [filters]);
|
||||
|
||||
const handleSelectionChange = (category: string, values: string[]) => {
|
||||
setSelectedFilters(prev => ({
|
||||
...prev,
|
||||
[category]: values,
|
||||
}));
|
||||
const handleCheckboxChange = (category: string, value: string) => {
|
||||
setSelectedFilters(prev => {
|
||||
const currentSelection = prev[category] || [];
|
||||
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 = () => {
|
||||
onFilterChange(selectedFilters);
|
||||
}
|
||||
onFilterChange(selectedFilters);
|
||||
};
|
||||
|
||||
const handleResetClick = () => {
|
||||
setSelectedFilters({});
|
||||
onFilterChange({});
|
||||
}
|
||||
};
|
||||
|
||||
if (Object.keys(filters).length === 0) {
|
||||
return <div>Upload a file to see filter options.</div>;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="filter-panel">
|
||||
<h3>Filters</h3>
|
||||
{Object.entries(filters).map(([category, options]) => (
|
||||
<div key={category} className="filter-group">
|
||||
<label>{category}</label>
|
||||
<select
|
||||
multiple
|
||||
value={selectedFilters[category] || []}
|
||||
onChange={(e) =>
|
||||
handleSelectionChange(category, Array.from(e.target.selectedOptions, option => option.value))
|
||||
}
|
||||
>
|
||||
{options.map(option => (
|
||||
<option key={option} value={option}>
|
||||
{option}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
<>
|
||||
<style>{`
|
||||
.filter-panel { padding-top: 20px; }
|
||||
.filter-group { margin-bottom: 15px; }
|
||||
.filter-group summary { font-weight: bold; cursor: pointer; padding: 5px; background-color: #444; border-radius: 4px; }
|
||||
.filter-options { max-height: 200px; overflow-y: auto; padding: 10px; background-color: #2a2a2a; border-radius: 4px; margin-top: 5px;}
|
||||
.filter-option { display: flex; align-items: center; margin-bottom: 5px; }
|
||||
.filter-option input { margin-right: 10px; }
|
||||
.filter-buttons { margin-top: 20px; display: flex; justify-content: space-between; }
|
||||
.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; }
|
||||
.filter-buttons button:disabled { background-color: #555; cursor: not-allowed; }
|
||||
`}</style>
|
||||
<div className="filter-panel">
|
||||
<h3>Filters</h3>
|
||||
{Object.entries(filters).map(([category, options]) => (
|
||||
<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 className="filter-buttons">
|
||||
<button onClick={handleApplyClick} disabled={isLoading}>
|
||||
{isLoading ? 'Loading...' : 'Apply Filters'}
|
||||
</button>
|
||||
<button onClick={handleResetClick} disabled={isLoading}>
|
||||
Reset Filters
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user