11"use client"
2- import { useState , useEffect , useRef , useCallback } from "react"
2+ import { useState , useEffect , useRef , useCallback , useMemo } from "react"
33import type { RealtimeChannel } from "@supabase/supabase-js"
44import styled from "styled-components"
55import { motion } from "framer-motion"
66import { PotionBackground } from "../components/PotionBackground"
77import { ErrorBoundary } from "../components/ErrorBoundary"
88import { Button } from "../components/Button"
99import { supabaseClient } from "@/lib/supabaseClient"
10+ import eventsData from "../data/events.json"
11+ import type { LumaEvent } from "../services/luma"
1012
1113// Components //
1214
@@ -16,6 +18,21 @@ export default function Doorbell() {
1618 const channelRef = useRef < RealtimeChannel | null > ( null )
1719 const lastRingIdRef = useRef < string | null > ( null )
1820
21+ const nearestEvent = useMemo ( ( ) => {
22+ const events = eventsData as LumaEvent [ ]
23+ const now = new Date ( )
24+
25+ return events . reduce < LumaEvent | null > ( ( nearest , event ) => {
26+ const eventDate = new Date ( event . start_at )
27+ const diff = Math . abs ( eventDate . getTime ( ) - now . getTime ( ) )
28+
29+ if ( ! nearest ) return event
30+
31+ const nearestDiff = Math . abs ( new Date ( nearest . start_at ) . getTime ( ) - now . getTime ( ) )
32+ return diff < nearestDiff ? event : nearest
33+ } , null )
34+ } , [ ] )
35+
1936 const triggerLocalRing = useCallback ( ( ) => {
2037 playDoorbellSound ( )
2138 setIsRinging ( true )
@@ -123,6 +140,17 @@ export default function Doorbell() {
123140 Ring Doorbell
124141 </ Button >
125142 ) }
143+ { nearestEvent && (
144+ < Button
145+ href = { nearestEvent . url }
146+ variant = "tertiary"
147+ size = "default"
148+ target = "_blank"
149+ rel = "noopener noreferrer"
150+ >
151+ Get Your Ticket
152+ </ Button >
153+ ) }
126154 </ ButtonSection >
127155 { ringCount >= 3 && (
128156 < CallSection >
@@ -207,8 +235,10 @@ const Paragraph = styled.p`
207235
208236const ButtonSection = styled . section `
209237 display: flex;
238+ flex-direction: column;
210239 justify-content: center;
211240 align-items: center;
241+ gap: 1rem;
212242`
213243
214244const AnimatedButtonContent = styled ( motion . span ) `
0 commit comments