Add frontend POI management and travel time display
POIManager component in FilterPanel for creating/deleting POIs and triggering distance calculations. PropertyCard shows travel time badges (walk/cycle/transit) per POI. Map renders POI locations as red markers. API client extended with POST body support for POI endpoints.
This commit is contained in:
parent
bb489c2032
commit
8509a0326f
9 changed files with 414 additions and 10 deletions
|
|
@ -15,8 +15,8 @@ import { StreamingProgressBar } from './components/StreamingProgressBar';
|
|||
import { Sheet, SheetContent, SheetTrigger } from './components/ui/sheet';
|
||||
import { Button } from './components/ui/button';
|
||||
import { Filter } from 'lucide-react';
|
||||
import type { GeoJSONFeatureCollection, PropertyProperties, PropertyFeature } from '@/types';
|
||||
import { refreshListings, fetchTasksForUser, streamListingGeoJSON, type StreamingProgress } from '@/services';
|
||||
import type { GeoJSONFeatureCollection, PropertyProperties, PropertyFeature, POI } from '@/types';
|
||||
import { refreshListings, fetchTasksForUser, streamListingGeoJSON, fetchUserPOIs, type StreamingProgress } from '@/services';
|
||||
|
||||
function App() {
|
||||
const [listingData, setListingData] = useState<GeoJSONFeatureCollection | null>(null);
|
||||
|
|
@ -30,6 +30,7 @@ function App() {
|
|||
const [mobileFilterOpen, setMobileFilterOpen] = useState(false);
|
||||
const [highlightedProperty, setHighlightedProperty] = useState<string | null>(null);
|
||||
const [streamingProgress, setStreamingProgress] = useState<StreamingProgress | null>(null);
|
||||
const [userPOIs, setUserPOIs] = useState<POI[]>([]);
|
||||
|
||||
// Ref to track accumulated features during streaming
|
||||
const accumulatedFeaturesRef = useRef<PropertyFeature[]>([]);
|
||||
|
|
@ -70,6 +71,12 @@ function App() {
|
|||
});
|
||||
}, [user, taskID]);
|
||||
|
||||
// Load user's POIs
|
||||
useEffect(() => {
|
||||
if (!user) return;
|
||||
fetchUserPOIs(user).then(setUserPOIs).catch(() => {});
|
||||
}, [user]);
|
||||
|
||||
// Load listings function - used by both auto-load and manual submit
|
||||
const loadListings = useCallback(async (parameters: ParameterValues) => {
|
||||
if (!user) return;
|
||||
|
|
@ -221,6 +228,7 @@ function App() {
|
|||
listingData={listingData}
|
||||
queryParameters={queryParameters}
|
||||
onPropertyClick={handlePropertyClick}
|
||||
pois={userPOIs}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
|
@ -243,6 +251,14 @@ function App() {
|
|||
setTaskID(null);
|
||||
};
|
||||
|
||||
const handlePOITaskCreated = (taskId: string) => {
|
||||
setTaskID(taskId);
|
||||
// Refresh POI list in case new ones were created
|
||||
if (user) {
|
||||
fetchUserPOIs(user).then(setUserPOIs).catch(() => {});
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="h-screen flex flex-col overflow-hidden">
|
||||
{/* Header */}
|
||||
|
|
@ -261,6 +277,8 @@ function App() {
|
|||
onMetricChange={handleMetricChange}
|
||||
isLoading={isLoading}
|
||||
listingCount={listingData?.features.length}
|
||||
user={user}
|
||||
onTaskCreated={handlePOITaskCreated}
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
|
@ -278,6 +296,8 @@ function App() {
|
|||
onMetricChange={handleMetricChange}
|
||||
isLoading={isLoading}
|
||||
listingCount={listingData?.features.length}
|
||||
user={user}
|
||||
onTaskCreated={handlePOITaskCreated}
|
||||
/>
|
||||
</SheetContent>
|
||||
</Sheet>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue