'use client' import { motion } from 'framer-motion' import { ExternalLink, MessageSquare, CheckCircle, XCircle, Loader2, AlertCircle } from 'lucide-react' import { useState, useEffect } from 'react' import { useTerminal } from '@/lib/TerminalContext' function RepoCIBadge({ label, repo, forgejoBase }: { label: string; repo: string; forgejoBase: string }) { const [ci, setCI] = useState<{ sha: string; status: string } | null>(null) useEffect(() => { fetch(`/api/ci-status?repo=${repo}`) .then(r => r.json()) .then(data => setCI({ sha: data.sha?.substring(0, 7) || '', status: data.conclusion || data.status || 'unknown', })) .catch(() => null) }, [repo]) const icon = !ci ? : ci.status === 'success' ? : ci.status === 'failure' ? : return (
{label} {ci?.sha ? ( {ci.sha} ) : ( ··· )} | {icon}
) } interface CIRepo { label: string repo: string forgejoBase: string } interface ProjectShowcaseProps { id?: string title: string description: string longDescription?: string stat: string highlight?: string status: 'live' | 'building' | 'planning' | 'completed' media?: { type: 'image' | 'video' url: string } videoUrl?: string articleUrl?: string watchVideoText?: string readArticleText?: string askPoimenText?: string bullets?: string[] deepDive?: { label: string url: string } ciRepos?: CIRepo[] } export function ProjectShowcase({ id, title, description, longDescription, stat, highlight, status, media, videoUrl, articleUrl, watchVideoText = 'Watch Video', readArticleText = 'Read Article', askPoimenText = 'Ask Poimen for technical details', bullets, deepDive, ciRepos, }: ProjectShowcaseProps) { const { setIsOpen } = useTerminal() const statusColors = { live: 'bg-green-100 dark:bg-green-900 text-green-800 dark:text-green-200', completed: 'bg-green-100 dark:bg-green-900 text-green-800 dark:text-green-200', building: 'bg-blue-100 dark:bg-blue-900 text-blue-800 dark:text-blue-200', planning: 'bg-gray-100 dark:bg-gray-800 text-gray-800 dark:text-gray-200', } return ( {/* Optional Media (Image or Video) */} {media && (
{media.type === 'video' ? ( (() => { const youtubeMatch = media.url.match(/(?:youtube\.com\/watch\?v=|youtu\.be\/)([^&]+)/) if (youtubeMatch) { return (