import { TrashIcon } from '@/components/icons' import { Seo } from '@/components/Seo' import { useWorkspace } from '@/features/workspace/WorkspaceProvider' import { useToast } from '@/hooks/useToast' import { isCloudProdInstance } from '@/helpers/isCloudProdInstance' import { Flex, Heading, HStack, IconButton, Stack, Wrap, Text, } from '@chakra-ui/react' import { Plan } from '@typebot.io/prisma' import { isDefined, isNotDefined } from '@typebot.io/lib' import { isPublicDomainAvailableQuery } from '../queries/isPublicDomainAvailableQuery' import { EditableUrl } from './EditableUrl' import { integrationsList } from './embeds/EmbedButton' import { useTypebot } from '@/features/editor/providers/TypebotProvider' import { LockTag } from '@/features/billing/components/LockTag' import { UpgradeButton } from '@/features/billing/components/UpgradeButton' import { hasProPerks } from '@/features/billing/helpers/hasProPerks' import { CustomDomainsDropdown } from '@/features/customDomains/components/CustomDomainsDropdown' import { TypebotHeader } from '@/features/editor/components/TypebotHeader' import { parseDefaultPublicId } from '../helpers/parseDefaultPublicId' import { useTranslate } from '@tolgee/react' import { env } from '@typebot.io/env' import DomainStatusIcon from '@/features/customDomains/components/DomainStatusIcon' import { TypebotNotFoundPage } from '@/features/editor/components/TypebotNotFoundPage' export const SharePage = () => { const { t } = useTranslate() const { workspace } = useWorkspace() const { typebot, updateTypebot, publishedTypebot, is404 } = useTypebot() const { showToast } = useToast() const handlePublicIdChange = async (publicId: string) => { updateTypebot({ updates: { publicId }, save: true }) } const publicId = typebot ? typebot?.publicId ?? parseDefaultPublicId(typebot.name, typebot.id) : '' const isPublished = isDefined(publishedTypebot) const handlePathnameChange = (pathname: string) => { if (!typebot?.customDomain) return const existingHost = typebot.customDomain?.split('/')[0] const newDomain = pathname === '' ? existingHost : existingHost + '/' + pathname handleCustomDomainChange(newDomain) } const handleCustomDomainChange = (customDomain: string | null) => updateTypebot({ updates: { customDomain }, save: true }) const checkIfPathnameIsValid = (pathname: string) => { const isCorrectlyFormatted = /^([a-z0-9]+-[a-z0-9]*)*$/.test(pathname) || /^[a-z0-9]*$/.test(pathname) if (!isCorrectlyFormatted) { showToast({ description: 'Can only contain lowercase letters, numbers and dashes.', }) return false } return true } const checkIfPublicIdIsValid = async (publicId: string) => { const isLongerThanAllowed = publicId.length >= 4 if (!isLongerThanAllowed && isCloudProdInstance()) { showToast({ description: 'Should be longer than 4 characters', }) return false } if (!checkIfPathnameIsValid(publicId)) return false const { data } = await isPublicDomainAvailableQuery(publicId) if (!data?.isAvailable) { showToast({ description: 'ID is already taken' }) return false } return true } if (is404) return return ( Your typebot link {typebot && ( )} {typebot?.customDomain && ( } aria-label="Remove custom URL" size="xs" onClick={() => handleCustomDomainChange(null)} /> {workspace?.id && ( )} )} {isNotDefined(typebot?.customDomain) && env.NEXT_PUBLIC_VERCEL_VIEWER_PROJECT_NAME ? ( <> {hasProPerks(workspace) ? ( ) : ( Add my domain{' '} )} ) : null} Embed your typebot {integrationsList.map((IntegrationButton, idx) => ( ))} ) }