Skip to content

Commit 66270f7

Browse files
committed
Dashboard: group project sidebar links (#7417)
<!-- ## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes" If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000): ## Notes for the reviewer Anything important to call out? Be sure to also clarify these in your comments. ## How to test Unit tests, playground, etc. --> <!-- start pr-codex --> --- ## PR-Codex overview This PR focuses on enhancing the sidebar layout by introducing new components for better organization and rendering of sidebar links. It refactors the sidebar structure to use `RenderSidebarMenu` and `RenderSidebarGroup`, allowing for grouped sidebar items. ### Detailed summary - Added `SidebarGroupLabel` and `SidebarMenuSubItem` components. - Refactored `FullWidthSidebarLayout` to use `RenderSidebarMenu` instead of `RenderSidebarGroup`. - Updated `RenderSidebarGroup` to include `SidebarGroupLabel` and `SidebarMenuItem`. - Introduced grouping for sidebar links with `group` and `links` properties. - Enhanced sidebar link structure to support separators and improved organization. > ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}` <!-- end pr-codex --> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **Refactor** - Improved sidebar navigation by organizing links into hierarchical groups ("Build," "Monetize," "Scale") for better clarity and usability. - Updated sidebar rendering for greater modularity and maintainability, with enhanced grouping and link management. - **Style** - Sidebar appearance and structure are updated for a more organized and user-friendly experience. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
1 parent 11b4d9e commit 66270f7

File tree

2 files changed

+99
-61
lines changed

2 files changed

+99
-61
lines changed

apps/dashboard/src/@/components/blocks/SidebarLayout.tsx

Lines changed: 34 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,11 @@ import {
44
SidebarFooter,
55
SidebarGroup,
66
SidebarGroupContent,
7+
SidebarGroupLabel,
78
SidebarMenu,
89
SidebarMenuButton,
910
SidebarMenuItem,
11+
SidebarMenuSubItem,
1012
SidebarRail,
1113
SidebarSeparator,
1214
SidebarTrigger,
@@ -66,23 +68,13 @@ export function FullWidthSidebarLayout(props: {
6668
>
6769
{/* left - sidebar */}
6870
<Sidebar className="pt-2" collapsible="icon" side="left">
69-
<SidebarContent>
70-
<SidebarGroup>
71-
<SidebarGroupContent>
72-
<RenderSidebarGroup
73-
groupName={undefined}
74-
sidebarLinks={contentSidebarLinks}
75-
/>
76-
</SidebarGroupContent>
77-
</SidebarGroup>
71+
<SidebarContent className="p-2">
72+
<RenderSidebarMenu links={contentSidebarLinks} />
7873
</SidebarContent>
7974

8075
{footerSidebarLinks && (
8176
<SidebarFooter className="pb-3">
82-
<RenderSidebarGroup
83-
groupName={undefined}
84-
sidebarLinks={footerSidebarLinks}
85-
/>
77+
<RenderSidebarMenu links={footerSidebarLinks} />
8678
</SidebarFooter>
8779
)}
8880

@@ -106,17 +98,29 @@ export function FullWidthSidebarLayout(props: {
10698

10799
function RenderSidebarGroup(props: {
108100
sidebarLinks: SidebarLink[];
109-
groupName: string | undefined;
101+
groupName: string;
110102
}) {
111-
const { sidebarLinks } = props;
112-
const sidebar = useSidebar();
103+
return (
104+
<SidebarGroup className="p-0">
105+
<SidebarMenuItem>
106+
<SidebarGroupLabel> {props.groupName}</SidebarGroupLabel>
107+
<SidebarGroupContent>
108+
<RenderSidebarMenu links={props.sidebarLinks} />
109+
</SidebarGroupContent>
110+
</SidebarMenuItem>
111+
</SidebarGroup>
112+
);
113+
}
113114

115+
function RenderSidebarMenu(props: { links: SidebarLink[] }) {
116+
const sidebar = useSidebar();
114117
return (
115118
<SidebarMenu className="gap-1.5">
116-
{sidebarLinks.map((link) => {
119+
{props.links.map((link, idx) => {
120+
// link
117121
if ("href" in link) {
118122
return (
119-
<SidebarMenuItem key={link.href}>
123+
<SidebarMenuSubItem key={link.href}>
120124
<SidebarMenuButton asChild>
121125
<NavLink
122126
activeClassName="text-foreground bg-accent"
@@ -132,14 +136,24 @@ function RenderSidebarGroup(props: {
132136
<span>{link.label}</span>
133137
</NavLink>
134138
</SidebarMenuButton>
135-
</SidebarMenuItem>
139+
</SidebarMenuSubItem>
136140
);
137141
}
138142

143+
// separator
139144
if ("separator" in link) {
140-
return <SidebarSeparator className="my-1" key={Math.random()} />;
145+
return (
146+
<SidebarSeparator
147+
className="my-1"
148+
key={`separator-${
149+
// biome-ignore lint/suspicious/noArrayIndexKey: index is fine here
150+
idx
151+
}`}
152+
/>
153+
);
141154
}
142155

156+
// group
143157
return (
144158
<RenderSidebarGroup
145159
groupName={link.group}

apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/components/ProjectSidebarLayout.tsx

Lines changed: 65 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -34,57 +34,81 @@ export function ProjectSidebarLayout(props: {
3434
label: "Overview",
3535
},
3636
{
37-
href: `${layoutPath}/wallets`,
38-
icon: WalletIcon,
39-
label: "Wallets",
40-
},
41-
{
42-
href: `${layoutPath}/account-abstraction`,
43-
icon: SmartAccountIcon,
44-
label: "Account Abstraction",
45-
},
46-
{
47-
href: `${layoutPath}/universal-bridge`,
48-
icon: PayIcon,
49-
label: "Universal Bridge",
37+
separator: true,
5038
},
5139
{
52-
href: `${layoutPath}/contracts`,
53-
icon: ContractIcon,
54-
label: "Contracts",
40+
group: "Build",
41+
links: [
42+
{
43+
href: `${layoutPath}/wallets`,
44+
icon: WalletIcon,
45+
label: "Wallets",
46+
},
47+
{
48+
href:
49+
engineLinkType === "cloud"
50+
? `${layoutPath}/transactions`
51+
: `${layoutPath}/engine/dedicated`,
52+
icon: ArrowLeftRightIcon,
53+
isActive: (pathname) => {
54+
return (
55+
pathname.startsWith(`${layoutPath}/transactions`) ||
56+
pathname.startsWith(`${layoutPath}/engine/dedicated`)
57+
);
58+
},
59+
label: "Transactions",
60+
},
61+
{
62+
href: `${layoutPath}/contracts`,
63+
icon: ContractIcon,
64+
label: "Contracts",
65+
},
66+
],
5567
},
5668
{
57-
href: `${layoutPath}/tokens`,
58-
icon: CoinsIcon,
59-
label: (
60-
<span className="flex items-center gap-2">
61-
Tokens <Badge>New</Badge>
62-
</span>
63-
),
69+
separator: true,
6470
},
6571
{
66-
href:
67-
engineLinkType === "cloud"
68-
? `${layoutPath}/transactions`
69-
: `${layoutPath}/engine/dedicated`,
70-
icon: ArrowLeftRightIcon,
71-
isActive: (pathname) => {
72-
return (
73-
pathname.startsWith(`${layoutPath}/transactions`) ||
74-
pathname.startsWith(`${layoutPath}/engine/dedicated`)
75-
);
76-
},
77-
label: "Transactions",
72+
group: "Monetize",
73+
links: [
74+
{
75+
href: `${layoutPath}/universal-bridge`,
76+
icon: PayIcon,
77+
label: "Universal Bridge",
78+
},
79+
{
80+
href: `${layoutPath}/tokens`,
81+
icon: CoinsIcon,
82+
label: (
83+
<span className="flex items-center gap-2">
84+
Tokens <Badge>New</Badge>
85+
</span>
86+
),
87+
},
88+
],
7889
},
7990
{
80-
href: `${layoutPath}/insight`,
81-
icon: InsightIcon,
82-
label: "Insight",
91+
separator: true,
8392
},
8493
{
85-
href: `${layoutPath}/vault`,
86-
icon: LockIcon,
87-
label: "Vault",
94+
group: "Scale",
95+
links: [
96+
{
97+
href: `${layoutPath}/insight`,
98+
icon: InsightIcon,
99+
label: "Insight",
100+
},
101+
{
102+
href: `${layoutPath}/account-abstraction`,
103+
icon: SmartAccountIcon,
104+
label: "Account Abstraction",
105+
},
106+
{
107+
href: `${layoutPath}/vault`,
108+
icon: LockIcon,
109+
label: "Vault",
110+
},
111+
],
88112
},
89113
]}
90114
footerSidebarLinks={[

0 commit comments

Comments
 (0)