Author sidebar nav with limited access
- Create author nav (sidebar)
// components/nav/AuthorNav
import React, { useState, useContext, useEffect } from "react";
import { Menu, Button } from "antd";
import {
PushpinOutlined,
CameraOutlined,
UserOutlined,
SettingOutlined,
} from "@ant-design/icons";
import { Layout } from "antd";
import Link from "next/link";
import { useWindowWidth } from "@react-hook/window-size";
const { Sider } = Layout;
const { SubMenu } = Menu;
const AuthorNav = () => {
// state
const [collapsed, setCollapsed] = useState(false);
const [current, setCurrent] = useState("");
useEffect(() => {
process.browser && setCurrent(window.location.pathname);
}, [process.browser && window.location.pathname]);
// console.log("##### NAV ##### ", current);
// detect window size and collapse sidebar
const onlyWidth = useWindowWidth();
useEffect(() => {
console.log("onlyWidth", onlyWidth);
if (onlyWidth < 800) {
setCollapsed(true);
} else if (onlyWidth > 800) {
setCollapsed(false);
}
}, [onlyWidth < 800]);
const activeName = (name) => `nav-link ${current === name && "active"}`;
return (
<Sider
collapsible
collapsed={collapsed}
onCollapse={() => setCollapsed(!collapsed)}
style={{
marginTop: 50,
}}
>
<Menu
// defaultSelectedKeys={["1"]}
defaultOpenKeys={["1", "6", "9", "14"]}
mode="inline"
inlineCollapsed={collapsed}
>
<Menu.Item key="19" icon={<SettingOutlined />}>
<Link href="/author">
<a className={activeName("/author")}>Dashboard</a>
</Link>
</Menu.Item>
{/* posts */}
<SubMenu key="1" icon={<PushpinOutlined />} title="Posts">
<Menu.Item key="2">
<Link href="/author/posts">
<a className={activeName("/author/posts")}>All Posts</a>
</Link>
</Menu.Item>
<Menu.Item key="3">
<Link href="/author/posts/new">
<a className={activeName("/author/posts/new")}>Add New</a>
</Link>
</Menu.Item>
<Menu.Item key="4">
<Link href="/author/categories">
<a className={activeName("/author/categories")}>Categories</a>
</Link>
</Menu.Item>
</SubMenu>
{/* media */}
<SubMenu key="6" icon={<CameraOutlined />} title="Media">
<Menu.Item key="7">
<Link href="/author/media/library">
<a className={activeName("/author/media/library")}>Library</a>
</Link>
</Menu.Item>
<Menu.Item key="8">
<Link href="/author/media/new">
<a className={activeName("/author/media/new")}>Add New</a>
</Link>
</Menu.Item>
</SubMenu>
<Menu.Item key="17" icon={<UserOutlined />}>
<Link href="/users/profile">
<a className={activeName("/users/profile")}>Profile</a>
</Link>
</Menu.Item>
</Menu>
</Sider>
);
};
export default AuthorNav;
- Create author layout
// components/layout/AuthorLayout
import { Layout } from "antd";
import AuthorNav from "../../components/nav/AuthorNav";
import { useState, useEffect, useContext } from "react";
import { SyncOutlined } from "@ant-design/icons";
import { useRouter } from "next/router";
import { AuthContext } from "../../context/auth";
import axios from "axios";
import LoadingToRedirect from "./LoadingToRedirect";
const { Content } = Layout;
const AuthorLayout = ({ children }) => {
// context
const [auth, setAuth] = useContext(AuthContext);
// hooks
const router = useRouter();
// state
const [loading, setLoading] = useState(true);
useEffect(() => {
if (auth?.token) {
getCurrentAuthor();
}
}, [auth?.token]);
const getCurrentAuthor = async () => {
try {
const { data } = await axios.get(`/current-author`);
console.log("current author", data);
if (data.ok) {
setLoading(false);
}
} catch (err) {
router.push("/");
}
};
return loading ? (
<LoadingToRedirect />
) : (
<Layout>
<AuthorNav />
<Layout>
<Content
style={{
margin: "16px 16px",
overflow: "auto",
height: "100vh",
// position: "fixed",
marginTop: 54,
}}
>
{children}
</Content>
</Layout>
</Layout>
);
};
export default AuthorLayout;
- Show role based nav link 'Dashboard' that will take users to different page based on their role
// components/nav/TopNav
const roleBasedLink = () => {
if (auth.user?.role === "Admin") {
return "/admin";
} else if (auth.user?.role === "Author") {
return "/author";
} else {
return "/subscriber";
}
};
<Menu.ItemGroup title="Management">
<Menu.Item key="setting:1">
<Link href={roleBasedLink()}>
<a>Dashboard</a>
</Link>
</Menu.Item>
</Menu.ItemGroup>