Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(platform): Create and Delete API Keys #726

Open
wants to merge 8 commits into
base: develop
Choose a base branch
from
5 changes: 5 additions & 0 deletions apps/platform/public/svg/shared/crown.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 2 additions & 1 deletion apps/platform/public/svg/shared/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ import VectorSVG from './vector.svg'
import ErrorSVG from './Error.svg'
import TrashSVG from './trash.svg'
import CopySVG from './copy.svg'
import CrownSVG from './crown.svg'
import RolesSVG from './roles.svg'
import CheckmarkSVG from './checkmark.svg'


export {
DropdownSVG,
KeyshadeLogoSVG,
Expand All @@ -31,6 +31,7 @@ export {
ErrorSVG,
TrashSVG,
CopySVG,
CrownSVG,
RolesSVG,
CheckmarkSVG
}
Original file line number Diff line number Diff line change
@@ -1,18 +1,31 @@
'use client'

import React, { useCallback, useEffect, useState } from 'react'
import { toast } from 'sonner'
import { useAtom } from 'jotai'
import { useAtom, useAtomValue } from 'jotai'
import InputLoading from './loading'
import { Input } from '@/components/ui/input'
import { Separator } from '@/components/ui/separator'
import ControllerInstance from '@/lib/controller-instance'
import { Button } from '@/components/ui/button'
import { userAtom } from '@/store'
import {
userAtom,
apiKeysOfProjectAtom,
deleteApiKeyOpenAtom,
selectedApiKeyAtom
} from '@/store'
import { useSearchParams } from 'next/navigation'
import AddApiKeyDialog from '@/components/userProfile/apiKeys/addApiKeyDialog'
import ApiKeyCard from '@/components/userProfile/apiKeys/apiKeyCard'
import ConfirmDeleteApiKey from '@/components/userProfile/apiKeys/confirmDeleteApiKey'
import { useHttp } from '@/hooks/use-http'
import { logout } from '@/lib/utils'

function ProfilePage(): React.JSX.Element {
const [user, setUser] = useAtom(userAtom)
const [apiKeys, setApiKeys] = useAtom(apiKeysOfProjectAtom)
const isDeleteApiKeyOpen = useAtomValue(deleteApiKeyOpenAtom)
const selectedApiKey = useAtomValue(selectedApiKeyAtom)

const [isLoading, setIsLoading] = useState<boolean>(true)
const [userData, setUserData] = useState({
Expand All @@ -22,6 +35,9 @@ function ProfilePage(): React.JSX.Element {
})
const [isModified, setIsModified] = useState<boolean>(false)

const searchParams = useSearchParams()
const tab = searchParams.get('profile') ?? 'profile'

const updateSelf = useHttp(() =>
ControllerInstance.getInstance().userController.updateSelf({
name: userData.name === user?.name ? undefined : userData.name,
Expand Down Expand Up @@ -87,6 +103,33 @@ function ProfilePage(): React.JSX.Element {
.finally(() => setIsLoading(false))
}, [getSelf])

useEffect(() => {
const getAllApiKeys = async () => {
const { success, error, data } = await ControllerInstance.getInstance().apiKeyController.getApiKeysOfUser(
{},
{}
)

if (success && data) {
setApiKeys(data.items)
}
if (error) {
toast.error('Something went wrong!', {
description: (
<p className="text-xs text-red-300">
Something went wrong while fetching API Keys. Check console for
more info.
</p>
)
})
// eslint-disable-next-line no-console -- we need to log the error
console.error(error)
}
}

getAllApiKeys()
}, [setApiKeys])

return (
<main className="flex flex-col gap-y-10">
{/* Avatar */}
Expand Down Expand Up @@ -152,15 +195,30 @@ function ProfilePage(): React.JSX.Element {
Save Changes
</Button>
</div>
<Separator className="max-w-[30vw] bg-white/15" />
<div className="flex max-w-[20vw] flex-col gap-4">
<Separator className="w-full bg-white/15" />
<div className="flex flex-row justify-between items-center gap-4 p-3">
<div className="flex flex-col gap-2">
<div className="text-xl font-semibold">API Keys</div>
<span className="text-sm text-white/70">
Generate new API keys to use with the Keyshade CLI.
</span>
</div>
<div>
{tab === 'profile' && <AddApiKeyDialog />}
</div>
</div>
{apiKeys.length !== 0 &&
<div className={`grid h-fit w-full grid-cols-1 gap-8 p-3 text-white md:grid-cols-2 xl:grid-cols-3 `}>
{apiKeys.map((apiKey) => (
<ApiKeyCard apiKey={apiKey} key={apiKey.id} />
))}

{/* Delete API Key alert dialog */}
{isDeleteApiKeyOpen && selectedApiKey ? (
<ConfirmDeleteApiKey />
) : null}
</div>
}

<Separator className="max-w-[30vw] bg-white/15" />

Expand Down
Loading
Loading