11import { useContext } from 'react'
22import { useDisclosure } from '@chakra-ui/hooks'
3- import { Menu as ChakraMenu , MenuButton , MenuList , MenuItem ,
4- Spinner , Image , Text , Divider } from '@chakra-ui/react'
5- import { SettingsIcon } from '@chakra-ui/icons'
3+ import { SettingsIcon , MoonIcon , SunIcon } from '@chakra-ui/icons'
64import { FiPlusCircle , FiLogOut } from 'react-icons/fi'
75import { UserInfo } from './user-info'
86import NewTeam from '@components/teams/new-team'
9-
107import { TeamContext } from '@components/contexts/team-context'
118
129import { signOut } from 'next-auth/react'
10+ import { useUser } from '@util/hooks'
11+
12+ import {
13+ MenuButton , MenuList , Spinner , Image , Text , Divider , useColorMode , useColorModeValue ,
14+ Menu as ChakraMenu , MenuItem as ChakraMenuItem
15+ } from '@chakra-ui/react'
1316
14- export default function SidebarMenu ( { user, teams, isTeamsLoading } ) {
17+ export default function SidebarMenu ( { teams, isTeamsLoading } ) {
18+ const { user } = useUser ( )
1519 const { currentTeam, handleTeamSwitch } = useContext ( TeamContext )
1620 const { isOpen, onOpen, onClose } = useDisclosure ( )
21+
22+ const menuItemSectionTextColor = useColorModeValue ( 'gray.600' , 'gray.100' )
23+ const logoutIconColor = useColorModeValue ( 'gray.600' , 'gray.100' )
1724
1825 return (
1926 < ChakraMenu >
@@ -26,9 +33,14 @@ export default function SidebarMenu({ user, teams, isTeamsLoading }) {
2633 < MenuList p = "2" borderRadius = "base" w = "full" >
2734 { isTeamsLoading ? < Spinner /> : (
2835 < >
29- < Text p = "0 8px 4px 8px" color = "gray.600" > Personal</ Text >
36+ < Text
37+ p = "0 8px 4px 8px" color = { menuItemSectionTextColor }
38+ >
39+ Personal
40+ </ Text >
3041 < MenuItem
31- as = "button" onClick = { ( ) => handleTeamSwitch ( user . ghLogin ) } color = "gray.700" borderRadius = "base" p = "8px"
42+ as = "button" borderRadius = "base" p = "8px"
43+ onClick = { ( ) => handleTeamSwitch ( user . ghLogin ) }
3244 >
3345 < Image
3446 boxSize = '20px'
@@ -37,55 +49,100 @@ export default function SidebarMenu({ user, teams, isTeamsLoading }) {
3749 alt = { user . ghLogin }
3850 mr = '12px'
3951 />
40- < Text fontWeight = { user . ghLogin === currentTeam ? 'bold' : 'normal' } > { user . ghLogin } </ Text >
52+ < Text fontWeight = { user . ghLogin === currentTeam ? 'bold' : 'normal' } >
53+ { user . ghLogin }
54+ </ Text >
4155 </ MenuItem >
42- < Text p = "0 8px 4px 8px" color = "gray.600" > Teams</ Text >
56+
57+ < Text p = "0 8px 4px 8px" color = { menuItemSectionTextColor } >
58+ Teams
59+ </ Text >
4360 { teams . map ( teamItem => ( user . ghLogin != teamItem . name ?
44- < MenuItem as = "button" color = "gray.700" borderRadius = "base" p = "8px" key = { `${ teamItem . name } -menu-item` }
45- onClick = { ( ) => handleTeamSwitch ( teamItem . name ) } >
61+ < MenuItem
62+ as = "button" borderRadius = "base" p = "8px"
63+ key = { `${ teamItem . name } -menu-item` }
64+ onClick = { ( ) => handleTeamSwitch ( teamItem . name ) }
65+ >
4666 < Image
4767 boxSize = '20px'
4868 borderRadius = 'full'
4969 src = { teamItem . avatarUrl ?? `https://avatars.dicebear.com/api/jdenticon/${ teamItem . name } .svg` }
5070 alt = { teamItem . name }
5171 mr = '12px'
5272 />
53- < Text fontWeight = { teamItem . name === currentTeam ? 'bold' : 'normal' } > { teamItem . name } </ Text >
73+ < Text fontWeight = { teamItem . name === currentTeam ? 'bold' : 'normal' } >
74+ { teamItem . name }
75+ </ Text >
5476 </ MenuItem >
5577 : null ) ) }
5678 < MenuItem
57- p = "8px"
58- color = "gray.700"
59- borderRadius = "base"
60- onClick = { onOpen }
79+ p = "8px"
80+ borderRadius = "base"
81+ onClick = { onOpen }
6182 icon = { < FiPlusCircle size = "20px" color = "#2780ce" /> }
6283 >
6384 Create Team
6485 </ MenuItem >
6586 < Divider my = "2" />
87+
88+ < ColorModeToggle />
6689 < MenuItem
6790 as = "a"
68- p = "8px"
69- color = "gray.700"
70- borderRadius = "base"
71- icon = { < SettingsIcon boxSize = "15px" color = "gray.600" /> }
91+ p = "8px"
92+ borderRadius = "base"
93+ icon = { < SettingsIcon boxSize = "15px" /> }
7294 href = { `/settings/teams/${ currentTeam } ` }
7395 >
7496 Team Settings
7597 </ MenuItem >
7698 < MenuItem
77- p = "8px"
78- color = "gray.700"
79- borderRadius = "base"
99+ p = "8px"
100+ borderRadius = "base"
80101 onClick = { ( ) => signOut ( ) }
81- icon = { < FiLogOut size = "15px" color = "#4A5568" /> }
102+ icon = { < FiLogOut size = "15px" color = { logoutIconColor } /> }
82103 >
83104 Logout
84105 </ MenuItem >
85106 </ >
86107 ) }
87108 </ MenuList >
88- < NewTeam isOpen = { isOpen } onOpen = { onOpen } onClose = { onClose } />
109+ < NewTeam isOpen = { isOpen } onOpen = { onOpen } onClose = { onClose } />
89110 </ ChakraMenu >
90111 )
91112}
113+
114+ /**
115+ * Small wrapper for MenuItem's text color
116+ */
117+ const MenuItem = ( { children, ...props } ) => {
118+ const menuItemTextColor = useColorModeValue ( 'gray.700' , 'gray.200' )
119+ return (
120+ < ChakraMenuItem color = { menuItemTextColor } { ...props } >
121+ { children }
122+ </ ChakraMenuItem >
123+ )
124+ }
125+
126+ const ColorModeToggle = ( ) => {
127+ const { colorMode, toggleColorMode } = useColorMode ( )
128+ const itemText = colorMode === 'light' ? 'Dark Mode' : 'Light Mode'
129+ const itemIcon = colorMode === 'light' ? < MoonIcon boxSize = "15px" /> : < SunIcon boxSize = "15px" />
130+
131+ // Delay in place because chakra toggles the entire UI and abruptly closes the menu
132+ const delayedToggle = ( ) => {
133+ setTimeout ( ( ) => {
134+ toggleColorMode ( )
135+ } , 200 )
136+ }
137+
138+ return (
139+ < MenuItem
140+ p = "8px"
141+ borderRadius = "base"
142+ onClick = { delayedToggle }
143+ icon = { itemIcon }
144+ >
145+ { itemText }
146+ </ MenuItem >
147+ )
148+ }
0 commit comments