Files
supabase/apps/docs/layouts/SiteLayout.tsx
T
8057309e51 chore: upgrade next 13 + react 18 (#17839)
* update deps + image codemod (studio)

* update next links (studio)

* update deps

* update links (ui)

* remove next-transpile-modules

* move next-themes dependency

* chore: update ConfirmDialog

* chore: remove old ConfirmModal js file. migrated to TS

* dependency wrangling

* remove empty page

* update next links (www)

* First run bump react-data-grid-v7 beta 4

* fix package-lock.json

* more deps wrangling

* update recharts

* update sentry options

* fix some broken things in www

* studio fixes

* fix graphiql

* fix studio build

* fix menu hydration

* small build error

* update turbo

* fix www typescript errors

* docs image codemod

* links codemod docs

* fix docs typescript errors

* move useConsent to ui to prevent circular deps

* Fix links

* Fix homepage

* Fix links

* move studio/ to apps/

* Revert "move studio/ to apps/"

This reverts commit 1b0a985fcb.

* disable outputFileTracingRoot

* remove outputFileTracingRoot

* fix homepage product cards

* fix PrivacySettings links

* Fix links

* Fix the build for www.

* Minor fixes for JWTGenerator.

* Fix the docs and ui tests.

* Revert codehike back to 0.8.3

* remove ConfirmAlert()

* reenable babel because mobx hates me

* fix blog image and comparison page avatar

* Fix svg errors

* update image synthax

* Fix code hike

* Move the button in a div so that it doesn't inherit its parent height and make the button look weird.

* When components are defined in a component, they get recreated on each render. This makes them unstable in certain cases and causes infinite rerenders.

* Replace the next/head usage with next/script.

* Chore/upgrade next 13 fix table editor (#18431)

* fix table editor styling and fix row deletion logic

* Fix deleting selected rows from header, and fix checkboxes not clearing up

* Fix deleting all rows when filter applied, and fix deleting all rows

* Fix grid size styling issue

* Fix TS error

* Hydration errors

* studio org pages fixes

* fix more studio links

* audit logs fixes

* dropdown icon styling fixes

* fix some images in www

* upgrade to next 14

* try new sentry wrapper for api

* see if this is even invoked

* Revert "see if this is even invoked"

This reverts commit 86c3973ffa.

* Revert "try new sentry wrapper for api"

This reverts commit f67623ebad.

* Revert "upgrade to next 14"

This reverts commit a24dd6131e.

* chore: allow node version 19/20

* Try to fix the LogTable so that it renders with the newer "react-data-grid" version.

* Fix type errors in the log renderer code.

* Fix the replication screen.

* Add the CSS for the GraphiQL.

* Fix SQL editor results rendering

* Lint

* Fix SQL editor results height issue

* Fix auth RLS not invalidating RQ when toggling RLS

* Fix database tables new/edit column regressed

* Fix migrations page empty state if migrations schema not yet created

* Fix API side panel docs temp remove postgrest text for column description PK and FK

* Fix + improve timeout handling in SQL editor

---------

Co-authored-by: Jonathan Summers-Muir <MildTomato@users.noreply.github.com>
Co-authored-by: Joshen Lim <joshenlimek@gmail.com>
Co-authored-by: Francesco Sansalvadore <f.sansalvadore@gmail.com>
Co-authored-by: Terry Sutton <saltcod@gmail.com>
Co-authored-by: Ivan Vasilov <vasilov.ivan@gmail.com>
Co-authored-by: Kevin Grüneberg <k.grueneberg1994@gmail.com>
2023-10-31 05:51:46 +00:00

374 lines
10 KiB
TypeScript

import { useTheme } from 'next-themes'
import Image from 'next/legacy/image'
import Link from 'next/link'
import NavigationMenu from '~/components/Navigation/NavigationMenu/NavigationMenu'
import TopNavBar from '~/components/Navigation/NavigationMenu/TopNavBar'
import Head from 'next/head'
import { PropsWithChildren, memo, useEffect } from 'react'
import Footer from '~/components/Navigation/Footer'
import { menuState, useMenuLevelId, useMenuMobileOpen } from '~/hooks/useMenuState'
const levelsData = {
home: {
icon: '/docs/img/icons/menu/home',
name: 'Home',
},
gettingstarted: {
icon: '/docs/img/icons/menu/getting-started',
name: 'Getting Started',
},
database: {
icon: '/docs/img/icons/menu/database',
name: 'Database',
},
api: {
icon: '/docs/img/icons/menu/rest',
name: 'REST API',
},
graphql: {
icon: '/docs/img/icons/menu/graphql',
name: 'GraphQL',
},
auth: {
icon: '/docs/img/icons/menu/auth',
name: 'Auth',
},
functions: {
icon: '/docs/img/icons/menu/functions',
name: 'Edge Functions',
},
realtime: {
icon: '/docs/img/icons/menu/realtime',
name: 'Realtime',
},
analytics: {
icon: '/docs/img/icons/menu/analytics',
name: 'Analytics',
},
storage: {
icon: '/docs/img/icons/menu/storage',
name: 'Storage',
},
ai: {
icon: '/docs/img/icons/menu/ai',
name: 'AI & Vectors',
},
supabase_cli: {
icon: '/docs/img/icons/menu/reference-cli',
name: 'Supabase CLI',
},
platform: {
icon: '/docs/img/icons/menu/platform',
name: 'Platform',
},
resources: {
icon: '/docs/img/icons/menu/resources',
name: 'Resources',
},
self_hosting: {
icon: '/docs/img/icons/menu/self-hosting',
name: 'Self-Hosting',
},
integrations: {
icon: '/docs/img/icons/menu/integrations',
name: 'Integrations',
},
reference_javascript_v1: {
icon: '/docs/img/icons/menu/reference-javascript',
name: 'Javascript Reference v1.0',
},
reference_javascript_v2: {
icon: '/docs/img/icons/menu/reference-javascript',
name: 'Javascript Reference v2.0',
},
reference_dart_v0: {
icon: '/docs/img/icons/menu/reference-dart',
name: 'Dart Reference v0.0',
},
reference_dart_v1: {
icon: '/docs/img/icons/menu/reference-dart',
name: 'Dart Reference v0.0',
},
reference_csharp_v0: {
icon: '/docs/img/icons/menu/reference-csharp',
name: 'C# Reference v0.0',
},
reference_python_v2: {
icon: '/docs/img/icons/menu/reference-python',
name: 'Python Reference v2.0',
},
reference_swift_v0: {
icon: '/docs/img/icons/menu/reference-swift',
name: 'Swift Reference v0.0',
},
reference_kotlin_v0: {
icon: '/docs/img/icons/menu/reference-kotlin',
name: 'Kotlin Reference v0.0',
},
reference_cli: {
icon: '/docs/img/icons/menu/reference-cli',
name: 'CLI Reference',
},
reference_api: {
icon: '/docs/img/icons/menu/reference-api',
name: 'Management API Reference',
},
reference_self_hosting_auth: {
icon: '/docs/img/icons/menu/reference-auth',
name: 'Auth Server Reference',
},
reference_self_hosting_storage: {
icon: '/docs/img/icons/menu/reference-storage',
name: 'Storage Server Reference',
},
reference_self_hosting_realtime: {
icon: '/docs/img/icons/menu/reference-realtime',
name: 'Realtime Server Reference',
},
reference_self_hosting_analytics: {
icon: '/docs/img/icons/menu/reference-analytics',
name: 'Analytics Server Reference',
},
reference_self_hosting_functions: {
icon: '/docs/img/icons/menu/reference-functions',
name: 'Functions Server Reference',
},
}
const MobileHeader = memo(function MobileHeader() {
const mobileMenuOpen = useMenuMobileOpen()
const menuLevel = useMenuLevelId()
return (
<div
className={[
'transition-all ease-out z-10',
'top-0',
mobileMenuOpen && 'absolute',
'flex items-center h-[40px]',
mobileMenuOpen ? 'gap-0' : 'gap-3',
].join(' ')}
>
<button
className={['mr-2', mobileMenuOpen && 'mt-0.5'].join(' ')}
onClick={() => menuState.setMenuMobileOpen(!mobileMenuOpen)}
>
<div
className={[
'space-y-1 group cursor-pointer relative',
mobileMenuOpen ? 'w-4 h-4' : 'w-4 h-[8px]',
].join(' ')}
>
<span
className={[
'transition-all ease-out block w-4 h-px bg-scale-900 group-hover:bg-scale-1200',
!mobileMenuOpen ? 'w-4' : 'absolute rotate-45 top-[6px]',
].join(' ')}
></span>
<span
className={[
'transition-all ease-out block h-px bg-scale-900 group-hover:bg-scale-1200',
!mobileMenuOpen ? 'w-3 group-hover:w-4' : 'absolute w-4 -rotate-45 top-[2px]',
].join(' ')}
></span>
</div>
</button>
<div className={[].join(' ')}>
<img
src={menuLevel ? levelsData[menuLevel].icon + '.svg' : levelsData['home'].icon + '.svg'}
className={[
'transition-all duration-200',
mobileMenuOpen ? 'invisible w-0 h-0' : 'w-4 h-4',
].join(' ')}
/>
</div>
<span
className={[
'transition-all duration-200',
'text-scale-1200',
mobileMenuOpen ? 'text-xs' : 'text-sm',
].join(' ')}
>
{mobileMenuOpen
? 'Close'
: menuLevel
? levelsData[menuLevel].name
: levelsData['home'].name}
</span>
</div>
)
})
const MobileMenuBackdrop = memo(function MobileMenuBackdrop() {
const mobileMenuOpen = useMenuMobileOpen()
useEffect(() => {
window.addEventListener('resize', (e: UIEvent) => {
const w = e.target as Window
if (mobileMenuOpen && w.innerWidth >= 1024) {
menuState.setMenuMobileOpen(!mobileMenuOpen)
}
})
return () => {
window.removeEventListener('resize', () => {})
}
}, [mobileMenuOpen])
return (
<div
className={[
'h-full',
'left-0',
'right-0',
'z-10',
'backdrop-blur-sm backdrop-filter bg-white-1200 dark:bg-scale-200/90',
mobileMenuOpen ? 'absolute h-full w-full top-0 left-0' : 'hidden h-0',
// always hide on desktop
'lg:hidden',
].join(' ')}
onClick={() => menuState.setMenuMobileOpen(!mobileMenuOpen)}
></div>
)
})
const HeaderLogo = memo(function HeaderLogo() {
const { resolvedTheme } = useTheme()
return (
<Link href="/" className="px-10 flex items-center gap-2">
<Image
className="cursor-pointer"
src={resolvedTheme === 'dark' ? '/docs/supabase-dark.svg' : '/docs/supabase-light.svg'}
width={96}
height={24}
alt="Supabase Logo"
/>
<span className="font-mono text-sm font-medium text-brand">DOCS</span>
</Link>
)
})
const Container = memo(function Container(props: PropsWithChildren) {
const mobileMenuOpen = useMenuMobileOpen()
return (
<div
// #docs-content-container is used by layout to scroll to top
id="docs-content-container"
className={[
// 'overflow-x-auto',
'w-full h-screen transition-all ease-out',
// 'absolute lg:relative',
mobileMenuOpen
? '!w-auto ml-[75%] sm:ml-[50%] md:ml-[33%] overflow-hidden'
: 'overflow-auto',
// desktop override any margin styles
'lg:ml-0',
].join(' ')}
>
<div className="flex flex-col relative">{props.children}</div>
</div>
)
})
const NavContainer = memo(function NavContainer() {
const mobileMenuOpen = useMenuMobileOpen()
return (
<div
className={[
// 'hidden',
'absolute lg:relative',
mobileMenuOpen ? 'w-[75%] sm:w-[50%] md:w-[33%] left-0' : 'w-0 -left-[280px]',
'lg:w-[420px] !lg:left-0',
// desktop override any left styles
'lg:left-0',
'transition-all',
'top-0',
'h-screen',
'flex flex-col ml-0',
].join(' ')}
>
<div
className={[
'top-0',
'relative',
'w-auto',
'border-r overflow-auto h-screen',
'backdrop-blur backdrop-filter bg-white-1200 dark:bg-scale-200',
'flex flex-col',
].join(' ')}
>
<div className="top-0 sticky z-10">
<div>
<div>
<div
className={[
'hidden lg:flex lg:height-auto',
'pt-8 bg-scale-200 flex-col gap-8',
].join(' ')}
>
<HeaderLogo />
</div>
<div className="h-4 bg-scale-200 w-full"></div>
<div className="bg-gradient-to-b from-scale-200 to-transparent h-4 w-full"></div>
</div>
</div>
</div>
<div
className={[
'transition-all ease-out duration-200',
'absolute left-0 right-0 h-screen',
'px-5 pl-5 py-16',
'top-[0px]',
'bg-scale-200',
// desktop styles
'lg:relative lg:top-0 lg:left-0 lg:pb-10 lg:px-10 lg:pt-0 lg:flex',
'lg:opacity-100 lg:visible',
].join(' ')}
>
<NavigationMenu />
</div>
</div>
</div>
)
})
const SiteLayout = ({ children }: PropsWithChildren<{}>) => {
return (
<>
<Head>
<title>Supabase Docs</title>
</Head>
<main>
<div className="flex flex-row h-screen">
<NavContainer />
<Container>
<div className={['lg:sticky top-0 z-10 overflow-hidden'].join(' ')}>
<TopNavBar />
</div>
<div
className={[
'sticky transition-all top-0',
'z-10',
'backdrop-blur backdrop-filter bg-white-1200 dark:bg-scale-200',
].join(' ')}
>
<div className={['lg:hidden', 'px-5 ', 'border-b z-10'].join(' ')}>
<MobileHeader />
</div>
</div>
<div className="grow">
{children}
<Footer />
</div>
<MobileMenuBackdrop />
</Container>
</div>
</main>
</>
)
}
export default SiteLayout