diff --git a/apps/client/@/shadcn/components/app-sidebar.tsx b/apps/client/@/shadcn/components/app-sidebar.tsx index 858bdc7f8..6217e2b25 100644 --- a/apps/client/@/shadcn/components/app-sidebar.tsx +++ b/apps/client/@/shadcn/components/app-sidebar.tsx @@ -1,25 +1,13 @@ import * as React from "react"; import { - AudioWaveform, - BookOpen, - Bot, Building, - Command, FileText, - Frame, GalleryVerticalEnd, - Map, - PieChart, Settings, - Settings2, SquareKanban, - SquareTerminal, } from "lucide-react"; import { NavMain } from "@/shadcn/components/nav-main"; -import { NavProjects } from "@/shadcn/components/nav-projects"; -import { NavUser } from "@/shadcn/components/nav-user"; -import { TeamSwitcher } from "@/shadcn/components/team-switcher"; import { Sidebar, SidebarContent, @@ -44,8 +32,6 @@ export function AppSidebar({ ...props }: React.ComponentProps) { const { t, lang } = useTranslation("peppermint"); - const [sidebarOpen, setSidebarOpen] = useState(false); - if (!user) { location.push("/auth/login"); } diff --git a/apps/client/@/shadcn/ui/sidebar.tsx b/apps/client/@/shadcn/ui/sidebar.tsx index 29e5a678c..3065f203c 100644 --- a/apps/client/@/shadcn/ui/sidebar.tsx +++ b/apps/client/@/shadcn/ui/sidebar.tsx @@ -18,12 +18,12 @@ import { TooltipTrigger, } from "@/shadcn/ui/tooltip" -const SIDEBAR_COOKIE_NAME = "sidebar:state" +const SIDEBAR_STORAGE_KEY = "sidebar:state" const SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7 const SIDEBAR_WIDTH = "16rem" const SIDEBAR_WIDTH_MOBILE = "18rem" const SIDEBAR_WIDTH_ICON = "3rem" -const SIDEBAR_KEYBOARD_SHORTCUT = "b" +const SIDEBAR_KEYBOARD_SHORTCUT = "[" type SidebarContext = { state: "expanded" | "collapsed" @@ -69,10 +69,18 @@ const SidebarProvider = React.forwardRef< const isMobile = useIsMobile() const [openMobile, setOpenMobile] = React.useState(false) - // This is the internal state of the sidebar. - // We use openProp and setOpenProp for control from outside the component. - const [_open, _setOpen] = React.useState(defaultOpen) + // Initialize state from localStorage + const [_open, _setOpen] = React.useState(() => { + try { + const storedValue = localStorage.getItem(SIDEBAR_STORAGE_KEY) + return storedValue ? JSON.parse(storedValue) : defaultOpen + } catch (e) { + return defaultOpen + } + }) + const open = openProp ?? _open + const setOpen = React.useCallback( (value: boolean | ((value: boolean) => boolean)) => { if (setOpenProp) { @@ -81,10 +89,15 @@ const SidebarProvider = React.forwardRef< ) } - _setOpen(value) + const newValue = typeof value === "function" ? value(open) : value + _setOpen(newValue) - // This sets the cookie to keep the sidebar state. - document.cookie = `${SIDEBAR_COOKIE_NAME}=${open}; path=/; max-age=${SIDEBAR_COOKIE_MAX_AGE}` + // Save to localStorage + try { + localStorage.setItem(SIDEBAR_STORAGE_KEY, JSON.stringify(newValue)) + } catch (e) { + console.warn('Failed to save sidebar state to localStorage:', e) + } }, [setOpenProp, open] ) diff --git a/apps/client/components/CreateTicketModal/index.tsx b/apps/client/components/CreateTicketModal/index.tsx index c6c54f093..62226784a 100644 --- a/apps/client/components/CreateTicketModal/index.tsx +++ b/apps/client/components/CreateTicketModal/index.tsx @@ -1,12 +1,8 @@ -import React, { useState, useEffect, Fragment, useRef } from "react"; +import React, { useState, useEffect, Fragment } from "react"; import { Dialog, Transition, Listbox } from "@headlessui/react"; import { CheckIcon } from "@heroicons/react/20/solid"; import useTranslation from "next-translate/useTranslation"; -import { - ChevronUpDownIcon, - PlusIcon, - XMarkIcon, -} from "@heroicons/react/24/outline"; +import { ChevronUpDownIcon, XMarkIcon } from "@heroicons/react/24/outline"; import { useRouter } from "next/router"; import { useUser } from "../../store/session"; import { getCookie } from "cookies-next"; @@ -14,6 +10,7 @@ import { getCookie } from "cookies-next"; import dynamic from "next/dynamic"; import { ListPlus } from "lucide-react"; import { toast } from "@/shadcn/hooks/use-toast"; +import { useSidebar } from "@/shadcn/ui/sidebar"; const Editor = dynamic(() => import("../BlockEditor"), { ssr: false }); @@ -40,6 +37,7 @@ export default function CreateTicketModal({ keypress, setKeyPressDown }) { const token = getCookie("session"); const { user } = useUser(); + const { state } = useSidebar(); const [name, setName] = useState(""); const [company, setCompany] = useState(); @@ -151,15 +149,23 @@ export default function CreateTicketModal({ keypress, setKeyPressDown }) { <> diff --git a/apps/client/layouts/adminLayout.tsx b/apps/client/layouts/adminLayout.tsx index 50c06bce0..c72f79fb6 100644 --- a/apps/client/layouts/adminLayout.tsx +++ b/apps/client/layouts/adminLayout.tsx @@ -22,6 +22,7 @@ import { Webhook, } from "lucide-react"; import ThemeSettings from "../components/ThemeSettings"; +import { SidebarProvider } from "@/shadcn/ui/sidebar"; export default function AdminLayout({ children }: any) { const { t, lang } = useTranslation("peppermint"); @@ -86,231 +87,238 @@ export default function AdminLayout({ children }: any) { return ( !loading && user && ( -
- - - +
+ + -
- - -
- - -
- -
-
- {/* Sidebar component, swap this element with another sidebar if you like */} -
-
- {/* Workflow */} - - - Peppermint - - -
- -
-
+
-
-
-
- {/* Static sidebar for desktop */} -
- {/* Sidebar component, swap this element with another sidebar if you like */} -
-
- {/* Workflow */} - - - Peppermint - - -
- +
+ +
+ + +
+
+
+ + {/* Static sidebar for desktop */} +
+ {/* Sidebar component, swap this element with another sidebar if you like */} +
+
+ {/* Workflow */} + + + Peppermint + + +
+ +
-
-
-
- + + {/* Separator */} +
-
+ ) ); } diff --git a/apps/client/layouts/shad.tsx b/apps/client/layouts/shad.tsx index c0ae40a42..dd39e3a18 100644 --- a/apps/client/layouts/shad.tsx +++ b/apps/client/layouts/shad.tsx @@ -1,38 +1,15 @@ -import { - Combobox, - Dialog, - Disclosure, - Menu, - Transition, - } from "@headlessui/react"; - import { - Bars3Icon, - Cog6ToothIcon, - FolderIcon, - HomeIcon, - InboxStackIcon, - MagnifyingGlassIcon, - TicketIcon, - XMarkIcon, - } from "@heroicons/react/24/outline"; - import { getCookie } from "cookies-next"; + import Link from "next/link"; import { useRouter } from "next/router"; import { Fragment, useEffect, useState } from "react"; import { Button } from "@radix-ui/themes"; import useTranslation from "next-translate/useTranslation"; - import CreateTicketModal from "../components/CreateTicketModal"; import { AccountDropdown } from "../components/AccountDropdown"; import { useUser } from "../store/session"; - import ThemeSettings from "../components/ThemeSettings"; import { Bell, - Building, - Settings, - SquareActivity, - SquareKanban, } from "lucide-react"; import { AppSidebar } from "@/shadcn/components/app-sidebar"; import { SidebarProvider, SidebarTrigger } from "@/shadcn/ui/sidebar"; @@ -41,7 +18,6 @@ import { const location = useRouter(); const { loading, user, fetchUserProfile } = useUser(); - const locale = user ? user.language : "en"; const [keypressdown, setKeyPressDown] = useState(false); @@ -60,23 +36,6 @@ import { location.push("/portal"); } - const navigation = [ - // { - // name: t("create_ticket"), - // href: `/${locale}/new`, - // icon: PlusIcon, - // current: location.pathname === "/new" ? true : false, - // initial: "c", - // }, - { - name: t("sl_dashboard"), - href: `/${locale}/`, - icon: Building, - current: location.pathname === "/" ? true : false, - initial: "h", - }, - ]; - function handleKeyPress(event: any) { const pathname = location.pathname; if (