|
|
|
|
@@ -12,24 +12,23 @@ import {
|
|
|
|
|
BsCloudFill,
|
|
|
|
|
BsCurrencyDollar,
|
|
|
|
|
BsClipboardData,
|
|
|
|
|
BsFileLock,
|
|
|
|
|
BsPeople,
|
|
|
|
|
} from "react-icons/bs";
|
|
|
|
|
import { CiDumbbell } from "react-icons/ci";
|
|
|
|
|
import { RiLogoutBoxFill } from "react-icons/ri";
|
|
|
|
|
import { SlPencil } from "react-icons/sl";
|
|
|
|
|
import { FaAward } from "react-icons/fa";
|
|
|
|
|
import Link from "next/link";
|
|
|
|
|
import { useRouter } from "next/router";
|
|
|
|
|
import axios from "axios";
|
|
|
|
|
import FocusLayer from "@/components/FocusLayer";
|
|
|
|
|
import { preventNavigation } from "@/utils/navigation.disabled";
|
|
|
|
|
import { useEffect, useState } from "react";
|
|
|
|
|
import usePreferencesStore from "@/stores/preferencesStore";
|
|
|
|
|
import { User } from "@/interfaces/user";
|
|
|
|
|
import useTicketsListener from "@/hooks/useTicketsListener";
|
|
|
|
|
import { checkAccess, getTypesOfUser } from "@/utils/permissions";
|
|
|
|
|
import usePermissions from "@/hooks/usePermissions";
|
|
|
|
|
import { EntityWithRoles } from "@/interfaces/entity";
|
|
|
|
|
import { useAllowedEntitiesSomePermissions } from "@/hooks/useEntityPermissions";
|
|
|
|
|
|
|
|
|
|
interface Props {
|
|
|
|
|
path: string;
|
|
|
|
|
navDisabled?: boolean;
|
|
|
|
|
@@ -37,6 +36,7 @@ interface Props {
|
|
|
|
|
onFocusLayerMouseEnter?: () => void;
|
|
|
|
|
className?: string;
|
|
|
|
|
user: User;
|
|
|
|
|
entities?: EntityWithRoles[]
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
interface NavProps {
|
|
|
|
|
@@ -76,7 +76,15 @@ const Nav = ({ Icon, label, path, keyPath, disabled = false, isMinimized = false
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export default function Sidebar({ path, navDisabled = false, focusMode = false, user, onFocusLayerMouseEnter, className }: Props) {
|
|
|
|
|
export default function Sidebar({
|
|
|
|
|
path,
|
|
|
|
|
entities = [],
|
|
|
|
|
navDisabled = false,
|
|
|
|
|
focusMode = false,
|
|
|
|
|
user,
|
|
|
|
|
onFocusLayerMouseEnter,
|
|
|
|
|
className
|
|
|
|
|
}: Props) {
|
|
|
|
|
const router = useRouter();
|
|
|
|
|
|
|
|
|
|
const [isMinimized, toggleMinimize] = usePreferencesStore((state) => [state.isSidebarMinimized, state.toggleSidebarMinimized]);
|
|
|
|
|
@@ -84,6 +92,10 @@ export default function Sidebar({ path, navDisabled = false, focusMode = false,
|
|
|
|
|
const { totalAssignedTickets } = useTicketsListener(user.id);
|
|
|
|
|
const { permissions } = usePermissions(user.id);
|
|
|
|
|
|
|
|
|
|
const entitiesAllowGeneration = useAllowedEntitiesSomePermissions(user, entities, [
|
|
|
|
|
"generate_reading", "generate_listening", "generate_writing", "generate_speaking", "generate_level"
|
|
|
|
|
])
|
|
|
|
|
|
|
|
|
|
const logout = async () => {
|
|
|
|
|
axios.post("/api/logout").finally(() => {
|
|
|
|
|
setTimeout(() => router.reload(), 500);
|
|
|
|
|
@@ -104,9 +116,6 @@ export default function Sidebar({ path, navDisabled = false, focusMode = false,
|
|
|
|
|
{checkAccess(user, ["student", "teacher", "developer"], permissions, "viewExams") && (
|
|
|
|
|
<Nav disabled={disableNavigation} Icon={BsFileEarmarkText} label="Exams" path={path} keyPath="/exam" isMinimized={isMinimized} />
|
|
|
|
|
)}
|
|
|
|
|
{checkAccess(user, ["student", "teacher", "developer"], permissions, "viewExercises") && (
|
|
|
|
|
<Nav disabled={disableNavigation} Icon={BsPencil} label="Exercises" path={path} keyPath="/exercises" isMinimized={isMinimized} />
|
|
|
|
|
)}
|
|
|
|
|
{checkAccess(user, getTypesOfUser(["agent"]), permissions, "viewStats") && (
|
|
|
|
|
<Nav disabled={disableNavigation} Icon={BsGraphUp} label="Stats" path={path} keyPath="/stats" isMinimized={isMinimized} />
|
|
|
|
|
)}
|
|
|
|
|
@@ -157,7 +166,7 @@ export default function Sidebar({ path, navDisabled = false, focusMode = false,
|
|
|
|
|
badge={totalAssignedTickets}
|
|
|
|
|
/>
|
|
|
|
|
)}
|
|
|
|
|
{checkAccess(user, ["developer", "admin", "corporate", "mastercorporate"]) && (
|
|
|
|
|
{entitiesAllowGeneration.length > 0 && (
|
|
|
|
|
<Nav
|
|
|
|
|
disabled={disableNavigation}
|
|
|
|
|
Icon={BsCloudFill}
|
|
|
|
|
@@ -169,40 +178,29 @@ export default function Sidebar({ path, navDisabled = false, focusMode = false,
|
|
|
|
|
)}
|
|
|
|
|
</div>
|
|
|
|
|
<div className="-xl:flex flex-col gap-3 xl:hidden">
|
|
|
|
|
<Nav disabled={disableNavigation} Icon={MdSpaceDashboard} label="Dashboard" path={path} keyPath="/" isMinimized={true} />
|
|
|
|
|
<Nav disabled={disableNavigation} Icon={BsFileEarmarkText} label="Exams" path={path} keyPath="/exam" isMinimized={true} />
|
|
|
|
|
<Nav disabled={disableNavigation} Icon={BsPencil} label="Exercises" path={path} keyPath="/exercises" isMinimized={true} />
|
|
|
|
|
<Nav disabled={disableNavigation} Icon={MdSpaceDashboard} label="Dashboard" path={path} keyPath="/" isMinimized />
|
|
|
|
|
<Nav disabled={disableNavigation} Icon={BsFileEarmarkText} label="Exams" path={path} keyPath="/exam" isMinimized />
|
|
|
|
|
{checkAccess(user, getTypesOfUser(["agent"]), permissions, "viewStats") && (
|
|
|
|
|
<Nav disabled={disableNavigation} Icon={BsGraphUp} label="Stats" path={path} keyPath="/stats" isMinimized={true} />
|
|
|
|
|
<Nav disabled={disableNavigation} Icon={BsGraphUp} label="Stats" path={path} keyPath="/stats" isMinimized />
|
|
|
|
|
)}
|
|
|
|
|
{checkAccess(user, getTypesOfUser(["agent"]), permissions, "viewRecords") && (
|
|
|
|
|
<Nav disabled={disableNavigation} Icon={BsClockHistory} label="Record" path={path} keyPath="/record" isMinimized={true} />
|
|
|
|
|
<Nav disabled={disableNavigation} Icon={BsClockHistory} label="Record" path={path} keyPath="/record" isMinimized />
|
|
|
|
|
)}
|
|
|
|
|
{checkAccess(user, getTypesOfUser(["agent"]), permissions, "viewRecords") && (
|
|
|
|
|
<Nav disabled={disableNavigation} Icon={CiDumbbell} label="Training" path={path} keyPath="/training" isMinimized={true} />
|
|
|
|
|
<Nav disabled={disableNavigation} Icon={CiDumbbell} label="Training" path={path} keyPath="/training" isMinimized />
|
|
|
|
|
)}
|
|
|
|
|
{checkAccess(user, getTypesOfUser(["student"])) && (
|
|
|
|
|
<Nav disabled={disableNavigation} Icon={BsShieldFill} label="Settings" path={path} keyPath="/settings" isMinimized={true} />
|
|
|
|
|
<Nav disabled={disableNavigation} Icon={BsShieldFill} label="Settings" path={path} keyPath="/settings" isMinimized />
|
|
|
|
|
)}
|
|
|
|
|
{checkAccess(user, ["developer"]) && (
|
|
|
|
|
<>
|
|
|
|
|
<Nav
|
|
|
|
|
disabled={disableNavigation}
|
|
|
|
|
Icon={BsCloudFill}
|
|
|
|
|
label="Generation"
|
|
|
|
|
path={path}
|
|
|
|
|
keyPath="/generation"
|
|
|
|
|
isMinimized={true}
|
|
|
|
|
/>
|
|
|
|
|
<Nav
|
|
|
|
|
disabled={disableNavigation}
|
|
|
|
|
Icon={BsFileLock}
|
|
|
|
|
label="Permissions"
|
|
|
|
|
path={path}
|
|
|
|
|
keyPath="/permissions"
|
|
|
|
|
isMinimized={true}
|
|
|
|
|
/>
|
|
|
|
|
</>
|
|
|
|
|
{entitiesAllowGeneration.length > 0 && (
|
|
|
|
|
<Nav
|
|
|
|
|
disabled={disableNavigation}
|
|
|
|
|
Icon={BsCloudFill}
|
|
|
|
|
label="Generation"
|
|
|
|
|
path={path}
|
|
|
|
|
keyPath="/generation"
|
|
|
|
|
isMinimized
|
|
|
|
|
/>
|
|
|
|
|
)}
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|