mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-05 12:26:38 +00:00
translate(frontend): navbar
This commit is contained in:
@@ -24,6 +24,8 @@ import { faPlus } from "@fortawesome/free-solid-svg-icons";
|
|||||||
import { decryptAssymmetric, encryptAssymmetric } from "../utilities/crypto";
|
import { decryptAssymmetric, encryptAssymmetric } from "../utilities/crypto";
|
||||||
import Button from "./buttons/Button";
|
import Button from "./buttons/Button";
|
||||||
|
|
||||||
|
import useTranslation from "next-translate/useTranslation";
|
||||||
|
|
||||||
export default function Layout({ children }) {
|
export default function Layout({ children }) {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const [workspaceList, setWorkspaceList] = useState([]);
|
const [workspaceList, setWorkspaceList] = useState([]);
|
||||||
@@ -34,6 +36,8 @@ export default function Layout({ children }) {
|
|||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
const [error, setError] = useState(false);
|
const [error, setError] = useState(false);
|
||||||
|
|
||||||
|
const { t } = useTranslation();
|
||||||
|
|
||||||
function closeModal() {
|
function closeModal() {
|
||||||
setIsOpen(false);
|
setIsOpen(false);
|
||||||
}
|
}
|
||||||
@@ -48,9 +52,7 @@ export default function Layout({ children }) {
|
|||||||
setLoading(true);
|
setLoading(true);
|
||||||
setTimeout(() => setLoading(false), 1500);
|
setTimeout(() => setLoading(false), 1500);
|
||||||
const workspaces = await getWorkspaces();
|
const workspaces = await getWorkspaces();
|
||||||
const currentWorkspaces = workspaces.map(
|
const currentWorkspaces = workspaces.map((workspace) => workspace.name);
|
||||||
(workspace) => workspace.name
|
|
||||||
);
|
|
||||||
if (!currentWorkspaces.includes(workspaceName)) {
|
if (!currentWorkspaces.includes(workspaceName)) {
|
||||||
const newWorkspace = await createWorkspace(
|
const newWorkspace = await createWorkspace(
|
||||||
workspaceName,
|
workspaceName,
|
||||||
@@ -104,7 +106,7 @@ export default function Layout({ children }) {
|
|||||||
setIsOpen(false);
|
setIsOpen(false);
|
||||||
setNewWorkspaceName("");
|
setNewWorkspaceName("");
|
||||||
} else {
|
} else {
|
||||||
setError("A project with this name already exists.");
|
setError(t("common:error_project-already-exists"));
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -119,29 +121,32 @@ export default function Layout({ children }) {
|
|||||||
"/dashboard/" +
|
"/dashboard/" +
|
||||||
workspaceMapping[workspaceSelected] +
|
workspaceMapping[workspaceSelected] +
|
||||||
"?Development",
|
"?Development",
|
||||||
title: "Secrets",
|
title: t("common:nav.menu.secrets"),
|
||||||
emoji: <FontAwesomeIcon icon={faHouse} />,
|
emoji: <FontAwesomeIcon icon={faHouse} />,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
href: "/users/" + workspaceMapping[workspaceSelected],
|
href: "/users/" + workspaceMapping[workspaceSelected],
|
||||||
title: "Members",
|
title: t("common:nav.menu.members"),
|
||||||
emoji: <FontAwesomeIcon icon={faUser} />,
|
emoji: <FontAwesomeIcon icon={faUser} />,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
href: "/integrations/" + workspaceMapping[workspaceSelected],
|
href: "/integrations/" + workspaceMapping[workspaceSelected],
|
||||||
title: "Integrations",
|
title: t("common:nav.menu.integrations"),
|
||||||
emoji: <FontAwesomeIcon icon={faLink} />,
|
emoji: <FontAwesomeIcon icon={faLink} />,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
href: "/settings/project/" + workspaceMapping[workspaceSelected],
|
href: "/settings/project/" + workspaceMapping[workspaceSelected],
|
||||||
title: "Project Settings",
|
title: t("common:nav.menu.project-settings"),
|
||||||
emoji: <FontAwesomeIcon icon={faGear} />,
|
emoji: <FontAwesomeIcon icon={faGear} />,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
useEffect(async () => {
|
useEffect(async () => {
|
||||||
// Put a user in a workspace if they're not in one yet
|
// 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();
|
const userOrgs = await getOrganizations();
|
||||||
localStorage.setItem("orgData.id", userOrgs[0]._id);
|
localStorage.setItem("orgData.id", userOrgs[0]._id);
|
||||||
}
|
}
|
||||||
@@ -150,7 +155,11 @@ export default function Layout({ children }) {
|
|||||||
orgId: localStorage.getItem("orgData.id"),
|
orgId: localStorage.getItem("orgData.id"),
|
||||||
});
|
});
|
||||||
let userWorkspaces = orgUserProjects;
|
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");
|
router.push("/noprojects");
|
||||||
} else if (router.asPath != "/noprojects") {
|
} else if (router.asPath != "/noprojects") {
|
||||||
const intendedWorkspaceId = router.asPath
|
const intendedWorkspaceId = router.asPath
|
||||||
@@ -158,7 +167,9 @@ export default function Layout({ children }) {
|
|||||||
[router.asPath.split("/").length - 1].split("?")[0];
|
[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 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)
|
.map((workspace) => workspace._id)
|
||||||
.includes(intendedWorkspaceId)
|
.includes(intendedWorkspaceId)
|
||||||
) {
|
) {
|
||||||
@@ -207,7 +218,10 @@ export default function Layout({ children }) {
|
|||||||
workspaceMapping[workspaceSelected] +
|
workspaceMapping[workspaceSelected] +
|
||||||
"?Development"
|
"?Development"
|
||||||
);
|
);
|
||||||
localStorage.setItem("projectData.id", workspaceMapping[workspaceSelected])
|
localStorage.setItem(
|
||||||
|
"projectData.id",
|
||||||
|
workspaceMapping[workspaceSelected]
|
||||||
|
);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
@@ -224,10 +238,10 @@ export default function Layout({ children }) {
|
|||||||
<div className="py-6"></div>
|
<div className="py-6"></div>
|
||||||
<div className="flex justify-center w-full mt-7 mb-8 bg-bunker-600 w-full h-full flex flex-col items-center px-4">
|
<div className="flex justify-center w-full mt-7 mb-8 bg-bunker-600 w-full h-full flex flex-col items-center px-4">
|
||||||
<div className="text-gray-400 self-start ml-1 mb-1 text-xs font-semibold tracking-wide">
|
<div className="text-gray-400 self-start ml-1 mb-1 text-xs font-semibold tracking-wide">
|
||||||
PROJECT
|
{t("common:nav.menu.project")}
|
||||||
</div>
|
</div>
|
||||||
{workspaceList.length>0
|
{workspaceList.length > 0 ? (
|
||||||
? <Listbox
|
<Listbox
|
||||||
selected={workspaceSelected}
|
selected={workspaceSelected}
|
||||||
onChange={setWorkspaceSelected}
|
onChange={setWorkspaceSelected}
|
||||||
data={workspaceList}
|
data={workspaceList}
|
||||||
@@ -235,58 +249,67 @@ export default function Layout({ children }) {
|
|||||||
text=""
|
text=""
|
||||||
workspaceMapping={workspaceMapping}
|
workspaceMapping={workspaceMapping}
|
||||||
/>
|
/>
|
||||||
: <Button
|
) : (
|
||||||
|
<Button
|
||||||
text="Add Project"
|
text="Add Project"
|
||||||
onButtonPressed={openModal}
|
onButtonPressed={openModal}
|
||||||
color="mineshaft"
|
color="mineshaft"
|
||||||
size="md"
|
size="md"
|
||||||
icon={faPlus}
|
icon={faPlus}
|
||||||
/>
|
/>
|
||||||
}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<ul>
|
<ul>
|
||||||
{workspaceList.length > 0 && menuItems.map(({ href, title, emoji }) => (
|
{workspaceList.length > 0 &&
|
||||||
<li className="mt-1.5 mx-2" key={title}>
|
menuItems.map(({ href, title, emoji }) => (
|
||||||
{router.asPath.split("/")[1] ===
|
<li className="mt-1.5 mx-2" key={title}>
|
||||||
href.split("/")[1] &&
|
{router.asPath.split("/")[1] ===
|
||||||
(["project", "billing", "org", "personal"].includes(
|
href.split("/")[1] &&
|
||||||
router.asPath.split("/")[2]
|
([
|
||||||
)
|
"project",
|
||||||
? router.asPath.split("/")[2] ===
|
"billing",
|
||||||
href.split("/")[2]
|
"org",
|
||||||
: true) ? (
|
"personal",
|
||||||
<div
|
].includes(
|
||||||
className={`flex p-2 text-white text-sm rounded cursor-pointer bg-mineshaft-50/10`}
|
router.asPath.split("/")[2]
|
||||||
>
|
)
|
||||||
<div className="bg-primary w-1 rounded-xl mr-1"></div>
|
? router.asPath.split(
|
||||||
<p className="ml-2 mr-4">
|
"/"
|
||||||
{emoji}
|
)[2] === href.split("/")[2]
|
||||||
</p>
|
: true) ? (
|
||||||
{title}
|
|
||||||
</div>
|
|
||||||
) : router.asPath == "/noprojects" ? (
|
|
||||||
<div
|
|
||||||
className={`flex p-2 text-white text-sm rounded`}
|
|
||||||
>
|
|
||||||
<p className="ml-2 mr-4">
|
|
||||||
{emoji}
|
|
||||||
</p>
|
|
||||||
{title}
|
|
||||||
</div>
|
|
||||||
) : (
|
|
||||||
<Link href={href}>
|
|
||||||
<div
|
<div
|
||||||
className={`flex p-2 text-white text-sm rounded cursor-pointer hover:bg-mineshaft-50/5`}
|
className={`flex p-2 text-white text-sm rounded cursor-pointer bg-mineshaft-50/10`}
|
||||||
|
>
|
||||||
|
<div className="bg-primary w-1 rounded-xl mr-1"></div>
|
||||||
|
<p className="ml-2 mr-4">
|
||||||
|
{emoji}
|
||||||
|
</p>
|
||||||
|
{title}
|
||||||
|
</div>
|
||||||
|
) : router.asPath ==
|
||||||
|
"/noprojects" ? (
|
||||||
|
<div
|
||||||
|
className={`flex p-2 text-white text-sm rounded`}
|
||||||
>
|
>
|
||||||
<p className="ml-2 mr-4">
|
<p className="ml-2 mr-4">
|
||||||
{emoji}
|
{emoji}
|
||||||
</p>
|
</p>
|
||||||
{title}
|
{title}
|
||||||
</div>
|
</div>
|
||||||
</Link>
|
) : (
|
||||||
)}
|
<Link href={href}>
|
||||||
</li>
|
<div
|
||||||
))}
|
className={`flex p-2 text-white text-sm rounded cursor-pointer hover:bg-mineshaft-50/5`}
|
||||||
|
>
|
||||||
|
<p className="ml-2 mr-4">
|
||||||
|
{emoji}
|
||||||
|
</p>
|
||||||
|
{title}
|
||||||
|
</div>
|
||||||
|
</Link>
|
||||||
|
)}
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
</ul>
|
</ul>
|
||||||
</nav>
|
</nav>
|
||||||
</aside>
|
</aside>
|
||||||
@@ -308,9 +331,7 @@ export default function Layout({ children }) {
|
|||||||
className="text-gray-300 text-7xl mb-8"
|
className="text-gray-300 text-7xl mb-8"
|
||||||
/>
|
/>
|
||||||
<p className="text-gray-200 px-6 text-center text-lg max-w-sm">
|
<p className="text-gray-200 px-6 text-center text-lg max-w-sm">
|
||||||
{" "}
|
{` ${t("common:need-login")} `}
|
||||||
To use Infisical, please log in through a device with larger
|
|
||||||
dimensions.{" "}
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -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 { useRouter } from "next/router";
|
||||||
|
|
||||||
import Image from "next/image";
|
import Image from "next/image";
|
||||||
@@ -12,8 +12,8 @@ import {
|
|||||||
faCoins,
|
faCoins,
|
||||||
faRightFromBracket,
|
faRightFromBracket,
|
||||||
faEnvelope,
|
faEnvelope,
|
||||||
faPlus,
|
faPlus,
|
||||||
faAngleDown
|
faAngleDown,
|
||||||
} from "@fortawesome/free-solid-svg-icons";
|
} from "@fortawesome/free-solid-svg-icons";
|
||||||
import { faSlack, faGithub } from "@fortawesome/free-brands-svg-icons";
|
import { faSlack, faGithub } from "@fortawesome/free-brands-svg-icons";
|
||||||
import { Menu, Transition } from "@headlessui/react";
|
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 getOrganizations from "../../pages/api/organization/getOrgs";
|
||||||
import getOrganization from "../../pages/api/organization/GetOrg";
|
import getOrganization from "../../pages/api/organization/GetOrg";
|
||||||
import guidGenerator from "../utilities/randomId";
|
import guidGenerator from "../utilities/randomId";
|
||||||
|
import useTranslation from "next-translate/useTranslation";
|
||||||
|
|
||||||
const supportOptions = [
|
/**
|
||||||
|
* @param {(key: string) => string} t
|
||||||
|
*/
|
||||||
|
const supportOptions = (t) => [
|
||||||
[
|
[
|
||||||
<FontAwesomeIcon className="text-lg pl-1.5 pr-3" icon={faSlack} />,
|
<FontAwesomeIcon className="text-lg pl-1.5 pr-3" icon={faSlack} />,
|
||||||
"[NEW] Join Slack Forum",
|
t("common:nav.support.slack"),
|
||||||
"https://join.slack.com/t/infisical/shared_invite/zt-1dgg63ln8-G7PCNJdCymAT9YF3j1ewVA",
|
"https://join.slack.com/t/infisical/shared_invite/zt-1dgg63ln8-G7PCNJdCymAT9YF3j1ewVA",
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
<FontAwesomeIcon className="text-lg pl-1.5 pr-3" icon={faBook} />,
|
<FontAwesomeIcon className="text-lg pl-1.5 pr-3" icon={faBook} />,
|
||||||
"Read Docs",
|
t("common:nav.support.docs"),
|
||||||
"https://infisical.com/docs/getting-started/introduction",
|
"https://infisical.com/docs/getting-started/introduction",
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
<FontAwesomeIcon className="text-lg pl-1.5 pr-3" icon={faGithub} />,
|
<FontAwesomeIcon className="text-lg pl-1.5 pr-3" icon={faGithub} />,
|
||||||
"Open a GitHub Issue",
|
t("common:nav.support.issue"),
|
||||||
"https://github.com/Infisical/infisical-cli/issues",
|
"https://github.com/Infisical/infisical-cli/issues",
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
<FontAwesomeIcon className="text-lg pl-1.5 pr-3" icon={faEnvelope} />,
|
<FontAwesomeIcon className="text-lg pl-1.5 pr-3" icon={faEnvelope} />,
|
||||||
"Send us an Email",
|
t("common:nav.support.email"),
|
||||||
"mailto:[email protected]",
|
"mailto:[email protected]",
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
@@ -51,6 +55,10 @@ export default function Navbar({ onButtonPressed }) {
|
|||||||
const [orgs, setOrgs] = useState([]);
|
const [orgs, setOrgs] = useState([]);
|
||||||
const [currentOrg, setCurrentOrg] = useState([]);
|
const [currentOrg, setCurrentOrg] = useState([]);
|
||||||
|
|
||||||
|
const { t } = useTranslation("common");
|
||||||
|
|
||||||
|
const supportOptionsList = useMemo(() => supportOptions(t), [t]);
|
||||||
|
|
||||||
useEffect(async () => {
|
useEffect(async () => {
|
||||||
const userData = await getUser();
|
const userData = await getUser();
|
||||||
setUser(userData);
|
setUser(userData);
|
||||||
@@ -87,7 +95,7 @@ export default function Navbar({ onButtonPressed }) {
|
|||||||
</div>
|
</div>
|
||||||
<div className="relative flex justify-start items-center mx-2 z-40">
|
<div className="relative flex justify-start items-center mx-2 z-40">
|
||||||
<Menu as="div" className="relative inline-block text-left">
|
<Menu as="div" className="relative inline-block text-left">
|
||||||
<div className="mr-4">
|
<div className="mr-4">
|
||||||
<Menu.Button className="inline-flex w-full justify-center rounded-md px-2 py-2 text-sm font-medium text-gray-200 rounded-md hover:bg-white/10 duration-200 focus:outline-none focus-visible:ring-2 focus-visible:ring-white focus-visible:ring-opacity-75">
|
<Menu.Button className="inline-flex w-full justify-center rounded-md px-2 py-2 text-sm font-medium text-gray-200 rounded-md hover:bg-white/10 duration-200 focus:outline-none focus-visible:ring-2 focus-visible:ring-white focus-visible:ring-opacity-75">
|
||||||
<FontAwesomeIcon
|
<FontAwesomeIcon
|
||||||
className="text-xl"
|
className="text-xl"
|
||||||
@@ -105,19 +113,17 @@ export default function Navbar({ onButtonPressed }) {
|
|||||||
leaveTo="transform opacity-0 scale-95"
|
leaveTo="transform opacity-0 scale-95"
|
||||||
>
|
>
|
||||||
<Menu.Items className="absolute right-0 mt-0.5 w-64 origin-top-right rounded-md bg-bunker border border-mineshaft-700 shadow-lg ring-1 ring-black z-20 ring-opacity-5 focus:outline-none px-2 py-1.5">
|
<Menu.Items className="absolute right-0 mt-0.5 w-64 origin-top-right rounded-md bg-bunker border border-mineshaft-700 shadow-lg ring-1 ring-black z-20 ring-opacity-5 focus:outline-none px-2 py-1.5">
|
||||||
{supportOptions.map((option) => (
|
{supportOptionsList.map(([icon, text, url]) => (
|
||||||
<a
|
<a
|
||||||
key={guidGenerator()}
|
key={guidGenerator()}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noopener"
|
rel="noopener"
|
||||||
href={option[2]}
|
href={url}
|
||||||
className="font-normal text-gray-300 duration-200 rounded-md w-full flex items-center py-0.5"
|
className="font-normal text-gray-300 duration-200 rounded-md w-full flex items-center py-0.5"
|
||||||
>
|
>
|
||||||
<div className="relative flex justify-start items-center cursor-pointer select-none py-2 px-2 rounded-md text-gray-400 hover:bg-white/10 duration-200 hover:text-gray-200 w-full">
|
<div className="relative flex justify-start items-center cursor-pointer select-none py-2 px-2 rounded-md text-gray-400 hover:bg-white/10 duration-200 hover:text-gray-200 w-full">
|
||||||
{option[0]}
|
{icon}
|
||||||
<div className="text-sm">
|
<div className="text-sm">{text}</div>
|
||||||
{option[1]}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
))}
|
))}
|
||||||
@@ -128,7 +134,10 @@ export default function Navbar({ onButtonPressed }) {
|
|||||||
<div>
|
<div>
|
||||||
<Menu.Button className="inline-flex w-full justify-center rounded-md pr-2 pl-2 py-2 text-sm font-medium text-gray-200 rounded-md hover:bg-white/10 duration-200 focus:outline-none focus-visible:ring-2 focus-visible:ring-white focus-visible:ring-opacity-75">
|
<Menu.Button className="inline-flex w-full justify-center rounded-md pr-2 pl-2 py-2 text-sm font-medium text-gray-200 rounded-md hover:bg-white/10 duration-200 focus:outline-none focus-visible:ring-2 focus-visible:ring-white focus-visible:ring-opacity-75">
|
||||||
{user?.firstName} {user?.lastName}
|
{user?.firstName} {user?.lastName}
|
||||||
<FontAwesomeIcon icon={faAngleDown} className="ml-2 mt-1 text-sm text-gray-300 hover:text-lime-100"/>
|
<FontAwesomeIcon
|
||||||
|
icon={faAngleDown}
|
||||||
|
className="ml-2 mt-1 text-sm text-gray-300 hover:text-lime-100"
|
||||||
|
/>
|
||||||
</Menu.Button>
|
</Menu.Button>
|
||||||
</div>
|
</div>
|
||||||
<Transition
|
<Transition
|
||||||
@@ -143,15 +152,17 @@ export default function Navbar({ onButtonPressed }) {
|
|||||||
<Menu.Items className="absolute right-0 mt-0.5 w-64 origin-top-right divide-y divide-gray-700 rounded-md bg-bunker border border-mineshaft-700 shadow-lg ring-1 ring-black z-20 ring-opacity-5 focus:outline-none">
|
<Menu.Items className="absolute right-0 mt-0.5 w-64 origin-top-right divide-y divide-gray-700 rounded-md bg-bunker border border-mineshaft-700 shadow-lg ring-1 ring-black z-20 ring-opacity-5 focus:outline-none">
|
||||||
<div className="px-1 py-1 ">
|
<div className="px-1 py-1 ">
|
||||||
<div className="text-gray-400 self-start ml-2 mt-2 text-xs font-semibold tracking-wide">
|
<div className="text-gray-400 self-start ml-2 mt-2 text-xs font-semibold tracking-wide">
|
||||||
SIGNED IN AS
|
{t("common:nav.user.signed-in-as")}
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
router.push(
|
router.push(
|
||||||
"/settings/personal/" + router.query.id
|
"/settings/personal/" +
|
||||||
|
router.query.id
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
className="flex flex-row items-center px-1 mx-1 my-1 hover:bg-white/5 cursor-pointer rounded-md">
|
className="flex flex-row items-center px-1 mx-1 my-1 hover:bg-white/5 cursor-pointer rounded-md"
|
||||||
|
>
|
||||||
<div className="bg-white/10 h-8 w-9 rounded-full flex items-center justify-center text-gray-300">
|
<div className="bg-white/10 h-8 w-9 rounded-full flex items-center justify-center text-gray-300">
|
||||||
{user?.firstName?.charAt(0)}
|
{user?.firstName?.charAt(0)}
|
||||||
</div>
|
</div>
|
||||||
@@ -159,7 +170,8 @@ export default function Navbar({ onButtonPressed }) {
|
|||||||
<div>
|
<div>
|
||||||
<p className="text-gray-300 px-2 pt-1 text-sm">
|
<p className="text-gray-300 px-2 pt-1 text-sm">
|
||||||
{" "}
|
{" "}
|
||||||
{user?.firstName} {user?.lastName}
|
{user?.firstName}{" "}
|
||||||
|
{user?.lastName}
|
||||||
</p>
|
</p>
|
||||||
<p className="text-gray-400 px-2 pb-1 text-xs">
|
<p className="text-gray-400 px-2 pb-1 text-xs">
|
||||||
{" "}
|
{" "}
|
||||||
@@ -175,7 +187,7 @@ export default function Navbar({ onButtonPressed }) {
|
|||||||
</div>
|
</div>
|
||||||
<div className="px-2 pt-2">
|
<div className="px-2 pt-2">
|
||||||
<div className="text-gray-400 self-start ml-2 mt-2 text-xs font-semibold tracking-wide">
|
<div className="text-gray-400 self-start ml-2 mt-2 text-xs font-semibold tracking-wide">
|
||||||
CURRENT ORGANIZATION
|
{t("common:nav.user.current-organization")}
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
@@ -216,7 +228,7 @@ export default function Navbar({ onButtonPressed }) {
|
|||||||
icon={faCoins}
|
icon={faCoins}
|
||||||
/>
|
/>
|
||||||
<div className="text-sm">
|
<div className="text-sm">
|
||||||
Usage & Billing
|
{t("common:nav.user.usage-billing")}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</button>
|
</button>
|
||||||
@@ -235,51 +247,58 @@ export default function Navbar({ onButtonPressed }) {
|
|||||||
className="relative flex justify-start cursor-pointer select-none py-2 pl-10 pr-4 rounded-md text-gray-400 hover:bg-primary/100 duration-200 hover:text-black hover:font-semibold mt-1"
|
className="relative flex justify-start cursor-pointer select-none py-2 pl-10 pr-4 rounded-md text-gray-400 hover:bg-primary/100 duration-200 hover:text-black hover:font-semibold mt-1"
|
||||||
>
|
>
|
||||||
<span className="rounded-lg absolute inset-y-0 left-0 flex items-center pl-3 pr-4">
|
<span className="rounded-lg absolute inset-y-0 left-0 flex items-center pl-3 pr-4">
|
||||||
<FontAwesomeIcon icon={faPlus} className="ml-1" />
|
<FontAwesomeIcon
|
||||||
|
icon={faPlus}
|
||||||
|
className="ml-1"
|
||||||
|
/>
|
||||||
</span>
|
</span>
|
||||||
<div className="text-sm ml-1">
|
<div className="text-sm ml-1">
|
||||||
Invite Members
|
{t("common:nav.user.invite")}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
{orgs?.length > 1 && <div className="px-1 pt-1">
|
{orgs?.length > 1 && (
|
||||||
<div className="text-gray-400 self-start ml-2 mt-2 text-xs font-semibold tracking-wide">
|
<div className="px-1 pt-1">
|
||||||
OTHER ORGANIZATIONS
|
<div className="text-gray-400 self-start ml-2 mt-2 text-xs font-semibold tracking-wide">
|
||||||
</div>
|
{t(
|
||||||
<div className="flex flex-col items-start px-1 mt-3 mb-2">
|
"common:nav.user.other-organizations"
|
||||||
{orgs
|
)}
|
||||||
.filter(
|
</div>
|
||||||
(org) =>
|
<div className="flex flex-col items-start px-1 mt-3 mb-2">
|
||||||
org._id !=
|
{orgs
|
||||||
localStorage.getItem(
|
.filter(
|
||||||
"orgData.id"
|
(org) =>
|
||||||
)
|
org._id !=
|
||||||
)
|
localStorage.getItem(
|
||||||
.map((org) => (
|
"orgData.id"
|
||||||
<div
|
)
|
||||||
key={guidGenerator()}
|
)
|
||||||
onClick={() => {
|
.map((org) => (
|
||||||
localStorage.setItem(
|
<div
|
||||||
"orgData.id",
|
key={guidGenerator()}
|
||||||
org._id
|
onClick={() => {
|
||||||
);
|
localStorage.setItem(
|
||||||
router.reload();
|
"orgData.id",
|
||||||
}}
|
org._id
|
||||||
className="flex flex-row justify-start items-center hover:bg-white/5 w-full p-1.5 cursor-pointer rounded-md"
|
);
|
||||||
>
|
router.reload();
|
||||||
<div className="bg-white/10 h-7 w-8 rounded-md flex items-center justify-center text-gray-300">
|
}}
|
||||||
{org.name.charAt(0)}
|
className="flex flex-row justify-start items-center hover:bg-white/5 w-full p-1.5 cursor-pointer rounded-md"
|
||||||
|
>
|
||||||
|
<div className="bg-white/10 h-7 w-8 rounded-md flex items-center justify-center text-gray-300">
|
||||||
|
{org.name.charAt(0)}
|
||||||
|
</div>
|
||||||
|
<div className="flex items-center justify-between w-full">
|
||||||
|
<p className="text-gray-300 px-2 text-sm">
|
||||||
|
{org.name}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center justify-between w-full">
|
))}
|
||||||
<p className="text-gray-300 px-2 text-sm">
|
</div>
|
||||||
{org.name}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</div>
|
</div>
|
||||||
</div>}
|
)}
|
||||||
<div className="px-1 py-1">
|
<div className="px-1 py-1">
|
||||||
<Menu.Item>
|
<Menu.Item>
|
||||||
{({ active }) => (
|
{({ active }) => (
|
||||||
@@ -296,7 +315,7 @@ export default function Navbar({ onButtonPressed }) {
|
|||||||
className="text-lg ml-1.5 mr-3"
|
className="text-lg ml-1.5 mr-3"
|
||||||
icon={faRightFromBracket}
|
icon={faRightFromBracket}
|
||||||
/>
|
/>
|
||||||
Log Out
|
{t("common:logout")}
|
||||||
</div>
|
</div>
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -11,11 +11,36 @@
|
|||||||
"og-description": "Infisical a simple end-to-end encrypted platform that enables teams to sync and manage API-keys and environemntal variables. Works with Node.js, Next.js, Gatsby, Nest.js..."
|
"og-description": "Infisical a simple end-to-end encrypted platform that enables teams to sync and manage API-keys and environemntal variables. Works with Node.js, Next.js, Gatsby, Nest.js..."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"nav": {
|
||||||
|
"support": {
|
||||||
|
"slack": "[NEW] Join Slack Forum",
|
||||||
|
"docs": "Read Docs",
|
||||||
|
"issue": "Open a Github Issue",
|
||||||
|
"email": "Send us an Email"
|
||||||
|
},
|
||||||
|
"user": {
|
||||||
|
"signed-in-as": "SIGNED IN AS",
|
||||||
|
"current-organization": "CURRENT ORGANIZATION",
|
||||||
|
"usage-billing": "Usage & Billing",
|
||||||
|
"invite": "Invite Members",
|
||||||
|
"other-organizations": "OTHER ORGANIZATION"
|
||||||
|
},
|
||||||
|
"menu": {
|
||||||
|
"project": "PROJECT",
|
||||||
|
"secrets": "Secrets",
|
||||||
|
"members": "Members",
|
||||||
|
"integrations": "Integrations",
|
||||||
|
"project-settings": "Project Settings"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"error_project-already-exists": "A project with this name already exists.",
|
||||||
|
"need-login": " To use Infisical, please log in through a device with larger dimensions. ",
|
||||||
"email": "Email",
|
"email": "Email",
|
||||||
"password": "Password",
|
"password": "Password",
|
||||||
"verify": "Verify",
|
"verify": "Verify",
|
||||||
"first-name": "First Name",
|
"first-name": "First Name",
|
||||||
"last-name": "Last Name",
|
"last-name": "Last Name",
|
||||||
|
"logout": "Log Out",
|
||||||
"validate-required": "Please input your {{name}}",
|
"validate-required": "Please input your {{name}}",
|
||||||
"password-validate": "Password should contain at least:",
|
"password-validate": "Password should contain at least:",
|
||||||
"password-validate-length": "14 characters",
|
"password-validate-length": "14 characters",
|
||||||
|
|||||||
Reference in New Issue
Block a user