feat: integrate Sensei Spook mascot in 4 stances, speech bubbles, and style updates

This commit is contained in:
Ajasra committed 2026-10-28 01:20:01 +08:00
commit e04672db2a
104 files changed
+8262

No files matched your search

+122
View File
@@ -0,0 +1,122 @@
"use client";
import React, { useState, useEffect } from "react";
import { BoothConfig } from "@/types/booth";
import { SpookyAtmosphere } from "@/components/SpookyAtmosphere";
import { useI18n } from "@/lib/i18n";
import { Globe } from "lucide-react";
interface KioskFrameProps {
config: BoothConfig;
children: React.ReactNode;
showHeaderLogo?: boolean;
showLanguageToggle?: boolean;
}
export const KioskFrame: React.FC<KioskFrameProps> = ({
config,
children,
showHeaderLogo = true,
showLanguageToggle = true,
}) => {
const [isModeFullscreen, setIsModeFullscreen] = useState(false);
const { language, toggleLanguage, isWeChat } = useI18n();
useEffect(() => {
if (typeof window !== "undefined") {
const params = new URLSearchParams(window.location.search);
const isFull = params.get("mode") === "fullscreen";
setIsModeFullscreen(isFull);
if (isFull) {
const triggerFullscreen = () => {
if (!document.fullscreenElement && document.documentElement.requestFullscreen) {
document.documentElement.requestFullscreen().catch((err) => {
console.log("[Kiosk] Fullscreen request prevented:", err);
});
}
};
window.addEventListener("pointerdown", triggerFullscreen, { once: true });
return () => window.removeEventListener("pointerdown", triggerFullscreen);
}
}
}, []);
const theme = config.theme;
return (
<div
data-fullscreen={isModeFullscreen}
className={`relative flex flex-col overflow-hidden select-none transition-all duration-300 ${
isModeFullscreen
? "w-screen h-screen max-w-none max-h-none rounded-none border-0 shadow-none"
: "kiosk-viewport rounded-none sm:rounded-3xl border-4 border-black shadow-[0_12px_0_#090314,0_0_40px_rgba(255,109,0,0.25)]"
}`}
style={
{
"--brand-primary": theme.primaryColor,
"--brand-accent": theme.accentColor,
"--brand-bg": theme.backgroundColor,
"--brand-surface": theme.surfaceColor,
"--brand-text": theme.textColor,
} as React.CSSProperties
}
>
{/* Dynamic Martial Arts & Shanghai Halloween Atmosphere */}
<SpookyAtmosphere />
{/* Floating Language Toggle (Top Right) */}
{showLanguageToggle && (
<div className="absolute top-[max(0.75rem,env(safe-area-inset-top))] right-4 z-30">
<button
onClick={toggleLanguage}
className="flex items-center space-x-1.5 px-3 py-1.5 rounded-full bg-[#1b0f2e]/90 hover:bg-[#2b184a] text-amber-300 border-2 border-black shadow-[0_3px_0_#090314] text-xs font-black tracking-wider transition active:scale-95"
title={language === "zh" ? "Switch to English" : "切换为中文"}
>
<Globe size={13} className="text-amber-400" />
<span>{language === "zh" ? "EN" : "中"}</span>
</button>
</div>
)}
{/* Brand Header Logo - 20% larger */}
{showHeaderLogo && (
<header className="no-print pt-[max(0.5rem,env(safe-area-inset-top))] sm:pt-3 pb-0.5 px-4 flex justify-center items-center z-20">
<div className="relative flex items-center justify-center">
{theme.logoUrl ? (
// eslint-disable-next-line @next/next/no-img-element
<img
src={theme.logoUrl}
alt={config.appName}
className="w-56 sm:w-72 md:w-84 h-auto max-h-16 sm:max-h-20 object-contain drop-shadow-[0_4px_14px_rgba(0,0,0,0.85)] filter"
/>
) : (
<h1 className="text-lg sm:text-xl font-black tracking-wider text-white uppercase drop-shadow-[0_3px_0_#090314]">
{config.appName}
</h1>
)}
</div>
</header>
)}
{/* Screen Content Layer */}
<main className="flex-1 relative flex flex-col overflow-hidden z-10 w-full pl-[max(0px,env(safe-area-inset-left))] pr-[max(0px,env(safe-area-inset-right))]">
{children}
</main>
{/* Dojo Brand Footer - clean single line, smaller font, no emoji */}
<footer className="no-print pt-0.5 pb-[max(0.75rem,env(safe-area-inset-bottom))] px-2 flex items-center justify-center z-20 select-none">
<a
href="https://www.shanghaikarate.com"
target="_blank"
rel="noopener noreferrer"
className="text-[8.5px] sm:text-[9.5px] text-white/50 hover:text-amber-300 transition-colors whitespace-nowrap overflow-hidden text-ellipsis tracking-wide"
title="Shanghai Karate Club (shanghaikarate.com)"
>
<span>上海健志空手道馆 · Shanghai Karate Club · Est. 2008</span>
</a>
</footer>
</div>
);
};