import clsx from "clsx"; import { IconType } from "react-icons"; import { MdSpaceDashboard } from "react-icons/md"; import { BsFileEarmarkText, BsClockHistory, BsGraphUp, BsChevronBarRight, BsChevronBarLeft, BsShieldFill, BsCloudFill, BsCurrencyDollar, BsClipboardData, BsPeople, } from "react-icons/bs"; import { GoWorkflow } from "react-icons/go"; import { CiDumbbell } from "react-icons/ci"; import { RiLogoutBoxFill } from "react-icons/ri"; 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 usePreferencesStore from "@/stores/preferencesStore"; import { User } from "@/interfaces/user"; import useTicketsListener from "@/hooks/useTicketsListener"; import { getTypesOfUser } from "@/utils/permissions"; import usePermissions from "@/hooks/usePermissions"; import { EntityWithRoles } from "@/interfaces/entity"; import { useAllowedEntities, useAllowedEntitiesSomePermissions, } from "@/hooks/useEntityPermissions"; import { useMemo } from "react"; import { PermissionType } from "../interfaces/permissions"; interface Props { path: string; navDisabled?: boolean; focusMode?: boolean; onFocusLayerMouseEnter?: () => void; className?: string; user: User; entities?: EntityWithRoles[]; } interface NavProps { Icon: IconType; label: string; path: string; keyPath: string; disabled?: boolean; isMinimized?: boolean; badge?: number; } const Nav = ({ Icon, label, path, keyPath, disabled = false, isMinimized = false, badge, }: NavProps) => { return ( {!isMinimized && {label}} {!!badge && badge > 0 && (
{badge}
)} ); }; export default function Sidebar({ path, entities = [], navDisabled = false, focusMode = false, user, onFocusLayerMouseEnter, className, }: Props) { const router = useRouter(); const isAdmin = useMemo( () => ["developer", "admin"].includes(user?.type), [user?.type] ); const [isMinimized, toggleMinimize] = usePreferencesStore((state) => [ state.isSidebarMinimized, state.toggleSidebarMinimized, ]); const { permissions } = usePermissions(user.id); const entitiesAllowStatistics = useAllowedEntities( user, entities, "view_statistics" ); const entitiesAllowPaymentRecord = useAllowedEntities( user, entities, "view_payment_record" ); const entitiesAllowGeneration = useAllowedEntitiesSomePermissions( user, entities, [ "generate_reading", "generate_listening", "generate_writing", "generate_speaking", "generate_level", ] ); const sidebarPermissions = useMemo<{ [key: string]: boolean }>(() => { if (user.type === "developer") { return { viewExams: true, viewStats: true, viewRecords: true, viewTickets: true, viewClassrooms: true, viewSettings: true, viewPaymentRecords: true, viewGeneration: true, viewApprovalWorkflows: true, }; } const sidebarPermissions: { [key: string]: boolean } = { viewExams: false, viewStats: false, viewRecords: false, viewTickets: false, viewClassrooms: false, viewSettings: false, viewPaymentRecords: false, viewGeneration: false, viewApprovalWorkflows: false, }; if (!user || !user?.type) return sidebarPermissions; const neededPermissions = permissions.reduce((acc, curr) => { if ( ["viewExams", "viewRecords", "viewTickets"].includes(curr as string) ) { acc.push(curr); } return acc; }, [] as PermissionType[]); if ( ["student", "teacher", "developer"].includes(user.type) && neededPermissions.includes("viewExams") ) { sidebarPermissions["viewExams"] = true; } if ( getTypesOfUser(["agent"]).includes(user.type) && (entitiesAllowStatistics.length > 0 || neededPermissions.includes("viewStats")) ) { sidebarPermissions["viewStats"] = true; } if ( [ "admin", "developer", "teacher", "corporate", "mastercorporate", ].includes(user.type) && (entitiesAllowGeneration.length > 0 || isAdmin) ) { sidebarPermissions["viewGeneration"] = true; sidebarPermissions["viewApprovalWorkflows"] = true; } if ( getTypesOfUser(["agent"]).includes(user.type) && neededPermissions.includes("viewRecords") ) { sidebarPermissions["viewRecords"] = true; } if ( ["admin", "developer", "agent"].includes(user.type) && neededPermissions.includes("viewTickets") ) { sidebarPermissions["viewTickets"] = true; } if ( [ "admin", "mastercorporate", "developer", "corporate", "teacher", "student", ].includes(user.type) ) { sidebarPermissions["viewClassrooms"] = true; } if (getTypesOfUser(["student", "agent"]).includes(user.type)) { sidebarPermissions["viewSettings"] = true; } if ( ["admin", "developer", "agent", "corporate", "mastercorporate"].includes( user.type ) && entitiesAllowPaymentRecord.length > 0 ) { sidebarPermissions["viewPaymentRecords"] = true; } return sidebarPermissions; }, [ entitiesAllowGeneration.length, entitiesAllowPaymentRecord.length, entitiesAllowStatistics.length, isAdmin, permissions, user, ]); const { totalAssignedTickets } = useTicketsListener( user.id, sidebarPermissions["viewTickets"] ); const logout = async () => { axios.post("/api/logout").finally(() => { setTimeout(() => router.reload(), 500); }); }; const disableNavigation = preventNavigation(navDisabled, focusMode); return (
{isMinimized ? ( ) : ( )} {!isMinimized && ( Minimize )}
{} : logout} className={clsx( "hover:text-mti-rose flex cursor-pointer items-center gap-4 rounded-full p-4 text-black transition duration-300 ease-in-out -xl:px-4", isMinimized ? "w-fit" : "w-full min-w-[250px] px-8" )} > {!isMinimized && ( Log Out )}
{focusMode && ( )}
); }