"use client"; import { useCallback, useEffect, useRef, useState } from "react"; import Link from "next/link"; import { useTranslations } from "next-intl"; import { ContentCard, SkeletonCard } from "@/components/public/ui"; export default function ClientPage() { const t = useTranslations("pages.client"); const [ticket, setTicket] = useState(null); const [clientUrl, setClientUrl] = useState("/nitro-client/"); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [errorType, setErrorType] = useState<"auth" | "generic" | null>(null); const [hotelName, setHotelName] = useState(""); const [isFullscreen, setIsFullscreen] = useState(false); const [onlineCount, setOnlineCount] = useState(0); const fetchedRef = useRef(false); useEffect(() => { if (fetchedRef.current) return; fetchedRef.current = true; async function fetchTicket() { try { const res = await fetch("/api/client/sso"); if (res.status === 401) { setErrorType("auth"); setError(t("errors.unauthorized")); return; } if (!res.ok) throw new Error("SSO fetch failed"); const data = await res.json(); setTicket(data.ticket); setHotelName(data.hotelName); if (data.clientUrl) setClientUrl(data.clientUrl); } catch { setErrorType("generic"); setError(t("errors.generic")); } finally { setLoading(false); } } fetchTicket(); }, [t]); useEffect(() => { async function fetchOnline() { try { const res = await fetch("/api/online/count"); if (res.ok) { const data = await res.json(); setOnlineCount(data.count ?? 0); } } catch { // ignore } } fetchOnline(); const interval = setInterval(fetchOnline, 15000); return () => clearInterval(interval); }, []); const toggleFullscreen = useCallback(() => { if (!document.fullscreenElement) { document.documentElement.requestFullscreen(); setIsFullscreen(true); } else { document.exitFullscreen(); setIsFullscreen(false); } }, []); useEffect(() => { function onFullscreenChange() { setIsFullscreen(!!document.fullscreenElement); } document.addEventListener("fullscreenchange", onFullscreenChange); return () => document.removeEventListener("fullscreenchange", onFullscreenChange); }, []); const getClientSrc = useCallback(() => { if (!ticket) return ""; const sep = clientUrl.includes("?") ? "&" : "?"; return `${clientUrl}${sep}sso=${encodeURIComponent(ticket)}`; }, [clientUrl, ticket]); if (loading) { return (
); } if (errorType === "auth") { return (
{hotelName || "Atom"}
{t("errors.loginRedirect")}
); } if (errorType === "generic" || !ticket) { return (
{hotelName || "Atom"}

{error ?? t("errors.generic")}

); } const clientSrc = getClientSrc(); return (
{/* Floating Toolbar */}
{/* Home Button */} {/* Reload Button */} {/* Fullscreen Button */} {/* Online Count Button */}
{onlineCount}
{/* Game Iframe */}