Redesign filter panel with range sliders, separated visualization card, and backend filter support

Simplify the filter UI to show only essential filters (type toggle, price/bedroom
range sliders, min size) by default, with advanced filters collapsed. Extract
visualization controls (color-by metric, POI travel mode) into a separate
VisualizationCard component. Wire up previously ignored backend filters: max_sqm,
min/max_price_per_sqm, and district_names now work end-to-end.
This commit is contained in:
Viktor Barzin 2026-02-08 18:50:06 +00:00
parent 1f4a3f858c
commit 743e018668
No known key found for this signature in database
GPG key ID: 0EB088298288D958
11 changed files with 422 additions and 588 deletions

View file

@ -8,6 +8,7 @@ import LoginModal from './components/LoginModal';
import AuthCallback from './components/AuthCallback';
import { Map } from './components/Map';
import { FilterPanel, type ParameterValues, DEFAULT_FILTER_VALUES, Metric } from './components/FilterPanel';
import { VisualizationCard } from './components/VisualizationCard';
import { Header } from './components/Header';
import { StatsBar, type ViewMode } from './components/StatsBar';
import { ListView } from './components/ListView';
@ -40,6 +41,7 @@ function App() {
travelMode: 'WALK' | 'BICYCLE' | 'TRANSIT';
} | null>(null);
const [poiTravelFilters, setPoiTravelFilters] = useState<Record<number, POITravelFilter>>({});
const [currentMetric, setCurrentMetric] = useState<Metric>(DEFAULT_FILTER_VALUES.metric);
// Ref to track accumulated features during streaming
const accumulatedFeaturesRef = useRef<PropertyFeature[]>([]);
@ -229,6 +231,7 @@ function App() {
};
const handleMetricChange = (metric: Metric) => {
setCurrentMetric(metric);
setQueryParameters(prev => prev ? { ...prev, metric } : null);
};
@ -351,20 +354,31 @@ function App() {
<div className="flex-1 flex overflow-hidden min-h-0">
{/* Filter Panel - Desktop (fixed sidebar) */}
<div className="hidden md:block w-80 shrink-0 h-full overflow-hidden">
<FilterPanel
onSubmit={onSubmit}
onMetricChange={handleMetricChange}
isLoading={isLoading}
listingCount={processedListingData?.features.length}
user={user}
onTaskCreated={handlePOITaskCreated}
onStartPoiPicking={handleStartPoiPicking}
pickedPoiLocation={pickedPoiLocation}
userPOIs={userPOIs}
onPoiMetricChange={setPoiMetricSelection}
poiTravelFilters={poiTravelFilters}
onPoiTravelFiltersChange={setPoiTravelFilters}
/>
<div className="h-full flex flex-col">
<div className="flex-1 min-h-0">
<FilterPanel
onSubmit={onSubmit}
currentMetric={currentMetric}
isLoading={isLoading}
listingCount={processedListingData?.features.length}
user={user}
onTaskCreated={handlePOITaskCreated}
onStartPoiPicking={handleStartPoiPicking}
pickedPoiLocation={pickedPoiLocation}
userPOIs={userPOIs}
poiTravelFilters={poiTravelFilters}
onPoiTravelFiltersChange={setPoiTravelFilters}
/>
</div>
<div className="shrink-0 p-4 border-r">
<VisualizationCard
metric={currentMetric}
onMetricChange={handleMetricChange}
userPOIs={userPOIs}
onPoiMetricChange={setPoiMetricSelection}
/>
</div>
</div>
</div>
{/* Filter Panel - Mobile (sheet) */}
@ -376,20 +390,31 @@ function App() {
</Button>
</SheetTrigger>
<SheetContent side="left" className="w-80 p-0">
<FilterPanel
onSubmit={onSubmit}
onMetricChange={handleMetricChange}
isLoading={isLoading}
listingCount={processedListingData?.features.length}
user={user}
onTaskCreated={handlePOITaskCreated}
onStartPoiPicking={handleStartPoiPicking}
pickedPoiLocation={pickedPoiLocation}
userPOIs={userPOIs}
onPoiMetricChange={setPoiMetricSelection}
poiTravelFilters={poiTravelFilters}
onPoiTravelFiltersChange={setPoiTravelFilters}
/>
<div className="h-full flex flex-col">
<div className="flex-1 min-h-0">
<FilterPanel
onSubmit={onSubmit}
currentMetric={currentMetric}
isLoading={isLoading}
listingCount={processedListingData?.features.length}
user={user}
onTaskCreated={handlePOITaskCreated}
onStartPoiPicking={handleStartPoiPicking}
pickedPoiLocation={pickedPoiLocation}
userPOIs={userPOIs}
poiTravelFilters={poiTravelFilters}
onPoiTravelFiltersChange={setPoiTravelFilters}
/>
</div>
<div className="shrink-0 p-4">
<VisualizationCard
metric={currentMetric}
onMetricChange={handleMetricChange}
userPOIs={userPOIs}
onPoiMetricChange={setPoiMetricSelection}
/>
</div>
</div>
</SheetContent>
</Sheet>
</div>