@@ -40,10 +40,9 @@ export default function PRListModal({
4040 const { getFilteredPRsForContributor, currentTimeFilter } =
4141 useCommunityStatsContext ( ) ;
4242
43- if ( ! contributor ) return null ;
44-
4543 // Get filtered PRs instead of using contributor.prDetails
4644 // Use useMemo to prevent infinite loops
45+ // IMPORTANT: All hooks must be called before any early returns
4746 const filteredPRs = useMemo ( ( ) => {
4847 if ( ! contributor ) return [ ] ;
4948 return getFilteredPRsForContributor ( contributor . username ) ;
@@ -54,6 +53,25 @@ export default function PRListModal({
5453 return filteredPRs . reduce ( ( sum , pr ) => sum + pr . points , 0 ) ;
5554 } , [ filteredPRs ] ) ;
5655
56+ // Close modal on Escape key press
57+ useEffect ( ( ) => {
58+ if ( ! isOpen ) return ;
59+ const handleEsc = ( event : KeyboardEvent ) => {
60+ if ( event . key === "Escape" ) {
61+ onClose ( ) ;
62+ }
63+ } ;
64+
65+ window . addEventListener ( "keydown" , handleEsc ) ;
66+ return ( ) => {
67+ window . removeEventListener ( "keydown" , handleEsc ) ;
68+ } ;
69+ } , [ isOpen , onClose ] ) ;
70+
71+ // Early return AFTER all hooks
72+ // Only return null if contributor is missing (not if isOpen is false, to allow exit animations)
73+ if ( ! contributor ) return null ;
74+
5775 const formatDate = ( dateString : string ) => {
5876 const date = new Date ( dateString ) ;
5977 return date . toLocaleDateString ( "en-US" , {
@@ -93,21 +111,6 @@ export default function PRListModal({
93111 return "#6b7280" ; // Gray for no points
94112 } ;
95113
96- // Close modal on Escape key press
97- useEffect ( ( ) => {
98- if ( ! isOpen ) return ;
99- const handleEsc = ( event : KeyboardEvent ) => {
100- if ( event . key === "Escape" ) {
101- onClose ( ) ;
102- }
103- } ;
104-
105- window . addEventListener ( "keydown" , handleEsc ) ;
106- return ( ) => {
107- window . removeEventListener ( "keydown" , handleEsc ) ;
108- } ;
109- } , [ isOpen , onClose ] ) ;
110-
111114 return (
112115 < AnimatePresence >
113116 { isOpen && (
0 commit comments