/* * Copyright (C) 2024 Aleksander WilczyƄski (aleks@alekswilc.dev) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * See LICENSE for more. */ import React, { useEffect, useRef, useState } from "react"; import { NavLink, useLocation } from "react-router-dom"; import SidebarLinkGroup from "./SidebarLinkGroup.tsx"; import { useTranslation } from "react-i18next"; import { HamburgerGoBackIcon } from "../icons/SidebarIcons.tsx"; import { ArrowIcon } from "../icons/ArrowIcon.tsx"; import { FaHome, FaClipboardList } from "react-icons/fa"; import { FaChartSimple, FaTrain, FaBuildingFlag, FaBolt } from "react-icons/fa6"; import { useAuth } from "../../../hooks/useAuth.tsx"; interface SidebarProps { sidebarOpen: boolean; setSidebarOpen: (arg: boolean) => void; } export const Sidebar = ({ sidebarOpen, setSidebarOpen }: SidebarProps) => { const location = useLocation(); const { pathname } = location; const trigger = useRef(null); const sidebar = useRef(null); const storedSidebarExpanded = localStorage.getItem("sidebar-expanded"); const [ sidebarExpanded, setSidebarExpanded ] = useState( storedSidebarExpanded === null ? false : storedSidebarExpanded === "true", ); const { t } = useTranslation(); // close on click outside useEffect(() => { const clickHandler = ({ target }: MouseEvent) => { if (!sidebar.current || !trigger.current) { return; } if ( !sidebarOpen || sidebar.current.contains(target) || trigger.current.contains(target) ) { return; } setSidebarOpen(false); }; document.addEventListener("click", clickHandler); return () => document.removeEventListener("click", clickHandler); }); // close if the esc key is pressed useEffect(() => { const keyHandler = ({ keyCode }: KeyboardEvent) => { if (!sidebarOpen || keyCode !== 27) { return; } setSidebarOpen(false); }; document.addEventListener("keydown", keyHandler); return () => document.removeEventListener("keydown", keyHandler); }); useEffect(() => { localStorage.setItem("sidebar-expanded", sidebarExpanded.toString()); if (sidebarExpanded) { document.querySelector("body")?.classList.add("sidebar-expanded"); } else { document.querySelector("body")?.classList.remove("sidebar-expanded"); } }, [ sidebarExpanded ]); const { isAdmin, username } = useAuth(); return ( ); };