Mobile support to come.
"use client";
import { Bell, Circle, MoreHorizontal, Plus, Search } from "lucide-react";
import { usePathname, useRouter } from "next/navigation";
import { useState } from "react";
import CreateRepoDialog from "@/(main)/[owner]/ui/create-repo-dialog";
import { useAuthBlocker } from "@/(main)/providers/auth-blocker-provider";
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from "@/ui/dropdown-menu";
import Link from "@/ui/link";
import {
Sidebar,
SidebarContent,
SidebarGroup,
SidebarGroupContent,
SidebarMenu,
SidebarMenuButton,
SidebarMenuItem,
} from "@/ui/sidebar";
import { cn } from "@/util";
const SIDEBAR_ICON_WIDTH = "2.5rem";
export function MainSidebar() {
const pathname = usePathname();
const router = useRouter();
const isDefault = !["/search", "/notifications", "/settings"].includes(
pathname,
);
const [createRepoOpen, setCreateRepoOpen] = useState(false);
const { requireAuth } = useAuthBlocker();
return (
<>
<Sidebar
className="bg-sidebar h-full! border-r"
style={{ width: SIDEBAR_ICON_WIDTH }}
>
<SidebarContent>
<SidebarGroup className="p-0!">
<SidebarGroupContent>
<SidebarMenu className="gap-0">
<NavItem
icon={Circle}
label="Home"
href="/home"
isActive={isDefault}
iconClassName="!size-2 fill-current"
requiresAuth={false}
/>
<SearchNavItem isActive={pathname === "/search"} />
<NavItem
icon={Bell}
label="Notifications"
href="/notifications"
isActive={pathname === "/notifications"}
requiresAuth={true}
/>
<DropdownNavItem icon={Plus} label="Create">
<DropdownMenuItem
onClick={() => {
if (requireAuth()) return null;
setCreateRepoOpen(true);
}}
className="rounded-none px-2 py-1.5 text-sm cursor-pointer"
>
New repo
</DropdownMenuItem>
</DropdownNavItem>
<DropdownNavItem icon={MoreHorizontal} label="More">
<DropdownMenuItem
onClick={() => {
if (requireAuth()) return null;
router.push("/settings");
}}
className="rounded-none px-2 py-1.5 text-sm cursor-pointer"
>
Settings
</DropdownMenuItem>
</DropdownNavItem>
</SidebarMenu>
</SidebarGroupContent>
</SidebarGroup>
</SidebarContent>
</Sidebar>
<CreateRepoDialog open={createRepoOpen} setOpen={setCreateRepoOpen} />
</>
);
}
function NavItem({
icon: Icon,
label,
href,
isActive,
iconClassName,
requiresAuth,
}: {
icon: React.ComponentType<{ className?: string }>;
label: string;
href: string;
isActive: boolean;
iconClassName?: string;
requiresAuth: boolean;
}) {
const { requireAuth } = useAuthBlocker();
return (
<SidebarMenuItem
className={`w-10 h-9 border-b p-0! border-l-4 bg-sidebar ${isActive ? "border-l-primary" : "border-l-transparent"}`}
>
<Link
prefetch={true}
href={href}
onClick={(e) => {
if (requiresAuth && requireAuth()) {
e.preventDefault();
}
}}
>
<SidebarMenuButton className="group w-full h-full flex items-center justify-center p-0! rounded-none hover:bg-sidebar-accent! hover:text-current!">
<Icon
className={cn(
iconClassName ?? "size-4",
"mr-1 group-hover:stroke-[2.5]",
)}
/>
<span className="sr-only">{label}</span>
</SidebarMenuButton>
</Link>
</SidebarMenuItem>
);
}
function SearchNavItem({ isActive }: { isActive: boolean }) {
const handleClick = () => {
window.dispatchEvent(new CustomEvent("openFileSearch"));
};
return (
<SidebarMenuItem
className={`w-10 h-9 border-b p-0! border-l-4 bg-sidebar ${isActive ? "border-l-primary" : "border-l-transparent"}`}
>
<SidebarMenuButton
onClick={handleClick}
className="group w-full h-full flex items-center justify-center p-0! rounded-none hover:bg-sidebar-accent! hover:text-current!"
>
<Search className="size-4 mr-1 group-hover:stroke-[2.5]" />
<span className="sr-only">Search</span>
</SidebarMenuButton>
</SidebarMenuItem>
);
}
function DropdownNavItem({
icon: Icon,
label,
children,
}: {
icon: React.ComponentType<{ className?: string }>;
label: string;
children: React.ReactNode;
}) {
return (
<SidebarMenuItem
className={`w-10 h-9 border-b p-0! border-l-4 bg-sidebar border-l-transparent`}
>
<DropdownMenu>
<DropdownMenuTrigger asChild>
<SidebarMenuButton className="group w-full h-full flex items-center justify-center p-0! rounded-none hover:bg-sidebar-accent! data-[state=open]:bg-sidebar-accent! hover:text-current! ring-0! outline-0!">
<Icon className={"h-4 w-4 mr-1 group-hover:stroke-[2.5]"} />
<span className="sr-only">{label}</span>
</SidebarMenuButton>
</DropdownMenuTrigger>
<DropdownMenuContent side="right" className="rounded-none min-w-32 p-0">
{children}
</DropdownMenuContent>
</DropdownMenu>
</SidebarMenuItem>
);
}
temporary - make search just be file search
baepaul•e975c8a7d ago
using stroke 2.5
baepaul•af2f13a9d ago
not much code for much staring but worth it i promise
baepaul•98a840f9d ago
bug fix
baepaul•f44852a9d ago
making auth working with new navbar
baepaul•0f0eaf710d ago
refactoring main sidebar
baepaul•5f2b7a010d ago
re-designing sidebar
baepaul•7e8536e10d ago
auth blocker dialog + provider
baepaul•c0126a410d ago
minimalism
baepaul•f1ebae010d ago
create repo button / dialog done
baepaul•6427df011d ago
reorganizign repo under (main)
baepaul•63f342411d ago