Skip to content

Commit

Permalink
Apply the design of sidebar (#306)
Browse files Browse the repository at this point in the history
* Implement workspace sidebar component

* Change the width of workspace selector

* Add changing hover state when collapsing side bar
  • Loading branch information
devleejb authored Aug 24, 2024
1 parent f595c97 commit 90fb7ca
Show file tree
Hide file tree
Showing 7 changed files with 169 additions and 185 deletions.
171 changes: 96 additions & 75 deletions frontend/src/components/drawers/WorkspaceDrawer.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
import {
Divider,
Drawer,
IconButton,
ListItem,
Box,
Collapse,
List,
ListItemButton,
ListItemIcon,
ListItemSecondaryAction,
ListItemText,
Paper,
} from "@mui/material";
import { useSelector } from "react-redux";
import { MouseEventHandler, useMemo, useState } from "react";
import KeyboardArrowDownIcon from "@mui/icons-material/KeyboardArrowDown";
import KeyboardArrowUpIcon from "@mui/icons-material/KeyboardArrowUp";
import WorkspaceListPopover from "../popovers/WorkspaceListPopover";
import { useDispatch } from "react-redux";
import { useMemo, useState } from "react";
import SpaceDashboardIcon from "@mui/icons-material/SpaceDashboard";
import PeopleIcon from "@mui/icons-material/People";
import { selectWorkspace } from "../../store/workspaceSlice";
import { WorkspaceDrawerHeader } from "../layouts/WorkspaceLayout";
import { useLocation, useNavigate, useParams } from "react-router-dom";
import { DRAWER_WIDTH } from "../../constants/layout";
import { COLLAPESED_DRAWER_WIDTH, DRAWER_WIDTH } from "../../constants/layout";
import KeyboardDoubleArrowRightIcon from "@mui/icons-material/KeyboardDoubleArrowRight";
import KeyboardDoubleArrowLeftIcon from "@mui/icons-material/KeyboardDoubleArrowLeft";
import { setDrawerOpen } from "../../store/configSlice";

interface WorkspaceDrawerProps {
open: boolean;
}
Expand All @@ -27,81 +27,102 @@ function WorkspaceDrawer(props: WorkspaceDrawerProps) {
const location = useLocation();
const params = useParams();
const navigate = useNavigate();
const workspaceStore = useSelector(selectWorkspace);
const [workspaceListAnchorEl, setWorkspaceListAnchorEl] = useState<
(EventTarget & Element) | null
>(null);
const dispatch = useDispatch();
const [hovered, setHovered] = useState(false);
const currentPage = useMemo(() => {
return location.pathname.split("/")[2] ?? "main";
}, [location.pathname]);
const menuList = useMemo(() => {
return [
{
title: "Workspace",
IconComponent: SpaceDashboardIcon,
selected: currentPage === "main",
moveTo: `/${params.workspaceSlug}`,
},
{
title: "Members",
IconComponent: PeopleIcon,
selected: currentPage === "member",
moveTo: `/${params.workspaceSlug}/member`,
},
];
}, [currentPage, params.workspaceSlug]);

const handleOpenWorkspacePopover: MouseEventHandler = (event) => {
setWorkspaceListAnchorEl(event.currentTarget);
const handleDrawerOpen = () => {
dispatch(setDrawerOpen(!open));
setHovered(false);
};

const handleCloseWorkspacePopover = () => {
setWorkspaceListAnchorEl(null);
const handleMouseEnter = () => {
setHovered(true);
};

const handleNavigateToMember = () => {
navigate(`/${params.workspaceSlug}/member`);
const handleMouseLeave = () => {
setHovered(false);
};

return (
<Drawer
sx={{
width: DRAWER_WIDTH,
flexShrink: 0,
"& .MuiDrawer-paper": {
width: DRAWER_WIDTH,
boxSizing: "border-box",
},
}}
variant="persistent"
anchor="left"
open={open}
>
<WorkspaceDrawerHeader>
<ListItem disablePadding>
<ListItemButton onClick={handleOpenWorkspacePopover}>
<ListItemText
primary={workspaceStore.data?.title}
primaryTypographyProps={{
variant: "subtitle1",
noWrap: true,
}}
/>
<ListItemSecondaryAction>
<IconButton>
{workspaceListAnchorEl ? (
<KeyboardArrowUpIcon />
) : (
<KeyboardArrowDownIcon />
)}
</IconButton>
</ListItemSecondaryAction>
</ListItemButton>
<WorkspaceListPopover
open={Boolean(workspaceListAnchorEl)}
anchorEl={workspaceListAnchorEl}
onClose={handleCloseWorkspacePopover}
width={DRAWER_WIDTH - 32}
/>
</ListItem>
</WorkspaceDrawerHeader>
<Divider />
<ListItem disablePadding>
<ListItemButton
onClick={handleNavigateToMember}
selected={currentPage === "member"}
<>
<Box sx={{ width: open ? DRAWER_WIDTH : COLLAPESED_DRAWER_WIDTH }} />
<Paper
sx={{
position: "fixed",
top: 0,
left: 0,
height: "100vh",
zIndex: 10,
}}
>
<Collapse
orientation="horizontal"
in={hovered || open}
collapsedSize={COLLAPESED_DRAWER_WIDTH}
>
<ListItemIcon>
<PeopleIcon />
</ListItemIcon>
<ListItemText primary="Members" />
</ListItemButton>
</ListItem>
</Drawer>
<Box
sx={{
width: DRAWER_WIDTH,
overflow: "hidden",
}}
>
<WorkspaceDrawerHeader />
<Paper
square
elevation={0}
onMouseEnter={handleMouseEnter}
onMouseLeave={handleMouseLeave}
sx={{ backgroundColor: "transparent" }}
>
<List>
<ListItemButton onClick={handleDrawerOpen}>
<ListItemIcon>
{open ? (
<KeyboardDoubleArrowLeftIcon />
) : (
<KeyboardDoubleArrowRightIcon />
)}
</ListItemIcon>
</ListItemButton>
{menuList.map((menu, index) => (
<ListItemButton
key={index}
onClick={() => navigate(menu.moveTo)}
selected={menu.selected}
>
<ListItemIcon>
<menu.IconComponent
color={menu.selected ? "primary" : "inherit"}
/>
</ListItemIcon>
<ListItemText primary={menu.title} />
</ListItemButton>
))}
</List>
</Paper>
</Box>
</Collapse>
</Paper>
</>
);
}

Expand Down
24 changes: 0 additions & 24 deletions frontend/src/components/headers/DrawerAppBar.tsx

This file was deleted.

7 changes: 3 additions & 4 deletions frontend/src/components/headers/SettingHeader.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import { MouseEventHandler, useState } from "react";
import { Avatar, IconButton, Stack, Toolbar } from "@mui/material";
import { AppBar, Avatar, IconButton, Stack, Toolbar } from "@mui/material";
import { useSelector } from "react-redux";
import { selectUser } from "../../store/userSlice";
import ProfilePopover from "../popovers/ProfilePopover";
import CodePairIcon from "../icons/CodePairIcon";
import { useNavigate } from "react-router-dom";
import { DrawerAppBar } from "./DrawerAppBar";

function SettingHeader() {
const navigate = useNavigate();
Expand All @@ -25,7 +24,7 @@ function SettingHeader() {
};

return (
<DrawerAppBar position="fixed">
<AppBar position="fixed">
<Toolbar>
<Stack
width="100%"
Expand All @@ -46,7 +45,7 @@ function SettingHeader() {
anchorEl={profileAnchorEl}
onClose={handleCloseProfilePopover}
/>
</DrawerAppBar>
</AppBar>
);
}

Expand Down
89 changes: 46 additions & 43 deletions frontend/src/components/headers/WorkspaceHeader.tsx
Original file line number Diff line number Diff line change
@@ -1,27 +1,20 @@
import { MouseEventHandler, useState } from "react";
import { Avatar, IconButton, Stack, Toolbar, useTheme } from "@mui/material";
import MenuIcon from "@mui/icons-material/Menu";
import { AppBar, Avatar, Button, IconButton, Stack, Toolbar, Typography } from "@mui/material";
import { useSelector } from "react-redux";
import { selectUser } from "../../store/userSlice";
import ProfilePopover from "../popovers/ProfilePopover";
import KeyboardDoubleArrowLeftIcon from "@mui/icons-material/KeyboardDoubleArrowLeft";
import KeyboardDoubleArrowRightIcon from "@mui/icons-material/KeyboardDoubleArrowRight";
import CodePairIcon from "../icons/CodePairIcon";
import { useNavigate } from "react-router-dom";
import { selectWorkspace } from "../../store/workspaceSlice";
import { DrawerAppBar } from "./DrawerAppBar";
import WorkspaceListPopover from "../popovers/WorkspaceListPopover";
import { DRAWER_WIDTH } from "../../constants/layout";
import KeyboardArrowDownIcon from "@mui/icons-material/KeyboardArrowDown";
import KeyboardArrowUpIcon from "@mui/icons-material/KeyboardArrowUp";

interface WorkspaceHeaderProps {
open: boolean;
onDrawerOpen: () => void;
}

function WorkspaceHeader(props: WorkspaceHeaderProps) {
const { open, onDrawerOpen } = props;
const theme = useTheme();
const navigate = useNavigate();
function WorkspaceHeader() {
const userStore = useSelector(selectUser);
const workspaceStore = useSelector(selectWorkspace);
const [workspaceListAnchorEl, setWorkspaceListAnchorEl] = useState<
(EventTarget & Element) | null
>(null);
const [profileAnchorEl, setProfileAnchorEl] = useState<(EventTarget & Element) | null>(null);

const handleOpenProfilePopover: MouseEventHandler = (event) => {
Expand All @@ -32,52 +25,62 @@ function WorkspaceHeader(props: WorkspaceHeaderProps) {
setProfileAnchorEl(null);
};

const handleToWorkspace = () => {
navigate(`/${workspaceStore.data?.slug}`);
const handleOpenWorkspacePopover: MouseEventHandler = (event) => {
setWorkspaceListAnchorEl(event.currentTarget);
};

const handleCloseWorkspacePopover = () => {
setWorkspaceListAnchorEl(null);
};

return (
<DrawerAppBar position="fixed" open={open}>
<AppBar position="fixed">
<Toolbar>
<Stack
width="100%"
direction="row-reverse"
direction="row"
justifyContent="space-between"
alignItems="center"
>
<IconButton onClick={handleOpenProfilePopover}>
<Avatar>{userStore.data?.nickname?.charAt(0)}</Avatar>
</IconButton>
<Stack direction="row">
<IconButton
color="inherit"
aria-label="open drawer"
onClick={onDrawerOpen}
edge="start"
sx={{ mr: 2 }}
<Button
variant="text"
color="inherit"
sx={{ width: DRAWER_WIDTH, textAlign: "left" }}
onClick={handleOpenWorkspacePopover}
>
<Stack
width={1}
direction="row"
justifyContent="space-between"
alignItems="center"
>
{open ? (
theme.direction === "ltr" ? (
<KeyboardDoubleArrowLeftIcon />
) : (
<KeyboardDoubleArrowRightIcon />
)
<Typography variant="h6" component="span" noWrap>
{workspaceStore.data?.title}
</Typography>
{workspaceListAnchorEl ? (
<KeyboardArrowUpIcon />
) : (
<MenuIcon />
<KeyboardArrowDownIcon />
)}
</IconButton>
<IconButton onClick={handleToWorkspace}>
<CodePairIcon />
</IconButton>
</Stack>
</Stack>
</Button>
<WorkspaceListPopover
open={Boolean(workspaceListAnchorEl)}
anchorEl={workspaceListAnchorEl}
onClose={handleCloseWorkspacePopover}
width={DRAWER_WIDTH}
/>
<IconButton onClick={handleOpenProfilePopover}>
<Avatar>{userStore.data?.nickname?.charAt(0)}</Avatar>
</IconButton>
</Stack>
</Toolbar>
<ProfilePopover
open={Boolean(profileAnchorEl)}
anchorEl={profileAnchorEl}
onClose={handleCloseProfilePopover}
/>
</DrawerAppBar>
</AppBar>
);
}

Expand Down
Loading

0 comments on commit 90fb7ca

Please sign in to comment.