@@ -5,6 +5,7 @@ import Link from "next/link";
55import SidebarItem from "../sidebar/SidebarItem" ;
66import { useRouter } from "next/navigation" ;
77import { IconWrapper } from "../ui/IconWrapper" ;
8+ import { motion , AnimatePresence } from "framer-motion" ;
89import {
910 XMarkIcon ,
1011 HomeIcon ,
@@ -41,9 +42,8 @@ const SIDEBAR_ROUTES = [
4142 } ,
4243] ;
4344
44- export default function Sidebar ( ) {
45- const { showSidebar, setShowSidebar, isCollapsed, toggleCollapsed } =
46- useShowSidebar ( ) ;
45+ export default function Sidebar ( { overlay = false } : { overlay ?: boolean } ) {
46+ const { setShowSidebar, isCollapsed, toggleCollapsed } = useShowSidebar ( ) ;
4747 const router = useRouter ( ) ;
4848 const { isPaidUser } = useSubscription ( ) ;
4949
@@ -58,14 +58,19 @@ export default function Sidebar() {
5858 router . push ( "/pricing" ) ;
5959 }
6060 } ;
61+ const desktopWidth = isCollapsed ? 80 : 288 ;
62+ const mobileWidth = desktopWidth ;
6163
6264 return (
63- < div
64- className = { `h-screen ${
65- isCollapsed ? "w-20" : "w-72"
66- } flex flex-col bg-ox-sidebar border-r border-ox-header z-50 transition-all duration-300 ease-out ${
67- showSidebar ? "fixed xl:relative left-0 top-0 bottom-0" : ""
65+ < motion . div
66+ className = { `h-screen flex flex-col bg-ox-sidebar border-r border-ox-header z-50 ${
67+ overlay ? "fixed left-0 top-0 bottom-0 xl:hidden" : ""
6868 } `}
69+ initial = { overlay ? { x : - 400 , width : mobileWidth } : { width : desktopWidth } }
70+ animate = { overlay ? { x : 0 , width : mobileWidth } : { width : desktopWidth } }
71+ exit = { overlay ? { x : - 400 , width : mobileWidth } : undefined }
72+ transition = { { type : "spring" , stiffness : 260 , damping : 30 } }
73+ style = { { width : overlay ? mobileWidth : desktopWidth } }
6974 >
7075 { /* Mobile header */ }
7176 < div className = "flex justify-between items-center h-16 px-4 border-b border-ox-header xl:hidden bg-ox-sideba" >
@@ -149,7 +154,7 @@ export default function Sidebar() {
149154
150155 { /* Bottom profile */ }
151156 < ProfileMenu isCollapsed = { isCollapsed } />
152- </ div >
157+ </ motion . div >
153158 ) ;
154159}
155160
@@ -203,46 +208,55 @@ function ProfileMenu({ isCollapsed }: { isCollapsed: boolean }) {
203208 ) }
204209 </ div >
205210 { /* Profile Card Dropdown */ }
206- { ! isCollapsed && open && (
207- < div className = "absolute bottom-full left-3 right-3 mb-2 bg-ox-profile-card border border-ox-header rounded-lg shadow-xl overflow-hidden z-50" >
208- { /* User Info Section */ }
209- < div className = "p-3 border-b border-ox-header" >
210- < div className = "flex items-center gap-3" >
211- < ProfilePic imageUrl = { userImage } />
212- < div className = "flex flex-col" >
213- < span className = "text-sm text-white font-semibold" >
214- { fullName }
215- </ span >
216- < span className = "text-xs text-zinc-400" > { userEmail } </ span >
211+ < AnimatePresence >
212+ { ! isCollapsed && open && (
213+ < motion . div
214+ key = "profile-dropdown"
215+ initial = { { opacity : 0 , y : 8 } }
216+ animate = { { opacity : 1 , y : 0 } }
217+ exit = { { opacity : 0 , y : 8 } }
218+ transition = { { duration : 0.18 } }
219+ className = "absolute bottom-full left-3 right-3 mb-2 bg-ox-profile-card border border-ox-header rounded-lg shadow-xl overflow-hidden z-50"
220+ >
221+ { /* User Info Section */ }
222+ < div className = "p-3 border-b border-ox-header" >
223+ < div className = "flex items-center gap-3" >
224+ < ProfilePic imageUrl = { userImage } />
225+ < div className = "flex flex-col" >
226+ < span className = "text-sm text-white font-semibold" >
227+ { fullName }
228+ </ span >
229+ < span className = "text-xs text-zinc-400" > { userEmail } </ span >
230+ </ div >
217231 </ div >
218232 </ div >
219- </ div >
220233
221- { /* Menu Items */ }
222- < div className = "py-1" >
223- < button
224- onClick = { ( ) => {
225- router . push ( "/dashboard/account" ) ;
226- setOpen ( false ) ;
227- } }
228- className = "w-full flex items-center gap-3 px-3 py-2 text-sm text-[#eaeaea] hover:bg-ox-sidebar transition-colors"
229- >
230- < Cog6ToothIcon className = "size-4" />
231- < span > Account Settings</ span >
232- </ button >
233- < button
234- onClick = { ( ) => {
235- signOut ( { callbackUrl : "/" } ) ;
236- setOpen ( false ) ;
237- } }
238- className = "w-full flex items-center gap-3 px-3 py-2 text-sm text-[#eaeaea] hover:bg-ox-sidebar transition-colors"
239- >
240- < ArrowRightOnRectangleIcon className = "size-4" />
241- < span > Logout</ span >
242- </ button >
243- </ div >
244- </ div >
245- ) }
234+ { /* Menu Items */ }
235+ < div className = "py-1" >
236+ < button
237+ onClick = { ( ) => {
238+ router . push ( "/dashboard/account" ) ;
239+ setOpen ( false ) ;
240+ } }
241+ className = "w-full flex items-center gap-3 px-3 py-2 text-sm text-[#eaeaea] hover:bg-ox-sidebar transition-colors"
242+ >
243+ < Cog6ToothIcon className = "size-4" />
244+ < span > Account Settings</ span >
245+ </ button >
246+ < button
247+ onClick = { ( ) => {
248+ signOut ( { callbackUrl : "/" } ) ;
249+ setOpen ( false ) ;
250+ } }
251+ className = "w-full flex items-center gap-3 px-3 py-2 text-sm text-[#eaeaea] hover:bg-ox-sidebar transition-colors"
252+ >
253+ < ArrowRightOnRectangleIcon className = "size-4" />
254+ < span > Logout</ span >
255+ </ button >
256+ </ div >
257+ </ motion . div >
258+ ) }
259+ </ AnimatePresence >
246260 </ div >
247261 ) ;
248262}
0 commit comments