Added a capability to minimize the sidebar

This commit is contained in:
Tiago Ribeiro
2023-09-03 14:41:10 +01:00
parent 0013d86ef8
commit 5263cc260d
4 changed files with 68 additions and 22 deletions

View File

@@ -1,7 +1,7 @@
import clsx from "clsx";
import {IconType} from "react-icons";
import {MdSpaceDashboard} from "react-icons/md";
import {BsFileEarmarkText, BsClockHistory, BsPencil, BsGraphUp} from "react-icons/bs";
import {BsFileEarmarkText, BsClockHistory, BsPencil, BsGraphUp, BsChevronBarRight, BsChevronBarLeft} from "react-icons/bs";
import {RiLogoutBoxFill} from "react-icons/ri";
import {SlPencil} from "react-icons/sl";
import {FaAward} from "react-icons/fa";
@@ -10,6 +10,8 @@ import {useRouter} from "next/router";
import axios from "axios";
import FocusLayer from "@/components/FocusLayer";
import {preventNavigation} from "@/utils/navigation.disabled";
import {useState} from "react";
import usePreferencesStore from "@/stores/preferencesStore";
interface Props {
path: string;
navDisabled?: boolean;
@@ -24,23 +26,28 @@ interface NavProps {
path: string;
keyPath: string;
disabled?: boolean;
isMinimized?: boolean;
}
const Nav = ({Icon, label, path, keyPath, disabled = false}: NavProps) => (
const Nav = ({Icon, label, path, keyPath, disabled = false, isMinimized = false}: NavProps) => (
<Link
href={!disabled ? keyPath : ""}
className={clsx(
"p-4 px-8 rounded-full flex gap-4 items-center cursor-pointer text-gray-500 hover:bg-mti-purple-light hover:text-white transition duration-300 ease-in-out",
"p-4 rounded-full flex gap-4 items-center cursor-pointer text-gray-500 hover:bg-mti-purple-light hover:text-white",
"transition-all duration-300 ease-in-out",
path === keyPath && "bg-mti-purple-light text-white",
isMinimized ? "w-fit" : "w-full min-w-[250px] px-8",
)}>
<Icon size={20} />
<span className="text-lg font-semibold">{label}</span>
<Icon size={24} />
{!isMinimized && <span className="text-lg font-semibold">{label}</span>}
</Link>
);
export default function Sidebar({path, navDisabled = false, focusMode = false, onFocusLayerMouseEnter, className}: Props) {
const router = useRouter();
const [isMinimized, toggleMinimize] = usePreferencesStore((state) => [state.isSidebarMinimized, state.toggleSidebarMinimized]);
const logout = async () => {
axios.post("/api/logout").finally(() => {
setTimeout(() => router.reload(), 500);
@@ -50,25 +57,43 @@ export default function Sidebar({path, navDisabled = false, focusMode = false, o
const disableNavigation = preventNavigation(navDisabled, focusMode);
return (
<section className={clsx("h-full flex bg-transparent flex-col justify-between w-1/6 px-4 py-4 pb-8 relative", className)}>
<section
className={clsx(
"h-full flex bg-transparent flex-col justify-between px-4 py-4 pb-8 relative",
isMinimized ? "w-fit" : "w-1/6",
className,
)}>
<div className="flex flex-col gap-3">
<Nav disabled={disableNavigation} Icon={MdSpaceDashboard} label="Dashboard" path={path} keyPath="/" />
<Nav disabled={disableNavigation} Icon={BsFileEarmarkText} label="Exams" path={path} keyPath="/exam" />
<Nav disabled={disableNavigation} Icon={BsPencil} label="Exercises" path={path} keyPath="/exercises" />
<Nav disabled={disableNavigation} Icon={BsGraphUp} label="Stats" path={path} keyPath="/stats" />
<Nav disabled={disableNavigation} Icon={BsClockHistory} label="Record" path={path} keyPath="/record" />
<Nav disabled={disableNavigation} Icon={MdSpaceDashboard} label="Dashboard" path={path} keyPath="/" isMinimized={isMinimized} />
<Nav disabled={disableNavigation} Icon={BsFileEarmarkText} label="Exams" path={path} keyPath="/exam" isMinimized={isMinimized} />
<Nav disabled={disableNavigation} Icon={BsPencil} label="Exercises" path={path} keyPath="/exercises" isMinimized={isMinimized} />
<Nav disabled={disableNavigation} Icon={BsGraphUp} label="Stats" path={path} keyPath="/stats" isMinimized={isMinimized} />
<Nav disabled={disableNavigation} Icon={BsClockHistory} label="Record" path={path} keyPath="/record" isMinimized={isMinimized} />
</div>
<div
role="button"
tabIndex={1}
onClick={focusMode ? () => {} : logout}
className={clsx(
"p-4 px-8 rounded-full flex gap-4 items-center cursor-pointer text-black hover:text-mti-rose transition duration-300 ease-in-out",
"absolute bottom-8",
)}>
<RiLogoutBoxFill size={20} />
<span className="text-lg font-medium">Log Out</span>
<div className="flex flex-col gap-0 absolute bottom-12">
<div
role="button"
tabIndex={1}
onClick={toggleMinimize}
className={clsx(
"p-4 rounded-full flex gap-4 items-center cursor-pointer text-black hover:text-mti-rose transition duration-300 ease-in-out",
isMinimized ? "w-fit" : "w-full min-w-[250px] px-8",
)}>
{isMinimized ? <BsChevronBarRight size={24} /> : <BsChevronBarLeft size={24} />}
{!isMinimized && <span className="text-lg font-medium">Minimize</span>}
</div>
<div
role="button"
tabIndex={1}
onClick={focusMode ? () => {} : logout}
className={clsx(
"p-4 rounded-full flex gap-4 items-center cursor-pointer text-black hover:text-mti-rose transition duration-300 ease-in-out",
isMinimized ? "w-fit" : "w-full min-w-[250px] px-8",
)}>
<RiLogoutBoxFill size={24} />
{!isMinimized && <span className="text-lg font-medium">Log Out</span>}
</div>
</div>
{focusMode && <FocusLayer onFocusLayerMouseEnter={onFocusLayerMouseEnter} />}
</section>