Files
assetx/components/layout/Sidebar.tsx

120 lines
4.1 KiB
TypeScript
Raw Normal View History

2026-02-04 12:56:06 +08:00
"use client";
import { useState, useEffect } from "react";
import Image from "next/image";
import { usePathname, useRouter } from "next/navigation";
import { Listbox, ListboxItem } from "@heroui/react";
import { useApp } from "@/contexts/AppContext";
export default function Sidebar() {
const { t } = useApp();
const pathname = usePathname();
const router = useRouter();
const navigationItems = [
{ icon: "/icon-lending.svg", label: t("nav.fundMarket"), key: "FundMarket", path: "/" },
{ icon: "/icon-alp.svg", label: t("nav.alp"), key: "ALP", path: "/alp" },
{ icon: "/icon-swap.svg", label: t("nav.swap"), key: "Swap", path: "/swap" },
{ icon: "/icon-lending.svg", label: t("nav.lending"), key: "Lending", path: "/lending" },
{ icon: "/icon-transparency.svg", label: t("nav.transparency"), key: "Transparency", path: "/transparency" },
{ icon: "/icon-ecosystem.svg", label: t("nav.ecosystem"), key: "Ecosystem", path: "/ecosystem" },
{ icon: "/icon-points.svg", label: t("nav.points"), key: "Points", path: "/points" },
];
const [currentKey, setCurrentKey] = useState("FundMarket");
useEffect(() => {
const matched = navigationItems.find(item => item.path === pathname)?.key;
if (matched) {
setCurrentKey(matched);
}
}, [pathname]);
return (
<aside className="fixed left-0 top-0 bg-bg-surface dark:bg-gray-800 border-r border-border-normal dark:border-gray-700 flex flex-col items-center px-6 py-8 gap-8 h-screen w-[222px] overflow-y-auto">
{/* Logo */}
<div className="w-full h-10">
<Image
src="/logo.svg"
alt="ASSETX Logo"
width={174}
height={40}
className="w-full h-full dark:invert"
/>
</div>
{/* Navigation */}
<Listbox
aria-label="Navigation"
selectedKeys={[currentKey]}
onAction={(key) => {
const item = navigationItems.find(i => i.key === key);
if (item) router.push(item.path);
}}
classNames={{
base: "w-full p-0",
list: "gap-1",
}}
>
{navigationItems.map((item) => (
<ListboxItem
key={item.key}
classNames={{
base: [
"h-11 px-3 rounded-xl gap-3",
"data-[selected=true]:bg-fill-tertiary-normal dark:data-[selected=true]:bg-gray-700",
"data-[selected=true]:text-text-primary dark:data-[selected=true]:text-white",
"hover:bg-fill-quaternary dark:hover:bg-gray-700",
].join(" "),
}}
startContent={
<div className="w-[22px] h-[22px] flex-shrink-0 relative">
<Image
src={item.icon}
alt={item.label}
width={22}
height={22}
className="w-full h-full"
/>
</div>
}
>
{item.label}
</ListboxItem>
))}
</Listbox>
{/* Spacer */}
<div className="flex-1" />
{/* Global TVL Section */}
<div className="w-full border-t border-border-gray dark:border-gray-700 pt-8">
<div className="bg-bg-subtle dark:bg-gray-700 rounded-xl p-4 flex flex-col gap-1 h-[85px]">
<p className="text-text-tertiary dark:text-gray-400 text-[10px] font-medium leading-[150%] tracking-[0.01em]">
{t("nav.globalTVL")}
</p>
<p className="text-text-primary dark:text-white text-base font-extrabold leading-[150%] font-jetbrains">
$465,000,000
</p>
</div>
{/* FAQs Link */}
<div className="rounded-xl flex items-center h-[42px] mt-8">
<div className="flex items-center gap-0">
<Image
src="/icon-faq.png"
alt="FAQ"
width={24}
height={24}
className="object-cover"
/>
<span className="text-text-primary dark:text-white text-sm font-bold leading-[150%]">
{t("nav.faqs")}
</span>
</div>
</div>
</div>
</aside>
);
}