import { useEffect } from 'react'
import type { BannerPlacement, PublicBanner } from '../../api/types'
import { Icon } from '../../components/Icon'
import { useRotation } from '../../lib/useBanners'
/**
* Miejsce na baner w sali.
*
* ROTACJA JEST NA MIEJSCE, NIE NA CALA SALE
* ------------------------------------------------------------------------
* Kazde miejsce rotuje niezaleznie: baner boczny i pas pod wideo nie musza
* zmieniac sie w tej samej chwili, a wspolny licznik wiazalby je bez powodu.
*
* KLIKNIECIE MA DWIE DROGI
* ------------------------------------------------------------------------
* Zwykly baner otwiera `targetUrl` w nowej karcie. Baner z tematem oferty
* otwiera **formularz zapytania** w oknie, bez opuszczania sali: to domyka
* droge od reklamy do kontaktu handlowego. Uczestnik, ktory wyszedl na obcy
* serwis w trakcie prezentacji, zwykle juz nie wraca.
*
* `rel="noopener noreferrer"` odcina nowej karcie dostep do `window.opener`
* i nie zdradza obcemu serwisowi, z jakiego adresu przyszedl uczestnik.
*/
export function BannerSlot({
placement,
banners,
rotationSeconds,
onImpression,
onClick,
onDismiss,
onOfferTopic,
className = '',
}: {
placement: BannerPlacement
banners: PublicBanner[]
rotationSeconds: number
onImpression: (bannerId: number) => void
onClick: (bannerId: number) => void
/** Zamkniecie, wylacznie przy OVERLAY. */
onDismiss?: (bannerId: number) => void
/** Otwarcie formularza oferty z wybranym z gory tematem. */
onOfferTopic?: (topic: string) => void
className?: string
}) {
const index = useRotation(banners.length, rotationSeconds)
const banner = banners[index]
/*
* Wyswietlenie liczymy, gdy baner faktycznie wchodzi na ekran, a nie gdy
* przychodzi z serwera: baner z rotacji, ktorego uczestnik nigdy nie
* zobaczyl, nie zostal wyswietlony.
*/
useEffect(() => {
if (banner) onImpression(banner.id)
}, [banner, onImpression])
if (!banner) return null
const isOffer = Boolean(banner.offerTopicName)
const clickable = isOffer || Boolean(banner.targetUrl)
function handleClick() {
onClick(banner.id)
if (isOffer && banner.offerTopicName && onOfferTopic) {
onOfferTopic(banner.offerTopicName)
}
}
const content = (
<>
{banner.mediaUrl ? (
) : (
/*
Tresc jest oczyszczona sanitizerem na backendzie, tym samym co tresc
strony zapisu, wiec nie czyscimy jej drugi raz w przegladarce.
*/
Kliknij, żeby zapytać o ofertę
)} {/* OVERLAY zaslania czesc obrazu, wiec musi dac sie zamknac: baner nie do usuniecia w trakcie prezentacji jest gorszy niz brak banera. */} {placement === 'OVERLAY' && onDismiss && ( )} {/* wskaznik rotacji: uczestnik widzi, ze jest wiecej niz jeden baner */} {banners.length > 1 && (