Skip to content

Commit

Permalink
feat(ui): navigation refactor: typography, icons, hover states
Browse files Browse the repository at this point in the history
  • Loading branch information
yg-lim committed Aug 9, 2024
1 parent 8b4883a commit a0951d2
Show file tree
Hide file tree
Showing 7 changed files with 213 additions and 48 deletions.
75 changes: 48 additions & 27 deletions ui/src/components/Navigation.tsx
Original file line number Diff line number Diff line change
@@ -1,36 +1,57 @@
import Logo from "../assets/paisley-logo-icon.svg";
import { Link } from "wouter";
import { NavigationLink } from "./NavigationLink";

const PRIMARY_NAV_LINKS = [
{ href: "/dashboard", text: "Dashboard" },
{ href: "/knowledge-bases", text: "Knowledge Bases" },
{ href: "/chatbots", text: "Chatbots" },
{ href: "/evaluations", text: "Evaluations" },
];

const SECONDARY_NAV_LINKS = [
{ href: "/api-keys", text: "API Keys" },
{ href: "/settings", text: "Settings" },
];
import { Typography } from "./Typography";
import {
LayoutDashboard,
BookOpenText,
BotMessageSquare,
ChartCandlestick,
KeyRound,
Settings,
} from "lucide-react";

export function Navigation() {
return (
<div className="flex flex-col justify-between fixed h-full w-72 bg-white z-10 px-12 py-8 border-r-2">
<nav>
<img src={Logo} alt="Paisley Logo" className="size-12" />
{PRIMARY_NAV_LINKS.map((link) => (
<Link key={link.href} href={link.href}>
<NavigationLink>{link.text}</NavigationLink>
</Link>
))}
<div className="flex flex-col justify-start gap-8 fixed h-full w-60 bg-white z-10 p-6 border-r">
<div className="flex items-center gap-3 pb-4 border-b">
<img src={Logo} alt="Paisley Logo" className="size-8" />
<Typography className="text-xl font-semibold font-inter">
Paisley
</Typography>
</div>
<nav className="flex flex-col gap-2">
<Typography variant="muted" className="px-2">
Main Menu
</Typography>
<NavigationLink href="/dashboard">
<LayoutDashboard />
<Typography className="text-base">Dashboard</Typography>
</NavigationLink>
<NavigationLink href="/knowledge-bases">
<BookOpenText />
<Typography className="text-base">Knowledge Bases</Typography>
</NavigationLink>
<NavigationLink href="/chatbots">
<BotMessageSquare />
<Typography className="text-base">Chatbots</Typography>
</NavigationLink>
<NavigationLink href="/evaluations">
<ChartCandlestick />
<Typography className="text-base">Evaluations</Typography>
</NavigationLink>
</nav>
<nav>
{SECONDARY_NAV_LINKS.map((link) => (
<Link key={link.href} href={link.href}>
<NavigationLink>{link.text}</NavigationLink>
</Link>
))}
<nav className="flex flex-col gap-2">
<Typography variant="muted" className="px-2">
Account
</Typography>
<NavigationLink href="/api-keys">
<KeyRound />
<Typography className="text-base">API Keys</Typography>
</NavigationLink>
<NavigationLink href="/settings">
<Settings />
<Typography className="text-base">Settings</Typography>
</NavigationLink>
</nav>
</div>
);
Expand Down
18 changes: 14 additions & 4 deletions ui/src/components/NavigationLink.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,17 @@
export function NavigationLink({ children }: { children: React.ReactNode }) {
import { Link } from "wouter";

interface NavigationLinkProps {
href: string;
children: React.ReactNode;
}

export function NavigationLink({ href, children }: NavigationLinkProps) {
return (
<div className="my-4">
<p className="px-4 py-2 border rounded-lg">{children}</p>
</div>
<Link
className="flex items-center gap-2 px-2 py-2 rounded-md hover:bg-gray-100"
href={href}
>
{children}
</Link>
);
}
16 changes: 11 additions & 5 deletions ui/src/components/Typography.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React from "react";
import { cn } from "@/lib/utils";

interface TypographyProps {
variant:
variant?:
| "h1"
| "h2"
| "h3"
Expand Down Expand Up @@ -37,15 +37,21 @@ export function Typography({ variant, children, className }: TypographyProps) {

if (variant === "p") {
Component = "p";
} else if (variant.startsWith("h")) {
} else if (variant?.startsWith("h")) {
Component = variant as keyof React.JSX.IntrinsicElements;
} else {
Component = "div";
}

if (variant) {
return (
<Component className={cn(baseStyles, variantStyles[variant], className)}>
{children}
</Component>
);
}

return (
<Component className={cn(baseStyles, variantStyles[variant], className)}>
{children}
</Component>
<Component className={cn(baseStyles, className)}>{children}</Component>
);
}
4 changes: 0 additions & 4 deletions ui/src/components/pages/PageCreateChatbot.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,13 +57,9 @@ export function PageCreateChatbot() {
const mutation = useMutation({
mutationFn: (data: z.infer<typeof clientPipelineConfigSchema>) =>
chatbotService.createChatbot(data),
onMutate: () => {},
onSuccess: (data) => {
navigate(`/chatbots/${data.id}`);
},
onError: (error) => {
console.error("Error creating chatbot:", error);
},
});

function handleFormSubmit(
Expand Down
128 changes: 128 additions & 0 deletions ui/src/components/ui/navigation-menu.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
import * as React from "react";
import * as NavigationMenuPrimitive from "@radix-ui/react-navigation-menu";
import { cva } from "class-variance-authority";
import { ChevronDown } from "lucide-react";

import { cn } from "@/lib/utils";

const NavigationMenu = React.forwardRef<
React.ElementRef<typeof NavigationMenuPrimitive.Root>,
React.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.Root>
>(({ className, children, ...props }, ref) => (
<NavigationMenuPrimitive.Root
ref={ref}
className={cn(
"relative z-10 flex max-w-max flex-1 items-center justify-center",
className
)}
{...props}
>
{children}
<NavigationMenuViewport />
</NavigationMenuPrimitive.Root>
));
NavigationMenu.displayName = NavigationMenuPrimitive.Root.displayName;

const NavigationMenuList = React.forwardRef<
React.ElementRef<typeof NavigationMenuPrimitive.List>,
React.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.List>
>(({ className, ...props }, ref) => (
<NavigationMenuPrimitive.List
ref={ref}
className={cn(
"group flex flex-1 list-none items-center justify-center",
className
)}
{...props}
/>
));
NavigationMenuList.displayName = NavigationMenuPrimitive.List.displayName;

const NavigationMenuItem = NavigationMenuPrimitive.Item;

const navigationMenuTriggerStyle = cva(
"group inline-flex h-10 w-max items-center justify-center rounded-md bg-background px-4 py-2 text-sm font-medium transition-colors hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground focus:outline-none disabled:pointer-events-none disabled:opacity-50 data-[active]:bg-accent/50 data-[state=open]:bg-accent/50"
);

const NavigationMenuTrigger = React.forwardRef<
React.ElementRef<typeof NavigationMenuPrimitive.Trigger>,
React.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.Trigger>
>(({ className, children, ...props }, ref) => (
<NavigationMenuPrimitive.Trigger
ref={ref}
className={cn(navigationMenuTriggerStyle(), "group", className)}
{...props}
>
{children}{" "}
<ChevronDown
className="relative top-[1px] ml-1 h-3 w-3 transition duration-200 group-data-[state=open]:rotate-180"
aria-hidden="true"
/>
</NavigationMenuPrimitive.Trigger>
));
NavigationMenuTrigger.displayName = NavigationMenuPrimitive.Trigger.displayName;

const NavigationMenuContent = React.forwardRef<
React.ElementRef<typeof NavigationMenuPrimitive.Content>,
React.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.Content>
>(({ className, ...props }, ref) => (
<NavigationMenuPrimitive.Content
ref={ref}
className={cn(
"left-0 top-0 w-full data-[motion^=from-]:animate-in data-[motion^=to-]:animate-out data-[motion^=from-]:fade-in data-[motion^=to-]:fade-out data-[motion=from-end]:slide-in-from-right-52 data-[motion=from-start]:slide-in-from-left-52 data-[motion=to-end]:slide-out-to-right-52 data-[motion=to-start]:slide-out-to-left-52 md:absolute md:w-auto ",
className
)}
{...props}
/>
));
NavigationMenuContent.displayName = NavigationMenuPrimitive.Content.displayName;

const NavigationMenuLink = NavigationMenuPrimitive.Link;

const NavigationMenuViewport = React.forwardRef<
React.ElementRef<typeof NavigationMenuPrimitive.Viewport>,
React.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.Viewport>
>(({ className, ...props }, ref) => (
<div className={cn("absolute left-0 top-full flex justify-center")}>
<NavigationMenuPrimitive.Viewport
className={cn(
"origin-top-center relative mt-1.5 h-[var(--radix-navigation-menu-viewport-height)] w-full overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-90 md:w-[var(--radix-navigation-menu-viewport-width)]",
className
)}
ref={ref}
{...props}
/>
</div>
));
NavigationMenuViewport.displayName =
NavigationMenuPrimitive.Viewport.displayName;

const NavigationMenuIndicator = React.forwardRef<
React.ElementRef<typeof NavigationMenuPrimitive.Indicator>,
React.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.Indicator>
>(({ className, ...props }, ref) => (
<NavigationMenuPrimitive.Indicator
ref={ref}
className={cn(
"top-full z-[1] flex h-1.5 items-end justify-center overflow-hidden data-[state=visible]:animate-in data-[state=hidden]:animate-out data-[state=hidden]:fade-out data-[state=visible]:fade-in",
className
)}
{...props}
>
<div className="relative top-[60%] h-2 w-2 rotate-45 rounded-tl-sm bg-border shadow-md" />
</NavigationMenuPrimitive.Indicator>
));
NavigationMenuIndicator.displayName =
NavigationMenuPrimitive.Indicator.displayName;

export {
navigationMenuTriggerStyle,
NavigationMenu,
NavigationMenuList,
NavigationMenuItem,
NavigationMenuContent,
NavigationMenuTrigger,
NavigationMenuLink,
NavigationMenuIndicator,
NavigationMenuViewport,
};
6 changes: 5 additions & 1 deletion ui/src/index.css
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
@import url("https://fonts.googleapis.com/css2?family=Rubik:ital,wght@0,300..900;1,300..900&display=swap");
@import url("https://fonts.googleapis.com/css2?family=Inter:[email protected]&display=swap");

@tailwind base;
@tailwind components;
@tailwind utilities;

@tailwind base;
@tailwind components;

@tailwind utilities;

@layer base {
Expand Down Expand Up @@ -73,4 +74,7 @@
body {
@apply bg-background text-foreground;
}
.font-inter {
font-family: "Inter", sans-serif;
}
}
14 changes: 7 additions & 7 deletions ui/src/main.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App.tsx'
import './index.css'
import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App.tsx";
import "./index.css";

ReactDOM.createRoot(document.getElementById('root')!).render(
ReactDOM.createRoot(document.getElementById("root")!).render(
<React.StrictMode>
<App />
</React.StrictMode>,
)
</React.StrictMode>
);

0 comments on commit a0951d2

Please sign in to comment.