Files
sign/apps/web/components/navigation.tsx

270 lines
9.5 KiB
TypeScript
Raw Normal View History

2023-01-25 11:03:22 +01:00
import { Fragment, useEffect, useState } from "react";
2023-01-11 18:31:30 +01:00
import Link from "next/link";
import { useRouter } from "next/router";
2023-04-04 22:02:32 +00:00
import { getUser } from "@documenso/lib/api";
import Logo from "./logo";
import { Disclosure, Menu, Transition } from "@headlessui/react";
2023-01-11 18:31:30 +01:00
import {
2023-04-04 22:02:32 +00:00
ArrowRightOnRectangleIcon,
2023-01-11 18:31:30 +01:00
Bars3Icon,
BellIcon,
2023-01-11 19:51:22 +01:00
ChartBarIcon,
2023-04-04 22:02:32 +00:00
DocumentTextIcon,
UserCircleIcon,
2023-01-11 19:51:22 +01:00
WrenchIcon,
2023-04-04 22:02:32 +00:00
XMarkIcon,
2023-01-11 18:31:30 +01:00
} from "@heroicons/react/24/outline";
2023-04-04 22:02:32 +00:00
import avatarFromInitials from "avatar-from-initials";
import { signOut, useSession } from "next-auth/react";
import { toast } from "react-hot-toast";
2023-01-11 18:31:30 +01:00
const navigation = [
2023-01-11 19:51:22 +01:00
{
name: "Dashboard",
href: "/dashboard",
current: false,
icon: ChartBarIcon,
},
{
name: "Documents",
href: "/documents",
current: false,
icon: DocumentTextIcon,
},
{
name: "Settings",
href: "/settings/profile",
2023-01-11 19:51:22 +01:00
current: true,
icon: WrenchIcon,
},
2023-01-11 18:31:30 +01:00
];
2023-03-22 09:45:15 +00:00
2023-01-11 18:31:30 +01:00
const userNavigation = [
2023-03-22 09:45:15 +00:00
{
name: "Your Profile",
href: "/settings/profile",
icon: UserCircleIcon,
},
2023-01-11 18:31:30 +01:00
{
name: "Sign out",
href: "",
2023-01-12 15:59:21 +01:00
click: async (e: any) => {
2023-01-11 18:31:30 +01:00
e.preventDefault();
2023-01-13 19:01:58 +01:00
const res: any = await toast.promise(
signOut({ callbackUrl: "/login" }),
{
2023-01-16 16:33:15 +01:00
loading: "Logging out...",
2023-01-13 19:01:58 +01:00
success: "Your are logged out.",
error: "Could not log out :/",
},
{
style: {
minWidth: "200px",
},
success: {
duration: 10000,
},
}
);
2023-01-11 18:31:30 +01:00
},
2023-01-11 19:51:22 +01:00
icon: ArrowRightOnRectangleIcon,
2023-01-11 18:31:30 +01:00
},
];
function classNames(...classes: any) {
return classes.filter(Boolean).join(" ");
}
2023-01-25 11:03:22 +01:00
type UserType = {
id?: number | undefined;
name?: string | null;
email?: string | null;
image?: string | null;
};
2023-01-11 18:31:30 +01:00
export default function TopNavigation() {
2023-01-25 13:22:47 +01:00
const router = useRouter();
2023-01-19 14:13:21 +01:00
const session = useSession();
2023-01-25 13:22:47 +01:00
const [user, setUser] = useState({
email: "",
name: "",
});
2023-01-19 14:13:21 +01:00
useEffect(() => {
2023-03-01 15:11:08 +01:00
getUser().then((res) => {
res.json().then((j: any) => {
2023-01-25 13:22:47 +01:00
setUser(j);
});
});
2023-01-26 14:32:38 +01:00
}, [session]);
2023-01-11 18:31:30 +01:00
navigation.forEach((element) => {
2023-03-22 18:44:03 +00:00
element.current =
router.route.endsWith("/" + element.href.split("/")[1]) ||
router.route.includes(element.href.split("/")[1]);
2023-01-11 18:31:30 +01:00
});
return (
<>
<Disclosure as="nav" className="border-b border-gray-200 bg-white">
{({ open, close }) => (
2023-01-11 18:31:30 +01:00
<>
<div className="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
<div className="flex h-16 justify-between">
<div className="flex">
2023-05-28 13:10:09 +10:00
<Link
href="/dashboard"
className="flex flex-shrink-0 items-center gap-x-2 self-center overflow-hidden">
<Logo className="h-8 w-8" />
</Link>
2023-01-11 18:31:30 +01:00
<div className="hidden sm:-my-px sm:ml-6 sm:flex sm:space-x-8">
{navigation.map((item) => (
<Link
key={item.name}
href={item.href}
className={classNames(
item.current
? "border-neon text-brown"
: "border-transparent text-gray-500 hover:border-gray-300 hover:text-gray-700",
2023-04-04 22:02:32 +00:00
"inline-flex items-center border-b-2 px-1 pt-1 text-sm font-medium"
2023-01-11 18:31:30 +01:00
)}
2023-04-04 22:02:32 +00:00
aria-current={item.current ? "page" : undefined}>
2023-01-11 19:51:22 +01:00
<item.icon
2023-04-04 22:02:32 +00:00
className="-ml-1 mr-3 inline h-6 w-6 flex-shrink-0"
aria-hidden="true"></item.icon>
2023-01-11 18:31:30 +01:00
{item.name}
</Link>
))}
</div>
</div>
2023-02-03 12:34:32 +01:00
<div
onClick={() => {
document?.getElementById("mb")?.click();
}}
2023-04-04 22:02:32 +00:00
className="hidden cursor-pointer px-3 hover:bg-gray-200 sm:ml-6 sm:flex sm:items-center">
2023-01-11 19:51:22 +01:00
<span className="text-sm">
2023-01-19 14:13:21 +01:00
<p className="font-bold">{user?.name || ""}</p>
<p>{user?.email}</p>
2023-01-11 19:51:22 +01:00
</span>
2023-01-11 18:31:30 +01:00
<Menu as="div" className="relative ml-3">
<div>
2023-02-03 12:34:32 +01:00
<Menu.Button
id="mb"
2023-04-04 22:02:32 +00:00
className="flex max-w-xs items-center rounded-full bg-white text-sm">
2023-01-11 18:31:30 +01:00
<span className="sr-only">Open user menu</span>
2023-01-12 13:57:26 +01:00
<div
2023-01-19 14:13:21 +01:00
key={user?.email}
2023-01-12 13:57:26 +01:00
dangerouslySetInnerHTML={{
__html: avatarFromInitials(user?.name || "" || "", 40),
2023-01-12 13:57:26 +01:00
}}
2023-01-11 18:31:30 +01:00
/>
</Menu.Button>
</div>
<Transition
as={Fragment}
enter="transition ease-out duration-200"
enterFrom="transform opacity-0 scale-95"
enterTo="transform opacity-100 scale-100"
leave="transition ease-in duration-75"
leaveFrom="transform opacity-100 scale-100"
2023-04-04 22:02:32 +00:00
leaveTo="transform opacity-0 scale-95">
2023-01-11 18:31:30 +01:00
<Menu.Items className="absolute right-0 z-10 mt-2 w-48 origin-top-right rounded-md bg-white py-1 shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none">
{userNavigation.map((item) => (
<Menu.Item key={item.name}>
{({ active }) => (
<Link
href={item.href}
onClick={item.click}
className={classNames(
active ? "bg-gray-100" : "",
"block px-4 py-2 text-sm text-gray-700"
2023-04-04 22:02:32 +00:00
)}>
2023-01-11 18:31:30 +01:00
<item.icon
2023-04-04 22:02:32 +00:00
className="-ml-1 mr-3 inline h-6 w-6 flex-shrink-0"
aria-hidden="true"></item.icon>
2023-01-11 18:31:30 +01:00
{item.name}
</Link>
)}
</Menu.Item>
))}
</Menu.Items>
</Transition>
</Menu>
</div>
<div className="-mr-2 flex items-center sm:hidden">
{/* Mobile menu button */}
2023-02-03 12:21:00 +01:00
<Disclosure.Button className="inline-flex items-center justify-center rounded-md bg-white p-2 text-gray-400 hover:bg-gray-100 hover:text-gray-500">
2023-01-11 18:31:30 +01:00
<span className="sr-only">Open main menu</span>
{open ? (
<XMarkIcon className="block h-6 w-6" aria-hidden="true" />
) : (
<Bars3Icon className="block h-6 w-6" aria-hidden="true" />
)}
</Disclosure.Button>
</div>
</div>
</div>
<Disclosure.Panel className="sm:hidden">
<div className="space-y-1 pt-2 pb-3">
{navigation.map((item) => (
2023-01-19 14:13:21 +01:00
<Link
2023-01-11 18:31:30 +01:00
key={item.name}
href={item.href}
className={classNames(
item.current
2023-04-04 22:02:32 +00:00
? "border-teal-500 bg-teal-50 text-teal-700"
: "border-transparent text-gray-600 hover:border-gray-300 hover:bg-gray-50 hover:text-gray-800",
"block border-l-4 py-2 pl-3 pr-4 text-base font-medium"
2023-01-11 18:31:30 +01:00
)}
aria-current={item.current ? "page" : undefined}
onClick={() => {
close();
2023-04-04 22:02:32 +00:00
}}>
2023-01-11 18:31:30 +01:00
{item.name}
2023-01-19 14:13:21 +01:00
</Link>
2023-01-11 18:31:30 +01:00
))}
</div>
<div className="border-t border-gray-200 pt-4 pb-3">
<div className="flex items-center px-4">
<div className="flex-shrink-0">
2023-01-19 14:13:21 +01:00
<div
key={user?.email}
dangerouslySetInnerHTML={{
__html: avatarFromInitials(user?.name || "" || "", 40),
}}
2023-01-11 18:31:30 +01:00
/>
</div>
<div className="ml-3">
<div className="text-base font-medium text-gray-800">{user?.name || ""}</div>
<div className="text-sm font-medium text-gray-500">{user?.email}</div>
2023-01-11 18:31:30 +01:00
</div>
</div>
<div className="mt-3 space-y-1">
{userNavigation.map((item) => (
2023-01-12 12:16:14 +01:00
<Link
2023-01-11 18:31:30 +01:00
key={item.name}
2023-03-22 09:45:15 +00:00
onClick={
item.href.includes("/settings/profile")
? () => {
close();
}
: item.click
}
2023-01-11 18:31:30 +01:00
href={item.href}
2023-04-04 22:02:32 +00:00
className="block px-4 py-2 text-base font-medium text-gray-500 hover:bg-gray-100 hover:text-gray-800">
2023-01-11 18:31:30 +01:00
{item.name}
2023-01-12 12:16:14 +01:00
</Link>
2023-01-11 18:31:30 +01:00
))}
</div>
</div>
</Disclosure.Panel>
</>
)}
</Disclosure>
2023-01-13 19:01:58 +01:00
{/* <Toaster position="top-center"></Toaster> */}
2023-01-11 18:31:30 +01:00
</>
);
}