useMobileMenuNavigation.ts75 lines · main
1'use client'
2
3import { useRouter } from 'next/router'
4import { useCallback, useState } from 'react'
5
6import { getProductMenuComponent } from './mobileProductMenuRegistry'
7import type { Route } from '@/components/ui/ui.types'
8
9const TOP_LEVEL_DIRECT_LINK_KEYS = ['editor', 'sql'] as const
10
11export function isDirectLinkAtTopLevel(route: Route): boolean {
12 return TOP_LEVEL_DIRECT_LINK_KEYS.includes(
13 route.key as (typeof TOP_LEVEL_DIRECT_LINK_KEYS)[number]
14 )
15}
16
17export function routeHasSubmenu(route: Route): boolean {
18 if (route.items && Array.isArray(route.items) && route.items.length > 0) return true
19 return getProductMenuComponent(route.key) !== null
20}
21
22interface UseMobileMenuNavigationParams {
23 currentSectionKey: string | null
24 hasCurrentProductMenu: boolean
25 onCloseSheet?: () => void
26}
27
28export function useMobileMenuNavigation({
29 currentSectionKey,
30 hasCurrentProductMenu,
31 onCloseSheet,
32}: UseMobileMenuNavigationParams) {
33 const router = useRouter()
34
35 const [viewLevel, setViewLevel] = useState<'top' | 'section'>(
36 hasCurrentProductMenu && currentSectionKey ? 'section' : 'top'
37 )
38 const [selectedSectionKey, setSelectedSectionKey] = useState<string | null>(null)
39
40 const handleTopLevelClick = useCallback(
41 (route: Route) => {
42 if (route.disabled) return
43
44 if (isDirectLinkAtTopLevel(route) && route.link) {
45 router.push(route.link)
46 onCloseSheet?.()
47 return
48 }
49
50 if (routeHasSubmenu(route)) {
51 setSelectedSectionKey(route.key)
52 setViewLevel('section')
53 return
54 }
55
56 if (route.link) {
57 router.push(route.link)
58 onCloseSheet?.()
59 }
60 },
61 [router, onCloseSheet]
62 )
63
64 const handleBackToTop = useCallback(() => {
65 setViewLevel('top')
66 setSelectedSectionKey(null)
67 }, [])
68
69 return {
70 viewLevel,
71 selectedSectionKey,
72 handleTopLevelClick,
73 handleBackToTop,
74 }
75}