Skip to content

Commit 9ecc0c8

Browse files
committed
feat: improve sidebar ui
1 parent dc0afaf commit 9ecc0c8

19 files changed

+1995
-732
lines changed

.cursor/mcp.json

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"mcpServers": {
3+
"shadcn": {
4+
"command": "npx",
5+
"args": [
6+
"shadcn@latest",
7+
"mcp"
8+
]
9+
}
10+
}
11+
}

app/client-layout.tsx

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
'use client';
22

33
import { Toaster } from 'sonner';
4-
import { SidebarProvider, SidebarTrigger } from '@/components/ui/sidebar';
4+
import { SidebarInset, SidebarProvider, SidebarTrigger } from '@/components/ui/sidebar';
55
import { AppSidebar } from '@/components/Sidebar/AppSiderbar';
66
import { SafeSdkProvider } from '@/features/safe-sdk/providers/safe-sdk-provider';
77
import Web3Layout from './web3-layout';
8+
import { SafeAccountSelect } from '@/components/Sidebar/SafeAccountSelect';
89

910
const ClientRootLayout = ({ children }: { children: React.ReactNode }) => {
1011
return (
@@ -13,12 +14,15 @@ const ClientRootLayout = ({ children }: { children: React.ReactNode }) => {
1314
<SafeSdkProvider>
1415
<SidebarProvider>
1516
<AppSidebar />
16-
<main className='flex flex-col w-full h-full overflow-hidden relative'>
17-
<div className='flex items-center gap-4 p-4 border-b h-12 flex-shrink-0 fixed w-full z-2 bg-background'>
18-
<SidebarTrigger />
19-
</div>
20-
<div className='h-[calc(100vh-3rem)] overflow-hidden mt-12'>{children}</div>
21-
</main>
17+
<SidebarInset>
18+
<header>
19+
<div className='flex items-center p-4 border-b h-12 flex-shrink-0'>
20+
<SidebarTrigger />
21+
<SafeAccountSelect className='absolute right-4' />
22+
</div>
23+
</header>
24+
<main>{children}</main>
25+
</SidebarInset>
2226
</SidebarProvider>
2327
<Toaster />
2428
</SafeSdkProvider>

components.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,8 @@
1717
"lib": "@/lib",
1818
"hooks": "@/hooks"
1919
},
20+
"registries": {
21+
"@acme": "https://acme.com/r/{name}.json"
22+
},
2023
"iconLibrary": "lucide"
2124
}

components/BlockChainNetworkIcon.tsx

Lines changed: 105 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -11,46 +11,126 @@ import {
1111
NetworkBerachain,
1212
NetworkHemi,
1313
NetworkLinea,
14+
NetworkCelo,
15+
NetworkMantle,
16+
NetworkScroll,
17+
NetworkZksync,
18+
NetworkAurora,
19+
NetworkSonic,
20+
NetworkInk,
21+
NetworkUnichain,
1422
} from '@web3icons/react';
1523

24+
/**
25+
* Get network icon component based on chain ID
26+
* @param chainId - The chain ID (from wagmi)
27+
* @param variant - Icon variant style
28+
* @param size - Icon size in pixels
29+
* @param color - Optional color override
30+
*/
1631
export function getNetworkIcon({
17-
networkId,
18-
variant,
19-
size,
32+
chainId,
33+
variant = 'branded',
34+
size = 24,
2035
color,
2136
}: {
22-
networkId: string;
23-
variant: 'branded' | 'mono' | 'background';
24-
size: number;
37+
chainId: number | null | undefined;
38+
variant?: 'branded' | 'mono' | 'background';
39+
size?: number;
2540
color?: string;
2641
}) {
27-
switch (networkId) {
28-
case 'ethereum':
42+
if (!chainId) return null;
43+
44+
// Map chain IDs to their respective icon components
45+
switch (chainId) {
46+
// Ethereum Mainnet
47+
case 1:
2948
return <NetworkEthereum variant={variant} size={size} color={color} />;
30-
case 'polygon':
31-
return <NetworkPolygon variant={variant} size={size} color={color} />;
32-
case 'arbitrum':
33-
return <NetworkArbitrumOne variant={variant} size={size} color={color} />;
34-
case 'optimism':
49+
50+
// Optimism
51+
case 10:
3552
return <NetworkOptimism variant={variant} size={size} color={color} />;
36-
case 'base':
37-
return <NetworkBase variant={variant} size={size} color={color} />;
38-
case 'bsc':
53+
54+
// BNB Smart Chain
55+
case 56:
3956
return <NetworkBinanceSmartChain variant={variant} size={size} color={color} />;
40-
case 'avalanche':
41-
return <NetworkAvalanche variant={variant} size={size} color={color} />;
42-
case 'gnosis':
57+
58+
// Gnosis
59+
case 100:
4360
return <NetworkGnosis variant={variant} size={size} color={color} />;
44-
case 'hemi':
61+
62+
// Unichain
63+
case 130:
64+
return <NetworkUnichain variant={variant} size={size} color={color} />;
65+
66+
// Polygon
67+
case 137:
68+
return <NetworkPolygon variant={variant} size={size} color={color} />;
69+
70+
// Sonic
71+
case 146:
72+
return <NetworkSonic variant={variant} size={size} color={color} />;
73+
74+
// zkSync Era
75+
case 324:
76+
return <NetworkZksync variant={variant} size={size} color={color} />;
77+
78+
// Polygon zkEVM
79+
case 1101:
80+
return <NetworkPolygonZkevm variant={variant} size={size} color={color} />;
81+
82+
// Mantle
83+
case 5000:
84+
return <NetworkMantle variant={variant} size={size} color={color} />;
85+
86+
// Base
87+
case 8453:
88+
return <NetworkBase variant={variant} size={size} color={color} />;
89+
90+
// Arbitrum One
91+
case 42161:
92+
return <NetworkArbitrumOne variant={variant} size={size} color={color} />;
93+
94+
// Celo
95+
case 42220:
96+
return <NetworkCelo variant={variant} size={size} color={color} />;
97+
98+
// Hemi
99+
case 43111:
45100
return <NetworkHemi variant={variant} size={size} color={color} />;
46-
case 'linea':
101+
102+
// Avalanche
103+
case 43114:
104+
return <NetworkAvalanche variant={variant} size={size} color={color} />;
105+
106+
// Ink
107+
case 57073:
108+
return <NetworkInk variant={variant} size={size} color={color} />;
109+
110+
// Linea
111+
case 59144:
47112
return <NetworkLinea variant={variant} size={size} color={color} />;
48-
case 'berachain':
113+
114+
// Berachain
115+
case 80094:
49116
return <NetworkBerachain variant={variant} size={size} color={color} />;
50-
case 'polygon-zkevm':
51-
return <NetworkPolygonZkevm variant={variant} size={size} color={color} />;
52-
case 'BaseSepolia':
117+
118+
// Base Sepolia (testnet)
119+
case 84532:
53120
return <NetworkBase variant={variant} size={size} color={color} />;
121+
122+
// Scroll
123+
case 534352:
124+
return <NetworkScroll variant={variant} size={size} color={color} />;
125+
126+
// Sepolia (Ethereum testnet)
127+
case 11155111:
128+
return <NetworkEthereum variant={variant} size={size} color={color} />;
129+
130+
// Aurora
131+
case 1313161554:
132+
return <NetworkAurora variant={variant} size={size} color={color} />;
133+
54134
default:
55135
return null;
56136
}

components/SafeAccountEmptyState.tsx

Lines changed: 0 additions & 55 deletions
This file was deleted.

components/Sidebar/AppSiderbar.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@ import { AppSidebarFooter } from './AppSiderbarFooter';
33
import { AppSidebarContent } from './AppSiderbarContent';
44
import { Sidebar } from '@/components/ui/sidebar';
55

6-
export function AppSidebar() {
6+
export function AppSidebar({ ...props }: React.ComponentProps<typeof Sidebar>) {
77
return (
8-
<Sidebar variant='sidebar'>
8+
<Sidebar collapsible='icon' {...props}>
99
<AppSidebarHeader />
1010
<AppSidebarContent />
1111
<AppSidebarFooter />

components/Sidebar/AppSiderbarContent.tsx

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,21 +9,7 @@ import {
99
SidebarGroupContent,
1010
SidebarMenuItem,
1111
} from '@/components/ui/sidebar';
12-
import {
13-
ArrowLeftRight,
14-
Clock,
15-
Coins,
16-
Gauge,
17-
HelpCircle,
18-
History,
19-
ListChecks,
20-
ListTodo,
21-
ListTodoIcon,
22-
Plus,
23-
Search,
24-
Settings,
25-
Wallet,
26-
} from 'lucide-react';
12+
import { ArrowLeftRight, Coins, Gauge, HelpCircle, ListTodoIcon, Plus, Search, Settings, Wallet } from 'lucide-react';
2713
import { usePathname, useRouter } from 'next/navigation';
2814

2915
const baseItems = [

components/Sidebar/AppSiderbarFooter.tsx

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,14 @@
11
'use client';
22

33
import { SidebarFooter, SidebarMenuItem, SidebarMenu } from '@/components/ui/sidebar';
4-
import WalletSidebarItem from '@/components/Sidebar/WalletSidebarItem';
5-
import { SafeAccountSelect } from './SafeAccountSelect';
4+
import ConnectWalletButton from '@/components/Sidebar/ConnectWalletButton';
65

76
export function AppSidebarFooter() {
87
return (
9-
<SidebarFooter className='pt-4'>
8+
<SidebarFooter>
109
<SidebarMenu>
1110
<SidebarMenuItem>
12-
<WalletSidebarItem />
13-
</SidebarMenuItem>
14-
<SidebarMenuItem>
15-
<SafeAccountSelect />
11+
<ConnectWalletButton />
1612
</SidebarMenuItem>
1713
</SidebarMenu>
1814
</SidebarFooter>
Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,21 @@
11
'use client';
22

3-
import { SidebarHeader } from '@/components/ui/sidebar';
3+
import { SidebarHeader, SidebarMenu, SidebarMenuButton, SidebarMenuItem } from '@/components/ui/sidebar';
4+
import { ScanEye } from 'lucide-react';
45

56
export function AppSidebarHeader() {
67
return (
78
<SidebarHeader>
8-
<div className='w-full h-10 bg-black/35 flex items-center p-2'>Our Logo</div>
9+
<SidebarMenu>
10+
<SidebarMenuItem>
11+
<SidebarMenuButton asChild className='data-[slot=sidebar-menu-button]:!p-1.5'>
12+
<a href='#'>
13+
<ScanEye className='!size-5' />
14+
<span className='text-base font-semibold'>SCAN EYE</span>
15+
</a>
16+
</SidebarMenuButton>
17+
</SidebarMenuItem>
18+
</SidebarMenu>
919
</SidebarHeader>
1020
);
1121
}

0 commit comments

Comments
 (0)