'use client'
import { useEffect, useState } from 'react'
import { JsDelivrPackages, JsDelivrPackage } from '@/components/phucbm/jsdelivr'
import { getPublicGithubRepos } from '@/registry/phucbm/lib/getPublicGithubRepos'
import { getJsDelivrPackages } from '@/lib/getJsDelivrPackages'
export default function Example02() {
const [username, setUsername] = useState('phucbm')
const [packages, setPackages] = useState<JsDelivrPackage[]>([])
const [loading, setLoading] = useState(false)
const [error, setError] = useState<string | null>(null)
const [reposFound, setReposFound] = useState(0)
const [packagesFound, setPackagesFound] = useState(0)
useEffect(() => {
// Debounce timer
const timer = setTimeout(async () => {
if (!username.trim()) {
setPackages([])
setReposFound(0)
setPackagesFound(0)
setError(null)
return
}
setLoading(true)
setError(null)
setPackages([])
try {
// Fetch public repos from GitHub
const repos = await getPublicGithubRepos(username, 50, 36)
setReposFound(repos.length)
if (repos.length === 0) {
setPackagesFound(0)
setLoading(false)
return
}
// Extract package names from repo names
const packageNames = repos.map((repo: any) => repo.name)
// Fetch jsDelivr stats for those packages
// Only show packages with actual hits (minHits: 1)
const jsDelivrPackages = await getJsDelivrPackages(packageNames, username, 'month', 1)
setPackagesFound(jsDelivrPackages.length)
setPackages(jsDelivrPackages)
} catch (err) {
setError(err instanceof Error ? err.message : 'Failed to load packages')
setPackagesFound(0)
} finally {
setLoading(false)
}
}, 1000) // 1 second debounce
return () => clearTimeout(timer)
}, [username])
return (
<div className="bg-slate-50">
{/* Sticky Header */}
<div className="sticky top-0 bg-white border-b border-slate-200 p-4 z-10">
<div className="flex items-end gap-4">
{/* Input Section */}
<div className="flex-1 relative">
<label className="text-xs font-semibold text-slate-700 block mb-1">GitHub Username</label>
<input
type="text"
value={username}
onChange={(e) => setUsername(e.target.value)}
placeholder="Enter username..."
className="w-full px-3 py-2 text-sm border border-slate-300 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500"
/>
<p className="text-xs text-slate-500 mt-1">
Shows repos with CDN downloads on jsDelivr
</p>
{/* Loading Indicator - Absolute to prevent CLS */}
{loading && (
<div className="absolute right-3 top-8 text-slate-500 text-xs whitespace-nowrap">
Loading...
</div>
)}
</div>
{/* Stats Section */}
{(reposFound > 0 || packagesFound > 0) && (
<div className="flex gap-3">
<div className="bg-blue-50 px-3 py-2 rounded border border-blue-200">
<p className="text-blue-600 font-semibold text-sm">{reposFound}</p>
<p className="text-blue-700 text-xs whitespace-nowrap">Repos</p>
</div>
<div className="bg-green-50 px-3 py-2 rounded border border-green-200">
<p className="text-green-600 font-semibold text-sm">{packagesFound}</p>
<p className="text-green-700 text-xs whitespace-nowrap">Downloads</p>
</div>
</div>
)}
</div>
</div>
{/* Scrollable Content */}
<div className="flex-1 p-6 space-y-4">
{/* Error State */}
{error && (
<div className="bg-red-50 border border-red-200 rounded p-4">
<p className="text-red-600 text-sm font-semibold">Error</p>
<p className="text-red-700 text-sm">{error}</p>
</div>
)}
{/* Results Section */}
{!loading && !error && packages.length > 0 && (
<div className="space-y-4">
<div className="text-sm font-semibold text-slate-700">
jsDelivr Packages ({packages.length})
</div>
<JsDelivrPackages packages={packages} statsPeriod="month" showBandwidth={true} />
</div>
)}
{/* No Results */}
{!loading && !error && reposFound > 0 && packages.length === 0 && (
<div className="bg-yellow-50 border border-yellow-200 rounded p-4">
<p className="text-yellow-700 text-sm">
Found {reposFound} repositories, but none have actual CDN downloads on jsDelivr.
Repos need distributed files and active downloads to appear here.
</p>
</div>
)}
{/* Empty State */}
{!loading && !error && reposFound === 0 && username.trim() && (
<div className="bg-slate-100 border border-slate-300 rounded p-4">
<p className="text-slate-600 text-sm">
No public repositories found for "{username}"
</p>
</div>
)}
</div>
</div>
)
}