Skip to content

Commit

Permalink
Add i18n menu
Browse files Browse the repository at this point in the history
  • Loading branch information
slhmy committed Sep 27, 2023
1 parent bf677ea commit 8bb4716
Show file tree
Hide file tree
Showing 8 changed files with 86 additions and 14 deletions.
2 changes: 2 additions & 0 deletions src/i18n/en_US.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import { Resource } from "i18next";

const EN_US_TRANSLATIONS: Resource = {
translation: {
"English (US)": "English (US)",
"Simple Chinese": "Simple Chinese",
Problem: "Problem",
User: "User",
Contest: "Contest",
Expand Down
9 changes: 7 additions & 2 deletions src/i18n.ts → src/i18n/i18n.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import i18n from "i18next";
import { initReactI18next } from "react-i18next";
import EN_US_TRANSLATIONS from "./i18n/en_US";
import ZH_CN_TRANSLATIONS from "./i18n/zh_CN";
import EN_US_TRANSLATIONS from "./en_US";
import ZH_CN_TRANSLATIONS from "./zh_CN";

export const LANGUAGE_SELECTIONS = [
{ value: "en_US", label: "English (US)" },
{ value: "zh_CN", label: "Simple Chinese" },
];

// the translations
// (tip move them in a JSON file and import them,
Expand Down
2 changes: 2 additions & 0 deletions src/i18n/zh_CN.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import { Resource } from "i18next";

const ZH_CN_TRANSLATIONS: Resource = {
translation: {
"English (US)": "英语 (美式)",
"Simple Chinese": "简体中文",
Problem: "问题",
User: "用户",
Contest: "竞赛",
Expand Down
2 changes: 1 addition & 1 deletion src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import ReactDOM from "react-dom/client";
import reportWebVitals from "./reportWebVitals";
import { worker } from "./mocks/server";

import "./i18n";
import "./i18n/i18n";
import "./index.css";

console.log("Running in:", import.meta.env.MODE);
Expand Down
54 changes: 54 additions & 0 deletions src/layouts/LanguageMenu.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { Menu, Transition } from "@headlessui/react";
import { Fragment } from "react";
import { useTranslation } from "react-i18next";
import { joinClasses } from "../utils/common";
import { LanguageIcon } from "@heroicons/react/24/outline";
import { changeLanguage } from "i18next";
import { LANGUAGE_SELECTIONS } from "../i18n/i18n";

const LanguageMenu: React.FC = () => {
const { t } = useTranslation();

return (
<>
{/* Profile dropdown */}
<Menu as="div" className="relative">
<Menu.Button className="flex items-center p-1.5">
<span className="sr-only">Open user menu</span>
<LanguageIcon className="h-5 w-5" />
</Menu.Button>
<Transition
as={Fragment}
enter="transition ease-out duration-200"
enterFrom="transform opacity-0 scale-95"
enterTo="transform opacity-100 scale-100"
leave="transition ease-in duration-75"
leaveFrom="transform opacity-100 scale-100"
leaveTo="transform opacity-0 scale-95"
>
<Menu.Items className="absolute right-0 z-10 mt-2 w-48 origin-top-right rounded-md bg-white py-1 shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none">
{LANGUAGE_SELECTIONS.map((item) => (
<Menu.Item key={item.value}>
{({ active }) => (
<div
className={joinClasses(
active ? "bg-gray-100" : "",
"block cursor-pointer px-4 py-2 text-sm text-gray-700",
)}
onClick={() => {
changeLanguage(item.value);
}}
>
{t(item.label)}
</div>
)}
</Menu.Item>
))}
</Menu.Items>
</Transition>
</Menu>
</>
);
};

export default LanguageMenu;
2 changes: 1 addition & 1 deletion src/layouts/UserMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ const UserMenu: React.FC<UserMenuProps> = (props) => {
<>
{/* Profile dropdown */}
<Menu as="div" className="relative">
<Menu.Button className="-m-1.5 flex items-center p-1.5">
<Menu.Button className="flex items-center p-1.5">
<span className="sr-only">Open user menu</span>
<img
className="h-8 w-8 rounded-full bg-gray-50"
Expand Down
6 changes: 4 additions & 2 deletions src/layouts/adminLayout/Sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
import { useTranslation } from "react-i18next";
import { joinClasses } from "../../utils/common";
import UserMenu from "../UserMenu";
import LanguageMenu from "../LanguageMenu";

const navigation = [
{ name: "Problem", href: "/admin/problem", icon: HomeIcon, current: true },
Expand Down Expand Up @@ -199,11 +200,12 @@ export default function Sidebar(props: SidebarProps) {
</button>

<div className="flex flex-1 justify-end gap-x-4 self-stretch lg:gap-x-6">
<div className="flex items-center gap-x-4 lg:gap-x-6">
<div className="flex flex-row items-center justify-center gap-2">
<LanguageMenu />
{/* Profile dropdown */}
<UserMenu
avatarUrl={user.imageUrl}
userName={user.name}
avatarUrl={user.imageUrl}
navigation={userNavigation}
/>
</div>
Expand Down
23 changes: 15 additions & 8 deletions src/layouts/userLayout/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import {
} from "@heroicons/react/24/outline";
import UserMenu from "../UserMenu";
import { joinClasses } from "../../utils/common";
import LanguageMenu from "../LanguageMenu";
import { useTranslation } from "react-i18next";

const user = {
name: "Tom Cook",
Expand All @@ -35,6 +37,8 @@ const userNavigation = [
];

export default function Header() {
const { t } = useTranslation();

return (
<Disclosure as="nav" className="h-auto border-b border-gray-200 bg-white">
{({ open }) => (
Expand Down Expand Up @@ -68,18 +72,21 @@ export default function Header() {
aria-current={item.current ? "page" : undefined}
>
{item.icon}
{item.name}
{t(item.name)}
</a>
))}
</div>
</div>
<div className="hidden sm:ml-6 sm:flex sm:items-center">
{/* Profile dropdown */}
<UserMenu
userName={user.name}
avatarUrl={user.imageUrl}
navigation={userNavigation}
/>
<div className="flex flex-row items-center justify-center gap-2">
<LanguageMenu />
{/* Profile dropdown */}
<UserMenu
userName={user.name}
avatarUrl={user.imageUrl}
navigation={userNavigation}
/>
</div>
</div>
<div className="-mr-2 flex items-center sm:hidden">
{/* Mobile menu button */}
Expand Down Expand Up @@ -110,7 +117,7 @@ export default function Header() {
)}
aria-current={item.current ? "page" : undefined}
>
{item.name}
{t(item.name)}
</Disclosure.Button>
))}
</div>
Expand Down

0 comments on commit 8bb4716

Please sign in to comment.