add: various improvements to connections

- improved organisation of connections (collapsibles)
- improved deploy button
- improved unique chat deployments
This commit is contained in:
KevIsDev 2025-02-25 00:41:44 +00:00
parent 96a0b2a066
commit 19137c934b
5 changed files with 95 additions and 154 deletions

View File

@ -1,73 +1,8 @@
import React, { useState, useEffect } from 'react';
import { logStore } from '~/lib/stores/logs';
import { motion } from 'framer-motion';
import { toast } from 'react-toastify';
import { GithubConnection } from './GithubConnection';
import { NetlifyConnection } from './NetlifyConnection';
interface GitHubUserResponse {
login: string;
avatar_url: string;
html_url: string;
name: string;
bio: string;
public_repos: number;
followers: number;
following: number;
created_at: string;
public_gists: number;
}
interface GitHubRepoInfo {
name: string;
full_name: string;
html_url: string;
description: string;
stargazers_count: number;
forks_count: number;
default_branch: string;
updated_at: string;
languages_url: string;
}
interface GitHubOrganization {
login: string;
avatar_url: string;
html_url: string;
}
interface GitHubEvent {
id: string;
type: string;
repo: {
name: string;
};
created_at: string;
}
interface GitHubLanguageStats {
[language: string]: number;
}
interface GitHubStats {
repos: GitHubRepoInfo[];
totalStars: number;
totalForks: number;
organizations: GitHubOrganization[];
recentActivity: GitHubEvent[];
languages: GitHubLanguageStats;
totalGists: number;
}
interface GitHubConnection {
user: GitHubUserResponse | null;
token: string;
tokenType: 'classic' | 'fine-grained';
stats?: GitHubStats;
}
export default function ConnectionsTab() {
return (
<div className="space-y-4">
{/* Header */}
@ -85,9 +20,7 @@ export default function ConnectionsTab() {
</p>
<div className="grid grid-cols-1 gap-4">
{/* GitHub Connection */}
<GithubConnection />
{/* Netlify Connection */}
<NetlifyConnection />
</div>
</div>

View File

@ -73,7 +73,6 @@ export function GithubConnection() {
});
const [isLoading, setIsLoading] = useState(true);
const [isConnecting, setIsConnecting] = useState(false);
const [isFetchingStats, setIsFetchingStats] = useState(false);
const [expandedSections, setExpandedSections] = useState({
organizations: false,
languages: false,
@ -82,16 +81,14 @@ export function GithubConnection() {
});
const toggleSection = (section: keyof typeof expandedSections) => {
setExpandedSections(prev => ({
setExpandedSections((prev) => ({
...prev,
[section]: !prev[section]
[section]: !prev[section],
}));
};
const fetchGitHubStats = async (token: string) => {
try {
setIsFetchingStats(true);
const reposResponse = await fetch(
'https://api.github.com/user/repos?sort=updated&per_page=10&affiliation=owner,organization_member,collaborator',
{
@ -168,7 +165,6 @@ export function GithubConnection() {
logStore.logError('Failed to fetch GitHub stats', { error });
toast.error('Failed to fetch GitHub statistics');
} finally {
setIsFetchingStats(false);
}
};
@ -188,6 +184,7 @@ export function GithubConnection() {
fetchGitHubStats(parsed.token);
}
}
setIsLoading(false);
}, []);
@ -407,10 +404,12 @@ export function GithubConnection() {
>
<div className="i-ph:buildings w-4 h-4" />
Organizations ({connection.stats.organizations.length})
<div className={classNames(
"i-ph:caret-down w-4 h-4 ml-auto transition-transform",
expandedSections.organizations ? "rotate-180" : ""
)} />
<div
className={classNames(
'i-ph:caret-down w-4 h-4 ml-auto transition-transform',
expandedSections.organizations ? 'rotate-180' : '',
)}
/>
</button>
{expandedSections.organizations && (
<div className="flex flex-wrap gap-3 pb-4">
@ -439,10 +438,12 @@ export function GithubConnection() {
>
<div className="i-ph:code w-4 h-4" />
Top Languages ({Object.keys(connection.stats.languages).length})
<div className={classNames(
"i-ph:caret-down w-4 h-4 ml-auto transition-transform",
expandedSections.languages ? "rotate-180" : ""
)} />
<div
className={classNames(
'i-ph:caret-down w-4 h-4 ml-auto transition-transform',
expandedSections.languages ? 'rotate-180' : '',
)}
/>
</button>
{expandedSections.languages && (
<div className="flex flex-wrap gap-2 pb-4">
@ -469,10 +470,12 @@ export function GithubConnection() {
>
<div className="i-ph:activity w-4 h-4" />
Recent Activity ({connection.stats.recentActivity.length})
<div className={classNames(
"i-ph:caret-down w-4 h-4 ml-auto transition-transform",
expandedSections.recentActivity ? "rotate-180" : ""
)} />
<div
className={classNames(
'i-ph:caret-down w-4 h-4 ml-auto transition-transform',
expandedSections.recentActivity ? 'rotate-180' : '',
)}
/>
</button>
{expandedSections.recentActivity && (
<div className="space-y-3 pb-4">
@ -509,10 +512,12 @@ export function GithubConnection() {
>
<div className="i-ph:clock-counter-clockwise w-4 h-4" />
Recent Repositories ({connection.stats.repos.length})
<div className={classNames(
"i-ph:caret-down w-4 h-4 ml-auto transition-transform",
expandedSections.repositories ? "rotate-180" : ""
)} />
<div
className={classNames(
'i-ph:caret-down w-4 h-4 ml-auto transition-transform',
expandedSections.repositories ? 'rotate-180' : '',
)}
/>
</button>
{expandedSections.repositories && (
<div className="space-y-3">

View File

@ -220,10 +220,12 @@ export function NetlifyConnection() {
>
<div className="i-ph:buildings w-4 h-4" />
Your Sites ({connection.stats?.totalSites || 0})
<div className={classNames(
"i-ph:caret-down w-4 h-4 ml-auto transition-transform",
isSitesExpanded ? "rotate-180" : ""
)} />
<div
className={classNames(
'i-ph:caret-down w-4 h-4 ml-auto transition-transform',
isSitesExpanded ? 'rotate-180' : '',
)}
/>
</button>
{isSitesExpanded && connection.stats?.sites?.length ? (
<div className="grid gap-3">

View File

@ -33,6 +33,7 @@ export function HeaderActionButtons({}: HeaderActionButtonsProps) {
}
}
document.addEventListener('mousedown', handleClickOutside);
return () => document.removeEventListener('mousedown', handleClickOutside);
}, []);
@ -109,6 +110,7 @@ export function HeaderActionButtons({}: HeaderActionButtonsProps) {
}
const fileContents = await getAllFiles(buildPath);
// Use chatId instead of artifact.id
const existingSiteId = localStorage.getItem(`netlify-site-${currentChatId}`);
@ -209,10 +211,9 @@ export function HeaderActionButtons({}: HeaderActionButtonsProps) {
className="px-4 hover:bg-bolt-elements-item-backgroundActive flex items-center gap-2"
>
{isDeploying ? 'Deploying...' : 'Deploy'}
<div className={classNames(
"i-ph:caret-down w-4 h-4 transition-transform",
isDropdownOpen ? "rotate-180" : ""
)} />
<div
className={classNames('i-ph:caret-down w-4 h-4 transition-transform', isDropdownOpen ? 'rotate-180' : '')}
/>
</Button>
</div>
@ -234,39 +235,39 @@ export function HeaderActionButtons({}: HeaderActionButtonsProps) {
crossOrigin="anonymous"
src="https://cdn.simpleicons.org/netlify"
/>
<span className='mx-auto'>Deploy to Netlify</span>
<span className="mx-auto">Deploy to Netlify</span>
</Button>
<Button
active={false}
disabled
className="flex items-center w-full rounded-md px-4 py-2 text-sm text-bolt-elements-textTertiary gap-2"
>
<span className='sr-only'>Coming Soon</span>
<span className="sr-only">Coming Soon</span>
<img
className="w-5 h-5 bg-black p-1 rounded"
height="24"
width="24"
crossOrigin="anonymous"
src="https://cdn.simpleicons.org/vercel/white"
alt='vercel'
alt="vercel"
/>
<span className='mx-auto'>Deploy to Vercel (Coming Soon)</span>
<span className="mx-auto">Deploy to Vercel (Coming Soon)</span>
</Button>
<Button
active={false}
disabled
className="flex items-center w-full rounded-md px-4 py-2 text-sm text-bolt-elements-textTertiary gap-2"
>
<span className='sr-only'>Coming Soon</span>
<span className="sr-only">Coming Soon</span>
<img
className="w-5 h-5"
height="24"
width="24"
crossOrigin="anonymous"
src="https://cdn.simpleicons.org/cloudflare"
alt='vercel'
alt="vercel"
/>
<span className='mx-auto'>Deploy to Cloudflare (Coming Soon)</span>
<span className="mx-auto">Deploy to Cloudflare (Coming Soon)</span>
</Button>
</div>
)}

View File

@ -5,7 +5,7 @@ import type { ChatHistoryItem } from './useChatHistory';
export interface IChatMetadata {
gitUrl: string;
gitBranch?: string;
netlifySiteId?: string; // Add this field
netlifySiteId?: string;
}
const logger = createScopedLogger('ChatHistory');