style: implement new navigation

This commit is contained in:
Scott Wilson
2025-10-15 18:06:34 -07:00
parent d00c9e422f
commit 4af3f6fc3f
116 changed files with 2644 additions and 2952 deletions
@@ -12,7 +12,7 @@ import { RedisBanner } from "@app/layouts/OrganizationLayout/components/RedisBan
import { SmtpBanner } from "@app/layouts/OrganizationLayout/components/SmtpBanner";
import { InsecureConnectionBanner } from "../OrganizationLayout/components/InsecureConnectionBanner";
import { AdminSidebar } from "./Sidebar";
import { AdminNavBar } from "./AdminNavBar";
export const AdminLayout = () => {
const { t } = useTranslation();
@@ -33,9 +33,9 @@ export const AdminLayout = () => {
{!isLoading && !serverDetails?.emailConfigured && <SmtpBanner />}
{!isLoading && subscription.auditLogs && <AuditLogBanner />}
{!window.isSecureContext && <InsecureConnectionBanner />}
<div className="flex grow flex-col overflow-y-hidden md:flex-row">
<AdminSidebar />
<div className="flex-1 overflow-x-hidden overflow-y-auto bg-bunker-800 px-4 pt-8 pb-4 dark:scheme-dark">
<div className="flex grow flex-col overflow-y-hidden">
<AdminNavBar />
<div className="flex-1 overflow-x-hidden overflow-y-auto bg-bunker-800 px-12 pt-10 pb-4 dark:scheme-dark">
<Outlet />
</div>
</div>
@@ -0,0 +1,102 @@
import { faCheckCircle } from "@fortawesome/free-regular-svg-icons";
import {
faArrowLeft,
faBuilding,
faCog,
faDatabase,
faGlobe,
faKey,
faLock,
faPlug,
faUserTie
} from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { Link, useMatchRoute } from "@tanstack/react-router";
import { motion } from "framer-motion";
import { Tab, TabList, Tabs } from "@app/components/v2";
const generalTabs = [
{
label: "General",
icon: faCog,
link: "/admin/"
},
{
label: "Encryption",
icon: faLock,
link: "/admin/encryption"
},
{
label: "Authentication",
icon: faCheckCircle,
link: "/admin/authentication"
},
{
label: "Integrations",
icon: faPlug,
link: "/admin/integrations"
},
{
label: "Caching",
icon: faDatabase,
link: "/admin/caching"
},
{
label: "Environment Variables",
icon: faKey,
link: "/admin/environment"
}
];
const othersTabs = [
{
label: "Access Controls",
icon: faUserTie,
link: "/admin/access-management"
},
{
label: "Resource Overview",
icon: faBuilding,
link: "/admin/resources/overview"
}
];
export const AdminNavBar = () => {
const matchRoute = useMatchRoute();
return (
<div className="border-b border-mineshaft-600 bg-mineshaft-900">
<motion.div
initial={{ x: -150 }}
animate={{ x: 0 }}
exit={{ x: -150 }}
transition={{ duration: 0.2 }}
className="px-4"
>
<nav className="w-full">
<Tabs value="selected">
<TabList className="border-b-0">
<Link to="/organization/projects">
<Tab value="back" className="flex gap-x-2">
<FontAwesomeIcon icon={faGlobe} />
<FontAwesomeIcon icon={faArrowLeft} />
</Tab>
</Link>
{[...generalTabs, ...othersTabs].map((tab) => {
const isActive = matchRoute({ to: tab.link, fuzzy: false });
return (
<Link key={tab.link} to={tab.link}>
<Tab variant="instance" value={isActive ? "selected" : ""}>
{tab.label}
</Tab>
</Link>
);
})}
</TabList>
</Tabs>
</nav>
</motion.div>
</div>
);
};
@@ -1,126 +0,0 @@
import { faCheckCircle } from "@fortawesome/free-regular-svg-icons";
import {
faBuilding,
faChevronLeft,
faCog,
faDatabase,
faKey,
faLock,
faPlug,
faUserTie
} from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { Link, useMatchRoute } from "@tanstack/react-router";
import { Menu, MenuGroup, MenuItem } from "@app/components/v2";
const generalTabs = [
{
label: "General",
icon: faCog,
link: "/admin/"
},
{
label: "Encryption",
icon: faLock,
link: "/admin/encryption"
},
{
label: "Authentication",
icon: faCheckCircle,
link: "/admin/authentication"
},
{
label: "Integrations",
icon: faPlug,
link: "/admin/integrations"
},
{
label: "Caching",
icon: faDatabase,
link: "/admin/caching"
},
{
label: "Environment Variables",
icon: faKey,
link: "/admin/environment"
}
];
const othersTabs = [
{
label: "Access Controls",
icon: faUserTie,
link: "/admin/access-management"
},
{
label: "Resource Overview",
icon: faBuilding,
link: "/admin/resources/overview"
}
];
export const AdminSidebar = () => {
const matchRoute = useMatchRoute();
return (
<aside className="dark w-full border-r border-mineshaft-600 bg-linear-to-tr from-mineshaft-700 via-mineshaft-800 to-mineshaft-900 md:w-60">
<nav className="items-between flex h-full flex-col justify-between overflow-y-auto dark:scheme-dark">
<div className="flex-1">
<Menu>
<MenuGroup title="Configuration">
{generalTabs.map((tab) => {
const isActive = matchRoute({ to: tab.link, fuzzy: false });
return (
<Link key={tab.link} to={tab.link}>
<MenuItem isSelected={Boolean(isActive)}>
<div className="mx-1 flex gap-2">
<div className="w-6">
<FontAwesomeIcon icon={tab.icon} />
</div>
{tab.label}
</div>
</MenuItem>
</Link>
);
})}
</MenuGroup>
<MenuGroup title="Others">
{othersTabs.map((tab) => {
const isActive = matchRoute({ to: tab.link, fuzzy: false });
return (
<Link key={tab.link} to={tab.link}>
<MenuItem isSelected={Boolean(isActive)}>
<div className="mx-1 flex gap-2">
<div className="w-6">
<FontAwesomeIcon icon={tab.icon} />
</div>
{tab.label}
</div>
</MenuItem>
</Link>
);
})}
</MenuGroup>
</Menu>
</div>
<Menu>
<Link to="/organization/projects">
<MenuItem
className="relative flex items-center gap-2 overflow-hidden text-sm text-mineshaft-400 hover:text-mineshaft-300"
leftIcon={
<FontAwesomeIcon
className="mx-1 inline-block shrink-0"
icon={faChevronLeft}
flip="vertical"
/>
}
>
Back to Organization
</MenuItem>
</Link>
</Menu>
</nav>
</aside>
);
};