kopia lustrzana https://github.com/transitive-bullshit/chatgpt-api
pull/715/head
rodzic
4725b9bfad
commit
927ec86116
|
@ -1,9 +1,8 @@
|
||||||
'use client'
|
'use client'
|
||||||
|
|
||||||
import { assert, omit } from '@agentic/platform-core'
|
import { assert, omit, sanitizeSearchParams } from '@agentic/platform-core'
|
||||||
import { redirect } from 'next/navigation'
|
import { redirect, useSearchParams } from 'next/navigation'
|
||||||
import { useCallback, useEffect } from 'react'
|
import { useCallback, useEffect, useRef } from 'react'
|
||||||
import { useSearchParam } from 'react-use'
|
|
||||||
|
|
||||||
import { useAgentic } from '@/components/agentic-provider'
|
import { useAgentic } from '@/components/agentic-provider'
|
||||||
import { LoadingIndicator } from '@/components/loading-indicator'
|
import { LoadingIndicator } from '@/components/loading-indicator'
|
||||||
|
@ -17,7 +16,10 @@ export function MarketplaceProjectIndex({
|
||||||
projectIdentifier: string
|
projectIdentifier: string
|
||||||
}) {
|
}) {
|
||||||
const ctx = useAgentic()
|
const ctx = useAgentic()
|
||||||
const checkoutStatus = useSearchParam('checkout')
|
const searchParams = useSearchParams()
|
||||||
|
const checkout = searchParams.get('checkout')
|
||||||
|
const plan = searchParams.get('plan')
|
||||||
|
|
||||||
const {
|
const {
|
||||||
data: project,
|
data: project,
|
||||||
isLoading,
|
isLoading,
|
||||||
|
@ -34,6 +36,7 @@ export function MarketplaceProjectIndex({
|
||||||
|
|
||||||
const onSubscribe = useCallback(
|
const onSubscribe = useCallback(
|
||||||
async (pricingPlanSlug: string) => {
|
async (pricingPlanSlug: string) => {
|
||||||
|
assert(ctx, 500, 'Agentic context is required')
|
||||||
assert(project, 500, 'Project is required')
|
assert(project, 500, 'Project is required')
|
||||||
const { lastPublishedDeploymentId } = project
|
const { lastPublishedDeploymentId } = project
|
||||||
assert(
|
assert(
|
||||||
|
@ -42,6 +45,14 @@ export function MarketplaceProjectIndex({
|
||||||
`Public project "${projectIdentifier}" expected to have a last published deployment, but none found.`
|
`Public project "${projectIdentifier}" expected to have a last published deployment, but none found.`
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if (!ctx.isAuthenticated) {
|
||||||
|
return redirect(
|
||||||
|
`/signup?${sanitizeSearchParams({
|
||||||
|
next: `/marketplace/projects/${projectIdentifier}?checkout=true&plan=${pricingPlanSlug}`
|
||||||
|
}).toString()}`
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
let checkoutSession: { url: string; id: string } | undefined
|
let checkoutSession: { url: string; id: string } | undefined
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -61,11 +72,38 @@ export function MarketplaceProjectIndex({
|
||||||
[ctx, projectIdentifier, project]
|
[ctx, projectIdentifier, project]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const hasInitializedCheckoutFromSearchParams = useRef(false)
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (ctx && checkoutStatus === 'canceled') {
|
if (!ctx) return
|
||||||
|
|
||||||
|
if (checkout === 'canceled') {
|
||||||
toast('Checkout canceled')
|
toast('Checkout canceled')
|
||||||
|
} else if (
|
||||||
|
checkout === 'true' &&
|
||||||
|
plan &&
|
||||||
|
project &&
|
||||||
|
!hasInitializedCheckoutFromSearchParams.current
|
||||||
|
) {
|
||||||
|
hasInitializedCheckoutFromSearchParams.current = true
|
||||||
|
|
||||||
|
// Start checkout flow if search params have `?checkout=true&plan={plan}`
|
||||||
|
// This is to allow unauthenticated users to subscribe to a plan by first
|
||||||
|
// visiting `/login` or `/signup` and then being redirected to this page
|
||||||
|
// with the target checkout search params already pre-filled.
|
||||||
|
// Another use case for this functionality is providing a single link to
|
||||||
|
// subscribe to a specific project and pricing plan – with the checkout
|
||||||
|
// details pre-filled.
|
||||||
|
void onSubscribe(checkout)
|
||||||
}
|
}
|
||||||
}, [checkoutStatus, ctx])
|
}, [
|
||||||
|
checkout,
|
||||||
|
plan,
|
||||||
|
ctx,
|
||||||
|
project,
|
||||||
|
onSubscribe,
|
||||||
|
hasInitializedCheckoutFromSearchParams
|
||||||
|
])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section>
|
<section>
|
||||||
|
|
|
@ -19,10 +19,9 @@
|
||||||
- if user is subscribed to a plan, show that plan as selected
|
- if user is subscribed to a plan, show that plan as selected
|
||||||
- handle unauthenticated checkout flow => auth and then redirect to create a checkout session
|
- handle unauthenticated checkout flow => auth and then redirect to create a checkout session
|
||||||
- will need a `redirect` url for `/login` and `/signup`
|
- will need a `redirect` url for `/login` and `/signup`
|
||||||
- `/marketplace/projects/@{projectIdentifier}/checkout?plan={plan}`
|
- `/marketplace/projects/@{projectIdentifier}?checkout=true&plan={plan}`
|
||||||
- stripe
|
- stripe checkout
|
||||||
- stripe checkout
|
- stripe billing portal
|
||||||
- stripe billing portal
|
|
||||||
- **API gateway**
|
- **API gateway**
|
||||||
- oauth flow
|
- oauth flow
|
||||||
- https://docs.scalekit.com/guides/mcp/oauth
|
- https://docs.scalekit.com/guides/mcp/oauth
|
||||||
|
|
Ładowanie…
Reference in New Issue