1- import React from 'react'
1+ import React , { useEffect , useState } from 'react'
22import Image from 'next/image'
3- import BannerImage from 'components/domain/landing-page/images/devcon-india-banner.png'
4- import TicketCard from 'components/domain/landing-page/images/ticket-card.png'
5- import TicketBack from 'components/domain/ticket-sharing/ticket-backside.png'
3+ import BannerImage from './images/devcon-8-india-bg.png'
4+ import DevconLogo from './images/devcon-8-india-logo.svg'
65import IconX from 'assets/icons/twitter.svg'
76import IconInstagram from 'assets/icons/instagram.svg'
87import IconTelegram from 'assets/icons/telegram.svg'
98import IconEmail from 'assets/icons/ui-email.svg'
109import { Link } from 'components/common/link'
1110import useGetElementHeight from 'hooks/useGetElementHeight'
11+ import { ChevronDown } from 'lucide-react'
12+ import { GetReminderDialog } from 'components/domain/landing-page/GetReminderDialog'
13+
14+ // Ticket launch date — May 12, 2026 @ 3:00 PM UTC
15+ const TICKET_LAUNCH_DATE = new Date ( Date . UTC ( 2026 , 4 , 12 , 15 , 0 , 0 ) )
16+
17+ type Countdown = { days : number ; hours : number ; mins : number ; secs : number }
18+
19+ function computeCountdown ( ) : Countdown {
20+ const now = Date . now ( )
21+ const diff = Math . max ( 0 , TICKET_LAUNCH_DATE . getTime ( ) - now )
22+ const days = Math . floor ( diff / 86_400_000 )
23+ const hours = Math . floor ( ( diff % 86_400_000 ) / 3_600_000 )
24+ const mins = Math . floor ( ( diff % 3_600_000 ) / 60_000 )
25+ const secs = Math . floor ( ( diff % 60_000 ) / 1000 )
26+ return { days, hours, mins, secs }
27+ }
28+
29+ const CountdownUnit = ( { value, label, width } : { value : number ; label : string ; width ?: string } ) => (
30+ < div className = { `flex flex-col items-center justify-center text-center ${ width || '' } ` } >
31+ < p className = "text-2xl font-extrabold text-white leading-[28.8px] tracking-[-0.5px]" > { value } </ p >
32+ < p className = "text-xs text-[#9188a2] leading-4" > { label } </ p >
33+ </ div >
34+ )
35+
36+ const Separator = ( ) => < div className = "w-px h-4 bg-white/10" aria-hidden />
1237
1338export const Hero = ( ) => {
1439 const stripHeight = useGetElementHeight ( 'strip' )
40+ const [ mounted , setMounted ] = useState ( false )
41+ const [ countdown , setCountdown ] = useState < Countdown > ( { days : 0 , hours : 0 , mins : 0 , secs : 0 } )
42+ const [ reminderOpen , setReminderOpen ] = useState ( false )
43+
44+ useEffect ( ( ) => {
45+ setMounted ( true )
46+ setCountdown ( computeCountdown ( ) )
47+ const interval = setInterval ( ( ) => setCountdown ( computeCountdown ( ) ) , 1000 )
48+ return ( ) => clearInterval ( interval )
49+ } , [ ] )
1550
1651 return (
1752 < div className = "relative w-full h-[90vh] md:h-screen overflow-hidden" >
@@ -22,84 +57,115 @@ export const Hero = () => {
2257 fill
2358 priority
2459 placeholder = "blur"
25- className = "object-cover object-top "
60+ className = "object-cover object-center "
2661 style = { { paddingTop : stripHeight } }
2762 />
2863
2964 { /* Edge gradients for smooth blending */ }
3065 < div
31- className = "absolute bottom-0 left-0 w-full h-[150px] mix-blend-hard-light"
32- style = { {
33- background : 'linear-gradient(to top, rgba(34,17,68,1) 4.5%, rgba(34,17,68,0) 100%)' ,
34- } }
66+ className = "absolute bottom-0 left-0 w-full h-[150px] mix-blend-hard-light pointer-events-none"
67+ style = { { background : 'linear-gradient(to top, rgba(34,17,68,1) 4.5%, rgba(34,17,68,0) 100%)' } }
3568 />
3669 < div
37- className = "absolute top-0 left-0 h-full w-[160px] mix-blend-hard-light"
38- style = { {
39- background : 'linear-gradient(to right, rgba(34,17,68,1) 0%, rgba(34,17,68,0) 100%)' ,
40- } }
70+ className = "absolute top-0 left-0 h-full w-[60px] md:w-[160px] mix-blend-hard-light pointer-events-none"
71+ style = { { background : 'linear-gradient(to right, rgba(34,17,68,1) 0%, rgba(34,17,68,0) 100%)' } }
4172 />
4273 < div
43- className = "absolute top-0 right-0 h-full w-[160px] mix-blend-hard-light"
44- style = { {
45- background : 'linear-gradient(to left, rgba(34,17,68,1) 0%, rgba(34,17,68,0) 100%)' ,
46- } }
74+ className = "absolute top-0 right-0 h-full w-[60px] md:w-[160px] mix-blend-hard-light pointer-events-none"
75+ style = { { background : 'linear-gradient(to left, rgba(34,17,68,1) 0%, rgba(34,17,68,0) 100%)' } }
4776 />
4877
4978 { /* Hero content at bottom */ }
50- < div className = "absolute bottom-0 left-0 right-0 pb-8 lg:pb-12 " >
79+ < div className = "absolute bottom-0 left-0 right-0 pb-6 md:pb- 8 lg:pb-14 " >
5180 < div className = "section" >
52- < div className = "flex items-end justify-between" >
53- { /* Left: Location + Social */ }
54- < div className = "flex flex-col gap-4" >
55- < div className = "flex flex-col gap-1.5 text-white" style = { { textShadow : '0 2px 12px rgba(34,17,68,1)' } } >
56- < h1 className = "text-3xl lg:text-[32px] font-extrabold leading-[1.2] tracking-[-0.5px]" >
57- Mumbai, India
58- </ h1 >
59- < p className = "text-xl lg:text-2xl tracking-[-0.5px]" > 3—6 November, 2026</ p >
60- </ div >
61-
62- < div className = "backdrop-blur-[2px] bg-[rgba(26,13,51,0.8)] border border-[rgba(255,255,255,0.1)] flex gap-4 items-center px-4 py-2 rounded-lg w-fit [&_path]:!fill-white" >
63- < span className = "text-white text-base" > Follow us</ span >
64- < Link to = "https://x.com/efdevcon" className = "text-white hover:text-white/80 transition-colors" >
65- < IconX className = "w-[18px] h-[18px]" />
66- </ Link >
67- < Link to = "https://instagram.com/efdevcon" className = "text-white hover:text-white/80 transition-colors" >
68- < IconInstagram className = "w-[18px] h-[18px]" />
69- </ Link >
70- < Link to = "https://t.me/+sitvvHw8D8EzN2Yx" className = "text-white hover:text-white/80 transition-colors" >
71- < IconTelegram className = "w-[18px] h-[18px]" />
72- </ Link >
73- < Link to = "mailto:devcon@ethereum.org" className = "text-white hover:text-white/80 transition-colors" >
74- < IconEmail className = "w-[18px] h-[18px]" />
75- </ Link >
81+ < div className = "flex flex-col md:flex-row gap-4 md:gap-8 md:items-end md:justify-between" >
82+ { /* Left: Logo + Location */ }
83+ < div className = "flex flex-col gap-4 md:gap-6 [filter:drop-shadow(0_2px_12px_#214)]" >
84+ < DevconLogo className = "w-[160px] md:w-[263px] h-auto text-white" />
85+ < div className = "flex flex-col gap-1 md:gap-2 text-white" >
86+ < h1 className = "text-3xl md:text-5xl font-extrabold leading-[1.2] tracking-[-0.5px]" > Mumbai, India</ h1 >
87+ < p className = "text-xl md:text-4xl font-light leading-[1.2] tracking-[-0.5px]" > 3—6 November, 2026</ p >
7688 </ div >
7789 </ div >
7890
79- { /* Right: Ticket card with fan-out effect — commented out while ticket sales are delayed
80- <Link to="/tickets" className="hidden md:flex flex-col gap-3 items-center w-[348px] shrink-0 group">
81- <div className="relative w-[338px] h-[190px]">
82- <div
83- className="absolute inset-0 origin-center scale-[0.90] transition-transform duration-[350ms] ease-[cubic-bezier(0.22,1,0.36,1)] group-hover:rotate-[-9deg] group-hover:translate-x-[0px] group-hover:translate-y-[2px] group-hover:scale-[0.93]"
84- style={{ filter: 'drop-shadow(0 8px 20px rgba(0, 0, 0, 0.3))' }}
85- >
86- <Image src={TicketBack} alt="" width={338} height={190} />
91+ { /* Right: Ticket countdown + social links */ }
92+ < div className = "flex flex-col gap-2 w-full sm:w-[315px] shrink-0" >
93+ { /* Ticket Countdown Widget */ }
94+ < div className = "backdrop-blur-[3px] bg-[rgba(26,13,51,0.8)] border border-solid border-[rgba(150,142,166,0.19)] rounded-lg p-4 flex flex-col gap-4" >
95+ < div className = "flex flex-col gap-3" >
96+ < p className = "text-xs font-semibold text-[#ffa366] text-center tracking-[2px] leading-none" >
97+ TICKETS LAUNCH MAY 12
98+ </ p >
99+
100+ { /* Countdown row — only render on client to avoid hydration mismatch */ }
101+ < div className = "flex items-center justify-between min-h-[44px]" >
102+ { mounted && (
103+ < >
104+ < CountdownUnit value = { countdown . days } label = "days" width = "w-12" />
105+ < Separator />
106+ < CountdownUnit value = { countdown . hours } label = "hours" />
107+ < Separator />
108+ < CountdownUnit value = { countdown . mins } label = "mins" width = "w-10" />
109+ < Separator />
110+ < CountdownUnit value = { countdown . secs } label = "secs" width = "w-10" />
111+ </ >
112+ ) }
113+ </ div >
114+
115+ { /* Early bird pricing */ }
116+ < div className = "flex items-center justify-between font-extrabold text-sm" >
117+ < p className = "text-white leading-[14px]" > Global Early Bird</ p >
118+ < div className = "flex gap-1 items-end" >
119+ < p className = "text-[#9188a2] line-through leading-[14px]" > $699</ p >
120+ < p className = "text-white text-base leading-4" > $349</ p >
121+ </ div >
122+ </ div >
87123 </ div >
88- <div
89- className="absolute inset-0 transition-transform duration-[350ms] ease-[cubic-bezier(0.22,1,0.36,1)]"
90- style={{ filter: 'drop-shadow(0 12px 30px rgba(0, 0, 0, 0.4))' }}
124+
125+ < button
126+ type = "button"
127+ onClick = { ( ) => setReminderOpen ( true ) }
128+ className = "flex gap-1 items-center justify-center w-full cursor-pointer hover:opacity-80 transition-opacity"
129+ aria-label = "Remind me when tickets launch"
91130 >
92- <Image src={TicketCard} alt="Devcon Early Bird Ticket" width={338} height={190} />
131+ < span className = "text-sm font-bold text-[#9668f1] leading-none" > Remind me</ span >
132+ < ChevronDown className = "w-3.5 h-3.5 text-[#9668f1]" strokeWidth = { 2.5 } />
133+ </ button >
134+ </ div >
135+
136+ { /* Social Links */ }
137+ < div className = "backdrop-blur-[3px] bg-[rgba(26,13,51,0.8)] border border-solid border-[rgba(150,142,166,0.19)] rounded-lg px-4 py-2 flex items-center justify-center gap-4 sm:justify-between sm:gap-0 [&_path]:!fill-white" >
138+ < p className = "text-sm text-white leading-5" > Follow for updates</ p >
139+ < div className = "flex gap-4 items-center" >
140+ < Link to = "https://x.com/efdevcon" className = "text-white hover:text-white/80 transition-colors" >
141+ < IconX className = "w-[18px] h-[18px]" />
142+ </ Link >
143+ < Link
144+ to = "https://instagram.com/efdevcon"
145+ className = "text-white hover:text-white/80 transition-colors"
146+ >
147+ < IconInstagram className = "w-[18px] h-[18px]" />
148+ </ Link >
149+ < Link
150+ to = "https://t.me/+sitvvHw8D8EzN2Yx"
151+ className = "text-white hover:text-white/80 transition-colors"
152+ >
153+ < IconTelegram className = "w-[18px] h-[18px]" />
154+ </ Link >
155+ < Link
156+ to = "https://paragraph.com/@efevents"
157+ className = "text-white hover:text-white/80 transition-colors"
158+ >
159+ < IconEmail className = "w-[18px] h-[18px]" />
160+ </ Link >
93161 </ div >
94162 </ div >
95- <p className="text-white font-bold text-base text-center translate-y-[0px] group-hover:translate-y-[8px] transition-transform duration-300">
96- Local Early Bird tickets now available!
97- </p>
98- </Link>
99- */ }
163+ </ div >
100164 </ div >
101165 </ div >
102166 </ div >
167+
168+ < GetReminderDialog open = { reminderOpen } onOpenChange = { setReminderOpen } />
103169 </ div >
104170 )
105171}
0 commit comments