import { useState, useEffect } from 'react' import type { ReactElement } from 'react' import { Link, NavLink, Routes, Route, useLocation, useNavigate, useParams } from 'react-router-dom' import AdminPage from './AdminPage' import QASection from './components/QASection' import ContactForm from './components/ContactForm' import { ColossiansStudyIndexPage, ColossiansStudyNotesPage, ColossiansStudySectionPage, StudyLandingPage, StudySignupPage, StudyAccountPage, StudyCommunityPage, StudyQuizPage } from './colossiansStudy' import { SpotifyIcon } from './icons' import type { SiteContent, ArchivedSeries, StudyProgram } from './content' import { DEFAULTS } from './content' import { usePageMeta } from './hooks/usePageMeta' import { useGlobalSearch } from './hooks/useGlobalSearch' import { GlobalSearch } from './components/GlobalSearch' import { EpisodeAudioPlayer } from './components/EpisodeAudioPlayer' import './App.css' import { sendEvent, useScrollDepthTracking, useTimeOnPage, useUTMCapture, useOutboundLinkTracking } from './analytics' const CONSENT_KEY = 'vbn_analytics_consent_choice' const HEADLINER_WIDGET_ID = 'WI_cmou3b4q7000701p0o9qmmcfj' function ScrollToTop() { const { pathname } = useLocation() useEffect(() => { window.scrollTo(0, 0) }, [pathname]) return null } function usePageTracking() { const location = useLocation() useEffect(() => { if (localStorage.getItem(CONSENT_KEY) !== 'accepted') return const referrer = document.referrer || '' const controller = new AbortController() const timeout = setTimeout(() => controller.abort(), 5000) fetch('/api/analytics/pageview', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ path: location.pathname, referrer }), keepalive: true, signal: controller.signal, }).catch(() => {}).finally(() => clearTimeout(timeout)) }, [location.pathname]) } function toSpotifyEpisodeEmbedUrl(url: string | undefined): string { if (!url) return '' try { const parsed = new URL(url) const host = parsed.hostname.toLowerCase() const parts = parsed.pathname.split('/').filter(Boolean) if (host === 'open.spotify.com') { if (parts[0] === 'embed' && parts[1] === 'episode' && parts[2]) { return `https://open.spotify.com/embed/episode/${parts[2]}?utm_source=generator` } if (parts[0] === 'episode' && parts[1]) { return `https://open.spotify.com/embed/episode/${parts[1]}?utm_source=generator` } } } catch { return '' } return '' } function isLikelySpotifyEpisodeUrl(url: string | undefined): boolean { if (!url) return false if (toSpotifyEpisodeEmbedUrl(url)) return true try { const parsed = new URL(url) const host = parsed.hostname.toLowerCase() const path = parsed.pathname.toLowerCase() if (host === 'creators.spotify.com' && path.includes('/episodes/')) return true if (host === 'anchor.fm' && path.includes('/episodes/')) return true if (host === 'podcasters.spotify.com' && path.includes('/episodes/')) return true } catch { return false } return false } function getHomepageFeaturedStudy(content: SiteContent): StudyProgram | null { const studies = Array.isArray(content.studies) ? content.studies : [] if (studies.length === 0) return null return studies.find(study => study.showOnHomepage === true) ?? studies.find(study => study.status === 'active') ?? studies[0] } function HeadlinerWidget() { const [iframeSrc, setIframeSrc] = useState('') const [status, setStatus] = useState<'loading' | 'ready' | 'empty'>('loading') useEffect(() => { const getDiscoUrl = () => { const canonicalHref = document.querySelector('link[rel="canonical"]')?.getAttribute('href') const ogUrl = document.querySelector('meta[property="og:url"]')?.getAttribute('content') const base = canonicalHref || ogUrl if (!base) return window.location.href try { const parsed = new URL(base) return `${parsed.origin}${window.location.pathname}` } catch { return window.location.href } } const discoUrl = getDiscoUrl() const discoTitle = document.querySelector('meta[property="og:title"]')?.getAttribute('content') || document.title const src = `https://disco.headliner.link/d/web/widget.html?widgetId=${encodeURIComponent(HEADLINER_WIDGET_ID)}&url=${encodeURIComponent(discoUrl)}&title=${encodeURIComponent(discoTitle)}` const sessionId = `SS_siteforge_${Date.now()}_${Math.random().toString(36).slice(2, 10)}` const query = new URLSearchParams({ sessionId, url: discoUrl, widgetId: HEADLINER_WIDGET_ID, }) fetch(`https://api.headliner.link/api/v1/widget/widget-request?${query.toString()}`) .then(r => (r.ok ? r.json() : Promise.reject(new Error('widget request failed')))) .then((data: { results?: unknown[] }) => { if (Array.isArray(data.results) && data.results.length > 0) { setIframeSrc(src) setStatus('ready') return } setStatus('empty') }) .catch(() => { // If API probing fails, still attempt iframe rendering. setIframeSrc(src) setStatus('ready') }) }, []) return ( status === 'empty' ? null : (
{status === 'ready' && iframeSrc && (