1+ /** @jsxImportSource theme-ui */
2+ import { useState , useEffect } from 'react'
13import { Box , Card , Grid , Heading , Text } from 'theme-ui'
2- import usePrefersMotion from '../../lib/use-prefers-motion'
3- import useHasMounted from '../../lib/use-has-mounted'
4+ import { keyframes } from '@emotion/react'
5+ import { getLiveCount , formatted as defaultFormatted } from '../../lib/members'
6+
7+ const float1 = keyframes `
8+ 0%, 100% { transform: translateY(0px); }
9+ 50% { transform: translateY(-18px); }
10+ `
11+ const float2 = keyframes `
12+ 0%, 100% { transform: translateY(0px); }
13+ 50% { transform: translateY(-12px); }
14+ `
15+ const float3 = keyframes `
16+ 0%, 100% { transform: translateY(0px); }
17+ 50% { transform: translateY(-20px); }
18+ `
19+
20+ const HeroGraphic = ( ) => (
21+ < Box
22+ sx = { {
23+ position : 'absolute' ,
24+ top : 0 , left : 0 , right : 0 , bottom : 0 ,
25+ overflow : 'hidden' ,
26+ zIndex : 0 ,
27+ pointerEvents : 'none'
28+ } }
29+ >
30+ < Box sx = { {
31+ position : 'absolute' , top : '10%' , left : '5%' ,
32+ width : [ '60px' , '90px' ] , height : [ '60px' , '90px' ] ,
33+ borderRadius : '50%' , bg : 'rgba(255,255,255,0.15)' ,
34+ animation : `${ float1 } 6s ease-in-out infinite`
35+ } } />
36+ < Box sx = { {
37+ position : 'absolute' , top : '60%' , left : '2%' ,
38+ width : [ '30px' , '50px' ] , height : [ '30px' , '50px' ] ,
39+ borderRadius : '50%' , bg : 'rgba(255,255,255,0.1)' ,
40+ animation : `${ float2 } 8s ease-in-out infinite`
41+ } } />
42+ < Box sx = { {
43+ position : 'absolute' , top : '20%' , right : [ '80px' , '200px' ] ,
44+ width : [ '40px' , '70px' ] , height : [ '40px' , '70px' ] ,
45+ borderRadius : '50%' , bg : 'rgba(255,255,255,0.12)' ,
46+ animation : `${ float3 } 7s ease-in-out infinite`
47+ } } />
48+ < Box aria-hidden = "true" sx = { {
49+ position : 'absolute' ,
50+ bottom : '-10px' ,
51+ left : [ '10px' , '40px' ] ,
52+ fontSize : [ '80px' , '140px' ] ,
53+ fontWeight : 800 ,
54+ color : 'rgba(255,255,255,0.08)' ,
55+ lineHeight : 1 ,
56+ fontFamily : 'inherit' ,
57+ userSelect : 'none'
58+ } } >
59+ #
60+ </ Box >
61+ < Box aria-hidden = "true" sx = { {
62+ position : 'absolute' ,
63+ top : '5px' ,
64+ right : [ '80px' , '220px' ] ,
65+ fontSize : [ '60px' , '100px' ] ,
66+ fontWeight : 800 ,
67+ color : 'rgba(255,255,255,0.06)' ,
68+ lineHeight : 1 ,
69+ fontFamily : 'inherit' ,
70+ userSelect : 'none'
71+ } } >
72+ #
73+ </ Box >
74+ </ Box >
75+ )
76+
77+ const MemberBadge = ( ) => {
78+ const [ count , setCount ] = useState ( defaultFormatted )
79+
80+ useEffect ( ( ) => {
81+ const controller = new AbortController ( )
82+ const timeout = setTimeout ( ( ) => controller . abort ( ) , 3000 )
83+ getLiveCount ( controller . signal )
84+ . then ( data => setCount ( data . formatted ) )
85+ . catch ( ( ) => { } )
86+ . finally ( ( ) => clearTimeout ( timeout ) )
87+ return ( ) => {
88+ controller . abort ( )
89+ clearTimeout ( timeout )
90+ }
91+ } , [ ] )
92+
93+ return (
94+ < Box sx = { {
95+ display : 'inline-flex' ,
96+ alignItems : 'center' ,
97+ gap : 2 ,
98+ bg : 'rgba(255,255,255,0.15)' ,
99+ border : '1px solid rgba(255,255,255,0.3)' ,
100+ borderRadius : '999px' ,
101+ px : 3 , py : 1 , mb : 3 ,
102+ backdropFilter : 'blur(8px)'
103+ } } >
104+ < Box sx = { {
105+ width : '8px' , height : '8px' ,
106+ borderRadius : '50%' , bg : '#2eb67d' ,
107+ boxShadow : '0 0 6px #2eb67d' ,
108+ animation : 'pulse 2s ease-in-out infinite' ,
109+ '@keyframes pulse' : {
110+ '0%, 100%' : { opacity : 1 } ,
111+ '50%' : { opacity : 0.4 }
112+ }
113+ } } />
114+ < Text sx = { { color : 'white' , fontSize : 1 , fontWeight : 600 , letterSpacing : '0.03em' } } >
115+ { count } hackers online
116+ </ Text >
117+ </ Box >
118+ )
119+ }
4120
5121const Content = ( { onJoinClick } ) => (
6122 < Grid
@@ -9,31 +125,22 @@ const Content = ({ onJoinClick }) => (
9125 pb = { [ 3 , 4 ] }
10126 sx = { {
11127 backgroundImage :
12- 'radial-gradient( ellipse farthest-corner at top left, #ff8c37, #ec3750)'
128+ 'radial-gradient(ellipse farthest-corner at top left, #ff8c37, #ec3750)' ,
129+ position : 'relative'
13130 } }
14131 >
15- < Box
16- sx = { {
17- position : 'relative' ,
18- zIndex : 1 ,
19- textShadow : 'text' ,
20- textAlign : [ 'center' , 'center' ]
21- } }
22- >
132+ < HeroGraphic />
133+ < Box sx = { { position : 'relative' , zIndex : 1 , textShadow : 'text' , textAlign : [ 'center' , 'center' ] } } >
134+ < MemberBadge />
23135 < Heading
24136 as = "h1"
25137 variant = "title"
26- sx = { {
27- color : 'white' ,
28- fontSize : [ 5 , 6 , 7 ] ,
29- lineHeight : 'limit' ,
30- mb : [ 2 , 3 ]
31- } }
138+ sx = { { color : 'white' , fontSize : [ 5 , 6 , 7 ] , lineHeight : 'limit' , mb : [ 2 , 3 ] } }
32139 >
33140 Hack Club Slack
34141 </ Heading >
35142 </ Box >
36- < Box sx = { { zIndex : 5 , display : 'flex' , alignItems : 'center' } } >
143+ < Box sx = { { zIndex : 5 , display : 'flex' , alignItems : 'center' , position : 'relative' } } >
37144 < Card
38145 sx = { {
39146 variant : 'cards.translucent' ,
@@ -47,14 +154,7 @@ const Content = ({ onJoinClick }) => (
47154 < br />
48155 Join up to make friends, find projects, and have fun.
49156 </ Text >
50- < Box
51- sx = { {
52- display : 'flex' ,
53- gap : 3 ,
54- justifyContent : 'center' ,
55- flexWrap : 'wrap'
56- } }
57- >
157+ < Box sx = { { display : 'flex' , gap : 3 , justifyContent : 'center' , flexWrap : 'wrap' } } >
58158 < Text
59159 as = "button"
60160 onClick = { onJoinClick }
@@ -64,8 +164,7 @@ const Content = ({ onJoinClick }) => (
64164 'radial-gradient(ellipse farthest-corner at top left, #ff8c37, #ec3750)' ,
65165 color : 'white' ,
66166 fontSize : [ 2 , 3 ] ,
67- px : 5 ,
68- py : 3 ,
167+ px : 5 , py : 3 ,
69168 borderRadius : 'extra' ,
70169 fontWeight : 'bold' ,
71170 textDecoration : 'none' ,
@@ -80,7 +179,7 @@ const Content = ({ onJoinClick }) => (
80179 transform : 'scale(1.05)' ,
81180 boxShadow : '0 0 0 2px white' ,
82181 backgroundImage :
83- 'radial-gradient(ellipse farthest-corner at bottom right, #ff8c373f , #ec37503f )'
182+ 'radial-gradient(ellipse farthest-corner at bottom right, #ff8c37 , #ec3750 )'
84183 }
85184 } }
86185 >
@@ -110,42 +209,18 @@ const Cover = () => (
110209 />
111210)
112211
113- const Static = ( {
114- img = 'https://cloud-r4rrjh2z8-hack-club-bot.vercel.app/02020-07-25_a1tcva4ch6mmr6j2cfmcb4e9ync3yhar.png' ,
115- onJoinClick
116- } ) => (
117- < Box
118- as = "section"
119- id = "slack"
120- sx = { {
121- position : 'relative' ,
122- overflow : 'hidden' ,
123- backgroundImage : `url(${ img } )` ,
124- backgroundSize : 'cover'
125- } }
212+
213+ const Slack = ( { onJoinClick} ) => (
214+ < Box
215+ as = "section"
216+ id = "slack"
217+ sx = { {
218+ position :'relative' ,
219+ overflow :'hidden'
220+ } }
126221 >
127- < Cover />
128- < Content onJoinClick = { onJoinClick } />
222+ < Cover />
223+ < Content onJoinClick = { onJoinClick } />
129224 </ Box >
130225)
131-
132- const Slack = ( { onJoinClick } ) => {
133- const hasMounted = useHasMounted ( )
134- const prefersMotion = usePrefersMotion ( )
135- if ( hasMounted && prefersMotion ) {
136- return (
137- < Box
138- as = "section"
139- id = "slack"
140- sx = { { overflow : 'hidden' , position : 'relative' } }
141- >
142- < Cover />
143- < Content onJoinClick = { onJoinClick } />
144- </ Box >
145- )
146- } else {
147- return < Static onJoinClick = { onJoinClick } />
148- }
149- }
150-
151- export default Slack
226+ export default Slack
0 commit comments