/* ============================================================ VU PAGE — VU Meter Gallery Design: Reference luxsin_x8_VU表.png - 3-column grid of VU style cards - Active = cyan check circle below card - Inactive = empty circle ============================================================ */ import { useDevice } from "@/contexts/DeviceContext"; import { cn } from "@/lib/utils"; import BottomNav from "@/components/BottomNav"; import { Check, ChevronLeft } from "lucide-react"; import { useLocation } from "wouter"; import { useMemo } from "react"; import localeZh from "@/locales/data-zh.json"; import localeEn from "@/locales/data-en.json"; import { resolveLocalePack } from "@/locales/resolveLocale"; import { usePageTitleWithConnection } from "@/hooks/usePageTitleWithConnection"; type VUPageLocale = NonNullable<(typeof localeZh)["vuPage"]>; interface VUStyle { index: number; name: string; preview: string; } const VU_STYLES: VUStyle[] = Array.from({ length: 16 }, (_, i) => ({ index: i, name: `VU ${i + 1}`, preview: `${import.meta.env.BASE_URL}images/vu/vu${i + 1}.png`, })); export default function VUPage() { const [, setLocation] = useLocation(); const { deviceState, updateSetting } = useDevice(); const currentVU = deviceState?.vu ?? 0; const vuPageText = useMemo((): VUPageLocale => { const loc = resolveLocalePack(deviceState?.language); return (loc.vuPage ?? localeEn.vuPage ?? {}) as VUPageLocale; }, [deviceState?.language]); const pageTitle = usePageTitleWithConnection(vuPageText.title ?? "VU"); return (

{pageTitle}

{VU_STYLES.map((style) => { const isActive = currentVU === style.index; return (
updateSetting({ vu: style.index })} > {style.name}

{style.name}

); })}
); }