@@ -6,12 +6,16 @@ import { PlayType } from 'src/types'
66import { useRouter } from 'next/router'
77import { DiscordIcon } from './Icons'
88import { useCallback , useContext , useEffect , useState } from 'react'
9+ import { motion , AnimatePresence } from 'framer-motion'
910import { AuthContext , ModalContext , WindowSizeContext } from 'src/contexts'
1011import { LeaderboardNavBadge } from '../Leaderboard/LeaderboardNavBadge'
1112import { useLeaderboardStatus } from 'src/hooks/useLeaderboardStatus'
1213
1314export const Header : React . FC = ( ) => {
1415 const [ showMenu , setShowMenu ] = useState ( false )
16+ const [ showPlayDropdown , setShowPlayDropdown ] = useState ( false )
17+ const [ showMoreDropdown , setShowMoreDropdown ] = useState ( false )
18+ const [ showProfileDropdown , setShowProfileDropdown ] = useState ( false )
1519 const { isMobile } = useContext ( WindowSizeContext )
1620
1721 const { user, connectLichess, logout } = useContext ( AuthContext )
@@ -70,32 +74,46 @@ export const Header: React.FC = () => {
7074 } , [ showMenu ] )
7175
7276 const userInfo = user ?. lichessId ? (
73- < div className = "group relative flex w-full items-center gap-3 rounded bg-background-1 px-3 py-2 md:w-auto" >
77+ < div
78+ className = "relative flex w-full items-center gap-3 rounded bg-background-1 px-3 py-2 md:w-auto"
79+ onMouseEnter = { ( ) => setShowProfileDropdown ( true ) }
80+ onMouseLeave = { ( ) => setShowProfileDropdown ( false ) }
81+ >
7482 < span className = "material-symbols-outlined text-3xl" > account_circle</ span >
7583 < div className = "flex flex-col" >
7684 < p className = "text-sm" > { user ?. displayName } </ p >
7785 < p className = "text-xs text-secondary" > View Info</ p >
7886 </ div >
79- < div className = "absolute bottom-[100%] left-0 z-50 hidden w-full overflow-hidden rounded bg-background-2 group-hover:flex group-hover:flex-col md:bottom-auto md:top-[100%]" >
80- < Link
81- href = "/profile"
82- className = "flex w-full items-center justify-start px-3 py-2 hover:bg-background-3"
83- >
84- Profile
85- </ Link >
86- < Link
87- href = "/settings"
88- className = "flex w-full items-center justify-start px-3 py-2 hover:bg-background-3"
89- >
90- Settings
91- </ Link >
92- < button
93- onClick = { logout }
94- className = "flex w-full items-center justify-start px-3 py-2 hover:bg-background-3"
95- >
96- Logout
97- </ button >
98- </ div >
87+ < AnimatePresence >
88+ { showProfileDropdown && (
89+ < motion . div
90+ initial = { { opacity : 0 , y : - 10 } }
91+ animate = { { opacity : 1 , y : 0 } }
92+ exit = { { opacity : 0 , y : - 10 } }
93+ transition = { { duration : 0.2 } }
94+ className = "absolute bottom-[100%] left-0 z-50 w-full overflow-hidden rounded border border-white/10 bg-background-1 shadow-lg md:bottom-auto md:top-[100%]"
95+ >
96+ < Link
97+ href = "/profile"
98+ className = "flex w-full items-center justify-start px-3 py-2 text-sm hover:bg-background-2/60"
99+ >
100+ Profile
101+ </ Link >
102+ < Link
103+ href = "/settings"
104+ className = "flex w-full items-center justify-start px-3 py-2 text-sm hover:bg-background-2/60"
105+ >
106+ Settings
107+ </ Link >
108+ < button
109+ onClick = { logout }
110+ className = "flex w-full items-center justify-start px-3 py-2 text-sm hover:bg-background-2/60"
111+ >
112+ Logout
113+ </ button >
114+ </ motion . div >
115+ ) }
116+ </ AnimatePresence >
99117 </ div >
100118 ) : (
101119 < button onClick = { connectLichess } > Sign in</ button >
@@ -110,31 +128,43 @@ export const Header: React.FC = () => {
110128 </ Link >
111129 < div className = "hidden flex-row gap-1 *:px-2 *:py-1 md:flex" >
112130 < div
113- className = { `${ router . pathname . startsWith ( '/play' ) && 'bg-background-1' } group relative` }
131+ className = { `${ router . pathname . startsWith ( '/play' ) && 'bg-background-1' } relative` }
132+ onMouseEnter = { ( ) => setShowPlayDropdown ( true ) }
133+ onMouseLeave = { ( ) => setShowPlayDropdown ( false ) }
114134 >
115135 < button className = "uppercase" > Play</ button >
116- < div className = "absolute left-0 top-[100%] z-30 hidden w-48 flex-col items-start bg-background-1 group-hover:flex" >
117- < button
118- onClick = { ( ) => startGame ( 'againstMaia' ) }
119- className = "flex w-full items-center justify-start px-3 py-2 hover:bg-background-2"
120- >
121- Play Maia
122- </ button >
123- < button
124- onClick = { ( ) => startGame ( 'handAndBrain' ) }
125- className = "flex w-full items-center justify-start px-3 py-2 hover:bg-background-2"
126- >
127- Play Hand and Brain
128- </ button >
129- < a
130- className = "flex w-full items-center justify-start px-3 py-2 hover:bg-background-2"
131- href = "https://lichess.org/@/maia1"
132- target = "_blank"
133- rel = "noreferrer"
134- >
135- Play Maia on Lichess
136- </ a >
137- </ div >
136+ < AnimatePresence >
137+ { showPlayDropdown && (
138+ < motion . div
139+ initial = { { opacity : 0 , y : - 10 } }
140+ animate = { { opacity : 1 , y : 0 } }
141+ exit = { { opacity : 0 , y : - 10 } }
142+ transition = { { duration : 0.2 } }
143+ className = "absolute left-0 top-[100%] z-30 w-48 overflow-hidden rounded border border-white/10 bg-background-1 shadow-lg"
144+ >
145+ < button
146+ onClick = { ( ) => startGame ( 'againstMaia' ) }
147+ className = "flex w-full items-center justify-start px-3 py-2 text-sm hover:bg-background-2/60"
148+ >
149+ Play Maia
150+ </ button >
151+ < button
152+ onClick = { ( ) => startGame ( 'handAndBrain' ) }
153+ className = "flex w-full items-center justify-start px-3 py-2 text-sm hover:bg-background-2/60"
154+ >
155+ Play Hand and Brain
156+ </ button >
157+ < a
158+ className = "flex w-full items-center justify-start px-3 py-2 text-sm hover:bg-background-2/60"
159+ href = "https://lichess.org/@/maia1"
160+ target = "_blank"
161+ rel = "noreferrer"
162+ >
163+ Play Maia on Lichess
164+ </ a >
165+ </ motion . div >
166+ ) }
167+ </ AnimatePresence >
138168 </ div >
139169 < Link
140170 href = "/analysis"
@@ -166,35 +196,55 @@ export const Header: React.FC = () => {
166196 >
167197 Leaderboard
168198 </ Link >
169- < div className = "group relative" >
199+ < div
200+ className = "relative"
201+ onMouseEnter = { ( ) => setShowMoreDropdown ( true ) }
202+ onMouseLeave = { ( ) => setShowMoreDropdown ( false ) }
203+ >
170204 < button className = "-gap-1 flex items-center" >
171205 < p className = "uppercase" > More</ p >
172- < i className = "material-symbols-outlined" > arrow_drop_down</ i >
173- </ button >
174- < div className = "absolute left-0 top-[100%] z-30 hidden w-32 flex-col items-start bg-background-1 group-hover:flex" >
175- < Link
176- href = "/blog"
177- className = "flex w-full items-center justify-start px-3 py-2 hover:bg-background-2"
178- >
179- Blog
180- </ Link >
181- < a
182- target = "_blank"
183- rel = "noreferrer"
184- href = "https://twitch.tv/maiachess"
185- className = "flex w-full items-center justify-start px-3 py-2 hover:bg-background-2"
186- >
187- Watch
188- </ a >
189- < a
190- target = "_blank"
191- rel = "noreferrer"
192- href = "https://forms.gle/XYeoTJF4YgUu4Vq28"
193- className = "flex w-full items-center justify-start px-3 py-2 hover:bg-background-2"
206+ < motion . i
207+ className = "material-symbols-outlined"
208+ animate = { { rotate : showMoreDropdown ? 180 : 0 } }
209+ transition = { { duration : 0.2 } }
194210 >
195- Feedback
196- </ a >
197- </ div >
211+ arrow_drop_down
212+ </ motion . i >
213+ </ button >
214+ < AnimatePresence >
215+ { showMoreDropdown && (
216+ < motion . div
217+ initial = { { opacity : 0 , y : - 10 } }
218+ animate = { { opacity : 1 , y : 0 } }
219+ exit = { { opacity : 0 , y : - 10 } }
220+ transition = { { duration : 0.2 } }
221+ className = "absolute left-0 top-[100%] z-30 w-32 overflow-hidden rounded border border-white/10 bg-background-1 shadow-lg"
222+ >
223+ < Link
224+ href = "/blog"
225+ className = "flex w-full items-center justify-start px-3 py-2 text-sm hover:bg-background-2/60"
226+ >
227+ Blog
228+ </ Link >
229+ < a
230+ target = "_blank"
231+ rel = "noreferrer"
232+ href = "https://twitch.tv/maiachess"
233+ className = "flex w-full items-center justify-start px-3 py-2 text-sm hover:bg-background-2/60"
234+ >
235+ Watch
236+ </ a >
237+ < a
238+ target = "_blank"
239+ rel = "noreferrer"
240+ href = "https://forms.gle/XYeoTJF4YgUu4Vq28"
241+ className = "flex w-full items-center justify-start px-3 py-2 text-sm hover:bg-background-2/60"
242+ >
243+ Feedback
244+ </ a >
245+ </ motion . div >
246+ ) }
247+ </ AnimatePresence >
198248 </ div >
199249 </ div >
200250 </ div >
0 commit comments