Implemented language selection
This commit is contained in:
@@ -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>
|
||||
);
|
||||
};
|
||||
@@ -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": "プロジェクト名を入力してください"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
|
||||
65
frontend/src/app/[locale]/Header.tsx
Normal file
65
frontend/src/app/[locale]/Header.tsx
Normal 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>
|
||||
);
|
||||
}
|
||||
44
frontend/src/app/[locale]/LangSwitch.tsx
Normal file
44
frontend/src/app/[locale]/LangSwitch.tsx
Normal 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>
|
||||
);
|
||||
}
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user