diff --git a/apps/studio/components/layouts/InterstitialLayout.tsx b/apps/studio/components/layouts/InterstitialLayout.tsx index ba7981cca87..7259e6ca7d3 100644 --- a/apps/studio/components/layouts/InterstitialLayout.tsx +++ b/apps/studio/components/layouts/InterstitialLayout.tsx @@ -103,15 +103,30 @@ export const SupabaseLogo = () => ( ) +export const PartnerLogo = ({ src, alt }: { src: string; alt: string }) => ( + + {alt} + +) + export const InterstitialAccountRow = ({ avatarUrl, displayName, + action, + className, }: { avatarUrl?: string displayName?: string + action?: ReactNode + className?: string }) => ( - - + + Loading account}

+ {action}
) diff --git a/apps/studio/pages/partners/stripe/projects/login.tsx b/apps/studio/pages/partners/stripe/projects/login.tsx index 80b7862fc71..bb8d48bc9d4 100644 --- a/apps/studio/pages/partners/stripe/projects/login.tsx +++ b/apps/studio/pages/partners/stripe/projects/login.tsx @@ -1,33 +1,36 @@ import { useQuery } from '@tanstack/react-query' import { useParams } from 'common' +import { LogOut } from 'lucide-react' import Head from 'next/head' import { useRouter } from 'next/router' import { useEffect } from 'react' -import { Button, LogoLoader } from 'ui' -import { Admonition } from 'ui-patterns' +import { Button } from 'ui' +import { Admonition, ShimmeringLoader } from 'ui-patterns' -import { APIAuthorizationLayout } from '@/components/layouts/APIAuthorizationLayout' +import { + InterstitialAccountRow, + InterstitialLayout, + LogoPair, + PartnerLogo, + SupabaseLogo, +} from '@/components/layouts/InterstitialLayout' +import { ButtonTooltip } from '@/components/ui/ButtonTooltip' import { useConfirmAccountRequestMutation } from '@/data/partners/stripe-projects-confirm-mutation' import { accountRequestQueryOptions } from '@/data/partners/stripe-projects-query' import { withAuth } from '@/hooks/misc/withAuth' import { useSignOut } from '@/lib/auth' import { BASE_PATH } from '@/lib/constants' +import { buildStudioPageTitle } from '@/lib/page-title' +import { useProfileNameAndPicture } from '@/lib/profile' +import type { NextPageWithLayout } from '@/types' -const StripeIcon = () => ( - Stripe -) +const PAGE_TITLE = buildStudioPageTitle({ section: 'Authorize Stripe Projects', brand: 'Supabase' }) -const StripeProjectsLoginPage = () => { +const StripeProjectsLoginPage: NextPageWithLayout = () => { const router = useRouter() const { ar_id } = useParams() - const signOut = useSignOut() + const { username, primaryEmail, avatarUrl } = useProfileNameAndPicture() const { data: accountRequest, @@ -51,7 +54,6 @@ const StripeProjectsLoginPage = () => { if (!ar_id) { router.push('/404') - return } }, [router.isReady, ar_id, router]) @@ -60,110 +62,157 @@ const StripeProjectsLoginPage = () => { confirmAccountRequest({ arId: ar_id }) } - const isPending = isQueryPending - const isSuccess = isQuerySuccess - const isConfirmed = isConfirmationSuccess - const isConfirming = isConfirmationPending - const isError = isQueryError - const linkedOrg = accountRequest?.linked_organization const emailMatches = accountRequest?.email_matches ?? false - - const loadingText = linkedOrg ? 'Authorizing...' : 'Creating organization...' - const successTitle = linkedOrg ? 'Authorized' : 'Organization created' - const successDescription = linkedOrg - ? null - : 'Your Supabase organization has been created and linked to your Stripe account.' + const displayName = primaryEmail ?? username ?? accountRequest?.email ?? '' + const isPending = router.isReady && isQueryPending + const isConfirmed = isConfirmationSuccess + const isConfirming = isConfirmationPending + const isSuccess = isQuerySuccess + const isError = isQueryError + const showAuthorizationState = isSuccess && !isConfirmed + const interstitialDescription = isConfirmed + ? undefined + : 'This will create an organization on your behalf in Supabase' return ( - -
- {isConfirming ? ( - <> - -

{loadingText}

- - ) : isConfirmed ? ( - <> - -

{successTitle}

-

- {successDescription && `${successDescription} `} - You can close this window. -

- - ) : isPending ? ( - - ) : isSuccess ? ( - <> - -

- Stripe Projects is requesting access -

-

- Stripe Projects wants to connect to the Supabase account for{' '} - {accountRequest?.email}. - {emailMatches && !linkedOrg && ( - <> This will create a new Supabase organization linked to Stripe. - )} -

- {!emailMatches ? ( - <> - -

- You're signed in as a different account. Sign out and sign back in as{' '} - {accountRequest?.email}. Then - return to Stripe to restart the request. -

-
-
- + <> + + {PAGE_TITLE} + + + } + right={} + /> + } + title="Authorize Stripe Projects" + description={interstitialDescription} + > +
+ {isPending && ( +
+
+ +
+ +
- - ) : linkedOrg ? ( - // Org already linked to this Stripe account — inform user and confirm - <> - -

- {linkedOrg.name} is already linked - to Stripe. Authorize Stripe Projects to continue. -

-
-
- -
- - ) : ( - // No linked org — a new one will be created -
- +
- )} - - ) : isError ? ( - <> -

Error

-

{error?.message}

-
-
+ )} + + {isConfirmed && ( +
+ +

+ You can now close this tab. +

+
+ )} + + {showAuthorizationState && !emailMatches && ( +
+ + You're signed in to a different account. Sign out and sign back in as{' '} + {accountRequest?.email}. + Then return to Stripe to restart the request. + + } + /> +
- - ) : null} -
- + )} + + {showAuthorizationState && emailMatches && linkedOrg && ( +
+ + {linkedOrg.name} is already + linked to this Stripe account, and just needs to be confirmed. + + } + /> +
+ + +
+
+ )} + + {showAuthorizationState && emailMatches && !linkedOrg && ( +
+ signOut()} + icon={ + + } + tooltip={{ + content: { + side: 'top', + text: 'Sign out', + }, + }} + /> + } + /> + +
+ + +
+
+ )} + + {isError && ( +
+ + +
+ )} +
+ + ) }