useMobileMenuNavigation.ts 1.9 KB

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