mirror of
https://github.com/supabase/supabase.git
synced 2026-06-01 10:21:10 +08:00
130 lines
4.2 KiB
TypeScript
130 lines
4.2 KiB
TypeScript
import { useParams } from 'common'
|
|
import Head from 'next/head'
|
|
import { PropsWithChildren, useMemo, useState } from 'react'
|
|
import { Admonition } from 'ui-patterns/admonition'
|
|
import { ShimmeringLoader } from 'ui-patterns/ShimmeringLoader'
|
|
|
|
import { ProjectClaimBenefits } from '@/components/interfaces/Organization/ProjectClaim/benefits'
|
|
import { ProjectClaimChooseOrg } from '@/components/interfaces/Organization/ProjectClaim/choose-org'
|
|
import { ProjectClaimConfirm } from '@/components/interfaces/Organization/ProjectClaim/confirm'
|
|
import { ProjectClaimLayout } from '@/components/interfaces/Organization/ProjectClaim/layout'
|
|
import { useApiAuthorizationQuery } from '@/data/api-authorization/api-authorization-query'
|
|
import { useOrganizationProjectClaimQuery } from '@/data/organizations/organization-project-claim-query'
|
|
import { useOrganizationsQuery } from '@/data/organizations/organizations-query'
|
|
import { useCustomContent } from '@/hooks/custom-content/useCustomContent'
|
|
import { withAuth } from '@/hooks/misc/withAuth'
|
|
import type { NextPageWithLayout } from '@/types'
|
|
|
|
const ClaimProjectPageLayout = ({ children }: PropsWithChildren) => {
|
|
const { appTitle } = useCustomContent(['app:title'])
|
|
|
|
return (
|
|
<>
|
|
<Head>
|
|
<title>{`Claim project | ${appTitle ?? 'Supabase'}`}</title>
|
|
</Head>
|
|
{children}
|
|
</>
|
|
)
|
|
}
|
|
|
|
const ClaimProjectPage: NextPageWithLayout = () => {
|
|
const { auth_id, token: claimToken } = useParams()
|
|
const [selectedOrgSlug, setSelectedOrgSlug] = useState<string>()
|
|
const [step, setStep] = useState<'choose-org' | 'benefits' | 'confirm'>('choose-org')
|
|
|
|
const {
|
|
data: requester,
|
|
isPending: isLoadingRequester,
|
|
isError: isErrorRequester,
|
|
error: errorRequester,
|
|
} = useApiAuthorizationQuery({ id: auth_id })
|
|
const { data: organizations } = useOrganizationsQuery()
|
|
|
|
const selectedOrganization = useMemo(() => {
|
|
return (organizations || []).find((org) => org.slug === selectedOrgSlug)
|
|
}, [selectedOrgSlug, organizations])
|
|
|
|
const {
|
|
data: projectClaim,
|
|
error: errorProjectClaim,
|
|
isError: isErrorProjectClaim,
|
|
isPending: isLoadingProjectClaim,
|
|
isSuccess: isSuccessProjectClaim,
|
|
} = useOrganizationProjectClaimQuery(
|
|
{
|
|
slug: selectedOrgSlug!,
|
|
token: claimToken!,
|
|
},
|
|
{
|
|
enabled: !!claimToken && !!selectedOrgSlug,
|
|
}
|
|
)
|
|
|
|
if ((selectedOrgSlug && claimToken && isLoadingProjectClaim) || isLoadingRequester) {
|
|
return (
|
|
<ProjectClaimLayout title="Claim a project" className="py-6">
|
|
<div className="space-y-2">
|
|
<ShimmeringLoader />
|
|
<ShimmeringLoader className="w-3/4" />
|
|
<ShimmeringLoader className="w-1/2" />
|
|
</div>
|
|
</ProjectClaimLayout>
|
|
)
|
|
}
|
|
|
|
if ((selectedOrgSlug && claimToken && isErrorProjectClaim) || isErrorRequester) {
|
|
return (
|
|
<ProjectClaimLayout title="Claim a project" className="py-6">
|
|
<Admonition type="warning" title="Failed to retrieve project claim request details">
|
|
<p>Please retry your claim request from the requesting app</p>
|
|
{!!errorProjectClaim && <p className="mt-2">Error: {errorProjectClaim?.message}</p>}
|
|
{!!errorRequester && <p className="mt-2">Error: {errorRequester?.message}</p>}
|
|
</Admonition>
|
|
</ProjectClaimLayout>
|
|
)
|
|
}
|
|
|
|
if (step === 'choose-org' || !selectedOrganization) {
|
|
return (
|
|
<ProjectClaimChooseOrg
|
|
onChoose={(orgSlug) => {
|
|
setSelectedOrgSlug(orgSlug)
|
|
setStep('benefits')
|
|
}}
|
|
/>
|
|
)
|
|
}
|
|
|
|
if (isSuccessProjectClaim) {
|
|
if (step === 'benefits') {
|
|
return (
|
|
<ProjectClaimBenefits
|
|
projectClaim={projectClaim}
|
|
requester={requester}
|
|
onContinue={() => setStep('confirm')}
|
|
/>
|
|
)
|
|
}
|
|
|
|
return (
|
|
<ProjectClaimConfirm
|
|
setStep={setStep}
|
|
selectedOrganization={selectedOrganization}
|
|
projectClaim={projectClaim}
|
|
requester={requester}
|
|
/>
|
|
)
|
|
}
|
|
|
|
return null
|
|
}
|
|
|
|
ClaimProjectPage.getLayout = (page) => (
|
|
<ClaimProjectPageLayout>
|
|
<main className="flex flex-col w-full min-h-screen overflow-y-auto">{page}</main>
|
|
</ClaimProjectPageLayout>
|
|
)
|
|
|
|
export default withAuth(ClaimProjectPage)
|