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:
parent
1f4a3f858c
commit
743e018668
11 changed files with 422 additions and 588 deletions
|
|
@ -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>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue