chore(frontend): fixed all eslint errors

This commit is contained in:
akhilmhdh
2023-01-17 21:06:14 +05:30
parent 9f82e2d836
commit cf7834bfc3
184 changed files with 6255 additions and 6117 deletions
+28 -40
View File
@@ -1,11 +1,10 @@
import { useEffect, useState } from 'react';
import Head from 'next/head';
import { useTranslation } from 'next-i18next';
import Plan from '~/components/billing/Plan';
import NavHeader from '~/components/navigation/NavHeader';
import { STRIPE_PRODUCT_PRO, STRIPE_PRODUCT_STARTER } from '~/utilities/config';
import { getTranslatedServerSideProps } from '~/utilities/withTranslateProps';
import Plan from '@app/components/billing/Plan';
import NavHeader from '@app/components/navigation/NavHeader';
import { STRIPE_PRODUCT_PRO, STRIPE_PRODUCT_STARTER } from '@app/components/utilities/config';
import { getTranslatedServerSideProps } from '@app/components/utilities/withTranslateProps';
import getOrganizationSubscriptions from '../../api/organization/GetOrgSubscription';
import getOrganizationUsers from '../../api/organization/GetOrgUsers';
@@ -26,7 +25,7 @@ export default function SettingsBilling() {
subtext: t('billing:starter.subtext')!,
buttonTextMain: t('billing:downgrade')!,
buttonTextSecondary: t('billing:learn-more')!,
current: currentPlan == STRIPE_PRODUCT_STARTER,
current: currentPlan === STRIPE_PRODUCT_STARTER
},
{
key: 2,
@@ -37,7 +36,7 @@ export default function SettingsBilling() {
text: t('billing:professional.text')!,
buttonTextMain: t('billing:upgrade')!,
buttonTextSecondary: t('billing:learn-more')!,
current: currentPlan == STRIPE_PRODUCT_PRO,
current: currentPlan === STRIPE_PRODUCT_PRO
},
{
key: 3,
@@ -46,61 +45,53 @@ export default function SettingsBilling() {
text: t('billing:enterprise.text')!,
buttonTextMain: t('billing:schedule-demo')!,
buttonTextSecondary: t('billing:learn-more')!,
current: false,
},
current: false
}
];
useEffect(() => {
(async () => {
const orgId = localStorage.getItem('orgData.id') as string;
const subscriptions = await getOrganizationSubscriptions({
orgId,
orgId
});
setCurrentPlan(subscriptions.data[0].plan.id);
const orgUsers = await getOrganizationUsers({
orgId,
orgId
});
setNumUsers(orgUsers.length);
})();
}, []);
return (
<div className='bg-bunker-800 max-h-screen flex flex-col justify-between text-white'>
<div className="bg-bunker-800 max-h-screen flex flex-col justify-between text-white">
<Head>
<title>{t('common:head-title', { title: t('billing:title') })}</title>
<link rel='icon' href='/infisical.ico' />
<link rel="icon" href="/infisical.ico" />
</Head>
<div className='flex flex-row'>
<div className='w-full max-h-screen pb-2 overflow-y-auto'>
<div className="flex flex-row">
<div className="w-full max-h-screen pb-2 overflow-y-auto">
<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'>
{t('billing:title')}
</p>
<p className='font-normal mr-4 text-gray-400 text-base'>
{t('billing:description')}
</p>
<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('billing:title')}</p>
<p className="font-normal mr-4 text-gray-400 text-base">{t('billing:description')}</p>
</div>
</div>
<div className='flex flex-col ml-6 text-mineshaft-50'>
<p className='text-xl font-semibold'>{t('billing:subscription')}</p>
<div className='flex flex-row mt-4 overflow-x-auto'>
<div className="flex flex-col ml-6 text-mineshaft-50">
<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'>
{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>
<p className='text-gray-300'>
{numUsers > 1
? 'Organization members'
: 'Organization member'}
<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 justify-center items-center flex flex-col">
<p className="text-6xl font-bold">{numUsers}</p>
<p className="text-gray-300">
{numUsers > 1 ? 'Organization members' : 'Organization member'}
</p>
</div>
{/* <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">
@@ -117,7 +108,4 @@ export default function SettingsBilling() {
SettingsBilling.requireAuth = true;
export const getServerSideProps = getTranslatedServerSideProps([
'settings',
'billing',
]);
export const getServerSideProps = getTranslatedServerSideProps(['settings', 'billing']);
+98 -124
View File
@@ -1,24 +1,19 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
import { useEffect, useState } from 'react';
import Head from 'next/head';
import { useRouter } from 'next/router';
import { useTranslation } from 'next-i18next';
import {
faMagnifyingGlass,
faPlus,
faX,
} from '@fortawesome/free-solid-svg-icons';
import { faCheck } from '@fortawesome/free-solid-svg-icons';
import Button from '@app/components/basic/buttons/Button';
import AddIncidentContactDialog from '@app/components/basic/dialog/AddIncidentContactDialog';
import AddUserDialog from '@app/components/basic/dialog/AddUserDialog';
import InputField from '@app/components/basic/InputField';
import UserTable from '@app/components/basic/table/UserTable';
import NavHeader from '@app/components/navigation/NavHeader';
import guidGenerator from '@app/components/utilities/randomId';
import { getTranslatedServerSideProps } from '@app/components/utilities/withTranslateProps';
import { faCheck, faMagnifyingGlass, faPlus, faX } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import Button from '~/components/basic/buttons/Button';
import AddIncidentContactDialog from '~/components/basic/dialog/AddIncidentContactDialog';
import AddUserDialog from '~/components/basic/dialog/AddUserDialog';
import InputField from '~/components/basic/InputField';
import UserTable from '~/components/basic/table/UserTable';
import NavHeader from '~/components/navigation/NavHeader';
import guidGenerator from '~/utilities/randomId';
import { getTranslatedServerSideProps } from '~/utilities/withTranslateProps';
import addUserToOrg from '../../api/organization/addUserToOrg';
import deleteIncidentContact from '../../api/organization/deleteIncidentContact';
import getIncidentContacts from '../../api/organization/getIncidentContacts';
@@ -37,11 +32,8 @@ export default function SettingsOrg() {
const [emailUser, setEmailUser] = useState('');
const [workspaceToBeDeletedName, setWorkspaceToBeDeletedName] = useState('');
const [searchUsers, setSearchUsers] = useState('');
const [isAddIncidentContactOpen, setIsAddIncidentContactOpen] =
useState(false);
const [isAddUserOpen, setIsAddUserOpen] = useState(
router.asPath.split('?')[1] == 'invite'
);
const [isAddIncidentContactOpen, setIsAddIncidentContactOpen] = useState(false);
const [isAddUserOpen, setIsAddUserOpen] = useState(router.asPath.split('?')[1] === 'invite');
const [incidentContacts, setIncidentContacts] = useState<string[]>([]);
const [searchIncidentContact, setSearchIncidentContact] = useState('');
const [userList, setUserList] = useState<any[]>([]);
@@ -57,7 +49,7 @@ export default function SettingsOrg() {
(async () => {
const orgId = localStorage.getItem('orgData.id') as string;
const org = await getOrganization({
orgId,
orgId
});
setOrgName(org.name);
@@ -65,33 +57,31 @@ export default function SettingsOrg() {
localStorage.getItem('orgData.id') as string
);
setIncidentContacts(
incidentContactsData?.map((contact) => contact.email)
);
setIncidentContacts(incidentContactsData?.map((contact) => contact.email));
const user = await getUser();
setPersonalEmail(user.email);
const orgUsers = await getOrganizationUsers({
orgId,
orgId
});
setUserList(
orgUsers.map((user) => ({
orgUsers.map((orgUser) => ({
key: guidGenerator(),
firstName: user.user?.firstName,
lastName: user.user?.lastName,
email: user.user?.email == null ? user.inviteEmail : user.user?.email,
role: user?.role,
status: user?.status,
userId: user.user?._id,
membershipId: user._id,
publicKey: user.user?.publicKey,
firstName: orgUser.user?.firstName,
lastName: orgUser.user?.lastName,
email: orgUser.user?.email === null ? orgUser.inviteEmail : orgUser.user?.email,
role: orgUser?.role,
status: orgUser?.status,
userId: orgUser.user?._id,
membershipId: orgUser._id,
publicKey: orgUser.user?.publicKey
}))
);
const subscriptions = await getOrganizationSubscriptions({
orgId,
orgId
});
setCurrentPlan(subscriptions.data[0].plan.product);
})();
@@ -107,37 +97,32 @@ export default function SettingsOrg() {
setButtonReady(false);
};
function closeAddUserModal() {
const closeAddUserModal = () => {
setIsAddUserOpen(false);
}
};
function closeAddIncidentContactModal() {
const closeAddIncidentContactModal = () => {
setIsAddIncidentContactOpen(false);
}
};
function openAddUserModal() {
const openAddUserModal = () => {
setIsAddUserOpen(true);
}
};
function openAddIncidentContactModal() {
const openAddIncidentContactModal = () => {
setIsAddIncidentContactOpen(true);
}
};
async function submitAddUserModal(email: string) {
const submitAddUserModal = async (newUserEmail: string) => {
await addUserToOrg(email, localStorage.getItem('orgData.id') as string);
setEmail('');
setIsAddUserOpen(false);
router.reload();
}
};
const deleteIncidentContactFully = (incidentContact: string) => {
setIncidentContacts(
incidentContacts.filter((contact) => contact != incidentContact)
);
deleteIncidentContact(
localStorage.getItem('orgData.id') as string,
incidentContact
);
setIncidentContacts(incidentContacts.filter((contact) => contact !== incidentContact));
deleteIncidentContact(localStorage.getItem('orgData.id') as string, incidentContact);
};
/**
@@ -151,69 +136,64 @@ export default function SettingsOrg() {
if (userWorkspaces.length > 1) {
if (
userWorkspaces.filter((workspace) => workspace._id == workspaceId)[0]
.name == workspaceToBeDeletedName
userWorkspaces.filter((workspace) => workspace._id === workspaceId)[0].name ===
workspaceToBeDeletedName
) {
await deleteWorkspace(workspaceId);
const userWorkspaces = await getWorkspaces();
router.push('/dashboard/' + userWorkspaces[0]._id);
const ws = await getWorkspaces();
router.push(`/dashboard/${ws[0]._id}`);
}
}
};
return (
<div className='bg-bunker-800 max-h-screen flex flex-col justify-between text-white'>
<div className="bg-bunker-800 max-h-screen flex flex-col justify-between text-white">
<Head>
<title>
{t('common:head-title', { title: t('settings-org:title') })}
</title>
<link rel='icon' href='/infisical.ico' />
<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'>
<div className="flex flex-row">
<div className="w-full max-h-screen pb-2 overflow-y-auto">
<NavHeader pageName={t('settings-org:title')} />
<AddIncidentContactDialog
isOpen={isAddIncidentContactOpen}
closeModal={closeAddIncidentContactModal}
workspaceId={workspaceId}
incidentContacts={incidentContacts}
setIncidentContacts={setIncidentContacts}
/>
<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-org:title')}
</p>
<p className='font-normal mr-4 text-gray-400 text-base'>
<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-org:title')}</p>
<p className="font-normal mr-4 text-gray-400 text-base">
{t('settings-org:description')}
</p>
</div>
</div>
<div className='flex flex-col ml-6 text-mineshaft-50 mr-6 max-w-5xl'>
<div className='flex flex-col'>
<div className='min-w-md mt-2 flex flex-col items-end pb-4'>
<div className='bg-white/5 rounded-md px-6 py-4 flex flex-col items-start w-full mb-6'>
<div className='max-h-28 w-full max-w-md mr-auto'>
<p className='font-semibold mr-4 text-gray-200 text-xl mb-2'>
<div className="flex flex-col ml-6 text-mineshaft-50 mr-6 max-w-5xl">
<div className="flex flex-col">
<div className="min-w-md mt-2 flex flex-col items-end pb-4">
<div className="bg-white/5 rounded-md px-6 py-4 flex flex-col items-start w-full mb-6">
<div className="max-h-28 w-full max-w-md mr-auto">
<p className="font-semibold mr-4 text-gray-200 text-xl mb-2">
{t('common:display-name')}
</p>
<InputField
label=''
label=""
// label="Organization Name"
onChangeHandler={modifyOrgName}
type='varName'
type="varName"
value={orgName}
placeholder=''
placeholder=""
isRequired
/>
</div>
<div className='flex justify-start w-full'>
<div className={`flex justify-start max-w-sm mt-4 mb-2`}>
<div className="flex justify-start w-full">
<div className="flex justify-start max-w-sm mt-4 mb-2">
<Button
text={t('common:save-changes') as string}
onButtonPressed={() => submitChanges(orgName)}
color='mineshaft'
size='md'
color="mineshaft"
size="md"
active={buttonReady}
iconDisabled={faCheck}
textDisabled={t('common:saved') as string}
@@ -223,11 +203,11 @@ export default function SettingsOrg() {
</div>
</div>
</div>
<div className='bg-white/5 rounded-md px-6 pt-6 pb-2 flex flex-col items-start w-full mb-6'>
<p className='font-semibold mr-4 text-white text-xl'>
<div className="bg-white/5 rounded-md px-6 pt-6 pb-2 flex flex-col items-start w-full mb-6">
<p className="font-semibold mr-4 text-white text-xl">
{t('section-members:org-members')}
</p>
<p className='mr-4 text-gray-400 mt-2 mb-2'>
<p className="mr-4 text-gray-400 mt-2 mb-2">
{t('section-members:org-members-description')}
</p>
<AddUserDialog
@@ -235,113 +215,107 @@ export default function SettingsOrg() {
closeModal={closeAddUserModal}
submitModal={submitAddUserModal}
email={emailUser}
workspaceId={workspaceId}
setEmail={setEmailUser}
currentPlan={currentPlan}
orgName={orgName}
/>
{/* <DeleteUserDialog isOpen={isDeleteOpen} closeModal={closeDeleteModal} submitModal={deleteMembership} userIdToBeDeleted={userIdToBeDeleted}/> */}
<div className='pb-1 w-full flex flex-row items-start max-w-6xl'>
<div className='h-10 w-full bg-white/5 mt-2 flex items-center rounded-md flex-row '>
<div className="pb-1 w-full flex flex-row items-start max-w-6xl">
<div className="h-10 w-full bg-white/5 mt-2 flex items-center rounded-md flex-row ">
<FontAwesomeIcon
className='bg-white/5 rounded-l-md py-3 pl-4 pr-2 text-gray-400'
className="bg-white/5 rounded-l-md py-3 pl-4 pr-2 text-gray-400"
icon={faMagnifyingGlass}
/>
<input
className='pl-2 text-gray-400 rounded-r-md bg-white/5 w-full h-full outline-none'
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('section-members:search-members') as string}
/>
</div>
<div className='mt-2 ml-2 min-w-max flex flex-row items-start justify-start'>
<div className="mt-2 ml-2 min-w-max flex flex-row items-start justify-start">
<Button
text={t('section-members:add-member') as string}
onButtonPressed={openAddUserModal}
color='mineshaft'
size='md'
color="mineshaft"
size="md"
icon={faPlus}
/>
</div>
</div>
{userList && (
<div className='overflow-y-auto max-w-6xl w-full'>
<div className="overflow-y-auto max-w-6xl w-full">
<UserTable
userData={userList}
changeData={setUserList}
myUser={personalEmail}
filter={searchUsers.toLowerCase()}
resendInvite={submitAddUserModal}
isOrg={true}
isOrg
// onClick={openDeleteModal}
// deleteUser={deleteMembership}
// setUserIdToBeDeleted={setUserIdToBeDeleted}
className='w-full'
/>
</div>
)}
</div>
<div className='bg-white/5 rounded-md px-6 pt-6 pb-6 flex flex-col items-start w-full mb-6 mt-4'>
<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'>
<div className="bg-white/5 rounded-md px-6 pt-6 pb-6 flex flex-col items-start w-full mb-6 mt-4">
<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('section-incident:incident-contacts')}
</p>
<p className='text-xs text-gray-500 mb-2 min-w-max'>
<p className="text-xs text-gray-500 mb-2 min-w-max">
{t('section-incident:incident-contacts-description')}
</p>
</div>
<div className='mt-4 mb-2 min-w-max flex flex-row items-end justify-center'>
<div className="mt-4 mb-2 min-w-max flex flex-row items-end justify-center">
<Button
text={t('section-incident:add-contact') as string}
onButtonPressed={openAddIncidentContactModal}
color='mineshaft'
size='md'
color="mineshaft"
size="md"
icon={faPlus}
/>
</div>
</div>
<div className='h-12 w-full max-w-5xl bg-white/5 mt-2 flex items-center rounded-t-md flwex-row'>
<div className="h-12 w-full max-w-5xl bg-white/5 mt-2 flex items-center rounded-t-md flwex-row">
<FontAwesomeIcon
className='bg-white/5 rounded-tl-md py-4 pl-4 pr-2 text-gray-400'
className="bg-white/5 rounded-tl-md py-4 pl-4 pr-2 text-gray-400"
icon={faMagnifyingGlass}
/>
<input
className='pl-2 text-gray-400 rounded-tr-md bg-white/5 w-full h-full outline-none'
className="pl-2 text-gray-400 rounded-tr-md bg-white/5 w-full h-full outline-none"
value={searchIncidentContact}
onChange={(e) => setSearchIncidentContact(e.target.value)}
placeholder={t('common:search') as string}
/>
</div>
{incidentContacts?.filter((email) =>
email.includes(searchIncidentContact)
{incidentContacts?.filter((incidentEmail) =>
incidentEmail.includes(searchIncidentContact)
).length > 0 ? (
incidentContacts
.filter((email) => email.includes(searchIncidentContact))
.filter((incidentEmail) => incidentEmail.includes(searchIncidentContact))
.map((contact) => (
<div
key={guidGenerator()}
className='flex flex-row items-center justify-between max-w-5xl px-4 py-3 hover:bg-white/5 border-t border-gray-600 w-full'
className="flex flex-row items-center justify-between max-w-5xl px-4 py-3 hover:bg-white/5 border-t border-gray-600 w-full"
>
<p className='text-gray-300'>{contact}</p>
<div className='opacity-50 hover:opacity-100 duration-200'>
<p className="text-gray-300">{contact}</p>
<div className="opacity-50 hover:opacity-100 duration-200">
<Button
onButtonPressed={() =>
deleteIncidentContactFully(contact)
}
color='red'
size='icon-sm'
onButtonPressed={() => deleteIncidentContactFully(contact)}
color="red"
size="icon-sm"
icon={faX}
/>
</div>
</div>
))
) : (
<div className='w-full flex flex-row justify-center mt-6 max-w-4xl ml-6'>
<p className='text-gray-400'>
{t('section-incident:no-incident-contacts')}
</p>
<div className="w-full flex flex-row justify-center mt-6 max-w-4xl ml-6">
<p className="text-gray-400">{t('section-incident:no-incident-contacts')}</p>
</div>
)}
</div>
@@ -394,5 +368,5 @@ export const getServerSideProps = getTranslatedServerSideProps([
'settings',
'settings-org',
'section-incident',
'section-members',
'section-members'
]);
+90 -139
View File
@@ -1,23 +1,22 @@
import { useEffect, useState } from "react";
import Head from "next/head";
import { useRouter } from "next/router";
import { useTranslation } from "next-i18next";
import { faCheck, faPlus, faX } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { useEffect, useState } from 'react';
import Head from 'next/head';
import { useRouter } from 'next/router';
import { useTranslation } from 'next-i18next';
import Button from '@app/components/basic/buttons/Button';
import InputField from '@app/components/basic/InputField';
import ListBox from '@app/components/basic/Listbox';
import ApiKeyTable from '@app/components/basic/table/ApiKeyTable';
import NavHeader from '@app/components/navigation/NavHeader';
import passwordCheck from '@app/components/utilities/checks/PasswordCheck';
import changePassword from '@app/components/utilities/cryptography/changePassword';
import issueBackupKey from '@app/components/utilities/cryptography/issueBackupKey';
import { getTranslatedServerSideProps } from '@app/components/utilities/withTranslateProps';
import { faCheck, faPlus, faX } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import Button from "~/components/basic/buttons/Button";
import InputField from "~/components/basic/InputField";
import ListBox from "~/components/basic/Listbox";
import ApiKeyTable from "~/components/basic/table/ApiKeyTable";
import NavHeader from "~/components/navigation/NavHeader";
import changePassword from "~/components/utilities/cryptography/changePassword";
import issueBackupKey from "~/components/utilities/cryptography/issueBackupKey";
import passwordCheck from "~/utilities/checks/PasswordCheck";
import { getTranslatedServerSideProps } from "~/utilities/withTranslateProps";
import AddApiKeyDialog from "../../../components/basic/dialog/AddApiKeyDialog";
import getAPIKeys from "../../api/apiKey/getAPIKeys";
import getUser from "../../api/user/getUser";
import AddApiKeyDialog from '../../../components/basic/dialog/AddApiKeyDialog';
import getAPIKeys from '../../api/apiKey/getAPIKeys';
import getUser from '../../api/user/getUser';
export default function PersonalSettings() {
const [personalEmail, setPersonalEmail] = useState('');
@@ -32,7 +31,7 @@ export default function PersonalSettings() {
const [passwordChanged, setPasswordChanged] = useState(false);
const [backupKeyIssued, setBackupKeyIssued] = useState(false);
const [backupKeyError, setBackupKeyError] = useState(false);
const [isAddApiKeyDialogOpen, setIsAddApiKeyDialogOpen] = useState(false)
const [isAddApiKeyDialogOpen, setIsAddApiKeyDialogOpen] = useState(false);
const [apiKeys, setApiKeys] = useState<any[]>([]);
const { t } = useTranslation();
@@ -48,16 +47,14 @@ export default function PersonalSettings() {
const load = async () => {
try {
const user = await getUser();
setApiKeys(
await getAPIKeys()
);
setApiKeys(await getAPIKeys());
setPersonalEmail(user.email);
setPersonalName(user.firstName + " " + user.lastName);
setPersonalName(`${user.firstName} ${user.lastName}`);
} catch (err) {
console.error(err);
}
}
};
load();
}, []);
@@ -66,12 +63,10 @@ export default function PersonalSettings() {
};
return (
<div className='bg-bunker-800 max-h-screen flex flex-col justify-between text-white'>
<div className="bg-bunker-800 max-h-screen flex flex-col justify-between text-white">
<Head>
<title>
{t('common:head-title', { title: t('settings-personal:title') })}
</title>
<link rel='icon' href='/infisical.ico' />
<title>{t('common:head-title', { title: t('settings-personal:title') })}</title>
<link rel="icon" href="/infisical.ico" />
</Head>
<AddApiKeyDialog
isOpen={isAddApiKeyDialogOpen}
@@ -81,16 +76,11 @@ export default function PersonalSettings() {
/>
<div className="flex flex-row">
<div className="w-full max-h-screen pb-2 overflow-y-auto">
<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'>
{t('settings-personal:title')}
</p>
<p className='font-normal mr-4 text-gray-400 text-base'>
<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">{t('settings-personal:title')}</p>
<p className="font-normal mr-4 text-gray-400 text-base">
{t('settings-personal:description')}
</p>
</div>
@@ -98,9 +88,9 @@ export default function PersonalSettings() {
<div className="flex flex-col ml-6 text-mineshaft-50 mr-6 max-w-5xl">
<div className="bg-white/5 rounded-md px-6 pt-6 pb-6 flex flex-col items-start w-full mb-6 mt-4">
<p className="text-xl font-semibold self-start">
{t("settings-personal:change-language")}
{t('settings-personal:change-language')}
</p>
<div className='max-h-28 w-ful mt-4'>
<div className="max-h-28 w-ful mt-4">
<ListBox
selected={lang}
onChange={setLanguage}
@@ -113,15 +103,15 @@ export default function PersonalSettings() {
<div className="flex flex-row justify-between w-full">
<div className="flex flex-col w-full">
<p className="text-xl font-semibold mb-3">
{t("settings-personal:api-keys.title")}
{t('settings-personal:api-keys.title')}
</p>
<p className="text-sm text-gray-400">
{t("settings-personal:api-keys.description")}
{t('settings-personal:api-keys.description')}
</p>
</div>
<div className="w-48 mt-2">
<Button
text={String(t("settings-personal:api-keys.add-new"))}
text={String(t('settings-personal:api-keys.add-new'))}
onButtonPressed={() => {
setIsAddApiKeyDialogOpen(true);
}}
@@ -131,35 +121,32 @@ export default function PersonalSettings() {
/>
</div>
</div>
<ApiKeyTable
data={apiKeys}
setApiKeys={setApiKeys as any}
/>
<ApiKeyTable data={apiKeys} setApiKeys={setApiKeys as any} />
</div>
<div className='bg-white/5 rounded-md px-6 pt-5 pb-6 flex flex-col items-start w-full mb-6'>
<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'>
<div className="bg-white/5 rounded-md px-6 pt-5 pb-6 flex flex-col items-start w-full mb-6">
<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('section-password:change')}
</p>
</div>
</div>
<div className='max-w-xl w-full'>
<div className="max-w-xl w-full">
<InputField
label={t('section-password:current') as string}
onChangeHandler={(password) => {
setCurrentPassword(password);
}}
type='password'
type="password"
value={currentPassword}
isRequired
error={currentPasswordError}
errorText={t('section-password:current-wrong') as string}
autoComplete='current-password'
id='current-password'
autoComplete="current-password"
id="current-password"
/>
<div className='py-2'></div>
<div className="py-2" />
<InputField
label={t('section-password:new') as string}
onChangeHandler={(password) => {
@@ -169,39 +156,27 @@ export default function PersonalSettings() {
setPasswordErrorLength,
setPasswordErrorNumber,
setPasswordErrorLowerCase,
errorCheck: false,
errorCheck: false
});
}}
type='password'
type="password"
value={newPassword}
isRequired
error={
passwordErrorLength &&
passwordErrorLowerCase &&
passwordErrorNumber
}
autoComplete='new-password'
id='new-password'
error={passwordErrorLength && passwordErrorLowerCase && passwordErrorNumber}
autoComplete="new-password"
id="new-password"
/>
</div>
{passwordErrorLength ||
passwordErrorLowerCase ||
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`}>
{passwordErrorLength || passwordErrorLowerCase || 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">
{t('section-password:validate-base')}
</div>
<div className='flex flex-row justify-start items-center ml-1'>
<div className="flex flex-row justify-start items-center ml-1">
{passwordErrorLength ? (
<FontAwesomeIcon
icon={faX}
className='text-md text-red mr-2.5'
/>
<FontAwesomeIcon icon={faX} className="text-md text-red mr-2.5" />
) : (
<FontAwesomeIcon
icon={faCheck}
className='text-md text-primary mr-2'
/>
<FontAwesomeIcon icon={faCheck} className="text-md text-primary mr-2" />
)}
<div
className={`${
@@ -211,39 +186,25 @@ export default function PersonalSettings() {
{t('section-password:validate-length')}
</div>
</div>
<div className='flex flex-row justify-start items-center ml-1'>
<div className="flex flex-row justify-start items-center ml-1">
{passwordErrorLowerCase ? (
<FontAwesomeIcon
icon={faX}
className='text-md text-red mr-2.5'
/>
<FontAwesomeIcon icon={faX} className="text-md text-red mr-2.5" />
) : (
<FontAwesomeIcon
icon={faCheck}
className='text-md text-primary mr-2'
/>
<FontAwesomeIcon icon={faCheck} className="text-md text-primary mr-2" />
)}
<div
className={`${
passwordErrorLowerCase
? 'text-gray-400'
: 'text-gray-600'
passwordErrorLowerCase ? 'text-gray-400' : 'text-gray-600'
} text-sm`}
>
{t('section-password:validate-case')}
</div>
</div>
<div className='flex flex-row justify-start items-center ml-1'>
<div className="flex flex-row justify-start items-center ml-1">
{passwordErrorNumber ? (
<FontAwesomeIcon
icon={faX}
className='text-md text-red mr-2.5'
/>
<FontAwesomeIcon icon={faX} className="text-md text-red mr-2.5" />
) : (
<FontAwesomeIcon
icon={faCheck}
className='text-md text-primary mr-2'
/>
<FontAwesomeIcon icon={faCheck} className="text-md text-primary mr-2" />
)}
<div
className={`${
@@ -255,17 +216,13 @@ export default function PersonalSettings() {
</div>
</div>
) : (
<div className='py-2'></div>
<div className="py-2" />
)}
<div className='flex flex-row items-center mt-3 w-52 pr-3'>
<div className="flex flex-row items-center mt-3 w-52 pr-3">
<Button
text={t('section-password:change') as string}
onButtonPressed={() => {
if (
!passwordErrorLength &&
!passwordErrorLowerCase &&
!passwordErrorNumber
) {
if (!passwordErrorLength && !passwordErrorLowerCase && !passwordErrorNumber) {
changePassword(
personalEmail,
currentPassword,
@@ -277,16 +234,12 @@ export default function PersonalSettings() {
);
}
}}
color='mineshaft'
size='md'
color="mineshaft"
size="md"
active={
newPassword != '' &&
currentPassword != '' &&
!(
passwordErrorLength ||
passwordErrorLowerCase ||
passwordErrorNumber
)
newPassword !== '' &&
currentPassword !== '' &&
!(passwordErrorLength || passwordErrorLowerCase || passwordErrorNumber)
}
textDisabled={t('section-password:change') as string}
/>
@@ -299,34 +252,34 @@ export default function PersonalSettings() {
</div>
</div>
<div className="bg-white/5 rounded-md px-6 pt-5 pb-6 mt-2 flex flex-col items-start flex flex-col items-start w-full mb-6">
<div className="bg-white/5 rounded-md px-6 pt-5 pb-6 mt-2 flex flex-col items-start w-full mb-6">
<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-personal:emergency.name")}
{t('settings-personal:emergency.name')}
</p>
<p className='text-sm text-mineshaft-300 min-w-max'>
<p className="text-sm text-mineshaft-300 min-w-max">
{t('settings-personal:emergency.text1')}
</p>
<p className='text-sm text-mineshaft-300 mb-5 min-w-max'>
<p className="text-sm text-mineshaft-300 mb-5 min-w-max">
{t('settings-personal:emergency.text2')}
</p>
</div>
</div>
<div className='w-full max-w-xl mb-4'>
<div className="w-full max-w-xl mb-4">
<InputField
label={t('section-password:current') as string}
onChangeHandler={setBackupPassword}
type='password'
type="password"
value={backupPassword}
isRequired
error={backupKeyError}
errorText={t('section-password:current-wrong') as string}
autoComplete='current-password'
id='current-password'
autoComplete="current-password"
id="current-password"
/>
</div>
<div className='flex flex-row items-center mt-3 w-60'>
<div className="flex flex-row items-center mt-3 w-60">
<Button
text={t('settings-personal:emergency.download') as string}
onButtonPressed={() => {
@@ -335,15 +288,13 @@ export default function PersonalSettings() {
password: backupPassword,
personalName,
setBackupKeyError,
setBackupKeyIssued,
setBackupKeyIssued
});
}}
color='mineshaft'
size='md'
active={backupPassword != ''}
textDisabled={
t('settings-personal:emergency.download') as string
}
color="mineshaft"
size="md"
active={backupPassword !== ''}
textDisabled={t('settings-personal:emergency.download') as string}
/>
<FontAwesomeIcon
icon={faCheck}
@@ -363,8 +314,8 @@ export default function PersonalSettings() {
PersonalSettings.requireAuth = true;
export const getServerSideProps = getTranslatedServerSideProps([
"settings",
"settings-personal",
"section-password",
"section-api-key"
'settings',
'settings-personal',
'section-password',
'section-api-key'
]);
+90 -115
View File
@@ -2,19 +2,18 @@ import { useEffect, useState } from 'react';
import Head from 'next/head';
import { useRouter } from 'next/router';
import { useTranslation } from 'next-i18next';
import Button from '@app/components/basic/buttons/Button';
import AddServiceTokenDialog from '@app/components/basic/dialog/AddServiceTokenDialog';
import InputField from '@app/components/basic/InputField';
import EnvironmentTable from '@app/components/basic/table/EnvironmentsTable';
import ServiceTokenTable from '@app/components/basic/table/ServiceTokenTable';
import NavHeader from '@app/components/navigation/NavHeader';
import { getTranslatedServerSideProps } from '@app/components/utilities/withTranslateProps';
import deleteEnvironment from '@app/pages/api/environments/deleteEnvironment';
import updateEnvironment from '@app/pages/api/environments/updateEnvironment';
import { faCheck, faCopy, faPlus } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import Button from '~/components/basic/buttons/Button';
import AddServiceTokenDialog from '~/components/basic/dialog/AddServiceTokenDialog';
import InputField from '~/components/basic/InputField';
import EnvironmentTable from '~/components/basic/table/EnvironmentsTable';
import ServiceTokenTable from '~/components/basic/table/ServiceTokenTable';
import NavHeader from '~/components/navigation/NavHeader';
import deleteEnvironment from '~/pages/api/environments/deleteEnvironment';
import updateEnvironment from '~/pages/api/environments/updateEnvironment';
import { getTranslatedServerSideProps } from '~/utilities/withTranslateProps';
import createEnvironment from '../../api/environments/createEnvironment';
import getServiceTokens from '../../api/serviceToken/getServiceTokens';
import deleteWorkspace from '../../api/workspace/deleteWorkspace';
@@ -33,9 +32,8 @@ export default function SettingsBasic() {
const [serviceTokens, setServiceTokens] = useState<any[]>([]);
const [environments, setEnvironments] = useState<Array<EnvData>>([]);
const [workspaceToBeDeletedName, setWorkspaceToBeDeletedName] = useState('');
const [isAddOpen, setIsAddOpen] = useState(false);
const [isAddServiceTokenDialogOpen, setIsAddServiceTokenDialogOpen] =
useState(false);
// const [isAddOpen, setIsAddOpen] = useState(false);
const [isAddServiceTokenDialogOpen, setIsAddServiceTokenDialogOpen] = useState(false);
const [projectIdCopied, setProjectIdCopied] = useState(false);
const workspaceId = router.query.id as string;
@@ -62,13 +60,13 @@ export default function SettingsBasic() {
const load = async () => {
const userWorkspaces = await getWorkspaces();
userWorkspaces.forEach((userWorkspace) => {
if (userWorkspace._id == workspaceId) {
if (userWorkspace._id === workspaceId) {
setWorkspaceName(userWorkspace.name);
setEnvironments(userWorkspace.environments);
}
});
const tempServiceTokens = await getServiceTokens({
workspaceId,
workspaceId
});
setServiceTokens(tempServiceTokens);
};
@@ -101,12 +99,12 @@ export default function SettingsBasic() {
if (userWorkspaces.length > 1) {
if (
userWorkspaces.filter((workspace) => workspace._id === workspaceId)[0]
.name == workspaceToBeDeletedName
userWorkspaces.filter((workspace) => workspace._id === workspaceId)[0].name ===
workspaceToBeDeletedName
) {
await deleteWorkspace(workspaceId);
const userWorkspaces = await getWorkspaces();
router.push('/dashboard/' + userWorkspaces[0]._id);
const ws = await getWorkspaces();
router.push(`/dashboard/${ws[0]._id}`);
}
}
};
@@ -114,7 +112,7 @@ export default function SettingsBasic() {
const onCreateEnvironment = async ({ name, slug }: EnvData) => {
const res = await createEnvironment(workspaceId, {
environmentName: name,
environmentSlug: slug,
environmentSlug: slug
});
if (res) {
// TODO: on react-query migration do an api call to resync
@@ -122,20 +120,15 @@ export default function SettingsBasic() {
}
};
const onUpdateEnvironment = async (
oldSlug: string,
{ name, slug }: EnvData
) => {
const onUpdateEnvironment = async (oldSlug: string, { name, slug }: EnvData) => {
const res = await updateEnvironment(workspaceId, {
oldEnvironmentSlug: oldSlug,
environmentName: name,
environmentSlug: slug,
environmentSlug: slug
});
// TODO: on react-query migration do an api call to resync
if (res) {
setEnvironments((env) =>
env.map((el) => (el.slug === oldSlug ? { name, slug } : el))
);
setEnvironments((env) => env.map((el) => (el.slug === oldSlug ? { name, slug } : el)));
}
};
@@ -143,19 +136,15 @@ export default function SettingsBasic() {
const res = await deleteEnvironment(workspaceId, slugToBeDelete);
// TODO: on react-query migration do an api call to resync
if (res) {
setEnvironments((env) =>
env.filter(({ slug }) => slug !== slugToBeDelete)
);
setEnvironments((env) => env.filter(({ slug }) => slug !== slugToBeDelete));
}
};
return (
<div className='bg-bunker-800 max-h-screen flex flex-col justify-between text-white'>
<div className="bg-bunker-800 max-h-screen flex flex-col justify-between text-white">
<Head>
<title>
{t('common:head-title', { title: t('settings-project:title') })}
</title>
<link rel='icon' href='/infisical.ico' />
<title>{t('common:head-title', { title: t('settings-project:title') })}</title>
<link rel="icon" href="/infisical.ico" />
</Head>
<AddServiceTokenDialog
isOpen={isAddServiceTokenDialogOpen}
@@ -166,104 +155,94 @@ export default function SettingsBasic() {
serviceTokens={serviceTokens}
setServiceTokens={setServiceTokens}
/>
<div className='flex flex-row mr-6 max-w-5xl'>
<div className='w-full max-h-screen pb-2 overflow-y-auto'>
<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'>
{t('settings-project:title')}
</p>
<p className='font-normal mr-4 text-gray-400 text-base'>
<div className="flex flex-row mr-6 max-w-5xl">
<div className="w-full max-h-screen pb-2 overflow-y-auto">
<NavHeader pageName={t('settings-project:title')} isProjectRelated />
<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-project:title')}</p>
<p className="font-normal mr-4 text-gray-400 text-base">
{t('settings-project:description')}
</p>
</div>
</div>
<div className='flex flex-col ml-6 text-mineshaft-50'>
<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 mt-2'>
{t('common:display-name')}
</p>
<div className='max-h-28 w-full max-w-md mr-auto'>
<div className="flex flex-col ml-6 text-mineshaft-50">
<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 pb-4 flex flex-col items-start w-full mb-6 pt-2">
<p className="text-xl font-semibold mb-4 mt-2">{t('common:display-name')}</p>
<div className="max-h-28 w-full max-w-md mr-auto">
<InputField
label=''
label=""
onChangeHandler={modifyWorkspaceName}
type='varName'
type="varName"
value={workspaceName}
placeholder=''
placeholder=""
isRequired
/>
</div>
<div className='flex justify-start w-full'>
<div className={`flex justify-start max-w-sm mt-4 mb-2`}>
<div className="flex justify-start w-full">
<div className="flex justify-start max-w-sm mt-4 mb-2">
<Button
text={t('common:save-changes') as string}
onButtonPressed={() => submitChanges(workspaceName)}
color='mineshaft'
size='md'
color="mineshaft"
size="md"
active={buttonReady}
iconDisabled={faCheck}
textDisabled='Saved'
textDisabled="Saved"
/>
</div>
</div>
</div>
<div className='bg-white/5 rounded-md px-6 pt-4 pb-2 flex flex-col items-start w-full mb-6 mt-4'>
<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'>
<div className="bg-white/5 rounded-md px-6 pt-4 pb-2 flex flex-col items-start w-full mb-6 mt-4">
<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">
{t('settings-project:project-id-description')}
</p>
<p className='text-base text-gray-400 font-normal self-start'>
<p className="text-base text-gray-400 font-normal self-start">
{t('settings-project:project-id-description2')}
{/* eslint-disable-next-line react/jsx-no-target-blank */}
<a
href='https://infisical.com/docs/getting-started/introduction'
target='_blank'
rel='noopener'
className='text-primary hover:opacity-80 duration-200'
href="https://infisical.com/docs/getting-started/introduction"
target="_blank"
rel="noopener"
className="text-primary hover:opacity-80 duration-200"
>
{t('settings-project:docs')}
</a>
</p>
<p className='mt-4 text-xs text-bunker-300'>
<p className="mt-4 text-xs text-bunker-300">
{t('settings-project:auto-generated')}
</p>
<div className='flex justify-end items-center bg-white/[0.07] text-base mt-2 mb-3 mr-2 rounded-md text-gray-400'>
<p className='mr-2 font-bold pl-4'>{`${t(
'common:project-id'
)}:`}</p>
<div className="flex justify-end items-center bg-white/[0.07] text-base mt-2 mb-3 mr-2 rounded-md text-gray-400">
<p className="mr-2 font-bold pl-4">{`${t('common:project-id')}:`}</p>
<input
type='text'
type="text"
value={workspaceId}
id='myInput'
className='bg-white/0 text-gray-400 py-2 w-60 px-2 min-w-md outline-none'
id="myInput"
className="bg-white/0 text-gray-400 py-2 w-60 px-2 min-w-md outline-none"
disabled
></input>
<div className='group font-normal group relative inline-block text-gray-400 underline hover:text-primary duration-200'>
/>
<div className="group font-normal group relative inline-block text-gray-400 underline hover:text-primary duration-200">
<button
type="button"
onClick={copyToClipboard}
className='pl-4 pr-4 border-l border-white/20 py-2 hover:bg-white/[0.12] duration-200'
className="pl-4 pr-4 border-l border-white/20 py-2 hover:bg-white/[0.12] duration-200"
>
{projectIdCopied ? (
<FontAwesomeIcon icon={faCheck} className='pr-0.5' />
<FontAwesomeIcon icon={faCheck} className="pr-0.5" />
) : (
<FontAwesomeIcon icon={faCopy} />
)}
</button>
<span className='absolute hidden group-hover:flex group-hover:animate-popup duration-300 w-28 -left-8 -top-20 translate-y-full pl-3 py-2 bg-bunker-800 rounded-md text-center text-gray-400 text-sm'>
<span className="absolute hidden group-hover:flex group-hover:animate-popup duration-300 w-28 -left-8 -top-20 translate-y-full pl-3 py-2 bg-bunker-800 rounded-md text-center text-gray-400 text-sm">
{t('common:click-to-copy')}
</span>
</div>
</div>
</div>
<div className='bg-white/5 rounded-md px-6 pt-6 flex flex-col items-start w-full mt-4 mb-4'>
<div className="bg-white/5 rounded-md px-6 pt-6 flex flex-col items-start w-full mt-4 mb-4">
<EnvironmentTable
data={environments}
onCreateEnv={onCreateEnvironment}
@@ -271,37 +250,37 @@ export default function SettingsBasic() {
onDeleteEnv={onDeleteEnvironment}
/>
</div>
<div className='bg-white/5 rounded-md px-6 flex flex-col items-start w-full mt-4 mb-4 pt-2'>
<div className='flex flex-row justify-between w-full'>
<div className='flex flex-col w-full'>
<p className='text-xl font-semibold mb-3'>
<div className="bg-white/5 rounded-md px-6 flex flex-col items-start w-full mt-4 mb-4 pt-2">
<div className="flex flex-row justify-between w-full">
<div className="flex flex-col w-full">
<p className="text-xl font-semibold mb-3">
{t('section-token:service-tokens')}
</p>
<p className='text-sm text-gray-400'>
<p className="text-sm text-gray-400">
{t('section-token:service-tokens-description')}
</p>
<p className='text-sm text-gray-400 mb-4'>
<p className="text-sm text-gray-400 mb-4">
Please, make sure you are on the
<a
className='text-primary underline underline-offset-2 ml-1'
href='https://infisical.com/docs/cli/overview'
target='_blank'
rel='noreferrer'
className="text-primary underline underline-offset-2 ml-1"
href="https://infisical.com/docs/cli/overview"
target="_blank"
rel="noreferrer"
>
latest version of CLI
</a>
.
</p>
</div>
<div className='w-48 mt-2'>
<div className="w-48 mt-2">
<Button
text={t('section-token:add-new') as string}
onButtonPressed={() => {
setIsAddServiceTokenDialogOpen(true);
}}
color='mineshaft'
color="mineshaft"
icon={faPlus}
size='md'
size="md"
/>
</div>
</div>
@@ -313,31 +292,27 @@ export default function SettingsBasic() {
</div>
</div>
</div>
<div className='bg-white/5 rounded-md px-6 border-l border-red pl-6 flex flex-col items-start w-full mb-6 mt-4 pb-4 pt-2'>
<p className='text-xl font-bold text-red'>
{t('settings-project:danger-zone')}
</p>
<p className='mt-2 text-md text-gray-400'>
{t('settings-project:danger-zone-note')}
</p>
<div className='max-h-28 w-full max-w-md mr-auto mt-4'>
<div className="bg-white/5 rounded-md px-6 border-l border-red pl-6 flex flex-col items-start w-full mb-6 mt-4 pb-4 pt-2">
<p className="text-xl font-bold text-red">{t('settings-project:danger-zone')}</p>
<p className="mt-2 text-md text-gray-400">{t('settings-project:danger-zone-note')}</p>
<div className="max-h-28 w-full max-w-md mr-auto mt-4">
<InputField
label={t('settings-project:project-to-delete') as string}
onChangeHandler={setWorkspaceToBeDeletedName}
type='varName'
type="varName"
value={workspaceToBeDeletedName}
placeholder=''
placeholder=""
isRequired
/>
</div>
<button
type='button'
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'
type="button"
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}
>
{t('settings-project:delete-project')}
</button>
<p className='mt-0.5 ml-1 text-xs text-gray-500'>
<p className="mt-0.5 ml-1 text-xs text-gray-500">
{t('settings-project:delete-project-note')}
</p>
</div>
@@ -353,5 +328,5 @@ SettingsBasic.requireAuth = true;
export const getServerSideProps = getTranslatedServerSideProps([
'settings',
'settings-project',
'section-token',
'section-token'
]);