11import React , { useEffect , useState , useRef , useCallback } from 'react' ;
2- import './Leaderboard.css' ;
2+ import './Leaderboard.module. css' ;
33import { isEqual , debounce } from 'lodash' ;
44import { Link } from 'react-router-dom' ;
55import {
@@ -275,7 +275,9 @@ function LeaderBoard({
275275
276276 const [ isLoading , setIsLoading ] = useState ( false ) ;
277277 // add state hook for the popup the personal's dashboard from leaderboard
278- const [ isDashboardOpen , setIsDashboardOpen ] = useState ( false ) ;
278+ const [ isDashboardOpen , setIsDashboardOpen ] = useState ( null ) ;
279+ const openDashboardModal = personId => setIsDashboardOpen ( personId ) ;
280+ const closeDashboardModal = ( ) => setIsDashboardOpen ( null ) ;
279281 const dashboardToggle = item => setIsDashboardOpen ( item . personId ) ;
280282 const dashboardClose = ( ) => setIsDashboardOpen ( false ) ;
281283
@@ -882,18 +884,67 @@ function LeaderBoard({
882884 if ( e . key === 'Enter' ) {
883885 handleDashboardAccess ( item ) ;
884886 }
887+ { /* Put the modal OUTSIDE the table rows to avoid JSX nesting issues */ }
888+ < Modal
889+ isOpen = { isDashboardOpen === item . personId }
890+ toggle = { closeDashboardModal }
891+ className = { darkMode ? 'text-light dark-mode' : '' }
892+ style = { darkMode ? boxStyleDark : { } }
893+ >
894+ < ModalHeader
895+ toggle = { closeDashboardModal }
896+ className = { darkMode ? 'bg-space-cadet' : '' }
897+ >
898+ Jump to personal Dashboard
899+ </ ModalHeader >
900+ < ModalBody className = { darkMode ? 'bg-yinmn-blue' : '' } >
901+ < p className = { darkMode ? 'text-light' : '' } >
902+ Are you sure you wish to view this { item . name } dashboard?
903+ </ p >
904+ </ ModalBody >
905+ < ModalFooter className = { darkMode ? 'bg-yinmn-blue' : '' } >
906+ < Button variant = "primary" onClick = { ( ) => showDashboard ( item ) } >
907+ Ok
908+ </ Button > { ' ' }
909+ < Button variant = "secondary" onClick = { closeDashboardModal } >
910+ Cancel
911+ </ Button >
912+ </ ModalFooter >
913+ </ Modal >
914+
915+ { /* First row - status + name */ }
916+ < tr
917+ className = { `${
918+ darkMode ? 'dark-leaderboard-row' : 'light-leaderboard-row'
919+ } user-row-first`}
920+ data-user-id = { item . personId }
921+ onMouseEnter = { ( ) => {
922+ document
923+ . querySelectorAll ( `[data-user-id="${ item . personId } "]` )
924+ . forEach ( el => el . classList . add ( 'row-hover' ) ) ;
925+ } }
926+ onMouseLeave = { ( ) => {
927+ document
928+ . querySelectorAll ( `[data-user-id="${ item . personId } "]` )
929+ . forEach ( el => el . classList . remove ( 'row-hover' ) ) ;
930+ } }
931+ >
932+ < td className = "align-middle status-cell" >
933+ < div
934+ style = { {
935+ display : 'flex' ,
936+ alignItems : 'center' ,
937+ justifyContent : hasSummaryIndicatorPermission
938+ ? 'space-between'
939+ : 'center' ,
885940 } }
886941 >
887942 < div
888943 role = "button"
889944 tabIndex = { 0 }
890- onClick = { ( ) => {
891- dashboardToggle ( item ) ;
892- } }
945+ onClick = { ( ) => openDashboardModal ( item . personId ) }
893946 onKeyDown = { e => {
894- if ( e . key === 'Enter' ) {
895- dashboardToggle ( item ) ;
896- }
947+ if ( e . key === 'Enter' ) openDashboardModal ( item . personId ) ;
897948 } }
898949 >
899950 { hasLeaderboardPermissions ( item . role ) &&
@@ -952,7 +1003,7 @@ function LeaderBoard({
9521003 </ div >
9531004 </ td >
9541005
955- { /* Extended Name cell spanning multiple columns - only name and visibility */ }
1006+ { /* name cell spanning columns */ }
9561007 < td className = "align-middle extended-name-cell" colSpan = "6" >
9571008 < Link
9581009 to = { `/userprofile/${ item . personId } ` }
@@ -975,7 +1026,7 @@ function LeaderBoard({
9751026 </ td >
9761027 </ tr >
9771028
978- { /* Second row - All other details aligned with columns */ }
1029+ { /* second row - actual columns */ }
9791030 < tr
9801031 className = { `${
9811032 darkMode ? 'dark-leaderboard-row' : 'light-leaderboard-row'
@@ -984,24 +1035,18 @@ function LeaderBoard({
9841035 onMouseEnter = { ( ) => {
9851036 document
9861037 . querySelectorAll ( `[data-user-id="${ item . personId } "]` )
987- . forEach ( el => {
988- el . classList . add ( 'row-hover' ) ;
989- } ) ;
1038+ . forEach ( el => el . classList . add ( 'row-hover' ) ) ;
9901039 } }
9911040 onMouseLeave = { ( ) => {
9921041 document
9931042 . querySelectorAll ( `[data-user-id="${ item . personId } "]` )
994- . forEach ( el => {
995- el . classList . remove ( 'row-hover' ) ;
996- } ) ;
1043+ . forEach ( el => el . classList . remove ( 'row-hover' ) ) ;
9971044 } }
9981045 >
999- < td > </ td > { /* Empty status cell */ }
1046+ < td / > { /* empty status cell to align */ }
10001047 < td className = "align-middle name-details-cell" >
1001- { /* All the additional elements moved here */ }
1002- { isAllowedOtherThanOwner || isOwner || item . personId === userId
1003- ? timeOffIndicator ( item . personId )
1004- : null }
1048+ { ( isAllowedOtherThanOwner || isOwner || item . personId === userId ) &&
1049+ timeOffIndicator ( item . personId ) }
10051050
10061051 { hasLeaderboardPermissions ( loggedInUser . role ) && showTrophy && (
10071052 < i
@@ -1020,27 +1065,26 @@ function LeaderBoard({
10201065 </ p >
10211066 </ i >
10221067 ) }
1023- < div >
1024- < Modal isOpen = { modalOpen === item . personId } toggle = { trophyIconToggle } >
1025- < ModalHeader toggle = { trophyIconToggle } > Followed Up?</ ModalHeader >
1026- < ModalBody >
1027- < p > Are you sure you have followed up this icon?</ p >
1028- </ ModalBody >
1029- < ModalFooter >
1030- < Button variant = "secondary" onClick = { trophyIconToggle } >
1031- Cancel
1032- </ Button > { ' ' }
1033- < Button
1034- color = "primary"
1035- onClick = { ( ) => {
1036- handleChangingTrophyIcon ( item , true ) ;
1037- } }
1038- >
1039- Confirm
1040- </ Button >
1041- </ ModalFooter >
1042- </ Modal >
1043- </ div >
1068+ { /* trophy modal stays here, it's local to this row */ }
1069+ < Modal isOpen = { modalOpen === item . personId } toggle = { trophyIconToggle } >
1070+ < ModalHeader toggle = { trophyIconToggle } > Followed Up?</ ModalHeader >
1071+ < ModalBody >
1072+ < p > Are you sure you have followed up this icon?</ p >
1073+ </ ModalBody >
1074+ < ModalFooter >
1075+ < Button variant = "secondary" onClick = { trophyIconToggle } >
1076+ Cancel
1077+ </ Button > { ' ' }
1078+ < Button
1079+ color = "primary"
1080+ onClick = { ( ) => {
1081+ handleChangingTrophyIcon ( item , true ) ;
1082+ } }
1083+ >
1084+ Confirm
1085+ </ Button >
1086+ </ ModalFooter >
1087+ </ Modal >
10441088 { hasTimeOffIndicatorPermission && additionalWeeks > 0 && (
10451089 < span
10461090 style = { {
@@ -1105,10 +1149,7 @@ function LeaderBoard({
11051149 < td className = "align-middle" id = { `id${ item . personId } ` } >
11061150 < span title = "Tangible time" > { item . tangibletime } </ span >
11071151 </ td >
1108- < td
1109- className = "align-middle"
1110- aria-label = "Description or purpose of the cell"
1111- >
1152+ < td className = "align-middle" >
11121153 < Link
11131154 to = { `/timelog/${ item . personId } ` }
11141155 title = { `TangibleEffort: ${ item . tangibletime } hours` }
0 commit comments