11import React , { type FC , useEffect , useState , useMemo } from "react" ;
2+ import SlotCounter from 'react-slot-counter' ;
23import "./LandingCommunity.css" ;
34import { useCommunityStatsContext } from "@site/src/lib/statsProvider" ;
45
@@ -7,121 +8,150 @@ type Props = {
78} ;
89
910export const LandingCommunity : FC < Props > = ( { className } ) => {
10- const { githubStarCountText, githubContributorsCount, githubForksCount } = useCommunityStatsContext ( ) ;
11- const [ state , setState ] = useState ( {
12- stat0 : 0 ,
13- stat1 : 0 ,
14- stat2 : 0 ,
15- stat3 : 0 ,
16- } ) ;
17-
11+ const {
12+ githubStarCountText,
13+ githubContributorsCountText,
14+ githubForksCountText,
15+ githubReposCountText,
16+ githubStarCount,
17+ githubContributorsCount,
18+ githubForksCount,
19+ githubReposCount,
20+ loading,
21+ error
22+ } = useCommunityStatsContext ( ) ;
23+
24+
1825 const generateList = useMemo ( ( ) => [
1926 {
20- stat : githubStarCountText ,
21- description : "Stars on our GitHub repository, showcase the support and contribution, we recieved from the community." ,
22- href : "https://github.com/recodehive" ,
23- // https://github.com/CodeHarborHub/codeharborhub.github.io/stargazers
27+ stat : githubStarCount ,
28+ statText : githubStarCountText ,
29+ description : "Stars across all our GitHub repositories, showcasing the support and appreciation from the community." ,
30+ href : "https://github.com/recodehive/Support" ,
31+ label : "GitHub Stars"
2432 } ,
2533 {
26- stat : 20 ,
27- description : "Live projects on recodehive, demonstrating the power of open-source collaboration." ,
34+ stat : githubReposCount ,
35+ statText : githubReposCountText ,
36+ description : "Live public projects on RecodHive, demonstrating the power of open-source collaboration." ,
37+ href : "https://github.com/orgs/recodehive/repositories?q=visibility%3Apublic+archived%3Afalse" ,
38+ label : "Public Repositories"
2839 } ,
2940 {
3041 stat : githubContributorsCount ,
31- description : "List of Contributors who have made our repository better." ,
32- href : "https://github.com/recodehive" ,
33- // https://github.com/CodeHarborHub/codeharborhub.github.io/graphs/contributors
42+ statText : githubContributorsCountText ,
43+ description : "Amazing contributors who have made our repositories better and helped build our community." ,
44+ href : "https://github.com/orgs/recodehive/people" ,
45+ label : "Contributors"
3446 } ,
3547 {
3648 stat : githubForksCount ,
37- description : "Forks of our repository, showing how our community extends our work." ,
38- href : "https://github.com/recodehive " ,
39-
40- //https://github.com/CodeHarborHub/codeharborhub.github.io/network/members
49+ statText : githubForksCountText ,
50+ description : "Forks of our repositories, showing how our community extends and builds upon our work. " ,
51+ href : "https://github.com/orgs/recodehive/discussions" ,
52+ label : "Community Forks"
4153 } ,
42- ] , [ githubStarCountText , githubContributorsCount , githubForksCount ] ) ;
54+ ] , [ githubStarCount , githubStarCountText , githubReposCount , githubReposCountText , githubContributorsCount , githubContributorsCountText , githubForksCount , githubForksCountText ] ) ;
4355
44- const handleDynamicChange = ( target : number , index : number ) => {
45- let count = 0 ;
46- const increment = target / 100 ;
47- const interval = setInterval ( ( ) => {
48- count += increment ;
49- setState ( prev => ( { ...prev , [ `stat${ index } ` ] : Math . round ( count ) } ) ) ;
50- if ( count >= target ) {
51- setState ( prev => ( { ...prev , [ `stat${ index } ` ] : target } ) ) ;
52- clearInterval ( interval ) ;
53- }
54- } , 20 ) ;
56+ const handleCardClick = ( href : string ) => {
57+ if ( href ) {
58+ window . open ( href , '_blank' , 'noopener,noreferrer' ) ;
59+ }
5560 } ;
5661
57- useEffect ( ( ) => {
58- generateList . forEach ( ( item , index ) => {
59- handleDynamicChange ( Number ( item . stat ) , index ) ;
60- } ) ;
61- } , [ generateList ] ) ;
62-
6362 return (
6463 < div className = { `landing-community ${ className || "" } ` } >
6564 < div className = "landing-community__header" >
6665 < h2 className = "landing-community__title" >
6766 Discover the strength of our{ " " }
6867 < span className = "landing-community__highlight" > amazing community</ span > .
6968 </ h2 >
69+ { error && (
70+ < div className = "landing-community__error" >
71+ < small > ⚠️ Stats may be cached or incomplete</ small >
72+ </ div >
73+ ) }
7074 </ div >
7175
7276 < div className = "landing-community__content" >
7377 < div className = "landing-community__stats" >
7478 { generateList . map ( ( item , index ) => (
75- < span key = { index } className = "landing-community__stat-item" >
79+ < div
80+ key = { index }
81+ className = { `landing-community__stat-item ${ item . href ? 'clickable' : '' } ${ loading ? 'loading' : '' } ` }
82+ onClick = { ( ) => handleCardClick ( item . href ) }
83+ role = { item . href ? "button" : "presentation" }
84+ tabIndex = { item . href ? 0 : - 1 }
85+ onKeyDown = { ( e ) => {
86+ if ( item . href && ( e . key === 'Enter' || e . key === ' ' ) ) {
87+ e . preventDefault ( ) ;
88+ handleCardClick ( item . href ) ;
89+ }
90+ } }
91+ title = { item . href ? `Click to visit ${ item . label } ` : item . label }
92+ >
7693 < div className = "landing-community__stat-value" >
77- { item . href ? (
78- < a
79- href = { item . href }
80- target = "_blank"
81- rel = "noopener noreferrer"
82- >
83- { `${ state [ `stat${ index } ` ] } ${ index !== 1 ? "" : "" } ` }
84- </ a >
94+ { loading ? (
95+ < div className = "landing-community__loading" >
96+ < span className = "loading-spinner" > ⏳</ span >
97+ </ div >
8598 ) : (
86- `${ state [ `stat${ index } ` ] } `
99+ < span >
100+ < SlotCounter
101+ value = { item . stat }
102+ duration = { 2 }
103+ animateOnVisible = { {
104+ triggerOnce : true ,
105+ rootMargin : '0px 0px -100px 0px'
106+ } }
107+ numberSlotClassName = "slot-counter-number"
108+ separatorClassName = "slot-counter-separator"
109+ />
110+ { item . href && < span className = "external-link-icon" > ↗</ span > }
111+ </ span >
87112 ) }
88113 </ div >
89114 < div className = "landing-community__stat-description" >
90115 { item . description }
91116 </ div >
92- </ span >
117+ </ div >
93118 ) ) }
94119 </ div >
95120
96- < div className = "landing-community__info" >
121+ < div
122+ className = "landing-community__info clickable"
123+ onClick = { ( ) => handleCardClick ( "https://github.com/recodehive" ) }
124+ role = "button"
125+ tabIndex = { 0 }
126+ onKeyDown = { ( e ) => {
127+ if ( e . key === 'Enter' || e . key === ' ' ) {
128+ e . preventDefault ( ) ;
129+ handleCardClick ( "https://github.com/recodehive" ) ;
130+ }
131+ } }
132+ title = "Click to visit RecodHive GitHub Organization"
133+ >
97134 < img
98135 className = "landing-community__image"
99136 src = "/community.png"
100137 alt = "team collaboration"
101138 loading = "lazy"
102139 />
103140 < div className = "landing-community__info-text" >
104- Our developers are the core of Hive community. We take pride in
141+ Our developers are the core of RecodHive community. We take pride in
105142 our{ " " }
106- < a
107- href = "https://github.com/recodehive"
108- //https://github.com/CodeHarborHub/codeharborhub.github.io/graphs/contributors
109- target = "_blank"
110- rel = "noopener noreferrer"
111- className = "landing-community__link"
112- >
113- GitHub community
114- </ a > { " " }
115- with over{ " " }
116- < a
117- href = "https://github.com/recodehive"
118- target = "_blank"
119- rel = "noopener noreferrer"
120- className = "landing-community__link"
121- >
122- 500+ contributors
123- </ a > { " " }
124- powering recodehive.
143+ < span className = "landing-community__link" >
144+ GitHub organization
145+ </ span > { " " }
146+ with amazing{ " " }
147+ < span className = "landing-community__link" >
148+ contributors and maintainers
149+ </ span > { " " }
150+ powering RecodHive's growth.
151+ < div className = "external-link-indicator" >
152+ < span className = "external-link-icon" > ↗</ span >
153+ < small > Click to explore our GitHub</ small >
154+ </ div >
125155 </ div >
126156 </ div >
127157 </ div >
0 commit comments