import { PencilSquare, Trash, XCircle } from "@medusajs/icons" import { ApiKeyDTO } from "@medusajs/types" import { Badge, Container, Copy, Heading, StatusBadge, Text, toast, usePrompt, } from "@medusajs/ui" import { useTranslation } from "react-i18next" import { useNavigate } from "react-router-dom" import { Action, ActionMenu, } from "../../../../../components/common/action-menu" import { Skeleton } from "../../../../../components/common/skeleton" import { UserLink } from "../../../../../components/common/user-link" import { useDeleteApiKey, useRevokeApiKey, } from "../../../../../hooks/api/api-keys" import { useUser } from "../../../../../hooks/api/users" import { useDate } from "../../../../../hooks/use-date" import { getApiKeyStatusProps, getApiKeyTypeProps, prettifyRedactedToken, } from "../../../common/utils" type ApiKeyGeneralSectionProps = { apiKey: ApiKeyDTO } export const ApiKeyGeneralSection = ({ apiKey }: ApiKeyGeneralSectionProps) => { const { t } = useTranslation() const navigate = useNavigate() const prompt = usePrompt() const { getFullDate } = useDate() const { mutateAsync: revokeAsync } = useRevokeApiKey(apiKey.id) const { mutateAsync: deleteAsync } = useDeleteApiKey(apiKey.id) const handleDelete = async () => { const res = await prompt({ title: t("general.areYouSure"), description: t("apiKeyManagement.delete.warning", { title: apiKey.title, }), confirmText: t("actions.delete"), cancelText: t("actions.cancel"), }) if (!res) { return } await deleteAsync(undefined, { onSuccess: () => { toast.success( t("apiKeyManagement.delete.successToast", { title: apiKey.title, }) ) navigate("..", { replace: true }) }, onError: (err) => { toast.error(err.message) }, }) } const handleRevoke = async () => { const res = await prompt({ title: t("general.areYouSure"), description: t("apiKeyManagement.revoke.warning", { title: apiKey.title, }), confirmText: t("apiKeyManagement.actions.revoke"), cancelText: t("actions.cancel"), }) if (!res) { return } await revokeAsync(undefined, { onSuccess: () => { toast.success( t("apiKeyManagement.revoke.successToast", { title: apiKey.title, }) ) }, onError: (err) => { toast.error(err.message) }, }) } const dangerousActions: Action[] = [ { icon: , label: t("actions.delete"), onClick: handleDelete, disabled: !apiKey.revoked_at, }, ] if (!apiKey.revoked_at) { dangerousActions.unshift({ icon: , label: t("apiKeyManagement.actions.revoke"), onClick: handleRevoke, disabled: !!apiKey.revoked_at, }) } const apiKeyStatus = getApiKeyStatusProps(apiKey.revoked_at, t) const apiKeyType = getApiKeyTypeProps(apiKey.type, t) return (
{apiKey.title}
{apiKeyStatus.label}
, to: "edit", }, ], }, { actions: dangerousActions, }, ]} />
{t("fields.key")} {apiKey.type === "secret" ? ( {prettifyRedactedToken(apiKey.redacted)} ) : ( {prettifyRedactedToken(apiKey.redacted)} )}
{t("fields.type")} {apiKeyType.label}
{t("apiKeyManagement.fields.lastUsedAtLabel")} {apiKey.last_used_at ? getFullDate({ date: apiKey.last_used_at, includeTime: true }) : "-"}
{t("apiKeyManagement.fields.createdByLabel")}
{apiKey.revoked_at && ( <>
{t("apiKeyManagement.fields.revokedAtLabel")} {getFullDate({ date: apiKey.revoked_at, includeTime: true })}
{t("apiKeyManagement.fields.revokedByLabel")}
)}
) } const ActionBy = ({ userId }: { userId: string | null }) => { const { user, isLoading, isError, error } = useUser(userId!, undefined, { enabled: !!userId, }) if (!userId) { return ( - ) } if (isError) { throw error } if (isLoading) { return (
) } if (!user) { return ( - ) } return }