mirror of
https://github.com/Significant-Gravitas/AutoGPT.git
synced 2026-04-08 03:00:28 -04:00
Added navbar
This commit is contained in:
@@ -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");
|
||||
},
|
||||
};
|
||||
|
||||
@@ -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}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user