import { LOCAL_STORAGE_KEYS, useParams } from 'common' import { AppBannerWrapper } from 'components/interfaces/App/AppBannerWrapper' import { Sidebar } from 'components/interfaces/Sidebar' import { useLocalStorageQuery } from 'hooks/misc/useLocalStorage' import { useCheckLatestDeploy } from 'hooks/use-check-latest-deploy' import { useRouter } from 'next/router' import { PropsWithChildren, useEffect, useState } from 'react' import { useAppStateSnapshot } from 'state/app-state' import { ResizablePanel, ResizablePanelGroup, SidebarProvider } from 'ui' import { BannerStack } from '../ui/BannerStack/BannerStack' import { BannerStackProvider } from '../ui/BannerStack/BannerStackProvider' import { LayoutHeader } from './ProjectLayout/LayoutHeader/LayoutHeader' import { LayoutSidebar } from './ProjectLayout/LayoutSidebar' import { LayoutSidebarProvider } from './ProjectLayout/LayoutSidebar/LayoutSidebarProvider' import MobileNavigationBar from './ProjectLayout/NavigationBar/MobileNavigationBar' import { MobileSheetProvider } from './ProjectLayout/NavigationBar/MobileSheetContext' import { StudioMobileSheetNav } from './ProjectLayout/NavigationBar/StudioMobileSheetNav' import { ProjectContextProvider } from './ProjectLayout/ProjectContext' export interface DefaultLayoutProps { headerTitle?: string hideMobileMenu?: boolean } /** * Base layout for all project pages in the dashboard, rendered as the first child on all page files within a project. * * A second layout as the child to this is required, and the layout depends on which section of the dashboard the page is on. (e.g Auth - AuthLayout) * * The base layout handles rendering the following UI components: * - App banner (e.g for notices or incidents) * - Mobile navigation bar * - First level side navigation bar (e.g For navigating to Table Editor, SQL Editor, Database page, etc) */ export const DefaultLayout = ({ children, headerTitle, hideMobileMenu, }: PropsWithChildren) => { const { ref } = useParams() const router = useRouter() const appSnap = useAppStateSnapshot() const showProductMenu = !!ref && router.pathname !== '/project/[ref]' const [lastVisitedOrganization] = useLocalStorageQuery( LOCAL_STORAGE_KEYS.LAST_VISITED_ORGANIZATION, '' ) const backToDashboardURL = appSnap.lastRouteBeforeVisitingAccountPage.length > 0 ? appSnap.lastRouteBeforeVisitingAccountPage : !!lastVisitedOrganization ? `/org/${lastVisitedOrganization}` : '/organizations' useCheckLatestDeploy() const contentMinSizePercentage = 50 const contentMaxSizePercentage = 70 const [isMounted, setIsMounted] = useState(false) useEffect(() => { setIsMounted(true) }, []) // This is required to prevent layout shift when rendering resizable panels (they initially render at 50%, then shift // to whatever is specified). if (!isMounted) { return null } return (
{/* Top Banner */}
{/* Main Content Area */}
{/* Sidebar - Only show for project pages, not account pages */} {!router.pathname.startsWith('/account') && } {/* Main Content with Layout Sidebar */}
{children}
) } export default DefaultLayout