Lou·Ka — tous les logements à louer du Québec, un seul endroit.
HTML 98.9%
Python 0.6%
1// -----------------------------------------------------------------------------2// Lou-Ka — Agrégateur de logements à louer (province de Québec)3// Auteur : Simon-Pierre Boucher — contact@spboucher.ai4// fiche/StickyListingCTA.tsx : barre CTA compacte du bas (mobile/tablette) —5// n'apparaît qu'une fois la rangée d'actions du héro sortie de l'écran,6// respecte la safe-area iOS, ne masque aucun contenu (padding de page).7// -----------------------------------------------------------------------------8import { useEffect, useState } from "react";9import { Listing, fmtPrice, sourceName } from "../api";10import { IcoExternal } from "../components/Icons";11import { ComparaisonPrix } from "./synthese";12import { NBSP } from "./ui";1314/** true dès que l'élément suivi est passé au-dessus du viewport (défilement). */15export function usePastElement(watch: React.RefObject<HTMLElement>): boolean {16 const [past, setPast] = useState(false);17 useEffect(() => {18 // visible dès que la rangée d'actions du héro est passée au-dessus du viewport19 const check = () => {20 const el = watch.current;21 if (!el) return;22 setPast(el.getBoundingClientRect().bottom < 0);23 };24 check();25 window.addEventListener("scroll", check, { passive: true });26 window.addEventListener("resize", check);27 return () => { window.removeEventListener("scroll", check); window.removeEventListener("resize", check); };28 }, [watch]);29 return past;30}3132export default function StickyListingCTA({ l, cmp, show }: {33 l: Listing; cmp: ComparaisonPrix | null; show: boolean;34}) {35 return (36 <div className={`lk-cta-bar ${show ? "show" : ""}`} aria-hidden={!show}>37 <div className="lk-cta-txt">38 <div className="lk-cta-price">{fmtPrice(l.price, l.price_label)}{l.price != null && <small>{NBSP}/ mois</small>}</div>39 {cmp && <div className={`lk-cta-sub ${cmp.tone === "good" ? "good" : ""}`}>{cmp.court}</div>}40 </div>41 <a className="lk-btn lk-btn-primary" href={`/passerelle/${encodeURIComponent(l.uid)}`}42 target="_blank" rel="noopener noreferrer" tabIndex={show ? 0 : -1}>43 Voir l'annonce <IcoExternal size={15} />44 <span className="visually-hidden"> chez {sourceName(l.source)}</span>45 </a>46 </div>47 );48}49