import React, { useEffect, useState } from 'react'; import { motion } from 'framer-motion'; import { toast } from 'react-toastify'; import { useStore } from '@nanostores/react'; import { logStore } from '~/lib/stores/logs'; import { classNames } from '~/utils/classNames'; import { netlifyConnection, isConnecting, isFetchingStats, updateNetlifyConnection, fetchNetlifyStats, } from '~/lib/stores/netlify'; import type { NetlifyUser } from '~/types/netlify'; export function NetlifyConnection() { const connection = useStore(netlifyConnection); const connecting = useStore(isConnecting); const fetchingStats = useStore(isFetchingStats); const [isSitesExpanded, setIsSitesExpanded] = useState(false); useEffect(() => { const fetchSites = async () => { if (connection.user && connection.token) { await fetchNetlifyStats(connection.token); } }; fetchSites(); }, [connection.user, connection.token]); const handleConnect = async (event: React.FormEvent) => { event.preventDefault(); isConnecting.set(true); try { const response = await fetch('https://api.netlify.com/api/v1/user', { headers: { Authorization: `Bearer ${connection.token}`, 'Content-Type': 'application/json', }, }); if (!response.ok) { throw new Error('Invalid token or unauthorized'); } const userData = (await response.json()) as NetlifyUser; updateNetlifyConnection({ user: userData, token: connection.token, }); await fetchNetlifyStats(connection.token); toast.success('Successfully connected to Netlify'); } catch (error) { console.error('Auth error:', error); logStore.logError('Failed to authenticate with Netlify', { error }); toast.error('Failed to connect to Netlify'); updateNetlifyConnection({ user: null, token: '' }); } finally { isConnecting.set(false); } }; const handleDisconnect = () => { updateNetlifyConnection({ user: null, token: '' }); toast.success('Disconnected from Netlify'); }; return (

Netlify Connection

{!connection.user ? (
updateNetlifyConnection({ ...connection, token: e.target.value })} disabled={connecting} placeholder="Enter your Netlify personal 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-[#00AD9F]', 'disabled:opacity-50', )} />
Get your token
) : (
Connected to Netlify
{connection.user.full_name}

{connection.user.full_name}

{connection.user.email}

{fetchingStats ? (
Fetching Netlify sites...
) : (
{isSitesExpanded && connection.stats?.sites?.length ? (
{connection.stats.sites.map((site) => (
{site.name}
{site.url} {site.published_deploy && ( <>
{new Date(site.published_deploy.published_at).toLocaleDateString()} )}
{site.build_settings?.provider && (
{site.build_settings.provider}
)}
))}
) : isSitesExpanded ? (
No sites found in your Netlify account
) : null}
)}
)}
); }