1+ import { Button } from "@nextui-org/react"
2+ import clsx from "clsx"
3+ import { motion } from "framer-motion"
14import Image from "next/image"
25import Link from "next/link"
36import { useRouter } from "next/router"
47import { Fragment , ReactNode , Ref , useRef , useState } from "react"
58import {
9+ BsArrowLeft ,
10+ BsArrowRight ,
611 BsBell ,
712 BsBellFill ,
813 BsGear ,
@@ -53,6 +58,8 @@ function NavbarItem({
5358export default function Navbar ( ) {
5459 const [ showManageProjects , setShowManageProjects ] = useState ( false )
5560
61+ const [ doNotHide , setDoNotHide ] = useState ( false )
62+
5663 const { projects, users } = useAuth ( )
5764
5865 const router = useRouter ( )
@@ -67,143 +74,169 @@ export default function Navbar() {
6774 const notificationRef = useRef < PopupActions > ( )
6875
6976 return (
70- < nav
71- className = { `${ navigationBorderRight } sticky top-0 z-50 flex h-full max-h-screen w-16 flex-col justify-between bg-section-darkest` }
72- >
73- < div className = "flex flex-grow flex-col overflow-y-auto" >
74- < div className = "w-full p-4" >
75- < Image src = { PerplexLogo } alt = "Logo" />
76- </ div >
77-
78- < ul className = "mt-6 flex flex-grow flex-col space-y-4 overflow-y-auto" >
79- { /* Dashboard Link */ }
80- < NavbarItem href = "/" >
81- < BsHouse />
82- < span className = "text-xs text-neutral-400" > Home</ span >
83- </ NavbarItem >
84-
85- { /* Project List */ }
86- < div className = "no-scrollbar z-50 flex-grow" >
87- { p . map ( ( project , index ) => (
88- < Fragment key = { index } >
89- < NavbarItem
90- key = { index }
91- href = { `/project/${ project . ID } ` }
92- tooltip_id = { `tooltip-project-${ project . ID } ` }
93- selected = { String ( project . ID ) === projectID }
77+ < >
78+ { ! doNotHide && (
79+ < motion . div animate = { { x : 25 } } >
80+ < Button
81+ isIconOnly
82+ startContent = { < BsArrowRight /> }
83+ className = "absolute bottom-4 left-4 z-50 -translate-x-[25px] md:hidden"
84+ onClick = { ( ) => setDoNotHide ( ( prev ) => ! prev ) }
85+ />
86+ </ motion . div >
87+ ) }
88+ < div className = { clsx ( { "hidden md:block" : ! doNotHide } ) } >
89+ < nav
90+ className = { `${ navigationBorderRight } sticky top-0 z-40 flex h-full max-h-screen w-16 flex-col justify-between bg-section-darkest` }
91+ >
92+ < div className = "flex flex-grow flex-col overflow-y-auto" >
93+ < div className = "w-full p-4" >
94+ < Image src = { PerplexLogo } alt = "Logo" />
95+ </ div >
96+
97+ < ul className = "mt-6 flex flex-grow flex-col space-y-4 overflow-y-auto" >
98+ { /* Dashboard Link */ }
99+ < NavbarItem href = "/" >
100+ < BsHouse />
101+ < span className = "text-xs text-neutral-400" > Home</ span >
102+ </ NavbarItem >
103+
104+ { /* Project List */ }
105+ < div className = "no-scrollbar z-50 flex-grow" >
106+ { p . map ( ( project , index ) => (
107+ < Fragment key = { index } >
108+ < NavbarItem
109+ key = { index }
110+ href = { `/project/${ project . ID } ` }
111+ tooltip_id = { `tooltip-project-${ project . ID } ` }
112+ selected = { String ( project . ID ) === projectID }
113+ >
114+ < UserAvatar
115+ userID = { String ( project . ID ) }
116+ className = { `${
117+ String ( project . ID ) === projectID ? "" : "grayscale"
118+ } w-full rounded-[50%] transition duration-150 ease-in-out hover:scale-110 hover:rounded-md hover:grayscale-0`}
119+ />
120+ </ NavbarItem >
121+ < Tooltip
122+ id = { `tooltip-project-${ project . ID } ` }
123+ place = "right"
124+ offset = { 10 }
125+ variant = "dark"
126+ opacity = { 1.0 }
127+ style = { {
128+ zIndex : 999999 ,
129+ } }
130+ className = "bg-section-darker"
131+ closeOnScroll = { false }
132+ clickable
133+ >
134+ < span className = "flex items-center space-x-1" >
135+ < span className = "font-semibold" > { project . name } </ span >
136+ < span className = "text-neutral-400" > #{ project . ID } </ span >
137+ </ span >
138+ < span className = "flex items-center space-x-1" >
139+ < span className = "text-neutral-400" > Created by</ span >
140+ < span >
141+ < ResolveUserName userID = { project . owner_id } />
142+ </ span >
143+ </ span >
144+ </ Tooltip >
145+ </ Fragment >
146+ ) ) }
147+
148+ < li className = "flex w-full items-center justify-center px-3 py-2" >
149+ < button
150+ onClick = { ( ) => setShowManageProjects ( true ) }
151+ className = "group flex h-10 w-10 animate-pulse items-center justify-center rounded-md bg-neutral-700 bg-opacity-0 p-2 text-lg text-neutral-400 transition duration-300 hover:scale-105 hover:bg-opacity-100 hover:text-white"
152+ >
153+ < span className = "group-hover:animate-spin" >
154+ < BsGear />
155+ </ span >
156+ </ button >
157+ </ li >
158+
159+ { /* Manage Projects */ }
160+ < ModalPopup
161+ open = { showManageProjects }
162+ setOpen = { setShowManageProjects }
94163 >
95- < UserAvatar
96- userID = { String ( project . ID ) }
97- className = { `${
98- String ( project . ID ) === projectID ? "" : "grayscale"
99- } w-full rounded-[50%] transition duration-150 ease-in-out hover:scale-110 hover:rounded-md hover:grayscale-0`}
164+ < ProjectModalManageProjects
165+ onClose = { ( ) => setShowManageProjects ( false ) }
100166 />
101- </ NavbarItem >
102- < Tooltip
103- id = { `tooltip-project-${ project . ID } ` }
104- place = "right"
105- offset = { 10 }
106- variant = "dark"
107- opacity = { 1.0 }
108- style = { {
109- zIndex : 999999 ,
167+ </ ModalPopup >
168+ </ div >
169+ </ ul >
170+ </ div >
171+ < div >
172+ < ul className = "mt-6 flex flex-col space-y-2" >
173+ { /* User Settings */ }
174+ < NavbarItem href = "/user" >
175+ < BsPersonCheck />
176+ < span className = "text-xs text-neutral-400" > User</ span >
177+ </ NavbarItem >
178+
179+ { /* Notifications */ }
180+ < li className = "w-full p-5" >
181+ < Popup
182+ contentStyle = { {
183+ background : "none" ,
184+ border : "none" ,
185+ width : "auto" ,
110186 } }
111- className = "bg-section-darker"
112- closeOnScroll = { false }
113- clickable
187+ trigger = {
188+ < button className = "relative inline-flex items-center text-center text-sm font-medium" >
189+ { unreadNotifications . length > 0 ? (
190+ < >
191+ < BsBellFill size = "100%" />
192+
193+ { /* Show annoying red dot with bounce animation */ }
194+ < div className = "absolute -right-3 -top-3 inline-flex h-6 w-6 animate-ping items-center justify-center rounded-full border-2 border-section-darkest bg-red-500 text-xs font-bold text-white" > </ div >
195+ < div className = "absolute -right-3 -top-3 inline-flex h-6 w-6 items-center justify-center rounded-full border-2 border-section-darkest bg-red-500 text-xs font-bold text-white" >
196+ { unreadNotifications . length }
197+ </ div >
198+ </ >
199+ ) : (
200+ < BsBell size = "100%" />
201+ ) }
202+ </ button >
203+ }
204+ ref = { notificationRef as Ref < PopupActions > }
205+ closeOnDocumentClick = { false }
206+ closeOnEscape = { true }
207+ position = "right center"
208+ offsetX = { 30 }
209+ offsetY = { - 60 }
210+ arrow = { false }
114211 >
115- < span className = "flex items-center space-x-1" >
116- < span className = "font-semibold" > { project . name } </ span >
117- < span className = "text-neutral-400" > #{ project . ID } </ span >
118- </ span >
119- < span className = "flex items-center space-x-1" >
120- < span className = "text-neutral-400" > Created by</ span >
121- < span >
122- < ResolveUserName userID = { project . owner_id } />
123- </ span >
124- </ span >
125- </ Tooltip >
126- </ Fragment >
127- ) ) }
128-
129- < li className = "flex w-full items-center justify-center px-3 py-2" >
130- < button
131- onClick = { ( ) => setShowManageProjects ( true ) }
132- className = "group flex h-10 w-10 animate-pulse items-center justify-center rounded-md bg-neutral-700 bg-opacity-0 p-2 text-lg text-neutral-400 transition duration-300 hover:scale-105 hover:bg-opacity-100 hover:text-white"
133- >
134- < span className = "group-hover:animate-spin" >
135- < BsGear />
136- </ span >
137- </ button >
138- </ li >
139-
140- { /* Manage Projects */ }
141- < ModalPopup
142- open = { showManageProjects }
143- setOpen = { setShowManageProjects }
144- >
145- < ProjectModalManageProjects
146- onClose = { ( ) => setShowManageProjects ( false ) }
147- />
148- </ ModalPopup >
212+ < NotificationModal
213+ onClose = { ( ) => notificationRef ?. current ?. close ( ) }
214+ />
215+ </ Popup >
216+ </ li >
217+
218+ { /* GitHub Link to Repository */ }
219+ < li className = "w-full p-4" >
220+ < a href = "https://github.com/darmiel/perplex" >
221+ < BsGithub size = "100%" />
222+ </ a >
223+ </ li >
224+
225+ { doNotHide && (
226+ < li className = "block w-full items-center p-4 text-center md:hidden" >
227+ < Button
228+ isIconOnly
229+ size = "sm"
230+ startContent = { < BsArrowLeft /> }
231+ onClick = { ( ) => setDoNotHide ( ( prev ) => ! prev ) }
232+ variant = "light"
233+ />
234+ </ li >
235+ ) }
236+ </ ul >
149237 </ div >
150- </ ul >
151- </ div >
152- < div >
153- < ul className = "mt-6 flex flex-col space-y-2" >
154- { /* User Settings */ }
155- < NavbarItem href = "/user" >
156- < BsPersonCheck />
157- < span className = "text-xs text-neutral-400" > User</ span >
158- </ NavbarItem >
159-
160- { /* Notifications */ }
161- < li className = "w-full p-5" >
162- < Popup
163- contentStyle = { {
164- background : "none" ,
165- border : "none" ,
166- width : "auto" ,
167- } }
168- trigger = {
169- < button className = "relative inline-flex items-center text-center text-sm font-medium" >
170- { unreadNotifications . length > 0 ? (
171- < >
172- < BsBellFill size = "100%" />
173-
174- { /* Show annoying red dot with bounce animation */ }
175- < div className = "absolute -right-3 -top-3 inline-flex h-6 w-6 animate-ping items-center justify-center rounded-full border-2 border-section-darkest bg-red-500 text-xs font-bold text-white" > </ div >
176- < div className = "absolute -right-3 -top-3 inline-flex h-6 w-6 items-center justify-center rounded-full border-2 border-section-darkest bg-red-500 text-xs font-bold text-white" >
177- { unreadNotifications . length }
178- </ div >
179- </ >
180- ) : (
181- < BsBell size = "100%" />
182- ) }
183- </ button >
184- }
185- ref = { notificationRef as Ref < PopupActions > }
186- closeOnDocumentClick = { false }
187- closeOnEscape = { true }
188- position = "right center"
189- offsetX = { 30 }
190- offsetY = { - 60 }
191- arrow = { false }
192- >
193- < NotificationModal
194- onClose = { ( ) => notificationRef ?. current ?. close ( ) }
195- />
196- </ Popup >
197- </ li >
198-
199- { /* GitHub Link to Repository */ }
200- < li className = "w-full p-4" >
201- < a href = "https://github.com/darmiel/perplex" >
202- < BsGithub size = "100%" />
203- </ a >
204- </ li >
205- </ ul >
238+ </ nav >
206239 </ div >
207- </ nav >
240+ </ >
208241 )
209242}
0 commit comments