mirror of
https://github.com/supabase/supabase.git
synced 2026-10-16 14:49:10 +03:00
Merge pull request #2 from goszczynskip/feat/mamba-username-ticket
username ticket lw14
This commit is contained in:
3 files changed
+27
-168
No files matched your search
@@ -9,8 +9,8 @@ export default function TicketCopy() {
|
||||
const { username } = userData
|
||||
const [copied, setCopied] = useState(false)
|
||||
const buttonRef = useRef<HTMLButtonElement>(null)
|
||||
const displayUrl = `.../launch-week?referal=${username}`
|
||||
const link = `${LW14_URL}?referal=${username}`
|
||||
const displayUrl = `.../launch-week/tickets/${username}`
|
||||
const link = `${LW14_URL}/tickets/${username}`
|
||||
|
||||
return (
|
||||
<button
|
||||
|
||||
@@ -18,7 +18,7 @@ export default function TicketShare() {
|
||||
const [_loading, setLoading] = useState(false)
|
||||
const isLessThanMd = useBreakpoint()
|
||||
const downloadLink = useRef<HTMLAnchorElement>()
|
||||
const link = `${LW14_URL}?referal=${username}`
|
||||
const link = `${LW14_URL}/tickets/${username}`
|
||||
const permalink = encodeURIComponent(link)
|
||||
const text = hasSecretTicket ? LW14_TWEET_TEXT_SECRET : platinum ? LW14_TWEET_TEXT_PLATINUM : LW14_TWEET_TEXT
|
||||
const encodedText = encodeURIComponent(text)
|
||||
|
||||
@@ -1,187 +1,46 @@
|
||||
import { useState } from 'react'
|
||||
import { GetStaticProps, GetStaticPaths } from 'next'
|
||||
import dayjs from 'dayjs'
|
||||
import { NextSeo } from 'next-seo'
|
||||
import Link from 'next/link'
|
||||
import Error from 'next/error'
|
||||
import { createClient, Session } from '@supabase/supabase-js'
|
||||
import { Button } from 'ui'
|
||||
import { LW_URL, SITE_ORIGIN } from '~/lib/constants'
|
||||
import supabase from '~/lib/supabase'
|
||||
import { Database } from '~/lib/database.types'
|
||||
import { AnimatePresence, m, LazyMotion, domAnimation } from 'framer-motion'
|
||||
import { DEFAULT_TRANSITION, INITIAL_BOTTOM, getAnimation } from '~/lib/animations'
|
||||
import { LW14_DATE, LW14_TITLE, LW14_URL, SITE_ORIGIN } from '~/lib/constants'
|
||||
import { LwView } from '~/components/LaunchWeek/14/LwView'
|
||||
import { useRouter } from 'next/router'
|
||||
import { Lw14ConfDataProvider } from '~/components/LaunchWeek/14/hooks/use-conf-data'
|
||||
|
||||
import DefaultLayout from '~/components/Layouts/Default'
|
||||
import SectionContainer from '~/components/Layouts/SectionContainer'
|
||||
import { TicketState, ConfDataContext, UserData } from '~/components/LaunchWeek/hooks/use-conf-data'
|
||||
import CanvasSingleMode from '~/components/LaunchWeek/13/Multiplayer/CanvasSingleMode'
|
||||
import ThreeTicketCanvas from '~/components/LaunchWeek/13/ThreeTicketCanvas'
|
||||
const Lw14Page = () => {
|
||||
const TITLE = `${LW14_TITLE} | ${LW14_DATE}`
|
||||
const DESCRIPTION = 'Join us for a week of announcing new features, every day at 7 AM PT.'
|
||||
const OG_IMAGE = `${SITE_ORIGIN}/images/launchweek/14/lw14-og.png?lw=14`
|
||||
|
||||
interface Props {
|
||||
user: UserData
|
||||
users: UserData[]
|
||||
ogImageUrl: string
|
||||
}
|
||||
|
||||
export default function UsernamePage({ user, ogImageUrl }: Props) {
|
||||
const { username, name, platinum, secret } = user
|
||||
|
||||
const ticketType = secret ? 'secret' : platinum ? 'platinum' : 'regular'
|
||||
|
||||
const DISPLAY_NAME = name || username
|
||||
const TITLE = `${DISPLAY_NAME ? DISPLAY_NAME.split(' ')[0] + '’s' : 'Get your'} Launch Week Ticket`
|
||||
const DESCRIPTION = `Claim your Supabase Launch Week 13 ticket for a chance to win supa swag.`
|
||||
|
||||
const [session] = useState<Session | null>(null)
|
||||
const [ticketState, setTicketState] = useState<TicketState>('ticket')
|
||||
|
||||
const transition = DEFAULT_TRANSITION
|
||||
const initial = INITIAL_BOTTOM
|
||||
const animate = getAnimation({ duration: 1 })
|
||||
const exit = { opacity: 0, transition: { ...transition, duration: 0.2 } }
|
||||
|
||||
if (!username) {
|
||||
return <Error statusCode={404} />
|
||||
const { query } = useRouter()
|
||||
const ticketNumber = query.ticketNumber?.toString()
|
||||
const defaultUserData = {
|
||||
id: query.id?.toString(),
|
||||
ticket_number: ticketNumber ? parseInt(ticketNumber, 10) : undefined,
|
||||
name: query.name?.toString(),
|
||||
username: query.username?.toString(),
|
||||
platinum: !!query.platinum,
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<NextSeo
|
||||
title={TITLE}
|
||||
description={DESCRIPTION}
|
||||
openGraph={{
|
||||
title: TITLE,
|
||||
description: DESCRIPTION,
|
||||
url: `${LW_URL}/tickets/${username}`,
|
||||
url: LW14_URL,
|
||||
images: [
|
||||
{
|
||||
url: ogImageUrl,
|
||||
width: 1200,
|
||||
height: 630,
|
||||
url: OG_IMAGE,
|
||||
},
|
||||
],
|
||||
}}
|
||||
/>
|
||||
<ConfDataContext.Provider
|
||||
value={{
|
||||
supabase,
|
||||
session,
|
||||
userData: user,
|
||||
setUserData: () => null,
|
||||
ticketState,
|
||||
setTicketState,
|
||||
}}
|
||||
>
|
||||
<DefaultLayout className="lg:h-[calc(100dvh-65px)] min-h-[calc(100vh)] md:min-h-[calc(100vh-65px)] overflow-hidden">
|
||||
<SectionContainer className="relative h-full flex-1 pt-4 md:pt-4 pointer-events-none">
|
||||
<div className="relative z-10 flex h-full">
|
||||
<LazyMotion features={domAnimation}>
|
||||
<AnimatePresence mode="wait" key={ticketState}>
|
||||
<m.div
|
||||
key="ticket"
|
||||
initial={initial}
|
||||
animate={animate}
|
||||
exit={exit}
|
||||
className="w-full flex-1 h-full flex flex-col lg:flex-row items-center lg:justify-center lg:items-center gap-8 md:gap-10 lg:gap-32 text-foreground text-center md:text-left"
|
||||
>
|
||||
<div className="w-full lg:w-full h-full mt-3 md:mt-6 lg:mt-0 max-w-lg flex flex-col items-center justify-center gap-3"></div>
|
||||
<div className="lg:h-full w-full max-w-lg gap-8 flex flex-col items-center justify-center lg:items-start lg:justify-center text-center lg:text-left">
|
||||
<div className="flex flex-col items-center justify-center lg:justify-start lg:items-start gap-2 text-foreground text-center md:text-left max-w-sm">
|
||||
<h1 className="text-foreground text-2xl">
|
||||
Join {DISPLAY_NAME?.split(' ')[0]} <br /> for Launch Week 13
|
||||
</h1>
|
||||
<span className="text-foreground-lighter">
|
||||
Claim your own ticket for a chance to win limited swag and to follow all
|
||||
the announcements.
|
||||
</span>
|
||||
</div>
|
||||
<div>
|
||||
<Button type="primary" asChild size="small">
|
||||
<Link
|
||||
href={`${LW_URL}${username ? '?referral=' + username : ''}`}
|
||||
className="pointer-events-auto"
|
||||
>
|
||||
Claim your ticket
|
||||
</Link>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</m.div>
|
||||
</AnimatePresence>
|
||||
</LazyMotion>
|
||||
</div>
|
||||
</SectionContainer>
|
||||
<CanvasSingleMode />
|
||||
<ThreeTicketCanvas
|
||||
username={DISPLAY_NAME ?? ''}
|
||||
className="relative -mt-40 -mb-20 lg:my-0 lg:absolute"
|
||||
ticketPosition="left"
|
||||
ticketType={ticketType}
|
||||
sharePage={true}
|
||||
/>
|
||||
</DefaultLayout>
|
||||
</ConfDataContext.Provider>
|
||||
|
||||
<Lw14ConfDataProvider initState={{ userTicketData: defaultUserData, partymodeStatus: 'on' }}>
|
||||
<LwView />
|
||||
</Lw14ConfDataProvider>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export const getStaticProps: GetStaticProps = async ({ params }) => {
|
||||
const username = params?.username?.toString() || null
|
||||
let user
|
||||
|
||||
const supabaseAdmin = createClient<Database>(
|
||||
process.env.NEXT_PUBLIC_SUPABASE_URL!,
|
||||
process.env.LIVE_SUPABASE_COM_SERVICE_ROLE_KEY!
|
||||
)
|
||||
|
||||
// fetch the normal ticket
|
||||
// stores the og images in supabase storage
|
||||
fetch(`${SITE_ORIGIN}/api-v2/ticket-og?username=${encodeURIComponent(username ?? '')}`)
|
||||
|
||||
// fetch a specific user
|
||||
if (username) {
|
||||
const { data } = await supabaseAdmin!
|
||||
.from('tickets_view')
|
||||
.select('name, username, ticket_number, metadata, platinum, secret, role, company, location')
|
||||
.eq('launch_week', 'lw13')
|
||||
.eq('username', username)
|
||||
.single()
|
||||
|
||||
user = data
|
||||
}
|
||||
|
||||
// fetch the platinum ticket
|
||||
// stores the og images in supabase storage
|
||||
if (user?.secret) {
|
||||
fetch(
|
||||
`${SITE_ORIGIN}/api-v2/ticket-og?username=${encodeURIComponent(username ?? '')}&secret=true`
|
||||
)
|
||||
} else if (user?.platinum) {
|
||||
// fetch /api-v2/ticket-og
|
||||
fetch(
|
||||
`${SITE_ORIGIN}/api-v2/ticket-og?username=${encodeURIComponent(username ?? '')}&platinum=true`
|
||||
)
|
||||
}
|
||||
|
||||
const ticketType = user?.secret ? 'secret' : user?.platinum ? 'platinum' : 'regular'
|
||||
const ogImageUrl = `${process.env.NEXT_PUBLIC_SUPABASE_URL}/storage/v1/object/public/images/launch-week/lw13/og/${ticketType}/${username}.png?t=${dayjs(new Date()).format('DHHmmss')}`
|
||||
|
||||
return {
|
||||
props: {
|
||||
user: {
|
||||
...user,
|
||||
username,
|
||||
},
|
||||
ogImageUrl,
|
||||
key: username,
|
||||
},
|
||||
revalidate: 5,
|
||||
}
|
||||
}
|
||||
|
||||
export const getStaticPaths: GetStaticPaths = async () => {
|
||||
return Promise.resolve({
|
||||
paths: [],
|
||||
fallback: 'blocking',
|
||||
})
|
||||
}
|
||||
export default Lw14Page
|
||||
Reference in new issue
Block a user