Implemented language selection

This commit is contained in:
Takeshi Kimata
2024-05-03 12:10:36 +09:00
parent 1e01535134
commit 72c71efedc
6 changed files with 146 additions and 107 deletions

View File

@@ -1,98 +0,0 @@
import {
Navbar as NextUINavbar,
NavbarContent,
NavbarMenuToggle,
NavbarBrand,
NavbarItem,
Kbd,
Link as NextUiLink,
Input,
} from "@nextui-org/react";
import { Link } from "@/src/navigation";
import { siteConfig } from "@/config/site";
import { ThemeSwitch } from "@/components/theme-switch";
import { GithubIcon, SearchIcon } from "@/components/icons";
import Image from "next/image";
export const Navbar = () => {
const searchInput = (
<Input
aria-label="Search"
classNames={{
inputWrapper: "bg-default-100",
input: "text-sm",
}}
endContent={
<Kbd className="hidden lg:inline-block" keys={["command"]}>
K
</Kbd>
}
labelPlacement="outside"
placeholder="Search..."
startContent={
<SearchIcon className="text-base text-default-400 pointer-events-none flex-shrink-0" />
}
type="search"
/>
);
return (
<NextUINavbar maxWidth="xl" position="sticky" className="bg-inherit">
<NavbarContent className="basis-1/5 sm:basis-full" justify="start">
<NavbarBrand as="li" className="gap-3 max-w-fit">
<Link className="flex justify-start items-center gap-1" href="/">
<Image
src="/favicon/android-chrome-192x192.png"
width={32}
height={32}
alt="Logo"
/>
<p className="font-bold text-inherit">Test Case Manager</p>
</Link>
</NavbarBrand>
<ul className="hidden lg:flex gap-4 justify-start ml-2">
{siteConfig.navItems.map((item) => (
<NavbarItem key={item.href}>
<Link
className="data-[active=true]:text-primary data-[active=true]:font-medium"
href={item.href}
>
{item.label}
</Link>
</NavbarItem>
))}
</ul>
</NavbarContent>
<NavbarContent
className="hidden sm:flex basis-1/5 sm:basis-full"
justify="end"
>
<NavbarItem className="hidden sm:flex gap-2">
<NextUiLink
isExternal
href={siteConfig.links.github}
aria-label="Github"
>
<GithubIcon className="text-default-500" />
</NextUiLink>
<ThemeSwitch />
</NavbarItem>
<NavbarItem className="hidden lg:flex">{searchInput}</NavbarItem>
</NavbarContent>
<NavbarContent className="sm:hidden basis-1 pl-4" justify="end">
<NextUiLink
isExternal
href={siteConfig.links.github}
aria-label="Github"
>
<GithubIcon className="text-default-500" />
</NextUiLink>
<ThemeSwitch />
<NavbarMenuToggle />
</NavbarContent>
</NextUINavbar>
);
};

View File

@@ -2,8 +2,22 @@
"Index": {
"title": "Hello world!"
},
"ProjectPage": {
"projects": "Projects",
"newProject": "New Project"
"Projects": {
"projects": "プロジェクト",
"project": "プロジェクト",
"new_project": "新規プロジェクト",
"edit_project": "プロジェクトの編集",
"delete_project": "プロジェクトの削除",
"id": "ID",
"name": "名前",
"detail": "詳細",
"last_update": "最終更新",
"actions": "アクション",
"project_name": "プロジェクト名",
"project_detail": "プロジェクト詳細",
"close": "閉じる",
"create": "作成",
"update": "作成",
"please_enter": "プロジェクト名を入力してください"
}
}
}

View File

@@ -2,8 +2,22 @@
"Index": {
"title": "はろー"
},
"ProjectPage": {
"projects": "プロジェクト",
"newProject": "プロジェクトの作成"
"Projects": {
"projects": "Projects",
"project": "Project",
"new_project": "New Project",
"edit_project": "Edit Project",
"delete_project": "Delete Project",
"id": "ID",
"name": "Name",
"detail": "Detail",
"last_update": "Last update",
"actions": "Actions",
"project_name": "Project Name",
"project_detail": "Project Detail",
"close": "Close",
"create": "Create",
"update": "Update",
"please_enter": "Please enter project name"
}
}

View File

@@ -0,0 +1,65 @@
import {
Navbar as NextUINavbar,
NavbarContent,
NavbarMenuToggle,
NavbarBrand,
NavbarItem,
Link as NextUiLink
} from "@nextui-org/react";
import { useTranslations } from "next-intl";
import { siteConfig } from "@/config/site";
import { Link } from "@/src/navigation";
import LangSwitch from "./LangSwitch";
import { ThemeSwitch } from "@/components/theme-switch";
import { GithubIcon } from "@/components/icons";
import Image from "next/image";
export default function Header(params: { locale: string }) {
const t = useTranslations("Index");
return (
<NextUINavbar maxWidth="xl" position="sticky" className="bg-inherit">
<NavbarContent className="basis-1/5 sm:basis-full" justify="start">
<NavbarBrand as="li" className="gap-3 max-w-fit">
<Link
className="flex justify-start items-center gap-1"
href="/"
locale={params.locale}
>
<Image
src="/favicon/android-chrome-192x192.png"
width={32}
height={32}
alt="Logo"
/>
<p className="font-bold text-inherit">Test Case Manager</p>
</Link>
</NavbarBrand>
{siteConfig.navItems.map((item) => (
<NavbarItem key={item.href}>
<Link
className="data-[active=true]:text-primary data-[active=true]:font-medium"
href={item.href}
locale={params.locale}
>
{item.label}
</Link>
</NavbarItem>
))}
</NavbarContent>
<NavbarContent className="basis-1 pl-4" justify="end">
<NextUiLink
isExternal
href="https://github.com/kimatata/TestCaseManager"
aria-label="Github"
>
<GithubIcon className="text-default-500" />
</NextUiLink>
<ThemeSwitch />
<LangSwitch locale={params.locale} />
</NavbarContent>
</NextUINavbar>
);
}

View File

@@ -0,0 +1,44 @@
"use client";
import {
Button,
DropdownTrigger,
Dropdown,
DropdownMenu,
DropdownItem,
} from "@nextui-org/react";
import { Globe } from "lucide-react";
import { useRouter } from "@/src/navigation";
const locales = [
{ code: "en", name: "English" },
{ code: "ja", name: "日本語" },
];
export default function LangSwitch(params: { locale: string }) {
const router = useRouter();
async function changeLocale(locale: string) {
router.push("/", { locale: locale });
}
return (
<Dropdown>
<DropdownTrigger>
<Button size="sm" color="primary" startContent={<Globe size={16} />}>
{locales.find((locale) => locale.code === params.locale)?.name ||
params.locale}
</Button>
</DropdownTrigger>
<DropdownMenu aria-label="lacales">
{locales.map((entry) => (
<DropdownItem
key={entry.code}
onClick={() => changeLocale(entry.code)}
>
{entry.name}
</DropdownItem>
))}
</DropdownMenu>
</Dropdown>
);
}

View File

@@ -3,7 +3,7 @@ import { Metadata } from "next";
import { siteConfig } from "@/config/site";
import { fontSans } from "@/config/fonts";
import { Providers } from "./providers";
import { Navbar } from "@/components/navbar";
import Header from "./Header";
import clsx from "clsx";
export const metadata: Metadata = {
@@ -41,7 +41,7 @@ export default function RootLayout({
>
<Providers themeProps={{ attribute: "class", defaultTheme: "dark" }}>
<div className="relative flex flex-col min-h-screen light:bg-neutral-50 dark:bg-neutral-800">
<Navbar />
<Header locale={locale} />
<main>{children}</main>
{/* <footer className="w-full flex items-center justify-center py-3">
<Link