diff --git a/src/app/client/page.tsx b/src/app/client/page.tsx
index cd48f7a2..98439704 100644
--- a/src/app/client/page.tsx
+++ b/src/app/client/page.tsx
@@ -1,10 +1,25 @@
"use client";
-import { useCallback, useEffect, useRef, useState } from "react";
+import { useCallback, useEffect, useRef, useState, type ReactNode } from "react";
import Link from "next/link";
import { useTranslations } from "next-intl";
import { ContentCard, SkeletonCard } from "@/components/public/ui";
+function ToolbarBtn({ onClick, title, children, href }: {
+ onClick?: () => void; title: string; children: ReactNode; href?: string;
+}) {
+ const cls = "w-10 h-10 rounded-lg border-2 cursor-pointer flex items-center justify-center shadow-lg transition-all duration-200 hover:-translate-y-0.5 hover:shadow-xl active:translate-y-0";
+ const style = {
+ borderColor: "color-mix(in srgb, var(--color-primary, #eeb425) 75%, black)",
+ background: "linear-gradient(135deg, var(--color-primary, #eeb425) 0%, color-mix(in srgb, var(--color-primary, #eeb425) 80%, black) 100%)",
+ color: "var(--button-text-color, #1a1a2e)",
+ } as const;
+ if (href) {
+ return {children};
+ }
+ return ;
+}
+
export default function ClientPage() {
const t = useTranslations("pages.client");
const [ticket, setTicket] = useState(null);
@@ -21,16 +36,19 @@ export default function ClientPage() {
if (fetchedRef.current) return;
fetchedRef.current = true;
- async function fetchTicket() {
+ async function init() {
try {
- const res = await fetch("/api/client/sso");
- if (res.status === 401) {
+ const [ssoRes] = await Promise.all([
+ fetch("/api/client/sso"),
+ fetch("/api/online/count").then(r => r.ok ? r.json() : { count: 0 }).then(d => setOnlineCount(d.count)).catch(() => {}),
+ ]);
+ if (ssoRes.status === 401) {
setErrorType("auth");
setError(t("errors.unauthorized"));
return;
}
- if (!res.ok) throw new Error("SSO fetch failed");
- const data = await res.json();
+ if (!ssoRes.ok) throw new Error("SSO fetch failed");
+ const data = await ssoRes.json();
setTicket(data.ticket);
setHotelName(data.hotelName);
if (data.clientUrl) setClientUrl(data.clientUrl);
@@ -41,25 +59,16 @@ export default function ClientPage() {
setLoading(false);
}
}
- fetchTicket();
- }, [t]);
+ init();
- useEffect(() => {
- async function fetchOnline() {
+ const interval = setInterval(async () => {
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);
+ if (res.ok) setOnlineCount((await res.json()).count ?? 0);
+ } catch {}
+ }, 15000);
return () => clearInterval(interval);
- }, []);
+ }, [t]);
const toggleFullscreen = useCallback(() => {
if (!document.fullscreenElement) {
@@ -150,58 +159,24 @@ export default function ClientPage() {
{/* Floating Toolbar */}
- {/* Home Button */}
-
+
-
-
- {/* Reload Button */}
-
+
window.location.reload()} title="Reload">
-
-
- {/* Fullscreen Button */}
-
+
-
-
- {/* Online Count Button */}
+