GuidePage.tsx 6.43 KB
import { useState, useEffect, useMemo } from "react";
import { BookOpen, Smartphone, Monitor } from "lucide-react";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "../components/ui/tabs";
import { DEFAULT_GUIDE_LOCALES } from "../guideContent";
import { KIOSK_EVENT, loadGuideOverrides, mergeGuideLocales } from "../kioskStorage";
import { PAGE_CONTENT_INSET } from "../pageContentInset";

export function GuidePage() {
  const [guideRev, setGuideRev] = useState(0);
  const [langIdx, setLangIdx] = useState(0);

  useEffect(() => {
    const h = () => setGuideRev((r) => r + 1);
    window.addEventListener(KIOSK_EVENT, h);
    window.addEventListener("storage", h);
    return () => {
      window.removeEventListener(KIOSK_EVENT, h);
      window.removeEventListener("storage", h);
    };
  }, []);

  const LOCALES = useMemo(
    () => mergeGuideLocales(DEFAULT_GUIDE_LOCALES, loadGuideOverrides()),
    [guideRev]
  );

  const locale = LOCALES[langIdx]!;

  useEffect(() => {
    document.documentElement.lang = locale.htmlLang;
    return () => {
      document.documentElement.lang = "zh-CN";
    };
  }, [locale.htmlLang]);

  return (
    <div
      className={`flex h-full min-h-0 w-full flex-1 flex-col overflow-hidden ${PAGE_CONTENT_INSET}`}
    >
      <Tabs
        value={locale.htmlLang}
        onValueChange={(v) => {
          const i = LOCALES.findIndex((l) => l.htmlLang === v);
          if (i >= 0) setLangIdx(i);
        }}
        className="flex min-h-0 w-full min-w-0 flex-1 flex-col gap-3 overflow-hidden sm:gap-4"
      >
        <header className="shrink-0 space-y-2 sm:space-y-2.5">
          <div className="flex flex-col gap-3 sm:flex-row sm:items-start sm:justify-between sm:gap-4">
            <h1
              lang={locale.htmlLang}
              className={`flex items-center gap-2 text-xl font-bold text-white sm:gap-2 sm:text-2xl ${
                locale.htmlLang === "bo" ? "font-serif" : ""
              }`}
            >
              <BookOpen className="h-6 w-6 shrink-0 text-sky-400 sm:h-7 sm:w-7" />
              {locale.title}
            </h1>
            <TabsList
              className="h-auto w-full shrink-0 flex-wrap justify-stretch gap-1 rounded-xl border border-white/15 bg-white/5 p-1 sm:w-auto sm:flex-nowrap"
              aria-label="语言"
            >
              {LOCALES.map((item) => (
                <TabsTrigger
                  key={item.htmlLang}
                  value={item.htmlLang}
                  className="min-h-[2.25rem] flex-1 rounded-lg border border-transparent px-3 py-1.5 text-sm font-medium text-blue-200 transition-colors data-[state=active]:border-white/20 data-[state=active]:bg-sky-500/90 data-[state=active]:text-white data-[state=inactive]:bg-transparent data-[state=inactive]:hover:bg-white/10 data-[state=inactive]:hover:text-white sm:flex-none sm:px-4 sm:py-2"
                >
                  {item.label}
                </TabsTrigger>
              ))}
            </TabsList>
          </div>
        </header>

        {LOCALES.map((loc, localeIdx) => (
          <TabsContent
            key={loc.htmlLang}
            value={loc.htmlLang}
            className="mt-0 min-h-0 flex-1 overflow-hidden outline-none data-[state=inactive]:hidden"
          >
            <div className="min-h-0 max-h-full overflow-y-auto overscroll-y-contain [-webkit-overflow-scrolling:touch] pr-0.5">
              <div className="grid grid-cols-1 gap-4 pb-1 lg:grid-cols-2 lg:gap-6 lg:pb-0">
                <section
                  className="flex min-h-0 min-w-0 flex-col rounded-2xl border border-white/20 bg-white/10 p-5 backdrop-blur-xl sm:p-6 lg:min-h-0 lg:p-8"
                  aria-labelledby={`guide-touch-${loc.htmlLang}`}
                >
                  <h2
                    id={`guide-touch-${loc.htmlLang}`}
                    lang={loc.htmlLang}
                    className={`mb-3 flex shrink-0 items-center gap-2 text-lg font-bold leading-snug text-white sm:mb-4 sm:text-xl ${
                      loc.htmlLang === "bo" ? "font-serif" : ""
                    }`}
                  >
                    <Smartphone className="h-5 w-5 shrink-0 text-sky-400 sm:h-6 sm:w-6" />
                    {loc.touchTitle}
                  </h2>
                  <ul
                    className={`list-outside list-disc space-y-3 pl-10 text-sm leading-relaxed text-blue-100 marker:text-sky-400 sm:space-y-3.5 sm:pl-11 sm:text-base sm:leading-loose ${
                      loc.htmlLang === "bo" ? "font-serif" : ""
                    }`}
                    lang={loc.htmlLang}
                  >
                    {loc.touchItems.map((line, idx) => (
                      <li
                        key={`t-${localeIdx}-${idx}`}
                        className="[overflow-wrap:anywhere]"
                      >
                        {line}
                      </li>
                    ))}
                  </ul>
                </section>

                <section
                  className="flex min-h-0 min-w-0 flex-col rounded-2xl border border-white/20 bg-white/10 p-5 backdrop-blur-xl sm:p-6 lg:min-h-0 lg:p-8"
                  aria-labelledby={`guide-software-${loc.htmlLang}`}
                >
                  <h2
                    id={`guide-software-${loc.htmlLang}`}
                    lang={loc.htmlLang}
                    className={`mb-3 flex shrink-0 items-center gap-2 text-lg font-bold leading-snug text-white sm:mb-4 sm:text-xl ${
                      loc.htmlLang === "bo" ? "font-serif" : ""
                    }`}
                  >
                    <Monitor className="h-5 w-5 shrink-0 text-sky-400 sm:h-6 sm:w-6" />
                    {loc.softwareTitle}
                  </h2>
                  <ul
                    className={`list-outside list-disc space-y-3 pl-10 text-sm leading-relaxed text-blue-100 marker:text-sky-400 sm:space-y-3.5 sm:pl-11 sm:text-base sm:leading-loose ${
                      loc.htmlLang === "bo" ? "font-serif" : ""
                    }`}
                    lang={loc.htmlLang}
                  >
                    {loc.softwareItems.map((line, idx) => (
                      <li
                        key={`s-${localeIdx}-${idx}`}
                        className="[overflow-wrap:anywhere]"
                      >
                        {line}
                      </li>
                    ))}
                  </ul>
                </section>
              </div>
            </div>
          </TabsContent>
        ))}
      </Tabs>
    </div>
  );
}