{{-- Page Acheter — portage fidele de maquettes/Acheter.dc.html. Donnees fournies par AcheterController@index : - $biens : biens filtres/tries (deja calcules par le CRM, voir CrmClientInterface::biens()) - $nombreBiens : count($biens) - $communes : referentiel des 262 communes wallonnes, indexe par cle normalisee (cle => ['nom','cle','province','d'], voir resources/data/communes-wallonie.php) - $comptesParCommune : nombre de biens par commune sur la liste COMPLETE (non filtree), comme les compteurs de la carte de la maquette qui ne dependent pas des filtres actifs - $provinces : cle => libelle (5 provinces wallonnes, utilise pour grouper la liste de communes et pour le filtre provinces[] conserve en compatibilite, voir AcheterController) - $types : cle => libelle (select "Type de bien") - $disponibilites : cle => libelle (select "Disponibilite") - $tris : cle => libelle (select "Trier par") - $filtres : valeurs normalisees pour pre-remplir le formulaire (localite, budget_max, type, chambres_min, disponibilite, provinces[], communes[], tri) Filtres en GET vers route('acheter') : rechargement serveur complet (pas d'AJAX), conforme a la consigne du lot. NEWSLETTER : dans la maquette (bloc "NEWSLETTER" de Acheter.dc.html), le champ email + bouton "Recevoir les nouveautes" ne sont relies a aucun on-submit dans DCLogic (purement visuel, aucune action reelle dans la source). Aucun endpoint backend d'inscription newsletter n'existe dans ce lot (StoreMessageContactRequest exige telephone + type_besoin, semantique differente). Le bloc est donc reproduit a l'identique visuellement mais reste non fonctionnel, fidele au comportement de la maquette source. A signaler si une vraie inscription newsletter est souhaitee. --}} @extends('layouts.site', ['active' => 'acheter']) @section('titre', 'Acheter - Biome Constructions') @php $localite = $filtres['localite']; $budgetMax = (int) $filtres['budget_max']; $typeActif = $filtres['type']; $chambresMin = (int) $filtres['chambres_min']; $dispoActive = $filtres['disponibilite']; $provincesActives = $filtres['provinces']; $communesActives = $filtres['communes']; $triActif = $filtres['tri']; $plafondBudget = 1000000; $hasFiltres = $localite !== '' || $provincesActives !== [] || $communesActives !== [] || $budgetMax < $plafondBudget || $typeActif !== 'all' || $chambresMin > 0 || $dispoActive !== 'all'; $fmtEuro = static fn (int $n): string => number_format($n, 0, ',', '.').' €'; $budgetLabel = $budgetMax >= $plafondBudget ? '1.000.000 € et +' : $fmtEuro($budgetMax); $countLabel = $nombreBiens.' '.($nombreBiens > 1 ? 'biens' : 'bien'); // Liste ACTIONNABLE : uniquement les communes ayant au moins un bien // (les 262 completes restent dans le SVG plus bas), groupees par // province (cle province => [cle commune => nom commune]), triees par // ordre alphabetique du nom dans chaque groupe. Les 262 communes ne sont // jamais toutes listees ici (pas de sens commercial). $communesParProvince = []; foreach ($communes as $cleCommune => $commune) { if (($comptesParCommune[$cleCommune] ?? 0) < 1) { continue; } $communesParProvince[$commune['province']][$cleCommune] = $commune['nom']; } foreach ($communesParProvince as $cleProvince => $liste) { asort($communesParProvince[$cleProvince]); } @endphp @section('contenu') {{-- MODALES : "etre rappele" (generique, sans bien) et "planifier une visite" par bien (une modale par bien present dans $biens, pour que le bouton "Planifier" de chaque PropertyCard cible la bonne, via data-ouvre-modale + data-bien-id cote JS). --}} @foreach ($biens as $bien) @endforeach {{-- HERO --}}
@php $imgHero = \App\Support\MediaSite::url($contenu->contenu('hero.image')); @endphp @if ($imgHero) @else
Intérieur lumineux
@endif

Nos biens à vendre

{{ $countLabel }} disponibles

Trouvez le bien qui correspond à votre projet de vie.

{{-- BOUTON "FILTRER" MOBILE/TABLETTE (<=1024px, decision client 2026-07-03). Le formulaire de filtres desktop (ci-dessous) est repris tel quel et transforme en tiroir plein ecran sous 1024px (classe .biome-filtres-tiroir-mobile, voir mobile.css) : pas de duplication du formulaire, un seul DOM, un seul submit. Ce bouton (.biome-visible-mobile, masque en desktop) pilote l'ouverture via initTiroirFiltres() (site.js), meme pattern que le tiroir du menu burger (data-ouvre-*/data-tiroir-*). --}}
{{-- FILTER BAR --}}
{{-- Entete du tiroir (mobile/tablette uniquement, .biome-visible-mobile) : titre + croix de fermeture. N'existe pas en desktop (aucun sens dans la barre de filtres horizontale d'origine). --}}

Filtrer les biens

{{-- Bouton toggle carte SVG : masque sous 1024px, le panneau (liste de communes a cocher) est toujours visible dans le tiroir mobile, voir plus bas. --}}
{{-- Bouton "Voir les X biens" — mobile/tablette uniquement (.biome-visible-mobile). Remplace le bouton "Rechercher" desktop (masque ci-dessus) : meme submit, meme formulaire, juste un libelle et une position (pied de tiroir plein ecran) adaptes. --}} @if ($communesActives !== [])
Communes sélectionnées : @foreach ($communesActives as $cleCommune) {{ $communes[$cleCommune]['nom'] ?? $cleCommune }} @endforeach Tout effacer
@endif {{-- CARTE DES COMMUNES : repliee par defaut (desktop), ouverte via JS (data-toggle-carte-communes). Remplace l'ancienne carte par province (5 formes abstraites) par une vraie carte de Wallonie (262 communes, resources/data/communes-wallonie.php, viewBox 1000x572 : NE PAS MODIFIER les traces "d" sans validation, voir CLAUDE.md). Une seule case a cocher reelle par commune : celles ayant au moins un bien vivent dans la liste actionnable ci-dessous (visible, groupee par province) ; les autres (0 bien) sont des cases "muettes" (bloc cache juste apres la liste). Le SVG et les boutons-communes pilotent tous les deux la meme case via data-commune, pour rester synchronises (voir initCarteCommunes() dans site.js). Submit reel au changement (pas d'AJAX), conforme a la consigne du lot. MOBILE/TABLETTE (<=1024px, decision client 2026-07-03) : le SVG a des cibles trop petites au doigt (262 formes). Le SVG est masque (.biome-masquer-tablette-mobile) et le panneau est TOUJOURS visible dans le tiroir de filtres (.biome-panneau-communes-mobile force son display, independamment du data-panneau-carte-communes desktop qui reste gere par JS/toggle) : seule la liste de cases a cocher (deja presente dans le DOM pour le desktop, reutilisee telle quelle) reste utilisable, en 1 colonne, scrollable. --}}
{{-- TOOLBAR --}}
{{ $countLabel }} trouvés @if ($hasFiltres) Effacer les filtres @endif
{{-- Bascule "Mes favoris" : filtre la liste sur les biens marques d'un coeur, memorises cote navigateur (localStorage). Le clic recharge la page avec ?favoris=... (ou le retire), gere en JS (data-toggle-favoris). Visible aussi en mobile/tablette. --}}
Trier par
{{-- Bascule liste/carte : masquee sous 1024px (decision client 2026-07-03). Seule la vue liste est proposee en mobile/tablette (voir aussi la section VUE CARTE plus bas, egalement masquee). --}}
{{-- Formulaire dedie au select "Trier par" (soumission GET independante du formulaire de filtres, mais reprenant les memes parametres actifs). --}} {{-- RESULTS : VUE LISTE — decision client 2026-07-03 : 1 bien par ligne en mobile (cartes empilees pleine largeur). .biome-grille-3 applique le catalogue standard (3 colonnes desktop inchange -> 2 en tablette -> 1 en mobile, voir docs/mobile-strategie.md). --}}
@if ($nombreBiens > 0)
@include('pages.partials.biens-cartes', ['biens' => $biens])
@if ($aSuivante)
Charger plus de biens
@endif @elseif ($favorisActif) {{-- Etat vide specifique au mode "mes favoris" : soit aucun coeur n'a ete pose, soit les favoris ne sont plus disponibles. --}}
Vous n'avez pas encore de coup de cœur

Cliquez sur le cœur d'un bien pour l'ajouter à vos favoris, puis retrouvez-les ici.

Voir tous les biens
@else
Aucun bien ne correspond

Essayez d'élargir vos critères de recherche.

Réinitialiser les filtres
@endif
{{-- RESULTS : VUE CARTE (masquee par defaut, bascule JS). Egalement masquee en dur sous 1024px (.biome-masquer-tablette-mobile) : le bouton de bascule qui l'affiche est lui-meme masque en mobile/tablette (voir TOOLBAR plus haut), ce filet de securite evite tout affichage residuel (ex: etat JS herite d'un redimensionnement de fenetre). --}} {{-- "Ne manquez aucune opportunite" : renvoie vers le formulaire de contact complet (nom/prenom/email/telephone) plutot qu'une simple saisie d'email, pour qualifier le prospect. --}}

Ne manquez aucune opportunité

Recevez nos nouveaux biens en avant-première et soyez informé des projets en cours.

@endsection