aboutsummaryrefslogtreecommitdiffstats
path: root/apps/web/components
diff options
context:
space:
mode:
authorMd Saban <45597394+mdsaban@users.noreply.github.com>2024-10-12 18:37:20 +0530
committerGitHub <noreply@github.com>2024-10-12 14:07:20 +0100
commit1f768be0485bbfa6b542dd24183fe8389acb9355 (patch)
treeb803eefba19cddfad988b3bd1979b693fbc0f694 /apps/web/components
parente2644ebc11e9521ece054a846f8c993c322a8332 (diff)
downloadkarakeep-1f768be0485bbfa6b542dd24183fe8389acb9355.tar.zst
feature(web): Introduce a new sticky navbar. Fixes 520 (#515)
* ui: add global header * fix: design fixes * fix: tests * fix navbar background, hide y scrollbar and change sidebar footer to show version --------- Co-authored-by: MohamedBassem <me@mbassem.com>
Diffstat (limited to 'apps/web/components')
-rw-r--r--apps/web/components/dashboard/GlobalActions.tsx2
-rw-r--r--apps/web/components/dashboard/header/Header.tsx71
-rw-r--r--apps/web/components/dashboard/header/ProfileOptions.tsx (renamed from apps/web/components/dashboard/sidebar/SidebarProfileOptions.tsx)15
-rw-r--r--apps/web/components/dashboard/lists/ListHeader.tsx2
-rw-r--r--apps/web/components/dashboard/sidebar/AllLists.tsx6
-rw-r--r--apps/web/components/dashboard/sidebar/ModileSidebar.tsx4
-rw-r--r--apps/web/components/dashboard/sidebar/Sidebar.tsx34
7 files changed, 92 insertions, 42 deletions
diff --git a/apps/web/components/dashboard/GlobalActions.tsx b/apps/web/components/dashboard/GlobalActions.tsx
index e09f92a2..9c05dddf 100644
--- a/apps/web/components/dashboard/GlobalActions.tsx
+++ b/apps/web/components/dashboard/GlobalActions.tsx
@@ -5,7 +5,7 @@ import ChangeLayout from "@/components/dashboard/ChangeLayout";
export default function GlobalActions() {
return (
- <div className="flex min-w-max flex-wrap overflow-hidden rounded-md border bg-background">
+ <div className="flex min-w-max flex-wrap overflow-hidden">
<ChangeLayout />
<BulkBookmarksAction />
</div>
diff --git a/apps/web/components/dashboard/header/Header.tsx b/apps/web/components/dashboard/header/Header.tsx
new file mode 100644
index 00000000..11e3b3c3
--- /dev/null
+++ b/apps/web/components/dashboard/header/Header.tsx
@@ -0,0 +1,71 @@
+import React from "react";
+import Link from "next/link";
+import { redirect } from "next/navigation";
+import GlobalActions from "@/components/dashboard/GlobalActions";
+import ProfileOptions from "@/components/dashboard/header/ProfileOptions";
+import { SearchInput } from "@/components/dashboard/search/SearchInput";
+import HoarderLogo from "@/components/HoarderIcon";
+import { Button } from "@/components/ui/button";
+import {
+ Tooltip,
+ TooltipContent,
+ TooltipTrigger,
+} from "@/components/ui/tooltip";
+import { getServerAuthSession } from "@/server/auth";
+import { Settings, Shield } from "lucide-react";
+
+export default async function Header() {
+ const session = await getServerAuthSession();
+ if (!session) {
+ redirect("/");
+ }
+
+ const adminItem =
+ session.user.role == "admin"
+ ? [
+ {
+ name: "Admin",
+ icon: <Shield size={18} />,
+ path: "/dashboard/admin",
+ },
+ ]
+ : [];
+
+ const headerItems = [
+ ...adminItem,
+ {
+ name: "Settings",
+ icon: <Settings size={18} />,
+ path: "/dashboard/settings",
+ },
+ ];
+
+ return (
+ <header className="sticky left-0 right-0 top-0 z-50 flex h-16 items-center justify-between overflow-x-auto overflow-y-hidden bg-background p-4 shadow">
+ <div className="hidden items-center sm:flex">
+ <Link href={"/dashboard/bookmarks"} className="w-56">
+ <HoarderLogo height={20} gap="8px" />
+ </Link>
+ </div>
+ <div className="flex w-full gap-2">
+ <SearchInput className="min-w-40 bg-muted" />
+ <GlobalActions />
+ </div>
+ <div className="hidden items-center sm:flex">
+ {headerItems.map((item) => (
+ <Tooltip key={item.name} delayDuration={0}>
+ <TooltipTrigger asChild>
+ <Button variant="ghost">
+ <Link href={item.path} className="flex items-center">
+ {item.icon}
+ </Link>
+ </Button>
+ </TooltipTrigger>
+ <TooltipContent side="bottom">{item.name}</TooltipContent>
+ </Tooltip>
+ ))}
+ <ProfileOptions />
+ </div>
+ </header>
+ );
+}
diff --git a/apps/web/components/dashboard/sidebar/SidebarProfileOptions.tsx b/apps/web/components/dashboard/header/ProfileOptions.tsx
index af3f1548..df31171c 100644
--- a/apps/web/components/dashboard/sidebar/SidebarProfileOptions.tsx
+++ b/apps/web/components/dashboard/header/ProfileOptions.tsx
@@ -1,6 +1,7 @@
"use client";
import Link from "next/link";
+import { redirect } from "next/navigation";
import { useToggleTheme } from "@/components/theme-provider";
import { Button } from "@/components/ui/button";
import {
@@ -9,8 +10,8 @@ import {
DropdownMenuItem,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
-import { LogOut, Moon, MoreHorizontal, Paintbrush, Sun } from "lucide-react";
-import { signOut } from "next-auth/react";
+import { LogOut, Moon, Paintbrush, Sun } from "lucide-react";
+import { signOut, useSession } from "next-auth/react";
import { useTheme } from "next-themes";
function DarkModeToggle() {
@@ -35,11 +36,17 @@ function DarkModeToggle() {
export default function SidebarProfileOptions() {
const toggleTheme = useToggleTheme();
+ const { data: session } = useSession();
+ if (!session) return redirect("/");
+
return (
<DropdownMenu>
<DropdownMenuTrigger asChild>
- <Button variant="ghost">
- <MoreHorizontal />
+ <Button
+ className="border-new-gray-200 aspect-square rounded-full border-4 bg-black p-0 text-white"
+ variant="ghost"
+ >
+ {session.user.name?.charAt(0) ?? "U"}
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent className="w-fit">
diff --git a/apps/web/components/dashboard/lists/ListHeader.tsx b/apps/web/components/dashboard/lists/ListHeader.tsx
index 1655a80b..a6780e1e 100644
--- a/apps/web/components/dashboard/lists/ListHeader.tsx
+++ b/apps/web/components/dashboard/lists/ListHeader.tsx
@@ -1,7 +1,6 @@
"use client";
import { useRouter } from "next/navigation";
-import GlobalActions from "@/components/dashboard/GlobalActions";
import { Button } from "@/components/ui/button";
import { MoreHorizontal } from "lucide-react";
@@ -43,7 +42,6 @@ export default function ListHeader({
<MoreHorizontal />
</Button>
</ListOptions>
- <GlobalActions />
</div>
</div>
);
diff --git a/apps/web/components/dashboard/sidebar/AllLists.tsx b/apps/web/components/dashboard/sidebar/AllLists.tsx
index 15bed88a..b6cadea9 100644
--- a/apps/web/components/dashboard/sidebar/AllLists.tsx
+++ b/apps/web/components/dashboard/sidebar/AllLists.tsx
@@ -47,12 +47,6 @@ export default function AllLists({
path={`/dashboard/favourites`}
linkClassName="py-0.5"
/>
- <SidebarItem
- logo={<span className="text-lg">🗄️</span>}
- name="Archive"
- path={`/dashboard/archive`}
- linkClassName="py-0.5"
- />
{
<CollapsibleBookmarkLists
diff --git a/apps/web/components/dashboard/sidebar/ModileSidebar.tsx b/apps/web/components/dashboard/sidebar/ModileSidebar.tsx
index 635f63bd..1117dd61 100644
--- a/apps/web/components/dashboard/sidebar/ModileSidebar.tsx
+++ b/apps/web/components/dashboard/sidebar/ModileSidebar.tsx
@@ -1,8 +1,8 @@
+import ProfileOptions from "@/components/dashboard/header/ProfileOptions";
import HoarderLogoIcon from "@/public/icons/logo-icon.svg";
import { ClipboardList, Search, Settings, Tag } from "lucide-react";
import MobileSidebarItem from "./ModileSidebarItem";
-import SidebarProfileOptions from "./SidebarProfileOptions";
export default async function MobileSidebar() {
return (
@@ -16,7 +16,7 @@ export default async function MobileSidebar() {
<MobileSidebarItem logo={<ClipboardList />} path="/dashboard/lists" />
<MobileSidebarItem logo={<Tag />} path="/dashboard/tags" />
<MobileSidebarItem logo={<Settings />} path="/dashboard/settings" />
- <SidebarProfileOptions />
+ <ProfileOptions />
</ul>
</aside>
);
diff --git a/apps/web/components/dashboard/sidebar/Sidebar.tsx b/apps/web/components/dashboard/sidebar/Sidebar.tsx
index 84a10d2d..13260e07 100644
--- a/apps/web/components/dashboard/sidebar/Sidebar.tsx
+++ b/apps/web/components/dashboard/sidebar/Sidebar.tsx
@@ -1,16 +1,13 @@
-import Link from "next/link";
import { redirect } from "next/navigation";
-import HoarderLogo from "@/components/HoarderIcon";
import { Separator } from "@/components/ui/separator";
import { api } from "@/server/api/client";
import { getServerAuthSession } from "@/server/auth";
-import { Home, Search, Settings, Shield, Tag } from "lucide-react";
+import { Archive, Home, Search, Tag } from "lucide-react";
import serverConfig from "@hoarder/shared/config";
import AllLists from "./AllLists";
import SidebarItem from "./SidebarItem";
-import SidebarProfileOptions from "./SidebarProfileOptions";
export default async function Sidebar() {
const session = await getServerAuthSession();
@@ -30,17 +27,6 @@ export default async function Sidebar() {
]
: [];
- const adminItem =
- session.user.role == "admin"
- ? [
- {
- name: "Admin",
- icon: <Shield size={18} />,
- path: "/dashboard/admin",
- },
- ]
- : [];
-
const menu: {
name: string;
icon: JSX.Element;
@@ -58,19 +44,14 @@ export default async function Sidebar() {
path: "/dashboard/tags",
},
{
- name: "Settings",
- icon: <Settings size={18} />,
- path: "/dashboard/settings",
+ name: "Archive",
+ icon: <Archive size={18} />,
+ path: "/dashboard/archive",
},
- ...adminItem,
];
return (
- <aside className="flex h-screen w-60 flex-col gap-5 border-r p-4">
- <Link href={"/dashboard/bookmarks"}>
- <HoarderLogo height={20} gap="8px" />
- </Link>
- <Separator />
+ <aside className="flex h-[calc(100vh-64px)] w-60 flex-col gap-5 border-r p-4 ">
<div>
<ul className="space-y-2 text-sm font-medium">
{menu.map((item) => (
@@ -85,9 +66,8 @@ export default async function Sidebar() {
</div>
<Separator />
<AllLists initialData={lists} />
- <div className="mt-auto flex justify-between justify-self-end">
- <div className="my-auto"> {session.user.name} </div>
- <SidebarProfileOptions />
+ <div className="mt-auto flex items-center border-t pt-2">
+ Hoarder v{serverConfig.serverVersion}
</div>
</aside>
);