GuidePage.tsx
6.43 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
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>
);
}