mirror of
https://github.com/supabase/supabase.git
synced 2026-10-05 09:25:06 +03:00
feat: Pricing for TPA (#28454)
* Don't set fixed height on the generateSecret button in hooks sheet. * Block two of the TPA providers on free plan orgs. * Fix some copy. Add more explanation about the pricing. * Update copy --------- Co-authored-by: Joshen Lim <joshenlimek@gmail.com>
This commit is contained in:
1 parent
d4eb4ed341
commit
b73317fc67
4 files changed
+94
-26
No files matched your search
@@ -225,7 +225,7 @@ export const CreateHookSheet = ({
|
||||
|
||||
return (
|
||||
<Sheet open={visible} onOpenChange={() => onClose()}>
|
||||
<SheetContent showClose={false} className="flex flex-col gap-0">
|
||||
<SheetContent size="lg" showClose={false} className="flex flex-col gap-0">
|
||||
<SheetHeader className="py-3 flex flex-row justify-between items-center border-b-0">
|
||||
<div className="flex flex-row gap-3 items-center">
|
||||
<SheetClose
|
||||
@@ -383,7 +383,7 @@ export const CreateHookSheet = ({
|
||||
<Button
|
||||
type="default"
|
||||
size="small"
|
||||
className="rounded-l-none h-[38px]"
|
||||
className="rounded-l-none"
|
||||
onClick={() => {
|
||||
const authHookSecret = generateAuthHookSecret()
|
||||
form.setValue('httpsValues.secret', authHookSecret)
|
||||
|
||||
+78
-19
@@ -1,18 +1,25 @@
|
||||
import { ChevronDown } from 'lucide-react'
|
||||
import Image from 'next/image'
|
||||
|
||||
import { IS_PLATFORM } from 'common'
|
||||
import { useOrgSubscriptionQuery } from 'data/subscriptions/org-subscription-query'
|
||||
import { useSelectedOrganization } from 'hooks/misc/useSelectedOrganization'
|
||||
import {
|
||||
Button,
|
||||
cn,
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuLabel,
|
||||
DropdownMenuSeparator,
|
||||
DropdownMenuTrigger,
|
||||
} from 'ui'
|
||||
import {
|
||||
INTEGRATION_TYPES,
|
||||
getIntegrationTypeIcon,
|
||||
getIntegrationTypeLabel,
|
||||
INTEGRATION_TYPES,
|
||||
} from './ThirdPartyAuthForm.utils'
|
||||
import Link from 'next/link'
|
||||
|
||||
interface AddIntegrationDropdownProps {
|
||||
buttonText?: string
|
||||
@@ -21,9 +28,38 @@ interface AddIntegrationDropdownProps {
|
||||
|
||||
const Providers: INTEGRATION_TYPES[] = ['firebase', 'auth0', 'awsCognito']
|
||||
|
||||
const ProviderDropdownItem = ({
|
||||
disabled,
|
||||
type,
|
||||
onSelectIntegrationType,
|
||||
}: {
|
||||
disabled?: boolean
|
||||
type: INTEGRATION_TYPES
|
||||
onSelectIntegrationType: (type: INTEGRATION_TYPES) => void
|
||||
}) => {
|
||||
return (
|
||||
<DropdownMenuItem
|
||||
key={type}
|
||||
onClick={() => onSelectIntegrationType(type)}
|
||||
className={cn('flex items-center gap-x-2 p-2', disabled && 'cursor-not-allowed')}
|
||||
disabled={disabled}
|
||||
>
|
||||
<Image src={getIntegrationTypeIcon(type)} width={16} height={16} alt={`${type} icon`} />
|
||||
<span>{getIntegrationTypeLabel(type)}</span>
|
||||
</DropdownMenuItem>
|
||||
)
|
||||
}
|
||||
|
||||
export const AddIntegrationDropdown = ({
|
||||
onSelectIntegrationType,
|
||||
}: AddIntegrationDropdownProps) => {
|
||||
const organization = useSelectedOrganization()
|
||||
|
||||
const { data: subscription } = useOrgSubscriptionQuery(
|
||||
{ orgSlug: organization?.slug },
|
||||
{ enabled: IS_PLATFORM }
|
||||
)
|
||||
|
||||
return (
|
||||
<DropdownMenu modal={false}>
|
||||
<DropdownMenuTrigger asChild>
|
||||
@@ -31,25 +67,48 @@ export const AddIntegrationDropdown = ({
|
||||
Add provider
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent align="end">
|
||||
{Providers.map((type) => {
|
||||
const name = getIntegrationTypeLabel(type)
|
||||
return (
|
||||
<DropdownMenuItem
|
||||
key={name}
|
||||
onClick={() => onSelectIntegrationType(type)}
|
||||
className="flex items-center gap-x-2 p-2"
|
||||
>
|
||||
<Image
|
||||
src={getIntegrationTypeIcon(type)}
|
||||
width={16}
|
||||
height={16}
|
||||
alt={`${name} icon`}
|
||||
<DropdownMenuContent align="end" className="w-56">
|
||||
<ProviderDropdownItem type="firebase" onSelectIntegrationType={onSelectIntegrationType} />
|
||||
|
||||
{subscription?.plan.id === 'free' ? (
|
||||
<>
|
||||
<DropdownMenuSeparator />
|
||||
<div className="bg-surface-200 -m-1 p-2">
|
||||
<DropdownMenuLabel className="grid gap-1">
|
||||
<p className="text-foreground-light">Unavailable on the Free plan</p>
|
||||
<p className="text-foreground-lighter text-xs">
|
||||
<Link
|
||||
target="_href"
|
||||
rel="noreferrer"
|
||||
className="underline hover:text-foreground-light transition"
|
||||
href={`/org/${organization?.slug}/billing`}
|
||||
>
|
||||
Upgrade your plan
|
||||
</Link>{' '}
|
||||
to add the following providers to your project.
|
||||
</p>
|
||||
</DropdownMenuLabel>
|
||||
<ProviderDropdownItem
|
||||
disabled
|
||||
type="auth0"
|
||||
onSelectIntegrationType={onSelectIntegrationType}
|
||||
/>
|
||||
<span>{name}</span>
|
||||
</DropdownMenuItem>
|
||||
)
|
||||
})}
|
||||
<ProviderDropdownItem
|
||||
disabled
|
||||
type="awsCognito"
|
||||
onSelectIntegrationType={onSelectIntegrationType}
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<ProviderDropdownItem type="auth0" onSelectIntegrationType={onSelectIntegrationType} />
|
||||
<ProviderDropdownItem
|
||||
type="awsCognito"
|
||||
onSelectIntegrationType={onSelectIntegrationType}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
)
|
||||
|
||||
@@ -21,9 +21,9 @@ import { CreateAwsCognitoAuthIntegrationDialog } from './CreateAwsCognitoAuthDia
|
||||
import { CreateFirebaseAuthIntegrationDialog } from './CreateFirebaseAuthDialog'
|
||||
import { IntegrationCard } from './IntegrationCard'
|
||||
import {
|
||||
INTEGRATION_TYPES,
|
||||
getIntegrationType,
|
||||
getIntegrationTypeLabel,
|
||||
INTEGRATION_TYPES,
|
||||
} from './ThirdPartyAuthForm.utils'
|
||||
|
||||
export const ThirdPartyAuthForm = () => {
|
||||
@@ -62,14 +62,23 @@ export const ThirdPartyAuthForm = () => {
|
||||
<div className="pb-4">
|
||||
<FormHeader
|
||||
title="Third Party Auth"
|
||||
className="mb-1"
|
||||
description="Use third-party authentication (TPA) systems based on JWTs to access your project."
|
||||
actions={
|
||||
integrations.length !== 0 ? (
|
||||
<AddIntegrationDropdown onSelectIntegrationType={setSelectedIntegration} />
|
||||
) : null
|
||||
}
|
||||
docsUrl="https://supabase.com/docs/guides/auth/third-party/overview"
|
||||
/>
|
||||
|
||||
<div className="prose text-sm mb-6 max-w-full">
|
||||
<span>
|
||||
Billing is based on the number of monthly active users (MAUs) requesting your API
|
||||
throughout the billing period (50 included then you'll be charged{' '}
|
||||
</span>
|
||||
<span className="text-brand">$0.00325</span>
|
||||
<span> per MAU).</span>
|
||||
</div>
|
||||
{isLoading && (
|
||||
<div
|
||||
className={cn(
|
||||
@@ -87,7 +96,7 @@ export const ThirdPartyAuthForm = () => {
|
||||
'border rounded border-default px-20 py-16 flex flex-col items-center justify-center space-y-4'
|
||||
)}
|
||||
>
|
||||
<p className="text-sm text-foreground-light">No integrations configured yet</p>
|
||||
<p className="text-sm text-foreground-light">No providers configured yet</p>
|
||||
<AddIntegrationDropdown
|
||||
buttonText="Add a new integration"
|
||||
onSelectIntegrationType={setSelectedIntegration}
|
||||
|
||||
@@ -3,8 +3,8 @@ import Link from 'next/link'
|
||||
import ReactMarkdown from 'react-markdown'
|
||||
|
||||
import { Markdown } from 'components/interfaces/Markdown'
|
||||
import { Button } from 'ui'
|
||||
import { ReactNode } from 'react'
|
||||
import { Button, cn } from 'ui'
|
||||
|
||||
const FormHeader = ({
|
||||
title,
|
||||
@@ -20,7 +20,7 @@ const FormHeader = ({
|
||||
className?: string
|
||||
}) => {
|
||||
return (
|
||||
<div className={`mb-6 flex items-center justify-between ${className}`}>
|
||||
<div className={cn(`mb-6 flex items-center justify-between ${className}`)}>
|
||||
<div className="space-y-1">
|
||||
<h3 className="text-foreground text-xl">
|
||||
<ReactMarkdown unwrapDisallowed disallowedElements={['p']}>
|
||||
|
||||
Reference in new issue
Block a user