useMobileMenuNavigation.ts75 lines · main
| 1 | 'use client' |
| 2 | |
| 3 | import { useRouter } from 'next/router' |
| 4 | import { useCallback, useState } from 'react' |
| 5 | |
| 6 | import { getProductMenuComponent } from './mobileProductMenuRegistry' |
| 7 | import type { Route } from '@/components/ui/ui.types' |
| 8 | |
| 9 | const TOP_LEVEL_DIRECT_LINK_KEYS = ['editor', 'sql'] as const |
| 10 | |
| 11 | export 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 | |
| 17 | export 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 | |
| 22 | interface UseMobileMenuNavigationParams { |
| 23 | currentSectionKey: string | null |
| 24 | hasCurrentProductMenu: boolean |
| 25 | onCloseSheet?: () => void |
| 26 | } |
| 27 | |
| 28 | export 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 | } |