"use client"; import { useEffect, useMemo, useState } from "react"; import { useRouter, useSearchParams } from "next/navigation"; import type { SearchParams, SearchResult } from "@/lib/types"; import { ListingCardView } from "@/components/listing-card"; import { FilterBar } from "@/components/filters"; import { SearchBar } from "@/components/search-bar"; import { MapView, type MapPoint } from "@/components/map-view"; import { Empty } from "@/components/ui"; import { IconList, IconMap, IconHeart } from "@/components/icons"; import { useSavedSearches } from "@/lib/favorites"; export function ResultsView({ initial, points, params, title }: { initial: SearchResult; points: MapPoint[]; params: SearchParams & { page: number }; title: string }) { const [mode, setMode] = useState<"list" | "map">("list"); const [active, setActive] = useState(null); const router = useRouter(); const sp = useSearchParams(); const saved = useSavedSearches(); const rent = params.market === "rent"; const pages = Math.max(1, Math.ceil(initial.total / initial.limit)); const center = useMemo<[number, number] | undefined>(() => { if (!points.length) return undefined; const la = points.reduce((s, p) => s + p.lat, 0) / points.length, ln = points.reduce((s, p) => s + p.lng, 0) / points.length; return [la, ln]; }, [points]); const goPage = (n: number) => { const u = new URLSearchParams(sp.toString()); u.set("page", String(n)); router.push(`/recherche?${u}`); }; useEffect(() => { setActive(null); }, [initial]); const href = `/recherche?${sp.toString()}`; return (

{title}

{initial.items.length === 0 ? ( ) : (
{initial.items.map((c, i) =>
setActive(c.uid)} className={active === c.uid ? "ring-2 ring-brand rounded-card" : ""}>
)}
)} {pages > 1 && ( )}
router.push(`/annonce/${encodeURIComponent(p.uid)}`)} />

Les annonces proviennent de sites publics ; chaque fiche indique sa source et renvoie à l'annonce d'origine. Les écarts « estimation vs prix » sont statistiques et indicatifs.

); }