🎨 style: adjust sidebar for mobile

This commit is contained in:
Wahyu Kurniawan 2024-03-06 08:25:29 +07:00
parent 3b1f03bcb6
commit e05e2c63c2
No known key found for this signature in database
GPG Key ID: 040A1549143A8E33

View File

@ -1,6 +1,6 @@
import React, { useCallback, useEffect, useState } from 'react'; import React, { useCallback, useEffect, useState } from 'react';
import { NavLink, useNavigate, useParams } from 'react-router-dom'; import { NavLink, useNavigate, useParams } from 'react-router-dom';
import { Organization } from 'gql-client'; import { Organization, User } from 'gql-client';
import { Option } from '@material-tailwind/react'; import { Option } from '@material-tailwind/react';
import { useDisconnect } from 'wagmi'; import { useDisconnect } from 'wagmi';
@ -12,11 +12,16 @@ import {
FolderIcon, FolderIcon,
GlobeIcon, GlobeIcon,
LifeBuoyIcon, LifeBuoyIcon,
LogoutIcon,
QuestionMarkRoundIcon, QuestionMarkRoundIcon,
SettingsSlidersIcon, SettingsSlidersIcon,
} from 'components/shared/CustomIcon'; } from 'components/shared/CustomIcon';
import { Tabs } from 'components/shared/Tabs'; import { Tabs } from 'components/shared/Tabs';
import { Logo } from 'components/Logo'; import { Logo } from 'components/Logo';
import { Avatar } from 'components/shared/Avatar';
import { formatAddress } from 'utils/format';
import { getInitials } from 'utils/geInitials';
import { Button } from 'components/shared/Button';
export const Sidebar = () => { export const Sidebar = () => {
const { orgSlug } = useParams(); const { orgSlug } = useParams();
@ -24,6 +29,17 @@ export const Sidebar = () => {
const client = useGQLClient(); const client = useGQLClient();
const { disconnect } = useDisconnect(); const { disconnect } = useDisconnect();
const [user, setUser] = useState<User>();
const fetchUser = useCallback(async () => {
const { user } = await client.getUser();
setUser(user);
}, []);
useEffect(() => {
fetchUser();
}, []);
const [selectedOrgSlug, setSelectedOrgSlug] = useState(orgSlug); const [selectedOrgSlug, setSelectedOrgSlug] = useState(orgSlug);
const [organizations, setOrganizations] = useState<Organization[]>([]); const [organizations, setOrganizations] = useState<Organization[]>([]);
@ -43,39 +59,21 @@ export const Sidebar = () => {
}, [disconnect, navigate]); }, [disconnect, navigate]);
return ( return (
<nav className="lg:flex hidden flex-col h-full px-6 py-8 gap-9"> <nav className="h-full w-[320px] lg:flex hidden flex-col">
<Logo orgSlug={orgSlug} /> <div className="flex flex-col h-full pt-8 pb-0 px-6 lg:pb-8 gap-9">
{/* Switch organization */} <Logo orgSlug={orgSlug} />
<div className="flex flex-1 flex-col gap-4"> {/* Switch organization */}
<AsyncSelect <div className="flex flex-1 flex-col gap-4">
containerProps={{ className: 'h-14 border-none' }} <AsyncSelect
labelProps={{ className: 'before:border-none after:border-none' }} containerProps={{ className: 'h-14 border-none' }}
className="bg-white rounded-lg shadow border-none" labelProps={{ className: 'before:border-none after:border-none' }}
value={selectedOrgSlug} className="bg-white rounded-lg shadow border-none"
onChange={(value) => { value={selectedOrgSlug}
setSelectedOrgSlug(value!); onChange={(value) => {
navigate(`/${value}`); setSelectedOrgSlug(value!);
}} navigate(`/${value}`);
selected={(_, index) => ( }}
<div className="flex items-center space-x-3"> selected={(_, index) => (
<img
src="/logo.svg"
alt="Application Logo"
className="h-8 w-8 rounded-lg"
/>
<div>
<div className="text-sm font-semibold">
{organizations[index!]?.name}
</div>
<div className="text-xs text-gray-500">Organization</div>
</div>
</div>
)}
arrow={<ChevronGrabberHorizontal className="h-4 w-4 text-gray-500" />}
>
{/* // TODO: Show label organization and manage in option */}
{organizations.map((org) => (
<Option key={org.id} value={org.slug}>
<div className="flex items-center space-x-3"> <div className="flex items-center space-x-3">
<img <img
src="/logo.svg" src="/logo.svg"
@ -83,50 +81,100 @@ export const Sidebar = () => {
className="h-8 w-8 rounded-lg" className="h-8 w-8 rounded-lg"
/> />
<div> <div>
<div className="text-sm font-semibold">{org.name}</div> <div className="text-sm font-semibold">
{organizations[index!]?.name}
</div>
<div className="text-xs text-gray-500">Organization</div> <div className="text-xs text-gray-500">Organization</div>
</div> </div>
</div> </div>
</Option> )}
))} arrow={
</AsyncSelect> <ChevronGrabberHorizontal className="h-4 w-4 text-gray-500" />
<Tabs defaultValue="Projects" orientation="vertical"> }
<Tabs.List> >
{[ {/* // TODO: Show label organization and manage in option */}
{ title: 'Projects', url: `/${orgSlug}/`, icon: <FolderIcon /> }, {organizations.map((org) => (
{ <Option key={org.id} value={org.slug}>
title: 'Settings', <div className="flex items-center space-x-3">
url: `/${orgSlug}/settings`, <img
icon: <SettingsSlidersIcon />, src="/logo.svg"
}, alt="Application Logo"
].map(({ title, icon, url }, index) => ( className="h-8 w-8 rounded-lg"
<NavLink to={url} key={index}> />
<Tabs.Trigger icon={icon} value={title}> <div>
{title} <div className="text-sm font-semibold">{org.name}</div>
</Tabs.Trigger> <div className="text-xs text-gray-500">Organization</div>
</NavLink> </div>
</div>
</Option>
))} ))}
</Tabs.List> </AsyncSelect>
</Tabs> <Tabs defaultValue="Projects" orientation="vertical">
<Tabs.List>
{[
{
title: 'Projects',
url: `/${orgSlug}/`,
icon: <FolderIcon />,
},
{
title: 'Settings',
url: `/${orgSlug}/settings`,
icon: <SettingsSlidersIcon />,
},
].map(({ title, icon, url }, index) => (
<NavLink to={url} key={index}>
<Tabs.Trigger icon={icon} value={title}>
{title}
</Tabs.Trigger>
</NavLink>
))}
</Tabs.List>
</Tabs>
</div>
{/* Bottom navigation */}
<div className="flex flex-col gap-5 justify-end">
<Tabs defaultValue="Projects" orientation="vertical">
{/* // TODO: use proper link buttons */}
<Tabs.List>
<Tabs.Trigger
icon={<GlobeIcon />}
value=""
className="hidden lg:flex"
>
<a className="cursor-pointer" onClick={handleLogOut}>
Log Out
</a>
</Tabs.Trigger>
<Tabs.Trigger icon={<QuestionMarkRoundIcon />} value="">
<a className="cursor-pointer">Documentation</a>
</Tabs.Trigger>
<Tabs.Trigger icon={<LifeBuoyIcon />} value="">
<a className="cursor-pointer">Support</a>
</Tabs.Trigger>
</Tabs.List>
</Tabs>
</div>
</div> </div>
{/* Bottom navigation */} <div className="shadow-card-sm py-4 pl-4 pr-2 flex lg:hidden items-center border-t border-border-separator/[0.06]">
<div className="flex flex-col justify-end"> {user?.name && (
<Tabs defaultValue="Projects" orientation="vertical"> <div className="flex items-center flex-1 gap-3">
{/* // TODO: use proper link buttons */} <Avatar
<Tabs.List> size={44}
<Tabs.Trigger icon={<GlobeIcon />} value=""> initials={getInitials(formatAddress(user.name))}
<a className="cursor-pointer" onClick={handleLogOut}> />
Log Out <p className="text-sm tracking-[-0.006em] text-elements-high-em">
</a> {formatAddress(user.name)}
</Tabs.Trigger> </p>
<Tabs.Trigger icon={<QuestionMarkRoundIcon />} value=""> </div>
<a className="cursor-pointer">Documentation</a> )}
</Tabs.Trigger> <Button
<Tabs.Trigger icon={<LifeBuoyIcon />} value=""> variant="ghost"
<a className="cursor-pointer">Support</a> className="text-elements-low-em"
</Tabs.Trigger> onClick={handleLogOut}
</Tabs.List> >
</Tabs> <LogoutIcon />
</Button>
</div> </div>
</nav> </nav>
); );