GuidePage.tsx 4.81 KB
import { useState, useEffect, useMemo } from "react";
import { BookOpen, Smartphone, Monitor } from "lucide-react";
import { DEFAULT_GUIDE_LOCALES } from "../guideContent";
import { KIOSK_EVENT, loadGuideOverrides, mergeGuideLocales } from "../kioskStorage";
import { PAGE_CONTENT_INSET } from "../pageContentInset";
import { useI18n } from "../i18n";

export function GuidePage() {
  const { lang } = useI18n();
  const [guideRev, setGuideRev] = 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 = useMemo(() => {
    const hit = LOCALES.find((l) => l.htmlLang === lang);
    return hit ?? LOCALES[0]!;
  }, [LOCALES, lang]);

  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}`}
    >
      <div 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>
          </div>
        </header>

        <div className="min-h-0 max-h-full flex-1 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-${locale.htmlLang}`}
            >
              <h2
                id={`guide-touch-${locale.htmlLang}`}
                lang={locale.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 ${
                  locale.htmlLang === "bo" ? "font-serif" : ""
                }`}
              >
                <Smartphone className="h-5 w-5 shrink-0 text-sky-400 sm:h-6 sm:w-6" />
                {locale.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 ${
                  locale.htmlLang === "bo" ? "font-serif" : ""
                }`}
                lang={locale.htmlLang}
              >
                {locale.touchItems.map((line, idx) => (
                  <li key={`t-${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-${locale.htmlLang}`}
            >
              <h2
                id={`guide-software-${locale.htmlLang}`}
                lang={locale.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 ${
                  locale.htmlLang === "bo" ? "font-serif" : ""
                }`}
              >
                <Monitor className="h-5 w-5 shrink-0 text-sky-400 sm:h-6 sm:w-6" />
                {locale.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 ${
                  locale.htmlLang === "bo" ? "font-serif" : ""
                }`}
                lang={locale.htmlLang}
              >
                {locale.softwareItems.map((line, idx) => (
                  <li key={`s-${idx}`} className="[overflow-wrap:anywhere]">
                    {line}
                  </li>
                ))}
              </ul>
            </section>
          </div>
        </div>
      </div>
    </div>
  );
}