SPB Git forge

spb/lou-ka

Public

Lou·Ka — tous les logements à louer du Québec, un seul endroit.

232commits 1branches 0releases
172.9 MBsize
maindefault branch
2 days agolast push
HTML 98.9% Python 0.6%
2.2 KB · 49 lines tsx
Raw Blame History
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