mirror of
https://github.com/supabase/supabase.git
synced 2026-10-10 20:05:06 +03:00
www pages that use DefaultLayout are bailing out of SSR because of useSearchParams. Removing the useSearchParams opts more pages (including the pricing page) into SSR. _However_, it breaks the build because once blog pages are opted into SSR, they fail due to next-mdx-remote/codehike incompatibilities. So we also need to opt blog pages back _out_ of SSR using next/dynamic. This reproduces previous behaviour for the blog. Also had to remove suspense wrapper around everything because that was causing the content div to be streamed in a hidden later chunk <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added support for the Contribute section with improved state management integration. * **Performance Improvements** * Optimized blog post rendering with client-side enhancements. * Improved navigation and layout loading strategies. * **Refactor** * Simplified provider architecture for better maintainability. * Restructured internal component organization. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
220 lines
8.4 KiB
TypeScript
220 lines
8.4 KiB
TypeScript
'use client'
|
|
|
|
import { useIsLoggedIn, useIsUserLoading, useUser } from 'common'
|
|
import ScrollProgress from 'components/ScrollProgress'
|
|
import { getMenu } from 'data/nav'
|
|
import { DevToolbarTrigger } from 'dev-tools'
|
|
import { useSendTelemetryEvent } from 'lib/telemetry'
|
|
import Link from 'next/link'
|
|
import { usePathname } from 'next/navigation'
|
|
import React, { useState } from 'react'
|
|
import { useWindowSize } from 'react-use'
|
|
import { Button, buttonVariants, cn } from 'ui'
|
|
import { AuthenticatedDropdownMenu } from 'ui-patterns'
|
|
import {
|
|
NavigationMenu,
|
|
NavigationMenuContent,
|
|
NavigationMenuItem,
|
|
NavigationMenuLink,
|
|
NavigationMenuList,
|
|
NavigationMenuTrigger,
|
|
} from 'ui/src/components/shadcn/ui/navigation-menu'
|
|
|
|
import GitHubButton from './GitHubButton'
|
|
import HamburgerButton from './HamburgerMenu'
|
|
import MenuItem from './MenuItem'
|
|
import MobileMenu from './MobileMenu'
|
|
import RightClickBrandLogo from './RightClickBrandLogo'
|
|
import useDropdownMenu from './useDropdownMenu'
|
|
|
|
interface Props {
|
|
hideNavbar: boolean
|
|
stickyNavbar?: boolean
|
|
}
|
|
|
|
const Nav = ({ hideNavbar, stickyNavbar = true }: Props) => {
|
|
const pathname = usePathname()
|
|
const { width } = useWindowSize()
|
|
const [open, setOpen] = useState(false)
|
|
const isLoggedIn = useIsLoggedIn()
|
|
const isUserLoading = useIsUserLoading()
|
|
const user = useUser()
|
|
const menu = getMenu()
|
|
const sendTelemetryEvent = useSendTelemetryEvent()
|
|
const userMenu = useDropdownMenu(user)
|
|
|
|
const isLaunchWeekXPage = pathname === '/launch-week/x'
|
|
const isLaunchWeek12Page = pathname === '/launch-week/12'
|
|
const isLaunchWeek13Page = pathname === '/launch-week/13'
|
|
const isGAWeekSection = pathname?.startsWith('/ga-week')
|
|
const isStateOfStartupsPage = pathname?.startsWith('/state-of-startups')
|
|
const disableStickyNav =
|
|
isLaunchWeekXPage ||
|
|
isGAWeekSection ||
|
|
isLaunchWeekXPage ||
|
|
isLaunchWeek12Page ||
|
|
isLaunchWeek13Page ||
|
|
!stickyNavbar
|
|
const showLaunchWeekNavMode = (isGAWeekSection || isLaunchWeekXPage) && !open
|
|
|
|
const [scrolled, setScrolled] = React.useState(false)
|
|
React.useEffect(() => {
|
|
if (!isStateOfStartupsPage) return
|
|
const handleScroll = () => setScrolled(window.scrollY > 50)
|
|
window.addEventListener('scroll', handleScroll)
|
|
return () => window.removeEventListener('scroll', handleScroll)
|
|
}, [isStateOfStartupsPage])
|
|
|
|
const isTransparent = isStateOfStartupsPage && !scrolled && !open
|
|
|
|
React.useEffect(() => {
|
|
if (open) {
|
|
// Prevent scrolling on mount
|
|
document.body.style.overflow = 'hidden'
|
|
} else {
|
|
document.body.style.overflow = 'auto'
|
|
}
|
|
}, [open])
|
|
|
|
// Close mobile menu when desktop
|
|
React.useEffect(() => {
|
|
if (width >= 1024) setOpen(false)
|
|
}, [width])
|
|
|
|
if (hideNavbar) {
|
|
return null
|
|
}
|
|
|
|
return (
|
|
<>
|
|
<div
|
|
className={cn(
|
|
'sticky top-0 z-40 transform',
|
|
disableStickyNav && 'relative',
|
|
isStateOfStartupsPage && 'fixed left-0 right-0'
|
|
)}
|
|
style={{ transform: 'translate3d(0,0,999px)' }}
|
|
data-nav-transparent={isTransparent ? '' : undefined}
|
|
>
|
|
<div
|
|
className={cn(
|
|
'absolute inset-0 h-full w-full bg-background/90 dark:bg-background/95 transition-all duration-300',
|
|
!showLaunchWeekNavMode && !isTransparent && 'opacity-100!',
|
|
showLaunchWeekNavMode && 'bg-transparent! dark:bg-black!',
|
|
isGAWeekSection && 'dark:bg-alternative!',
|
|
isTransparent && 'bg-transparent! dark:bg-transparent! opacity-100!'
|
|
)}
|
|
/>
|
|
<nav
|
|
className={cn(
|
|
`relative z-40 border-default border-b backdrop-blur-xs transition-all duration-300`,
|
|
showLaunchWeekNavMode && 'border-muted border-b bg-transparent',
|
|
isTransparent && 'border-transparent backdrop-blur-none'
|
|
)}
|
|
>
|
|
<div className="relative flex justify-between h-16 mx-auto lg:container lg:px-16 xl:px-20">
|
|
<div className="flex items-center px-6 lg:px-0 flex-1 sm:items-stretch justify-between">
|
|
<div className="flex items-center">
|
|
<div className="flex items-center shrink-0">
|
|
<RightClickBrandLogo />
|
|
</div>
|
|
<NavigationMenu
|
|
delayDuration={0}
|
|
className="hidden pl-8 sm:space-x-4 lg:flex h-16"
|
|
viewportClassName="rounded-xl bg-background"
|
|
>
|
|
<NavigationMenuList>
|
|
{menu.primaryNav.map((menuItem) =>
|
|
menuItem.hasDropdown ? (
|
|
<NavigationMenuItem className="text-sm font-medium" key={menuItem.title}>
|
|
<NavigationMenuTrigger
|
|
className={cn(
|
|
buttonVariants({ type: 'text', size: 'small' }),
|
|
'bg-transparent! hover:text-brand-link data-open:text-brand-link! data-radix-collection-item:focus-visible:ring-2 data-radix-collection-item:focus-visible:ring-foreground-lighter data-radix-collection-item:focus-visible:text-foreground px-2 h-auto'
|
|
)}
|
|
>
|
|
{menuItem.title}
|
|
</NavigationMenuTrigger>
|
|
<NavigationMenuContent>{menuItem.dropdown}</NavigationMenuContent>
|
|
</NavigationMenuItem>
|
|
) : (
|
|
<NavigationMenuItem className="text-sm font-medium" key={menuItem.title}>
|
|
<NavigationMenuLink asChild>
|
|
<MenuItem
|
|
href={menuItem.url}
|
|
title={menuItem.title}
|
|
className="group-hover:bg-transparent text-foreground focus-visible:text-brand-link"
|
|
hoverColor="brand"
|
|
/>
|
|
</NavigationMenuLink>
|
|
</NavigationMenuItem>
|
|
)
|
|
)}
|
|
</NavigationMenuList>
|
|
</NavigationMenu>
|
|
</div>
|
|
<div className="flex items-center gap-2 opacity-0 animate-fade-in scale-100! delay-300">
|
|
<div
|
|
className={cn(
|
|
'flex items-center gap-2 transition-opacity',
|
|
isUserLoading ? 'opacity-0' : 'opacity-100'
|
|
)}
|
|
>
|
|
<DevToolbarTrigger />
|
|
<GitHubButton />
|
|
{isLoggedIn ? (
|
|
<>
|
|
<Button className="hidden lg:block" asChild>
|
|
<Link href="/dashboard/projects">Dashboard</Link>
|
|
</Button>
|
|
<AuthenticatedDropdownMenu menu={userMenu} user={user} site="www" />
|
|
</>
|
|
) : (
|
|
<>
|
|
<Button type="default" className="hidden lg:block" asChild>
|
|
<Link
|
|
href="https://supabase.com/dashboard"
|
|
onClick={() =>
|
|
sendTelemetryEvent({
|
|
action: 'sign_in_button_clicked',
|
|
properties: { buttonLocation: 'Header Nav' },
|
|
})
|
|
}
|
|
>
|
|
Sign in
|
|
</Link>
|
|
</Button>
|
|
<Button className="hidden lg:block" asChild>
|
|
<Link
|
|
href="https://supabase.com/dashboard/sign-up"
|
|
onClick={() =>
|
|
sendTelemetryEvent({
|
|
action: 'start_project_button_clicked',
|
|
properties: { buttonLocation: 'Header Nav' },
|
|
})
|
|
}
|
|
>
|
|
Start your project
|
|
</Link>
|
|
</Button>
|
|
</>
|
|
)}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<HamburgerButton
|
|
toggleFlyOut={() => setOpen(true)}
|
|
showLaunchWeekNavMode={showLaunchWeekNavMode}
|
|
/>
|
|
</div>
|
|
<MobileMenu open={open} setOpen={setOpen} menu={menu} />
|
|
</nav>
|
|
|
|
<ScrollProgress />
|
|
</div>
|
|
</>
|
|
)
|
|
}
|
|
|
|
export default Nav
|