mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-15 20:25:43 +00:00
Merge pull request #1591 from Infisical/daniel/prettier-fix
Chore: Prettier formatting
This commit is contained in:
+11
-14
@@ -4,34 +4,31 @@ import Link from "next/link";
|
||||
|
||||
export default function Custom404() {
|
||||
return (
|
||||
<div className='bg-bunker-800 md:h-screen flex flex-col justify-between'>
|
||||
<div className="flex flex-col justify-between bg-bunker-800 md:h-screen">
|
||||
<Head>
|
||||
<title>Infisical | Page Not Found</title>
|
||||
<link rel='icon' href='/infisical.ico' />
|
||||
<link rel="icon" href="/infisical.ico" />
|
||||
</Head>
|
||||
<div className='flex flex-col items-center justify-center text-gray-200 h-screen w-screen'>
|
||||
<p className='text-4xl mt-32'>Oops, something went wrong</p>
|
||||
<p className='mt-2 mb-1 text-lg'>
|
||||
<div className="flex h-screen w-screen flex-col items-center justify-center text-gray-200">
|
||||
<p className="mt-32 text-4xl">Oops, something went wrong</p>
|
||||
<p className="mt-2 mb-1 text-lg">
|
||||
Think this is a mistake? Email{" "}
|
||||
<a
|
||||
className='text-primary underline underline-offset-4'
|
||||
href='mailto:[email protected]'
|
||||
>
|
||||
<a className="text-primary underline underline-offset-4" href="mailto:[email protected]">
|
||||
team@infisical.com
|
||||
</a>{" "}
|
||||
and we`ll fix it!{" "}
|
||||
</p>
|
||||
<Link href='/dashboard'>
|
||||
<div className="mt-8 bg-mineshaft-500 py-2 px-4 rounded-md hover:bg-primary diration-200 hover:text-black font-semibold cursor-default">
|
||||
<Link href="/dashboard">
|
||||
<div className="diration-200 mt-8 cursor-default rounded-md bg-mineshaft-500 py-2 px-4 font-semibold hover:bg-primary hover:text-black">
|
||||
Go to Dashboard
|
||||
</div>
|
||||
</Link>
|
||||
<Image
|
||||
src='/images/dragon-404.svg'
|
||||
src="/images/dragon-404.svg"
|
||||
height={554}
|
||||
width={942}
|
||||
alt='infisical dragon - page not found'
|
||||
/>
|
||||
alt="infisical dragon - page not found"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -7,7 +7,7 @@ export default function LoginPage() {
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<div className="flex min-h-screen max-h-screen overflow-y-auto flex-col justify-center bg-gradient-to-tr from-mineshaft-600 via-mineshaft-800 to-bunker-700 px-6">
|
||||
<div className="flex max-h-screen min-h-screen flex-col justify-center overflow-y-auto bg-gradient-to-tr from-mineshaft-600 via-mineshaft-800 to-bunker-700 px-6">
|
||||
<Head>
|
||||
<title>{t("common.head-title", { title: t("signup.title") })}</title>
|
||||
<link rel="icon" href="/infisical.ico" />
|
||||
|
||||
@@ -11,6 +11,6 @@ const checkAuth = async () => {
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
}).then((res) => res);
|
||||
}
|
||||
};
|
||||
|
||||
export default checkAuth;
|
||||
|
||||
@@ -2,7 +2,7 @@ import SecurityClient from "@app/components/utilities/SecurityClient";
|
||||
|
||||
/**
|
||||
* Will create a new integration session and return it for the given org
|
||||
* @returns
|
||||
* @returns
|
||||
*/
|
||||
const linkGitAppInstallationWithOrganization = (installationId: string, sessionId: string) =>
|
||||
SecurityClient.fetchCall("/api/v1/secret-scanning/link-installation", {
|
||||
@@ -16,7 +16,7 @@ const linkGitAppInstallationWithOrganization = (installationId: string, sessionI
|
||||
})
|
||||
}).then(async (res) => {
|
||||
if (res && res.status === 200) {
|
||||
return true
|
||||
return true;
|
||||
}
|
||||
console.log("Failed to link installation to organization");
|
||||
return undefined;
|
||||
|
||||
@@ -4,25 +4,26 @@ export enum RiskStatus {
|
||||
RESOLVED_FALSE_POSITIVE = "RESOLVED_FALSE_POSITIVE",
|
||||
RESOLVED_REVOKED = "RESOLVED_REVOKED",
|
||||
RESOLVED_NOT_REVOKED = "RESOLVED_NOT_REVOKED",
|
||||
UNRESOLVED = "UNRESOLVED",
|
||||
UNRESOLVED = "UNRESOLVED"
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Will create a new integration session and return it for the given org
|
||||
* @returns
|
||||
* @returns
|
||||
*/
|
||||
const updateRiskStatus = (organizationId: string, riskId: string, status: RiskStatus) =>
|
||||
SecurityClient.fetchCall(`/api/v1/secret-scanning/organization/${organizationId}/risks/${riskId}/status`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json"
|
||||
},
|
||||
body: JSON.stringify({
|
||||
status
|
||||
})
|
||||
}).then(async (res) => {
|
||||
SecurityClient.fetchCall(
|
||||
`/api/v1/secret-scanning/organization/${organizationId}/risks/${riskId}/status`,
|
||||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json"
|
||||
},
|
||||
body: JSON.stringify({
|
||||
status
|
||||
})
|
||||
}
|
||||
).then(async (res) => {
|
||||
if (res && res.status === 200) {
|
||||
return res.json();
|
||||
}
|
||||
|
||||
@@ -3,17 +3,19 @@ import Image from "next/image";
|
||||
|
||||
export default function CliRedirect() {
|
||||
return (
|
||||
<div className='bg-bunker-800 md:h-screen flex flex-col justify-between'>
|
||||
<div className="flex flex-col justify-between bg-bunker-800 md:h-screen">
|
||||
<Head>
|
||||
<title>Infisical CLI | Login Successful!</title>
|
||||
<link rel='icon' href='/infisical.ico' />
|
||||
<link rel="icon" href="/infisical.ico" />
|
||||
</Head>
|
||||
<div className='flex flex-col items-center justify-center text-gray-200 h-screen w-screen'>
|
||||
<div className="flex h-screen w-screen flex-col items-center justify-center text-gray-200">
|
||||
<div className="mb-8 flex justify-center">
|
||||
<Image src="/images/gradientLogo.svg" height={90} width={120} alt="Infisical Logo" />
|
||||
</div>
|
||||
<p className='text-3xl font-medium text-transparent bg-clip-text bg-gradient-to-b from-white to-bunker-200 text-center'>Head back to your terminal</p>
|
||||
<p className='mb-1 text-lg text-light text-mineshaft-400'>
|
||||
<p className="bg-gradient-to-b from-white to-bunker-200 bg-clip-text text-center text-3xl font-medium text-transparent">
|
||||
Head back to your terminal
|
||||
</p>
|
||||
<p className="text-light mb-1 text-lg text-mineshaft-400">
|
||||
You've successfully logged in to the Infisical CLI
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -3,16 +3,16 @@ import Head from "next/head";
|
||||
|
||||
export default function EmailNotFeriviedPage() {
|
||||
return (
|
||||
<div className="bg-bunker-800 md:h-screen flex flex-col justify-between">
|
||||
<div className="flex flex-col justify-between bg-bunker-800 md:h-screen">
|
||||
<Head>
|
||||
<title>Request a New Invite</title>
|
||||
<link rel="icon" href="/infisical.ico" />
|
||||
</Head>
|
||||
<div className="flex flex-col items-center justify-center text-gray-200 h-screen w-screen">
|
||||
<div className="flex h-screen w-screen flex-col items-center justify-center text-gray-200">
|
||||
<p className="text-6xl">Oops.</p>
|
||||
<p className="mt-2 mb-1 text-xl">Your email was not verified. </p>
|
||||
<p className="text-xl">Please try again.</p>
|
||||
<p className="text-md mt-8 text-gray-600 max-w-sm text-center">
|
||||
<p className="text-md mt-8 max-w-sm text-center text-gray-600">
|
||||
Note: If it still doesn't work, please reach out to us at support@infisical.com
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -9,5 +9,5 @@ export default function Home() {
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, []);
|
||||
|
||||
return <div className="bg-bunker-800 w-screen" />;
|
||||
return <div className="w-screen bg-bunker-800" />;
|
||||
}
|
||||
|
||||
@@ -1,92 +1,87 @@
|
||||
import { useState } from "react";
|
||||
import { useRouter } from "next/router";
|
||||
|
||||
import {
|
||||
useSaveIntegrationAccessToken
|
||||
} from "@app/hooks/api";
|
||||
import { useSaveIntegrationAccessToken } from "@app/hooks/api";
|
||||
|
||||
import { Button,Card, CardTitle, FormControl, Input } from "../../../components/v2";
|
||||
import { Button, Card, CardTitle, FormControl, Input } from "../../../components/v2";
|
||||
|
||||
export default function CloudflarePagesIntegrationPage() {
|
||||
const router = useRouter();
|
||||
const { mutateAsync } = useSaveIntegrationAccessToken();
|
||||
const router = useRouter();
|
||||
const { mutateAsync } = useSaveIntegrationAccessToken();
|
||||
|
||||
const [accessKey, setAccessKey] = useState("");
|
||||
const [accessKeyErrorText, setAccessKeyErrorText] = useState("");
|
||||
const [accountId, setAccountId] = useState("");
|
||||
const [accountIdErrorText, setAccountIdErrorText] = useState("");
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [accessKey, setAccessKey] = useState("");
|
||||
const [accessKeyErrorText, setAccessKeyErrorText] = useState("");
|
||||
const [accountId, setAccountId] = useState("");
|
||||
const [accountIdErrorText, setAccountIdErrorText] = useState("");
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
|
||||
const handleButtonClick = async () => {
|
||||
try {
|
||||
setAccessKeyErrorText("");
|
||||
setAccountIdErrorText("");
|
||||
if (accessKey.length === 0 || accountId.length === 0) {
|
||||
if (accessKey.length === 0) setAccessKeyErrorText("API token cannot be blank!");
|
||||
if (accountId.length === 0) setAccountIdErrorText("Account ID cannot be blank!");
|
||||
return;
|
||||
}
|
||||
const handleButtonClick = async () => {
|
||||
try {
|
||||
setAccessKeyErrorText("");
|
||||
setAccountIdErrorText("");
|
||||
if (accessKey.length === 0 || accountId.length === 0) {
|
||||
if (accessKey.length === 0) setAccessKeyErrorText("API token cannot be blank!");
|
||||
if (accountId.length === 0) setAccountIdErrorText("Account ID cannot be blank!");
|
||||
return;
|
||||
}
|
||||
|
||||
setIsLoading(true);
|
||||
setIsLoading(true);
|
||||
|
||||
const integrationAuth = await mutateAsync({
|
||||
workspaceId: localStorage.getItem("projectData.id"),
|
||||
integration: "cloudflare-pages",
|
||||
accessId: accountId,
|
||||
accessToken: accessKey
|
||||
});
|
||||
const integrationAuth = await mutateAsync({
|
||||
workspaceId: localStorage.getItem("projectData.id"),
|
||||
integration: "cloudflare-pages",
|
||||
accessId: accountId,
|
||||
accessToken: accessKey
|
||||
});
|
||||
|
||||
setAccessKey("");
|
||||
setAccountId("");
|
||||
setIsLoading(false);
|
||||
setAccessKey("");
|
||||
setAccountId("");
|
||||
setIsLoading(false);
|
||||
|
||||
router.push(`/integrations/cloudflare-pages/create?integrationAuthId=${integrationAuth.id}`);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
}
|
||||
router.push(`/integrations/cloudflare-pages/create?integrationAuthId=${integrationAuth.id}`);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="flex h-full w-full items-center justify-center">
|
||||
<Card className="max-w-lg rounded-md border border-mineshaft-600 mb-12">
|
||||
<CardTitle className="text-left px-6" subTitle="After adding your API-key, you will be prompted to set up an integration for a particular Infisical project and environment.">Cloudflare Pages Integration</CardTitle>
|
||||
<FormControl
|
||||
label="Cloudflare Pages API token"
|
||||
errorText={accessKeyErrorText}
|
||||
isError={accessKeyErrorText !== "" ?? false}
|
||||
className="mx-6"
|
||||
>
|
||||
<Input
|
||||
placeholder=""
|
||||
value={accessKey}
|
||||
onChange={(e) => setAccessKey(e.target.value)}
|
||||
/>
|
||||
</FormControl>
|
||||
<FormControl
|
||||
label="Cloudflare Pages Account ID"
|
||||
errorText={accountIdErrorText}
|
||||
isError={accountIdErrorText !== "" ?? false}
|
||||
className="mx-6"
|
||||
>
|
||||
<Input
|
||||
placeholder=""
|
||||
value={accountId}
|
||||
onChange={(e) => setAccountId(e.target.value)}
|
||||
/>
|
||||
</FormControl>
|
||||
<Button
|
||||
onClick={handleButtonClick}
|
||||
color="mineshaft"
|
||||
variant="outline_bg"
|
||||
className="mb-6 mt-2 ml-auto mr-6 w-min"
|
||||
isFullWidth={false}
|
||||
isLoading={isLoading}
|
||||
>
|
||||
Connect to Cloudflare Pages
|
||||
</Button>
|
||||
</Card>
|
||||
</div>
|
||||
);
|
||||
return (
|
||||
<div className="flex h-full w-full items-center justify-center">
|
||||
<Card className="mb-12 max-w-lg rounded-md border border-mineshaft-600">
|
||||
<CardTitle
|
||||
className="px-6 text-left"
|
||||
subTitle="After adding your API-key, you will be prompted to set up an integration for a particular Infisical project and environment."
|
||||
>
|
||||
Cloudflare Pages Integration
|
||||
</CardTitle>
|
||||
<FormControl
|
||||
label="Cloudflare Pages API token"
|
||||
errorText={accessKeyErrorText}
|
||||
isError={accessKeyErrorText !== "" ?? false}
|
||||
className="mx-6"
|
||||
>
|
||||
<Input placeholder="" value={accessKey} onChange={(e) => setAccessKey(e.target.value)} />
|
||||
</FormControl>
|
||||
<FormControl
|
||||
label="Cloudflare Pages Account ID"
|
||||
errorText={accountIdErrorText}
|
||||
isError={accountIdErrorText !== "" ?? false}
|
||||
className="mx-6"
|
||||
>
|
||||
<Input placeholder="" value={accountId} onChange={(e) => setAccountId(e.target.value)} />
|
||||
</FormControl>
|
||||
<Button
|
||||
onClick={handleButtonClick}
|
||||
color="mineshaft"
|
||||
variant="outline_bg"
|
||||
className="mb-6 mt-2 ml-auto mr-6 w-min"
|
||||
isFullWidth={false}
|
||||
isLoading={isLoading}
|
||||
>
|
||||
Connect to Cloudflare Pages
|
||||
</Button>
|
||||
</Card>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
CloudflarePagesIntegrationPage.requireAuth = true;
|
||||
CloudflarePagesIntegrationPage.requireAuth = true;
|
||||
|
||||
@@ -6,7 +6,15 @@ import queryString from "query-string";
|
||||
import { useNotificationContext } from "@app/components/context/Notifications/NotificationProvider";
|
||||
import { useCreateIntegration, useGetWorkspaceById } from "@app/hooks/api";
|
||||
|
||||
import { Button, Card, CardTitle, FormControl, Input, Select, SelectItem } from "../../../components/v2";
|
||||
import {
|
||||
Button,
|
||||
Card,
|
||||
CardTitle,
|
||||
FormControl,
|
||||
Input,
|
||||
Select,
|
||||
SelectItem
|
||||
} from "../../../components/v2";
|
||||
import {
|
||||
useGetIntegrationAuthApps,
|
||||
useGetIntegrationAuthById
|
||||
|
||||
@@ -4,11 +4,11 @@ import Head from "next/head";
|
||||
import Image from "next/image";
|
||||
import Link from "next/link";
|
||||
import { useRouter } from "next/router";
|
||||
import {
|
||||
faArrowUpRightFromSquare,
|
||||
faBookOpen,
|
||||
faBugs,
|
||||
// faCircleInfo
|
||||
import {
|
||||
faArrowUpRightFromSquare,
|
||||
faBookOpen,
|
||||
faBugs
|
||||
// faCircleInfo
|
||||
} from "@fortawesome/free-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { yupResolver } from "@hookform/resolvers/yup";
|
||||
@@ -34,13 +34,16 @@ import {
|
||||
useGetIntegrationAuthApps,
|
||||
useGetIntegrationAuthById
|
||||
} from "../../../hooks/api/integrationAuth";
|
||||
import {
|
||||
// useCreateWsEnvironment,
|
||||
useGetWorkspaceById
|
||||
import {
|
||||
// useCreateWsEnvironment,
|
||||
useGetWorkspaceById
|
||||
} from "../../../hooks/api/workspace";
|
||||
|
||||
const initialSyncBehaviors = [
|
||||
{ label: "No Import - Overwrite all values in Heroku", value: IntegrationSyncBehavior.OVERWRITE_TARGET },
|
||||
{
|
||||
label: "No Import - Overwrite all values in Heroku",
|
||||
value: IntegrationSyncBehavior.OVERWRITE_TARGET
|
||||
},
|
||||
{ label: "Import - Prefer values from Heroku", value: IntegrationSyncBehavior.PREFER_TARGET },
|
||||
{ label: "Import - Prefer values from Infisical", value: IntegrationSyncBehavior.PREFER_SOURCE }
|
||||
];
|
||||
@@ -51,7 +54,10 @@ const schema = yup.object({
|
||||
targetApp: yup.string().required("Heroku app is required"),
|
||||
initialSyncBehavior: yup
|
||||
.string()
|
||||
.oneOf(initialSyncBehaviors.map((b) => b.value), "Invalid initial sync behavior")
|
||||
.oneOf(
|
||||
initialSyncBehaviors.map((b) => b.value),
|
||||
"Invalid initial sync behavior"
|
||||
)
|
||||
.required("Initial sync behavior is required")
|
||||
});
|
||||
|
||||
@@ -59,7 +65,7 @@ type FormData = yup.InferType<typeof schema>;
|
||||
|
||||
export default function HerokuCreateIntegrationPage() {
|
||||
const router = useRouter();
|
||||
|
||||
|
||||
const { control, handleSubmit, setValue, watch } = useForm<FormData>({
|
||||
resolver: yupResolver(schema),
|
||||
defaultValues: {
|
||||
@@ -70,7 +76,6 @@ export default function HerokuCreateIntegrationPage() {
|
||||
|
||||
const selectedSourceEnvironment = watch("selectedSourceEnvironment");
|
||||
|
||||
|
||||
const { mutateAsync } = useCreateIntegration();
|
||||
// const { mutateAsync: mutateAsyncEnv } = useCreateWsEnvironment();
|
||||
|
||||
@@ -78,19 +83,20 @@ export default function HerokuCreateIntegrationPage() {
|
||||
|
||||
const { data: workspace } = useGetWorkspaceById(localStorage.getItem("projectData.id") ?? "");
|
||||
const { data: integrationAuth } = useGetIntegrationAuthById((integrationAuthId as string) ?? "");
|
||||
const { data: integrationAuthApps, isLoading: isIntegrationAuthAppsLoading } = useGetIntegrationAuthApps({
|
||||
integrationAuthId: (integrationAuthId as string) ?? ""
|
||||
});
|
||||
const { data: integrationAuthApps, isLoading: isIntegrationAuthAppsLoading } =
|
||||
useGetIntegrationAuthApps({
|
||||
integrationAuthId: (integrationAuthId as string) ?? ""
|
||||
});
|
||||
|
||||
// const { data: integrationAuthPipelineCouplings } = useGetIntegrationAuthHerokuPipelines({
|
||||
// integrationAuthId: (integrationAuthId as string) ?? ""
|
||||
// });
|
||||
|
||||
|
||||
// const [uniquePipelines, setUniquePipelines] = useState<Pipeline[]>();
|
||||
// const [selectedPipeline, setSelectedPipeline] = useState("");
|
||||
// const [selectedPipelineApps, setSelectedPipelineApps] = useState<App[]>();
|
||||
// const [integrationType, setIntegrationType] = useState("App");
|
||||
|
||||
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
@@ -110,7 +116,7 @@ export default function HerokuCreateIntegrationPage() {
|
||||
// }))
|
||||
// .map((obj) => JSON.stringify(obj))
|
||||
// )).map((str) => JSON.parse(str)) as { pipelineId: string; name: string }[]
|
||||
|
||||
|
||||
// [... (new Set())]
|
||||
// setUniquePipelines(uniquePipelinesConst);
|
||||
// if (uniquePipelinesConst) {
|
||||
@@ -181,11 +187,7 @@ export default function HerokuCreateIntegrationPage() {
|
||||
// }
|
||||
// };
|
||||
|
||||
const onFormSubmit = async ({
|
||||
secretPath,
|
||||
targetApp,
|
||||
initialSyncBehavior,
|
||||
}: FormData) => {
|
||||
const onFormSubmit = async ({ secretPath, targetApp, initialSyncBehavior }: FormData) => {
|
||||
try {
|
||||
if (!integrationAuth?.id) return;
|
||||
|
||||
@@ -207,13 +209,10 @@ export default function HerokuCreateIntegrationPage() {
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return integrationAuth &&
|
||||
workspace &&
|
||||
selectedSourceEnvironment &&
|
||||
integrationAuthApps ? (
|
||||
<div className="flex flex-col h-full w-full items-center justify-center">
|
||||
return integrationAuth && workspace && selectedSourceEnvironment && integrationAuthApps ? (
|
||||
<div className="flex h-full w-full flex-col items-center justify-center">
|
||||
<Head>
|
||||
<title>Set Up Heroku Integration</title>
|
||||
<link rel="icon" href="/infisical.ico" />
|
||||
@@ -280,11 +279,7 @@ export default function HerokuCreateIntegrationPage() {
|
||||
defaultValue=""
|
||||
name="secretPath"
|
||||
render={({ field, fieldState: { error } }) => (
|
||||
<FormControl
|
||||
label="Secrets Path"
|
||||
isError={Boolean(error)}
|
||||
errorText={error?.message}
|
||||
>
|
||||
<FormControl label="Secrets Path" isError={Boolean(error)} errorText={error?.message}>
|
||||
<Input {...field} placeholder="/" />
|
||||
</FormControl>
|
||||
)}
|
||||
@@ -294,11 +289,7 @@ export default function HerokuCreateIntegrationPage() {
|
||||
name="targetApp"
|
||||
render={({ field: { onChange, ...field }, fieldState: { error } }) => {
|
||||
return (
|
||||
<FormControl
|
||||
label="Heroku App"
|
||||
errorText={error?.message}
|
||||
isError={Boolean(error)}
|
||||
>
|
||||
<FormControl label="Heroku App" errorText={error?.message} isError={Boolean(error)}>
|
||||
<Select
|
||||
{...field}
|
||||
onValueChange={(e) => {
|
||||
|
||||
@@ -114,7 +114,9 @@ export default function RailwayCreateIntegrationPage() {
|
||||
}
|
||||
};
|
||||
|
||||
const filteredTargetServices = targetServices ? [ { name: "", serviceId: "none" }, ...targetServices ] : [ { name: "", serviceId: "none" } ];
|
||||
const filteredTargetServices = targetServices
|
||||
? [{ name: "", serviceId: "none" }, ...targetServices]
|
||||
: [{ name: "", serviceId: "none" }];
|
||||
|
||||
return workspace &&
|
||||
selectedSourceEnvironment &&
|
||||
@@ -201,14 +203,14 @@ export default function RailwayCreateIntegrationPage() {
|
||||
className="w-full border border-mineshaft-500"
|
||||
isDisabled={targetServices.length === 0}
|
||||
>
|
||||
{filteredTargetServices.map((targetService) => (
|
||||
<SelectItem
|
||||
value={targetService.serviceId as string}
|
||||
key={`target-service-${targetService.serviceId as string}`}
|
||||
>
|
||||
{targetService.name}
|
||||
</SelectItem>
|
||||
))}
|
||||
{filteredTargetServices.map((targetService) => (
|
||||
<SelectItem
|
||||
value={targetService.serviceId as string}
|
||||
key={`target-service-${targetService.serviceId as string}`}
|
||||
>
|
||||
{targetService.name}
|
||||
</SelectItem>
|
||||
))}
|
||||
</Select>
|
||||
</FormControl>
|
||||
<Button
|
||||
|
||||
@@ -45,7 +45,7 @@ type FormData = yup.InferType<typeof schema>;
|
||||
export default function RenderCreateIntegrationPage() {
|
||||
const router = useRouter();
|
||||
const { mutateAsync } = useCreateIntegration();
|
||||
|
||||
|
||||
const { control, handleSubmit, setValue, watch } = useForm<FormData>({
|
||||
resolver: yupResolver(schema),
|
||||
defaultValues: {
|
||||
@@ -84,12 +84,8 @@ export default function RenderCreateIntegrationPage() {
|
||||
}
|
||||
}
|
||||
}, [integrationAuthApps]);
|
||||
|
||||
const onFormSubmit = async ({
|
||||
secretPath,
|
||||
targetAppId,
|
||||
shouldAutoRedeploy
|
||||
}: FormData) => {
|
||||
|
||||
const onFormSubmit = async ({ secretPath, targetAppId, shouldAutoRedeploy }: FormData) => {
|
||||
try {
|
||||
if (!integrationAuth?.id) return;
|
||||
|
||||
@@ -115,13 +111,10 @@ export default function RenderCreateIntegrationPage() {
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return integrationAuth &&
|
||||
workspace &&
|
||||
selectedSourceEnvironment &&
|
||||
integrationAuthApps ? (
|
||||
<form
|
||||
return integrationAuth && workspace && selectedSourceEnvironment && integrationAuthApps ? (
|
||||
<form
|
||||
onSubmit={handleSubmit(onFormSubmit)}
|
||||
className="flex h-full w-full flex-col items-center justify-center"
|
||||
>
|
||||
@@ -191,11 +184,7 @@ export default function RenderCreateIntegrationPage() {
|
||||
defaultValue=""
|
||||
name="secretPath"
|
||||
render={({ field, fieldState: { error } }) => (
|
||||
<FormControl
|
||||
label="Secrets Path"
|
||||
isError={Boolean(error)}
|
||||
errorText={error?.message}
|
||||
>
|
||||
<FormControl label="Secrets Path" isError={Boolean(error)} errorText={error?.message}>
|
||||
<Input {...field} placeholder="/" />
|
||||
</FormControl>
|
||||
)}
|
||||
@@ -256,7 +245,7 @@ export default function RenderCreateIntegrationPage() {
|
||||
<Button
|
||||
colorSchema="primary"
|
||||
variant="outline_bg"
|
||||
className="mb-8 ml-auto mr-6 w-min mt-4"
|
||||
className="mb-8 ml-auto mr-6 mt-4 w-min"
|
||||
size="sm"
|
||||
type="submit"
|
||||
isLoading={isLoading}
|
||||
|
||||
@@ -9,7 +9,7 @@ export default function LoginPage() {
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<div className="flex min-h-screen max-h-screen overflow-y-auto flex-col justify-center bg-gradient-to-tr from-mineshaft-600 via-mineshaft-800 to-bunker-700 px-6">
|
||||
<div className="flex max-h-screen min-h-screen flex-col justify-center overflow-y-auto bg-gradient-to-tr from-mineshaft-600 via-mineshaft-800 to-bunker-700 px-6">
|
||||
<Head>
|
||||
<title>{t("common.head-title", { title: t("login.title") })}</title>
|
||||
<link rel="icon" href="/infisical.ico" />
|
||||
@@ -23,7 +23,7 @@ export default function LoginPage() {
|
||||
</div>
|
||||
</Link>
|
||||
<Login />
|
||||
<div className="pb-28"/>
|
||||
<div className="pb-28" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { useEffect } from "react";
|
||||
|
||||
export default function LoginProviderError() {
|
||||
useEffect(() => {
|
||||
window.localStorage.setItem("PROVIDER_AUTH_ERROR", "err");
|
||||
window.close();
|
||||
}, [])
|
||||
useEffect(() => {
|
||||
window.localStorage.setItem("PROVIDER_AUTH_ERROR", "err");
|
||||
window.close();
|
||||
}, []);
|
||||
|
||||
return <div />
|
||||
return <div />;
|
||||
}
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
import { useEffect } from "react";
|
||||
import { useRouter } from "next/router"
|
||||
import { useRouter } from "next/router";
|
||||
|
||||
import SecurityClient from "@app/components/utilities/SecurityClient";
|
||||
|
||||
export default function LoginProviderSuccess() {
|
||||
const router = useRouter();
|
||||
const router = useRouter();
|
||||
|
||||
useEffect(() => {
|
||||
const { token } = router.query;
|
||||
SecurityClient.setProviderAuthToken(token as string);
|
||||
window.close();
|
||||
}, [])
|
||||
useEffect(() => {
|
||||
const { token } = router.query;
|
||||
SecurityClient.setProviderAuthToken(token as string);
|
||||
window.close();
|
||||
}, []);
|
||||
|
||||
return <div />
|
||||
return <div />;
|
||||
}
|
||||
|
||||
@@ -2,30 +2,30 @@ import { useTranslation } from "react-i18next";
|
||||
import Head from "next/head";
|
||||
import Image from "next/image";
|
||||
import Link from "next/link";
|
||||
import { useRouter } from "next/router"
|
||||
import { useRouter } from "next/router";
|
||||
|
||||
import { LoginSSO } from "@app/views/Login";
|
||||
|
||||
export default function LoginSSOPage() {
|
||||
const { t } = useTranslation();
|
||||
const router = useRouter();
|
||||
const token = router.query.token as string;
|
||||
const { t } = useTranslation();
|
||||
const router = useRouter();
|
||||
const token = router.query.token as string;
|
||||
|
||||
return (
|
||||
<div className="flex h-screen flex-col justify-center bg-gradient-to-tr from-mineshaft-600 via-mineshaft-800 to-bunker-700 px-6 pb-28 ">
|
||||
<Head>
|
||||
<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("login.og-title") ?? ""} />
|
||||
<meta name="og:description" content={t("login.og-description") ?? ""} />
|
||||
</Head>
|
||||
<Link href="/">
|
||||
<div className="mb-4 mt-20 flex justify-center">
|
||||
<Image src="/images/gradientLogo.svg" height={90} width={120} alt="Infisical logo" />
|
||||
</div>
|
||||
</Link>
|
||||
<LoginSSO providerAuthToken={token} />
|
||||
return (
|
||||
<div className="flex h-screen flex-col justify-center bg-gradient-to-tr from-mineshaft-600 via-mineshaft-800 to-bunker-700 px-6 pb-28 ">
|
||||
<Head>
|
||||
<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("login.og-title") ?? ""} />
|
||||
<meta name="og:description" content={t("login.og-description") ?? ""} />
|
||||
</Head>
|
||||
<Link href="/">
|
||||
<div className="mb-4 mt-20 flex justify-center">
|
||||
<Image src="/images/gradientLogo.svg" height={90} width={120} alt="Infisical logo" />
|
||||
</div>
|
||||
</Link>
|
||||
<LoginSSO providerAuthToken={token} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@@ -18,4 +18,4 @@ export default function SettingsOrg() {
|
||||
);
|
||||
}
|
||||
|
||||
SettingsOrg.requireAuth = true;
|
||||
SettingsOrg.requireAuth = true;
|
||||
|
||||
@@ -5,16 +5,16 @@ import Head from "next/head";
|
||||
import { NonePage } from "@app/views/Org/NonePage";
|
||||
|
||||
export default function NoneOrganization() {
|
||||
const { t } = useTranslation();
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<title>{t("common.head-title", { title: t("settings.org.title") })}</title>
|
||||
<link rel="icon" href="/infisical.ico" />
|
||||
</Head>
|
||||
<NonePage />
|
||||
</>
|
||||
);
|
||||
const { t } = useTranslation();
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<title>{t("common.head-title", { title: t("settings.org.title") })}</title>
|
||||
<link rel="icon" href="/infisical.ico" />
|
||||
</Head>
|
||||
<NonePage />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
NoneOrganization.requireAuth = true;
|
||||
NoneOrganization.requireAuth = true;
|
||||
|
||||
@@ -308,64 +308,58 @@ export default function PasswordReset() {
|
||||
<FontAwesomeIcon icon={faCheck} className="text-md mr-2 text-primary" />
|
||||
)}
|
||||
<div
|
||||
className={`${passwordErrorNoNumOrSpecialChar ? "text-gray-400" : "text-gray-600"} text-sm`}
|
||||
className={`${
|
||||
passwordErrorNoNumOrSpecialChar ? "text-gray-400" : "text-gray-600"
|
||||
} text-sm`}
|
||||
>
|
||||
at least 1 number or special character
|
||||
</div>
|
||||
</div>
|
||||
<div className="ml-1 flex flex-row items-center justify-start">
|
||||
{passwordErrorRepeatedChar ? (
|
||||
<FontAwesomeIcon icon={faX} className="text-md mr-2.5 text-red" />
|
||||
) : (
|
||||
<FontAwesomeIcon icon={faCheck} className="text-md mr-2 text-primary" />
|
||||
)}
|
||||
<div
|
||||
className={`${
|
||||
passwordErrorRepeatedChar ? "text-gray-400" : "text-gray-600"
|
||||
} text-sm`}
|
||||
>
|
||||
at most 3 repeated, consecutive characters
|
||||
</div>
|
||||
{passwordErrorRepeatedChar ? (
|
||||
<FontAwesomeIcon icon={faX} className="text-md mr-2.5 text-red" />
|
||||
) : (
|
||||
<FontAwesomeIcon icon={faCheck} className="text-md mr-2 text-primary" />
|
||||
)}
|
||||
<div
|
||||
className={`${passwordErrorRepeatedChar ? "text-gray-400" : "text-gray-600"} text-sm`}
|
||||
>
|
||||
at most 3 repeated, consecutive characters
|
||||
</div>
|
||||
</div>
|
||||
<div className="ml-1 flex flex-row items-center justify-start">
|
||||
{passwordErrorEscapeChar ? (
|
||||
<FontAwesomeIcon icon={faX} className="text-md mr-2.5 text-red" />
|
||||
) : (
|
||||
<FontAwesomeIcon icon={faCheck} className="text-md mr-2 text-primary" />
|
||||
)}
|
||||
<div
|
||||
className={`${
|
||||
passwordErrorEscapeChar ? "text-gray-400" : "text-gray-600"
|
||||
} text-sm`}
|
||||
>
|
||||
No escape characters allowed.
|
||||
</div>
|
||||
{passwordErrorEscapeChar ? (
|
||||
<FontAwesomeIcon icon={faX} className="text-md mr-2.5 text-red" />
|
||||
) : (
|
||||
<FontAwesomeIcon icon={faCheck} className="text-md mr-2 text-primary" />
|
||||
)}
|
||||
<div
|
||||
className={`${passwordErrorEscapeChar ? "text-gray-400" : "text-gray-600"} text-sm`}
|
||||
>
|
||||
No escape characters allowed.
|
||||
</div>
|
||||
</div>
|
||||
<div className="ml-1 flex flex-row items-center justify-start">
|
||||
{passwordErrorLowEntropy ? (
|
||||
<FontAwesomeIcon icon={faX} className="text-md mr-2.5 text-red" />
|
||||
) : (
|
||||
<FontAwesomeIcon icon={faCheck} className="text-md mr-2 text-primary" />
|
||||
)}
|
||||
<div
|
||||
className={`${passwordErrorLowEntropy ? "text-gray-400" : "text-gray-600"} text-sm`}
|
||||
>
|
||||
Password contains personal info.
|
||||
</div>
|
||||
{passwordErrorLowEntropy ? (
|
||||
<FontAwesomeIcon icon={faX} className="text-md mr-2.5 text-red" />
|
||||
) : (
|
||||
<FontAwesomeIcon icon={faCheck} className="text-md mr-2 text-primary" />
|
||||
)}
|
||||
<div
|
||||
className={`${passwordErrorLowEntropy ? "text-gray-400" : "text-gray-600"} text-sm`}
|
||||
>
|
||||
Password contains personal info.
|
||||
</div>
|
||||
</div>
|
||||
<div className="ml-1 flex flex-row items-center justify-start">
|
||||
{passwordErrorBreached ? (
|
||||
<FontAwesomeIcon icon={faX} className="text-md mr-2.5 text-red" />
|
||||
) : (
|
||||
<FontAwesomeIcon icon={faCheck} className="text-md mr-2 text-primary" />
|
||||
)}
|
||||
<div
|
||||
className={`${
|
||||
passwordErrorBreached ? "text-gray-400" : "text-gray-600"
|
||||
} text-sm`}
|
||||
>
|
||||
Password was found in a data breach.
|
||||
</div>
|
||||
{passwordErrorBreached ? (
|
||||
<FontAwesomeIcon icon={faX} className="text-md mr-2.5 text-red" />
|
||||
) : (
|
||||
<FontAwesomeIcon icon={faCheck} className="text-md mr-2 text-primary" />
|
||||
)}
|
||||
<div className={`${passwordErrorBreached ? "text-gray-400" : "text-gray-600"} text-sm`}>
|
||||
Password was found in a data breach.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
|
||||
@@ -7,7 +7,7 @@ export default function PersonalSettings() {
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<div className="bg-bunker-800 text-white h-full">
|
||||
<div className="h-full bg-bunker-800 text-white">
|
||||
<Head>
|
||||
<title>{t("common.head-title", { title: t("settings.personal.title") })}</title>
|
||||
<link rel="icon" href="/infisical.ico" />
|
||||
|
||||
@@ -4,18 +4,18 @@ import Head from "next/head";
|
||||
import { IPAllowlistPage } from "@app/views/Project/IPAllowListPage";
|
||||
|
||||
const ProjectAllowlist = () => {
|
||||
const { t } = useTranslation();
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<title>{t("common.head-title", { title: t("settings.project.title") })}</title>
|
||||
<link rel="icon" href="/infisical.ico" />
|
||||
</Head>
|
||||
<IPAllowlistPage />
|
||||
</>
|
||||
);
|
||||
}
|
||||
const { t } = useTranslation();
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<title>{t("common.head-title", { title: t("settings.project.title") })}</title>
|
||||
<link rel="icon" href="/infisical.ico" />
|
||||
</Head>
|
||||
<IPAllowlistPage />
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default ProjectAllowlist;
|
||||
|
||||
ProjectAllowlist.requireAuth = true;
|
||||
ProjectAllowlist.requireAuth = true;
|
||||
|
||||
@@ -4,20 +4,20 @@ import Head from "next/head";
|
||||
import { AuditLogsPage } from "@app/views/Project/AuditLogsPage";
|
||||
|
||||
const Logs = () => {
|
||||
const { t } = useTranslation();
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<div className="h-full bg-bunker-800">
|
||||
<Head>
|
||||
<title>{t("common.head-title", { title: t("settings.project.title") })}</title>
|
||||
<link rel="icon" href="/infisical.ico" />
|
||||
<meta property="og:image" content="/images/message.png" />
|
||||
</Head>
|
||||
<AuditLogsPage />
|
||||
return (
|
||||
<div className="h-full bg-bunker-800">
|
||||
<Head>
|
||||
<title>{t("common.head-title", { title: t("settings.project.title") })}</title>
|
||||
<link rel="icon" href="/infisical.ico" />
|
||||
<meta property="og:image" content="/images/message.png" />
|
||||
</Head>
|
||||
<AuditLogsPage />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
export default Logs;
|
||||
|
||||
Logs.requireAuth = true;
|
||||
Logs.requireAuth = true;
|
||||
|
||||
@@ -7,20 +7,25 @@ import Image from "next/image";
|
||||
*/
|
||||
export default function RequestNewInvite() {
|
||||
return (
|
||||
<div className="bg-bunker-700 md:h-screen flex flex-col justify-between">
|
||||
<div className="flex flex-col justify-between bg-bunker-700 md:h-screen">
|
||||
<Head>
|
||||
<title>Request a New Invite</title>
|
||||
<link rel="icon" href="/infisical.ico" />
|
||||
</Head>
|
||||
<div className="flex flex-col items-center justify-center text-bunker-200 h-screen w-screen mt-8">
|
||||
<div className="mt-8 flex h-screen w-screen flex-col items-center justify-center text-bunker-200">
|
||||
<p className="text-4xl text-primary-100">Oops, your invite has expired.</p>
|
||||
<p className="text-lg my-4">Ask your admin for a new one.</p>
|
||||
<p className="text-sm text-bunker-400 max-w-xs px-7 text-center leading-tight">
|
||||
<span className="bg-primary-500/40 text-black px-1 rounded-md">Note:</span> If it still
|
||||
<p className="my-4 text-lg">Ask your admin for a new one.</p>
|
||||
<p className="max-w-xs px-7 text-center text-sm leading-tight text-bunker-400">
|
||||
<span className="rounded-md bg-primary-500/40 px-1 text-black">Note:</span> If it still
|
||||
doesn't work, please reach out to us at support@infisical.com
|
||||
</p>
|
||||
<div className="">
|
||||
<Image src="/images/invitation-expired.svg" height={500} width={800} alt="invitation expired illustration" />
|
||||
<Image
|
||||
src="/images/invitation-expired.svg"
|
||||
height={500}
|
||||
width={800}
|
||||
alt="invitation expired illustration"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,15 +1,18 @@
|
||||
import { useEffect } from "react";
|
||||
import { useRouter } from "next/router"
|
||||
import { useRouter } from "next/router";
|
||||
|
||||
export default function SecretScanning() {
|
||||
const router = useRouter();
|
||||
|
||||
useEffect(()=>{
|
||||
router.push(`${router.asPath.split("secret-scanning")[0]}/org/${localStorage.getItem("orgData.id")}/secret-scanning${router.asPath.split("secret-scanning")[1]}`)
|
||||
}, [])
|
||||
useEffect(() => {
|
||||
router.push(
|
||||
`${router.asPath.split("secret-scanning")[0]}/org/${localStorage.getItem(
|
||||
"orgData.id"
|
||||
)}/secret-scanning${router.asPath.split("secret-scanning")[1]}`
|
||||
);
|
||||
}, []);
|
||||
|
||||
|
||||
return <div/>;
|
||||
return <div />;
|
||||
}
|
||||
|
||||
SecretScanning.requireAuth = true;
|
||||
SecretScanning.requireAuth = true;
|
||||
|
||||
@@ -1,28 +1,28 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import Head from "next/head";
|
||||
import Image from "next/image";
|
||||
import { useRouter } from "next/router"
|
||||
import { useRouter } from "next/router";
|
||||
|
||||
import { SignupSSO } from "@app/views/Signup";
|
||||
|
||||
export default function SignupSSOPage() {
|
||||
const { t } = useTranslation();
|
||||
const router = useRouter();
|
||||
const token = router.query.token as string;
|
||||
const { t } = useTranslation();
|
||||
const router = useRouter();
|
||||
const token = router.query.token as string;
|
||||
|
||||
return (
|
||||
<div className="flex min-h-screen flex-col justify-center bg-gradient-to-tr from-mineshaft-600 via-mineshaft-800 to-bunker-700 px-6 pb-28 ">
|
||||
<Head>
|
||||
<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("signup.og-title") as string} />
|
||||
<meta name="og:description" content={t("signup.og-description") as string} />
|
||||
</Head>
|
||||
<div className="mb-4 mt-20 flex justify-center">
|
||||
<Image src="/images/gradientLogo.svg" height={90} width={120} alt="Infisical Logo" />
|
||||
</div>
|
||||
<SignupSSO providerAuthToken={token} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<div className="flex min-h-screen flex-col justify-center bg-gradient-to-tr from-mineshaft-600 via-mineshaft-800 to-bunker-700 px-6 pb-28 ">
|
||||
<Head>
|
||||
<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("signup.og-title") as string} />
|
||||
<meta name="og:description" content={t("signup.og-description") as string} />
|
||||
</Head>
|
||||
<div className="mb-4 mt-20 flex justify-center">
|
||||
<Image src="/images/gradientLogo.svg" height={90} width={120} alt="Infisical Logo" />
|
||||
</div>
|
||||
<SignupSSO providerAuthToken={token} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -59,7 +59,10 @@ export default function VerifyEmail() {
|
||||
</div>
|
||||
</Link>
|
||||
{step === 1 && (
|
||||
<form onSubmit={onSubmit} className="h-7/12 mx-auto w-full max-w-md rounded-xl bg-bunker px-6 py-4 pt-8 drop-shadow-xl">
|
||||
<form
|
||||
onSubmit={onSubmit}
|
||||
className="h-7/12 mx-auto w-full max-w-md rounded-xl bg-bunker px-6 py-4 pt-8 drop-shadow-xl"
|
||||
>
|
||||
<p className="mx-auto mb-6 flex w-max justify-center text-2xl font-semibold text-bunker-100 md:text-3xl">
|
||||
Forgot your password?
|
||||
</p>
|
||||
@@ -81,7 +84,13 @@ export default function VerifyEmail() {
|
||||
</div>
|
||||
<div className="mx-auto mt-4 flex max-h-20 w-full max-w-md flex-col items-center justify-center text-sm md:p-2">
|
||||
<div className="text-l m-8 mt-6 px-8 py-3 text-lg">
|
||||
<Button type="submit" text="Continue" size="lg" onButtonPressed={() => {}} loading={loading} />
|
||||
<Button
|
||||
type="submit"
|
||||
text="Continue"
|
||||
size="lg"
|
||||
onButtonPressed={() => {}}
|
||||
loading={loading}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
Reference in New Issue
Block a user