import { useParams } from 'common'
import dayjs from 'dayjs'
import { useRouter } from 'next/router'
import { useEffect, useState } from 'react'
import { toast } from 'sonner'
import AuthorizeRequesterDetails from 'components/interfaces/Organization/OAuthApps/AuthorizeRequesterDetails'
import APIAuthorizationLayout from 'components/layouts/APIAuthorizationLayout'
import { FormPanel } from 'components/ui/Forms/FormPanel'
import ShimmeringLoader from 'components/ui/ShimmeringLoader'
import { useApiAuthorizationApproveMutation } from 'data/api-authorization/api-authorization-approve-mutation'
import { useApiAuthorizationDeclineMutation } from 'data/api-authorization/api-authorization-decline-mutation'
import { useApiAuthorizationQuery } from 'data/api-authorization/api-authorization-query'
import { useOrganizationsQuery } from 'data/organizations/organizations-query'
import { withAuth } from 'hooks/misc/withAuth'
import type { NextPageWithLayout } from 'types'
import { Alert, Button, Listbox } from 'ui'
// Need to handle if no organizations in account
// Need to handle if not logged in yet state
const APIAuthorizationPage: NextPageWithLayout = () => {
const router = useRouter()
const { auth_id } = useParams()
const [selectedOrgSlug, setSelectedOrgSlug] = useState()
const { data: organizations, isLoading: isLoadingOrganizations } = useOrganizationsQuery()
const { data: requester, isLoading, isError, error } = useApiAuthorizationQuery({ id: auth_id })
const isApproved = (requester?.approved_at ?? null) !== null
const isExpired = dayjs().isAfter(dayjs(requester?.expires_at))
const { mutate: approveRequest, isLoading: isApproving } = useApiAuthorizationApproveMutation({
onSuccess: (res) => {
window.location.href = res.url
},
})
const { mutate: declineRequest, isLoading: isDeclining } = useApiAuthorizationDeclineMutation({
onSuccess: () => {
toast.success('Declined API authorization request')
router.push('/projects')
},
})
const isSubmitting = isApproving || isDeclining
useEffect(() => {
if (!isLoadingOrganizations) {
setSelectedOrgSlug(organizations?.[0].slug ?? undefined)
}
}, [isLoadingOrganizations])
const onApproveRequest = async () => {
if (!auth_id) {
return toast.error('Unable to approve request: auth_id is missing ')
}
if (!selectedOrgSlug) {
return toast.error('Unable to approve request: No organization selected')
}
approveRequest({ id: auth_id, slug: selectedOrgSlug })
}
const onDeclineRequest = async () => {
if (!auth_id) {
return toast.error('Unable to decline request: auth_id is missing ')
}
if (!selectedOrgSlug) {
return toast.error('Unable to decline request: No organization selected')
}
declineRequest({ id: auth_id, slug: selectedOrgSlug })
}
if (isLoading) {
return (
Authorize API access
}>
)
}
if (auth_id === undefined) {
return (
Authorization for API access}>
Please provide a valid authorization ID in the URL
)
}
if (isError) {
return (
Authorize API access}>
Please retry your authorization request from the requesting app
{error !== undefined && Error: {error?.message}
}
)
}
if (isApproved) {
const approvedOrganization = organizations?.find(
(org) => org.slug === requester.approved_organization_slug
)
return (
Authorize API access for {requester?.name}}>
{requester.name} has read and write access to the organization "
{approvedOrganization?.name ?? 'Unknown'}" and all of its projects
Approved on: {dayjs(requester.approved_at).format('DD MMM YYYY HH:mm:ss (ZZ)')}
)
}
return (
Authorize API access for {requester?.name}}
footer={
}
>
{/* API Authorization requester details */}
{/* Expiry warning */}
{isExpired && (
Please retry your authorization request from the requesting app
)}
{/* Organization selection */}
{isLoadingOrganizations ? (
) : (
{(organizations ?? []).map((organization) => (
{organization.name}
))}
)}
)
}
APIAuthorizationPage.getLayout = (page) => {page}
export default withAuth(APIAuthorizationPage)