Skip to content

Commit

Permalink
🐛 (usage) Archive typebot to be able to compute usage
Browse files Browse the repository at this point in the history
  • Loading branch information
baptisteArno committed Oct 1, 2022
1 parent 75ca255 commit 15dbc95
Show file tree
Hide file tree
Showing 20 changed files with 152 additions and 84 deletions.
6 changes: 6 additions & 0 deletions apps/builder/components/dashboard/DashboardHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import { useWorkspace } from 'contexts/WorkspaceContext'
import { EmojiOrImageIcon } from 'components/shared/EmojiOrImageIcon'
import { WorkspaceSettingsModal } from './WorkspaceSettingsModal'
import { isNotDefined } from 'utils'
import { PlanTag } from 'components/shared/PlanTag'

export const DashboardHeader = () => {
const { user } = useUser()
Expand Down Expand Up @@ -90,9 +91,13 @@ export const DashboardHeader = () => {
/>
</SkeletonCircle>
{workspace && (
<>
<Text noOfLines={1} maxW="200px">
{workspace.name}
</Text>
<PlanTag plan={workspace.plan}/>
</>

)}
<ChevronLeftIcon transform="rotate(-90deg)" />
</HStack>
Expand All @@ -112,6 +117,7 @@ export const DashboardHeader = () => {
defaultIcon={HardDriveIcon}
/>
<Text>{workspace.name}</Text>
<PlanTag plan={workspace.plan}/>
</HStack>
</MenuItem>
))}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { Button, HStack, useDisclosure, Text } from '@chakra-ui/react'
import { FolderPlusIcon } from 'assets/icons'
import { LockTag } from 'components/shared/LockTag'
import {
LimitReached,
ChangePlanModal,
} from 'components/shared/modals/ChangePlanModal'
import { PlanTag } from 'components/shared/PlanTag'
import { useWorkspace } from 'contexts/WorkspaceContext'
import { Plan } from 'db'
import React from 'react'
Expand All @@ -28,7 +28,7 @@ export const CreateFolderButton = ({ isLoading, onClick }: Props) => {
>
<HStack>
<Text>Create a folder</Text>
{isFreePlan(workspace) && <PlanTag plan={Plan.STARTER} />}
{isFreePlan(workspace) && <LockTag plan={Plan.STARTER} />}
</HStack>
<ChangePlanModal
isOpen={isOpen}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export const CurrentSubscriptionContent = ({
return (
<Stack gap="2">
<Heading fontSize="3xl">Subscription</Heading>
<HStack>
<HStack data-testid="current-subscription">
<Text>Current workspace subscription: </Text>
{isCancelling ? (
<Spinner color="gray.500" size="xs" />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { HStack, Text, Tooltip } from '@chakra-ui/react'
import { PlanTag } from 'components/shared/PlanTag'
import { LockTag } from 'components/shared/LockTag'
import { useWorkspace } from 'contexts/WorkspaceContext'
import { Plan } from 'db'
import {
Expand Down Expand Up @@ -54,7 +54,7 @@ export const BlockTypeLabel = ({ type }: Props): JSX.Element => {
<Tooltip label="Upload Files">
<HStack>
<Text>File</Text>
{isFreePlan(workspace) && <PlanTag plan={Plan.STARTER} />}
{isFreePlan(workspace) && <LockTag plan={Plan.STARTER} />}
</HStack>
</Tooltip>
)
Expand Down
4 changes: 2 additions & 2 deletions apps/builder/components/settings/GeneralSettingsForm.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { Flex, FormLabel, Stack, Switch, useDisclosure } from '@chakra-ui/react'
import { LockTag } from 'components/shared/LockTag'
import {
ChangePlanModal,
LimitReached,
} from 'components/shared/modals/ChangePlanModal'
import { PlanTag } from 'components/shared/PlanTag'
import { SwitchWithLabel } from 'components/shared/SwitchWithLabel'
import { useWorkspace } from 'contexts/WorkspaceContext'
import { Plan } from 'db'
Expand Down Expand Up @@ -66,7 +66,7 @@ export const GeneralSettingsForm = ({
>
<FormLabel htmlFor="branding" mb="0">
Typebot.io branding{' '}
{isWorkspaceFreePlan && <PlanTag plan={Plan.STARTER} />}
{isWorkspaceFreePlan && <LockTag plan={Plan.STARTER} />}
</FormLabel>
<Switch
id="branding"
Expand Down
31 changes: 17 additions & 14 deletions apps/builder/components/share/ShareContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ import {
import { TrashIcon } from 'assets/icons'
import { UpgradeButton } from 'components/shared/buttons/UpgradeButton'
import { useToast } from 'components/shared/hooks/useToast'
import { LockTag } from 'components/shared/LockTag'
import { LimitReached } from 'components/shared/modals/ChangePlanModal'
import { PlanTag } from 'components/shared/PlanTag'
import { useTypebot } from 'contexts/TypebotContext/TypebotContext'
import { useWorkspace } from 'contexts/WorkspaceContext'
import { Plan } from 'db'
Expand Down Expand Up @@ -82,19 +82,22 @@ export const ShareContent = () => {
/>
</HStack>
)}
{isWorkspaceProPlan(workspace) &&
isNotDefined(typebot?.customDomain) ? (
<CustomDomainsDropdown
onCustomDomainSelect={handleCustomDomainChange}
/>
) : (
<UpgradeButton
colorScheme="gray"
limitReachedType={LimitReached.CUSTOM_DOMAIN}
>
<Text mr="2">Add my domain</Text> <PlanTag plan={Plan.PRO} />
</UpgradeButton>
)}
{isNotDefined(typebot?.customDomain) ? (
<>
{isWorkspaceProPlan(workspace) ? (
<CustomDomainsDropdown
onCustomDomainSelect={handleCustomDomainChange}
/>
) : (
<UpgradeButton
colorScheme="gray"
limitReachedType={LimitReached.CUSTOM_DOMAIN}
>
<Text mr="2">Add my domain</Text> <LockTag plan={Plan.PRO} />
</UpgradeButton>
)}
</>
) : null}
</Stack>

<Stack spacing={4}>
Expand Down
14 changes: 14 additions & 0 deletions apps/builder/components/shared/LockTag.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { Tag, TagProps } from '@chakra-ui/react'
import { LockedIcon } from 'assets/icons'
import { Plan } from 'db'
import { planColorSchemes } from './PlanTag'

export const LockTag = ({ plan, ...props }: { plan?: Plan } & TagProps) => (
<Tag
colorScheme={plan ? planColorSchemes[plan] : 'gray'}
data-testid={`${plan?.toLowerCase()}-lock-tag`}
{...props}
>
<LockedIcon />
</Tag>
)
34 changes: 29 additions & 5 deletions apps/builder/components/shared/PlanTag.tsx
Original file line number Diff line number Diff line change
@@ -1,33 +1,57 @@
import { Tag, TagProps } from '@chakra-ui/react'
import { Tag, TagProps, ThemeTypings } from '@chakra-ui/react'
import { Plan } from 'db'

export const planColorSchemes: Record<Plan, ThemeTypings['colorSchemes']> = {
[Plan.LIFETIME]: 'purple',
[Plan.PRO]: 'blue',
[Plan.OFFERED]: 'orange',
[Plan.STARTER]: 'orange',
[Plan.FREE]: 'gray',
}

export const PlanTag = ({ plan, ...props }: { plan?: Plan } & TagProps) => {
switch (plan) {
case Plan.LIFETIME: {
return (
<Tag colorScheme="purple" data-testid="lifetime-plan-tag" {...props}>
<Tag
colorScheme={planColorSchemes[plan]}
data-testid="lifetime-plan-tag"
{...props}
>
Lifetime
</Tag>
)
}
case Plan.PRO: {
return (
<Tag colorScheme="blue" data-testid="pro-plan-tag" {...props}>
<Tag
colorScheme={planColorSchemes[plan]}
data-testid="pro-plan-tag"
{...props}
>
Pro
</Tag>
)
}
case Plan.OFFERED:
case Plan.STARTER: {
return (
<Tag colorScheme="orange" data-testid="starter-plan-tag" {...props}>
<Tag
colorScheme={planColorSchemes[plan]}
data-testid="starter-plan-tag"
{...props}
>
Starter
</Tag>
)
}
default: {
return (
<Tag colorScheme="gray" data-testid="free-plan-tag" {...props}>
<Tag
colorScheme={planColorSchemes[Plan.FREE]}
data-testid="free-plan-tag"
{...props}
>
Free
</Tag>
)
Expand Down
13 changes: 7 additions & 6 deletions apps/builder/contexts/WorkspaceContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -139,13 +139,14 @@ export const WorkspaceContext = ({ children }: WorkspaceContextProps) => {
if (!currentWorkspace || !workspaces || workspaces.length < 2) return
const { data } = await deleteWorkspace(currentWorkspace.id)
if (!data || !currentWorkspace) return
setCurrentWorkspace(workspaces[0])
const newWorkspaces = (workspaces ?? []).filter((w) =>
w.id === currentWorkspace.id
? { ...data.workspace, members: w.members }
: w
)
setCurrentWorkspace(newWorkspaces[0])
mutate({
workspaces: (workspaces ?? []).filter((w) =>
w.id === currentWorkspace.id
? { ...data.workspace, members: w.members }
: w
),
workspaces: newWorkspaces,
})
}

Expand Down
4 changes: 4 additions & 0 deletions apps/builder/pages/api/typebots.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
{
workspace: { members: { some: { userId: user.id } } },
id: { in: typebotIds },
isArchived: { not: true },
},
{
id: { in: typebotIds },
Expand All @@ -39,6 +40,7 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
userId: user.id,
},
},
isArchived: { not: true },
},
],
},
Expand All @@ -51,6 +53,7 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
where: {
OR: [
{
isArchived: { not: true },
folderId,
workspace: {
id: workspaceId,
Expand All @@ -63,6 +66,7 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
},
},
{
isArchived: { not: true },
workspace: {
id: workspaceId,
members: {
Expand Down
9 changes: 7 additions & 2 deletions apps/builder/pages/api/typebots/[typebotId].ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,17 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
const typebotId = req.query.typebotId as string
if (req.method === 'GET') {
const typebot = await prisma.typebot.findFirst({
where: canReadTypebot(typebotId, user),
where: {
...canReadTypebot(typebotId, user),
isArchived: { not: true },
},
include: {
publishedTypebot: true,
collaborators: { select: { userId: true, type: true } },
webhooks: true,
},
})
console.log(typebot)
if (!typebot) return res.send({ typebot: null })
const { publishedTypebot, collaborators, webhooks, ...restOfTypebot } =
typebot
Expand All @@ -35,8 +39,9 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
}

if (req.method === 'DELETE') {
const typebots = await prisma.typebot.deleteMany({
const typebots = await prisma.typebot.updateMany({
where: canWriteTypebot(typebotId, user),
data: { isArchived: true },
})
await archiveResults(res)({
typebotId,
Expand Down
16 changes: 1 addition & 15 deletions apps/builder/pages/api/workspaces/[workspaceId].ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { withSentry } from '@sentry/nextjs'
import { Prisma, Workspace, WorkspaceRole } from 'db'
import prisma from 'libs/prisma'
import { NextApiRequest, NextApiResponse } from 'next'
import { archiveResults, getAuthenticatedUser } from 'services/api/utils'
import { getAuthenticatedUser } from 'services/api/utils'
import { methodNotAllowed, notAuthenticated } from 'utils/api'

const handler = async (req: NextApiRequest, res: NextApiResponse) => {
Expand All @@ -28,23 +28,9 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
id,
members: { some: { userId: user.id, role: WorkspaceRole.ADMIN } },
}
const deletedTypebots = await prisma.typebot.findMany({
where: {
workspace: workspaceFilter,
},
})
await prisma.workspace.deleteMany({
where: workspaceFilter,
})
await Promise.all(
deletedTypebots.map((typebot) =>
archiveResults(res)({
typebotId: typebot.id,
user,
resultsFilter: { typebotId: typebot.id },
})
)
)
return res.status(200).json({
message: 'success',
})
Expand Down
27 changes: 17 additions & 10 deletions apps/builder/playwright/services/database.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,14 +102,16 @@ export const setupDatabase = async () => {
return setupCredentials()
}

export const setupWorkspaces = async () =>
prisma.workspace.createMany({
export const setupWorkspaces = async () => {
await prisma.workspace.create({
data: {
id: freeWorkspaceId,
name: 'Free workspace',
plan: Plan.FREE,
},
})
await prisma.workspace.createMany({
data: [
{
id: freeWorkspaceId,
name: 'Free workspace',
plan: Plan.FREE,
},
{
id: starterWorkspaceId,
name: 'Starter workspace',
Expand All @@ -128,6 +130,7 @@ export const setupWorkspaces = async () =>
},
],
})
}

export const createWorkspaces = async (workspaces: Partial<Workspace>[]) => {
const workspaceIds = workspaces.map((workspace) => workspace.id ?? cuid())
Expand Down Expand Up @@ -231,11 +234,15 @@ export const getSignedInUser = (email: string) =>
prisma.user.findFirst({ where: { email } })

export const createTypebots = async (partialTypebots: Partial<Typebot>[]) => {
const typebotsWithId = partialTypebots.map((typebot) => ({
...typebot,
id: typebot.id ?? cuid(),
}))
await prisma.typebot.createMany({
data: partialTypebots.map(parseTestTypebot),
data: typebotsWithId.map(parseTestTypebot),
})
return prisma.publicTypebot.createMany({
data: partialTypebots.map((t) =>
data: typebotsWithId.map((t) =>
parseTypebotToPublicTypebot(t.id + '-public', parseTestTypebot(t))
),
})
Expand Down Expand Up @@ -304,7 +311,7 @@ const parseTypebotToPublicTypebot = (
})

const parseTestTypebot = (partialTypebot: Partial<Typebot>): Typebot => ({
id: partialTypebot.id ?? 'typebot',
id: cuid(),
workspaceId: proWorkspaceId,
folderId: null,
name: 'My typebot',
Expand Down
Loading

4 comments on commit 15dbc95

@vercel
Copy link

@vercel vercel bot commented on 15dbc95 Oct 1, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vercel
Copy link

@vercel vercel bot commented on 15dbc95 Oct 1, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vercel
Copy link

@vercel vercel bot commented on 15dbc95 Oct 1, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

viewer-v2-alpha – ./apps/viewer

247987.com
yobot.me
ns8.vn
sat.cr8.ai
bot.aipr.kr
finplex.be
minipost.uk
bot.aws.bj
biiapp.com
8jours.top
ticketfute.com
ar.nigerias.io
bt.id8rs.com
an.nigerias.io
vhpage.cr8.ai
am.nigerias.io
bot.enreso.org
apo.nigerias.io
bot.lalmon.com
bot.krdfy.com
bot.ageenda.com
bot.artiweb.app
apr.nigerias.io
aso.nigerias.io
bot.tc-mail.com
chat.sureb4.com
eventhub.com.au
games.klujo.com
typebot.aloe.do
sakuranembro.it
form.syncwin.com
botc.ceox.com.br
clo.closeer.work
bot.upfunnel.art
faqs.nigerias.io
feedback.ofx.one
bot.piccinato.co
stan.vselise.com
kw.wpwakanda.com
myrentalhost.com
voicehelp.cr8.ai
typebot.aloe.bot
bot.agfunnel.tech
app.chatforms.net
bot.phuonghub.com
bot.hostnation.de
bot.maitempah.com
bot.reviewzer.com
cares.urlabout.me
fmm.wpwakanda.com
gentleman-shop.fr
k1.kandabrand.com
lb.ticketfute.com
ov1.wpwakanda.com
1988.bouclidom.com
ov3.wpwakanda.com
ov2.wpwakanda.com
andreimayer.com.br
bot.neferlopez.com
bot.megafox.com.br
positivobra.com.br
cadu.uninta.edu.br
dicanatural.online
bots.robomotion.io
goalsettingbot.com
survey.digienge.io
this-is-a-test.com
zap.techadviser.in
bot.eventhub.com.au
bot.digitalbled.com
carsalesenquiry.com
demo.botscientis.us
forms.webisharp.com
kbsub.wpwakanda.com
live.botscientis.us
mentoria.omelhor.vc
nutrisamirbayde.com
order.maitempah.com
quest.wpwakanda.com
test.botscientis.us
bium.gratirabbit.com
typebot.stillio.com
bot.cotemeuplano.com
bot.ansuraniphone.my
chat.hayurihijab.com
chatbee.agfunnel.com
click.sevenoways.com
kuiz.sistemniaga.com
get.freebotoffer.xyz
connect.growthguy.in
offer.botscientis.us
talkbot.agfunnel.com
tenorioadvogados.com
uppity.wpwakanda.com
aidigitalmarketing.kr
abutton.wpwakanda.com
bbutton.wpwakanda.com
bot.incusservices.com
bot.meuesocial.com.br
bot.ramonmatos.com.br

@vercel
Copy link

@vercel vercel bot commented on 15dbc95 Oct 1, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

builder-v2 – ./apps/builder

builder-v2-git-main-typebot-io.vercel.app
builder-v2-typebot-io.vercel.app
app.typebot.io

Please sign in to comment.