Created
May 18, 2026 16:37
-
-
Save fayimora/7d99e9fd91254690c3164e57471992b1 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import { useMemo, type ReactNode } from 'react' | |
| import AccountBalanceWalletIcon from '@mui/icons-material/AccountBalanceWallet' | |
| import DashboardIcon from '@mui/icons-material/Dashboard' | |
| import NotificationsNoneIcon from '@mui/icons-material/NotificationsNone' | |
| import { | |
| Box, | |
| Divider, | |
| Drawer, | |
| Typography, | |
| type SxProps, | |
| type Theme, | |
| } from '@mui/material' | |
| import { | |
| createFileRoute, | |
| Link, | |
| Outlet, | |
| useLocation, | |
| useMatchRoute, | |
| type LinkComponentProps, | |
| } from '@tanstack/react-router' | |
| import type { RegisteredRouter } from '@tanstack/router-core' | |
| import { PillButton } from '@components/ui/PillButton' | |
| import { useAccounts } from '@hooks/useAccounts' | |
| const SIDEBAR_WIDTH = (theme: Theme) => | |
| `clamp(${theme.spacing(25)}, 18vw, ${theme.spacing(35)})` | |
| export const Route = createFileRoute('/next/dashboard')({ | |
| component: RouteComponent, | |
| }) | |
| function RouteComponent() { | |
| const accounts = useAccounts() | |
| const pathname = useLocation({ select: (location) => location.pathname }) | |
| const matchRoute = useMatchRoute() | |
| const wallets = useMemo( | |
| () => | |
| accounts.slice().sort( | |
| // make sure primary account is first | |
| (a, b) => | |
| Number(b.primary) - Number(a.primary) || | |
| a.hint.localeCompare(b.hint) | |
| ), | |
| [accounts] | |
| ) | |
| return ( | |
| <Box sx={{ display: 'flex', minHeight: '100vh' }}> | |
| <Drawer | |
| variant="permanent" | |
| sx={{ | |
| width: SIDEBAR_WIDTH, | |
| flexShrink: 0, | |
| '& .MuiDrawer-paper': { | |
| width: SIDEBAR_WIDTH, | |
| boxSizing: 'border-box', | |
| bgcolor: 'portfolio.sidebar.background', | |
| borderColor: 'divider', | |
| color: 'text.primary', | |
| }, | |
| }} | |
| > | |
| <Box | |
| component="nav" | |
| aria-label="Portfolio navigation" | |
| sx={{ | |
| display: 'flex', | |
| minHeight: '100%', | |
| flexDirection: 'column', | |
| px: 1, | |
| py: 3, | |
| }} | |
| > | |
| <Box | |
| sx={{ | |
| display: 'flex', | |
| alignItems: 'center', | |
| justifyContent: 'space-between', | |
| px: 3, | |
| mb: 2, | |
| }} | |
| > | |
| <Typography | |
| variant="h6" | |
| component="div" | |
| sx={{ fontWeight: 600, letterSpacing: 0.2 }} | |
| > | |
| Splice Portfolio | |
| </Typography> | |
| {/* <Typography */} | |
| {/* aria-hidden="true" */} | |
| {/* sx={{ color: 'text.secondary', fontSize: 18 }} */} | |
| {/* > */} | |
| {/* ‹ */} | |
| {/* </Typography> */} | |
| </Box> | |
| <Box sx={{ display: 'grid', gap: 0.5 }}> | |
| <SidebarLink | |
| to="/next/dashboard" | |
| active={isDashboardPath(pathname)} | |
| icon={<DashboardIcon fontSize="small" />} | |
| > | |
| Dashboard | |
| </SidebarLink> | |
| <SidebarLink | |
| to="/next/dashboard/offers" | |
| active={pathname === '/next/dashboard/offers'} | |
| icon={<NotificationsNoneIcon fontSize="small" />} | |
| > | |
| Offers | |
| </SidebarLink> | |
| </Box> | |
| <Divider sx={{ my: 2 }} /> | |
| <Box | |
| sx={{ | |
| flex: 1, | |
| // minHeight: 0, | |
| display: 'grid', | |
| alignContent: 'start', | |
| gap: 0.5, | |
| overflowY: 'auto', | |
| pr: 0.5, | |
| mb: 2, | |
| scrollbarWidth: 'thin', | |
| }} | |
| > | |
| {wallets.map((wallet) => ( | |
| <SidebarLink | |
| key={wallet.partyId} | |
| to="/next/dashboard/wallet/$walletId" | |
| params={{ walletId: wallet.partyId }} | |
| active={Boolean( | |
| matchRoute({ | |
| to: '/next/dashboard/wallet/$walletId', | |
| params: { walletId: wallet.partyId }, | |
| }) | |
| )} | |
| icon={ | |
| <AccountBalanceWalletIcon fontSize="small" /> | |
| } | |
| > | |
| {wallet.hint} | |
| </SidebarLink> | |
| ))} | |
| </Box> | |
| <Box sx={{ display: 'grid', gap: 1.5, pb: 4 }}> | |
| <PillButton type="button" fullWidth> | |
| Wallet Gateway | |
| </PillButton> | |
| <PillButton type="button" tone="danger" fullWidth> | |
| Disconnect | |
| </PillButton> | |
| </Box> | |
| </Box> | |
| </Drawer> | |
| <Box | |
| component="main" | |
| sx={{ | |
| flex: 1, | |
| minWidth: 0, | |
| bgcolor: 'background.default', | |
| }} | |
| > | |
| <Outlet /> | |
| </Box> | |
| </Box> | |
| ) | |
| } | |
| type SidebarLinkProps = { | |
| active: boolean | |
| icon: ReactNode | |
| children: ReactNode | |
| } & LinkComponentProps<'a', RegisteredRouter> | |
| function SidebarLink({ | |
| active, | |
| icon, | |
| children, | |
| ...linkProps | |
| }: SidebarLinkProps) { | |
| return ( | |
| <Link | |
| {...linkProps} | |
| aria-current={active ? 'page' : undefined} | |
| style={{ color: 'inherit', textDecoration: 'none' }} | |
| > | |
| <Box sx={sidebarLinkSx(active)}> | |
| <Box | |
| aria-hidden="true" | |
| sx={{ | |
| display: 'flex', | |
| alignItems: 'center', | |
| color: 'text.secondary', | |
| }} | |
| > | |
| {icon} | |
| </Box> | |
| <Typography | |
| component="span" | |
| variant="body2" | |
| sx={{ | |
| minWidth: 0, | |
| overflow: 'hidden', | |
| textOverflow: 'ellipsis', | |
| whiteSpace: 'nowrap', | |
| }} | |
| > | |
| {children} | |
| </Typography> | |
| </Box> | |
| </Link> | |
| ) | |
| } | |
| const sidebarLinkSx = (active: boolean): SxProps<Theme> => ({ | |
| display: 'grid', | |
| gridTemplateColumns: '18px minmax(0, 1fr)', | |
| alignItems: 'center', | |
| gap: 1, | |
| minHeight: 34, | |
| borderRadius: 1, | |
| px: 3, | |
| color: 'text.primary', | |
| bgcolor: active ? 'portfolio.sidebar.active' : 'transparent', | |
| transition: (theme) => | |
| theme.transitions.create(['background-color', 'color'], { | |
| duration: theme.transitions.duration.shortest, | |
| }), | |
| '&:hover': { | |
| bgcolor: active ? 'portfolio.sidebar.active' : 'action.hover', | |
| }, | |
| }) | |
| function isDashboardPath(pathname: string) { | |
| return pathname === '/next/dashboard' || pathname === '/next/dashboard/' | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment