Skip to content

Commit

Permalink
Sidebar UI fixes (#2752)
Browse files Browse the repository at this point in the history
* mobile nav

* improve sidebar ui

* Remove commented code

Co-authored-by: Justin Torre <justintorre75@gmail.com>

---------

Co-authored-by: Justin Torre <justintorre75@gmail.com>
  • Loading branch information
kavinvalli and chitalian authored Oct 15, 2024
1 parent 1d3063b commit b963514
Show file tree
Hide file tree
Showing 5 changed files with 324 additions and 143 deletions.
57 changes: 53 additions & 4 deletions web/components/layout/auth/DesktopSidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
ChevronRightIcon,
Cog6ToothIcon,
QuestionMarkCircleIcon,
Bars3Icon,
} from "@heroicons/react/24/outline";
import Link from "next/link";
import { useRouter } from "next/router";
Expand Down Expand Up @@ -133,24 +134,68 @@ const DesktopSidebar = ({ NAVIGATION }: SidebarProps) => {
};
}, [isCollapsed, expandedItems, setIsCollapsed]);

const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false);

const handleCollapseToggle = () => {
if (window.innerWidth < 768) {
// Mobile breakpoint
setIsMobileMenuOpen(false);
} else {
setIsCollapsed(!isCollapsed);
}
};

return (
<>
{/* Mobile hamburger menu */}
<div className="sticky top-0 z-20 px-2 py-3 flex md:hidden flex-shrink-0 bg-white dark:bg-black border-b border-slate-300 dark:border-slate-70">
<Button
variant="ghost"
size="icon"
onClick={() => {
setIsCollapsed(false);
setIsMobileMenuOpen(true);
}}
className="text-slate-500 hover:text-slate-600"
>
<Bars3Icon className="h-6 w-6" />
</Button>
</div>

{/* Mobile drawer overlay */}
{isMobileMenuOpen && (
<div
className="fixed inset-0 bg-black bg-opacity-50 z-40 md:hidden"
onClick={() => {
setIsCollapsed(false);
setIsMobileMenuOpen(false);
}}
/>
)}

{/* Sidebar container */}
<div
className={cn(
"hidden md:block",
largeWith,
"transition-all duration-300"
)}
/>

{/* Sidebar content */}
<div
ref={sidebarRef}
className={cn(
"hidden md:flex md:flex-col z-30 bg-background dark:bg-neutral-950 transition-all duration-300 h-screen bg-white ",
"flex flex-col z-50 bg-background dark:bg-slate-900 transition-all duration-300 h-screen bg-white",
largeWith,
"fixed top-0 left-0"
"fixed top-0 left-0",
"md:translate-x-0", // Always visible on desktop
isMobileMenuOpen
? "translate-x-0"
: "-translate-x-full md:translate-x-0"
)}
>
<div className="w-full flex flex-grow flex-col overflow-y-auto border-r dark:border-slate-800 justify-between pb-4">
<div className="w-full flex flex-grow flex-col overflow-y-auto border-r dark:border-slate-800 justify-between pb-4">
<div className="flex items-center gap-2 h-14 border-b dark:border-slate-800">
<div className="flex items-center gap-2 w-full">
{!isCollapsed && <OrgDropdown />}
Expand All @@ -161,7 +206,7 @@ const DesktopSidebar = ({ NAVIGATION }: SidebarProps) => {
<Button
variant="ghost"
size="icon"
onClick={() => setIsCollapsed(!isCollapsed)}
onClick={handleCollapseToggle}
className="w-full flex justify-center dark:hover:bg-slate-800 px-2"
>
{isCollapsed ? (
Expand Down Expand Up @@ -210,6 +255,10 @@ const DesktopSidebar = ({ NAVIGATION }: SidebarProps) => {
isCollapsed={isCollapsed}
expandedItems={expandedItems}
toggleExpand={toggleExpand}
onClick={() => {
setIsCollapsed(false);
setIsMobileMenuOpen(false);
}}
deep={0}
/>
))}
Expand Down
5 changes: 4 additions & 1 deletion web/components/layout/auth/NavItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ interface NavItemProps {
expandedItems: string[];
toggleExpand: (name: string) => void;
deep?: number;
onClick: () => void;
}

const NavItem: React.FC<NavItemProps> = ({
Expand All @@ -34,6 +35,7 @@ const NavItem: React.FC<NavItemProps> = ({
expandedItems,
toggleExpand,
deep,
onClick,
}) => {
const router = useRouter();
const hasSubItems = link.subItems && link.subItems.length > 0;
Expand Down Expand Up @@ -87,7 +89,7 @@ const NavItem: React.FC<NavItemProps> = ({
<div className={cn(isSubItem)}>
<Link
href={hasSubItems ? "#" : link.href}
onClick={hasSubItems ? () => toggleExpand(link.name) : undefined}
onClick={hasSubItems ? () => toggleExpand(link.name) : onClick}
className={cn(
hasSubItems
? "flex items-center gap-1 font-medium text-slate-400 text-xs mt-[10px] text-[11px]"
Expand Down Expand Up @@ -134,6 +136,7 @@ const NavItem: React.FC<NavItemProps> = ({
expandedItems={expandedItems}
toggleExpand={toggleExpand}
deep={deep ? deep + 1 : 1}
onClick={onClick}
/>
))}
</div>
Expand Down
4 changes: 2 additions & 2 deletions web/components/layout/auth/Sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import { useMemo } from "react";
import DesktopSidebar, { NavigationItem } from "./DesktopSidebar";

import { PiGraphLight } from "react-icons/pi";
import MobileNavigation from "./MobileNavigation";
import { useOrg } from "../organizationContext";
import { NotepadText, TestTube2, Webhook } from "lucide-react";

Expand Down Expand Up @@ -209,7 +208,8 @@ const Sidebar = ({ setOpen }: SidebarProps) => {

return (
<>
<MobileNavigation NAVIGATION={NAVIGATION} setOpen={setOpen} />
{/* Remove this line */}
{/* <MobileNavigation NAVIGATION={NAVIGATION} setOpen={setOpen} /> */}

<DesktopSidebar NAVIGATION={NAVIGATION} setOpen={setOpen} />
</>
Expand Down
206 changes: 70 additions & 136 deletions web/components/layout/orgDropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,15 @@ import { Dialog, DialogContent } from "@/components/ui/dialog";
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuGroup,
DropdownMenuItem,
DropdownMenuLabel,
DropdownMenuSeparator,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import { ScrollArea } from "@/components/ui/scroll-area";
import { Switch } from "@/components/ui/switch";
import { cn } from "@/lib/utils";
import { Database } from "@/supabase/database.types";
import { CheckIcon } from "@heroicons/react/24/outline";
import { useSupabaseClient, useUser } from "@supabase/auth-helpers-react";
import { useRouter } from "next/router";
import { useCallback, useMemo, useState } from "react";
Expand All @@ -26,6 +25,9 @@ import {
ORGANIZATION_COLORS,
ORGANIZATION_ICONS,
} from "../templates/organization/orgConstants";
import { LogOutIcon } from "lucide-react";
import Link from "next/link";
import OrgMoreDropdown from "./orgMoreDropdown";

interface OrgDropdownProps {}

Expand Down Expand Up @@ -90,7 +92,7 @@ export default function OrgDropdown({}: OrgDropdownProps) {
<DropdownMenuTrigger asChild>
<Button
variant="ghost"
className="flex items-center justify-start w-full ml-1 p-2"
className="flex items-center justify-start w-full ml-1 p-2"
>
{currentIcon && (
<currentIcon.icon
Expand All @@ -106,143 +108,75 @@ export default function OrgDropdown({}: OrgDropdownProps) {
</p>
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent className="w-[15rem] ml-2 mt-1 max-h-[90vh] flex flex-col">
<DropdownMenuLabel>Organizations</DropdownMenuLabel>
<div className="flex-grow flex flex-col overflow-hidden">
{ownedOrgs && ownedOrgs.length > 0 && (
<div className="flex flex-col min-h-0">
<DropdownMenuLabel className="text-xs text-muted-foreground">
Your Organizations
{ownedOrgs.length > 7 && ` (${ownedOrgs.length})`}
</DropdownMenuLabel>
<ScrollArea className="flex-grow overflow-y-auto">
{ownedOrgs.map((org, idx) => {
const icon = ORGANIZATION_ICONS.find(
(icon) => icon.name === org.icon
);
return (
<DropdownMenuItem
key={idx}
onSelect={() => orgContext?.setCurrentOrg(org.id)}
>
<div className="flex items-center justify-between w-full">
<div className="flex items-center space-x-2">
{icon && (
<icon.icon className="h-4 w-4 text-muted-foreground" />
)}
<span className="truncate max-w-[7.5rem]">
{org.name}
</span>
</div>
{org.id === orgContext?.currentOrg?.id && (
<CheckIcon className="h-4 w-4 text-primary" />
)}
</div>
</DropdownMenuItem>
);
})}
</ScrollArea>
<DropdownMenuContent className="w-[15rem] ml-2 mt-2 max-h-[90vh] flex flex-col border-slate-200">
<DropdownMenuLabel className="flex justify-between items-center">
<div className="flex gap-2">
{currentIcon && (
<currentIcon.icon
className={clsx(
`text-${currentColor?.name}-500`,
"mt-1 flex-shrink-0 h-4 w-4"
)}
aria-hidden="true"
/>
)}
<div className="flex flex-col gap-1">
<h3 className="text-sm font-semibold text-slate-900 dark:text-slate-50">
{orgContext?.currentOrg?.name}
</h3>
<p className="text-xs text-slate-500 font-medium">
{user?.email}
</p>
</div>
)}
{memberOrgs && memberOrgs.length > 0 && (
<div className="flex flex-col min-h-0">
<DropdownMenuLabel className="text-xs text-muted-foreground">
Member Organizations
{memberOrgs.length > 7 && ` (${memberOrgs.length})`}
</DropdownMenuLabel>
<ScrollArea className="flex-grow overflow-y-auto">
{memberOrgs.map((org, idx) => {
const icon = ORGANIZATION_ICONS.find(
(icon) => icon.name === org.icon
);
return (
<DropdownMenuItem
key={idx}
onSelect={() => orgContext?.setCurrentOrg(org.id)}
>
<div className="flex items-center justify-between w-full">
<div className="flex items-center space-x-2">
{icon && (
<icon.icon className="h-4 w-4 text-muted-foreground" />
)}
<span className="truncate max-w-[7.5rem]">
{org.name}
</span>
</div>
{org.id === orgContext?.currentOrg?.id && (
<CheckIcon className="h-4 w-4 text-primary" />
)}
</div>
</DropdownMenuItem>
);
})}
</ScrollArea>
</div>
)}
{customerOrgs && customerOrgs.length > 0 && (
<div className="flex flex-col min-h-0">
<DropdownMenuLabel className="text-xs text-muted-foreground">
Customers
{customerOrgs.length > 7 && ` (${customerOrgs.length})`}
</DropdownMenuLabel>
<ScrollArea className="flex-grow overflow-y-auto">
{customerOrgs.map((org, idx) => {
const icon = ORGANIZATION_ICONS.find(
(icon) => icon.name === org.icon
);
return (
<DropdownMenuItem
key={idx}
onSelect={() => orgContext?.setCurrentOrg(org.id)}
>
<div className="flex items-center justify-between w-full">
<div className="flex items-center space-x-2">
{icon && (
<icon.icon className="h-4 w-4 text-muted-foreground" />
)}
<span className="truncate max-w-[7.5rem]">
{org.name}
</span>
</div>
{org.id === orgContext?.currentOrg?.id && (
<CheckIcon className="h-4 w-4 text-primary" />
)}
</div>
</DropdownMenuItem>
);
})}
</ScrollArea>
</div>
)}
</div>
<DropdownMenuSeparator />
<DropdownMenuItem onSelect={() => createNewOrgHandler()}>
Create New Org
</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuLabel>User Settings</DropdownMenuLabel>
<DropdownMenuItem
className={cn("hover:bg-transparent cursor-default")}
disableHover
disableClickClose
>
<div className="flex items-center justify-between w-full">
<span>Theme</span>
<Switch
checked={theme === "dark"}
onCheckedChange={handleThemeChange}
/>
</div>
</DropdownMenuItem>
<DropdownMenuItem disableHover>
<div className="flex items-center justify-between w-full">
<span className="text-sm text-muted-foreground truncate">
{user?.email}
</span>
<div className="hidden sm:block">
<OrgMoreDropdown
ownedOrgs={ownedOrgs}
memberOrgs={memberOrgs}
customerOrgs={customerOrgs}
createNewOrgHandler={createNewOrgHandler}
currentOrgId={orgContext?.currentOrg?.id}
setCurrentOrg={orgContext?.setCurrentOrg}
/>
</div>
</DropdownMenuItem>
</DropdownMenuLabel>
<DropdownMenuSeparator />
<DropdownMenuItem onSelect={handleSignOut}>Sign out</DropdownMenuItem>
<div className="block sm:hidden">
<OrgMoreDropdown
ownedOrgs={ownedOrgs}
memberOrgs={memberOrgs}
customerOrgs={customerOrgs}
createNewOrgHandler={createNewOrgHandler}
currentOrgId={orgContext?.currentOrg?.id}
setCurrentOrg={orgContext?.setCurrentOrg}
/>
<DropdownMenuSeparator />
</div>
<DropdownMenuGroup>
<DropdownMenuItem asChild className="cursor-pointer text-xs">
<Link href="/settings/members">Invite members</Link>
</DropdownMenuItem>
<DropdownMenuItem
className={cn("hover:bg-transparent cursor-default")}
disableHover
disableClickClose
>
<div className="flex items-center justify-between w-full text-xs">
<span>Dark mode</span>
<Switch
checked={themeContext?.theme === "dark"}
onCheckedChange={handleThemeChange}
size="md"
/>
</div>
</DropdownMenuItem>
</DropdownMenuGroup>
<DropdownMenuSeparator />

<DropdownMenuItem onSelect={handleSignOut} className="text-xs">
<LogOutIcon className="h-4 w-4 mr-2" />
Sign out
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>

Expand Down
Loading

0 comments on commit b963514

Please sign in to comment.