Repository: supabase/supabase
File: apps/studio/components/interfaces/Organization/ProjectClaim/confirm.tsx (TypeScript)

Code before:
  Collapsible_Shadcn_,
  CollapsibleContent_Shadcn_,
  CollapsibleTrigger_Shadcn_,
} from 'ui'
import { Admonition } from 'ui-patterns/admonition'
import { ScopeSection } from '../OAuthApps/AuthorizeRequesterDetails'
import { PERMISSIONS_DESCRIPTIONS } from '../OAuthApps/OAuthApps.constants'
import { ProjectClaimLayout } from './layout'

export const ProjectClaimConfirm = ({
  selectedOrganization,
  projectClaim,
  requester,
  setStep,
}: {
  selectedOrganization: Organization
  projectClaim: OrganizationProjectClaimResponse
  requester: ApiAuthorizationResponse
  setStep: (step: 'choose-org' | 'benefits' | 'confirm') => void
}) => {
  const router = useRouter()
  const { auth_id, token: claimToken } = useParams()
  const queryClient = useQueryClient()

  const { mutateAsync: approveRequest, isLoading: isApproving } =
    useApiAuthorizationApproveMutation()

  const { mutateAsync: claimProject, isLoading: isClaiming } = useOrganizationProjectClaimMutation()

  const onClaimProject = async () => {
    try {
      const response = await approveRequest({ id: auth_id!, slug: selectedOrganization.slug })
      await claimProject({
        slug: selectedOrganization.slug,
        token: claimToken!,
      })

      toast.success('Project claimed successfully')
      try {
        // check if the redirect url is valid. If not, redirect the user to the org dashboard
        const url = new URL(response.url)
        window.location.href = url.toString()
      } catch {
        // invalidate the org projects to force them to be refetched
        queryClient.invalidateQueries(projectKeys.list())
        router.push(`/org/${selectedOrganization.slug}`)
      }
    } catch (error: any) {
      toast.error(`Failed to claim project ${error.message}`)
    }
  }

Review comment (suggestion):
To avoid double toasts, there's another in a `try/catch` block which catches errors from 2 API calls.

Code after:
  Collapsible_Shadcn_,
  CollapsibleContent_Shadcn_,
  CollapsibleTrigger_Shadcn_,
} from 'ui'
import { Admonition } from 'ui-patterns/admonition'
import { ScopeSection } from '../OAuthApps/AuthorizeRequesterDetails'
import { PERMISSIONS_DESCRIPTIONS } from '../OAuthApps/OAuthApps.constants'
import { ProjectClaimLayout } from './layout'

export const ProjectClaimConfirm = ({
  selectedOrganization,
  projectClaim,
  requester,
  setStep,
}: {
  selectedOrganization: Organization
  projectClaim: OrganizationProjectClaimResponse
  requester: ApiAuthorizationResponse
  setStep: (step: 'choose-org' | 'benefits' | 'confirm') => void
}) => {
  const router = useRouter()
  const { auth_id, token: claimToken } = useParams()
  const queryClient = useQueryClient()

  const { mutateAsync: approveRequest, isLoading: isApproving } =
    useApiAuthorizationApproveMutation({ onError: () => {} })

  const { mutateAsync: claimProject, isLoading: isClaiming } = useOrganizationProjectClaimMutation()

  const onClaimProject = async () => {
    try {
      const response = await approveRequest({ id: auth_id!, slug: selectedOrganization.slug })

      await claimProject({
        slug: selectedOrganization.slug,
        token: claimToken!,
      })

      toast.success('Project claimed successfully')
      try {
        // check if the redirect url is valid. If not, redirect the user to the org dashboard
        const url = new URL(response.url)
        window.location.href = url.toString()
      } catch {
        // invalidate the org projects to force them to be refetched
        queryClient.invalidateQueries(projectKeys.list())
        router.push(`/org/${selectedOrganization.slug}`)
      }
    } catch (error: any) {
      toast.error(`Failed to claim project ${error.message}`)
    }