// ---------------------------------------------------------------------------
// Fabri-Ka — Agrégateur de produits fabriqués au Québec
// Auteur : Simon-Pierre Boucher — contact@spboucher.ai
// fiche/Closing.tsx : « En bref », CTA sticky mobile, aside desktop et
// « Demander à Ka » (widget KA Agent partagé) de la fiche produit.
// ---------------------------------------------------------------------------
import { useEffect, useState } from 'react'
import { ProductDetail, formatPrice } from '../api'
import { Ico, IcoHeart } from '../components/KaIcons'
import OriginBadge from '../components/OriginBadge'
import BottomSheet from './BottomSheet'
import { Constat, rabais } from './synthese'
import { SectionCard, SkeletonLines } from './ui'
export function BriefList({ items, compact = false }: { items: Constat[]; compact?: boolean }) {
const glyph = (t: Constat['tone']) => (t === 'good' ? '✓' : t === 'bad' ? '✕' : t === 'warn' ? '!' : '○')
return (
{items.map((c) => (
-
{glyph(c.tone)}
{c.titre}
{!compact && c.detail &&
{c.detail}
}
))}
)
}
export function Summary({ items }: { items: Constat[] }) {
return (
{items.length > 0 ? : }
)
}
export function usePastElement(watch: React.RefObject): boolean {
const [past, setPast] = useState(false)
useEffect(() => {
const check = () => { const el = watch.current; if (el) setPast(el.getBoundingClientRect().bottom < 0) }
check()
window.addEventListener('scroll', check, { passive: true })
window.addEventListener('resize', check)
return () => { window.removeEventListener('scroll', check); window.removeEventListener('resize', check) }
}, [watch])
return past
}
const prixTxt = (p: ProductDetail) => (p.price != null ? formatPrice(p.price, p.currency) : p.price_on_request ? 'Sur devis' : 'Prix en boutique')
export function StickyCTA({ p, show }: { p: ProductDetail; show: boolean }) {
const r = rabais(p)
return (
)
}
export function DesktopAside({ p, brief, fav, onFav, onShare }: {
p: ProductDetail; brief: Constat[]; fav: boolean; onFav: () => void; onShare: () => void
}) {
const r = rabais(p)
return (
)
}
const SUGGESTIONS = ['Ce produit est-il fabriqué au Québec ?', 'Trouve des produits semblables d\'ici', 'Explique la classe d\'origine', 'Compare le prix à d\'autres boutiques', 'Idée cadeau dans la même catégorie']
function envoyerAKa(question: string): boolean {
const btn = document.querySelector('.kaa-btn')
const ta = document.querySelector('.kaa-panel textarea')
const send = document.querySelector('.kaa-in button')
if (!btn || !ta || !send) return false
btn.click(); ta.value = question; setTimeout(() => send.click(), 60)
return true
}
export function KaAssistant({ p, hidden }: { p: ProductDetail; hidden?: boolean }) {
const [open, setOpen] = useState(false)
const [q, setQ] = useState('')
const [err, setErr] = useState(false)
useEffect(() => { const on = () => setOpen(true); window.addEventListener('fb:askka', on); return () => window.removeEventListener('fb:askka', on) }, [])
const contexte = () => `(Produit consulté sur Fabri-Ka : ${p.title} chez ${p.store_name}${p.price != null ? ` — ${formatPrice(p.price, p.currency)}` : ''} — https://www.fabri-ka.com/produits/${encodeURIComponent(p.uid)})`
const poser = (question: string) => { const ok = envoyerAKa(`${question}\n\n${contexte()}`); if (ok) { setOpen(false); setQ(''); setErr(false) } else setErr(true) }
return (
<>
setOpen(false)} title="Demander à Ka" sub="Assistant Groupe KA · connaît cette fiche"
footer={}>
Je peux expliquer l'origine du produit, trouver des alternatives fabriquées au Québec et comparer les boutiques d'ici.
{p.images?.[0] &&

}
{p.title}{[p.store_name, p.price != null ? formatPrice(p.price, p.currency) : null].filter(Boolean).join(' · ')}
{SUGGESTIONS.map((s) => )}
{err && L'assistant n'est pas encore chargé — réessayez dans un instant.
}
>
)
}