diff --git a/frontend/components/basic/layout.js b/frontend/components/basic/layout.js
index 28557d853..366368d9a 100644
--- a/frontend/components/basic/layout.js
+++ b/frontend/components/basic/layout.js
@@ -24,6 +24,8 @@ import { faPlus } from "@fortawesome/free-solid-svg-icons";
import { decryptAssymmetric, encryptAssymmetric } from "../utilities/crypto";
import Button from "./buttons/Button";
+import useTranslation from "next-translate/useTranslation";
+
export default function Layout({ children }) {
const router = useRouter();
const [workspaceList, setWorkspaceList] = useState([]);
@@ -34,6 +36,8 @@ export default function Layout({ children }) {
const [loading, setLoading] = useState(false);
const [error, setError] = useState(false);
+ const { t } = useTranslation();
+
function closeModal() {
setIsOpen(false);
}
@@ -48,9 +52,7 @@ export default function Layout({ children }) {
setLoading(true);
setTimeout(() => setLoading(false), 1500);
const workspaces = await getWorkspaces();
- const currentWorkspaces = workspaces.map(
- (workspace) => workspace.name
- );
+ const currentWorkspaces = workspaces.map((workspace) => workspace.name);
if (!currentWorkspaces.includes(workspaceName)) {
const newWorkspace = await createWorkspace(
workspaceName,
@@ -104,7 +106,7 @@ export default function Layout({ children }) {
setIsOpen(false);
setNewWorkspaceName("");
} else {
- setError("A project with this name already exists.");
+ setError(t("common:error_project-already-exists"));
setLoading(false);
}
}
@@ -119,29 +121,32 @@ export default function Layout({ children }) {
"/dashboard/" +
workspaceMapping[workspaceSelected] +
"?Development",
- title: "Secrets",
+ title: t("common:nav.menu.secrets"),
emoji: ,
},
{
href: "/users/" + workspaceMapping[workspaceSelected],
- title: "Members",
+ title: t("common:nav.menu.members"),
emoji: ,
},
{
href: "/integrations/" + workspaceMapping[workspaceSelected],
- title: "Integrations",
+ title: t("common:nav.menu.integrations"),
emoji: ,
},
{
href: "/settings/project/" + workspaceMapping[workspaceSelected],
- title: "Project Settings",
+ title: t("common:nav.menu.project-settings"),
emoji: ,
},
];
useEffect(async () => {
// Put a user in a workspace if they're not in one yet
- if (localStorage.getItem("orgData.id") == null || localStorage.getItem("orgData.id") == "") {
+ if (
+ localStorage.getItem("orgData.id") == null ||
+ localStorage.getItem("orgData.id") == ""
+ ) {
const userOrgs = await getOrganizations();
localStorage.setItem("orgData.id", userOrgs[0]._id);
}
@@ -150,7 +155,11 @@ export default function Layout({ children }) {
orgId: localStorage.getItem("orgData.id"),
});
let userWorkspaces = orgUserProjects;
- if (userWorkspaces.length == 0 && (router.asPath != "/noprojects" && !router.asPath.includes("settings"))) {
+ if (
+ userWorkspaces.length == 0 &&
+ router.asPath != "/noprojects" &&
+ !router.asPath.includes("settings")
+ ) {
router.push("/noprojects");
} else if (router.asPath != "/noprojects") {
const intendedWorkspaceId = router.asPath
@@ -158,7 +167,9 @@ export default function Layout({ children }) {
[router.asPath.split("/").length - 1].split("?")[0];
// If a user is not a member of a workspace they are trying to access, just push them to one of theirs
- if (intendedWorkspaceId != "heroku" && !userWorkspaces
+ if (
+ intendedWorkspaceId != "heroku" &&
+ !userWorkspaces
.map((workspace) => workspace._id)
.includes(intendedWorkspaceId)
) {
@@ -207,7 +218,10 @@ export default function Layout({ children }) {
workspaceMapping[workspaceSelected] +
"?Development"
);
- localStorage.setItem("projectData.id", workspaceMapping[workspaceSelected])
+ localStorage.setItem(
+ "projectData.id",
+ workspaceMapping[workspaceSelected]
+ );
}
} catch (error) {
console.log(error);
@@ -224,10 +238,10 @@ export default function Layout({ children }) {
- PROJECT
+ {t("common:nav.menu.project")}
- {workspaceList.length>0
- ?
0 ? (
+
- :
- }
+ )}
- {workspaceList.length > 0 && menuItems.map(({ href, title, emoji }) => (
- -
- {router.asPath.split("/")[1] ===
- href.split("/")[1] &&
- (["project", "billing", "org", "personal"].includes(
- router.asPath.split("/")[2]
- )
- ? router.asPath.split("/")[2] ===
- href.split("/")[2]
- : true) ? (
-
-
-
- {emoji}
-
- {title}
-
- ) : router.asPath == "/noprojects" ? (
-
-
- {emoji}
-
- {title}
-
- ) : (
-
+ {workspaceList.length > 0 &&
+ menuItems.map(({ href, title, emoji }) => (
+ -
+ {router.asPath.split("/")[1] ===
+ href.split("/")[1] &&
+ ([
+ "project",
+ "billing",
+ "org",
+ "personal",
+ ].includes(
+ router.asPath.split("/")[2]
+ )
+ ? router.asPath.split(
+ "/"
+ )[2] === href.split("/")[2]
+ : true) ? (
+
+
+ {emoji}
+
+ {title}
+
+ ) : router.asPath ==
+ "/noprojects" ? (
+
-
- )}
-
- ))}
+ ) : (
+
+
+
+ {emoji}
+
+ {title}
+
+
+ )}
+
+ ))}
@@ -308,9 +331,7 @@ export default function Layout({ children }) {
className="text-gray-300 text-7xl mb-8"
/>
- {" "}
- To use Infisical, please log in through a device with larger
- dimensions.{" "}
+ {` ${t("common:need-login")} `}
>
diff --git a/frontend/components/navigation/NavBarDashboard.js b/frontend/components/navigation/NavBarDashboard.js
index e73a61268..d4429b00e 100644
--- a/frontend/components/navigation/NavBarDashboard.js
+++ b/frontend/components/navigation/NavBarDashboard.js
@@ -1,4 +1,4 @@
-import React, { useState, Fragment, useEffect } from "react";
+import React, { useState, Fragment, useEffect, useMemo } from "react";
import { useRouter } from "next/router";
import Image from "next/image";
@@ -12,8 +12,8 @@ import {
faCoins,
faRightFromBracket,
faEnvelope,
- faPlus,
- faAngleDown
+ faPlus,
+ faAngleDown,
} from "@fortawesome/free-solid-svg-icons";
import { faSlack, faGithub } from "@fortawesome/free-brands-svg-icons";
import { Menu, Transition } from "@headlessui/react";
@@ -21,26 +21,30 @@ import getUser from "../../pages/api/user/getUser";
import getOrganizations from "../../pages/api/organization/getOrgs";
import getOrganization from "../../pages/api/organization/GetOrg";
import guidGenerator from "../utilities/randomId";
+import useTranslation from "next-translate/useTranslation";
-const supportOptions = [
+/**
+ * @param {(key: string) => string} t
+ */
+const supportOptions = (t) => [
[
,
- "[NEW] Join Slack Forum",
+ t("common:nav.support.slack"),
"https://join.slack.com/t/infisical/shared_invite/zt-1dgg63ln8-G7PCNJdCymAT9YF3j1ewVA",
],
[
,
- "Read Docs",
+ t("common:nav.support.docs"),
"https://infisical.com/docs/getting-started/introduction",
],
[
,
- "Open a GitHub Issue",
+ t("common:nav.support.issue"),
"https://github.com/Infisical/infisical-cli/issues",
],
[
,
- "Send us an Email",
+ t("common:nav.support.email"),
"mailto:support@infisical.com",
],
];
@@ -51,6 +55,10 @@ export default function Navbar({ onButtonPressed }) {
const [orgs, setOrgs] = useState([]);
const [currentOrg, setCurrentOrg] = useState([]);
+ const { t } = useTranslation("common");
+
+ const supportOptionsList = useMemo(() => supportOptions(t), [t]);
+
useEffect(async () => {
const userData = await getUser();
setUser(userData);
@@ -87,7 +95,7 @@ export default function Navbar({ onButtonPressed }) {