feat: add state and scroll position of sidemenu to sess storage

This commit is contained in:
Thomas Bishop 2025-07-25 15:22:21 +01:00
parent 4927d91d00
commit a772a6567e
4 changed files with 93 additions and 52 deletions

View file

@ -7,17 +7,44 @@ import { useQuery } from "@tanstack/react-query"
import api from "../api/eolas-api"
import { Link } from "react-router"
import { useState, useRef, useEffect } from "react"
export default function EntriesListSidebar() {
const scrollRef = useRef(null)
const [isOpen, setIsOpen] = useState(() => {
if (typeof window !== "undefined") {
const saved = sessionStorage.getItem("entries_list_sidebar_open")
return saved ? JSON.parse(saved) : false
}
return false
})
const { data: entries, isLoading } = useQuery({
queryKey: ["entries_list"],
queryFn: () => api.get("/entries").then((res) => res.data),
})
console.log(entries)
useEffect(() => {
sessionStorage.setItem("entries_list_sidebar_open", JSON.stringify(isOpen))
}, [isOpen])
useEffect(() => {
const savedScroll = sessionStorage.getItem("entries_list_sidebar_scroll_position")
if (savedScroll && scrollRef.current) {
scrollRef.current.scrollTop = parseInt(savedScroll)
}
}, [entries])
const handleScroll = () => {
if (scrollRef.current) {
sessionStorage.setItem("entries_list_sidebar_scroll_position", scrollRef.current.scrollTop)
}
}
return (
<Collapsible className="group/collapsible">
<Collapsible open={isOpen} onOpenChange={setIsOpen} className="group/collapsible">
<SidebarMenuItem key="entries">
<CollapsibleTrigger asChild>
<CollapsibleTrigger asChild className="rounded-none">
<SidebarMenuButton asChild className="rounded-none">
<a href="#">
<FileText />
@ -30,7 +57,7 @@ export default function EntriesListSidebar() {
</SidebarMenuButton>
</CollapsibleTrigger>
<CollapsibleContent>
<div className="max-h-100 overflow-y-auto">
<div ref={scrollRef} onScroll={handleScroll} className="max-h-100 overflow-y-auto">
<SidebarMenuSub>
{entries?.data.map((item, i) => (
<SidebarMenuItem key={i} asChild>

View file

@ -1,29 +1,48 @@
import { Tags, ChevronRight } from "lucide-react"
import {
SidebarMenuButton,
SidebarMenuItem,
SidebarMenuSub,
SidebarMenuSubButton,
SidebarMenuSubItem,
} from "@/components/ui/sidebar"
import { SidebarMenuButton, SidebarMenuItem, SidebarMenuSub } from "@/components/ui/sidebar"
import { Collapsible, CollapsibleTrigger } from "@radix-ui/react-collapsible"
import { CollapsibleContent } from "../components/ui/collapsible"
import { useQuery } from "@tanstack/react-query"
import api from "../api/eolas-api"
import { Badge } from "./ui/badge"
import { Link } from "react-router"
import { useState, useRef, useEffect } from "react"
export default function TagListSidebar() {
const { data: tags, isLoading } = useQuery({
const scrollRef = useRef(null)
const [isOpen, setIsOpen] = useState(() => {
if (typeof window !== "undefined") {
const saved = sessionStorage.getItem("tags_list_sidebar_open")
return saved ? JSON.parse(saved) : false
}
return false
})
const { data: tags } = useQuery({
queryKey: ["tag_list"],
queryFn: () => api.get("/tags").then((res) => res.data),
})
console.log(tags)
useEffect(() => {
sessionStorage.setItem("tags_list_sidebar_open", JSON.stringify(isOpen))
}, [isOpen])
useEffect(() => {
const savedScroll = sessionStorage.getItem("tags_list_sidebar_open")
if (savedScroll && scrollRef.current) {
scrollRef.current.scrollTop = parseInt(savedScroll)
}
}, [tags])
const handleScroll = () => {
if (scrollRef.current) {
sessionStorage.setItem("tags_list_sidebar_open", scrollRef.current.scrollTop)
}
}
return (
<Collapsible className="group/collapsible">
<Collapsible open={isOpen} onOpenChange={setIsOpen} className="group/collapsible">
<SidebarMenuItem key="tags">
<CollapsibleTrigger asChild>
<SidebarMenuButton asChild className="rounded-none">
@ -33,13 +52,12 @@ export default function TagListSidebar() {
<Badge className="ml-0" variant="secondary">
{tags?.count}
</Badge>
<ChevronRight className="ml-auto transition-transform duration-200 group-data-[state=open]/collapsible:rotate-90" />
</a>
</SidebarMenuButton>
</CollapsibleTrigger>
<CollapsibleContent>
<div className="max-h-100 overflow-y-auto">
<div ref={scrollRef} onScroll={handleScroll} className="max-h-100 overflow-y-auto">
<SidebarMenuSub>
{tags?.data.map((item, i) => (
<SidebarMenuItem key={i} asChild>
@ -51,10 +69,6 @@ export default function TagListSidebar() {
</SidebarMenuItem>
))}
</SidebarMenuSub>
{/*
*/}
</div>
</CollapsibleContent>
</SidebarMenuItem>

View file

@ -7,8 +7,8 @@ export default function Entry() {
<Main>
<div className="flex-1 flex flex-col overflow-auto">
<div className="@container/main flex flex-col">
<div className="p-4 lg:p-6 flex flex-1">
<div className="border w-full">
<div className="flex flex-1">
<div className="border-l-none w-full">
<div className="border-b py-2 px-4 lg:px-6 bg-sidebar">
<h2 className="scroll-m-20 font-semibold">
<span>{entry?.replace(/_/g, " ")}</span>

View file

@ -2,7 +2,7 @@ import AppHeader from "@/components/AppHeader"
import { AppSidebar } from "@/containers/AppSidebar"
import { SidebarInset, SidebarProvider } from "@/components/ui/sidebar"
export default function Main({ children, pageTitle = undefined }) {
export default function Main({ children, pageTitle }) {
return (
<>
<SidebarProvider variant="inset">