1+ import { PageHeader } from '@vibe/shared' ;
2+ import { Badge , Card , CardGrid } from '@vibe/ui' ;
3+ import { GitBranch , Star , Package , Users , ExternalLink } from 'lucide-react' ;
4+ import dependentsData from '../../../../data/dependents.json' ;
5+ import { PageContainer } from '../components/layout/PageContainer' ;
6+
7+ interface Dependent {
8+ url : string ;
9+ stars : number ;
10+ }
11+
12+ interface DependentsData {
13+ [ repo : string ] : {
14+ [ pkg : string ] : Dependent [ ] ;
15+ } ;
16+ }
17+
18+ interface PackageData {
19+ repo : string ;
20+ package : string ;
21+ dependents : Dependent [ ] ;
22+ }
23+
24+ function DependentsPage ( ) {
25+ const data = dependentsData as DependentsData ;
26+
27+ // Flatten the data structure to get all packages
28+ const allPackages : PackageData [ ] = [ ] ;
29+ Object . entries ( data ) . forEach ( ( [ repo , packages ] ) => {
30+ Object . entries ( packages ) . forEach ( ( [ pkg , dependents ] ) => {
31+ allPackages . push ( {
32+ repo,
33+ package : pkg ,
34+ dependents
35+ } ) ;
36+ } ) ;
37+ } ) ;
38+
39+ // Calculate stats
40+ const totalRepos = Object . keys ( data ) . length ;
41+ const totalPackages = allPackages . length ;
42+ const totalDependents = allPackages . reduce ( ( sum , pkg ) => sum + pkg . dependents . length , 0 ) ;
43+
44+ // Get top dependent across all packages
45+ const allDependents : Array < Dependent & { package : string ; repo : string } > = [ ] ;
46+ allPackages . forEach ( ( { repo, package : pkg , dependents } ) => {
47+ dependents . forEach ( dep => {
48+ allDependents . push ( { ...dep , package : pkg , repo } ) ;
49+ } ) ;
50+ } ) ;
51+ const topDependent = allDependents . sort ( ( a , b ) => b . stars - a . stars ) [ 0 ] ;
52+
53+ return (
54+ < PageContainer >
55+ < PageHeader
56+ icon = { < GitBranch className = 'text-purple-600 dark:text-purple-400' /> }
57+ title = 'GitHub Dependents'
58+ subtitle = 'Top repositories and packages that depend on our projects'
59+ action = {
60+ < Badge variant = 'info' size = 'md' >
61+ { totalDependents } Total Dependents
62+ </ Badge >
63+ }
64+ />
65+
66+ { /* Stats Cards */ }
67+ < CardGrid className = 'grid-cols-1 md:grid-cols-4 mb-8' >
68+ < Card className = 'bg-gradient-to-br from-purple-50 to-purple-100 dark:from-purple-900/20 dark:to-purple-800/20 border-purple-200 dark:border-purple-800' >
69+ < div className = 'flex items-center justify-between' >
70+ < div >
71+ < p className = 'text-sm font-medium text-purple-600 dark:text-purple-300' > Repositories</ p >
72+ < p className = 'text-2xl font-bold text-purple-900 dark:text-white' > { totalRepos } </ p >
73+ </ div >
74+ < GitBranch className = 'w-8 h-8 text-purple-500' />
75+ </ div >
76+ </ Card >
77+
78+ < Card className = 'bg-gradient-to-br from-blue-50 to-blue-100 dark:from-blue-900/20 dark:to-blue-800/20 border-blue-200 dark:border-blue-800' >
79+ < div className = 'flex items-center justify-between' >
80+ < div >
81+ < p className = 'text-sm font-medium text-blue-600 dark:text-blue-300' > Packages</ p >
82+ < p className = 'text-2xl font-bold text-blue-900 dark:text-white' > { totalPackages } </ p >
83+ </ div >
84+ < Package className = 'w-8 h-8 text-blue-500' />
85+ </ div >
86+ </ Card >
87+
88+ < Card className = 'bg-gradient-to-br from-amber-50 to-amber-100 dark:from-amber-900/20 dark:to-amber-800/20 border-amber-200 dark:border-amber-800' >
89+ < div className = 'flex items-center justify-between' >
90+ < div >
91+ < p className = 'text-sm font-medium text-amber-600 dark:text-amber-300' > Top Stars</ p >
92+ < p className = 'text-2xl font-bold text-amber-900 dark:text-white' >
93+ { topDependent ? topDependent . stars . toLocaleString ( ) : '0' }
94+ </ p >
95+ </ div >
96+ < Star className = 'w-8 h-8 text-amber-500' />
97+ </ div >
98+ </ Card >
99+
100+ < Card className = 'bg-gradient-to-br from-green-50 to-green-100 dark:from-green-900/20 dark:to-green-800/20 border-green-200 dark:border-green-800' >
101+ < div className = 'flex items-center justify-between' >
102+ < div >
103+ < p className = 'text-sm font-medium text-green-600 dark:text-green-300' > Total Dependents</ p >
104+ < p className = 'text-2xl font-bold text-green-900 dark:text-white' > { totalDependents } </ p >
105+ </ div >
106+ < Users className = 'w-8 h-8 text-green-500' />
107+ </ div >
108+ </ Card >
109+ </ CardGrid >
110+
111+ { /* All Packages in 2 Column Grid */ }
112+ < div className = 'grid grid-cols-1 lg:grid-cols-2 gap-6' >
113+ { allPackages . map ( ( { repo, package : pkg , dependents } ) => (
114+ < Card key = { `${ repo } /${ pkg } ` } className = 'p-6' >
115+ < div className = 'mb-4 flex items-center justify-between' >
116+ < div className = 'flex items-center gap-2' >
117+ < Package className = 'w-4 h-4' />
118+ < span className = 'text-sm text-slate-600 dark:text-slate-400' > { repo } </ span >
119+ </ div >
120+ < h3 className = 'text-lg font-semibold' >
121+ { pkg }
122+ </ h3 >
123+ < div className = 'w-20' > </ div >
124+ </ div >
125+
126+ < div className = 'overflow-x-auto max-h-96 overflow-y-auto' >
127+ < table className = 'w-full text-sm' >
128+ < thead className = 'sticky top-0 bg-white dark:bg-slate-900 z-10' >
129+ < tr className = 'border-b border-slate-200 dark:border-slate-700' >
130+ < th className = 'text-left py-2 px-2 font-medium text-slate-600 dark:text-slate-400 w-12' >
131+ #
132+ </ th >
133+ < th className = 'text-left py-2 px-2 font-medium text-slate-600 dark:text-slate-400' >
134+ Repository
135+ </ th >
136+ < th className = 'text-right py-2 px-2 font-medium text-slate-600 dark:text-slate-400 w-24' >
137+ Stars
138+ </ th >
139+ </ tr >
140+ </ thead >
141+ < tbody >
142+ { dependents . map ( ( dep , index ) => {
143+ const repoName = dep . url . replace ( 'https://github.com/' , '' ) ;
144+ return (
145+ < tr
146+ key = { index }
147+ className = { `
148+ border-b border-slate-100 dark:border-slate-800
149+ transition-colors duration-150
150+ ${ index % 2 === 0
151+ ? 'bg-white dark:bg-slate-950'
152+ : 'bg-gray-50/20 dark:bg-slate-900/10'
153+ }
154+ hover:bg-blue-50 dark:hover:bg-blue-950/40
155+ ` }
156+ >
157+ < td className = 'py-2 px-2 text-slate-500 dark:text-slate-400' >
158+ { index + 1 }
159+ </ td >
160+ < td className = 'py-2 px-2' >
161+ < a
162+ href = { dep . url }
163+ target = '_blank'
164+ rel = 'noopener noreferrer'
165+ className = 'text-slate-700 dark:text-slate-300 hover:text-blue-600 dark:hover:text-blue-400 transition-colors flex items-center gap-1 group'
166+ >
167+ < span className = 'truncate' > { repoName } </ span >
168+ < ExternalLink className = 'w-3 h-3 opacity-0 group-hover:opacity-100 transition-opacity flex-shrink-0' />
169+ </ a >
170+ </ td >
171+ < td className = 'py-2 px-2 text-right' >
172+ < span className = 'inline-flex items-center gap-1 text-slate-600 dark:text-slate-400' >
173+ < Star className = 'w-3 h-3' />
174+ < span className = 'font-medium' > { dep . stars . toLocaleString ( ) } </ span >
175+ </ span >
176+ </ td >
177+ </ tr >
178+ ) ;
179+ } ) }
180+ </ tbody >
181+ </ table >
182+ </ div >
183+ </ Card >
184+ ) ) }
185+ </ div >
186+ </ PageContainer >
187+ ) ;
188+ }
189+
190+ export default DependentsPage ;
0 commit comments