Author dashboard with limited sidebar menu 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>