♻️ (builder) Remove barrel export and flatten folder arch
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import prisma from '@/lib/prisma'
|
||||
import { authenticatedProcedure } from '@/utils/server/trpc'
|
||||
import { authenticatedProcedure } from '@/helpers/server/trpc'
|
||||
import { TRPCError } from '@trpc/server'
|
||||
import { Plan, WorkspaceRole } from '@typebot.io/prisma'
|
||||
import Stripe from 'stripe'
|
||||
@@ -1,10 +1,10 @@
|
||||
import prisma from '@/lib/prisma'
|
||||
import { authenticatedProcedure } from '@/utils/server/trpc'
|
||||
import { authenticatedProcedure } from '@/helpers/server/trpc'
|
||||
import { TRPCError } from '@trpc/server'
|
||||
import { Plan, WorkspaceRole } from '@typebot.io/prisma'
|
||||
import Stripe from 'stripe'
|
||||
import { z } from 'zod'
|
||||
import { parseSubscriptionItems } from '../utils/parseSubscriptionItems'
|
||||
import { parseSubscriptionItems } from '../helpers/parseSubscriptionItems'
|
||||
|
||||
export const createCheckoutSession = authenticatedProcedure
|
||||
.meta({
|
||||
@@ -1,5 +1,5 @@
|
||||
import prisma from '@/lib/prisma'
|
||||
import { authenticatedProcedure } from '@/utils/server/trpc'
|
||||
import { authenticatedProcedure } from '@/helpers/server/trpc'
|
||||
import { TRPCError } from '@trpc/server'
|
||||
import { WorkspaceRole } from '@typebot.io/prisma'
|
||||
import Stripe from 'stripe'
|
||||
@@ -1,5 +1,5 @@
|
||||
import prisma from '@/lib/prisma'
|
||||
import { authenticatedProcedure } from '@/utils/server/trpc'
|
||||
import { authenticatedProcedure } from '@/helpers/server/trpc'
|
||||
import { TRPCError } from '@trpc/server'
|
||||
import { WorkspaceRole } from '@typebot.io/prisma'
|
||||
import Stripe from 'stripe'
|
||||
@@ -1,5 +1,5 @@
|
||||
import prisma from '@/lib/prisma'
|
||||
import { authenticatedProcedure } from '@/utils/server/trpc'
|
||||
import { authenticatedProcedure } from '@/helpers/server/trpc'
|
||||
import { TRPCError } from '@trpc/server'
|
||||
import { z } from 'zod'
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import prisma from '@/lib/prisma'
|
||||
import { authenticatedProcedure } from '@/utils/server/trpc'
|
||||
import { authenticatedProcedure } from '@/helpers/server/trpc'
|
||||
import { TRPCError } from '@trpc/server'
|
||||
import { WorkspaceRole } from '@typebot.io/prisma'
|
||||
import Stripe from 'stripe'
|
||||
@@ -1,11 +1,11 @@
|
||||
import { router } from '@/utils/server/trpc'
|
||||
import { getBillingPortalUrl } from './procedures/getBillingPortalUrl'
|
||||
import { listInvoices } from './procedures/listInvoices'
|
||||
import { cancelSubscription } from './procedures/cancelSubscription'
|
||||
import { createCheckoutSession } from './procedures/createCheckoutSession'
|
||||
import { updateSubscription } from './procedures/updateSubscription'
|
||||
import { getSubscription } from './procedures/getSubscription'
|
||||
import { getUsage } from './procedures/getUsage'
|
||||
import { router } from '@/helpers/server/trpc'
|
||||
import { cancelSubscription } from './cancelSubscription'
|
||||
import { createCheckoutSession } from './createCheckoutSession'
|
||||
import { getBillingPortalUrl } from './getBillingPortalUrl'
|
||||
import { getSubscription } from './getSubscription'
|
||||
import { getUsage } from './getUsage'
|
||||
import { listInvoices } from './listInvoices'
|
||||
import { updateSubscription } from './updateSubscription'
|
||||
|
||||
export const billingRouter = router({
|
||||
getBillingPortalUrl,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { sendTelemetryEvents } from '@typebot.io/lib/telemetry/sendTelemetryEvent'
|
||||
import prisma from '@/lib/prisma'
|
||||
import { authenticatedProcedure } from '@/utils/server/trpc'
|
||||
import { authenticatedProcedure } from '@/helpers/server/trpc'
|
||||
import { TRPCError } from '@trpc/server'
|
||||
import { Plan, WorkspaceRole } from '@typebot.io/prisma'
|
||||
import { workspaceSchema } from '@typebot.io/schemas'
|
||||
@@ -1 +0,0 @@
|
||||
export { UsageContent } from './UsageContent'
|
||||
@@ -1 +0,0 @@
|
||||
export { BillingContent } from './BillingContent'
|
||||
@@ -1,7 +0,0 @@
|
||||
import { sendRequest } from '@typebot.io/lib'
|
||||
|
||||
export const cancelSubscriptionQuery = (stripeId: string) =>
|
||||
sendRequest({
|
||||
url: `api/stripe/subscription?stripeId=${stripeId}`,
|
||||
method: 'DELETE',
|
||||
})
|
||||
@@ -1,23 +1,23 @@
|
||||
import { HStack, Stack, Text } from '@chakra-ui/react'
|
||||
import { useWorkspace } from '@/features/workspace'
|
||||
import { useWorkspace } from '@/features/workspace/WorkspaceProvider'
|
||||
import { Plan } from '@typebot.io/prisma'
|
||||
import React from 'react'
|
||||
import { CurrentSubscriptionContent } from './CurrentSubscriptionContent'
|
||||
import { InvoicesList } from './InvoicesList'
|
||||
import { UsageContent } from './UsageContent/UsageContent'
|
||||
import { StripeClimateLogo } from '../StripeClimateLogo'
|
||||
import { StripeClimateLogo } from './StripeClimateLogo'
|
||||
import { TextLink } from '@/components/TextLink'
|
||||
import { ChangePlanForm } from '../ChangePlanForm'
|
||||
import { ChangePlanForm } from './ChangePlanForm'
|
||||
import { UsageProgressBars } from './UsageProgressBars'
|
||||
import { CurrentSubscriptionSummary } from './CurrentSubscriptionSummary'
|
||||
|
||||
export const BillingContent = () => {
|
||||
export const BillingSettingsLayout = () => {
|
||||
const { workspace, refreshWorkspace } = useWorkspace()
|
||||
|
||||
if (!workspace) return null
|
||||
return (
|
||||
<Stack spacing="10" w="full">
|
||||
<UsageContent workspace={workspace} />
|
||||
<UsageProgressBars workspace={workspace} />
|
||||
<Stack spacing="4">
|
||||
<CurrentSubscriptionContent
|
||||
<CurrentSubscriptionSummary
|
||||
workspace={workspace}
|
||||
onCancelSuccess={refreshWorkspace}
|
||||
/>
|
||||
@@ -1,16 +1,16 @@
|
||||
import { Stack, HStack, Text } from '@chakra-ui/react'
|
||||
import { useUser } from '@/features/account'
|
||||
import { Plan } from '@typebot.io/prisma'
|
||||
import { ProPlanContent } from './ProPlanContent'
|
||||
import { StarterPlanContent } from './StarterPlanContent'
|
||||
import { TextLink } from '@/components/TextLink'
|
||||
import { useToast } from '@/hooks/useToast'
|
||||
import { trpc } from '@/lib/trpc'
|
||||
import { guessIfUserIsEuropean } from '@typebot.io/lib/pricing'
|
||||
import { Workspace } from '@typebot.io/schemas'
|
||||
import { PreCheckoutModal, PreCheckoutModalProps } from '../PreCheckoutModal'
|
||||
import { PreCheckoutModal, PreCheckoutModalProps } from './PreCheckoutModal'
|
||||
import { useState } from 'react'
|
||||
import { ParentModalProvider } from '@/features/graph/providers/ParentModalProvider'
|
||||
import { useUser } from '@/features/account/hooks/useUser'
|
||||
import { StarterPlanPricingCard } from './StarterPlanPricingCard'
|
||||
import { ProPlanPricingCard } from './ProPlanPricingCard'
|
||||
|
||||
type Props = {
|
||||
workspace: Pick<Workspace, 'id' | 'stripeId' | 'plan'>
|
||||
@@ -88,7 +88,7 @@ export const ChangePlanForm = ({ workspace, onUpgradeSuccess }: Props) => {
|
||||
</ParentModalProvider>
|
||||
)}
|
||||
<HStack alignItems="stretch" spacing="4" w="full">
|
||||
<StarterPlanContent
|
||||
<StarterPlanPricingCard
|
||||
initialChatsLimitIndex={
|
||||
workspace?.plan === Plan.STARTER
|
||||
? data?.subscription.additionalChatsIndex
|
||||
@@ -106,7 +106,7 @@ export const ChangePlanForm = ({ workspace, onUpgradeSuccess }: Props) => {
|
||||
currency={data?.subscription.currency}
|
||||
/>
|
||||
|
||||
<ProPlanContent
|
||||
<ProPlanPricingCard
|
||||
initialChatsLimitIndex={
|
||||
workspace?.plan === Plan.PRO
|
||||
? data?.subscription.additionalChatsIndex
|
||||
@@ -1 +0,0 @@
|
||||
export { ChangePlanForm } from './ChangePlanForm'
|
||||
@@ -1,5 +1,5 @@
|
||||
import { AlertInfo } from '@/components/AlertInfo'
|
||||
import { useWorkspace } from '@/features/workspace'
|
||||
import { useWorkspace } from '@/features/workspace/WorkspaceProvider'
|
||||
import {
|
||||
Modal,
|
||||
ModalBody,
|
||||
@@ -10,16 +10,9 @@ import {
|
||||
Button,
|
||||
HStack,
|
||||
} from '@chakra-ui/react'
|
||||
import { LimitReached } from '../types'
|
||||
import { ChangePlanForm } from './ChangePlanForm'
|
||||
|
||||
export enum LimitReached {
|
||||
BRAND = 'remove branding',
|
||||
CUSTOM_DOMAIN = 'add custom domains',
|
||||
FOLDER = 'create folders',
|
||||
FILE_INPUT = 'use file input blocks',
|
||||
ANALYTICS = 'unlock in-depth analytics',
|
||||
}
|
||||
|
||||
type ChangePlanModalProps = {
|
||||
type?: LimitReached
|
||||
isOpen: boolean
|
||||
|
||||
@@ -2,20 +2,20 @@ import { Text, HStack, Link, Spinner, Stack, Heading } from '@chakra-ui/react'
|
||||
import { useToast } from '@/hooks/useToast'
|
||||
import { Plan } from '@typebot.io/prisma'
|
||||
import React from 'react'
|
||||
import { PlanTag } from '../PlanTag'
|
||||
import { PlanTag } from './PlanTag'
|
||||
import { BillingPortalButton } from './BillingPortalButton'
|
||||
import { trpc } from '@/lib/trpc'
|
||||
import { Workspace } from '@typebot.io/schemas'
|
||||
|
||||
type CurrentSubscriptionContentProps = {
|
||||
type Props = {
|
||||
workspace: Pick<Workspace, 'id' | 'plan' | 'stripeId'>
|
||||
onCancelSuccess: () => void
|
||||
}
|
||||
|
||||
export const CurrentSubscriptionContent = ({
|
||||
export const CurrentSubscriptionSummary = ({
|
||||
workspace,
|
||||
onCancelSuccess,
|
||||
}: CurrentSubscriptionContentProps) => {
|
||||
}: Props) => {
|
||||
const { showToast } = useToast()
|
||||
|
||||
const { mutate: cancelSubscription, isLoading: isCancelling } =
|
||||
@@ -1,6 +1,6 @@
|
||||
import { TextInput } from '@/components/inputs'
|
||||
import { Select } from '@/components/inputs/Select'
|
||||
import { useParentModal } from '@/features/graph'
|
||||
import { useParentModal } from '@/features/graph/providers/ParentModalProvider'
|
||||
import { useToast } from '@/hooks/useToast'
|
||||
import { trpc } from '@/lib/trpc'
|
||||
import {
|
||||
|
||||
@@ -15,7 +15,7 @@ import {
|
||||
useColorModeValue,
|
||||
} from '@chakra-ui/react'
|
||||
import { ChevronLeftIcon } from '@/components/icons'
|
||||
import { useWorkspace } from '@/features/workspace'
|
||||
import { useWorkspace } from '@/features/workspace/WorkspaceProvider'
|
||||
import { Plan } from '@typebot.io/prisma'
|
||||
import { useEffect, useState } from 'react'
|
||||
import { parseNumberWithCommas } from '@typebot.io/lib'
|
||||
@@ -27,10 +27,10 @@ import {
|
||||
getStorageLimit,
|
||||
storageLimit,
|
||||
} from '@typebot.io/lib/pricing'
|
||||
import { FeaturesList } from './components/FeaturesList'
|
||||
import { FeaturesList } from './FeaturesList'
|
||||
import { MoreInfoTooltip } from '@/components/MoreInfoTooltip'
|
||||
|
||||
type ProPlanContentProps = {
|
||||
type Props = {
|
||||
initialChatsLimitIndex?: number
|
||||
initialStorageLimitIndex?: number
|
||||
currency?: 'usd' | 'eur'
|
||||
@@ -41,13 +41,13 @@ type ProPlanContentProps = {
|
||||
}) => void
|
||||
}
|
||||
|
||||
export const ProPlanContent = ({
|
||||
export const ProPlanPricingCard = ({
|
||||
initialChatsLimitIndex,
|
||||
initialStorageLimitIndex,
|
||||
currency,
|
||||
isLoading,
|
||||
onPayClick,
|
||||
}: ProPlanContentProps) => {
|
||||
}: Props) => {
|
||||
const { workspace } = useWorkspace()
|
||||
const [selectedChatsLimitIndex, setSelectedChatsLimitIndex] =
|
||||
useState<number>()
|
||||
@@ -11,7 +11,7 @@ import {
|
||||
Text,
|
||||
} from '@chakra-ui/react'
|
||||
import { ChevronLeftIcon } from '@/components/icons'
|
||||
import { useWorkspace } from '@/features/workspace'
|
||||
import { useWorkspace } from '@/features/workspace/WorkspaceProvider'
|
||||
import { Plan } from '@typebot.io/prisma'
|
||||
import { useEffect, useState } from 'react'
|
||||
import { parseNumberWithCommas } from '@typebot.io/lib'
|
||||
@@ -23,10 +23,10 @@ import {
|
||||
getStorageLimit,
|
||||
storageLimit,
|
||||
} from '@typebot.io/lib/pricing'
|
||||
import { FeaturesList } from './components/FeaturesList'
|
||||
import { FeaturesList } from './FeaturesList'
|
||||
import { MoreInfoTooltip } from '@/components/MoreInfoTooltip'
|
||||
|
||||
type StarterPlanContentProps = {
|
||||
type Props = {
|
||||
initialChatsLimitIndex?: number
|
||||
initialStorageLimitIndex?: number
|
||||
currency?: 'eur' | 'usd'
|
||||
@@ -37,13 +37,13 @@ type StarterPlanContentProps = {
|
||||
}) => void
|
||||
}
|
||||
|
||||
export const StarterPlanContent = ({
|
||||
export const StarterPlanPricingCard = ({
|
||||
initialChatsLimitIndex,
|
||||
initialStorageLimitIndex,
|
||||
isLoading,
|
||||
currency,
|
||||
onPayClick,
|
||||
}: StarterPlanContentProps) => {
|
||||
}: Props) => {
|
||||
const { workspace } = useWorkspace()
|
||||
const [selectedChatsLimitIndex, setSelectedChatsLimitIndex] =
|
||||
useState<number>()
|
||||
@@ -1,9 +1,9 @@
|
||||
import { Button, ButtonProps, useDisclosure } from '@chakra-ui/react'
|
||||
import { useWorkspace } from '@/features/workspace'
|
||||
import { useWorkspace } from '@/features/workspace/WorkspaceProvider'
|
||||
import React from 'react'
|
||||
import { isNotDefined } from '@typebot.io/lib'
|
||||
import { ChangePlanModal } from './ChangePlanModal'
|
||||
import { LimitReached } from './ChangePlanModal'
|
||||
import { LimitReached } from '../types'
|
||||
|
||||
type Props = { limitReachedType?: LimitReached } & ButtonProps
|
||||
|
||||
|
||||
@@ -13,14 +13,14 @@ import { Plan, Workspace } from '@typebot.io/prisma'
|
||||
import React from 'react'
|
||||
import { parseNumberWithCommas } from '@typebot.io/lib'
|
||||
import { getChatsLimit, getStorageLimit } from '@typebot.io/lib/pricing'
|
||||
import { storageToReadable } from './helpers'
|
||||
import { trpc } from '@/lib/trpc'
|
||||
import { storageToReadable } from '../helpers/storageToReadable'
|
||||
|
||||
type Props = {
|
||||
workspace: Workspace
|
||||
}
|
||||
|
||||
export const UsageContent = ({ workspace }: Props) => {
|
||||
export const UsageProgressBars = ({ workspace }: Props) => {
|
||||
const { data, isLoading } = trpc.billing.getUsage.useQuery({
|
||||
workspaceId: workspace.id,
|
||||
})
|
||||
5
apps/builder/src/features/billing/helpers/isFreePlan.ts
Normal file
5
apps/builder/src/features/billing/helpers/isFreePlan.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import { isNotDefined } from '@typebot.io/lib'
|
||||
import { Workspace, Plan } from '@typebot.io/prisma'
|
||||
|
||||
export const isFreePlan = (workspace?: Pick<Workspace, 'plan'>) =>
|
||||
isNotDefined(workspace) || workspace?.plan === Plan.FREE
|
||||
9
apps/builder/src/features/billing/helpers/isProPlan.ts
Normal file
9
apps/builder/src/features/billing/helpers/isProPlan.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import { isDefined } from '@typebot.io/lib'
|
||||
import { Workspace, Plan } from '@typebot.io/prisma'
|
||||
|
||||
export const isProPlan = (workspace?: Pick<Workspace, 'plan'>) =>
|
||||
isDefined(workspace) &&
|
||||
(workspace.plan === Plan.PRO ||
|
||||
workspace.plan === Plan.LIFETIME ||
|
||||
workspace.plan === Plan.CUSTOM ||
|
||||
workspace.plan === Plan.UNLIMITED)
|
||||
17
apps/builder/src/features/billing/helpers/planToReadable.ts
Normal file
17
apps/builder/src/features/billing/helpers/planToReadable.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import { Plan } from '@typebot.io/prisma'
|
||||
|
||||
export const planToReadable = (plan?: Plan) => {
|
||||
if (!plan) return
|
||||
switch (plan) {
|
||||
case Plan.FREE:
|
||||
return 'Free'
|
||||
case Plan.LIFETIME:
|
||||
return 'Lifetime'
|
||||
case Plan.OFFERED:
|
||||
return 'Offered'
|
||||
case Plan.PRO:
|
||||
return 'Pro'
|
||||
case Plan.UNLIMITED:
|
||||
return 'Unlimited'
|
||||
}
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
export { ChangePlanModal, LimitReached } from './components/ChangePlanModal'
|
||||
export { planToReadable, isFreePlan, isProPlan } from './utils'
|
||||
export { BillingContent } from './components/BillingContent'
|
||||
export { LockTag } from './components/LockTag'
|
||||
export { UpgradeButton } from './components/UpgradeButton'
|
||||
export { PlanTag } from './components/PlanTag'
|
||||
7
apps/builder/src/features/billing/types.ts
Normal file
7
apps/builder/src/features/billing/types.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
export enum LimitReached {
|
||||
BRAND = 'remove branding',
|
||||
CUSTOM_DOMAIN = 'add custom domains',
|
||||
FOLDER = 'create folders',
|
||||
FILE_INPUT = 'use file input blocks',
|
||||
ANALYTICS = 'unlock in-depth analytics',
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
import { Plan, Workspace } from '@typebot.io/prisma'
|
||||
import { isDefined, isNotDefined } from '@typebot.io/lib'
|
||||
|
||||
export const planToReadable = (plan?: Plan) => {
|
||||
if (!plan) return
|
||||
switch (plan) {
|
||||
case Plan.FREE:
|
||||
return 'Free'
|
||||
case Plan.LIFETIME:
|
||||
return 'Lifetime'
|
||||
case Plan.OFFERED:
|
||||
return 'Offered'
|
||||
case Plan.PRO:
|
||||
return 'Pro'
|
||||
case Plan.UNLIMITED:
|
||||
return 'Unlimited'
|
||||
}
|
||||
}
|
||||
|
||||
export const isFreePlan = (workspace?: Pick<Workspace, 'plan'>) =>
|
||||
isNotDefined(workspace) || workspace?.plan === Plan.FREE
|
||||
|
||||
export const isProPlan = (workspace?: Pick<Workspace, 'plan'>) =>
|
||||
isDefined(workspace) &&
|
||||
(workspace.plan === Plan.PRO ||
|
||||
workspace.plan === Plan.LIFETIME ||
|
||||
workspace.plan === Plan.CUSTOM ||
|
||||
workspace.plan === Plan.UNLIMITED)
|
||||
Reference in New Issue
Block a user