/* global React */ const { useState, useEffect, useRef } = React; // ───────────────────────────────────────────── // Logo — real PNG provided by client (white / black / green variants) // Native aspect ratio ≈ 2675×709 (~3.77:1). // ───────────────────────────────────────────── function TGLogo({ height = 26, variant = "white" }) { const src = variant === "green" ? "assets/logo-green.png" : variant === "black" ? "assets/logo-black.png" : "assets/logo-white.png"; return ( TRENDINGOLF ); } // ───────────────────────────────────────────── // Hero // ───────────────────────────────────────────── function Hero({ tweaks }) { const variant = tweaks.heroVariant; // image | split | card const cta = tweaks.ctaCopy; // Hero slideshow — rotates through 9 photos with a 6s interval and a soft // crossfade. Disabled if the user picks a specific photo from Tweaks. const HERO_SLIDESHOW = [ "assets/hero/hero-sunset-swing.jpg", "assets/hero/hero-fairway-swing.jpg", "assets/hero/hero-bunker-spray.jpg", "assets/hero/hero-tee-clouds.jpg", "assets/hero/hero-red-swing.jpg", "assets/hero/hero-green-flag.jpg", "assets/hero/hero-putt-line.jpg", "assets/hero/hero-bunker-side.jpg", "assets/hero/hero-cheers.jpg", ]; const HERO_PINNED = { sunset: "assets/hero/hero-sunset-swing.jpg", fairway: "assets/hero/hero-fairway-swing.jpg", original: "https://images.unsplash.com/photo-1535132011086-b8818f016104?auto=format&fit=crop&w=2000&q=80", }; const isSlideshow = tweaks.heroImage === "slideshow"; const [slideIdx, setSlideIdx] = useState(0); useEffect(() => { if (!isSlideshow) return; // Preload all images so the crossfade is smooth. HERO_SLIDESHOW.forEach((src) => { const img = new Image(); img.src = src; }); const id = setInterval(() => { setSlideIdx((i) => (i + 1) % HERO_SLIDESHOW.length); }, 8000); return () => clearInterval(id); }, [isSlideshow]); const accentBgImage = isSlideshow ? HERO_SLIDESHOW[slideIdx] : (HERO_PINNED[tweaks.heroImage] || HERO_PINNED.sunset); const headlineByVariant = { image: ( <> EL CIRCUITO QUE MUEVE TU JUEGO ), split: ( <> FIXTURE.
RANKING.
RESERVAS. ), card: ( <> ENTRA EN CANCHA ), }; // Renders the hero background. In slideshow mode, all images are stacked and // we fade between them by toggling the active class. In pinned mode it's a // single static layer. const HeroBg = ({ opacity = 1 }) => { if (isSlideshow) { return (
{HERO_SLIDESHOW.map((src, i) => ( ); } return (
); }; return (
{variant === "image" && ( <>
)} {variant === "split" &&
} {variant === "card" && ( <>
)}
{variant === "card" ? (
TEMPORADA 2026 · AMBA

{headlineByVariant.card}

Torneos semanales en los mejores clubes de Buenos Aires. Inscribite, jugá, sumá puntos para el ranking.

) : ( <>
TEMPORADA 2026 · AMBA

{headlineByVariant[variant]}

El circuito de torneos amateurs que recorre los mejores clubes del AMBA. Fixture semanal, resultados en vivo y próximamente rankings.

)}
SEÑAL EN VIVO · TG.LIVE
); } function FeaturedFixture() { const [next, setNext] = useState(null); useEffect(() => { const handler = (e) => setNext(e.detail); window.addEventListener("tg:next-fixture", handler); return () => window.removeEventListener("tg:next-fixture", handler); }, []); if (!next) { return (
PRÓXIMA FECHA
·· CARGANDO
SINCRONIZANDO FIXTURE
Conectando con golf.trendingolf.com…
); } return (
▶ PRÓXIMA FECHA
{String(next.day).padStart(2, "0")} {next.monthShort}
{next.club}
{next.dow} · {next.price}
RESERVAR
); } // ───────────────────────────────────────────── // Fixture — pulls from adondejugamos via fetcher // ───────────────────────────────────────────── function Fixture({ tweaks }) { // Try cache first → instant render on repeat visits. const cached = (window.TGFixtures && window.TGFixtures.loadCached()) || null; const today = new Date(); today.setHours(0,0,0,0); const initialCached = cached ? cached.filter(f => f.date >= today) : []; const [fixtures, setFixtures] = useState(initialCached); const [status, setStatus] = useState(initialCached.length ? "ok" : "loading"); // loading | ok | error | empty const [lastSync, setLastSync] = useState(null); useEffect(() => { let cancelled = false; async function load() { try { if (!fixtures.length) setStatus("loading"); const data = await window.TGFixtures.load(); if (cancelled) return; if (!data || data.length === 0) { if (!fixtures.length) { setStatus("empty"); setFixtures([]); } return; } setFixtures(data); setStatus("ok"); setLastSync(new Date()); // Emit next fixture for hero featured card window.dispatchEvent(new CustomEvent("tg:next-fixture", { detail: data[0] })); } catch (e) { console.error("Fixture load error", e); if (!cancelled && !fixtures.length) setStatus("error"); } } load(); const id = setInterval(load, 60 * 60 * 1000); // hourly return () => { cancelled = true; clearInterval(id); }; }, []); const layoutClass = `fixture--${tweaks.fixtureLayout}`; // carousel | grid | list const tickerItems = fixtures.slice(0, 8).map((f) => `${f.dow.slice(0,3)} ${String(f.day).padStart(2,"0")}/${f.monthShort} · ${f.club}`); return (
{/* Marquee strip with dates */}
{Array(2).fill(0).map((_, dup) => ( {(tickerItems.length ? tickerItems : ["TRENDINGOLF · TEMPORADA 2026", "FIXTURE · AMBA", "RANKING EN VIVO"]).map((item, i) => ( {item} ))} ))}
FIXTURE · AUTO-SYNC

PRÓXIMAS FECHAS

Datos en vivo desde la operación de TRENDINGOLF. Actualización automática cada hora.

{status === "ok" && lastSync ? `SYNC ${lastSync.toLocaleTimeString("es-AR", {hour:"2-digit",minute:"2-digit"})}` : status === "loading" ? "CONECTANDO…" : status === "error" ? "OFFLINE — VOLVER A INTENTAR" : "SIN FECHAS"}
{status === "loading" && (
SINCRONIZANDO FIXTURE…
)} {status === "error" && (
NO PUDIMOS LEER EL FIXTURE EN VIVO.
VER EN GOLF.TRENDINGOLF.COM →
)} {status === "empty" && (
NO HAY FECHAS PROGRAMADAS EN ESTE MOMENTO.
)} {status === "ok" && (
{fixtures.slice(0, 12).map((f, i) => ( ))}
)}
); } function FixtureCard({ f, isNext }) { const rankingClass = f.isRanking ? "fcard--ranking" : ""; return (
{f.isRanking && (
RANKING{f.rankingLabel ? ` ${f.rankingLabel}` : ""}
)} {isNext && !f.isRanking &&
▶ PRÓXIMA
}
{String(f.day).padStart(2, "0")}
{f.monthShort} {f.dow}

{f.club}

CIRCUITO TRENDINGOLF
GREEN FEE {f.price}
RESERVAR
); } // ───────────────────────────────────────────── // About // ───────────────────────────────────────────── function About() { return (
QUÉ ES TRENDINGOLF

UN CIRCUITO. MUCHAS CANCHAS.

Organizamos torneos amateurs en los mejores clubes del AMBA. Cada semana, una cancha distinta. Cada torneo, una oportunidad de jugar, conocer y ranquear.

Reservas, inscripciones y resultados viven en golf.trendingolf.com. Acá te contamos qué se viene.

12+
CLUBES DEL AMBA
5+
TORNEOS POR SEMANA
2026
TEMPORADA EN CURSO
100%
AMATEUR · ABIERTO
[ ESTANCIAS GC · 2024 ]
); } // ───────────────────────────────────────────── // Clubs // ───────────────────────────────────────────── function Clubs() { const clubs = [ { name: "Highland Park CC", loc: "DEL VISO · BS.AS." }, { name: "Los Lagartos CC", loc: "PILAR · BS.AS." }, { name: "Golfer's CC", loc: "BERAZATEGUI · BS.AS." }, { name: "Estancias GC", loc: "PILAR · BS.AS." }, { name: "Club de Campo Los Pingüinos", loc: "ITUZAINGO · BS.AS." }, { name: "Ituzaingo GC", loc: "ITUZAINGO · BS.AS." }, { name: "Abril CC", loc: "HUDSON · BS.AS." }, { name: "San Andrés GC", loc: "SAN ANDRÉS · BS.AS." }, { name: "Club Campos de Golf Las Praderas de Luján", loc: "OPEN DOOR · BS.AS." }, { name: "Haras Santa María", loc: "ESCOBAR · BS.AS." }, { name: "La Colina Villa de Campo", loc: "OPEN DOOR · BS.AS." }, { name: "La Martona CC", loc: "CAÑUELAS · BS.AS." }, ]; return (
CLUBES · AMBA

DONDE JUGAMOS

Recorremos los campos más emblemáticos del Área Metropolitana. Cada fecha, una cancha distinta.

{clubs.map((c, i) => (
CLUB / {String(i+1).padStart(2,"0")}
{c.name}
{c.loc}
))}
); } // ───────────────────────────────────────────── // Results — list of recent finished torneos pulled live from // golf.trendingolf.com/golf/torneos.php (via TGResults loader). // ───────────────────────────────────────────── // Skeleton placeholder rows (rendered while we wait for live data on first // visit — cached results from the previous load are preferred when available). const RESULTS_SKELETON = Array.from({ length: 6 }, (_, i) => ({ skeleton: true, id: i, })); function Results() { // Try cache first → instant render on repeat visits. const cached = (window.TGResults && window.TGResults.loadCached()) || null; const [items, setItems] = useState(cached ? cached.filter(t => t.date < new Date()).slice(0, 8) : RESULTS_SKELETON); const [status, setStatus] = useState(cached ? "live" : "loading"); // loading | live | error useEffect(() => { let cancelled = false; if (!window.TGResults) { setStatus("error"); setItems([]); return; } window.TGResults.load() .then((data) => { if (cancelled) return; const past = data.filter((t) => t.date < new Date()).slice(0, 8); if (past.length) { setItems(past); setStatus("live"); } else if (!cached) { setStatus("error"); setItems([]); } }) .catch(() => { if (cancelled) return; if (!cached) { setStatus("error"); setItems([]); } }); return () => { cancelled = true; }; }, []); const last = items.find(t => !t.skeleton) || null; const eyebrow = last ? `ÚLTIMA FECHA · ${String(last.day).padStart(2,"0")}/${String(last.date.getMonth()+1).padStart(2,"0")} · ${last.venue}` : "TEMPORADA 2026"; return (
{eyebrow}

RESULTADOS RECIENTES

VER TODOS LOS TORNEOS →
FECHA SEDE MODALIDAD
{items.map((t, i) => ( t.skeleton ? ( ) : ( {String(t.day).padStart(2,"0")} {t.monthShort} '{String(t.year).slice(2)} {t.venue} {t.isRanking && ( ★ RANKING{t.rankingLabel ? ` ${t.rankingLabel}` : ""} )} {t.dow} {t.modality || "—"} TARJETAS → ) ))} {status === "error" && items.length === 0 && (
No pudimos sincronizar los resultados ahora. Ver en golf.trendingolf.com →
)}
{status === "live" && } {status === "loading" && } {status === "error" && } {status === "live" ? "DATOS EN VIVO" : status === "loading" ? "SINCRONIZANDO…" : "SIN CONEXIÓN A LA FUENTE"} FUENTE: GOLF.TRENDINGOLF.COM
); } // ───────────────────────────────────────────── // Sponsors // ───────────────────────────────────────────── function Sponsors() { const partners = [ { name: "Srixon", logo: "assets/sponsors/srixon.png", scale: 1.71 }, { name: "WildGolf", logo: "assets/sponsors/wildgolf.png", scale: 1.0 }, { name: "Colosso Wines", logo: "assets/sponsors/colosso.png", scale: 1.76 }, { name: "TeeDel", logo: "assets/sponsors/teedel.png", scale: 1.0 }, ]; return (
PARTNERS

QUIENES NOS ACOMPAÑAN

{partners.map((p, i) => (
{p.name}
))}
); } // ───────────────────────────────────────────── // Viajes — feed of TEEDEL1 group trips // ───────────────────────────────────────────── function Viajes() { const trips = [ { title: "Patagonia Open 2026: Chapelco Edition", sub: "El desafío Nicklaus en el corazón de la Cordillera", img: "https://teedel1.com/wp-content/uploads/2026/01/Chapelco-01-374x226.jpg", tag: "ARGENTINA · PATAGONIA", duration: "4 DÍAS · 3 NOCHES", price: "$690", priceOriginal: "$770", url: "https://teedel1.com/trip/patagonia-open-2026-chapelco-edition/", }, { title: "Costa del Sol Golf Challenge", sub: "10 al 17 de Mayo 2026", img: "https://teedel1.com/wp-content/uploads/2022/03/Golf-Course-374x226.webp", tag: "ESPAÑA · COSTA DEL SOL", duration: "8 DÍAS · 7 NOCHES", price: "$2,890", priceOriginal: "$3,090", url: "https://teedel1.com/trip/costa-del-sol-golf-challenge/", }, { title: "Miami Golfer's World Cup 2026", sub: "Trump National Doral & PGA National · 29 jun – 7 jul", img: "https://teedel1.com/wp-content/uploads/2026/01/course-the-fazio-374x226.jpg", tag: "USA · FLORIDA", duration: "9 DÍAS · 8 NOCHES", price: "$3,690", priceOriginal: "$4,680", url: "https://teedel1.com/trip/miami-golfers-world-cup-2026-trump-national-doral-pga-national/", }, { title: "Stage 1: Trump National Doral", sub: "Blue Monster · 29 jun al 3 jul 2026", img: "https://teedel1.com/wp-content/uploads/2026/01/Blue-Monster-2-374x226.jpg", tag: "USA · FLORIDA", duration: "5 DÍAS · 4 NOCHES", price: "$2,190", priceOriginal: "$2,490", url: "https://teedel1.com/trip/miami-golfers-world-cup-2026-stage-1-trump-national-doral-blue-monster/", }, { title: "Stage 2: PGA National & The Bear Trap", sub: "3 al 7 de julio 2026", img: "https://teedel1.com/wp-content/uploads/2025/12/course-champion-1920x720-1-374x226.webp", tag: "USA · FLORIDA", duration: "5 DÍAS · 4 NOCHES", price: "$1,790", priceOriginal: "$2,190", url: "https://teedel1.com/trip/pga-national-y-alentar-a-argentina/", }, { title: "Punta Cana Golf Trophy", sub: "16 al 23 de agosto 2026", img: "https://teedel1.com/wp-content/uploads/2025/12/GRUPAL-374x226.webp", tag: "CARIBE · PUNTA CANA", duration: "8 DÍAS · 7 NOCHES", price: "$2,490", priceOriginal: null, url: "https://teedel1.com/trip/punta-cana-golf-trophy/", }, ]; return (
VIAJES · TEEDEL1

JUGÁ EN LAS MEJORES CANCHAS DEL MUNDO

Programas grupales seleccionados con TEEDEL1 Golf Travel. Argentina, Caribe, España y USA.

{trips.map((t, i) => (
{t.tag}
{t.priceOriginal && (
{Math.round((1 - parseInt(t.price.replace(/[^0-9]/g,"")) / parseInt(t.priceOriginal.replace(/[^0-9]/g,""))) * 100)}% OFF
)}
{t.duration}
{t.title}
{t.sub}
{t.priceOriginal && {t.priceOriginal}} {t.price}
VER VIAJE
))}
VER TODOS LOS VIAJES EN TEEDEL1.COM →
); } // ───────────────────────────────────────────── // Final CTA // ───────────────────────────────────────────── function FinalCTA({ tweaks }) { return (

JUGÁ LA PRÓXIMA

Asegurá tu lugar en el siguiente torneo. Reservas en línea, pago digital, salida garantizada.

{tweaks.ctaCopy}
); } // ───────────────────────────────────────────── // Footer // ───────────────────────────────────────────── function Footer() { return ( ); } // ───────────────────────────────────────────── // Header // ───────────────────────────────────────────── function Header({ tweaks }) { return (
WHATSAPP
); } // ───────────────────────────────────────────── // App // ───────────────────────────────────────────── function App() { const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{ "heroVariant": "image", "heroImage": "slideshow", "fixtureLayout": "carousel", "ctaCopy": "RESERVAR" }/*EDITMODE-END*/; const [tweaks, setTweak] = window.useTweaks(TWEAK_DEFAULTS); return ( <>