// components.jsx — theme-aware homepage sections for saraslot
// Loaded after React + Babel. Exports components on window.
const { useState, useEffect, useRef, useCallback } = React;
/* ─────────────────────────────────────────────────────────────
ICONS — minimal inline SVG/text for reliability
──────────────────────────────────────────────────────────── */
const Icon = ({ name, size = 18, color = "currentColor" }) => {
const s = size, c = color;
switch (name) {
case "soccer": return ;
case "trophy": return ;
case "crown": return ;
case "ticket": return ;
case "home": return ;
case "history": return ;
case "chat": return ;
case "settings": return ;
case "slot": return ;
case "live": return ;
case "esport": return ;
case "lightning": return ;
case "menu": return ;
case "invite": return ;
case "link": return ;
case "downline": return ;
case "gift": return ;
case "female": return ♀;
default: return null;
}
};
window.Icon = Icon;
/* ─────────────────────────────────────────────────────────────
Logo — theme-specific
──────────────────────────────────────────────────────────── */
function Logo({ theme }) {
const b = window.useBranding ? window.useBranding() : window.BRANDING_DEFAULTS;
const w1 = b.brand_word_1, w2 = b.brand_word_2;
if (theme === "jade") {
return (
);
}
if (theme === "neon") {
return (
);
}
return (
);
}
window.Logo = Logo;
/* ─────────────────────────────────────────────────────────────
AppDownloadBanner — sourced from site_settings('app_banner')
──────────────────────────────────────────────────────────── */
function AppDownloadBanner({ onDismiss }) {
const q = window.useSiteSetting ? window.useSiteSetting("app_banner") : { data: null };
const cfg = (q.data && q.data.value) || { title: "App · Download And Play Now!", rating: "4.9", users: "50K+ players", show: true };
if (cfg.show === false) return null;
return (
{cfg.title}
★★★★★
{cfg.rating} · {cfg.users}
);
}
window.AppDownloadBanner = AppDownloadBanner;
/* ─────────────────────────────────────────────────────────────
Header
──────────────────────────────────────────────────────────── */
function Header({ theme, navigate, onOpenLogin, onOpenRegister }) {
const { session } = (window.useSession ? window.useSession() : { session: null });
const profileQuery = window.useProfile ? window.useProfile() : { data: null };
const profile = profileQuery && profileQuery.data;
const b = window.useBranding ? window.useBranding() : window.BRANDING_DEFAULTS;
const [menuOpen, setMenuOpen] = useState(false);
const goHome = () => {
if (navigate) navigate("/");
else window.location.hash = "/";
};
const handleLogout = async () => {
setMenuOpen(false);
if (window.signOut) await window.signOut();
};
return (
{!session && (
<>
>
)}
{session && (
)}
{session && menuOpen && (
setMenuOpen(false)}>
)}
);
}
window.Header = Header;
/* ─────────────────────────────────────────────────────────────
HeroCarousel — slides from `hero_slides` table
──────────────────────────────────────────────────────────── */
const FALLBACK_HERO_SLIDES = [
{ eyebrow: "Welcome", title: "SARASLOT", big: "PLAY NOW", body: "Loading promotions…", cta_label: "Explore", art: "medal" },
];
function MedalArt({ theme }) {
if (theme === "neon") {
return (
);
}
if (theme === "jade") {
return (
);
}
return (
);
}
function CoinsArt({ theme }) {
const coinColors = theme === "neon"
? ["#39FF14", "#00F0FF", "#FF00C8"]
: theme === "jade"
? ["#D4AF37", "#C8102E", "#D4AF37"]
: ["#FFD24A", "#FFB800", "#E60012"];
return (
);
}
function BallArt({ theme }) {
if (theme === "neon") {
return (
);
}
return (
);
}
function HeroArtBySlide({ slide, theme }) {
if (slide.art === "coins") return ;
if (slide.art === "ball") return ;
return ;
}
function HeroCarousel({ theme }) {
const q = window.useHeroSlides ? window.useHeroSlides() : { data: null };
const slides = (Array.isArray(q.data) && q.data.length > 0) ? q.data : FALLBACK_HERO_SLIDES;
const b = window.useBranding ? window.useBranding() : window.BRANDING_DEFAULTS;
const [idx, setIdx] = useState(0);
const pausedRef = useRef(false);
const total = slides.length;
useEffect(() => {
if (idx >= total) setIdx(0);
}, [total, idx]);
useEffect(() => {
if (total <= 1) return;
const t = setInterval(() => {
if (!pausedRef.current) setIdx((i) => (i + 1) % total);
}, 5000);
return () => clearInterval(t);
}, [total]);
const slide = slides[Math.min(idx, total - 1)] || FALLBACK_HERO_SLIDES[0];
return (
{ pausedRef.current = true; }}
onTouchEnd={() => { pausedRef.current = false; }}
onMouseEnter={() => { pausedRef.current = true; }}
onMouseLeave={() => { pausedRef.current = false; }}
>
{slide.eyebrow}
{slide.title}
{slide.big}
{slide.body}
{slides.map((_, i) => (
setIdx(i)} />
))}
{b.brand_strip_pre} {b.brand_strip_accent} {b.brand_strip_post}
);
}
window.HeroCarousel = HeroCarousel;
/* ─────────────────────────────────────────────────────────────
Marquee — items from `marquee_items` table
──────────────────────────────────────────────────────────── */
function MarqueeStrip() {
const q = window.useMarqueeItems ? window.useMarqueeItems() : { data: [] };
const items = (Array.isArray(q.data) ? q.data : []).map((r) => r.body);
if (items.length === 0) return null;
const content = (
{items.map((t, i) => (
{t}
·
))}
);
return (
);
}
window.MarqueeStrip = MarqueeStrip;
/* ─────────────────────────────────────────────────────────────
FeatureCardRow — feature_cards table
──────────────────────────────────────────────────────────── */
function FeatureCardRow({ theme }) {
const q = window.useFeatureCards ? window.useFeatureCards() : { data: [] };
const cards = Array.isArray(q.data) ? q.data : [];
if (cards.length === 0) return null;
return (
{cards.map((c) => (
{c.label}
{c.sub}
{c.icon}
))}
);
}
window.FeatureCardRow = FeatureCardRow;
/* ─────────────────────────────────────────────────────────────
ReferralBar — copy from site_settings('referral_copy')
──────────────────────────────────────────────────────────── */
function ReferralBar({ theme }) {
const q = window.useSiteSetting ? window.useSiteSetting("referral_copy") : { data: null };
const cfg = (q.data && q.data.value) || { title: "Referral", sub: "Share to Earn More!" };
return (
);
}
window.ReferralBar = ReferralBar;
Object.assign(window, { Icon, Logo, AppDownloadBanner, Header, HeroCarousel, MarqueeStrip, FeatureCardRow, ReferralBar });