fix: error layout

This commit is contained in:
hamster1963 2024-09-26 12:26:39 +08:00
parent 3de5a8193b
commit b02e995a99
5 changed files with 157 additions and 68 deletions

View File

@ -6,6 +6,7 @@ import Image from "next/image";
import { Separator } from "../../../components/ui/separator";
import { DateTime } from "luxon";
import { ModeToggle } from "../../../components/ThemeSwitcher";
import { LanguageSwitcher } from "@/components/LanguageSwitcher";
function Header() {
const t = useTranslations("Header");
return (
@ -31,7 +32,10 @@ function Header() {
{t("p_1079-1199_Simpleandbeautifuldashbo")}
</p>
</section>
<ModeToggle />
<section className="flex items-center gap-2">
<LanguageSwitcher />
<ModeToggle />
</section>
</section>
<Overview />
</div>

View File

@ -1,7 +1,37 @@
import { useTranslations } from "next-intl";
import React from "react";
import Header from "@/app/[locale]/(main)/header";
import Footer from "./footer";
import type { Metadata } from "next";
import { Inter as FontSans } from "next/font/google";
import { ThemeProvider } from "next-themes";
import { Viewport } from "next";
import { cn } from "@/lib/utils";
import { PublicEnvScript } from "next-runtime-env";
const fontSans = FontSans({
subsets: ["latin"],
variable: "--font-sans",
});
export const metadata: Metadata = {
manifest: "/manifest.json",
title: "NezhaDash",
description: "A dashboard for nezha",
appleWebApp: {
capable: true,
title: "NezhaDash",
statusBarStyle: "black-translucent",
},
};
export const viewport: Viewport = {
width: "device-width",
initialScale: 1,
maximumScale: 1,
userScalable: false,
};
type DashboardProps = {
children: React.ReactNode;
};

View File

@ -1,7 +1,37 @@
// @auto-i18n-check. Please do not delete the line.
import "@/styles/globals.css";
import React from "react";
import { NextIntlClientProvider, useMessages } from "next-intl";
import { PublicEnvScript } from "next-runtime-env";
import type { Metadata } from "next";
import { Inter as FontSans } from "next/font/google";
import { ThemeProvider } from "next-themes";
import { Viewport } from "next";
import { cn } from "@/lib/utils";
const fontSans = FontSans({
subsets: ["latin"],
variable: "--font-sans",
});
export const metadata: Metadata = {
manifest: "/manifest.json",
title: "NezhaDash",
description: "A dashboard for nezha",
appleWebApp: {
capable: true,
title: "NezhaDash",
statusBarStyle: "black-translucent",
},
};
export const viewport: Viewport = {
width: "device-width",
initialScale: 1,
maximumScale: 1,
userScalable: false,
};
export default function LocaleLayout({
children,
@ -12,11 +42,26 @@ export default function LocaleLayout({
}) {
const messages = useMessages();
return (
<html lang={locale}>
<body>
<NextIntlClientProvider locale={locale} messages={messages}>
{children}
</NextIntlClientProvider>
<html lang={locale} suppressHydrationWarning>
<head>
<PublicEnvScript />
</head>
<body
className={cn(
"min-h-screen bg-background font-sans antialiased",
fontSans.variable,
)}
>
<ThemeProvider
attribute="class"
defaultTheme="system"
enableSystem
disableTransitionOnChange
>
<NextIntlClientProvider locale={locale} messages={messages}>
{children}
</NextIntlClientProvider>
</ThemeProvider>
</body>
</html>
);

View File

@ -1,61 +0,0 @@
import "@/styles/globals.css";
import type { Metadata } from "next";
import { Inter as FontSans } from "next/font/google";
import { ThemeProvider } from "next-themes";
import React from "react";
import { Viewport } from "next";
import { cn } from "@/lib/utils";
import { PublicEnvScript } from "next-runtime-env";
const fontSans = FontSans({
subsets: ["latin"],
variable: "--font-sans",
});
export const metadata: Metadata = {
manifest: "/manifest.json",
title: "NezhaDash",
description: "A dashboard for nezha",
appleWebApp: {
capable: true,
title: "NezhaDash",
statusBarStyle: "black-translucent",
},
};
export const viewport: Viewport = {
width: "device-width",
initialScale: 1,
maximumScale: 1,
userScalable: false,
};
interface RootLayoutProps {
children: React.ReactNode;
}
export default function RootLayout({ children }: RootLayoutProps) {
return (
<html lang="en" suppressHydrationWarning>
<head>
<PublicEnvScript />
</head>
<body
className={cn(
"min-h-screen bg-background font-sans antialiased",
fontSans.variable,
)}
>
<ThemeProvider
attribute="class"
defaultTheme="system"
enableSystem
disableTransitionOnChange
>
{children}
</ThemeProvider>
</body>
</html>
);
}

View File

@ -0,0 +1,71 @@
"use client";
import { useLocale } from "next-intl";
import { localeItems } from "../i18n-metadata";
import { useRouter, usePathname } from "next/navigation";
import * as React from "react";
import { Button } from "@/components/ui/button";
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
export function LanguageSwitcher() {
const locale = useLocale();
const router = useRouter();
const pathname = usePathname();
const handleChange = (code: string) => {
const newLocale = code;
const rootPath = "/";
const currentLocalePath = `/${locale}`;
const newLocalePath = `/${newLocale}`;
// Function to construct new path with locale prefix
const constructLocalePath = (path: string, newLocale: string) => {
if (path.startsWith(currentLocalePath)) {
return path.replace(currentLocalePath, `/${newLocale}`);
} else {
return `/${newLocale}${path}`;
}
};
if (pathname === rootPath || !pathname) {
router.push(newLocalePath);
} else if (
pathname === currentLocalePath ||
pathname === `${currentLocalePath}/`
) {
router.push(newLocalePath);
} else {
const newPath = constructLocalePath(pathname, newLocale);
router.push(newPath);
}
router.refresh();
};
return (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="outline" size="sm" className="rounded-full px-[9px]">
{localeItems.find((item) => item.code === locale)?.name}
<span className="sr-only">Change language</span>
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
{localeItems.map((item) => (
<DropdownMenuItem
key={item.code}
onClick={() => handleChange(item.code)}
>
{item.name}
</DropdownMenuItem>
))}
</DropdownMenuContent>
</DropdownMenu>
);
}