1
1
"use client" ;
2
2
3
3
import React from "react" ;
4
- import Link from "next/link" ;
5
- import { usePathname , useSearchParams } from "next/navigation" ;
4
+ import { usePathname , useSearchParams , useRouter } from "next/navigation" ;
6
5
import { Layout , Menu , ConfigProvider } from "antd" ;
7
6
import {
8
7
KeyOutlined ,
@@ -62,6 +61,11 @@ const withBase = (relativePath: string) => {
62
61
} ;
63
62
64
63
const Sidebar2 : React . FC < SidebarProps > = ( { accessToken, userRole, defaultSelectedKey, collapsed = false } ) => {
64
+ const router = useRouter ( ) ;
65
+ const pathname = usePathname ( ) ;
66
+ const searchParams = useSearchParams ( ) ;
67
+
68
+ /** ---------- Menu model ---------- */
65
69
const menuItems : MenuItem [ ] = [
66
70
{ key : "1" , page : "api-keys" , label : "Virtual Keys" , icon : < KeyOutlined style = { { fontSize : 18 } } /> } ,
67
71
{
@@ -217,9 +221,7 @@ const Sidebar2: React.FC<SidebarProps> = ({ accessToken, userRole, defaultSelect
217
221
children : item . children ?. filter ( ( child ) => ! child . roles || child . roles . includes ( userRole ) ) ,
218
222
} ) ) ;
219
223
220
- // Highlight selection based on pathname or ?page=
221
- const pathname = usePathname ( ) ;
222
- const searchParams = useSearchParams ( ) ;
224
+ /** ---------- Selection state ---------- */
223
225
const pageParam = searchParams . get ( "page" ) || undefined ;
224
226
225
227
const findMenuItemKey = ( page : string ) : string => {
@@ -244,31 +246,47 @@ const Sidebar2: React.FC<SidebarProps> = ({ accessToken, userRole, defaultSelect
244
246
? findMenuItemKey ( defaultSelectedKey )
245
247
: "1" ;
246
248
247
- // Root-only routing helper: always replace everything after the domain, honoring base path
248
- const rootWithPage = ( p : string ) => ( {
249
- pathname : getBasePath ( ) || "/" ,
250
- query : { page : p } ,
251
- } ) ;
249
+ /** ---------- Navigation helpers (SPA only) ---------- */
250
+ // Build a root URL ("/" or "/base/") with an updated ?page=...
251
+ const goTo = ( p : string ) => {
252
+ const base = getBasePath ( ) || "/" ;
253
+ const root = base . endsWith ( "/" ) ? base : `${ base } /` ;
254
+ const sp = new URLSearchParams ( typeof window !== "undefined" ? window . location . search : "" ) ;
255
+ sp . set ( "page" , p ) ;
256
+ // Use Next router for client navigation on the SAME route (no hard fetch)
257
+ router . replace ( `${ root } ?${ sp . toString ( ) } ` , { scroll : false } ) ;
258
+ } ;
252
259
253
- // Convert to AntD Menu items:
254
- // - "Virtual Keys" routes to "/<BASE>/virtual-keys"
255
- // - All other items (and children) route to "/<BASE>/?page=<page>"
260
+ // Keep the /virtual-keys path the same, but avoid route fetches/hard reloads.
261
+ const goToVirtualKeys = ( ) => {
262
+ const base = getBasePath ( ) || "/" ;
263
+ const root = base . endsWith ( "/" ) ? base : `${ base } /` ;
264
+ const sp = new URLSearchParams ( typeof window !== "undefined" ? window . location . search : "" ) ;
265
+ sp . set ( "page" , "api-keys" ) ;
266
+
267
+ // 1) Client transition to the root with ?page=api-keys so the view updates.
268
+ router . replace ( `${ root } ?${ sp . toString ( ) } ` , { scroll : false } ) ;
269
+
270
+ // 2) Cosmetic URL swap to ".../virtual-keys" without navigation (keeps path the same).
271
+ const vk = withBase ( "virtual-keys" ) ;
272
+ if ( typeof window !== "undefined" ) {
273
+ window . history . replaceState ( null , "" , vk ) ;
274
+ }
275
+ } ;
276
+
277
+ /** ---------- AntD items with onClick handlers ---------- */
256
278
const antdItems = filteredMenuItems . map ( ( item ) => {
257
279
const isVirtualKeys = item . key === "1" ;
258
- const label = isVirtualKeys ? (
259
- < Link href = { withBase ( "virtual-keys" ) } > Virtual Keys</ Link >
260
- ) : (
261
- < Link href = { rootWithPage ( item . page ) } > { item . label } </ Link >
262
- ) ;
263
-
264
280
return {
265
281
key : item . key ,
266
282
icon : item . icon ,
267
- label,
283
+ label : item . label , // plain text; click handled via onClick
284
+ onClick : ! item . children ? ( isVirtualKeys ? goToVirtualKeys : ( ) => goTo ( item . page ) ) : undefined ,
268
285
children : item . children ?. map ( ( child ) => ( {
269
286
key : child . key ,
270
287
icon : child . icon ,
271
- label : < Link href = { rootWithPage ( child . page ) } > { child . label } </ Link > ,
288
+ label : child . label ,
289
+ onClick : ( ) => goTo ( child . page ) ,
272
290
} ) ) ,
273
291
} ;
274
292
} ) ;
0 commit comments