mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-14 10:29:52 +00:00
translate(frontend): update namespace names, move translate keys, translate some keys into korean
This commit is contained in:
@@ -2,6 +2,7 @@ import React, { useEffect, useState } from "react";
|
||||
import Head from "next/head";
|
||||
import Image from "next/image";
|
||||
import { useRouter } from "next/router";
|
||||
import useTranslation from "next-translate/useTranslation";
|
||||
import {
|
||||
faArrowRight,
|
||||
faCheck,
|
||||
@@ -54,6 +55,8 @@ const Integration = ({ projectIntegration }) => {
|
||||
projectIntegration.app ? projectIntegration.app : apps[0]
|
||||
);
|
||||
|
||||
const { t } = useTranslation();
|
||||
|
||||
useEffect(async () => {
|
||||
const tempHerokuApps = await getIntegrationApps({
|
||||
integrationAuthId: projectIntegration.integrationAuth,
|
||||
@@ -179,6 +182,8 @@ export default function Integrations() {
|
||||
const router = useRouter();
|
||||
const [csrfToken, setCsrfToken] = useState("");
|
||||
|
||||
const { t } = useTranslation();
|
||||
|
||||
useEffect(async () => {
|
||||
const tempCSRFToken = crypto.randomBytes(16).toString("hex");
|
||||
setCsrfToken(tempCSRFToken);
|
||||
@@ -205,24 +210,28 @@ export default function Integrations() {
|
||||
return integrations ? (
|
||||
<div className="bg-bunker-800 max-h-screen flex flex-col justify-between text-white">
|
||||
<Head>
|
||||
<title>Dashboard</title>
|
||||
<title>
|
||||
<title>
|
||||
{t("common:head-title", { title: t("integrations:title") })}
|
||||
</title>
|
||||
</title>
|
||||
<link rel="icon" href="/infisical.ico" />
|
||||
<meta property="og:image" content="/images/message.png" />
|
||||
<meta property="og:title" content="Manage your .env files in seconds" />
|
||||
<meta
|
||||
name="og:description"
|
||||
content="Infisical a simple end-to-end encrypted platform that enables teams to sync and manage their .env files."
|
||||
/>
|
||||
<meta name="og:description" content={t("integrations:description")} />
|
||||
</Head>
|
||||
<div className="flex flex-row">
|
||||
<div className="w-full max-h-96 pb-2 h-screen max-h-[calc(100vh-10px)] overflow-y-scroll no-scrollbar no-scrollbar::-webkit-scrollbar">
|
||||
<NavHeader pageName="Project Integrations" isProjectRelated={true} />
|
||||
<NavHeader
|
||||
pageName={t("integrations:title")}
|
||||
isProjectRelated={true}
|
||||
/>
|
||||
<div className="flex flex-col justify-between items-start mx-4 mt-6 mb-4 text-xl max-w-5xl px-2">
|
||||
<div className="flex flex-row justify-start items-center text-3xl">
|
||||
<p className="font-semibold mr-4">Current Project Integrations</p>
|
||||
<p className="font-semibold mr-4">{t("integrations:title")}</p>
|
||||
</div>
|
||||
<p className="mr-4 text-base text-gray-400">
|
||||
Manage your integrations of Infisical with third-party services.
|
||||
{t("integrations:description")}
|
||||
</p>
|
||||
</div>
|
||||
{projectIntegrations.length > 0 ? (
|
||||
@@ -235,34 +244,22 @@ export default function Integrations() {
|
||||
) : (
|
||||
<div className="flex flex-col max-w-5xl justify-center bg-white/5 p-6 rounded-md mx-6 mt-8">
|
||||
<div className="relative px-4 flex flex-col text-gray-400 items-center justify-center">
|
||||
<div className="mb-1">
|
||||
You {"don't"} have any integrations set up yet. When you do,
|
||||
they will appear here.
|
||||
</div>
|
||||
<div className="">
|
||||
To start, click on any of the options below. It takes 5 clicks
|
||||
to set up.
|
||||
</div>
|
||||
<div className="mb-1">{t("integrations:no-integrations1")}</div>
|
||||
<div className="">{t("integrations:no-integrations2")}</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<div className="flex flex-col justify-between items-start mx-4 mt-12 mb-4 text-xl max-w-5xl px-2">
|
||||
<div className="flex flex-row justify-start items-center text-3xl">
|
||||
<p className="font-semibold mr-4">Available Integrations</p>
|
||||
<p className="font-semibold mr-4">
|
||||
{t("integrations:available")}
|
||||
</p>
|
||||
</div>
|
||||
<p className="mr-4 text-base text-gray-400">
|
||||
Click on the itegration you want to connect. This will let your
|
||||
environment variables flow automatically into selected third-party
|
||||
services.
|
||||
{t("integrations:available-text1")}
|
||||
</p>
|
||||
<p className="mr-4 text-xs text-gray-600 mt-1">
|
||||
Note: during an integration with Heroku, for security reasons, it
|
||||
is impossible to maintain end-to-end encryption. In theory, this
|
||||
lets Infisical decrypt yor environment variables. In practice, we
|
||||
can assure you that this will never be done, and it allows us to
|
||||
protect your secrets from bad actors online. The core Infisical
|
||||
service will always stay end-to-end encrypted. With any questions,
|
||||
reach out support@infisical.com.
|
||||
{t("integrations:available-text2")}
|
||||
</p>
|
||||
</div>
|
||||
<div className="grid gap-4 grid-cols-3 grid-rows-3 mx-6 mt-4 max-w-5xl">
|
||||
|
||||
+8
-11
@@ -55,14 +55,11 @@ export default function Login() {
|
||||
return (
|
||||
<div className="bg-bunker-800 h-screen flex flex-col justify-start px-6">
|
||||
<Head>
|
||||
<title>{t("auth:meta.login.title")}</title>
|
||||
<title>{t("common:head-title", { title: t("login:title") })}</title>
|
||||
<link rel="icon" href="/infisical.ico" />
|
||||
<meta property="og:image" content="/images/message.png" />
|
||||
<meta property="og:title" content={t("auth:meta.login.og-title")} />
|
||||
<meta
|
||||
name="og:description"
|
||||
content={t("auth:meta.login.og-description")}
|
||||
/>
|
||||
<meta property="og:title" content={t("login:og-title")} />
|
||||
<meta name="og:description" content={t("login:og-description")} />
|
||||
</Head>
|
||||
<Link href="/">
|
||||
<div className="flex justify-center mb-8 mt-20 cursor-pointer">
|
||||
@@ -76,18 +73,18 @@ export default function Login() {
|
||||
</Link>
|
||||
<div className="bg-bunker w-full max-w-md mx-auto h-7/12 py-4 pt-8 px-6 rounded-xl drop-shadow-xl">
|
||||
<p className="text-4xl flex justify-center font-semibold text-transparent bg-clip-text bg-gradient-to-br from-sky-400 to-primary">
|
||||
{t("auth:login")}
|
||||
{t("login:login")}
|
||||
</p>
|
||||
<div className="flex flex-row items-center justify-center">
|
||||
<p className="text-md flex justify-center mt-2 text-gray-400">
|
||||
{t("auth:need-account")}
|
||||
{t("login:need-account")}
|
||||
</p>
|
||||
</div>
|
||||
<div className="flex flex-col items-center justify-center w-full md:pb-4 max-h-24 max-w-md mx-auto">
|
||||
<Link href="/signup">
|
||||
<button className="w-full pb-3 hover:opacity-90 duration-200">
|
||||
<u className="font-normal text-md text-sky-500">
|
||||
{t("auth:create-account")}
|
||||
{t("login:create-account")}
|
||||
</u>
|
||||
</button>
|
||||
</Link>
|
||||
@@ -116,7 +113,7 @@ export default function Login() {
|
||||
<div className="flex flex-col items-center justify-center w-full md:p-2 max-h-20 max-w-md mt-4 mx-auto text-sm">
|
||||
<div className="text-l mt-6 m-8 px-8 py-3 text-lg">
|
||||
<Button
|
||||
text={t("auth:login")}
|
||||
text={t("login:login")}
|
||||
onButtonPressed={loginCheck}
|
||||
loading={isLoading}
|
||||
size="lg"
|
||||
@@ -131,7 +128,7 @@ export default function Login() {
|
||||
<div className="w-full p-2 flex flex-row items-center bg-white/10 text-gray-300 rounded-md max-w-md mx-auto mt-4">
|
||||
<FontAwesomeIcon icon={faWarning} className="ml-2 mr-6 text-6xl" />
|
||||
|
||||
{t("auth:maintenance-alert")}
|
||||
{t("common:maintenance-alert")}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
import Head from "next/head";
|
||||
import useTranslation from "next-translate/useTranslation";
|
||||
|
||||
import Plan from "~/components/billing/Plan";
|
||||
import NavHeader from "~/components/navigation/NavHeader";
|
||||
@@ -12,36 +13,38 @@ export default function SettingsBilling() {
|
||||
let [currentPlan, setCurrentPlan] = useState("");
|
||||
let [numUsers, setNumUsers] = useState("");
|
||||
|
||||
const { t } = useTranslation();
|
||||
|
||||
const plans = [
|
||||
{
|
||||
key: 1,
|
||||
name: "Starter",
|
||||
price: "Free",
|
||||
priceExplanation: "up to 5 team members",
|
||||
text: "Manage any project with 5 members for free!",
|
||||
subtext: "$5 per member/month afterwards.",
|
||||
buttonTextMain: "Downgrade",
|
||||
buttonTextSecondary: "Learn More",
|
||||
name: t("common:starter"),
|
||||
price: t("common:free"),
|
||||
priceExplanation: t("billing:starter.price-explanation"),
|
||||
text: t("billing:starter.text"),
|
||||
subtext: t("billing:starter.subtext"),
|
||||
buttonTextMain: t("common:downgrade"),
|
||||
buttonTextSecondary: t("common:learn-more"),
|
||||
current: currentPlan == STRIPE_PRODUCT_STARTER,
|
||||
},
|
||||
{
|
||||
key: 2,
|
||||
name: "Professional",
|
||||
name: t("common:professional"),
|
||||
price: "$9",
|
||||
priceExplanation: "/member/month",
|
||||
subtext: "Includes unlimited projects & members.",
|
||||
text: "Keep up with key management as you grow.",
|
||||
buttonTextMain: "Upgrade",
|
||||
buttonTextSecondary: "Learn More",
|
||||
priceExplanation: t("billing:professional.price-explanation"),
|
||||
subtext: t("billing:professional.subtext"),
|
||||
text: t("billing:professional.text"),
|
||||
buttonTextMain: t("common:upgrade"),
|
||||
buttonTextSecondary: t("common:learn-more"),
|
||||
current: currentPlan == STRIPE_PRODUCT_PRO,
|
||||
},
|
||||
{
|
||||
key: 3,
|
||||
name: "Enterprise",
|
||||
price: "Custom Pricing",
|
||||
text: "More control for advanced organizations.",
|
||||
buttonTextMain: "Schedule a Demo",
|
||||
buttonTextSecondary: "Learn More",
|
||||
name: t("common:enterprise"),
|
||||
price: t("common:custom-pricing"),
|
||||
text: t("billing:enterprise.text"),
|
||||
buttonTextMain: t("common:schedule-demo"),
|
||||
buttonTextSecondary: t("common:learn-more"),
|
||||
current: false,
|
||||
},
|
||||
];
|
||||
@@ -61,30 +64,32 @@ export default function SettingsBilling() {
|
||||
return (
|
||||
<div className="bg-bunker-800 max-h-screen flex flex-col justify-between text-white">
|
||||
<Head>
|
||||
<title>Settings - Billing</title>
|
||||
<title>{t("common:head-title", { title: t("billing:title") })}</title>
|
||||
<link rel="icon" href="/infisical.ico" />
|
||||
</Head>
|
||||
<div className="flex flex-row">
|
||||
<div className="w-full max-h-screen pb-2 overflow-y-auto">
|
||||
<NavHeader pageName="Usage & Billing" />
|
||||
<NavHeader pageName={t("billing:title")} />
|
||||
<div className="flex flex-row justify-between items-center ml-6 my-8 text-xl max-w-5xl">
|
||||
<div className="flex flex-col justify-start items-start text-3xl">
|
||||
<p className="font-semibold mr-4 text-gray-200">
|
||||
Usage & Billing
|
||||
{t("billing:title")}
|
||||
</p>
|
||||
<p className="font-normal mr-4 text-gray-400 text-base">
|
||||
View and manage your {"organization's"} subscription here.
|
||||
{t("billing:description")}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-col ml-6 text-mineshaft-50">
|
||||
<p className="text-xl font-semibold">Subscription</p>
|
||||
<p className="text-xl font-semibold">{t("billing:subscription")}</p>
|
||||
<div className="flex flex-row mt-4 overflow-x-auto">
|
||||
{plans.map((plan) => (
|
||||
<Plan key={plan.name} plan={plan} />
|
||||
))}
|
||||
</div>
|
||||
<p className="text-xl font-bold mt-12">Current Usage</p>
|
||||
<p className="text-xl font-bold mt-12">
|
||||
{t("billing:current-usage")}
|
||||
</p>
|
||||
<div className="flex flex-row">
|
||||
<div className="mr-4 mt-8 text-gray-300 w-60 pt-6 pb-10 rounded-md bg-white/5 flex justify-center items-center flex flex-col">
|
||||
<p className="text-6xl font-bold">{numUsers}</p>
|
||||
|
||||
@@ -159,12 +159,14 @@ export default function SettingsOrg() {
|
||||
return (
|
||||
<div className="bg-bunker-800 max-h-screen flex flex-col justify-between text-white">
|
||||
<Head>
|
||||
<title>{t("settings:meta.org.head-title")}</title>
|
||||
<title>
|
||||
{t("common:head-title", { title: t("settings-org:title") })}
|
||||
</title>
|
||||
<link rel="icon" href="/infisical.ico" />
|
||||
</Head>
|
||||
<div className="flex flex-row">
|
||||
<div className="w-full max-h-screen pb-2 overflow-y-auto">
|
||||
<NavHeader pageName={t("settings:meta.org.title")} />
|
||||
<NavHeader pageName={t("settings-org:title")} />
|
||||
<AddIncidentContactDialog
|
||||
isOpen={isAddIncidentContactOpen}
|
||||
closeModal={closeAddIncidentContactModal}
|
||||
@@ -175,10 +177,10 @@ export default function SettingsOrg() {
|
||||
<div className="flex flex-row justify-between items-center ml-6 my-8 text-xl max-w-5xl">
|
||||
<div className="flex flex-col justify-start items-start text-3xl">
|
||||
<p className="font-semibold mr-4 text-gray-200">
|
||||
{t("settings:meta.org.title")}
|
||||
{t("settings-org:title")}
|
||||
</p>
|
||||
<p className="font-normal mr-4 text-gray-400 text-base">
|
||||
{t("settings:meta.org.description")}
|
||||
{t("settings-org:description")}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -278,15 +280,15 @@ export default function SettingsOrg() {
|
||||
<div className="flex flex-row max-w-5xl justify-between items-center w-full">
|
||||
<div className="flex flex-col justify-between w-full max-w-3xl">
|
||||
<p className="text-xl font-semibold mb-3 min-w-max">
|
||||
{t("settings:incident-contacts")}
|
||||
{t("section-incident:incident-contacts")}
|
||||
</p>
|
||||
<p className="text-xs text-gray-500 mb-2 min-w-max">
|
||||
{t("settings:incident-contacts-description")}
|
||||
{t("section-incident:incident-contacts-description")}
|
||||
</p>
|
||||
</div>
|
||||
<div className="mt-4 mb-2 min-w-max flex flex-row items-end justify-end justify-center">
|
||||
<Button
|
||||
text={t("common:add-contact")}
|
||||
text={t("section-incident:add-contact")}
|
||||
onButtonPressed={openAddIncidentContactModal}
|
||||
color="mineshaft"
|
||||
size="md"
|
||||
@@ -332,7 +334,7 @@ export default function SettingsOrg() {
|
||||
) : (
|
||||
<div className="w-full flex flex-row justify-center mt-6 max-w-4xl ml-6">
|
||||
<p className="text-gray-400">
|
||||
{t("settings:no-incident-contacts")}
|
||||
{t("section-incident:no-incident-contacts")}
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
import Head from "next/head";
|
||||
import useTranslation from "next-translate/useTranslation";
|
||||
import { faCheck, faX } from "@fortawesome/free-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
|
||||
@@ -26,6 +27,8 @@ export default function PersonalSettings() {
|
||||
const [backupKeyIssued, setBackupKeyIssued] = useState(false);
|
||||
const [backupKeyError, setBackupKeyError] = useState(false);
|
||||
|
||||
const { t } = useTranslation();
|
||||
|
||||
useEffect(async () => {
|
||||
let user = await getUser();
|
||||
setPersonalEmail(user.email);
|
||||
@@ -35,19 +38,24 @@ export default function PersonalSettings() {
|
||||
return (
|
||||
<div className="bg-bunker-800 max-h-screen flex flex-col justify-between text-white">
|
||||
<Head>
|
||||
<title>Personal Settings</title>
|
||||
<title>
|
||||
{t("common:head-title", { title: t("settings-personal:title") })}
|
||||
</title>
|
||||
<link rel="icon" href="/infisical.ico" />
|
||||
</Head>
|
||||
<div className="flex flex-row">
|
||||
<div className="w-full max-h-screen pb-2 overflow-y-auto">
|
||||
<NavHeader pageName="Personal Settings" isProjectRelated={false} />
|
||||
<NavHeader
|
||||
pageName={t("settings-personal:title")}
|
||||
isProjectRelated={false}
|
||||
/>
|
||||
<div className="flex flex-row justify-between items-center ml-6 mt-8 mb-6 text-xl max-w-5xl">
|
||||
<div className="flex flex-col justify-start items-start text-3xl">
|
||||
<p className="font-semibold mr-4 text-gray-200">
|
||||
Personal Settings
|
||||
{t("settings-personal:title")}
|
||||
</p>
|
||||
<p className="font-normal mr-4 text-gray-400 text-base">
|
||||
View and manage your personal information here.
|
||||
{t("settings-personal:description")}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -104,13 +112,13 @@ export default function PersonalSettings() {
|
||||
<div className="flex flex-row max-w-5xl justify-between items-center w-full">
|
||||
<div className="flex flex-col justify-between w-full max-w-3xl">
|
||||
<p className="text-xl font-semibold mb-3 min-w-max">
|
||||
Change password
|
||||
{t("form-password:change")}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="max-w-xl w-full">
|
||||
<InputField
|
||||
label="Current Password"
|
||||
label={t("form-password:current")}
|
||||
onChangeHandler={(password) => {
|
||||
setCurrentPassword(password);
|
||||
}}
|
||||
@@ -118,11 +126,11 @@ export default function PersonalSettings() {
|
||||
value={currentPassword}
|
||||
isRequired
|
||||
error={currentPasswordError}
|
||||
errorText="The current password may be wrong"
|
||||
errorText={t("form-password:current-wrong")}
|
||||
/>
|
||||
<div className="py-2"></div>
|
||||
<InputField
|
||||
label="New Password"
|
||||
label={t("form-password:new")}
|
||||
onChangeHandler={(password) => {
|
||||
setNewPassword(password);
|
||||
passwordCheck(
|
||||
@@ -148,7 +156,7 @@ export default function PersonalSettings() {
|
||||
passwordErrorNumber ? (
|
||||
<div className="w-full mt-3 bg-white/5 px-2 flex flex-col items-start py-2 rounded-md max-w-xl mb-2">
|
||||
<div className={`text-gray-400 text-sm mb-1`}>
|
||||
Password should contain at least:
|
||||
{t("form-password:validate-base")}
|
||||
</div>
|
||||
<div className="flex flex-row justify-start items-center ml-1">
|
||||
{passwordErrorLength ? (
|
||||
@@ -167,7 +175,7 @@ export default function PersonalSettings() {
|
||||
passwordErrorLength ? "text-gray-400" : "text-gray-600"
|
||||
} text-sm`}
|
||||
>
|
||||
14 characters
|
||||
{t("form-password:validate-length")}
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-row justify-start items-center ml-1">
|
||||
@@ -189,7 +197,7 @@ export default function PersonalSettings() {
|
||||
: "text-gray-600"
|
||||
} text-sm`}
|
||||
>
|
||||
1 lowercase character
|
||||
{t("form-password:validate-case")}
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-row justify-start items-center ml-1">
|
||||
@@ -209,7 +217,7 @@ export default function PersonalSettings() {
|
||||
passwordErrorNumber ? "text-gray-400" : "text-gray-600"
|
||||
} text-sm`}
|
||||
>
|
||||
1 number
|
||||
{t("form-password:validate-number")}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -247,7 +255,7 @@ export default function PersonalSettings() {
|
||||
passwordErrorNumber
|
||||
)
|
||||
}
|
||||
textDisabled="Change Password"
|
||||
textDisabled={t("password:change")}
|
||||
/>
|
||||
<FontAwesomeIcon
|
||||
icon={faCheck}
|
||||
@@ -262,32 +270,30 @@ export default function PersonalSettings() {
|
||||
<div className="flex flex-row max-w-5xl justify-between items-center w-full">
|
||||
<div className="flex flex-col justify-between w-full max-w-3xl">
|
||||
<p className="text-xl font-semibold mb-3 min-w-max">
|
||||
Emergency Kit
|
||||
{t("settings-personal:emergency.name")}
|
||||
</p>
|
||||
<p className="text-sm text-mineshaft-300 min-w-max">
|
||||
Your Emergency Kit contains the information you’ll need to
|
||||
sign in to your Infisical account.
|
||||
{t("settings-personal:emergency.text1")}
|
||||
</p>
|
||||
<p className="text-sm text-mineshaft-300 mb-5 min-w-max">
|
||||
Only the latest issued Emergency Kit remains valid. To get a
|
||||
new Emergency Kit, verify your password.
|
||||
{t("settings-personal:emergency.text2")}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="w-full max-w-xl mb-4">
|
||||
<InputField
|
||||
label="Current Password"
|
||||
label={t("password:current")}
|
||||
onChangeHandler={setBackupPassword}
|
||||
type="password"
|
||||
value={backupPassword}
|
||||
isRequired
|
||||
error={backupKeyError}
|
||||
errorText="The current password is wrong"
|
||||
errorText={t("password:current-wrong")}
|
||||
/>
|
||||
</div>
|
||||
<div className="flex flex-row items-center mt-3 w-full w-60">
|
||||
<Button
|
||||
text="Download Emergency Kit"
|
||||
text={t("settings-personal:emergency.download")}
|
||||
onButtonPressed={() => {
|
||||
issueBackupKey({
|
||||
email: personalEmail,
|
||||
@@ -300,7 +306,7 @@ export default function PersonalSettings() {
|
||||
color="mineshaft"
|
||||
size="md"
|
||||
active={backupPassword != ""}
|
||||
textDisabled="Download Emergency Kit"
|
||||
textDisabled={t("settings-personal:emergency.download")}
|
||||
/>
|
||||
<FontAwesomeIcon
|
||||
icon={faCheck}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import React, { useEffect, useRef, useState } from "react";
|
||||
import Head from "next/head";
|
||||
import { useRouter } from "next/router";
|
||||
import useTranslation from "next-translate/useTranslation";
|
||||
import { faCheck, faPlus } from "@fortawesome/free-solid-svg-icons";
|
||||
|
||||
import Button from "~/components/basic/buttons/Button";
|
||||
@@ -25,6 +26,8 @@ export default function SettingsBasic() {
|
||||
let [isAddServiceTokenDialogOpen, setIsAddServiceTokenDialogOpen] =
|
||||
useState(false);
|
||||
|
||||
const { t } = useTranslation();
|
||||
|
||||
useEffect(async () => {
|
||||
let userWorkspaces = await getWorkspaces();
|
||||
userWorkspaces.map((userWorkspace) => {
|
||||
@@ -89,7 +92,9 @@ export default function SettingsBasic() {
|
||||
return (
|
||||
<div className="bg-bunker-800 max-h-screen flex flex-col justify-between text-white">
|
||||
<Head>
|
||||
<title>Settings</title>
|
||||
<title>
|
||||
{t("common:head-title", { title: t("settings-project:title") })}
|
||||
</title>
|
||||
<link rel="icon" href="/infisical.ico" />
|
||||
</Head>
|
||||
<AddServiceTokenDialog
|
||||
@@ -100,14 +105,17 @@ export default function SettingsBasic() {
|
||||
/>
|
||||
<div className="flex flex-row mr-6 max-w-5xl">
|
||||
<div className="w-full max-h-screen pb-2 overflow-y-auto">
|
||||
<NavHeader pageName="Project Settings" isProjectRelated={true} />
|
||||
<NavHeader
|
||||
pageName={t("settings-project:title")}
|
||||
isProjectRelated={true}
|
||||
/>
|
||||
<div className="flex flex-row justify-between items-center ml-6 my-8 text-xl max-w-5xl">
|
||||
<div className="flex flex-col justify-start items-start text-3xl">
|
||||
<p className="font-semibold mr-4 text-gray-200">
|
||||
Project Settings
|
||||
{t("settings-project:title")}
|
||||
</p>
|
||||
<p className="font-normal mr-4 text-gray-400 text-base">
|
||||
These settings only apply to the currently selected Project.
|
||||
{t("settings-project:description")}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -115,7 +123,9 @@ export default function SettingsBasic() {
|
||||
<div className="flex flex-col">
|
||||
<div className="min-w-md mt-2 flex flex-col items-start">
|
||||
<div className="bg-white/5 rounded-md px-6 pt-6 pb-4 flex flex-col items-start flex flex-col items-start w-full mb-6 pt-2">
|
||||
<p className="text-xl font-semibold mb-4">Display Name</p>
|
||||
<p className="text-xl font-semibold mb-4">
|
||||
{t("common:display-name")}
|
||||
</p>
|
||||
<div className="max-h-28 w-full max-w-md mr-auto">
|
||||
<InputField
|
||||
onChangeHandler={modifyWorkspaceName}
|
||||
@@ -128,7 +138,7 @@ export default function SettingsBasic() {
|
||||
<div className="flex justify-start w-full">
|
||||
<div className={`flex justify-start max-w-sm mt-4 mb-2`}>
|
||||
<Button
|
||||
text="Save Changes"
|
||||
text={t("common:save-changes")}
|
||||
onButtonPressed={() => submitChanges(workspaceName)}
|
||||
color="mineshaft"
|
||||
size="md"
|
||||
@@ -140,15 +150,14 @@ export default function SettingsBasic() {
|
||||
</div>
|
||||
</div>
|
||||
<div className="bg-white/5 rounded-md px-6 pt-6 pb-2 flex flex-col items-start flex flex-col items-start w-full mb-6 mt-4">
|
||||
<p className="text-xl font-semibold self-start">Project ID</p>
|
||||
<p className="text-xl font-semibold self-start">
|
||||
{t("common:project-id")}
|
||||
</p>
|
||||
<p className="text-base text-gray-400 font-normal self-start mt-4">
|
||||
To integrate Infisical into your code base and get automatic
|
||||
injection of environmental variables, you should use the
|
||||
following Project ID.
|
||||
{t("settings-project:project-id-description")}
|
||||
</p>
|
||||
<p className="text-base text-gray-400 font-normal self-start">
|
||||
For more guidance, including code snipets for various
|
||||
languages and frameworks, see{" "}
|
||||
{t("settings-project:project-id-description2")}
|
||||
{/* eslint-disable-next-line react/jsx-no-target-blank */}
|
||||
<a
|
||||
href="https://infisical.com/docs/getting-started/introduction"
|
||||
@@ -156,7 +165,7 @@ export default function SettingsBasic() {
|
||||
rel="noopener"
|
||||
className="text-primary hover:opacity-80 duration-200"
|
||||
>
|
||||
Infisical Docs.
|
||||
{t("settings-project:docs")}
|
||||
</a>
|
||||
</p>
|
||||
<div className="max-h-28 w-ful">
|
||||
@@ -166,7 +175,7 @@ export default function SettingsBasic() {
|
||||
placeholder=""
|
||||
isRequired
|
||||
static
|
||||
text="This is your project's auto-generated unique identifier. It can't be changed."
|
||||
text={t("settings-project:auto-generated")}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -174,16 +183,15 @@ export default function SettingsBasic() {
|
||||
<div className="flex flex-row justify-between w-full">
|
||||
<div className="flex flex-col w-full">
|
||||
<p className="text-xl font-semibold mb-3">
|
||||
Service Tokens
|
||||
{t("section-token:service-tokens")}
|
||||
</p>
|
||||
<p className="text-base text-gray-400 mb-4">
|
||||
Every service token is specific to you, a certain
|
||||
project and a certain environment within this project.
|
||||
{t("section-token:service-tokens-description")}
|
||||
</p>
|
||||
</div>
|
||||
<div className="w-48">
|
||||
<Button
|
||||
text="Add New Token"
|
||||
text={t("section-token:add-new")}
|
||||
onButtonPressed={() => {
|
||||
setIsAddServiceTokenDialogOpen(true);
|
||||
}}
|
||||
@@ -237,15 +245,15 @@ export default function SettingsBasic() {
|
||||
</div>
|
||||
</div>
|
||||
<div className="bg-white/5 rounded-md px-6 pt-6 pb-6 border-l border-red pl-6 flex flex-col items-start flex flex-col items-start w-full mb-6 mt-4 pb-4 pt-2">
|
||||
<p className="text-xl font-bold text-red">Danger Zone</p>
|
||||
<p className="text-xl font-bold text-red">
|
||||
{t("settings-project:danger-zone")}
|
||||
</p>
|
||||
<p className="mt-2 text-md text-gray-400">
|
||||
As soon as you delete this project, you will not be able to undo
|
||||
it. This will immediately remove all the keys. If you still want
|
||||
to do that, please enter the name of the project below.
|
||||
{t("settings-project:danger-zone-note")}
|
||||
</p>
|
||||
<div className="max-h-28 w-full max-w-md mr-auto mt-4">
|
||||
<InputField
|
||||
label="Project to be Deleted"
|
||||
label={t("settings-project:project-to-delete")}
|
||||
onChangeHandler={setWorkspaceToBeDeletedName}
|
||||
type="varName"
|
||||
value={workspaceToBeDeletedName}
|
||||
@@ -258,11 +266,10 @@ export default function SettingsBasic() {
|
||||
className="max-w-md mt-6 w-full inline-flex justify-center rounded-md border border-transparent bg-gray-800 px-4 py-2.5 text-sm font-medium text-gray-400 hover:bg-red hover:text-white hover:font-semibold hover:text-semibold duration-200 focus:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:ring-offset-2"
|
||||
onClick={executeDeletingWorkspace}
|
||||
>
|
||||
Delete Project
|
||||
{t("settings-project:delete-project")}
|
||||
</button>
|
||||
<p className="mt-0.5 ml-1 text-xs text-gray-500">
|
||||
Note: You can only delete a project in case you have more than
|
||||
one.
|
||||
{t("settings-project:delete-project-note")}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
+17
-21
@@ -250,13 +250,13 @@ export default function SignUp() {
|
||||
const step1 = (
|
||||
<div className="bg-bunker w-full max-w-md mx-auto h-7/12 py-8 md:px-6 mx-1 mb-48 md:mb-16 rounded-xl drop-shadow-xl">
|
||||
<p className="text-4xl font-semibold flex justify-center text-transparent bg-clip-text bg-gradient-to-br from-sky-400 to-primary">
|
||||
{t("auth:step1-start")}
|
||||
{t("signup:step1-start")}
|
||||
</p>
|
||||
<div className="flex flex-col items-center justify-center w-full md:pb-2 max-h-24 max-w-md mx-auto pt-2">
|
||||
<Link href="/login">
|
||||
<button className="w-max pb-3 hover:opacity-90 duration-200">
|
||||
<u className="font-normal text-md text-sky-500">
|
||||
{t("auth:already-have-account")}
|
||||
{t("signup:already-have-account")}
|
||||
</u>
|
||||
</button>
|
||||
</Link>
|
||||
@@ -279,12 +279,11 @@ export default function SignUp() {
|
||||
</div> */}
|
||||
<div className="flex flex-col items-center justify-center w-5/6 md:w-full md:p-2 max-h-28 max-w-xs md:max-w-md mx-auto mt-4 md:mt-4 text-sm text-center md:text-left">
|
||||
<p className="text-gray-400 mt-2 md:mx-0.5">
|
||||
By creating an account, you agree to our Terms and have read and
|
||||
acknowledged the Privacy Policy.
|
||||
{t("signup:step1-privacy")}
|
||||
</p>
|
||||
<div className="text-l mt-6 m-2 md:m-8 px-8 py-1 text-lg">
|
||||
<Button
|
||||
text={t("auth:step1-submit")}
|
||||
text={t("signup:step1-submit")}
|
||||
onButtonPressed={emailCheck}
|
||||
size="lg"
|
||||
/>
|
||||
@@ -297,7 +296,7 @@ export default function SignUp() {
|
||||
const step2 = (
|
||||
<div className="bg-bunker w-max mx-auto h-7/12 pt-10 pb-4 px-8 rounded-xl drop-shadow-xl mb-64 md:mb-16">
|
||||
<Trans
|
||||
i18nKey="common:step2-message"
|
||||
i18nKey="signup:step2-message"
|
||||
components={{
|
||||
wrapper: <p className="text-l flex justify-center text-gray-400" />,
|
||||
email: (
|
||||
@@ -325,10 +324,10 @@ export default function SignUp() {
|
||||
className="mt-2 mb-6"
|
||||
/>
|
||||
</div>
|
||||
{codeError && <Error text={t("auth:step2-code-error")} />}
|
||||
{codeError && <Error text={t("signup:step2-code-error")} />}
|
||||
<div className="flex max-w-min flex-col items-center justify-center md:p-2 max-h-24 max-w-md mx-auto text-lg px-4 mt-4 mb-2">
|
||||
<Button
|
||||
text={t("auth:verify")}
|
||||
text={t("signup:verify")}
|
||||
onButtonPressed={incrementStep}
|
||||
size="lg"
|
||||
/>
|
||||
@@ -342,7 +341,7 @@ export default function SignUp() {
|
||||
</button>
|
||||
</Link> */}
|
||||
<p className="text-sm text-gray-500 pb-2">
|
||||
{t("auth:step2-spam-alert")}
|
||||
{t("signup:step2-spam-alert")}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -352,7 +351,7 @@ export default function SignUp() {
|
||||
const step3 = (
|
||||
<div className="bg-bunker w-max mx-auto h-7/12 py-10 px-8 rounded-xl drop-shadow-xl mb-36 md:mb-16">
|
||||
<p className="text-4xl font-bold flex justify-center mb-6 text-gray-400 mx-8 md:mx-16 text-transparent bg-clip-text bg-gradient-to-br from-sky-400 to-primary">
|
||||
{t("auth:step3-message")}
|
||||
{t("signup:step3-message")}
|
||||
</p>
|
||||
<div className="relative z-0 flex items-center justify-end w-full md:p-2 rounded-lg max-h-24">
|
||||
<InputField
|
||||
@@ -382,7 +381,7 @@ export default function SignUp() {
|
||||
</div>
|
||||
<div className="mt-2 flex flex-col items-center justify-center w-full md:p-2 rounded-lg max-h-60">
|
||||
<InputField
|
||||
label={t("common:password")}
|
||||
label={t("form-password:password")}
|
||||
onChangeHandler={(password) => {
|
||||
setPassword(password);
|
||||
passwordCheck(
|
||||
@@ -405,7 +404,7 @@ export default function SignUp() {
|
||||
passwordErrorNumber ? (
|
||||
<div className="w-full mt-4 bg-white/5 px-2 flex flex-col items-start py-2 rounded-md">
|
||||
<div className={`text-gray-400 text-sm mb-1`}>
|
||||
{t("auth:password-validate")}
|
||||
{t("form-password:validate-base")}
|
||||
</div>
|
||||
<div className="flex flex-row justify-start items-center ml-1">
|
||||
{passwordErrorLength ? (
|
||||
@@ -424,7 +423,7 @@ export default function SignUp() {
|
||||
passwordErrorLength ? "text-gray-400" : "text-gray-600"
|
||||
} text-sm`}
|
||||
>
|
||||
{t("auth:password-validate-length")}
|
||||
{t("form-password:validate-length")}
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-row justify-start items-center ml-1">
|
||||
@@ -444,7 +443,7 @@ export default function SignUp() {
|
||||
passwordErrorLowerCase ? "text-gray-400" : "text-gray-600"
|
||||
} text-sm`}
|
||||
>
|
||||
{t("auth:password-validate-case")}
|
||||
{t("form-password:validate-case")}
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-row justify-start items-center ml-1">
|
||||
@@ -464,7 +463,7 @@ export default function SignUp() {
|
||||
passwordErrorNumber ? "text-gray-400" : "text-gray-600"
|
||||
} text-sm`}
|
||||
>
|
||||
{t("auth:password-validate-number")}
|
||||
{t("form-password:validate-number")}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -531,14 +530,11 @@ export default function SignUp() {
|
||||
return (
|
||||
<div className="bg-bunker-800 h-screen flex flex-col items-center justify-center">
|
||||
<Head>
|
||||
<title>{t("auth:meta.signup.title")}</title>
|
||||
<title>{t("common:head-title", { title: t("signup:title") })}</title>
|
||||
<link rel="icon" href="/infisical.ico" />
|
||||
<meta property="og:image" content="/images/message.png" />
|
||||
<meta property="og:title" content={t("auth:meta.signup.og-title")} />
|
||||
<meta
|
||||
name="og:description"
|
||||
content={t("auth:meta.signup.og-description")}
|
||||
/>
|
||||
<meta property="og:title" content={t("signup:og-title")} />
|
||||
<meta name="og:description" content={t("signup:og-description")} />
|
||||
</Head>
|
||||
<div className="flex flex-col justify-center items-center">
|
||||
<Link href="/">
|
||||
|
||||
@@ -127,19 +127,21 @@ export default function Users() {
|
||||
return userList ? (
|
||||
<div className="bg-bunker-800 md:h-screen flex flex-col justify-start">
|
||||
<Head>
|
||||
<title>{t("settings:meta.members.head-title")}</title>
|
||||
<title>
|
||||
{t("common:head-title", { title: t("settings-members:title") })}
|
||||
</title>
|
||||
<link rel="icon" href="/infisical.ico" />
|
||||
</Head>
|
||||
<NavHeader
|
||||
pageName={t("settings:meta.members.title")}
|
||||
pageName={t("settings-members:title")}
|
||||
isProjectRelated={true}
|
||||
/>
|
||||
<div className="flex flex-col justify-start items-start px-6 py-6 pb-4 text-3xl">
|
||||
<p className="font-semibold mr-4 text-white">
|
||||
{t("settings:meta.members.title")}
|
||||
{t("settings-members:title")}
|
||||
</p>
|
||||
<p className="mr-4 text-base text-gray-400">
|
||||
{t("settings:meta.members.description")}
|
||||
{t("settings-members:description")}
|
||||
</p>
|
||||
</div>
|
||||
<AddProjectMemberDialog
|
||||
@@ -167,12 +169,12 @@ export default function Users() {
|
||||
className="pl-2 text-gray-400 rounded-r-md bg-white/5 w-full h-full outline-none"
|
||||
value={searchUsers}
|
||||
onChange={(e) => setSearchUsers(e.target.value)}
|
||||
placeholder={t("settings:search-members")}
|
||||
placeholder={t("section-members:search-members")}
|
||||
/>
|
||||
</div>
|
||||
<div className="mt-2 ml-2 min-w-max flex flex-row items-start justify-start mr-4">
|
||||
<Button
|
||||
text={t("settings:add-member")}
|
||||
text={t("section-members:add-member")}
|
||||
onButtonPressed={openAddModal}
|
||||
color="mineshaft"
|
||||
size="md"
|
||||
|
||||
Reference in New Issue
Block a user