Files
supabase/apps/www/components/LaunchWeek/14/hooks/use-registration.ts
94e919d417 lw14 ticketing #34444
* mamba init

* shader-updates

* feat: add better bloom

* cleanup

* Fix GLTF model loading to respect original material properties

Signed-off-by: Piotr Goszczyński <pg@tonik.com>

* Fix GLTF model loading to respect original material properties

Signed-off-by: Piotr Goszczyński <pg@tonik.com>

* stash changes

* Update font to Arial in mamba ticket component

Signed-off-by: Piotr Goszczyński <pg@tonik.com>

* Fix wireframe size in debug mode

Signed-off-by: Piotr Goszczyński <pg@tonik.com>

* Fix wireframe size in debug mode by attaching to child mesh instead of model

Signed-off-by: Piotr Goszczyński <pg@tonik.com>

* fix scaling

* fix

* feat: load png with color material

* fix: spline material

* add toggling of effects

* stash

* feat: ticket model

* load better model

* strcture

* fix rotation speed

* rotation

* fix rotation

* new model

* prepare final designs

* add color palette

* feat: add fonts and rendering

* render dynamic texture

* load all textures

* fix: color sace

* feat: secret model

* improve perf

* postprocessing

* fix: output pass

* improve shaders

* increase glitches

* cleanup

* update colors

* remove unused files

* add header

* feat: ui

* fix: raycaster

* feat: add button toggling

* Improve ui

* fix corners positoins

* add tunnel effect

* fix: dates

* add dynamic rocket position rendering

* add different logs

* feat: add migrations and connect to real data

* chore: state cleanup to use reducer

Migrate logic to centralized reducer for ease of debugging

* feat: add hud layout

* add grain effect to hud

* limit glitching, move page to main url

* add vignette effect

* fix: desktop layout

* remove vertical space

* feat: save secret state on ticket upgrade

* feat: make platinum version take priority over secret

* add mobile header

* remove unnecessary allocations

* fix: resize hud

* add page scaling for mobile layouts

* add ticket scaling based on resolution

* adjust mobile styles

* fix: resize texture distortion

* add gauges mobile breaking points

* feat: mobile claim layout

* mobile styles

* Show ticket referer

* rename files

* update copy links

* add partymode part 1

* feat: og images, lw14

* add presence tracking

* add live updates of guages

* Update meetups label

* update label

* username ticket lw14

* add proper subscription on first render

* remove green edge

* feat: remove species & planet from ticket scene

* change urls

* feat/mamba-assets: update assets

* feat: fix shader grain

* add color to shader

* remove vertical space

* fix: og image generation

* fix referal and removing of access token

* make urls nicer

* feat/mamba-assets: dynamic line break + dynamic background

* small adjustments

* add trimming to ogimages

* minor: missing font file

* fix og image line wrapping

* remove dot from meetups

* improve ticket quality

* upss, forgot to commit one file

* feat add dynamic og image linking

* update static site url

* fix low mobile resolution

* add banners

* simplify banner loading

* add missing fonts

* fix name breaking to prioritize spaces

* update quality based on devicePixelRatio

* fix button positioning

* revert: feature flags disabling

* update start date

* limit shader effects and disable axis, potential fix to chrome freeze

* feat: init mamba 01

* create narrow ticket scene

* narrow scene for ticket and fix follow mouse

* fix dates

* alternative version

* updated ticket page

* remove migrations

* remove files

* prettier

* prettier

* Fix TS and prettier issues

* Fix TS issues

* Test

* Remove console log

* fix updating ticket on share

* chore: lw cleanup

* fix ticket layout

* fix chrome crashes

* lower crt intensity

* tunnel improvements

* fix tunnel effect

* chore: z-index and prettier fix

* chore: padding

* fix double tunnel

* chore: font on banners

---------

Signed-off-by: Piotr Goszczyński <pg@tonik.com>
Co-authored-by: dztonik <dz@tonik.com>
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>
2025-03-27 15:55:47 +00:00

215 lines
5.9 KiB
TypeScript

import { useCallback, useEffect, useRef, useState } from 'react'
import { REALTIME_CHANNEL_STATES, RealtimeChannel, SupabaseClient } from '@supabase/supabase-js'
import useConfData from './use-conf-data'
import { LW14_URL } from '~/lib/constants'
import supabase from '../supabase'
function subscribeToTicketChanges(
username: string,
onChange: (payload: any) => void
): RealtimeChannel {
return supabase
.channel('changes')
.on(
'postgres_changes',
{
event: 'UPDATE',
schema: 'public',
table: 'tickets',
filter: `username=eq.${username}`,
},
onChange
)
.subscribe()
}
interface RegistrationProps {
onRegister?: () => void
onError?: (error: any) => void
}
export const useRegistration = ({ onError, onRegister }: RegistrationProps = {}) => {
// const [realtimeChannel, setRealtimeChannel] = useState<RealtimeChannel | null>(null)
const [
{ userTicketData: userData, session, userTicketDataState, urlParamsLoaded, referal },
dispatch,
] = useConfData()
const sessionUser = session?.user
const callbacksRef = useRef({ onError, onRegister })
// Triggered on session
const fetchOrCreateUser = useCallback(async () => {
if (['loading', 'loaded'].includes(userTicketDataState)) return
if (!urlParamsLoaded) return
if (!sessionUser) {
console.warn('Cannot fetch user without session. Skipping...')
return
}
const username = sessionUser.user_metadata?.user_name as string | undefined
const name = sessionUser.user_metadata.full_name
const email = sessionUser.email
const userId = sessionUser.id
if (!username) {
throw new Error('Username is required')
}
if (!userData.id) {
dispatch({ type: 'USER_TICKET_FETCH_STARTED' })
// console.log('Inserting ticket for user', username, referal)
const { error: ticketInsertError } = await supabase
.from('tickets')
.insert({
user_id: userId,
launch_week: 'lw14',
email,
name,
username,
referred_by: referal ?? null,
})
.select()
.single()
// If error because of duplicate email, ignore and proceed, otherwise sign out.
if (ticketInsertError && ticketInsertError?.code !== '23505') {
dispatch({ type: 'USER_TICKET_FETCH_ERROR', payload: ticketInsertError })
callbacksRef.current.onError?.(ticketInsertError)
return supabase.auth.signOut()
}
const { data, error: ticketsViewError } = await supabase
.from('tickets_view')
.select('*')
.eq('launch_week', 'lw14')
.eq('username', username)
.single()
if (ticketsViewError) {
dispatch({ type: 'USER_TICKET_FETCH_ERROR', payload: ticketsViewError })
callbacksRef.current.onError?.(ticketsViewError)
return
}
dispatch({ type: 'USER_TICKET_FETCH_SUCCESS', payload: data })
await prefetchData(username)
}
callbacksRef.current.onRegister?.()
}, [dispatch, referal, sessionUser, urlParamsLoaded, userData.id, userTicketDataState])
async function prefetchData(username: string) {
// Prefetch GitHub avatar
// new Image().src = `https://github.com/${username}.png`
// Prefetch the twitter share URL to eagerly generate the page
await fetch(`/api-v2/ticket-og?username=${username}`)
}
const handleGithubSignIn = useCallback(async () => {
let redirectTo = `${LW14_URL}`
if (referal) {
redirectTo += `?referal=${referal}`
}
const response = await supabase?.auth.signInWithOAuth({
provider: 'github',
options: {
redirectTo,
},
})
if (response) {
if (response.error) {
callbacksRef.current?.onError?.(response.error)
return
}
}
}, [referal])
useEffect(() => {
fetchOrCreateUser()
const username = sessionUser?.user_metadata?.user_name as string | undefined
if (username) {
const channel = subscribeToTicketChanges(username, (payload) => {
const platinum = !!payload.new.shared_on_twitter && !!payload.new.shared_on_linkedin
const secret = !!payload.new.game_won_at
dispatch({
type: 'USER_TICKET_UPDATED',
payload: {
...payload.new,
platinum,
secret,
},
})
})
return () => {
// Cleanup realtime subscription on unmount
channel?.unsubscribe()
}
}
}, [dispatch, fetchOrCreateUser, sessionUser?.user_metadata?.user_name])
useEffect(() => {
supabase.auth.getSession().then(({ data, error }) => {
if (error) console.error('Session error', error)
dispatch({ type: 'SESSION_UPDATED', payload: data.session })
})
const {
data: { subscription },
} = supabase.auth.onAuthStateChange((_event, session) => {
dispatch({ type: 'SESSION_UPDATED', payload: session })
if (session && window.location.hash.includes('access_token')) {
window.history.replaceState(null, '', window.location.pathname + window.location.search)
}
})
return () => subscription.unsubscribe()
}, [dispatch])
useEffect(() => {
callbacksRef.current = { onError, onRegister }
})
const upgradeTicket = async () => {
if (userData.id) {
if (userData.secret) {
// console.log('User already has a secret ticket')
return
}
const { error } = await supabase
.from('tickets')
.update({ game_won_at: new Date() })
.eq('launch_week', 'lw14')
.eq('username', userData.username)
if (error) {
return console.error('Failed to upgrade user ticket', error)
}
// Trigger og-image ticket generation
await fetch(`/api-v2/ticket-og?username=${userData.username}&secret=true`)
} else {
console.warn('Cannot upgrade ticket without user data')
}
}
return {
signIn: handleGithubSignIn,
upgradeTicket,
}
}