From 7903ddba89e6235ada42fd5c91775deec34aff13 Mon Sep 17 00:00:00 2001 From: JiPai Date: Sun, 9 Mar 2025 16:53:19 +0800 Subject: [PATCH] feat(i18n): add i18n support for sidebar --- apps/dokploy/components/layouts/side.tsx | 77 +++++++++--- apps/dokploy/pages/dashboard/settings/ai.tsx | 2 +- .../pages/dashboard/settings/billing.tsx | 3 + .../pages/dashboard/settings/certificates.tsx | 3 + .../pages/dashboard/settings/cluster.tsx | 3 + .../pages/dashboard/settings/destinations.tsx | 3 + .../dashboard/settings/git-providers.tsx | 115 +++++++++--------- .../pages/dashboard/settings/index.tsx | 3 + .../dashboard/settings/notifications.tsx | 3 + .../pages/dashboard/settings/profile.tsx | 2 +- .../pages/dashboard/settings/registry.tsx | 3 + .../pages/dashboard/settings/server.tsx | 2 +- .../pages/dashboard/settings/servers.tsx | 2 +- .../pages/dashboard/settings/ssh-keys.tsx | 7 +- .../pages/dashboard/settings/users.tsx | 3 + apps/dokploy/public/locales/en/common.json | 38 +++++- .../public/locales/zh-Hans/common.json | 38 +++++- 17 files changed, 229 insertions(+), 78 deletions(-) diff --git a/apps/dokploy/components/layouts/side.tsx b/apps/dokploy/components/layouts/side.tsx index 0b29112a..f7d0a097 100644 --- a/apps/dokploy/components/layouts/side.tsx +++ b/apps/dokploy/components/layouts/side.tsx @@ -86,6 +86,7 @@ import { Logo } from "../shared/logo"; import { Button } from "../ui/button"; import { UpdateServerButton } from "./update-server"; import { UserNav } from "./user-nav"; +import { useTranslation } from "next-i18next"; // The types of the queries we are going to use type AuthQueryOutput = inferRouterOutputs["user"]["get"]; @@ -93,6 +94,7 @@ type AuthQueryOutput = inferRouterOutputs["user"]["get"]; type SingleNavItem = { isSingle?: true; title: string; + titleKey: string; url: string; icon?: LucideIcon; isEnabled?: (opts: { @@ -110,6 +112,7 @@ type NavItem = | { isSingle: false; title: string; + titleKey: string; icon: LucideIcon; items: SingleNavItem[]; isEnabled?: (opts: { @@ -122,6 +125,7 @@ type NavItem = // Represents an external link item (used for the help section) type ExternalLink = { name: string; + nameKey: string; url: string; icon: React.ComponentType<{ className?: string }>; isEnabled?: (opts: { @@ -147,12 +151,14 @@ const MENU: Menu = { { isSingle: true, title: "Projects", + titleKey: "common.side.projects", url: "/dashboard/projects", icon: Folder, }, { isSingle: true, title: "Monitoring", + titleKey: "common.side.monitoring", url: "/dashboard/monitoring", icon: BarChartHorizontalBigIcon, // Only enabled in non-cloud environments @@ -161,6 +167,7 @@ const MENU: Menu = { { isSingle: true, title: "Traefik File System", + titleKey: "common.side.traefik", url: "/dashboard/traefik", icon: GalleryVerticalEnd, // Only enabled for admins and users with access to Traefik files in non-cloud environments @@ -173,6 +180,7 @@ const MENU: Menu = { { isSingle: true, title: "Docker", + titleKey: "common.side.docker", url: "/dashboard/docker", icon: BlocksIcon, // Only enabled for admins and users with access to Docker in non-cloud environments @@ -182,6 +190,7 @@ const MENU: Menu = { { isSingle: true, title: "Swarm", + titleKey: "common.side.swarm", url: "/dashboard/swarm", icon: PieChart, // Only enabled for admins and users with access to Docker in non-cloud environments @@ -191,6 +200,7 @@ const MENU: Menu = { { isSingle: true, title: "Requests", + titleKey: "common.side.requests", url: "/dashboard/requests", icon: Forward, // Only enabled for admins and users with access to Docker in non-cloud environments @@ -259,6 +269,7 @@ const MENU: Menu = { { isSingle: true, title: "Web Server", + titleKey: "common.side.web-server", url: "/dashboard/settings/server", icon: Activity, // Only enabled for admins in non-cloud environments @@ -267,12 +278,14 @@ const MENU: Menu = { { isSingle: true, title: "Profile", + titleKey: "common.side.profile", url: "/dashboard/settings/profile", icon: User, }, { isSingle: true, title: "Remote Servers", + titleKey: "common.side.remote-servers", url: "/dashboard/settings/servers", icon: Server, // Only enabled for admins @@ -281,6 +294,7 @@ const MENU: Menu = { { isSingle: true, title: "Users", + titleKey: "common.side.users", icon: Users, url: "/dashboard/settings/users", // Only enabled for admins @@ -289,6 +303,7 @@ const MENU: Menu = { { isSingle: true, title: "SSH Keys", + titleKey: "common.side.ssh-keys", icon: KeyRound, url: "/dashboard/settings/ssh-keys", // Only enabled for admins and users with access to SSH keys @@ -297,6 +312,7 @@ const MENU: Menu = { }, { title: "AI", + titleKey: "common.side.ai", icon: BotIcon, url: "/dashboard/settings/ai", isSingle: true, @@ -305,6 +321,7 @@ const MENU: Menu = { { isSingle: true, title: "Git", + titleKey: "common.side.git", url: "/dashboard/settings/git-providers", icon: GitBranch, // Only enabled for admins and users with access to Git providers @@ -314,6 +331,7 @@ const MENU: Menu = { { isSingle: true, title: "Registry", + titleKey: "common.side.registry", url: "/dashboard/settings/registry", icon: Package, // Only enabled for admins @@ -322,6 +340,7 @@ const MENU: Menu = { { isSingle: true, title: "S3 Destinations", + titleKey: "common.side.s3-destinations", url: "/dashboard/settings/destinations", icon: Database, // Only enabled for admins @@ -331,6 +350,7 @@ const MENU: Menu = { { isSingle: true, title: "Certificates", + titleKey: "common.side.certificates", url: "/dashboard/settings/certificates", icon: ShieldCheck, // Only enabled for admins @@ -339,6 +359,7 @@ const MENU: Menu = { { isSingle: true, title: "Cluster", + titleKey: "common.side.cluster", url: "/dashboard/settings/cluster", icon: Boxes, // Only enabled for admins in non-cloud environments @@ -347,6 +368,7 @@ const MENU: Menu = { { isSingle: true, title: "Notifications", + titleKey: "common.side.notifications", url: "/dashboard/settings/notifications", icon: Bell, // Only enabled for admins @@ -355,6 +377,7 @@ const MENU: Menu = { { isSingle: true, title: "Billing", + titleKey: "common.side.billing", url: "/dashboard/settings/billing", icon: CreditCard, // Only enabled for admins in cloud environments @@ -365,16 +388,19 @@ const MENU: Menu = { help: [ { name: "Documentation", + nameKey: "common.side.documentation", url: "https://docs.dokploy.com/docs/core", icon: BookIcon, }, { name: "Support", + nameKey: "common.side.support", url: "https://discord.gg/2tBnJ3jDJc", icon: CircleHelp, }, { name: "Sponsor", + nameKey: "common.side.sponsor", url: "https://opencollective.com/dokploy", icon: ({ className }) => ( - Pending Invitations + + {t("common.side.invitations.pending-invitations")} +
{invitations && invitations.length > 0 ? ( invitations.map((invitation) => ( @@ -702,16 +731,23 @@ function SidebarLogo() { {invitation?.organization?.name}
- Expires:{" "} - {new Date(invitation.expiresAt).toLocaleString()} + {t("common.side.invitations.expires", { + expireDate: new Date( + invitation.expiresAt, + ).toLocaleString(), + })}
- Role: {invitation.role} + {t("common.side.invitations.role", { + role: invitation.role, + })}
{ const { error } = @@ -721,24 +757,31 @@ function SidebarLogo() { if (error) { toast.error( - error.message || "Error accepting invitation", + error.message || + t( + "common.side.invitations.error-accepting-invitation", + ), ); } else { - toast.success("Invitation accepted successfully"); + toast.success( + t( + "common.side.invitations.invitation-accepted", + ), + ); await refetchInvitations(); await refetch(); } }} > )) ) : ( - No pending invitations + {t("common.side.invitations.no-pending-invitations")} )} @@ -752,6 +795,8 @@ function SidebarLogo() { } export default function Page({ children }: Props) { + const { t } = useTranslation("common"); + const [defaultOpen, setDefaultOpen] = useState( undefined, ); @@ -818,7 +863,7 @@ export default function Page({ children }: Props) { - Home + {t("common.side.home")} {filteredHome.map((item) => { const isSingle = item.isSingle !== false; @@ -851,7 +896,7 @@ export default function Page({ children }: Props) { className={cn(isActive && "text-primary")} /> )} - {item.title} + {t(item.titleKey)} ) : ( @@ -907,7 +952,7 @@ export default function Page({ children }: Props) { - Settings + {t("common.side.settings")} {filteredSettings.map((item) => { const isSingle = item.isSingle !== false; @@ -940,7 +985,7 @@ export default function Page({ children }: Props) { className={cn(isActive && "text-primary")} /> )} - {item.title} + {t(item.titleKey)} ) : ( @@ -996,7 +1041,7 @@ export default function Page({ children }: Props) { - Extra + {t("common.side.extra")} {help.map((item: ExternalLink) => ( @@ -1010,7 +1055,7 @@ export default function Page({ children }: Props) { - {item.name} + {t(item.nameKey)} diff --git a/apps/dokploy/pages/dashboard/settings/ai.tsx b/apps/dokploy/pages/dashboard/settings/ai.tsx index 92ca2fab..985df7dc 100644 --- a/apps/dokploy/pages/dashboard/settings/ai.tsx +++ b/apps/dokploy/pages/dashboard/settings/ai.tsx @@ -55,7 +55,7 @@ export async function getServerSideProps( return { props: { trpcState: helpers.dehydrate(), - ...(await serverSideTranslations(locale, ["settings"])), + ...(await serverSideTranslations(locale, ["common", "settings"])), }, }; } diff --git a/apps/dokploy/pages/dashboard/settings/billing.tsx b/apps/dokploy/pages/dashboard/settings/billing.tsx index 7ba5717e..2c176e23 100644 --- a/apps/dokploy/pages/dashboard/settings/billing.tsx +++ b/apps/dokploy/pages/dashboard/settings/billing.tsx @@ -2,6 +2,7 @@ import { ShowBilling } from "@/components/dashboard/settings/billing/show-billin import { DashboardLayout } from "@/components/layouts/dashboard-layout"; import { appRouter } from "@/server/api/root"; +import { getLocale, serverSideTranslations } from "@/utils/i18n"; import { IS_CLOUD } from "@dokploy/server/constants"; import { validateRequest } from "@dokploy/server/lib/auth"; import { createServerSideHelpers } from "@trpc/react-query/server"; @@ -30,6 +31,7 @@ export async function getServerSideProps( }; } const { req, res } = ctx; + const locale = getLocale(req.cookies); const { user, session } = await validateRequest(req); if (!user || user.role === "member") { return { @@ -59,6 +61,7 @@ export async function getServerSideProps( return { props: { trpcState: helpers.dehydrate(), + ...(await serverSideTranslations(locale, ["common", "settings"])), }, }; } diff --git a/apps/dokploy/pages/dashboard/settings/certificates.tsx b/apps/dokploy/pages/dashboard/settings/certificates.tsx index 0c82ed4f..2b2ca22d 100644 --- a/apps/dokploy/pages/dashboard/settings/certificates.tsx +++ b/apps/dokploy/pages/dashboard/settings/certificates.tsx @@ -2,6 +2,7 @@ import { ShowCertificates } from "@/components/dashboard/settings/certificates/s import { DashboardLayout } from "@/components/layouts/dashboard-layout"; import { appRouter } from "@/server/api/root"; +import { getLocale, serverSideTranslations } from "@/utils/i18n"; import { validateRequest } from "@dokploy/server"; import { createServerSideHelpers } from "@trpc/react-query/server"; import type { GetServerSidePropsContext } from "next"; @@ -24,6 +25,7 @@ export async function getServerSideProps( ctx: GetServerSidePropsContext<{ serviceId: string }>, ) { const { req, res } = ctx; + const locale = await getLocale(req.cookies); const { user, session } = await validateRequest(req); if (!user || user.role === "member") { return { @@ -51,6 +53,7 @@ export async function getServerSideProps( return { props: { trpcState: helpers.dehydrate(), + ...(await serverSideTranslations(locale, ["common", "settings"])), }, }; } diff --git a/apps/dokploy/pages/dashboard/settings/cluster.tsx b/apps/dokploy/pages/dashboard/settings/cluster.tsx index a1a46bb6..8ebc8b8f 100644 --- a/apps/dokploy/pages/dashboard/settings/cluster.tsx +++ b/apps/dokploy/pages/dashboard/settings/cluster.tsx @@ -2,6 +2,7 @@ import { ShowNodes } from "@/components/dashboard/settings/cluster/nodes/show-no import { DashboardLayout } from "@/components/layouts/dashboard-layout"; import { appRouter } from "@/server/api/root"; +import { getLocale, serverSideTranslations } from "@/utils/i18n"; import { IS_CLOUD, validateRequest } from "@dokploy/server"; import { createServerSideHelpers } from "@trpc/react-query/server"; import type { GetServerSidePropsContext } from "next"; @@ -25,6 +26,7 @@ export async function getServerSideProps( ctx: GetServerSidePropsContext<{ serviceId: string }>, ) { const { req, res } = ctx; + const locale = await getLocale(req.cookies); if (IS_CLOUD) { return { redirect: { @@ -58,6 +60,7 @@ export async function getServerSideProps( return { props: { trpcState: helpers.dehydrate(), + ...(await serverSideTranslations(locale, ["common", "settings"])), }, }; } diff --git a/apps/dokploy/pages/dashboard/settings/destinations.tsx b/apps/dokploy/pages/dashboard/settings/destinations.tsx index 3c906b55..72cced44 100644 --- a/apps/dokploy/pages/dashboard/settings/destinations.tsx +++ b/apps/dokploy/pages/dashboard/settings/destinations.tsx @@ -2,6 +2,7 @@ import { ShowDestinations } from "@/components/dashboard/settings/destination/sh import { DashboardLayout } from "@/components/layouts/dashboard-layout"; import { appRouter } from "@/server/api/root"; +import { getLocale, serverSideTranslations } from "@/utils/i18n"; import { validateRequest } from "@dokploy/server"; import { createServerSideHelpers } from "@trpc/react-query/server"; import type { GetServerSidePropsContext } from "next"; @@ -25,6 +26,7 @@ export async function getServerSideProps( ctx: GetServerSidePropsContext<{ serviceId: string }>, ) { const { req, res } = ctx; + const locale = await getLocale(req.cookies); const { user, session } = await validateRequest(req); if (!user || user.role === "member") { return { @@ -52,6 +54,7 @@ export async function getServerSideProps( return { props: { trpcState: helpers.dehydrate(), + ...(await serverSideTranslations(locale, ["common", "settings"])), }, }; } diff --git a/apps/dokploy/pages/dashboard/settings/git-providers.tsx b/apps/dokploy/pages/dashboard/settings/git-providers.tsx index 7a9b08df..82293180 100644 --- a/apps/dokploy/pages/dashboard/settings/git-providers.tsx +++ b/apps/dokploy/pages/dashboard/settings/git-providers.tsx @@ -2,6 +2,7 @@ import { ShowGitProviders } from "@/components/dashboard/settings/git/show-git-p import { DashboardLayout } from "@/components/layouts/dashboard-layout"; import { appRouter } from "@/server/api/root"; +import { getLocale, serverSideTranslations } from "@/utils/i18n"; import { validateRequest } from "@dokploy/server"; import { createServerSideHelpers } from "@trpc/react-query/server"; import type { GetServerSidePropsContext } from "next"; @@ -9,68 +10,72 @@ import type { ReactElement } from "react"; import superjson from "superjson"; const Page = () => { - return ( -
- -
- ); + return ( +
+ +
+ ); }; export default Page; Page.getLayout = (page: ReactElement) => { - return {page}; + return {page}; }; export async function getServerSideProps( - ctx: GetServerSidePropsContext<{ serviceId: string }>, + ctx: GetServerSidePropsContext<{ serviceId: string }> ) { - const { user, session } = await validateRequest(ctx.req); - if (!user) { - return { - redirect: { - permanent: true, - destination: "/", - }, - }; - } - const { req, res } = ctx; - const helpers = createServerSideHelpers({ - router: appRouter, - ctx: { - req: req as any, - res: res as any, - db: null as any, - session: session as any, - user: user as any, - }, - transformer: superjson, - }); - await helpers.user.get.prefetch(); - try { - await helpers.project.all.prefetch(); - await helpers.settings.isCloud.prefetch(); - if (user.role === "member") { - const userR = await helpers.user.one.fetch({ - userId: user.id, - }); + const { user, session } = await validateRequest(ctx.req); + if (!user) { + return { + redirect: { + permanent: true, + destination: "/", + }, + }; + } + const { req, res } = ctx; + const locale = await getLocale(req.cookies); + const helpers = createServerSideHelpers({ + router: appRouter, + ctx: { + req: req as any, + res: res as any, + db: null as any, + session: session as any, + user: user as any, + }, + transformer: superjson, + }); + await helpers.user.get.prefetch(); + try { + await helpers.project.all.prefetch(); + await helpers.settings.isCloud.prefetch(); + if (user.role === "member") { + const userR = await helpers.user.one.fetch({ + userId: user.id, + }); - if (!userR?.canAccessToGitProviders) { - return { - redirect: { - permanent: true, - destination: "/", - }, - }; - } - } - return { - props: { - trpcState: helpers.dehydrate(), - }, - }; - } catch (_error) { - return { - props: {}, - }; - } + if (!userR?.canAccessToGitProviders) { + return { + redirect: { + permanent: true, + destination: "/", + }, + }; + } + } + return { + props: { + trpcState: helpers.dehydrate(), + ...(await serverSideTranslations(locale, ["common", "settings"])), + }, + }; + } catch (_error) { + return { + props: { + ...(await serverSideTranslations(locale, ["common", "settings"])), + }, + }; + } } diff --git a/apps/dokploy/pages/dashboard/settings/index.tsx b/apps/dokploy/pages/dashboard/settings/index.tsx index 4c060cbb..5f9bf3df 100644 --- a/apps/dokploy/pages/dashboard/settings/index.tsx +++ b/apps/dokploy/pages/dashboard/settings/index.tsx @@ -21,6 +21,7 @@ import { import { Switch } from "@/components/ui/switch"; import { appRouter } from "@/server/api/root"; import { api } from "@/utils/api"; +import { getLocale, serverSideTranslations } from "@/utils/i18n"; import { validateRequest } from "@dokploy/server"; import { zodResolver } from "@hookform/resolvers/zod"; import { createServerSideHelpers } from "@trpc/react-query/server"; @@ -180,6 +181,7 @@ export async function getServerSideProps( ctx: GetServerSidePropsContext<{ serviceId: string }>, ) { const { req, res } = ctx; + const locale = await getLocale(req.cookies); const { user, session } = await validateRequest(ctx.req); if (!user) { return { @@ -214,6 +216,7 @@ export async function getServerSideProps( return { props: { trpcState: helpers.dehydrate(), + ...(await serverSideTranslations(locale, ["common", "settings"])), }, }; } diff --git a/apps/dokploy/pages/dashboard/settings/notifications.tsx b/apps/dokploy/pages/dashboard/settings/notifications.tsx index fbdc2e20..e595279c 100644 --- a/apps/dokploy/pages/dashboard/settings/notifications.tsx +++ b/apps/dokploy/pages/dashboard/settings/notifications.tsx @@ -2,6 +2,7 @@ import { ShowNotifications } from "@/components/dashboard/settings/notifications import { DashboardLayout } from "@/components/layouts/dashboard-layout"; import { appRouter } from "@/server/api/root"; +import { getLocale, serverSideTranslations } from "@/utils/i18n"; import { validateRequest } from "@dokploy/server"; import { createServerSideHelpers } from "@trpc/react-query/server"; import type { GetServerSidePropsContext } from "next"; @@ -25,6 +26,7 @@ export async function getServerSideProps( ctx: GetServerSidePropsContext<{ serviceId: string }>, ) { const { req, res } = ctx; + const locale = await getLocale(req.cookies); const { user, session } = await validateRequest(req); if (!user || user.role === "member") { return { @@ -52,6 +54,7 @@ export async function getServerSideProps( return { props: { trpcState: helpers.dehydrate(), + ...(await serverSideTranslations(locale, ["common", "settings"])), }, }; } diff --git a/apps/dokploy/pages/dashboard/settings/profile.tsx b/apps/dokploy/pages/dashboard/settings/profile.tsx index 83ff5624..db2e2782 100644 --- a/apps/dokploy/pages/dashboard/settings/profile.tsx +++ b/apps/dokploy/pages/dashboard/settings/profile.tsx @@ -66,7 +66,7 @@ export async function getServerSideProps( return { props: { trpcState: helpers.dehydrate(), - ...(await serverSideTranslations(locale, ["settings"])), + ...(await serverSideTranslations(locale, ["common", "settings"])), }, }; } diff --git a/apps/dokploy/pages/dashboard/settings/registry.tsx b/apps/dokploy/pages/dashboard/settings/registry.tsx index 42f0627f..17010a0c 100644 --- a/apps/dokploy/pages/dashboard/settings/registry.tsx +++ b/apps/dokploy/pages/dashboard/settings/registry.tsx @@ -2,6 +2,7 @@ import { ShowRegistry } from "@/components/dashboard/settings/cluster/registry/s import { DashboardLayout } from "@/components/layouts/dashboard-layout"; import { appRouter } from "@/server/api/root"; +import { serverSideTranslations, getLocale } from "@/utils/i18n"; import { validateRequest } from "@dokploy/server"; import { createServerSideHelpers } from "@trpc/react-query/server"; import type { GetServerSidePropsContext } from "next"; @@ -25,6 +26,7 @@ export async function getServerSideProps( ctx: GetServerSidePropsContext<{ serviceId: string }>, ) { const { req, res } = ctx; + const locale = await getLocale(req.cookies); const { user, session } = await validateRequest(req); if (!user || user.role === "member") { return { @@ -51,6 +53,7 @@ export async function getServerSideProps( return { props: { trpcState: helpers.dehydrate(), + ...(await serverSideTranslations(locale, ["common", "settings"])), }, }; } diff --git a/apps/dokploy/pages/dashboard/settings/server.tsx b/apps/dokploy/pages/dashboard/settings/server.tsx index 0c5e36dc..62430eec 100644 --- a/apps/dokploy/pages/dashboard/settings/server.tsx +++ b/apps/dokploy/pages/dashboard/settings/server.tsx @@ -115,7 +115,7 @@ export async function getServerSideProps( return { props: { trpcState: helpers.dehydrate(), - ...(await serverSideTranslations(locale, ["settings"])), + ...(await serverSideTranslations(locale, ["common", "settings"])), }, }; } diff --git a/apps/dokploy/pages/dashboard/settings/servers.tsx b/apps/dokploy/pages/dashboard/settings/servers.tsx index 5cc30b83..2192749a 100644 --- a/apps/dokploy/pages/dashboard/settings/servers.tsx +++ b/apps/dokploy/pages/dashboard/settings/servers.tsx @@ -62,7 +62,7 @@ export async function getServerSideProps( return { props: { trpcState: helpers.dehydrate(), - ...(await serverSideTranslations(locale, ["settings"])), + ...(await serverSideTranslations(locale, ["common", "settings"])), }, }; } diff --git a/apps/dokploy/pages/dashboard/settings/ssh-keys.tsx b/apps/dokploy/pages/dashboard/settings/ssh-keys.tsx index 2472feab..9d746eb3 100644 --- a/apps/dokploy/pages/dashboard/settings/ssh-keys.tsx +++ b/apps/dokploy/pages/dashboard/settings/ssh-keys.tsx @@ -2,6 +2,7 @@ import { ShowDestinations } from "@/components/dashboard/settings/ssh-keys/show- import { DashboardLayout } from "@/components/layouts/dashboard-layout"; import { appRouter } from "@/server/api/root"; +import { getLocale, serverSideTranslations } from "@/utils/i18n"; import { validateRequest } from "@dokploy/server"; import { createServerSideHelpers } from "@trpc/react-query/server"; import type { GetServerSidePropsContext } from "next"; @@ -34,6 +35,7 @@ export async function getServerSideProps( }; } const { req, res } = ctx; + const locale = await getLocale(req.cookies); const helpers = createServerSideHelpers({ router: appRouter, ctx: { @@ -67,11 +69,14 @@ export async function getServerSideProps( return { props: { trpcState: helpers.dehydrate(), + ...(await serverSideTranslations(locale, ["common", "settings"])), }, }; } catch (_error) { return { - props: {}, + props: { + ...(await serverSideTranslations(locale, ["common", "settings"])), + }, }; } } diff --git a/apps/dokploy/pages/dashboard/settings/users.tsx b/apps/dokploy/pages/dashboard/settings/users.tsx index 16f90abb..3c32a029 100644 --- a/apps/dokploy/pages/dashboard/settings/users.tsx +++ b/apps/dokploy/pages/dashboard/settings/users.tsx @@ -3,6 +3,7 @@ import { ShowUsers } from "@/components/dashboard/settings/users/show-users"; import { DashboardLayout } from "@/components/layouts/dashboard-layout"; import { appRouter } from "@/server/api/root"; +import { getLocale, serverSideTranslations } from "@/utils/i18n"; import { validateRequest } from "@dokploy/server"; import { createServerSideHelpers } from "@trpc/react-query/server"; import type { GetServerSidePropsContext } from "next"; @@ -27,6 +28,7 @@ export async function getServerSideProps( ctx: GetServerSidePropsContext<{ serviceId: string }>, ) { const { req, res } = ctx; + const locale = await getLocale(req.cookies); const { user, session } = await validateRequest(req); if (!user || user.role === "member") { @@ -55,6 +57,7 @@ export async function getServerSideProps( return { props: { trpcState: helpers.dehydrate(), + ...(await serverSideTranslations(locale, ["common", "settings"])), }, }; } diff --git a/apps/dokploy/public/locales/en/common.json b/apps/dokploy/public/locales/en/common.json index 0967ef42..ab7f2718 100644 --- a/apps/dokploy/public/locales/en/common.json +++ b/apps/dokploy/public/locales/en/common.json @@ -1 +1,37 @@ -{} +{ + "common.side.home": "Home", + "common.side.settings": "Settings", + "common.side.extra": "Extra", + + "common.side.projects": "Projects", + "common.side.monitoring": "Monitoring", + "common.side.traefik": "Traefik File System", + "common.side.docker": "Docker", + "common.side.swarm": "Swarm", + "common.side.requests": "Requests", + "common.side.web-server": "Web Server", + "common.side.profile": "Profile", + "common.side.remote-servers": "Remote Servers", + "common.side.users": "Users", + "common.side.ssh-keys": "SSH Keys", + "common.side.ai": "AI", + "common.side.git": "Git", + "common.side.registry": "Registry", + "common.side.s3-destinations": "S3 Destinations", + "common.side.certificates": "Certificates", + "common.side.cluster": "Cluster", + "common.side.notifications": "Notifications", + "common.side.billing": "Billing", + "common.side.documentation": "Documentation", + "common.side.support": "Support", + "common.side.sponsor": "Sponsor", + + "common.side.invitations.pending-invitations": "Pending Invitations", + "common.side.invitations.no-pending-invitations": "No pending invitations", + "common.side.invitations.accept-invitation": "Accept Invitation", + "common.side.invitations.confirm-accept-invitation": "Are you sure you want to accept this invitation?", + "common.side.invitations.error-accepting-invitation": "Error accepting invitation", + "common.side.invitations.invitation-accepted": "Invitation accepted successfully", + "common.side.invitations.expires": "Expires: {{expireDate}}", + "common.side.invitations.role": "Role: {{role}}" +} diff --git a/apps/dokploy/public/locales/zh-Hans/common.json b/apps/dokploy/public/locales/zh-Hans/common.json index 0967ef42..bc0605d7 100644 --- a/apps/dokploy/public/locales/zh-Hans/common.json +++ b/apps/dokploy/public/locales/zh-Hans/common.json @@ -1 +1,37 @@ -{} +{ + "common.side.home": "主页", + "common.side.settings": "设置", + "common.side.extra": "其他", + + "common.side.projects": "项目", + "common.side.monitoring": "监控", + "common.side.traefik": "Traefik", + "common.side.docker": "Docker", + "common.side.swarm": "Swarm", + "common.side.requests": "请求", + "common.side.web-server": "本地配置", + "common.side.profile": "个人资料", + "common.side.remote-servers": "远程服务器", + "common.side.users": "用户", + "common.side.ssh-keys": "SSH 密钥", + "common.side.ai": "AI", + "common.side.git": "Git 集成", + "common.side.registry": "注册表", + "common.side.s3-destinations": "S3 存储", + "common.side.certificates": "证书", + "common.side.cluster": "集群", + "common.side.notifications": "通知", + "common.side.billing": "账单", + "common.side.documentation": "文档", + "common.side.support": "支持", + "common.side.sponsor": "赞助", + + "common.side.invitations.pending-invitations": "待处理邀请", + "common.side.invitations.no-pending-invitations": "没有待处理的邀请", + "common.side.invitations.accept-invitation": "接受邀请", + "common.side.invitations.confirm-accept-invitation": "您确定要接受此邀请吗?", + "common.side.invitations.error-accepting-invitation": "接受邀请时出错", + "common.side.invitations.invitation-accepted": "邀请已成功接受", + "common.side.invitations.expires": "有效期:{{expireDate}}", + "common.side.invitations.role": "角色:{{role}}" +}