Added navbar

This commit is contained in:
SwiftyOS
2024-10-17 12:31:28 +02:00
parent f96f2f101b
commit 9a742cbe93
2 changed files with 129 additions and 54 deletions

View File

@@ -1,64 +1,99 @@
import type { Meta, StoryObj } from "@storybook/react";
import { Navbar } from "./Navbar";
import { userEvent, within } from "@storybook/test";
import { IconType } from "../ui/icons";
const meta = {
title: "AGPTUI/Navbar",
component: Navbar,
parameters: {
layout: "centered",
layout: "fullscreen",
},
tags: ["autodocs"],
argTypes: {
userName: { control: "text" },
links: { control: "object" },
activeLink: { control: "text" },
onProfileClick: { action: "profileClicked" },
avatarSrc: { control: "text" },
userEmail: { control: "text" },
menuItemGroups: { control: "object" },
},
} satisfies Meta<typeof Navbar>;
export default meta;
type Story = StoryObj<typeof meta>;
const defaultMenuItemGroups = [
{
items: [
{ icon: IconType.Edit, text: "Edit profile", href: "/profile/edit" },
],
},
{
items: [
{
icon: IconType.LayoutDashboard,
text: "Creator Dashboard",
href: "/dashboard",
},
{
icon: IconType.UploadCloud,
text: "Publish an agent",
href: "/publish",
},
],
},
{
items: [{ icon: IconType.Settings, text: "Settings", href: "/settings" }],
},
{
items: [
{
icon: IconType.LogOut,
text: "Log out",
onClick: () => console.log("Logged out"),
},
],
},
];
const defaultLinks = [
{ name: "Marketplace", href: "/marketplace" },
{ name: "Library", href: "/library" },
{ name: "Build", href: "/builder" },
];
export const Default: Story = {
args: {
userName: "John Doe",
links: [
{ name: "Marketplace", href: "/" },
{ name: "Library", href: "/agents" },
{ name: "Build", href: "/tasks" },
],
activeLink: "/",
onProfileClick: () => console.log("Profile clicked"),
links: defaultLinks,
activeLink: "/marketplace",
avatarSrc: "https://avatars.githubusercontent.com/u/123456789?v=4",
userEmail: "john.doe@example.com",
menuItemGroups: defaultMenuItemGroups,
},
};
export const WithActiveLink: Story = {
args: {
...Default.args,
activeLink: "/agents",
activeLink: "/library",
},
};
export const LongUserName: Story = {
args: {
...Default.args,
userName: "John Doe with a Very Long Name",
userName: "Alexander Bartholomew Christopherson III",
userEmail: "alexander@example.com",
avatarSrc: "https://avatars.githubusercontent.com/u/987654321?v=4",
},
};
export const ManyLinks: Story = {
export const NoAvatar: Story = {
args: {
userName: "Jane Smith",
links: [
{ name: "Home", href: "/" },
{ name: "Agents", href: "/agents" },
{ name: "Tasks", href: "/tasks" },
{ name: "Analytics", href: "/analytics" },
{ name: "Settings", href: "/settings" },
],
activeLink: "/analytics",
onProfileClick: () => console.log("Profile clicked"),
...Default.args,
avatarSrc: undefined,
},
};
@@ -68,8 +103,11 @@ export const WithInteraction: Story = {
},
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
const profileElement = canvas.getByText("John Doe");
const profileTrigger = canvas.getByRole("button");
await userEvent.click(profileElement);
await userEvent.click(profileTrigger);
// Wait for the popover to appear
await canvas.findByText("Edit profile");
},
};

View File

@@ -1,5 +1,8 @@
import * as React from "react";
import Link from "next/link";
import { ProfilePopoutMenu } from "./ProfilePopoutMenu";
import { IconType } from "../ui/icons";
import { MobileNavBar } from "./MobileNavBar";
interface NavLink {
name: string;
@@ -10,44 +13,78 @@ interface NavbarProps {
userName: string;
links: NavLink[];
activeLink: string;
onProfileClick: () => void;
avatarSrc?: string;
userEmail?: string;
menuItemGroups: {
groupName?: string;
items: {
icon: IconType;
text: string;
href?: string;
onClick?: () => void;
}[];
}[];
}
export const Navbar: React.FC<NavbarProps> = ({
userName,
links,
activeLink,
onProfileClick,
avatarSrc,
userEmail,
menuItemGroups,
}) => {
return (
<nav className="flex h-[5.5rem] w-screen items-center justify-between border border-black/10 bg-[#f0f0f0] px-10">
<div className="flex items-center space-x-10">
{links.map((link) => (
<div key={link.name} className="relative">
<Link href={link.href}>
<div
className={`text-[${activeLink === link.href ? "#272727" : "#474747"}] font-neue text-2xl font-medium leading-9 tracking-tight`}
>
{link.name}
</div>
</Link>
{activeLink === link.href && (
<div className="absolute bottom-[-30px] left-[-10px] h-1.5 w-full bg-[#282828]" />
)}
</div>
))}
</div>
<div className="flex items-center space-x-5">
<div
className="cursor-pointer font-neue text-2xl font-medium leading-9 tracking-tight text-[#474747]"
onClick={onProfileClick}
>
{userName}
<>
<nav className="hidden h-[5.5rem] w-full items-center justify-between border border-black/10 bg-[#f0f0f0] px-16 md:flex">
<div className="flex items-center space-x-10">
{links.map((link) => (
<div key={link.name} className="relative">
<Link href={link.href}>
<div
className={`text-[${activeLink === link.href ? "#272727" : "#474747"}] font-neue text-2xl font-medium leading-9 tracking-tight`}
>
{link.name}
</div>
</Link>
{activeLink === link.href && (
<div className="absolute bottom-[-30px] left-[-10px] h-1.5 w-full bg-[#282828]" />
)}
</div>
))}
</div>
<div className="h-10 w-10 cursor-pointer" onClick={onProfileClick}>
<div className="h-10 w-10 rounded-full border border-[#474747] bg-[#dbdbdb]" />
</div>
</div>
</nav>
{/* Profile section */}
<ProfilePopoutMenu
menuItemGroups={menuItemGroups}
userName={userName}
userEmail={userEmail}
avatarSrc={avatarSrc}
/>
</nav>
<MobileNavBar
userName={userName}
activeLink={activeLink}
menuItemGroups={[
{
groupName: "Navigation",
items: links.map((link) => ({
icon:
link.name === "Marketplace"
? IconType.Marketplace
: link.name === "Library"
? IconType.Library
: link.name === "Build"
? IconType.Builder
: IconType.LayoutDashboard,
text: link.name,
href: link.href,
})),
},
...menuItemGroups,
]}
userEmail={userEmail}
avatarSrc={avatarSrc}
/>
</>
);
};