@@ -27,6 +27,7 @@ interface Contributor {
2727 avatar_url : string ;
2828 contributions : number ;
2929 html_url : string ;
30+ type ?: string ;
3031}
3132
3233const ContributorsPage = ( ) => {
@@ -35,6 +36,8 @@ const ContributorsPage = () => {
3536 const [ error , setError ] = useState < string | null > ( null ) ;
3637 const [ search , setSearch ] = useState ( "" ) ;
3738 const [ sortOrder , setSortOrder ] = useState ( "desc" ) ;
39+ const [ minPRs , setMinPRs ] = useState < string > ( "" ) ;
40+ const [ prType , setPrType ] = useState < string > ( "all" ) ;
3841
3942 useEffect ( ( ) => {
4043 const fetchContributors = async ( ) => {
@@ -46,23 +49,34 @@ const ContributorsPage = () => {
4649 } catch {
4750 setError ( "Failed to fetch contributors. Please try again later." ) ;
4851 } finally {
49- setLoading ( false ) ;
52+ loading && setLoading ( false ) ;
5053 }
5154 } ;
5255 fetchContributors ( ) ;
5356 } , [ ] ) ;
5457
55- const filtered = useMemo (
56- ( ) =>
57- contributors
58- . filter ( ( c ) => c . login . toLowerCase ( ) . includes ( search . toLowerCase ( ) ) )
59- . sort ( ( a , b ) =>
60- sortOrder === "desc"
61- ? b . contributions - a . contributions
62- : a . contributions - b . contributions
63- ) ,
64- [ contributors , search , sortOrder ]
65- ) ;
58+ const handleClearFilters = ( ) => {
59+ setSearch ( "" ) ;
60+ setSortOrder ( "desc" ) ;
61+ setMinPRs ( "" ) ;
62+ setPrType ( "all" ) ;
63+ } ;
64+
65+ const filtered = useMemo ( ( ) => {
66+ return contributors
67+ . filter ( ( c ) => {
68+ const matchesSearch = c . login . toLowerCase ( ) . includes ( search . toLowerCase ( ) ) ;
69+ const matchesMinPR = minPRs === "" || c . contributions >= parseInt ( minPRs , 10 ) ;
70+ const matchesType = prType === "all" || ( c . type && c . type . toLowerCase ( ) === prType . toLowerCase ( ) ) ;
71+ return matchesSearch && matchesMinPR && matchesType ;
72+ } )
73+ . sort ( ( a , b ) => {
74+ if ( sortOrder === "desc" ) {
75+ return b . contributions - a . contributions ;
76+ }
77+ return a . contributions - b . contributions ;
78+ } ) ;
79+ } , [ contributors , search , sortOrder , minPRs , prType ] ) ;
6680
6781 if ( loading ) {
6882 return (
@@ -87,7 +101,7 @@ const ContributorsPage = () => {
87101 🤝 Contributors
88102 </ Typography >
89103
90- < Box sx = { { display : "flex" , gap : 2 , mb : 4 , flexWrap : "wrap" } } >
104+ < Box sx = { { display : "flex" , gap : 2 , mb : 4 , flexWrap : "wrap" , alignItems : "center" } } >
91105 < TextField
92106 label = "Search by username"
93107 variant = "outlined"
@@ -96,6 +110,28 @@ const ContributorsPage = () => {
96110 onChange = { ( e ) => setSearch ( e . target . value ) }
97111 sx = { { flex : 1 , minWidth : 200 } }
98112 />
113+ < TextField
114+ label = "Min PR Count"
115+ type = "number"
116+ variant = "outlined"
117+ size = "small"
118+ value = { minPRs }
119+ onChange = { ( e ) => setMinPRs ( e . target . value ) }
120+ sx = { { width : 130 } }
121+ />
122+ < FormControl size = "small" sx = { { minWidth : 150 } } >
123+ < InputLabel > PR Type</ InputLabel >
124+ < Select
125+ value = { prType }
126+ label = "PR Type"
127+ onChange = { ( e ) => setPrType ( e . target . value ) }
128+ >
129+ < MenuItem value = "all" > All Types</ MenuItem >
130+ < MenuItem value = "merged" > Merged</ MenuItem >
131+ < MenuItem value = "open" > Open</ MenuItem >
132+ < MenuItem value = "closed" > Closed</ MenuItem >
133+ </ Select >
134+ </ FormControl >
99135 < FormControl size = "small" sx = { { minWidth : 180 } } >
100136 < InputLabel > Sort by Contributions</ InputLabel >
101137 < Select
@@ -107,6 +143,14 @@ const ContributorsPage = () => {
107143 < MenuItem value = "asc" > Least to Most</ MenuItem >
108144 </ Select >
109145 </ FormControl >
146+ < Button
147+ variant = "outlined"
148+ color = "secondary"
149+ onClick = { handleClearFilters }
150+ sx = { { textTransform : "none" , height : 40 } }
151+ >
152+ Clear Filters
153+ </ Button >
110154 </ Box >
111155
112156 < Typography variant = "body2" sx = { { mb : 2 } } color = "text.secondary" >
@@ -159,7 +203,7 @@ const ContributorsPage = () => {
159203 backgroundColor : "#333333" ,
160204 textTransform : "none" ,
161205 color : "#FFFFFF" ,
162- "& :hover" : { backgroundColor : "#555555" } ,
206+ & amp ; :hover : { backgroundColor : "#555555" } ,
163207 } }
164208 >
165209 GitHub
0 commit comments