// @ts-nocheck import { PermissionAction } from '@supabase/shared-types/out/constants' import { ExternalLink } from 'lucide-react' import Link from 'next/link' import { useCallback, useMemo } from 'react' import { toast } from 'sonner' import { Button, cn } from 'ui' import { GenericSkeletonLoader } from 'ui-patterns/ShimmeringLoader' import { IntegrationImageHandler } from '../IntegrationsSettings' import VercelIntegrationConnectionForm from './VercelIntegrationConnectionForm' import { IntegrationConnectionItem } from '@/components/interfaces/Integrations/VercelGithub/IntegrationConnection' import { EmptyIntegrationConnection, IntegrationConnectionHeader, IntegrationInstallation, } from '@/components/interfaces/Integrations/VercelGithub/IntegrationPanels' import { ScaffoldContainer, ScaffoldSection, ScaffoldSectionContent, ScaffoldSectionDetail, } from '@/components/layouts/Scaffold' import { InlineLink } from '@/components/ui/InlineLink' import NoPermission from '@/components/ui/NoPermission' import { useOrgIntegrationsQuery } from '@/data/integrations/integrations-query-org-only' import { useIntegrationsVercelInstalledConnectionDeleteMutation } from '@/data/integrations/integrations-vercel-installed-connection-delete-mutation' import { useVercelProjectsQuery } from '@/data/integrations/integrations-vercel-projects-query' import type { Integration, IntegrationName, IntegrationProjectConnection, } from '@/data/integrations/integrations.types' import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions' import { useSelectedOrganizationQuery } from '@/hooks/misc/useSelectedOrganization' import { useSelectedProjectQuery } from '@/hooks/misc/useSelectedProject' import { pluralize } from '@/lib/helpers' import { getIntegrationConfigurationUrl } from '@/lib/integration-utils' import { useSidePanelsStateSnapshot } from '@/state/side-panels' export const VercelSection = ({ isProjectScoped }: { isProjectScoped: boolean }) => { const { data: project } = useSelectedProjectQuery() const { data: org } = useSelectedOrganizationQuery() const { data } = useOrgIntegrationsQuery({ orgSlug: org?.slug }) const sidePanelsStateSnapshot = useSidePanelsStateSnapshot() const isBranch = project?.parent_project_ref !== undefined const { can: canReadVercelConnection, isLoading: isLoadingPermissions } = useAsyncCheckPermissions(PermissionAction.READ, 'integrations.vercel_connections') const { can: canCreateVercelConnection } = useAsyncCheckPermissions( PermissionAction.CREATE, 'integrations.vercel_connections' ) const { can: canUpdateVercelConnection } = useAsyncCheckPermissions( PermissionAction.UPDATE, 'integrations.vercel_connections' ) const { mutate: deleteVercelConnection } = useIntegrationsVercelInstalledConnectionDeleteMutation( { onSuccess: () => { toast.success('Successfully deleted Vercel connection') }, } ) const vercelIntegrations = useMemo(() => { return data ?.filter((integration) => integration.integration.name === 'Vercel') .map((integration) => { if (integration.metadata && integration.integration.name === 'Vercel') { const avatarSrc = !integration.metadata.account.avatar && integration.metadata.account.type === 'Team' ? `https://vercel.com/api/www/avatar?teamId=${integration.metadata.account.team_id}&s=48&format=png` : `https://vercel.com/api/www/avatar/${integration.metadata.account.avatar}?s=48` return { ...integration, metadata: { ...integration.metadata, account: { ...integration.metadata.account, avatar: avatarSrc, }, }, } as Integration } return integration }) }, [data]) // We're only supporting one Vercel integration per org for now // this will need to be updated when we support multiple integrations const vercelIntegration = vercelIntegrations?.[0] const { data: vercelProjectsData } = useVercelProjectsQuery( { organization_integration_id: vercelIntegration?.id, }, { enabled: vercelIntegration?.id !== undefined } ) const vercelProjectCount = vercelProjectsData?.length ?? 0 const onAddVercelConnection = useCallback( (integrationId: string) => { sidePanelsStateSnapshot.setVercelConnectionsIntegrationId(integrationId) sidePanelsStateSnapshot.setVercelConnectionsOpen(true) }, [sidePanelsStateSnapshot] ) const onDeleteVercelConnection = useCallback( async (connection: IntegrationProjectConnection) => { deleteVercelConnection({ id: connection.id, organization_integration_id: connection.organization_integration_id, orgSlug: org?.slug, }) }, [deleteVercelConnection, org?.slug] ) const VercelTitle = `Vercel Integration` const integrationUrl = process.env.NEXT_PUBLIC_ENVIRONMENT === 'prod' ? 'https://vercel.com/integrations/briven' : process.env.NEXT_PUBLIC_ENVIRONMENT === 'staging' ? `https://vercel.com/integrations/briven-staging` : 'https://vercel.com/integrations/briven-local' let connections = (isProjectScoped ? vercelIntegration?.connections.filter( (connection) => connection.briven_project_ref === project?.ref ) : vercelIntegration?.connections) || [] const ConnectionHeaderTitle = `${connections.length} project ${pluralize( connections.length, 'connection' )} ` return (

Connect your Vercel teams to your Briven organization.

{isLoadingPermissions ? ( ) : !canReadVercelConnection ? ( ) : (

How does the Vercel integration work?

Briven will keep your environment variables up to date in each of the projects you assign to a Briven project. You can also link multiple Vercel projects to the same Briven project.

{vercelIntegration ? (
{connections.length > 0 ? ( <>
    {connections.map((connection) => (
    li]:pb-0' )} > {isProjectScoped ? (
    ) : null}
    ))}
) : ( )} onAddVercelConnection(vercelIntegration.id)} > Add new project connection
) : (
)}
{vercelProjectCount > 0 && vercelIntegration !== undefined && (

Your Vercel connection can access {vercelProjectCount} Vercel projects. To change which projects Briven may use, open your organization’s{' '} Vercel integration settings .

)}
)}
) }