mirror of
https://github.com/supabase/supabase.git
synced 2026-10-15 14:19:11 +03:00
add banners
This commit is contained in:
1 parent
400ef6f70f
commit
be2c3fe8cd
18 files changed
+105
-128
No files matched your search
@@ -11,6 +11,7 @@ import { QueryClientProvider } from './data/queryClient.client'
|
||||
import { PageTelemetry } from './telemetry/telemetry.client'
|
||||
import { ScrollRestoration } from './ui/helpers.scroll.client'
|
||||
import { ThemeSandbox } from './ui/theme.client'
|
||||
import { PromoToast } from 'ui-patterns'
|
||||
|
||||
/**
|
||||
* Global providers that wrap the entire app
|
||||
@@ -27,6 +28,7 @@ function GlobalProviders({ children }: PropsWithChildren) {
|
||||
<CommandProvider>
|
||||
<div className="flex flex-col">
|
||||
<SiteLayout>
|
||||
<PromoToast />
|
||||
{children}
|
||||
<DocsCommandMenu />
|
||||
</SiteLayout>
|
||||
|
||||
@@ -1,78 +0,0 @@
|
||||
import { useEffect, useState } from 'react'
|
||||
|
||||
import Link from 'next/link'
|
||||
import { useRouter } from 'next/router'
|
||||
import { PropsWithChildren } from 'react'
|
||||
import _announcement from './data/Announcement.json'
|
||||
import { X } from 'lucide-react'
|
||||
|
||||
export interface AnnouncementProps {
|
||||
show: boolean
|
||||
text: string
|
||||
launchDate: string
|
||||
link: string
|
||||
badge?: string
|
||||
}
|
||||
|
||||
const announcement = _announcement as AnnouncementProps
|
||||
|
||||
interface AnnouncementComponentProps {
|
||||
show?: boolean
|
||||
className?: string
|
||||
link?: string
|
||||
}
|
||||
|
||||
const Announcement = ({
|
||||
show = true,
|
||||
className,
|
||||
children,
|
||||
link,
|
||||
}: PropsWithChildren<AnnouncementComponentProps>) => {
|
||||
const [hidden, setHidden] = useState(true)
|
||||
|
||||
const router = useRouter()
|
||||
const isLaunchWeekSection = router.pathname.includes('launch-week')
|
||||
|
||||
// override to hide announcement
|
||||
if (!show || !announcement.show) return null
|
||||
|
||||
// construct the key for the announcement, based on the title text
|
||||
const announcementKey = 'announcement_' + announcement.text.replace(/ /g, '')
|
||||
|
||||
// window.localStorage is kept inside useEffect
|
||||
// to prevent error
|
||||
useEffect(function () {
|
||||
if (!window.localStorage.getItem(announcementKey)) {
|
||||
return setHidden(false)
|
||||
}
|
||||
}, [])
|
||||
|
||||
function handleClose(event: any) {
|
||||
event.stopPropagation()
|
||||
|
||||
window.localStorage.setItem(announcementKey, 'hidden')
|
||||
return setHidden(true)
|
||||
}
|
||||
|
||||
// Always show if on LW section
|
||||
if (!isLaunchWeekSection && hidden) {
|
||||
return null
|
||||
} else {
|
||||
return (
|
||||
<div className={['relative z-40 w-full cursor-pointer', className].join(' ')}>
|
||||
{!isLaunchWeekSection && (
|
||||
<div
|
||||
className="absolute z-50 right-4 flex h-full items-center opacity-100 text-white transition-opacity hover:opacity-90"
|
||||
onClick={handleClose}
|
||||
>
|
||||
<X size={16} />
|
||||
</div>
|
||||
)}
|
||||
{children}
|
||||
<Link href={link ?? announcement.link} className="absolute inset-0 z-40"></Link>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default Announcement
|
||||
@@ -1,7 +0,0 @@
|
||||
{
|
||||
"show": true,
|
||||
"text": "Supabase Launch Week 13: Day 1",
|
||||
"launchDate": "2023-08-07T09:00:00.000-07:00",
|
||||
"link": "https://supabase.com/launch-week#day-1",
|
||||
"badge": "Get your ticket"
|
||||
}
|
||||
@@ -3,6 +3,7 @@ import Link from 'next/link'
|
||||
import { Button } from 'ui'
|
||||
import SectionContainer from '~/components/Layouts/SectionContainer'
|
||||
import { useSendTelemetryEvent } from '~/lib/telemetry'
|
||||
import AnnouncementBadge from '../Announcement/Badge'
|
||||
|
||||
const Hero = () => {
|
||||
const sendTelemetryEvent = useSendTelemetryEvent()
|
||||
@@ -15,6 +16,13 @@ const Hero = () => {
|
||||
<div className="mx-auto max-w-2xl lg:col-span-6 lg:flex lg:items-center justify-center text-center">
|
||||
<div className="relative z-10 lg:h-auto pt-[90px] lg:pt-[90px] lg:min-h-[300px] flex flex-col items-center justify-center sm:mx-auto md:w-3/4 lg:mx-0 lg:w-full gap-4 lg:gap-8">
|
||||
<div className="flex flex-col items-center">
|
||||
<div className="z-40 w-full flex justify-center -mt-4 lg:-mt-12 mb-8">
|
||||
<AnnouncementBadge
|
||||
url="/launch-week"
|
||||
badge="Launch Week 14"
|
||||
announcement="Claim ticket"
|
||||
/>
|
||||
</div>
|
||||
<h1 className="text-foreground text-4xl sm:text-5xl sm:leading-none lg:text-7xl">
|
||||
<span className="block text-foreground">Build in a weekend</span>
|
||||
<span className="text-brand block md:ml-0">Scale to millions</span>
|
||||
|
||||
@@ -64,8 +64,10 @@ export const LW14_DATE = '31 March — 4 April / 7am PT'
|
||||
export const LW14_LAUNCH_DATE = '2025-03-31T07:00:00.000-07:00'
|
||||
export const LW14_LAUNCH_DATE_END = '2025-04-04T23:59:59.000-07:00'
|
||||
export const LW14_TITLE = 'Launch Week 14'
|
||||
export const LW14_TWEET_TEXT = 'Launch Week 14 is just around the corner at @supabase. \nClaim your ticket and stay tuned for all the announcements! \n#launchweek'
|
||||
export const LW14_TWEET_TEXT_PLATINUM = 'Just conquered a platinum @supabase Launch Week 14 ticket. Share twice to get one! \n#launchweek'
|
||||
export const LW14_TWEET_TEXT =
|
||||
'Launch Week 14 is just around the corner at @supabase. \nClaim your ticket and stay tuned for all the announcements! \n#launchweek'
|
||||
export const LW14_TWEET_TEXT_PLATINUM =
|
||||
'Just conquered a platinum @supabase Launch Week 14 ticket. Share twice to get one! \n#launchweek'
|
||||
export const LW14_TWEET_TEXT_SECRET = `Found the secret golden ticket for @supabase's Launch Week 14. \nCan you find it? \n#launchweek`
|
||||
export const LW14_URL = `${SITE_ORIGIN}/launch-week`
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ import MetaFaviconsPagesRouter, {
|
||||
import { WwwCommandMenu } from '~/components/CommandMenu'
|
||||
import { API_URL, APP_NAME, DEFAULT_META_DESCRIPTION } from '~/lib/constants'
|
||||
import useDarkLaunchWeeks from '../hooks/useDarkLaunchWeeks'
|
||||
import { LW14Announcement } from 'ui-patterns/Banners/LW14Announcement'
|
||||
|
||||
export default function App({ Component, pageProps }: AppProps) {
|
||||
const router = useRouter()
|
||||
@@ -93,6 +94,7 @@ export default function App({ Component, pageProps }: AppProps) {
|
||||
>
|
||||
<TooltipProvider delayDuration={0}>
|
||||
<CommandProvider>
|
||||
<LW14Announcement />
|
||||
<SonnerToaster position="top-right" />
|
||||
<Component {...pageProps} />
|
||||
<WwwCommandMenu />
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 382 KiB |
@@ -0,0 +1,36 @@
|
||||
import Countdown from 'react-countdown'
|
||||
import { CountdownWidget } from '../CountdownWidget'
|
||||
|
||||
const CountdownComponent = ({
|
||||
date,
|
||||
showCard = true,
|
||||
}: {
|
||||
date: string | number | Date
|
||||
showCard?: boolean
|
||||
}) => {
|
||||
if (!date) return null
|
||||
|
||||
const renderer = ({ days, hours, minutes, seconds, completed }: any) => {
|
||||
if (completed) {
|
||||
// Render a completed state
|
||||
return null
|
||||
} else {
|
||||
// Render countdown
|
||||
return (
|
||||
<CountdownWidget
|
||||
days={days}
|
||||
hours={hours}
|
||||
minutes={minutes}
|
||||
seconds={seconds}
|
||||
showCard={showCard}
|
||||
className='text-emerald-400 [text-shadow:0_0_15px_rgba(52,211,153,0.8)]'
|
||||
dividerClassName='text-emerald-400 [text-shadow:0_0_15px_rgba(52,211,153,0.8)]'
|
||||
/>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return <Countdown date={new Date(date)} renderer={renderer} />
|
||||
}
|
||||
|
||||
export default CountdownComponent
|
||||
@@ -0,0 +1,10 @@
|
||||
import { Announcement } from 'ui/src/layout/banners'
|
||||
import LW14Banner from './LW14Banner'
|
||||
|
||||
export const LW14Announcement = () => {
|
||||
return (
|
||||
<Announcement show={true} announcementKey="announcement_lw14_countdown">
|
||||
<LW14Banner />
|
||||
</Announcement>
|
||||
)
|
||||
}
|
||||
+8
-9
@@ -2,22 +2,21 @@
|
||||
|
||||
import Link from 'next/link'
|
||||
import { usePathname } from 'next/navigation'
|
||||
import { Button } from '../../../components/Button/Button'
|
||||
import { cn } from '../../../lib/utils/cn'
|
||||
import announcement from '../data/Announcement.json'
|
||||
import announcement from './data.json'
|
||||
import Image from 'next/image'
|
||||
import { useTheme } from 'next-themes'
|
||||
// import Countdown from './Countdown'
|
||||
import { Button } from 'ui/src/components/Button'
|
||||
import { cn } from 'ui'
|
||||
|
||||
const LW13BGDark =
|
||||
const LW14BGDark =
|
||||
'https://xguihxuzqibwxjnimxev.supabase.co/storage/v1/object/public/images/launch-week/lw13/assets/lw13-banner-dark.png?t=2024-11-22T23%3A10%3A37.646Z'
|
||||
const LW13BGLight =
|
||||
const LW14BGLight =
|
||||
'https://xguihxuzqibwxjnimxev.supabase.co/storage/v1/object/public/images/launch-week/lw13/assets/lw13-banner-light.png?t=2024-11-22T23%3A10%3A37.646Z'
|
||||
|
||||
export function LW13CountdownBanner() {
|
||||
export function LW14Banner() {
|
||||
const pathname = usePathname()
|
||||
const { resolvedTheme } = useTheme()
|
||||
const bgImage = resolvedTheme?.includes('dark') ? LW13BGDark : LW13BGLight
|
||||
const bgImage = resolvedTheme?.includes('dark') ? LW14BGDark : LW14BGLight
|
||||
const isHomePage = pathname === '/'
|
||||
const isLaunchWeekPage =
|
||||
pathname === '/launch-week' || pathname?.includes('/launch-week/tickets/')
|
||||
@@ -55,4 +54,4 @@ export function LW13CountdownBanner() {
|
||||
)
|
||||
}
|
||||
|
||||
export default LW13CountdownBanner
|
||||
export default LW14Banner
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"text": "Launch Week 14",
|
||||
"launchDate": "2025-03-31T07:00:00.000-08:00",
|
||||
"link": "/launch-week",
|
||||
"cta": "Learn more"
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ interface CountdownWidgetProps {
|
||||
seconds?: string
|
||||
showCard?: boolean
|
||||
className?: string
|
||||
dividerClassName?: string
|
||||
size?: 'small' | 'large'
|
||||
}
|
||||
|
||||
@@ -18,11 +19,12 @@ export function CountdownWidget({
|
||||
seconds,
|
||||
showCard = true,
|
||||
className,
|
||||
dividerClassName,
|
||||
size,
|
||||
}: CountdownWidgetProps) {
|
||||
const isLarge = size === 'large'
|
||||
const Colon = () => (
|
||||
<span className={cn('text-xs mx-px text-foreground-lighter', isLarge && 'text-lg')}>:</span>
|
||||
<span className={cn('text-xs mx-px text-foreground-lighter', isLarge && 'text-lg', dividerClassName)}>:</span>
|
||||
)
|
||||
|
||||
return (
|
||||
|
||||
@@ -7,17 +7,16 @@ import { cn } from 'ui/src/lib/utils/cn'
|
||||
import { Button } from 'ui/src/components/Button/Button'
|
||||
import { LOCAL_STORAGE_KEYS } from 'common'
|
||||
import { useTheme } from 'next-themes'
|
||||
import announcement from 'ui/src/layout/banners/data/Announcement.json'
|
||||
import announcement from '../Banners/data.json'
|
||||
import CountdownComponent from '../Banners/Countdown'
|
||||
import "./styles.css"
|
||||
|
||||
const LW13BGDark =
|
||||
'https://xguihxuzqibwxjnimxev.supabase.co/storage/v1/object/public/images/launch-week/lw13/assets/lw13-bg-dark.png?t=2024-11-22T23%3A10%3A37.646Z'
|
||||
const LW13BGLight =
|
||||
'https://xguihxuzqibwxjnimxev.supabase.co/storage/v1/object/public/images/launch-week/lw13/assets/lw13-bg-light.png?t=2024-11-22T23%3A10%3A37.646Z'
|
||||
const SITE_ORIGIN = process.env.NEXT_PUBLIC_VERCEL_ENV === 'production' || process.env.NEXT_PUBLIC_VERCEL_ENV === 'preview' ? "" : "http://localhost:3000"
|
||||
const LW14BG = `${SITE_ORIGIN}/images/launchweek/14/promo-banner-bg.png`
|
||||
|
||||
const PromoToast = () => {
|
||||
const [visible, setVisible] = useState(false)
|
||||
const { resolvedTheme } = useTheme()
|
||||
const bgImage = resolvedTheme?.includes('dark') ? LW13BGDark : LW13BGLight
|
||||
|
||||
useEffect(() => {
|
||||
const shouldHide =
|
||||
@@ -43,20 +42,19 @@ const PromoToast = () => {
|
||||
visible && 'opacity-100 translate-y-0'
|
||||
)}
|
||||
>
|
||||
<div className="relative z-10 text-foreground-lighter leading-3 flex flex-col font-mono uppercase tracking-wide w-full text-xs">
|
||||
<div className="text-foreground uppercase tracking-wider text-lg -mb-1">Launch Week 13</div>
|
||||
<p className="text-foreground-lighter uppercase tracking-wider text-xl md:text-lg leading-snug">
|
||||
2—6 Dec
|
||||
<div className="relative z-10 text-foreground-lighter uppercase flex flex-col text-sm w-full font-mono mb-2">
|
||||
<span className="mb-1">31 APR - 04 MAR / 7AM PT</span>
|
||||
|
||||
<p className="relative z-10 text-foreground flex flex-col text-xl w-full leading-7 font-['Departure_Mono']">
|
||||
Launch Week 14
|
||||
</p>
|
||||
</div>
|
||||
<div className="relative z-10 text-foreground-lighter flex flex-col text-sm uppercase font-mono tracking-widest w-full -mt-1">
|
||||
A week of new features
|
||||
<CountdownComponent date={new Date(announcement.launchDate)} showCard={false} />
|
||||
</div>
|
||||
|
||||
<div className="relative z-10 flex items-center space-x-2 mt-2">
|
||||
<div className="relative z-10 flex items-center space-x-2">
|
||||
<Button asChild type="secondary">
|
||||
<Link target="_blank" rel="noreferrer" href={`https://supabase.com${announcement.link}`}>
|
||||
Learn more
|
||||
Claim ticket
|
||||
</Link>
|
||||
</Button>
|
||||
<Button type="default" onClick={handleHide}>
|
||||
@@ -64,7 +62,7 @@ const PromoToast = () => {
|
||||
</Button>
|
||||
</div>
|
||||
<Image
|
||||
src={bgImage}
|
||||
src={LW14BG}
|
||||
alt=""
|
||||
fill
|
||||
sizes="100%"
|
||||
|
||||
Whitespace-only changes.
@@ -28,6 +28,7 @@
|
||||
"monaco-editor": "*",
|
||||
"next-themes": "*",
|
||||
"openai": "^4.20.1",
|
||||
"react-countdown": "^2.3.5",
|
||||
"react-error-boundary": "^4.0.12",
|
||||
"react-hook-form": "^7.45.0",
|
||||
"react-intersection-observer": "^9.8.2",
|
||||
|
||||
@@ -5,7 +5,6 @@ import { useEffect, useState } from 'react'
|
||||
import { usePathname } from 'next/navigation'
|
||||
import { PropsWithChildren } from 'react'
|
||||
import { cn } from '../../lib/utils/cn'
|
||||
import _announcement from './data/Announcement.json'
|
||||
import { X } from 'lucide-react'
|
||||
|
||||
export interface AnnouncementProps {
|
||||
@@ -16,12 +15,11 @@ export interface AnnouncementProps {
|
||||
badge?: string
|
||||
}
|
||||
|
||||
const announcement = _announcement as AnnouncementProps
|
||||
|
||||
interface AnnouncementComponentProps {
|
||||
show?: boolean
|
||||
dismissable?: boolean
|
||||
className?: string
|
||||
announcementKey: `announcement_${string}`
|
||||
}
|
||||
|
||||
const Announcement = ({
|
||||
@@ -29,6 +27,7 @@ const Announcement = ({
|
||||
dismissable = true,
|
||||
className,
|
||||
children,
|
||||
announcementKey,
|
||||
}: PropsWithChildren<AnnouncementComponentProps>) => {
|
||||
const [hidden, setHidden] = useState(true)
|
||||
|
||||
@@ -36,19 +35,19 @@ const Announcement = ({
|
||||
const isLaunchWeekSection = pathname?.includes('launch-week') ?? false
|
||||
|
||||
// override to hide announcement
|
||||
if (!show || !announcement.show) return null
|
||||
if (!show) return null
|
||||
|
||||
// construct the key for the announcement, based on the title text
|
||||
const announcementKey = 'announcement_' + announcement.text.replace(/ /g, '')
|
||||
const announcementKeyNoSpaces = announcementKey.replace(/ /g, '')
|
||||
|
||||
// window.localStorage is kept inside useEffect
|
||||
// to prevent error
|
||||
useEffect(function () {
|
||||
if (window.localStorage.getItem(announcementKey) === 'hidden') {
|
||||
if (window.localStorage.getItem(announcementKeyNoSpaces) === 'hidden') {
|
||||
setHidden(true)
|
||||
}
|
||||
|
||||
if (!window.localStorage.getItem(announcementKey)) {
|
||||
if (!window.localStorage.getItem(announcementKeyNoSpaces)) {
|
||||
setHidden(false)
|
||||
}
|
||||
}, [])
|
||||
@@ -56,7 +55,7 @@ const Announcement = ({
|
||||
function handleClose(event: any) {
|
||||
event.stopPropagation()
|
||||
|
||||
window.localStorage.setItem(announcementKey, 'hidden')
|
||||
window.localStorage.setItem(announcementKeyNoSpaces, 'hidden')
|
||||
return setHidden(true)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
{
|
||||
"show": true,
|
||||
"text": "Launch Week 13",
|
||||
"launchDate": "2024-12-02T07:00:00.000-08:00",
|
||||
"link": "/launch-week",
|
||||
"cta": "Learn more"
|
||||
}
|
||||
Generated
+3
@@ -2045,6 +2045,9 @@ importers:
|
||||
react:
|
||||
specifier: '*'
|
||||
version: 18.2.0
|
||||
react-countdown:
|
||||
specifier: ^2.3.5
|
||||
version: 2.3.5(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
|
||||
react-dom:
|
||||
specifier: '*'
|
||||
version: 18.2.0(react@18.2.0)
|
||||
|
||||
Reference in new issue
Block a user