Skip to content

Commit

Permalink
chore: save sidebar state to localstorage
Browse files Browse the repository at this point in the history
  • Loading branch information
potts99 committed Nov 3, 2024
1 parent 5e94900 commit 15ed4dc
Show file tree
Hide file tree
Showing 5 changed files with 251 additions and 279 deletions.
14 changes: 0 additions & 14 deletions apps/client/@/shadcn/components/app-sidebar.tsx
Original file line number Diff line number Diff line change
@@ -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,
Expand All @@ -44,8 +32,6 @@ export function AppSidebar({ ...props }: React.ComponentProps<typeof Sidebar>) {

const { t, lang } = useTranslation("peppermint");

const [sidebarOpen, setSidebarOpen] = useState(false);

if (!user) {
location.push("/auth/login");
}
Expand Down
29 changes: 21 additions & 8 deletions apps/client/@/shadcn/ui/sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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) {
Expand All @@ -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]
)
Expand Down
32 changes: 19 additions & 13 deletions apps/client/components/CreateTicketModal/index.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,16 @@
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";

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 });

Expand All @@ -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<any>();
Expand Down Expand Up @@ -151,15 +149,23 @@ export default function CreateTicketModal({ keypress, setKeyPressDown }) {
<>
<button
onClick={() => setOpen(true)}
className="group gap-x-3 w-[93%] mx-3 p-0.5 flex rounded-md text-xs font-semibold leading-6 hover:bg-secondary"
className={
state === "expanded"
? "group gap-x-3 w-[93%] mt-2 mx-3 p-0.5 flex rounded-md text-xs font-semibold leading-6 hover:bg-secondary outline-none"
: "flex mx-auto p-1.5 rounded-md text-xs font-semibold leading-6 hover:bg-secondary outline-none"
}
>
<ListPlus className="h-4 w-4 ml-1 shrink-0 mt-1" aria-hidden="true" />
<span className="whitespace-nowrap">New Issue</span>
<div className="flex w-full justify-end float-right">
<span className="flex h-6 w-6 shrink-0 items-center bg-transparent border-none justify-center text-md font-medium">
c
</span>
</div>
{state === "expanded" && (
<>
<span className="whitespace-nowrap">New Issue</span>
<div className="flex w-full justify-end float-right">
<span className="flex h-6 w-6 shrink-0 items-center bg-transparent border-none justify-center text-md font-medium">
c
</span>
</div>
</>
)}
</button>

<Transition.Root show={open} as={Fragment}>
Expand Down
Loading

0 comments on commit 15ed4dc

Please sign in to comment.