bolt.diy/app/lib/hooks/useSupabaseConnection.ts
KevIsDev 02974089de feat: integrate Supabase for database operations and migrations
Add support for Supabase database operations, including migrations and queries. Implement new Supabase-related types, actions, and components to handle database interactions. Enhance the prompt system to include Supabase-specific instructions and constraints. Ensure data integrity and security by enforcing row-level security and proper migration practices.
2025-03-19 23:11:31 +00:00

112 lines
3.1 KiB
TypeScript

import { useEffect, useState } from 'react';
import { toast } from 'react-toastify';
import { useStore } from '@nanostores/react';
import { logStore } from '~/lib/stores/logs';
import { supabaseConnection, isConnecting, isFetchingStats, updateSupabaseConnection } from '~/lib/stores/supabase';
export function useSupabaseConnection() {
const connection = useStore(supabaseConnection);
const connecting = useStore(isConnecting);
const fetchingStats = useStore(isFetchingStats);
const [isProjectsExpanded, setIsProjectsExpanded] = useState(false);
const [isDropdownOpen, setIsDropdownOpen] = useState(false);
useEffect(() => {
const savedConnection = localStorage.getItem('supabase_connection');
if (savedConnection) {
const parsed = JSON.parse(savedConnection);
updateSupabaseConnection(parsed);
}
}, []);
const handleConnect = async () => {
isConnecting.set(true);
try {
const cleanToken = connection.token.trim();
const response = await fetch('/api/supabase', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
token: cleanToken,
}),
});
const data = (await response.json()) as any;
if (!response.ok) {
throw new Error(data.error || 'Failed to connect');
}
updateSupabaseConnection({
user: data.user,
token: connection.token,
stats: data.stats,
});
toast.success('Successfully connected to Supabase');
// Keep the dialog open and expand the projects section
setIsProjectsExpanded(true);
return true;
} catch (error) {
console.error('Connection error:', error);
logStore.logError('Failed to authenticate with Supabase', { error });
toast.error(error instanceof Error ? error.message : 'Failed to connect to Supabase');
updateSupabaseConnection({ user: null, token: '' });
return false;
} finally {
isConnecting.set(false);
}
};
const handleDisconnect = () => {
updateSupabaseConnection({ user: null, token: '' });
toast.success('Disconnected from Supabase');
setIsDropdownOpen(false);
};
const selectProject = (projectId: string) => {
const currentState = supabaseConnection.get();
let projectData = undefined;
if (projectId && currentState.stats?.projects) {
projectData = currentState.stats.projects.find((project) => project.id === projectId);
}
updateSupabaseConnection({
selectedProjectId: projectId,
project: projectData,
});
toast.success('Project selected successfully');
setIsDropdownOpen(false);
};
const handleCreateProject = async () => {
window.open('https://app.supabase.com/new/new-project', '_blank');
};
return {
connection,
connecting,
fetchingStats,
isProjectsExpanded,
setIsProjectsExpanded,
isDropdownOpen,
setIsDropdownOpen,
handleConnect,
handleDisconnect,
selectProject,
handleCreateProject,
updateToken: (token: string) => updateSupabaseConnection({ ...connection, token }),
isConnected: !!(connection.user && connection.token),
};
}