From cae57e81e39e5aef4973335d8cf9944017372682 Mon Sep 17 00:00:00 2001 From: Arthur Belleville Date: Thu, 3 Apr 2025 08:56:41 +0200 Subject: [PATCH] Add basic navigation --- ui/src/App.tsx | 10 +- ui/src/components/Layout.tsx | 16 ++ ui/src/components/NavigationBar.tsx | 342 ++++++++++++++++++++++++++++ ui/src/pages/tablo.tsx | 2 - 4 files changed, 367 insertions(+), 3 deletions(-) create mode 100644 ui/src/components/Layout.tsx create mode 100644 ui/src/components/NavigationBar.tsx diff --git a/ui/src/App.tsx b/ui/src/App.tsx index 1236ac7..37485d4 100644 --- a/ui/src/App.tsx +++ b/ui/src/App.tsx @@ -11,6 +11,7 @@ import { TabloPage } from "./pages/tablo"; import { SessionProvider } from "./contexts/SessionContext"; import { OAuthSigninPage } from "./pages/oauth-signin"; import { NotFoundPage } from "./pages/NotFoundPage"; +import { Layout } from "./components/Layout"; export const App = () => { return ( @@ -24,7 +25,14 @@ export const App = () => { )} > - }> + + + + } + > } /> } /> diff --git a/ui/src/components/Layout.tsx b/ui/src/components/Layout.tsx new file mode 100644 index 0000000..c14f7e9 --- /dev/null +++ b/ui/src/components/Layout.tsx @@ -0,0 +1,16 @@ +import { ReactNode } from "react"; +import { SideNavigation, HamburgerMenu } from "./NavigationBar"; + +interface LayoutProps { + children: ReactNode; +} + +export function Layout({ children }: LayoutProps) { + return ( +
+ + +
{children}
+
+ ); +} diff --git a/ui/src/components/NavigationBar.tsx b/ui/src/components/NavigationBar.tsx new file mode 100644 index 0000000..1cb1f7b --- /dev/null +++ b/ui/src/components/NavigationBar.tsx @@ -0,0 +1,342 @@ +import { twMerge } from "tailwind-merge"; +// import { useSession } from "../contexts/SessionContext"; +import { + HomeIcon, + TableIcon, + SettingsIcon, + UserIcon, + HelpCircleIcon, + SendIcon, + Menu, + Settings2Icon, + LogOutIcon, + SearchIcon, + MenuIcon, + ChevronRightIcon, +} from "lucide-react"; +import { + MenuButton, + MenuItem, + MenuItemLabel, + MenuSeparator, + MenuTrigger, +} from "../ui-library/menu"; +import { MenuPopover } from "../ui-library/menu"; +import { Link } from "../ui-library/link"; +import { Icon } from "../ui-library/icon"; +import { Avatar } from "../ui-library/avatar"; +import { DialogHeader } from "../ui-library/dialog"; +import { Dialog } from "../ui-library/dialog"; +import { Button } from "../ui-library/button"; +import { Modal } from "../ui-library/modal"; +import { DialogTrigger } from "../ui-library/dialog"; +import { DialogCloseButton } from "../ui-library/dialog"; +import { DialogBody } from "../ui-library/dialog"; +import { + DisclosurePanel, + DisclosureControl, + Disclosure, +} from "../ui-library/disclosure"; +import { LinkProps } from "react-aria-components"; + +type NavLinkItem = { + isActive?: boolean; +} & LinkProps; + +type NavLinkProps = NavLinkItem | { title: string; items: NavLinkItem[] }; + +function NavLink(props: NavLinkProps) { + if ("items" in props) { + return ( + + + {props.title}{" "} + + + +
    + {props.items.map((item) => ( +
  • + +
  • + ))} +
+
+
+ ); + } + + const { isActive, ...rest } = props; + return ( + [data-ui=icon]:not([class*=size-])]:size-4.5", + "[&>[data-ui=notification-badge]]:text-foreground/70", + "[&>[data-ui=notification-badge]]:rounded-md", + "[&>[data-ui=notification-badge]]:top-1/2", + "[&>[data-ui=notification-badge]]:right-1", + "[&>[data-ui=notification-badge]]:-translate-y-1/2", + "[&>[data-ui=notification-badge]]:bg-zinc-200/40", + "dark:[&>[data-ui=notification-badge]]:bg-zinc-900", + "[&>[data-ui=notification-badge]]:p-3", + "[&>[data-ui=notification-badge]]:text-xs/6", + "[&>[data-ui=notification-badge]]:font-semibold", + isActive + ? "bg-zinc-100/50 font-semibold dark:bg-zinc-900 [&>[data-ui=notification-badge]]:bg-transparent" + : [ + "font-medium", + "text-foreground/70 [&:not(:hover)>[data-ui=icon]]:text-foreground/35", + ], + rest.className + )} + /> + ); +} + +function AvatarMenuPopover() { + return ( + + + Clear status + + + + + + My profile + + + + + + Settings + + + + + + + + Sign out + + + + ); +} + +export function SideNavigation() { + return ( +
+
+
+ + + + Acme, Inc + + + + Item 1 + Item 2 + + + +
+
+ + + +
+ + + + + + Marissa Whitaker + + + + +
+
+ ); +} + +export function HamburgerMenu() { + return ( +
+ + + + + +
+ + + + Acme, Inc + + + + Item 1 + Item 2 + + + +
+
+ + + + + +
+
+
+ +
+ + + + + + + +
+
+ ); +} + +export function MainNavigation() { + // const location = useLocation(); + // const { session } = useSession(); + + // const isActive = (path: string) => { + // return location.pathname === path; + // }; + + const navItems = [ + { path: "/", label: "Accueil", icon: }, + { + path: "/tablo", + label: "Tableaux", + icon: , + }, + { + path: "/settings", + label: "Paramètres", + icon: , + }, + ]; + + return ( + + ); + + // return ( + //
+ //
+ //

Xtablo

+ //
+ + // + + // {session && ( + //
+ //
+ //
+ // + //
+ //
+ //

+ // {session.user?.email} + //

+ //

+ // {session.user?.email?.split("@")[0]} + //

+ //
+ //
+ //
+ // )} + //
+ // ); + // } +} diff --git a/ui/src/pages/tablo.tsx b/ui/src/pages/tablo.tsx index f26a19c..1f62484 100644 --- a/ui/src/pages/tablo.tsx +++ b/ui/src/pages/tablo.tsx @@ -1,12 +1,10 @@ import { SignOutButton } from "../components/SignOutButton"; import { useSession } from "../contexts/SessionContext"; -import { Header } from "../components/header"; export const TabloPage = () => { const { session } = useSession(); return (
-

Tablo