chore: update header menu style in mobile view

pull/2509/head
Steven 2 years ago
parent 4499f45b67
commit e76509a577

@ -1,12 +1,10 @@
import classNames from "classnames"; import classNames from "classnames";
import { useEffect } from "react"; import { useEffect } from "react";
import { NavLink, useLocation } from "react-router-dom"; import { NavLink } from "react-router-dom";
import useCurrentUser from "@/hooks/useCurrentUser"; import useCurrentUser from "@/hooks/useCurrentUser";
import { useLayoutStore } from "@/store/module";
import { useInboxStore } from "@/store/v1"; import { useInboxStore } from "@/store/v1";
import { Inbox_Status } from "@/types/proto/api/v2/inbox_service"; import { Inbox_Status } from "@/types/proto/api/v2/inbox_service";
import { useTranslate } from "@/utils/i18n"; import { useTranslate } from "@/utils/i18n";
import { resolution } from "@/utils/layout";
import Icon from "./Icon"; import Icon from "./Icon";
import UserBanner from "./UserBanner"; import UserBanner from "./UserBanner";
@ -19,11 +17,8 @@ interface NavLinkItem {
const Header = () => { const Header = () => {
const t = useTranslate(); const t = useTranslate();
const location = useLocation();
const layoutStore = useLayoutStore();
const user = useCurrentUser(); const user = useCurrentUser();
const inboxStore = useInboxStore(); const inboxStore = useInboxStore();
const showHeader = layoutStore.state.showHeader;
const hasUnreadInbox = inboxStore.inboxes.some((inbox) => inbox.status === Inbox_Status.UNREAD); const hasUnreadInbox = inboxStore.inboxes.some((inbox) => inbox.status === Inbox_Status.UNREAD);
useEffect(() => { useEffect(() => {
@ -42,22 +37,6 @@ const Header = () => {
}; };
}, []); }, []);
useEffect(() => {
const handleWindowResize = () => {
if (window.innerWidth < resolution.sm) {
layoutStore.setHeaderStatus(false);
} else {
layoutStore.setHeaderStatus(true);
}
};
handleWindowResize();
window.addEventListener("resize", handleWindowResize);
return () => {
window.removeEventListener("resize", handleWindowResize);
};
}, [location]);
const homeNavLink: NavLinkItem = { const homeNavLink: NavLinkItem = {
id: "header-home", id: "header-home",
path: "/", path: "/",
@ -119,44 +98,28 @@ const Header = () => {
: [exploreNavLink, signInNavLink]; : [exploreNavLink, signInNavLink];
return ( return (
<div <header className={`w-full h-full overflow-auto flex flex-col justify-start items-start py-4 z-30`}>
className={`fixed sm:sticky top-0 left-0 w-full sm:w-56 h-screen shrink-0 pointer-events-none sm:pointer-events-auto z-10 ${ <UserBanner />
showHeader && "pointer-events-auto" <div className="w-full px-2 py-2 flex flex-col justify-start items-start shrink-0 space-y-2">
}`} {navLinks.map((navLink) => (
> <NavLink
<div key={navLink.id}
className={`fixed top-0 left-0 w-full h-full max-h-screen opacity-0 pointer-events-none transition-opacity duration-300 sm:!hidden ${ to={navLink.path}
showHeader && "opacity-60 pointer-events-auto" id={navLink.id}
}`} className={({ isActive }) =>
onClick={() => layoutStore.setHeaderStatus(false)} classNames(
></div> "px-4 pr-5 py-2 rounded-2xl border flex flex-row items-center text-lg text-gray-800 dark:text-gray-300 hover:bg-white hover:border-gray-200 dark:hover:border-zinc-600 dark:hover:bg-zinc-700",
<header isActive ? "bg-white drop-shadow-sm dark:bg-zinc-700 border-gray-200 dark:border-zinc-600" : "border-transparent"
className={`relative w-56 sm:w-full h-full max-h-screen border-r sm:border-none dark:border-r-zinc-700 overflow-auto hide-scrollbar flex flex-col justify-start items-start py-4 z-30 bg-zinc-100 dark:bg-zinc-800 sm:bg-transparent sm:shadow-none transition-all duration-300 -translate-x-full sm:translate-x-0 ${ )
showHeader && "translate-x-0 shadow-2xl" }
}`} >
> <>
<UserBanner /> {navLink.icon} {navLink.title}
<div className="w-full px-2 py-2 flex flex-col justify-start items-start shrink-0 space-y-2"> </>
{navLinks.map((navLink) => ( </NavLink>
<NavLink ))}
key={navLink.id} </div>
to={navLink.path} </header>
id={navLink.id}
className={({ isActive }) =>
classNames(
"px-4 pr-5 py-2 rounded-2xl border flex flex-row items-center text-lg text-gray-800 dark:text-gray-300 hover:bg-white hover:border-gray-200 dark:hover:border-zinc-600 dark:hover:bg-zinc-700",
isActive ? "bg-white drop-shadow-sm dark:bg-zinc-700 border-gray-200 dark:border-zinc-600" : "border-transparent"
)
}
>
<>
{navLink.icon} {navLink.title}
</>
</NavLink>
))}
</div>
</header>
</div>
); );
}; };

@ -0,0 +1,37 @@
import { Drawer, IconButton } from "@mui/joy";
import { useEffect, useState } from "react";
import { useLocation } from "react-router-dom";
import Header from "./Header";
import Icon from "./Icon";
const HeaderDrawer = () => {
const location = useLocation();
const [open, setOpen] = useState(false);
useEffect(() => {
setOpen(false);
}, [location.pathname]);
const toggleDrawer = (inOpen: boolean) => (event: React.KeyboardEvent | React.MouseEvent) => {
if (event.type === "keydown" && ((event as React.KeyboardEvent).key === "Tab" || (event as React.KeyboardEvent).key === "Shift")) {
return;
}
setOpen(inOpen);
};
return (
<div>
<IconButton onClick={toggleDrawer(true)}>
<Icon.Menu className="w-5 h-auto dark:text-gray-200" />
</IconButton>
<Drawer anchor="left" open={open} onClose={toggleDrawer(false)}>
<div className="w-full px-4">
<Header />
</div>
</Drawer>
</div>
);
};
export default HeaderDrawer;

@ -1,5 +1,6 @@
import { useState } from "react"; import { useState } from "react";
import { useLayoutStore } from "@/store/module"; import { useLayoutStore } from "@/store/module";
import HeaderDrawer from "./HeaderDrawer";
import Icon from "./Icon"; import Icon from "./Icon";
interface Props { interface Props {
@ -14,12 +15,13 @@ const MobileHeader = (props: Props) => {
return ( return (
<div className="sticky top-0 pt-4 sm:pt-1 pb-1 mb-1 backdrop-blur bg-zinc-100 dark:bg-zinc-800 bg-opacity-70 flex @lg:hidden flex-row justify-between items-center w-full h-auto flex-nowrap shrink-0 z-2"> <div className="sticky top-0 pt-4 sm:pt-1 pb-1 mb-1 backdrop-blur bg-zinc-100 dark:bg-zinc-800 bg-opacity-70 flex @lg:hidden flex-row justify-between items-center w-full h-auto flex-nowrap shrink-0 z-2">
<div className="flex flex-row justify-start items-center mr-2 shrink-0 overflow-hidden"> <div className="flex flex-row justify-start items-center mr-2 shrink-0 overflow-hidden">
<div {/* <div
className="flex sm:hidden flex-row justify-center items-center w-6 h-6 mr-1 shrink-0 bg-transparent" className="flex sm:hidden flex-row justify-center items-center w-6 h-6 mr-1 shrink-0 bg-transparent"
onClick={() => layoutStore.setHeaderStatus(true)} onClick={() => layoutStore.setHeaderStatus(true)}
> >
<Icon.Menu className="w-5 h-auto dark:text-gray-200" /> <Icon.Menu className="w-5 h-auto dark:text-gray-200" />
</div> </div> */}
<HeaderDrawer />
<span <span
className="font-bold text-lg leading-10 mr-1 text-ellipsis shrink-0 cursor-pointer overflow-hidden text-gray-700 dark:text-gray-200" className="font-bold text-lg leading-10 mr-1 text-ellipsis shrink-0 cursor-pointer overflow-hidden text-gray-700 dark:text-gray-200"
onClick={() => location.reload()} onClick={() => location.reload()}

@ -9,7 +9,9 @@ function Root() {
<DemoBanner /> <DemoBanner />
</div> </div>
<div className="w-full max-w-6xl mx-auto flex flex-row justify-center items-start sm:px-4"> <div className="w-full max-w-6xl mx-auto flex flex-row justify-center items-start sm:px-4">
<Header /> <div className="hidden sm:block sticky top-0 left-0 w-56">
<Header />
</div>
<main className="w-full min-h-screen sm:max-w-[calc(100%-14rem)] flex-grow shrink flex flex-col justify-start items-start"> <main className="w-full min-h-screen sm:max-w-[calc(100%-14rem)] flex-grow shrink flex flex-col justify-start items-start">
<Outlet /> <Outlet />
</main> </main>

@ -1,5 +1,5 @@
import store, { useAppSelector } from ".."; import store, { useAppSelector } from "..";
import { setHeaderStatus, setHomeSidebarStatus } from "../reducer/layout"; import { setHomeSidebarStatus } from "../reducer/layout";
export const useLayoutStore = () => { export const useLayoutStore = () => {
const state = useAppSelector((state) => state.layout); const state = useAppSelector((state) => state.layout);
@ -8,9 +8,6 @@ export const useLayoutStore = () => {
getState: () => { getState: () => {
return store.getState().tag; return store.getState().tag;
}, },
setHeaderStatus: (showHeader: boolean) => {
store.dispatch(setHeaderStatus(showHeader));
},
setHomeSidebarStatus: (showHomeSidebar: boolean) => { setHomeSidebarStatus: (showHomeSidebar: boolean) => {
store.dispatch(setHomeSidebarStatus(showHomeSidebar)); store.dispatch(setHomeSidebarStatus(showHomeSidebar));
}, },

@ -1,23 +1,15 @@
import { createSlice, PayloadAction } from "@reduxjs/toolkit"; import { createSlice, PayloadAction } from "@reduxjs/toolkit";
interface State { interface State {
showHeader: boolean;
showHomeSidebar: boolean; showHomeSidebar: boolean;
} }
const layoutSlice = createSlice({ const layoutSlice = createSlice({
name: "layout", name: "layout",
initialState: { initialState: {
showHeader: false,
showHomeSidebar: false, showHomeSidebar: false,
} as State, } as State,
reducers: { reducers: {
setHeaderStatus: (state, action: PayloadAction<boolean>) => {
return {
...state,
showHeader: action.payload,
};
},
setHomeSidebarStatus: (state, action: PayloadAction<boolean>) => { setHomeSidebarStatus: (state, action: PayloadAction<boolean>) => {
return { return {
...state, ...state,
@ -27,6 +19,6 @@ const layoutSlice = createSlice({
}, },
}); });
export const { setHeaderStatus, setHomeSidebarStatus } = layoutSlice.actions; export const { setHomeSidebarStatus } = layoutSlice.actions;
export default layoutSlice.reducer; export default layoutSlice.reducer;

Loading…
Cancel
Save