import { useEffect } from 'react'; import { useSupabaseConnection } from '~/lib/hooks/useSupabaseConnection'; import { classNames } from '~/utils/classNames'; import { useStore } from '@nanostores/react'; import { chatId } from '~/lib/persistence/useChatHistory'; import { fetchSupabaseStats } from '~/lib/stores/supabase'; import { Dialog, DialogRoot, DialogClose, DialogTitle, DialogButton } from '~/components/ui/Dialog'; export function SupabaseConnection() { const { connection: supabaseConn, connecting, fetchingStats, isProjectsExpanded, setIsProjectsExpanded, isDropdownOpen: isDialogOpen, setIsDropdownOpen: setIsDialogOpen, handleConnect, handleDisconnect, selectProject, handleCreateProject, updateToken, isConnected, fetchProjectApiKeys, } = useSupabaseConnection(); const currentChatId = useStore(chatId); useEffect(() => { const handleOpenConnectionDialog = () => { setIsDialogOpen(true); }; document.addEventListener('open-supabase-connection', handleOpenConnectionDialog); return () => { document.removeEventListener('open-supabase-connection', handleOpenConnectionDialog); }; }, [setIsDialogOpen]); useEffect(() => { if (isConnected && currentChatId) { const savedProjectId = localStorage.getItem(`supabase-project-${currentChatId}`); /* * If there's no saved project for this chat but there is a global selected project, * use the global one instead of clearing it */ if (!savedProjectId && supabaseConn.selectedProjectId) { // Save the current global project to this chat localStorage.setItem(`supabase-project-${currentChatId}`, supabaseConn.selectedProjectId); } else if (savedProjectId && savedProjectId !== supabaseConn.selectedProjectId) { selectProject(savedProjectId); } } }, [isConnected, currentChatId]); useEffect(() => { if (currentChatId && supabaseConn.selectedProjectId) { localStorage.setItem(`supabase-project-${currentChatId}`, supabaseConn.selectedProjectId); } else if (currentChatId && !supabaseConn.selectedProjectId) { localStorage.removeItem(`supabase-project-${currentChatId}`); } }, [currentChatId, supabaseConn.selectedProjectId]); useEffect(() => { if (isConnected && supabaseConn.token) { fetchSupabaseStats(supabaseConn.token).catch(console.error); } }, [isConnected, supabaseConn.token]); useEffect(() => { if (isConnected && supabaseConn.selectedProjectId && supabaseConn.token && !supabaseConn.credentials) { fetchProjectApiKeys(supabaseConn.selectedProjectId).catch(console.error); } }, [isConnected, supabaseConn.selectedProjectId, supabaseConn.token, supabaseConn.credentials]); return (
{isDialogOpen && ( {!isConnected ? (
Connect to Supabase
updateToken(e.target.value)} disabled={connecting} placeholder="Enter your Supabase access token" className={classNames( 'w-full px-3 py-2 rounded-lg text-sm', 'bg-[#F8F8F8] dark:bg-[#1A1A1A]', 'border border-[#E5E5E5] dark:border-[#333333]', 'text-bolt-elements-textPrimary placeholder-bolt-elements-textTertiary', 'focus:outline-none focus:ring-1 focus:ring-[#3ECF8E]', 'disabled:opacity-50', )} />
Cancel
) : (
Supabase Connection

{supabaseConn.user?.email}

Role: {supabaseConn.user?.role}

{fetchingStats ? (
Fetching projects...
) : (
{isProjectsExpanded && ( <> {!supabaseConn.selectedProjectId && (
Select a project or create a new one for this chat
)} {supabaseConn.stats?.projects?.length ? (
{supabaseConn.stats.projects.map((project) => (
{project.name}
{project.region}
))}
) : (
No projects found
)} )}
)}
Close
Disconnect
)}
)}
); } interface ButtonProps { active?: boolean; disabled?: boolean; children?: any; onClick?: VoidFunction; className?: string; } function Button({ active = false, disabled = false, children, onClick, className }: ButtonProps) { return ( ); }