diff --git a/apps/web/src/components/Dashboard.tsx b/apps/web/src/components/Dashboard.tsx index 4df94997..7d94eca8 100644 --- a/apps/web/src/components/Dashboard.tsx +++ b/apps/web/src/components/Dashboard.tsx @@ -61,6 +61,10 @@ export default function Dashboard({ } }; + const closeSideNav = () => { + setIsSideNavOpen(false); + }; + const toggleRightPanel = () => { setIsRightPanelOpen(!isRightPanelOpen); if (!isRightPanelOpen) { @@ -98,9 +102,9 @@ export default function Dashboard({ background-color: ${!isDarkMode ? "hsl(0deg 0% 97.3%)" : "#1c1c1c"}; } `} -
- {/* Mobile Navigation Controls - positioned absolutely over content */} -
+
+ {/* Mobile Header */} +
-
- {/* {hasRightPanel && ( -
+ {hasRightPanel && ( -
- )} */} + )} +
-
+
-
+
{children}
@@ -161,13 +164,11 @@ export default function Dashboard({ {hasRightPanel && rightPanel && (
-
- {rightPanel} -
+
{rightPanel}
)} diff --git a/apps/web/src/components/ReactiveButton.tsx b/apps/web/src/components/ReactiveButton.tsx index b8752704..f409d352 100644 --- a/apps/web/src/components/ReactiveButton.tsx +++ b/apps/web/src/components/ReactiveButton.tsx @@ -1,7 +1,9 @@ import Link from "next/link"; import { useState } from "react"; +import { twMerge } from "tailwind-merge"; import LottieIcon from "~/components/LottieIcon"; +import { useIsMobile } from "~/hooks/useMediaQuery"; function classNames(...classes: string[]): string { return classes.filter(Boolean).join(" "); @@ -13,30 +15,41 @@ const Button: React.FC<{ name: string; json: object; isCollapsed?: boolean; -}> = ({ href, current, name, json, isCollapsed = false }) => { + onCloseSideNav?: () => void; +}> = ({ href, current, name, json, isCollapsed = false, onCloseSideNav }) => { const [isHovered, setIsHovered] = useState(false); const [index, setIndex] = useState(0); + const isMobile = useIsMobile(); const handleMouseEnter = () => { setIsHovered(true); setIndex((index) => index + 1); }; + const handleClick = () => { + if (onCloseSideNav && isMobile) { + onCloseSideNav(); + } + }; + return ( - {!isCollapsed && name} + {name} ); }; diff --git a/apps/web/src/components/SideNavigation.tsx b/apps/web/src/components/SideNavigation.tsx index 5c3d9094..74489949 100644 --- a/apps/web/src/components/SideNavigation.tsx +++ b/apps/web/src/components/SideNavigation.tsx @@ -23,6 +23,7 @@ import { useTheme } from "~/providers/theme"; interface SideNavigationProps { user: UserType; isLoading: boolean; + onCloseSideNav?: () => void; } interface UserType { @@ -33,6 +34,7 @@ interface UserType { export default function SideNavigation({ user, isLoading, + onCloseSideNav, }: SideNavigationProps) { const router = useRouter(); const [isCollapsed, setIsCollapsed] = useState(false); @@ -87,12 +89,12 @@ export default function SideNavigation({ <> diff --git a/apps/web/src/components/UserMenu.tsx b/apps/web/src/components/UserMenu.tsx index d5d8a114..c79127f4 100644 --- a/apps/web/src/components/UserMenu.tsx +++ b/apps/web/src/components/UserMenu.tsx @@ -4,9 +4,11 @@ import { useRouter } from "next/navigation"; import { Menu, Transition } from "@headlessui/react"; import { t } from "@lingui/core/macro"; import { Fragment } from "react"; +import { twMerge } from "tailwind-merge"; import { authClient } from "@kan/auth/client"; +import { useIsMobile } from "~/hooks/useMediaQuery"; import { useModal } from "~/providers/modal"; import { useTheme } from "~/providers/theme"; import { getAvatarUrl } from "~/utils/helpers"; @@ -16,10 +18,7 @@ interface UserMenuProps { email: string; isLoading: boolean; isCollapsed?: boolean; -} - -function classNames(...classes: string[]): string { - return classes.filter(Boolean).join(" "); + onCloseSideNav?: () => void; } export default function UserMenu({ @@ -27,27 +26,48 @@ export default function UserMenu({ email, isLoading, isCollapsed = false, + onCloseSideNav, }: UserMenuProps) { const router = useRouter(); const { themePreference, switchTheme } = useTheme(); const { openModal } = useModal(); + const isMobile = useIsMobile(); const handleLogout = async () => { + if (onCloseSideNav && isMobile) { + onCloseSideNav(); + } await authClient.signOut(); router.push("/login"); }; + const handleLinkClick = () => { + if (onCloseSideNav && isMobile) { + onCloseSideNav(); + } + }; + + const handleModalOpen = (modalType: string) => { + if (onCloseSideNav && isMobile) { + onCloseSideNav(); + } + openModal(modalType); + }; + const avatarUrl = imageUrl ? getAvatarUrl(imageUrl) : null; return (
{isLoading ? ( -
+
- {!isCollapsed && ( -
- )} +
) : ( )} - {!isCollapsed && ( - {email} - )} + + {email} + )}
@@ -90,7 +115,7 @@ export default function UserMenu({ leaveTo="transform opacity-0 scale-95" > {t`Support`} @@ -159,6 +185,7 @@ export default function UserMenu({ href="https://docs.kan.bn" target="_blank" rel="noreferrer" + onClick={handleLinkClick} className="flex w-full items-center rounded-[5px] px-3 py-2 text-left text-xs hover:bg-light-200 dark:hover:bg-dark-400" > {t`Documentation`} @@ -166,7 +193,7 @@ export default function UserMenu({