import dayjs from 'dayjs' import Link from 'next/link' import { useRouter } from 'next/router' import { useEffect, useState } from 'react' import { toast } from 'sonner' import { useParams } from 'common' import { AuthorizeRequesterDetails } from 'components/interfaces/Organization/OAuthApps/AuthorizeRequesterDetails' import APIAuthorizationLayout from 'components/layouts/APIAuthorizationLayout' 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_Shadcn_, AlertDescription_Shadcn_, AlertTitle_Shadcn_, Button, Card, CardContent, CardFooter, CardHeader, CheckIcon, Select_Shadcn_, SelectContent_Shadcn_, SelectItem_Shadcn_, SelectTrigger_Shadcn_, SelectValue_Shadcn_, WarningIcon, } from 'ui' import { FormLayout } from 'ui-patterns/form/Layout/FormLayout' // 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, organization_slug } = useParams() const [isApproving, setIsApproving] = useState(false) const [isDeclining, setIsDeclining] = useState(false) const [selectedOrgSlug, setSelectedOrgSlug] = useState() const { data: organizations, isSuccess: isSuccessOrganizations, 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 searchParams = typeof window !== 'undefined' ? new URLSearchParams(location.search) : new URLSearchParams() const basePath = process.env.NEXT_PUBLIC_BASE_PATH const pathname = typeof window !== 'undefined' ? basePath ? location.pathname.replace(basePath, '') : location.pathname : '' searchParams.set('returnTo', pathname) const { mutate: approveRequest } = useApiAuthorizationApproveMutation({ onSuccess: (res) => { window.location.href = res.url }, }) const { mutate: declineRequest } = useApiAuthorizationDeclineMutation({ onSuccess: () => { toast.success('Declined API authorization request') router.push('/organizations') }, }) 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') } setIsApproving(true) approveRequest({ id: auth_id, slug: selectedOrgSlug }, { onError: () => setIsApproving(false) }) } 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') } setIsDeclining(true) declineRequest({ id: auth_id, slug: selectedOrgSlug }, { onError: () => setIsDeclining(false) }) } useEffect(() => { if (isSuccessOrganizations && organizations.length > 0) { if (organization_slug) { setSelectedOrgSlug(organizations.find(({ slug }) => slug === organization_slug)?.slug) } else { setSelectedOrgSlug(organizations[0].slug) } } // eslint-disable-next-line react-hooks/exhaustive-deps }, [isSuccessOrganizations]) if (isLoading) { return ( Authorize API access
) } if (isError) { return ( Authorize API access Failed to fetch details for API authorization request

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} This authorization request has been approved

{requester.name} has been approved access to the organization " {approvedOrganization?.name ?? 'Unknown'}" and all of its projects for the following scopes:

Approved on: {dayjs(requester.approved_at).format('DD MMM YYYY HH:mm:ss (ZZ)')}

) } return ( Authorize API access for {requester?.name} {isExpired && ( This authorization request is expired Please retry your authorization request from the requesting app )} {isLoadingOrganizations ? (
) : organizations?.length === 0 ? ( Organization is needed for installing an integration Your account isn't associated with any organizations. To use this integration, it must be installed within an organization. You'll be redirected to create an organization first. ) : organization_slug && !selectedOrgSlug ? ( Organization is needed for installing an integration Your account is not a member of the pre-selected organization. To use this integration, it must be installed within an organization your account is associated with. ) : ( {organizations?.find((x) => x.slug === selectedOrgSlug)?.name} {(organizations ?? []).map((organization) => ( {organization.name} ))} )}
{isLoadingOrganizations ? ( ) : isSuccessOrganizations && organizations.length === 0 ? ( ) : ( )}
) } APIAuthorizationPage.getLayout = (page) => {page} export default withAuth(APIAuthorizationPage)