a tool for shared writing and social publishing

store tab state in search params

+19 -3
+19 -3
components/PageLayouts/DashboardLayout.tsx
··· 1 1 "use client"; 2 - import { useState, createContext, useContext } from "react"; 2 + import { useState, createContext, useContext, useEffect } from "react"; 3 + import { useSearchParams } from "next/navigation"; 3 4 import { Header } from "../PageHeader"; 4 5 import { Footer } from "components/ActionBar/Footer"; 5 6 import { Sidebar } from "components/ActionBar/Sidebar"; ··· 134 135 publication?: string; 135 136 actions: React.ReactNode; 136 137 }) { 137 - let [tab, setTab] = useState(props.defaultTab); 138 + const searchParams = useSearchParams(); 139 + const tabParam = searchParams.get("tab"); 140 + 141 + // Initialize tab from search param if valid, otherwise use default 142 + const initialTab = tabParam && props.tabs[tabParam] ? tabParam : props.defaultTab; 143 + let [tab, setTab] = useState<keyof T>(initialTab); 144 + 145 + // Custom setter that updates both state and URL 146 + const setTabWithUrl = (newTab: keyof T) => { 147 + setTab(newTab); 148 + const params = new URLSearchParams(searchParams.toString()); 149 + params.set("tab", newTab as string); 150 + const newUrl = `${window.location.pathname}?${params.toString()}`; 151 + window.history.replaceState(null, "", newUrl); 152 + }; 153 + 138 154 let { content, controls } = props.tabs[tab]; 139 155 let { ref } = usePreserveScroll<HTMLDivElement>( 140 156 `dashboard-${props.id}-${tab as string}`, ··· 175 191 key={t} 176 192 name={t} 177 193 selected={t === tab} 178 - onSelect={() => setTab(t)} 194 + onSelect={() => setTabWithUrl(t)} 179 195 /> 180 196 ); 181 197 })}