1
- import { useState } from 'react'
2
- import { Dialog } from '@headlessui/react'
3
- import { Bars3Icon , XMarkIcon } from '@heroicons/react/24/outline'
1
+ import { useState , useEffect } from 'react'
2
+ import { Dialog , Popover , Transition } from '@headlessui/react'
3
+ import { Bars3Icon , XMarkIcon , ChevronDownIcon , AcademicCapIcon , BuildingOfficeIcon } from '@heroicons/react/24/outline'
4
4
import TextLoop from "react-text-loop" ;
5
5
import Link from 'next/link'
6
6
import { Logo } from '@/components/Logo'
7
7
import Banner from '@/components/home/Banner' ;
8
-
8
+ import request from '@/utils/request' ;
9
9
10
10
const navigation = [
11
11
@@ -15,7 +15,29 @@ const navigation = [
15
15
16
16
export function Hero ( ) {
17
17
const [ mobileMenuOpen , setMobileMenuOpen ] = useState ( false )
18
+ const [ visibleCards , setVisibleCards ] = useState ( 0 )
19
+ const [ activityFeed , setActivityFeed ] = useState ( [ ] )
20
+
21
+ useEffect ( ( ) => {
22
+ const fetchActivityFeed = async ( ) => {
23
+
24
+ // use mock data if api is down
25
+ setActivityFeed ( [
26
+ { userName : 'laphatize' , challengeName : 'Excel-lently Hidden' , profilePic : 'https://imagedelivery.net/1Dym4oPRvM_5USnDWCdSCw/7523c0cb-2330-443c-94f1-030cd8bde300/public' } ,
27
+ { userName : 'herronjo' , challengeName : 'Trading Bananas' , profilePic : 'https://imagedelivery.net/1Dym4oPRvM_5USnDWCdSCw/1bd03d05-1057-48fc-3d3f-b3ed512cb500/public' } ,
28
+ { userName : 'thunderbird' , challengeName : 'Sneaky Cat ' , profilePic : 'https://imagedelivery.net/1Dym4oPRvM_5USnDWCdSCw/3b312b5f-c90d-490d-80d0-e52b367d4400/public' } ,
29
+ { userName : 'stevestef' , challengeName : 'Pretty Obvious' , profilePic : 'https://imagedelivery.net/1Dym4oPRvM_5USnDWCdSCw/3e75c7a3-dfe9-47cc-0d46-736187e62400/public' } ,
30
+ ] ) ;
31
+ } ;
32
+
33
+ fetchActivityFeed ( ) ;
18
34
35
+ const timer = setInterval ( ( ) => {
36
+ setVisibleCards ( ( prev ) => ( prev < activityFeed . length ? prev + 1 : prev ) )
37
+ } , 1000 ) // Adjust timing as needed
38
+
39
+ return ( ) => clearInterval ( timer )
40
+ } , [ activityFeed . length ] )
19
41
20
42
return (
21
43
< div className = "bg-neutral-900" >
@@ -27,6 +49,59 @@ export function Hero() {
27
49
< Link href = "../" aria-label = "Home" >
28
50
< Logo className = "h-10 w-auto" />
29
51
</ Link >
52
+
53
+ </ div >
54
+ < div className = "flex items-center gap-x-5 md:gap-x-8 hidden sm:flex" >
55
+ < Popover className = "relative" >
56
+ { ( { open } ) => (
57
+ < >
58
+ < Popover . Button className = "flex items-center gap-x-1 text-white focus:outline-none" >
59
+ Solutions
60
+ < ChevronDownIcon className = { `${ open ? 'transform rotate-180' : '' } h-5 w-5 transition-transform duration-150 ease-in-out` } />
61
+ </ Popover . Button >
62
+ < Transition
63
+ enter = "transition duration-100 ease-out"
64
+ enterFrom = "transform scale-95 opacity-0"
65
+ enterTo = "transform scale-100 opacity-100"
66
+ leave = "transition duration-75 ease-out"
67
+ leaveFrom = "transform scale-100 opacity-100"
68
+ leaveTo = "transform scale-95 opacity-0"
69
+ >
70
+ < Popover . Panel className = "absolute left-1/2 z-10 mt-3 w-screen max-w-md -translate-x-1/2 transform px-2 sm:px-0" >
71
+ < div className = "overflow-hidden rounded-lg shadow-lg ring-1 ring-black ring-opacity-5" >
72
+ < div className = "relative grid gap-6 bg-neutral-900 bg-blend-overlay px-5 py-6 sm:gap-8 sm:p-8" >
73
+ < Link href = "/education" className = "block p-3 -m-3 transition duration-150 ease-in-out rounded-md hover:bg-neutral-800" >
74
+ < div className = "flex items-start" >
75
+ < AcademicCapIcon className = "h-8 w-8 text-blue-500 mr-3 mt-1" />
76
+ < div >
77
+ < p className = "text-base font-medium text-white pb-1" > < span className = 'font-semibold' > CTFGuide</ span > Education</ p >
78
+ < p className = "text-sm text-white" > A platform for learning and training cybersecurity skills in the classroom.</ p >
79
+ </ div >
80
+ </ div >
81
+ </ Link >
82
+ < div className = "block p-3 -m-3 transition duration-150 ease-in-out rounded-md hover:bg-neutral-800" >
83
+ < div className = "flex items-start" >
84
+ < BuildingOfficeIcon className = "h-6 w-6 text-blue-500 mr-3 mt-1" />
85
+ < div className = "flex-grow" >
86
+ < div className = "text-base font-medium text-white flex justify-between items-center" >
87
+ < span > < span className = 'font-semibold' > CTFGuide</ span > Enterprise</ span >
88
+ < span className = 'text-xs text-white bg-blue-800 px-2 rounded-full' > Coming Soon</ span >
89
+ </ div >
90
+ < p className = "text-sm text-white" > Train your team to defend against real-world threats.</ p >
91
+ </ div >
92
+ </ div >
93
+ </ div >
94
+ </ div >
95
+ </ div >
96
+ </ Popover . Panel >
97
+ </ Transition >
98
+ </ >
99
+ ) }
100
+ </ Popover >
101
+ < Link href = "/careers" className = "text-white" >
102
+ Company
103
+ </ Link >
104
+
30
105
</ div >
31
106
< div className = "flex lg:hidden" >
32
107
< button
@@ -112,22 +187,31 @@ export function Hero() {
112
187
} }
113
188
/>
114
189
</ div >
115
- < div className = "py-24 sm:py-32 lg:pb-40" >
190
+ < div className = "py-24 sm:py-24 lg:pb-40" >
116
191
< div className = "mx-auto max-w-7xl px-6 lg:px-8" >
117
- < div className = " animate__animated animate__fadeInUp mx-auto max-w-4xl text-center" >
118
- < h1 className = "text-4xl font-bold tracking-normal text-white sm:text-6xl leading-relaxed " >
192
+ < div className = " animate__animated animate__fadeInUp mx-auto max-w-6xl text-left" >
193
+ < div className = 'grid sm:grid-cols-6 grid-cols-1' >
194
+ < div className = 'col-span-4 ' >
195
+ < h1 className = "text-4xl font-normal tracking-normal text-white sm:text-4xl leading-relaxed " >
196
+
197
+ < div className = "mt-10 mb-2 text-3xl text-white sm:text-2xl flex items-center justify-left" >
198
+ < img className = " w-8 text-center ml-0 mr-2 " src = "../../../../darkLogocrop.png" />
199
+
200
+ < h1 className = 'text-3xl font-normal m' > < span className = "text-white font-semibold" > CTFGuide </ span >
201
+ </ h1 >
202
+ </ div >
119
203
The platform that < span className = "text-blue-600 leading-relaxed" >
120
204
< TextLoop >
121
205
< span > grows</ span >
122
206
< span > develops</ span >
123
207
< span > trains</ span >
124
208
</ TextLoop >
125
- </ span > < span className = 'mt-3' > cybersecurity talent.</ span >
209
+ </ span > < br > </ br > < span className = 'mt-3' > cybersecurity talent.</ span >
126
210
</ h1 >
127
211
< p className = "mt-6 text-lg leading-8 text-gray-300" >
128
- A data-driven simulation platform that provides a realistic, hands-on experience for you to become a cybersecurity professional .
212
+ The social learning platform for all things cybersecurity.
129
213
</ p >
130
- < div className = "mt-10 flex items-center justify-center gap-x-6" >
214
+ < div className = "mt-10 flex items-center gap-x-6" >
131
215
< a
132
216
href = "../register"
133
217
className = "rounded-md px-6 py-1.5 text-lg font-semibold text-white border border-white hover:bg-white hover:text-black focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-400"
@@ -137,7 +221,32 @@ export function Hero() {
137
221
< p onClick = { ( ) => window . scrollTo ( 0 , 1500 ) } className = "cursor-pointer text-lg font-semibold leading-6 text-white" >
138
222
Learn more < span aria-hidden = "true" > →</ span >
139
223
</ p >
224
+ </ div >
140
225
</ div >
226
+
227
+ < div className = 'col-span-2 mt-10 hidden sm:block' >
228
+ < div className = "space-y-2" >
229
+ { activityFeed . slice ( 0 , visibleCards ) . map ( ( card , index ) => (
230
+ < div
231
+ key = { card . userName }
232
+ className = 'hover:bg-neutral-700 duration-300 bg-neutral-800 cursor-pointer p-4 rounded-lg flex items-center transform transition-all ease-in-out'
233
+ style = { {
234
+ opacity : 0 ,
235
+ animation : `fadeInUp 0.5s ease-out ${ index * 0.2 } s forwards` ,
236
+ } }
237
+ >
238
+ < img src = { card . profilePic ? card . profilePic : `https://robohash.org/${ card . userName } ` } className = 'w-12 h-12 rounded-full mr-4' alt = { card . userName } />
239
+ < div >
240
+ < p className = 'text-white font-bold' > { card . userName } </ p >
241
+ < p className = 'text-gray-400 text-sm' >
242
+ solved < span className = 'text-yellow-400' > { card . challengeName } </ span >
243
+ </ p >
244
+ </ div >
245
+ </ div >
246
+ ) ) }
247
+ </ div >
248
+ </ div >
249
+ </ div >
141
250
</ div >
142
251
< img
143
252
@@ -148,7 +257,7 @@ export function Hero() {
148
257
autoPlay
149
258
width = { 2432 }
150
259
height = { 1442 }
151
- className = "animate__animated animate__fadeInUp mt-16 rounded-md bg-white/5 shadow-2xl ring-1 ring-white/10 sm:mt-24 "
260
+ className = "animate__animated animate__fadeInUp mt-16 rounded-md bg-white/5 shadow-2xl ring-1 ring-white/10 sm:mt-28 "
152
261
153
262
>
154
263
< source src = "../sample_vid.mp4" type = "video/mp4" />
@@ -171,4 +280,4 @@ export function Hero() {
171
280
</ div >
172
281
</ div >
173
282
) ;
174
- }
283
+ }
0 commit comments