Improve EnvKeys component

This commit is contained in:
Stan Wohlwend 2024-03-04 15:07:53 +01:00
parent eab70e273c
commit 15f92a6996
3 changed files with 80 additions and 18 deletions

View File

@ -65,7 +65,7 @@ export function OnboardingDialog() {
{/* TODO: Add document link */}
<Stack spacing={1}>
<Paragraph body>
Congratulations on creating your new project! We have automatically created an API key for you. Please copy it to your <InlineCode>.env.local</InlineCode> file; please see the <SmartLink rel="noopener noreferrer" target="_blank" href={process.env.NEXT_PUBLIC_DOC_URL || ""}>Getting Started guide</SmartLink>.
Congratulations on creating your new project! We have automatically created an API key for you. Please copy it to your <InlineCode>.env.local</InlineCode> file; please see the <SmartLink target="_blank" href={process.env.NEXT_PUBLIC_DOC_URL}>Getting Started guide</SmartLink>.
</Paragraph>
<EnvKeys projectId={project.id} publishableClientKey={apiKey.publishableClientKey} secretServerKey={apiKey.secretServerKey} />
<Paragraph body>

View File

@ -13,6 +13,8 @@ import { useAdminApp } from "../../useAdminInterface";
import { runAsynchronously } from "@stackframe/stack-shared/src/utils/promises";
import EnvKeys from "@/components/env-keys";
import Link from "next/link";
import { SmartLink } from "@/components/smart-link";
import { throwErr } from "@stackframe/stack-shared/dist/utils/errors";
export default function ApiKeysDashboardClient() {
@ -101,7 +103,7 @@ function CreateNewDialog(props: { open: boolean, onClose(): void, onInvalidate()
<DialogContent>
<Stack spacing={2} overflow='hidden'>
<Paragraph body>
Success! Your new API keys have been created. <Typography fontWeight="bold">Note that you will not be able to view this again</Typography> and you will need to create a new one if you lose it. Detailed setup instructions can be found <Link rel="noopener noreferrer" target="_blank" href={process.env.NEXT_PUBLIC_DOC_URL || ""}>here</Link>
Success! Your new API keys have been created. <Typography fontWeight="bold">Note that you will not be able to view this again</Typography> and you will need to create a new one if you lose it. Visit the <SmartLink target="_blank" href={process.env.NEXT_PUBLIC_DOC_URL}>documentation</SmartLink> for detailed setup instructions.
</Paragraph>
<EnvKeys
projectId={project.id}

View File

@ -1,4 +1,7 @@
import { Box, Typography } from "@mui/joy";
import { Box, FormControl, FormHelperText, FormLabel, Input, Stack, Tab, TabList, TabPanel, Tabs, Textarea, Typography } from "@mui/joy";
import { CopyButton } from "./copy-button";
import { InlineCode } from "./inline-code";
import { deindent } from "@stackframe/stack-shared/dist/utils/strings";
export default function EnvKeys(props: {
projectId: string,
@ -7,19 +10,76 @@ export default function EnvKeys(props: {
superSecretAdminKey?: string,
}) {
return (
<Box p={2} bgcolor="background.paper" borderRadius={4} overflow='auto'>
<Typography>
NEXT_PUBLIC_STACK_PROJECT_ID={props.projectId}
</Typography>
{props.publishableClientKey && <Typography>
NEXT_PUBLIC_STACK_PUBLISHABLE_CLIENT_KEY={props.publishableClientKey}
</Typography>}
{props.secretServerKey && <Typography>
STACK_SECRET_SERVER_KEY={props.secretServerKey}
</Typography>}
{props.superSecretAdminKey && <Typography>
STACK_SUPER_SECRET_ADMIN_KEY={props.superSecretAdminKey}
</Typography>}
</Box>
<Tabs>
<TabList>
<Tab>API Keys</Tab>
<Tab>Next.js</Tab>
</TabList>
<TabPanel value={0}>
<Stack spacing={2}>
{props.publishableClientKey && (
<CopyField
value={props.publishableClientKey}
label="Publishable client key"
helper="You will use this key in your client-side code. It's safe to expose it to the public."
/>
)}
{props.secretServerKey && (
<CopyField
value={props.secretServerKey}
label="Secret server key"
helper="You will use this key in your server-side code. It can be used to perform actions on behalf of your users, so keep it safe."
/>
)}
{props.superSecretAdminKey && (
<CopyField
value={props.superSecretAdminKey}
label="Super secret admin key"
helper={<>This key is for administrative use only. Anyone owning this key will be able to create unlimited new keys and revoke any other keys. <Typography fontWeight="bold">Be careful!</Typography></>}
/>
)}
</Stack>
</TabPanel>
<TabPanel value={1}>
<CopyField
value={Object.entries({
NEXT_PUBLIC_STACK_PROJECT_ID: props.projectId,
NEXT_PUBLIC_STACK_PUBLISHABLE_CLIENT_KEY: props.publishableClientKey,
STACK_SECRET_SERVER_KEY: props.secretServerKey,
STACK_SUPER_SECRET_ADMIN_KEY: props.superSecretAdminKey,
}).filter(([k, v]) => v).map(([k, v]) => `${k}=${v}`).join("\n")}
label="Environment variables"
helper={<>Copy these variables into your <InlineCode>.env.local</InlineCode> file.</>}
/>
</TabPanel>
</Tabs>
);
}
}
function CopyField(props: { value: string, label?: React.ReactNode, helper?: React.ReactNode }) {
return (
<FormControl>
{props.label && (
<FormLabel>
{props.label}
</FormLabel>
)}
<Box position="relative">
<Textarea
readOnly
value={props.value}
sx={{
paddingRight: 2,
}}
/>
<CopyButton content={props.value} size="sm" sx={{ position: "absolute", right: 2, top: 2 }} />
</Box>
{props.helper && (
<FormHelperText>
{props.helper}
</FormHelperText>
)}
</FormControl>
);
}