feat(i18n): add i18n support

This commit is contained in:
JiPai
2024-11-08 01:32:46 +08:00
parent 237106428b
commit 0ca8ee17be
9 changed files with 145 additions and 2 deletions

View File

@@ -18,6 +18,7 @@ import { Input } from "@/components/ui/input";
import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group";
import { api } from "@/utils/api";
import { zodResolver } from "@hookform/resolvers/zod";
import { useTranslation } from "next-i18next";
import { useEffect } from "react";
import { useForm } from "react-hook-form";
import { toast } from "sonner";
@@ -51,6 +52,7 @@ const randomImages = [
export const ProfileForm = () => {
const { data, refetch } = api.auth.get.useQuery();
const { mutateAsync, isLoading } = api.auth.update.useMutation();
const { t } = useTranslation("common");
const form = useForm<Profile>({
defaultValues: {
@@ -91,7 +93,9 @@ export const ProfileForm = () => {
<Card className="bg-transparent">
<CardHeader className="flex flex-row gap-2 flex-wrap justify-between items-center">
<div>
<CardTitle className="text-xl">Account</CardTitle>
<CardTitle className="text-xl">
{t("dashboard.settings.profile.title")}
</CardTitle>
<CardDescription>
Change the details of your profile here.
</CardDescription>

View File

@@ -0,0 +1,9 @@
/** @type {import('next-i18next').UserConfig} */
module.exports = {
i18n: {
defaultLocale: "en",
locales: ["en", "zh-Hans"],
localeDetection: false,
},
fallbackLng: "en",
};

View File

@@ -84,6 +84,7 @@
"dotenv": "16.4.5",
"drizzle-orm": "^0.30.8",
"drizzle-zod": "0.5.1",
"i18next": "^23.16.4",
"input-otp": "^1.2.4",
"js-yaml": "4.1.0",
"lodash": "4.17.21",
@@ -91,6 +92,7 @@
"lucide-react": "^0.312.0",
"nanoid": "3",
"next": "^15.0.1",
"next-i18next": "^15.3.1",
"next-themes": "^0.2.1",
"node-pty": "1.0.0",
"node-schedule": "2.1.1",
@@ -100,6 +102,7 @@
"react": "18.2.0",
"react-dom": "18.2.0",
"react-hook-form": "^7.49.3",
"react-i18next": "^15.1.0",
"recharts": "^2.12.7",
"slugify": "^1.6.6",
"sonner": "^1.4.0",

View File

@@ -3,6 +3,7 @@ import "@/styles/globals.css";
import { Toaster } from "@/components/ui/sonner";
import { api } from "@/utils/api";
import type { NextPage } from "next";
import { appWithTranslation } from "next-i18next";
import { ThemeProvider } from "next-themes";
import type { AppProps } from "next/app";
import { Inter } from "next/font/google";
@@ -27,6 +28,7 @@ const MyApp = ({
pageProps: { ...pageProps },
}: AppPropsWithLayout) => {
const getLayout = Component.getLayout ?? ((page) => page);
return (
<>
<style jsx global>{`
@@ -59,4 +61,4 @@ const MyApp = ({
);
};
export default api.withTRPC(MyApp);
export default api.withTRPC(appWithTranslation(MyApp));

View File

@@ -4,9 +4,11 @@ import { DashboardLayout } from "@/components/layouts/dashboard-layout";
import { SettingsLayout } from "@/components/layouts/settings-layout";
import { appRouter } from "@/server/api/root";
import { api } from "@/utils/api";
import { getLocale } from "@/utils/i18n";
import { validateRequest } from "@dokploy/server";
import { createServerSideHelpers } from "@trpc/react-query/server";
import type { GetServerSidePropsContext } from "next";
import { serverSideTranslations } from "next-i18next/serverSideTranslations";
import React, { type ReactElement } from "react";
import superjson from "superjson";
@@ -41,6 +43,7 @@ export async function getServerSideProps(
ctx: GetServerSidePropsContext<{ serviceId: string }>,
) {
const { req, res } = ctx;
const locale = getLocale(req.cookies);
const { user, session } = await validateRequest(req, res);
const helpers = createServerSideHelpers({
@@ -75,6 +78,7 @@ export async function getServerSideProps(
return {
props: {
trpcState: helpers.dehydrate(),
...(await serverSideTranslations(locale, ["common"])),
},
};
}

View File

@@ -0,0 +1,9 @@
{
"dashboard": {
"settings": {
"profile": {
"title": "Account"
}
}
}
}

View File

@@ -0,0 +1,9 @@
{
"dashboard": {
"settings": {
"profile": {
"title": "账户偏好"
}
}
}
}

View File

@@ -0,0 +1,6 @@
import type { NextApiRequestCookies } from "next/dist/server/api-utils";
export function getLocale(cookies: NextApiRequestCookies) {
const locale = cookies.DOKPLOY_LOCALE ?? "en";
return locale;
}