♻️ refactor: use useMemo to render organization and sidebar menu

This commit is contained in:
Wahyu Kurniawan 2024-03-06 13:22:17 +07:00
parent 90295fd620
commit 287fe360d3
No known key found for this signature in database
GPG Key ID: 040A1549143A8E33
2 changed files with 48 additions and 39 deletions

View File

@ -1,4 +1,4 @@
import React, { useCallback, useEffect, useState } from 'react'; import React, { useCallback, useEffect, useMemo, useState } from 'react';
import { NavLink, useNavigate, useParams } from 'react-router-dom'; import { NavLink, useNavigate, useParams } from 'react-router-dom';
import { Organization, User } from 'gql-client'; import { Organization, User } from 'gql-client';
import { motion } from 'framer-motion'; import { motion } from 'framer-motion';
@ -10,12 +10,10 @@ import { useGQLClient } from 'context/GQLClientContext';
import AsyncSelect from 'components/shared/AsyncSelect'; import AsyncSelect from 'components/shared/AsyncSelect';
import { import {
ChevronGrabberHorizontal, ChevronGrabberHorizontal,
FolderIcon,
GlobeIcon, GlobeIcon,
LifeBuoyIcon, LifeBuoyIcon,
LogoutIcon, LogoutIcon,
QuestionMarkRoundIcon, QuestionMarkRoundIcon,
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';
@ -25,6 +23,7 @@ import { getInitials } from 'utils/geInitials';
import { Button } from 'components/shared/Button'; import { Button } from 'components/shared/Button';
import { cn } from 'utils/classnames'; import { cn } from 'utils/classnames';
import { useMediaQuery } from 'usehooks-ts'; import { useMediaQuery } from 'usehooks-ts';
import { SIDEBAR_MENU } from './constants';
interface SidebarProps { interface SidebarProps {
mobileOpen?: boolean; mobileOpen?: boolean;
@ -61,11 +60,39 @@ export const Sidebar = ({ mobileOpen }: SidebarProps) => {
setSelectedOrgSlug(orgSlug); setSelectedOrgSlug(orgSlug);
}, [orgSlug]); }, [orgSlug]);
const renderOrganizations = useMemo(() => {
return organizations.map((org) => (
<Option key={org.id} value={org.slug}>
<div className="flex items-center space-x-3">
<img
src="/logo.svg"
alt="Application Logo"
className="h-8 w-8 rounded-lg"
/>
<div>
<div className="text-sm font-semibold">{org.name}</div>
<div className="text-xs text-gray-500">Organization</div>
</div>
</div>
</Option>
));
}, [organizations]);
const renderMenu = useMemo(() => {
return SIDEBAR_MENU(orgSlug).map(({ title, icon, url }, index) => (
<NavLink to={url} key={index}>
<Tabs.Trigger icon={icon} value={title}>
{title}
</Tabs.Trigger>
</NavLink>
));
}, [orgSlug]);
const handleLogOut = useCallback(() => { const handleLogOut = useCallback(() => {
disconnect(); disconnect();
navigate('/login'); navigate('/login');
}, [disconnect, navigate]); }, [disconnect, navigate]);
console.log(isDesktop);
return ( return (
<motion.nav <motion.nav
initial={{ x: -320 }} initial={{ x: -320 }}
@ -116,43 +143,10 @@ export const Sidebar = ({ mobileOpen }: SidebarProps) => {
} }
> >
{/* // TODO: Show label organization and manage in option */} {/* // TODO: Show label organization and manage in option */}
{organizations.map((org) => ( {renderOrganizations}
<Option key={org.id} value={org.slug}>
<div className="flex items-center space-x-3">
<img
src="/logo.svg"
alt="Application Logo"
className="h-8 w-8 rounded-lg"
/>
<div>
<div className="text-sm font-semibold">{org.name}</div>
<div className="text-xs text-gray-500">Organization</div>
</div>
</div>
</Option>
))}
</AsyncSelect> </AsyncSelect>
<Tabs defaultValue="Projects" orientation="vertical"> <Tabs defaultValue="Projects" orientation="vertical">
<Tabs.List> <Tabs.List>{renderMenu}</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> </Tabs>
</div> </div>
{/* Bottom navigation */} {/* Bottom navigation */}

View File

@ -0,0 +1,15 @@
import React from 'react';
import { FolderIcon, SettingsSlidersIcon } from 'components/shared/CustomIcon';
export const SIDEBAR_MENU = (orgSlug?: string) => [
{
title: 'Projects',
url: `/${orgSlug}/`,
icon: <FolderIcon />,
},
{
title: 'Settings',
url: `/${orgSlug}/settings`,
icon: <SettingsSlidersIcon />,
},
];