Remove organization switcher from side bar #9
@ -1,13 +1,7 @@
|
|||||||
import { Link } from 'react-router-dom';
|
|
||||||
import { Heading } from './shared/Heading';
|
import { Heading } from './shared/Heading';
|
||||||
|
|
||||||
interface LogoProps {
|
export const Logo = () => {
|
||||||
orgSlug?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const Logo = ({ orgSlug }: LogoProps) => {
|
|
||||||
return (
|
return (
|
||||||
<Link to={`/${orgSlug}`}>
|
|
||||||
<div className="flex items-center gap-3 px-0 lg:px-2">
|
<div className="flex items-center gap-3 px-0 lg:px-2">
|
||||||
<img
|
<img
|
||||||
src="/logo.svg"
|
src="/logo.svg"
|
||||||
@ -18,6 +12,5 @@ export const Logo = ({ orgSlug }: LogoProps) => {
|
|||||||
Snowball
|
Snowball
|
||||||
</Heading>
|
</Heading>
|
||||||
</div>
|
</div>
|
||||||
</Link>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { useCallback, useEffect, useMemo, useState } from 'react';
|
import { useCallback, useEffect, useState } from 'react';
|
||||||
import { NavLink, useNavigate, useParams } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
import { Organization, User } from 'gql-client';
|
import { User } from 'gql-client';
|
||||||
import { motion } from 'framer-motion';
|
import { motion } from 'framer-motion';
|
||||||
import { useDisconnect } from 'wagmi';
|
import { useDisconnect } from 'wagmi';
|
||||||
|
|
||||||
@ -19,8 +19,6 @@ 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';
|
|
||||||
import { UserSelect } from 'components/shared/UserSelect';
|
|
||||||
import { BASE_URL } from 'utils/constants';
|
import { BASE_URL } from 'utils/constants';
|
||||||
|
|
||||||
interface SidebarProps {
|
interface SidebarProps {
|
||||||
@ -28,7 +26,6 @@ interface SidebarProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const Sidebar = ({ mobileOpen }: SidebarProps) => {
|
export const Sidebar = ({ mobileOpen }: SidebarProps) => {
|
||||||
const { orgSlug } = useParams();
|
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const client = useGQLClient();
|
const client = useGQLClient();
|
||||||
const isDesktop = useMediaQuery('(min-width: 960px)');
|
const isDesktop = useMediaQuery('(min-width: 960px)');
|
||||||
@ -45,46 +42,6 @@ export const Sidebar = ({ mobileOpen }: SidebarProps) => {
|
|||||||
fetchUser();
|
fetchUser();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const [selectedOrgSlug, setSelectedOrgSlug] = useState(orgSlug);
|
|
||||||
const [organizations, setOrganizations] = useState<Organization[]>([]);
|
|
||||||
|
|
||||||
const fetchUserOrganizations = useCallback(async () => {
|
|
||||||
const { organizations } = await client.getOrganizations();
|
|
||||||
setOrganizations(organizations);
|
|
||||||
}, [orgSlug]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
fetchUserOrganizations();
|
|
||||||
setSelectedOrgSlug(orgSlug);
|
|
||||||
}, [orgSlug]);
|
|
||||||
|
|
||||||
const formattedSelected = useMemo(() => {
|
|
||||||
const selected = organizations.find((org) => org.slug === selectedOrgSlug);
|
|
||||||
return {
|
|
||||||
value: selected?.slug ?? '',
|
|
||||||
label: selected?.name ?? '',
|
|
||||||
imgSrc: '/logo.svg',
|
|
||||||
};
|
|
||||||
}, [organizations, selectedOrgSlug, orgSlug]);
|
|
||||||
|
|
||||||
const formattedSelectOptions = useMemo(() => {
|
|
||||||
return organizations.map((org) => ({
|
|
||||||
value: org.slug,
|
|
||||||
label: org.name,
|
|
||||||
imgSrc: '/logo.svg',
|
|
||||||
}));
|
|
||||||
}, [organizations, selectedOrgSlug, orgSlug]);
|
|
||||||
|
|
||||||
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(async () => {
|
const handleLogOut = useCallback(async () => {
|
||||||
await fetch(`${BASE_URL}/auth/logout`, {
|
await fetch(`${BASE_URL}/auth/logout`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
@ -115,18 +72,10 @@ export const Sidebar = ({ mobileOpen }: SidebarProps) => {
|
|||||||
>
|
>
|
||||||
{/* Logo */}
|
{/* Logo */}
|
||||||
<div className="hidden lg:flex">
|
<div className="hidden lg:flex">
|
||||||
<Logo orgSlug={orgSlug} />
|
<Logo />
|
||||||
</div>
|
|
||||||
{/* Switch organization */}
|
|
||||||
<div className="flex flex-1 flex-col gap-4">
|
|
||||||
<UserSelect
|
|
||||||
value={formattedSelected}
|
|
||||||
options={formattedSelectOptions}
|
|
||||||
/>
|
|
||||||
<Tabs defaultValue="Projects" orientation="vertical">
|
|
||||||
<Tabs.List>{renderMenu}</Tabs.List>
|
|
||||||
</Tabs>
|
|
||||||
</div>
|
</div>
|
||||||
|
{/* This element ensures the space between logo and navigation */}
|
||||||
|
<div className="flex-1"></div>
|
||||||
{/* Bottom navigation */}
|
{/* Bottom navigation */}
|
||||||
<div className="flex flex-col gap-5 justify-end">
|
<div className="flex flex-col gap-5 justify-end">
|
||||||
<Tabs defaultValue="Projects" orientation="vertical">
|
<Tabs defaultValue="Projects" orientation="vertical">
|
||||||
|
@ -9,7 +9,7 @@ import {
|
|||||||
import { Sidebar } from 'components/shared/Sidebar';
|
import { Sidebar } from 'components/shared/Sidebar';
|
||||||
import { OctokitProvider } from 'context/OctokitContext';
|
import { OctokitProvider } from 'context/OctokitContext';
|
||||||
import { ComponentPropsWithoutRef, useEffect, useState } from 'react';
|
import { ComponentPropsWithoutRef, useEffect, useState } from 'react';
|
||||||
import { Outlet, useParams } from 'react-router-dom';
|
import { Outlet } from 'react-router-dom';
|
||||||
import { AnimatePresence, motion } from 'framer-motion';
|
import { AnimatePresence, motion } from 'framer-motion';
|
||||||
import { cn } from 'utils/classnames';
|
import { cn } from 'utils/classnames';
|
||||||
import { useMediaQuery } from 'usehooks-ts';
|
import { useMediaQuery } from 'usehooks-ts';
|
||||||
@ -22,7 +22,6 @@ export const DashboardLayout = ({
|
|||||||
className,
|
className,
|
||||||
...props
|
...props
|
||||||
}: DashboardLayoutProps) => {
|
}: DashboardLayoutProps) => {
|
||||||
const { orgSlug } = useParams();
|
|
||||||
const isDesktop = useMediaQuery('(min-width: 960px)');
|
const isDesktop = useMediaQuery('(min-width: 960px)');
|
||||||
|
|
||||||
const [isSidebarOpen, setIsSidebarOpen] = useState(false);
|
const [isSidebarOpen, setIsSidebarOpen] = useState(false);
|
||||||
@ -45,7 +44,7 @@ export const DashboardLayout = ({
|
|||||||
>
|
>
|
||||||
{/* Header on mobile */}
|
{/* Header on mobile */}
|
||||||
<div className="flex lg:hidden items-center px-4 py-2.5 justify-between">
|
<div className="flex lg:hidden items-center px-4 py-2.5 justify-between">
|
||||||
<Logo orgSlug={orgSlug} />
|
<Logo />
|
||||||
<div className="flex items-center gap-0.5">
|
<div className="flex items-center gap-0.5">
|
||||||
<AnimatePresence>
|
<AnimatePresence>
|
||||||
{isSidebarOpen ? (
|
{isSidebarOpen ? (
|
||||||
|
Loading…
Reference in New Issue
Block a user