'use client' import { useState, useCallback } from 'react' import { motion, AnimatePresence } from 'framer-motion' import { Github, Loader2, AlertCircle, CheckCircle2, Package, Terminal, Star, GitBranch, ExternalLink } from 'lucide-react' interface GitHubAnalysis { owner: string repo: string description: string language: string | null projectType: string hasCli: boolean installMethods: Array<{ method: string command: string packageManager?: string }> latestVersion?: string stars: number topics: string[] homepage: string | null } interface GitHubTabProps { onGenerated: (content: string) => void } export default function GitHubTab({ onGenerated }: GitHubTabProps) { const [url, setUrl] = useState('') const [githubToken, setGithubToken] = useState('') const [showToken, setShowToken] = useState(false) const [isAnalyzing, setIsAnalyzing] = useState(false) const [isGenerating, setIsGenerating] = useState(false) const [analysis, setAnalysis] = useState(null) const [error, setError] = useState(null) const handleAnalyze = useCallback(async () => { if (!url.trim()) { setError('Please enter a GitHub URL') return } setIsAnalyzing(true) setError(null) setAnalysis(null) try { const params = new URLSearchParams({ url: url.trim(), type: 'github' }) const response = await fetch(`/api/generate-install?${params}`) const data = await response.json() if (!response.ok) { throw new Error(data.error || 'Analysis failed') } setAnalysis(data.analysis) } catch (err) { setError(err instanceof Error ? err.message : 'Analysis failed') } finally { setIsAnalyzing(false) } }, [url]) const handleGenerate = useCallback(async () => { if (!url.trim()) { setError('Please enter a GitHub URL') return } setIsGenerating(true) setError(null) try { const response = await fetch('/api/generate-install', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ url: url.trim(), type: 'github', githubToken: githubToken.trim() || undefined, }), }) const data = await response.json() if (!response.ok) { throw new Error(data.error || 'Generation failed') } if (data.installMd) { onGenerated(data.installMd) } else { throw new Error('No install.md content returned') } } catch (err) { setError(err instanceof Error ? err.message : 'Generation failed') } finally { setIsGenerating(false) } }, [url, githubToken, onGenerated]) const handleKeyDown = useCallback((e: React.KeyboardEvent) => { if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault() if (analysis) { handleGenerate() } else { handleAnalyze() } } }, [analysis, handleAnalyze, handleGenerate]) return (
{/* URL Input */}
{ setUrl(e.target.value) setAnalysis(null) setError(null) }} onKeyDown={handleKeyDown} placeholder="github.com/owner/repo or owner/repo" className="w-full pl-10 pr-4 py-3 bg-black border border-neutral-700 rounded-lg text-white placeholder-neutral-500 focus:outline-none focus:border-white transition-colors" />

Supports: github.com/owner/repo, owner/repo, or full GitHub URLs

{/* Optional GitHub Token */}
{showToken && ( setGithubToken(e.target.value)} placeholder="ghp_xxxxxxxxxxxx" className="w-full px-4 py-2 bg-black border border-neutral-700 rounded-lg text-white placeholder-neutral-500 focus:outline-none focus:border-white transition-colors text-sm" />

Token is sent securely and not stored. Needed for private repos or to avoid rate limits.

)}
{/* Error */} {error && (

{error}

)}
{/* Analysis Results */} {analysis && (

{analysis.owner}/{analysis.repo}

{analysis.description && (

{analysis.description}

)}
{analysis.homepage && ( )}
{/* Stats Row */}
{analysis.language && (
{analysis.language}
)}
{analysis.stars.toLocaleString()}
{analysis.latestVersion && (
{analysis.latestVersion}
)}
{analysis.projectType}
{analysis.hasCli && (
CLI
)}
{/* Topics */} {analysis.topics.length > 0 && (
{analysis.topics.slice(0, 8).map((topic) => ( {topic} ))}
)} {/* Install Methods */} {analysis.installMethods.length > 0 && (

Detected Install Methods

{analysis.installMethods.slice(0, 4).map((method, index) => (
{method.method}: {method.command}
))}
)} {/* Generate Button */} )} {/* Instructions when no analysis */} {!analysis && !error && !isAnalyzing && (

Enter a GitHub repository URL to analyze and generate install.md

We'll extract README, package.json, workflows, and releases

)}
) }