import { useParams } from 'common' import { ChevronRight, FileCode, X } from 'lucide-react' import Link from 'next/link' import { PropsWithChildren, ReactNode } from 'react' import { Badge, Button, cn, Collapsible, CollapsibleContent, CollapsibleTrigger, WarningIcon, } from 'ui' import { Admonition } from 'ui-patterns/admonition' import { CodeBlock, type CodeBlockLang } from 'ui-patterns/CodeBlock' import { ConnectionParameters } from './ConnectionParameters' import { useSupavisorConfigurationQuery } from '@/data/database/supavisor-configuration-query' import { IS_PLATFORM } from '@/lib/constants' import { useDatabaseSelectorStateSnapshot } from '@/state/database-selector' interface ConnectionPanelProps { type?: 'direct' | 'transaction' | 'session' badge?: string title: string description: string contentFooter?: ReactNode connectionString: string ipv4Status: { type: 'error' | 'success' title: string description?: string | ReactNode links?: { text: string; url: string }[] } notice?: string[] parameters?: Array<{ key: string value: string description?: string }> contentType?: 'input' | 'code' lang?: CodeBlockLang fileTitle?: string onCopyCallback: () => void } const IPv4StatusIcon = ({ className, active }: { className?: string; active: boolean }) => { return (
{!active ? (
) : (
)}
) } export const CodeBlockFileHeader = ({ title }: { title: string }) => { return (
{title}
) } export const ConnectionPanel = ({ type = 'direct', badge, title, description, contentFooter, connectionString, ipv4Status, notice, parameters = [], lang = 'bash', fileTitle, children, onCopyCallback, }: PropsWithChildren) => { const { ref: projectRef } = useParams() const state = useDatabaseSelectorStateSnapshot() const { data: poolingInfo } = useSupavisorConfigurationQuery({ projectRef }) const poolingConfiguration = poolingInfo?.find((x) => x.identifier === state.selectedDatabaseId) const isSessionMode = poolingConfiguration?.pool_mode === 'session' const links = ipv4Status.links ?? [] const isTransactionDedicatedPooler = type === 'transaction' && badge === 'Dedicated Pooler' return (

{title}

{!!badge && !isTransactionDedicatedPooler && {badge}}

{description}

{contentFooter}
{isTransactionDedicatedPooler && (
Using the Dedicated Pooler:
)}
{fileTitle && } {type === 'transaction' && isSessionMode ? ( ) : ( <> {notice && (
{notice?.map((text: string) => (

{text}

))}
)} {parameters.length > 0 && } )}
{IS_PLATFORM && (
{ipv4Status.title} {ipv4Status.description && (typeof ipv4Status.description === 'string' ? ( {ipv4Status.description} ) : ( ipv4Status.description ))} {links.length > 0 && (
{links.map((link) => ( ))}
)}
)} {type === 'session' && (
Only use on a IPv4 network

Session pooler connections are IPv4 proxied for free.

Use Direct Connection if connecting via an IPv6 network.

)} {IS_PLATFORM && ipv4Status.type === 'error' && (

A few major platforms are IPv4-only and may not work with a Direct Connection:

Vercel
GitHub Actions
Render
Retool

If you wish to use a Direct Connection with these, please purchase{' '} IPv4 support .

You may also use the{' '} Session Pooler or{' '} Transaction Pooler if you are on a IPv4 network.

)}
{children}
) }