Skip to content

Commit

Permalink
feat: 切換語系
Browse files Browse the repository at this point in the history
  • Loading branch information
sexyoung committed Jul 31, 2023
1 parent 4b483bc commit 02b0aef
Show file tree
Hide file tree
Showing 7 changed files with 123 additions and 11 deletions.
87 changes: 87 additions & 0 deletions app/components/LangModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import { useEffect } from "react";
import { useTranslation } from "react-i18next";

type ModalProps = {
lang: string;
onClose: () => void;
};

let path: string = "";

export default function LangModal({ onClose, lang }: ModalProps) {
let { t } = useTranslation("common");
useEffect(() => {
document.body.classList.add("overflow-hidden");
path = location.pathname.split("/").at(-1) || "";
}, [lang]);

return (
<div
className="relative z-10"
aria-labelledby="modal-title"
role="dialog"
aria-modal="true"
>
{/* <!--
Background backdrop, show/hide based on modal state.
Entering: "ease-out duration-300"
From: "opacity-0"
To: "opacity-100"
Leaving: "ease-in duration-200"
From: "opacity-100"
To: "opacity-0"
--> */}
<div className="fixed inset-0 bg-gray-500 bg-opacity-75 transition-opacity"></div>

<div className="fixed inset-0 z-10 overflow-y-auto">
<div
className="flex min-h-full items-end justify-center p-4 text-center sm:items-center sm:p-0"
onClick={onClose}
>
<div className="relative transform overflow-hidden rounded-lg bg-white text-left shadow-xl transition-all sm:my-8 sm:w-full sm:max-w-lg">
<div className="bg-white px-4 pb-4 pt-5 sm:p-6 sm:pb-4">
<div className="sm:flex sm:items-start">
<div className="mx-auto mt-3 text-center sm:mt-0">
<h3
className="text-base font-semibold leading-6 text-gray-900"
id="modal-title"
>
切換語系
</h3>
<div className="mt-2 text-sm text-gray-500">
<ul className="whitespace-nowrap bg-white py-2 text-black [&>*]:py-0.5">
<li>
<a href={[`/zh-TW`, path].join("/")}>
{t("menu.zh-TW")}
</a>
</li>
<li>
<a href={`/${path}`}>{t("menu.")}</a>
</li>
<li>
<a href={["/ja-JP", path].join("/")}>
{t("menu.ja-JP")}
</a>
</li>
<li>
<a href={["/vi-VN", path].join("/")}>
{t("menu.vi-VN")}
</a>
</li>
<li>
<a href={["/id-ID", path].join("/")}>
{t("menu.id-ID")}
</a>
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
);
}
5 changes: 3 additions & 2 deletions app/components/footer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ import Links from "./links";

type FooterProps = {
lang: string;
openLang: () => void;
};

export default function Footer({ lang }: FooterProps) {
export default function Footer({ lang, openLang }: FooterProps) {
return (
<div className="mt-10 bg-slate-100">
<footer className="container mx-auto py-5 text-center text-[#9b8e8e]">
Expand All @@ -15,7 +16,7 @@ export default function Footer({ lang }: FooterProps) {
alt="Home"
/> */}
<ul className="my-5 inline-block whitespace-nowrap [&>*]:mx-2 [&>*]:my-2 sm:[&>*]:block md:[&>*]:inline-block">
<Links {...{ lang }} />
<Links {...{ lang }} openLang={openLang} />
</ul>
<div className="flex-1 px-4">
本網站是由台大醫院雲林分院所贊助,網站作者群無財務衝突關係
Expand Down
11 changes: 8 additions & 3 deletions app/components/header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,22 @@ import Links from "./links";
type HeaderProps = {
lang: string;
isHeaderBG: boolean;
openLang: () => void;
};

export default function Header({ lang, isHeaderBG }: HeaderProps) {
export default function Header({
lang = "",
isHeaderBG,
openLang,
}: HeaderProps) {
const headerBG = isHeaderBG ? "bg-slate-100" : "";
const svgColor = isHeaderBG ? "text-red-200" : "";
return (
<header
className={`fixed inset-x-0 top-0 z-50 md:absolute ${headerBG} md:bg-transparent`}
>
<nav className="container mx-auto flex flex-wrap items-start justify-between px-5 py-5 text-right md:block md:px-0">
<Link to="/">
<Link to={`/${lang}`}>
<img src={logo} className="mr-5 inline-block w-[60px]" alt="Home" />
</Link>
<label htmlFor="menu-toggle" className="pointer-cursor block md:hidden">
Expand All @@ -37,7 +42,7 @@ export default function Header({ lang, isHeaderBG }: HeaderProps) {
id="menu-toggle"
/>
<ul id="menu" className="header-menu">
<Links {...{ lang }} />
<Links openLang={openLang} {...{ lang }} />
</ul>
</nav>
</header>
Expand Down
8 changes: 7 additions & 1 deletion app/components/links.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ import { useTranslation } from "react-i18next";

type HeaderProps = {
lang: string;
openLang: () => void;
};

export default function Links({ lang }: HeaderProps) {
export default function Links({ lang, openLang }: HeaderProps) {
let { t } = useTranslation("common");
const prefix = lang && `/${lang}`;
const handleClick = () => {
Expand Down Expand Up @@ -48,6 +49,11 @@ export default function Links({ lang }: HeaderProps) {
{t("menu.contact")}
</Link>
</li>
<li className="relative">
<span className="cursor-pointer" onClick={openLang}>
{t(`menu.${lang}`)}
</span>
</li>
</>
);
}
4 changes: 2 additions & 2 deletions app/components/modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -68,13 +68,13 @@ export default function Modal({ onClose, personLink, proLink }: ModalProps) {
<div className="justify-center gap-4 bg-gray-50 px-4 py-3 sm:flex sm:flex-row-reverse sm:px-6">
<Link
to={personLink}
className="rounded-full bg-[#4e81bd] px-4 py-2 font-bold text-white hover:bg-[#3e6796]"
className="rounded-full bg-[#9b8e8e] px-4 py-2 font-bold text-white hover:bg-[#3e6796]"
>
個人表單
</Link>
<Link
to={proLink}
className="rounded-full bg-[#4e81bd] px-4 py-2 font-bold text-white hover:bg-[#3e6796]"
className="rounded-full bg-[#9b8e8e] px-4 py-2 font-bold text-white hover:bg-[#3e6796]"
>
醫療人員表單
</Link>
Expand Down
12 changes: 10 additions & 2 deletions app/root.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import stylesheet from "~/tailwind.css";
import Modal from "./components/modal";
import Header from "./components/header";
import Footer from "./components/footer";
import LangModal from "./components/LangModal";

export const links: LinksFunction = () => [
{ rel: "stylesheet", href: stylesheet },
Expand Down Expand Up @@ -71,6 +72,7 @@ export default function App() {
const [goTop, setGoTop] = useState("hidden");
const [isHeaderBG, setIsHeaderBG] = useState(false);
const [showModal, setShowModal] = useState(false);
const [showLangModal, setShowLangModal] = useState(false);
const [isPlayLogo, setIsPlayLogo] = useState<boolean | null>(null);
const bottomToTop = () => {
window.scrollTo({
Expand All @@ -94,6 +96,7 @@ export default function App() {
const handleCloseModal = () => {
document.body.classList.remove("overflow-hidden");
setShowModal(false);
setShowLangModal(false);
};

useEffect(() => {
Expand All @@ -117,7 +120,11 @@ export default function App() {
<Links />
</head>
<body className="h-full">
<Header isHeaderBG={isHeaderBG} lang={lang} />
<Header
isHeaderBG={isHeaderBG}
openLang={setShowLangModal.bind(null, true)}
lang={lang}
/>
<Outlet />
<div className="mt-10 text-center text-[#9b8e8e]">
<img src={icon5} className="mx-auto w-20" alt="icon" />
Expand All @@ -144,14 +151,15 @@ export default function App() {
</Link>
</div>
</div>
<Footer lang={lang} />
<Footer lang={lang} openLang={setShowLangModal.bind(null, true)} />
{showModal && !isToday() && (
<Modal
proLink={formLink[lang].pro}
personLink={formLink[lang].person}
onClose={handleCloseModal}
/>
)}
{showLangModal && <LangModal lang={lang} onClose={handleCloseModal} />}
<div
onClick={bottomToTop}
className={`fixed bottom-7 right-7 flex h-[31px] w-[31px] cursor-pointer items-center justify-center bg-slate-400 opacity-80 ${goTop}`}
Expand Down
7 changes: 6 additions & 1 deletion public/locales/zh-TW/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@
"choice": "選擇障礙專區",
"curing": "CP 值專區",
"assessment": "專業評估",
"contact": "關於我們"
"contact": "關於我們",
"zh-TW": "中文",
"": "English",
"ja-JP": "日本語",
"vi-VN": "Tiếng Việt",
"id-ID": "bahasa Indonésia"
}
}

0 comments on commit 02b0aef

Please sign in to comment.