feat(api-keys): Add API overview

This commit is contained in:
Myzel394 2023-03-10 22:55:27 +01:00
parent 7cd798a343
commit eeb6ba4892
No known key found for this signature in database
GPG Key ID: 79CC92F37B3E1A2B
7 changed files with 130 additions and 1 deletions

View File

@ -0,0 +1,10 @@
{
"title": "Manage your API Keys",
"create": {
"label": "Create a new API Key"
},
"emptyState": {
"title": "Welcome to your API Keys",
"description": "Create an API Key to get started with the API."
}
}

View File

@ -3,6 +3,6 @@
"actions": {
"enable2fa": "Two-Factor-Authentication",
"aliasPreferences": "Alias Preferences",
"apiKeys": "Edit API Keys"
"apiKeys": "Manage API Keys"
}
}

View File

@ -28,6 +28,7 @@ import ReservedAliasDetailRoute from "~/routes/ReservedAliasDetailRoute"
import ReservedAliasesRoute from "~/routes/ReservedAliasesRoute"
import RootRoute from "~/routes/Root"
import Settings2FARoute from "~/routes/Settings2FARoute"
import SettingsAPIKeysRoute from "~/routes/SettingsAPIKeysRoute"
import SettingsAliasPreferencesRoute from "~/routes/SettingsAliasPreferencesRoute"
import SettingsRoute from "~/routes/SettingsRoute"
import SignupRoute from "~/routes/SignupRoute"
@ -105,6 +106,10 @@ const router = createBrowserRouter([
path: "/settings/2fa",
element: <Settings2FARoute />,
},
{
path: "/settings/api-keys",
element: <SettingsAPIKeysRoute />,
},
{
path: "/reports",
loader: getServerSettings,

View File

@ -0,0 +1,24 @@
import {ReactElement} from "react"
import {APIKey} from "~/server-types"
import {IconButton, ListItem, ListItemSecondaryAction, ListItemText} from "@mui/material"
import {useTranslation} from "react-i18next"
import {MdDelete} from "react-icons/md"
export interface APIKeyListItemProps {
apiKey: APIKey
}
export default function APIKeyListItem({apiKey}: APIKeyListItemProps): ReactElement {
const {t} = useTranslation("settings-api-keys")
return (
<ListItem>
<ListItemText primary={apiKey.label} secondary={apiKey.expiresAt.toString()} />
<ListItemSecondaryAction>
<IconButton edge="end">
<MdDelete />
</IconButton>
</ListItemSecondaryAction>
</ListItem>
)
}

View File

@ -0,0 +1,35 @@
import {ReactElement} from "react"
import {useTranslation} from "react-i18next"
import {Container, Grid, Typography} from "@mui/material"
import {MdVpnKey} from "react-icons/md"
export default function EmptyStateScreen(): ReactElement {
const {t} = useTranslation("settings-api-keys")
return (
<Container maxWidth="xs">
<Grid
container
spacing={4}
direction="column"
alignItems="center"
maxWidth="80%"
alignSelf="center"
marginX="auto"
>
<Grid item>
<Typography variant="h6" component="h2">
{t("emptyState.title")}
</Typography>
</Grid>
<Grid item>
<MdVpnKey size={40} />
</Grid>
<Grid item>
<Typography variant="body1">{t("emptyState.description")}</Typography>
</Grid>
</Grid>
</Container>
)
}

View File

@ -0,0 +1,48 @@
import {ReactElement} from "react"
import {useTranslation} from "react-i18next"
import {useQuery} from "@tanstack/react-query"
import {APIKey, PaginationResult} from "~/server-types"
import {AxiosError} from "axios"
import {getAPIKeys} from "~/apis"
import {QueryResult, SimplePage} from "~/components"
import {Button, List} from "@mui/material"
import {Link} from "react-router-dom"
import APIKeyListItem from "~/route-widgets/SettingsAPIKeysRoute/APIKeyListItem"
import EmptyStateScreen from "~/route-widgets/SettingsAPIKeysRoute/EmptyStateScreen"
export default function SettingsAPIKeysRoute(): ReactElement {
const {t} = useTranslation("settings-api-keys")
const query = useQuery<PaginationResult<APIKey>, AxiosError>(["get_api_keys"], () =>
getAPIKeys(),
)
return (
<SimplePage
title={t("title")}
actions={
<Button
variant="contained"
color="primary"
component={Link}
to="/settings/api-keys/new"
>
{t("create.label")}
</Button>
}
>
<QueryResult<PaginationResult<APIKey>, AxiosError> query={query}>
{({items: apiKeys}) =>
apiKeys.length > 0 ? (
<List>
{apiKeys.map(apiKey => (
<APIKeyListItem apiKey={apiKey} key={apiKey.id} />
))}
</List>
) : (
<EmptyStateScreen />
)
}
</QueryResult>
</SimplePage>
)
}

View File

@ -141,6 +141,13 @@ export interface AliasList {
type: AliasType
}
export interface APIKey {
id: string
label: string
expiresAt: Date
scopes: string[]
}
export interface Report {
id: string
encryptedContent: string