127127
128128 // --- Components ---
129129
130- const Hero = ( { totalContributors, totalContributions } ) => {
130+ const Hero = ( { totalContributors, totalContributions, repoStats } ) => {
131+ // Prepare Repo Stats Data
132+ const repoStatItems = repoStats ? [
133+ {
134+ label : "Stars" ,
135+ value : repoStats . total_stars ,
136+ icon : "star" ,
137+ color : "text-yellow-500" ,
138+ bg : "bg-yellow-50 dark:bg-yellow-900/20" ,
139+ border : "border-yellow-200 dark:border-yellow-800"
140+ } ,
141+ {
142+ label : "Forks" ,
143+ value : repoStats . total_forks ,
144+ icon : "call_split" ,
145+ color : "text-blue-500" ,
146+ bg : "bg-blue-50 dark:bg-blue-900/20" ,
147+ border : "border-blue-200 dark:border-blue-800"
148+ } ,
149+ {
150+ label : "Issues" ,
151+ value : repoStats . open_issues ,
152+ icon : "bug_report" ,
153+ color : "text-red-500" ,
154+ bg : "bg-red-50 dark:bg-red-900/20" ,
155+ border : "border-red-200 dark:border-red-800"
156+ }
157+ ] : [ ] ;
158+
159+ const updatedTime = repoStats ? new Date ( repoStats . updated_at ) . toLocaleString ( undefined , {
160+ year : 'numeric' ,
161+ month : 'short' ,
162+ day : 'numeric' ,
163+ hour : '2-digit' ,
164+ minute : '2-digit'
165+ } ) : null ;
166+
131167 return (
132168 < div className = "relative overflow-hidden bg-white dark:bg-gray-900 py-12 sm:py-16 border-b border-gray-200 dark:border-gray-800 transition-colors duration-300" >
133169 < div className = "relative z-10 max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 text-center" >
@@ -150,14 +186,38 @@ <h1 className="text-4xl sm:text-5xl lg:text-6xl font-extrabold tracking-tight te
150186 initial = { { opacity : 0 } }
151187 animate = { { opacity : 1 } }
152188 transition = { { delay : 0.5 , duration : 0.8 } }
153- className = "mt-8 flex justify-center gap-4 flex-wrap "
189+ className = "mt-8 flex flex-wrap justify-center gap-3 "
154190 >
155- < div className = "px-4 py-2 bg-gray-100 dark:bg-gray-800 rounded-full border border-gray-200 dark:border-gray-700 text-sm font-medium text-gray-700 dark:text-gray-200 font-roboto transition-colors duration-300" >
156- < span className = "text-green-600 dark:text-green-400 font-bold" > { totalContributors } </ span > Contributors
191+ { /* Contributors */ }
192+ < div className = "flex items-center gap-2 px-4 py-2 bg-gray-50 dark:bg-gray-800 rounded-full border border-gray-200 dark:border-gray-700 shadow-sm whitespace-nowrap transition-transform hover:scale-105" >
193+ < span className = "text-green-600 dark:text-green-400 font-bold" > { totalContributors } </ span >
194+ < span className = "text-gray-700 dark:text-gray-200 font-medium text-sm" > Contributors</ span >
157195 </ div >
158- < div className = "px-4 py-2 bg-gray-100 dark:bg-gray-800 rounded-full border border-gray-200 dark:border-gray-700 text-sm font-medium text-gray-700 dark:text-gray-200 font-roboto transition-colors duration-300" >
159- < span className = "text-blue-600 dark:text-blue-400 font-bold" > { totalContributions } </ span > Total Contributions
196+
197+ { /* Contributions */ }
198+ < div className = "flex items-center gap-2 px-4 py-2 bg-gray-50 dark:bg-gray-800 rounded-full border border-gray-200 dark:border-gray-700 shadow-sm whitespace-nowrap transition-transform hover:scale-105" >
199+ < span className = "text-blue-600 dark:text-blue-400 font-bold" > { totalContributions } </ span >
200+ < span className = "text-gray-700 dark:text-gray-200 font-medium text-sm" > Total Contributions</ span >
160201 </ div >
202+
203+ { /* Repo Stats Loop */ }
204+ { repoStatItems . map ( ( item ) => (
205+ < div key = { item . label } className = { `flex items-center gap-2 px-4 py-2 rounded-full border ${ item . bg } ${ item . border } shadow-sm whitespace-nowrap transition-transform hover:scale-105` } >
206+ < span className = { `material-symbols-outlined text-[18px] ${ item . color } ` } >
207+ { item . icon }
208+ </ span >
209+ < span className = "font-bold text-gray-800 dark:text-gray-100" > { item . value } </ span >
210+ < span className = "text-sm font-medium text-gray-500 dark:text-gray-400" > { item . label } </ span >
211+ </ div >
212+ ) ) }
213+
214+ { /* Updated Badge */ }
215+ { updatedTime && (
216+ < div className = "flex items-center gap-2 px-4 py-2 rounded-full bg-gray-100 dark:bg-gray-800/50 border border-gray-200 dark:border-gray-700 text-sm text-gray-500 dark:text-gray-400 whitespace-nowrap transition-transform hover:scale-105" >
217+ < span className = "material-symbols-outlined text-[18px]" > schedule</ span >
218+ < span > Updated: { updatedTime } </ span >
219+ </ div >
220+ ) }
161221 </ motion . div >
162222 </ div >
163223 </ div >
@@ -223,6 +283,7 @@ <h3 className="text-lg font-bold text-gray-900 dark:text-white truncate transiti
223283
224284 const App = ( ) => {
225285 const [ contributorsData , setContributorsData ] = useState ( [ ] ) ;
286+ const [ repoStats , setRepoStats ] = useState ( null ) ;
226287 const [ searchTerm , setSearchTerm ] = useState ( '' ) ;
227288 const [ selectedYear , setSelectedYear ] = useState ( 'All Time' ) ;
228289 const [ sortType , setSortType ] = useState ( 'count' ) ; // 'count', 'az', 'za', 'recent'
@@ -233,25 +294,28 @@ <h3 className="text-lg font-bold text-gray-900 dark:text-white truncate transiti
233294 useEffect ( ( ) => {
234295 Promise . all ( [
235296 fetch ( 'https://raw.githubusercontent.com/samapriya/awesome-gee-community-datasets/refs/heads/master/issues-summary.json' ) . then ( res => res . json ( ) ) ,
236- fetch ( 'https://api.github.com/repos/samapriya/awesome-gee-community-datasets/issues?state=all&per_page=100' ) . then ( res => res . json ( ) ) // Note: Using GitHub API directly might hit rate limits. Better to use your own processed JSON if possible.
237- // If you have a processed issues.json like you uploaded, use that URL instead.
238- // For now, I'll simulate the yearly processing based on the issues.json structure you shared.
239- // Assuming you host issues.json at a URL, replace the second fetch above.
297+ fetch ( 'https://api.github.com/repos/samapriya/awesome-gee-community-datasets/issues?state=all&per_page=100' ) . then ( res => res . json ( ) ) ,
298+ fetch ( 'https://raw.githubusercontent.com/samapriya/awesome-gee-community-datasets/refs/heads/master/repo-stats.json' ) . then ( res => res . json ( ) )
240299 ] )
241- . then ( ( [ summary , issues ] ) => {
300+ . then ( ( [ summary , issues , stats ] ) => {
301+ // Set Repo Stats
302+ setRepoStats ( stats ) ;
303+
242304 // Process issues to calculate yearly stats per user
243305 const yearlyData = { } ;
244306
245307 // Note: If 'issues' is the raw array of issue objects:
246- issues . forEach ( issue => {
247- const user = issue . user . login ;
248- const date = new Date ( issue . created_at ) ;
249- const year = date . getFullYear ( ) . toString ( ) ;
250-
251- if ( ! yearlyData [ user ] ) yearlyData [ user ] = { } ;
252- if ( ! yearlyData [ user ] [ year ] ) yearlyData [ user ] [ year ] = 0 ;
253- yearlyData [ user ] [ year ] ++ ;
254- } ) ;
308+ if ( Array . isArray ( issues ) ) {
309+ issues . forEach ( issue => {
310+ const user = issue . user . login ;
311+ const date = new Date ( issue . created_at ) ;
312+ const year = date . getFullYear ( ) . toString ( ) ;
313+
314+ if ( ! yearlyData [ user ] ) yearlyData [ user ] = { } ;
315+ if ( ! yearlyData [ user ] [ year ] ) yearlyData [ user ] [ year ] = 0 ;
316+ yearlyData [ user ] [ year ] ++ ;
317+ } ) ;
318+ }
255319
256320 // Merge yearly data into summary data
257321 const mergedData = summary . map ( user => ( {
@@ -264,6 +328,7 @@ <h3 className="text-lg font-bold text-gray-900 dark:text-white truncate transiti
264328 } )
265329 . catch ( err => {
266330 console . error ( "Failed to fetch data" , err ) ;
331+ // Even if stats fail, we might want to show partial data, but here we'll just stop loading
267332 setLoading ( false ) ;
268333 } ) ;
269334 } , [ ] ) ;
@@ -364,6 +429,7 @@ <h3 className="text-lg font-bold text-gray-900 dark:text-white truncate transiti
364429 < Hero
365430 totalContributors = { contributorsData . length }
366431 totalContributions = { contributorsData . reduce ( ( acc , curr ) => acc + curr . total_contributions , 0 ) }
432+ repoStats = { repoStats }
367433 />
368434
369435 < div className = "max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 -mt-8 relative z-20" >
0 commit comments