1- import { useState } from "react" ;
1+ import { useEffect , useState } from "react" ;
22import ScrollText from "./ScrollText" ;
3+ import { getProjects } from "../../utils/sanity" ;
34
45interface DataProps {
56 data : {
6- tabs : TabProps [ ] ;
7+ projects : ProjectProps [ ] ;
78 headline : string ;
89 } ;
910}
1011
11- interface TabProps {
12- title : string ;
13- projects : ProjectProps [ ] ;
14- }
15-
1612interface ProjectProps {
1713 name : string ;
1814 github ?: string ;
1915 link ?: string ;
2016 score : number ;
17+ tab ?: string ;
2118}
2219
20+ const TABS = [ "Top 100" , "America" , "Europe" , "Asia" , "Africa" ] ;
21+
2322export const Leaderboard = ( { data } : DataProps ) => {
24- const [ activeTab , setTab ] = useState ( 0 ) ;
23+ const [ projects , setProjects ] = useState < ProjectProps [ ] > ( [ ] ) ;
24+ const [ activeTab , setActiveTab ] = useState < number > ( 0 ) ;
25+ const [ searchTerm , setSearchTerm ] = useState < string > ( "" ) ;
2526
26- function handleClick ( i : number ) {
27- setTab ( i ) ;
28- }
27+ useEffect ( ( ) => {
28+ getProjects ( activeTab . toString ( ) )
29+ . then ( ( data ) => {
30+ //console.log("Loaded projects:", data); // ✅ Actual data
31+ setProjects ( data || [ ] ) ;
32+ } )
33+ . catch ( ( error ) => {
34+ console . error ( "Error loading projects:" , error ) ;
35+ setProjects ( [ ] ) ;
36+ } ) ;
37+ } , [ activeTab ] ) ;
38+
39+ const filteredProjects = projects . filter ( ( project ) =>
40+ project . name . toLowerCase ( ) . includes ( searchTerm . toLowerCase ( ) ) ,
41+ ) ;
2942
3043 return (
3144 < div >
@@ -35,19 +48,47 @@ export const Leaderboard = ({ data }: DataProps) => {
3548 </ div >
3649 { data && (
3750 < div className = "px-8" >
38- < div className = "flex gap-2" >
39- { data . tabs . map ( ( tab , i : number ) => (
40- < button
41- onClick = { ( ) => handleClick ( i ) }
42- className = { `bg-pink cursor-pointer rounded-full px-3 py-2 ${ activeTab === i ? "" : "opacity-50" } ` }
51+ < div className = "mb-8 flex flex-col gap-4 md:flex-row" >
52+ < div className = "flex flex-wrap justify-center gap-2 md:justify-start" >
53+ { TABS . map ( ( tab , index : number ) => (
54+ < button
55+ key = { tab }
56+ onClick = { ( ) => setActiveTab ( index ) }
57+ className = { `bg-pink cursor-pointer rounded-full px-4 py-2 text-white transition ${
58+ activeTab === index ? "" : "opacity-60 hover:opacity-80"
59+ } `}
60+ >
61+ { tab }
62+ </ button >
63+ ) ) }
64+ </ div >
65+ < div className = "mx-auto flex items-center justify-between gap-4 rounded-full border border-white pr-4 md:mr-0" >
66+ < input
67+ name = "search"
68+ id = "search"
69+ placeholder = "Search project"
70+ value = { searchTerm }
71+ onChange = { ( e ) => setSearchTerm ( e . target . value ) }
72+ className = "px-4 py-2 text-white focus:outline-none"
73+ />
74+ < svg
75+ width = "16"
76+ height = "17"
77+ viewBox = "0 0 16 17"
78+ fill = "none"
79+ xmlns = "http://www.w3.org/2000/svg"
80+ className = "w-4"
4381 >
44- { tab . title }
45- </ button >
46- ) ) }
82+ < path
83+ d = "M15.8233 15.3129L12.0528 11.5432C15.3217 7.61869 13.1164 1.6272 8.08322 0.758511C3.05005 -0.11017 -1.03606 4.79546 0.728222 9.58865C2.31195 13.8913 7.67828 15.3292 11.2012 12.3949L14.9708 16.1653C15.2989 16.4934 15.8592 16.3433 15.9793 15.8951C16.035 15.6871 15.9755 15.4651 15.8233 15.3129ZM1.54131 7.30515C1.54131 3.13144 6.05948 0.522861 9.67403 2.60972C13.2886 4.69658 13.2886 9.91372 9.67403 12.0006C8.84988 12.4764 7.91477 12.7269 6.96312 12.727C3.97012 12.7236 1.54463 10.2982 1.54131 7.30515Z"
84+ fill = "#F1F1F5"
85+ />
86+ </ svg >
87+ </ div >
4788 </ div >
4889 < div className = "grid" >
4990 < div
50- className = { `text-pink grid items-center gap-4 border-b border-gray-200/30 px-4 py-4 md:grid-cols-6` }
91+ className = { `md: text-pink grid hidden items-center gap-4 border-b border-gray-200/30 px-4 py-4 md:grid-cols-6` }
5192 >
5293 < div className = "flex gap-4 md:col-span-3" >
5394 < span className = "block min-w-16" > </ span >
@@ -57,79 +98,78 @@ export const Leaderboard = ({ data }: DataProps) => {
5798 < div className = "" > App</ div >
5899 < div className = "" > Score</ div >
59100 </ div >
60- { [ ...data . tabs [ activeTab ] . projects ]
61- . sort ( ( a , b ) => b . score - a . score )
62- . map ( ( p , index : number ) => (
63- < div
64- className = { `grid items-center gap-4 border-b border-gray-200/30 px-4 py-4 md:grid-cols-6 ${ index % 2 === 0 ? "bg-white/10" : "" } ` }
65- >
66- < div className = "font-pp flex gap-4 text-3xl md:col-span-3" >
67- < span className = "text-blue block min-w-16" >
68- { index + 1 } .
69- </ span >
70- { p . name }
71- </ div >
72- < div className = "" >
73- { p . github && (
74- < a
75- href = { p . github }
76- target = "_blank"
77- className = "flex items-center gap-2"
101+ { filteredProjects . map ( ( p , i ) => (
102+ < div
103+ className = { `grid items-center gap-4 border-b border-gray-200/30 px-4 py-4 md:grid-cols-6 ${ i % 2 === 0 ? "bg-white/10" : "" } ` }
104+ >
105+ < div className = "font-pp flex gap-4 text-3xl md:col-span-3" >
106+ < span className = "text-blue block min-w-16" > { i + 1 } .</ span >
107+ { p . name }
108+ </ div >
109+ < div className = "" >
110+ { p . github && (
111+ < a
112+ href = { p . github }
113+ target = "_blank"
114+ className = "flex items-center gap-2"
115+ >
116+ < svg
117+ width = "24"
118+ height = "23"
119+ viewBox = "0 0 24 23"
120+ fill = "none"
121+ xmlns = "http://www.w3.org/2000/svg"
122+ className = "w-5"
78123 >
79- < svg
80- width = "24"
81- height = "23 "
82- viewBox = "0 0 24 23"
83- fill = "none"
84- xmlns = "http://www.w3.org/2000/svg"
85- className = "w-5"
86- >
87- < path
88- d = "M11.7599 0C8.96748 0.0001 6.26618 0.9939 4.13948 2.8034C2.01268 4.6129 0.599183 7.1202 0.151883 9.8766C-0.295417 12.6329 0.252683 15.4585 1.69808 17.8478C3.14338 20.2369 5.39178 22.0339 8.04088 22.9171C8.62888 23.02 8.84938 22.6672 8.84938 22.3585C8.84938 22.0792 8.83468 21.1531 8.83468 20.1682C5.87998 20.7121 5.11558 19.448 4.88038 18.7865C4.61938 18.1432 4.20568 17.5731 3.67498 17.1254C3.26338 16.9049 2.67538 16.361 3.66028 16.3463C4.03638 16.3871 4.39698 16.518 4.71178 16.7278C5.02648 16.9376 5.28608 17.2203 5.46838 17.5517C5.62918 17.8406 5.84548 18.095 6.10478 18.3002C6.36408 18.5054 6.66138 18.6575 6.97958 18.7475C7.29778 18.8376 7.63058 18.8641 7.95898 18.8254C8.28738 18.7867 8.60498 18.6836 8.89338 18.5219C8.94428 17.924 9.21078 17.365 9.64318 16.949C7.02658 16.655 4.29238 15.6407 4.29238 11.1425C4.27588 9.9738 4.70708 8.843 5.49778 7.9821C5.13828 6.9663 5.18028 5.8515 5.61538 4.8657C5.61538 4.8657 6.60018 4.557 8.84938 6.0711C10.7736 5.5419 12.805 5.5419 14.7293 6.0711C16.9784 4.5423 17.9633 4.8657 17.9633 4.8657C18.3984 5.8515 18.4405 6.9663 18.0809 7.9821C18.8738 8.8415 19.3056 9.9734 19.2863 11.1425C19.2863 15.6554 16.5374 16.655 13.9208 16.949C14.2014 17.2334 14.4175 17.575 14.5545 17.9503C14.6915 18.3258 14.7461 18.7263 14.7146 19.1246C14.7146 20.6976 14.6999 21.9616 14.6999 22.3585C14.6999 22.6672 14.9204 23.0347 15.5084 22.9171C18.1528 22.0268 20.3947 20.2256 21.8339 17.8352C23.2732 15.4447 23.816 12.6205 23.3656 9.8668C22.9152 7.1132 21.5009 4.6092 19.375 2.8019C17.2492 0.9945 14.5502 0.0015 11.7599 0Z"
89- fill = "#F1F1F5"
90- />
91- </ svg > { " " }
92- Github
93- </ a >
94- ) }
95- </ div >
96- < div className = "" >
97- { p . link && (
98- < a
99- href = { p . link }
100- target = "_blank "
101- className = "flex items-center gap-2 "
124+ < path
125+ d = "M11.7599 0C8.96748 0.0001 6.26618 0.9939 4.13948 2.8034C2.01268 4.6129 0.599183 7.1202 0.151883 9.8766C-0.295417 12.6329 0.252683 15.4585 1.69808 17.8478C3.14338 20.2369 5.39178 22.0339 8.04088 22.9171C8.62888 23.02 8.84938 22.6672 8.84938 22.3585C8.84938 22.0792 8.83468 21.1531 8.83468 20.1682C5.87998 20.7121 5.11558 19.448 4.88038 18.7865C4.61938 18.1432 4.20568 17.5731 3.67498 17.1254C3.26338 16.9049 2.67538 16.361 3.66028 16.3463C4.03638 16.3871 4.39698 16.518 4.71178 16.7278C5.02648 16.9376 5.28608 17.2203 5.46838 17.5517C5.62918 17.8406 5.84548 18.095 6.10478 18.3002C6.36408 18.5054 6.66138 18.6575 6.97958 18.7475C7.29778 18.8376 7.63058 18.8641 7.95898 18.8254C8.28738 18.7867 8.60498 18.6836 8.89338 18.5219C8.94428 17.924 9.21078 17.365 9.64318 16.949C7.02658 16.655 4.29238 15.6407 4.29238 11.1425C4.27588 9.9738 4.70708 8.843 5.49778 7.9821C5.13828 6.9663 5.18028 5.8515 5.61538 4.8657C5.61538 4.8657 6.60018 4.557 8.84938 6.0711C10.7736 5.5419 12.805 5.5419 14.7293 6.0711C16.9784 4.5423 17.9633 4.8657 17.9633 4.8657C18.3984 5.8515 18.4405 6.9663 18.0809 7.9821C18.8738 8.8415 19.3056 9.9734 19.2863 11.1425C19.2863 15.6554 16.5374 16.655 13.9208 16.949C14.2014 17.2334 14.4175 17.575 14.5545 17.9503C14.6915 18.3258 14.7461 18.7263 14.7146 19.1246C14.7146 20.6976 14.6999 21.9616 14.6999 22.3585C14.6999 22.6672 14.9204 23.0347 15.5084 22.9171C18.1528 22.0268 20.3947 20.2256 21.8339 17.8352C23.2732 15.4447 23.816 12.6205 23.3656 9.8668C22.9152 7.1132 21.5009 4.6092 19.375 2.8019C17.2492 0.9945 14.5502 0.0015 11.7599 0Z"
126+ fill = "#F1F1F5 "
127+ />
128+ </ svg > { " " }
129+ Github
130+ </ a >
131+ ) }
132+ </ div >
133+ < div className = "" >
134+ { p . link && (
135+ < a
136+ href = { p . link }
137+ target = "_blank"
138+ className = "flex items-center gap-2"
139+ >
140+ < svg
141+ width = "25"
142+ height = "24"
143+ viewBox = "0 0 25 24"
144+ fill = "none"
145+ xmlns = "http://www.w3.org/2000/svg "
146+ className = "w-5 "
102147 >
103- < svg
104- width = "25"
105- height = "24"
106- viewBox = "0 0 25 24"
107- fill = "none"
108- xmlns = "http://www.w3.org/2000/svg"
109- className = "w-5"
110- >
111- < path
112- d = "M10.5195 13C10.949 13.5742 11.4969 14.0492 12.1261 14.393C12.7553 14.7367 13.451 14.9411 14.1662 14.9924C14.8813 15.0436 15.5991 14.9404 16.2709 14.6898C16.9426 14.4392 17.5526 14.0471 18.0595 13.54L21.0595 10.54C21.9703 9.59702 22.4743 8.334 22.4629 7.02302C22.4515 5.71204 21.9257 4.45797 20.9986 3.53093C20.0716 2.60389 18.8175 2.07805 17.5065 2.06666C16.1956 2.05526 14.9325 2.55924 13.9895 3.47003L12.2695 5.18003"
113- stroke = "#F1F1F5"
114- strokeWidth = "2"
115- strokeLinecap = "round"
116- strokeLinejoin = "round"
117- />
118- < path
119- d = "M14.5197 11C14.0903 10.4259 13.5424 9.9508 12.9132 9.60704C12.284 9.26328 11.5882 9.05886 10.8731 9.00765C10.1579 8.95643 9.44014 9.05961 8.76839 9.3102C8.09663 9.56079 7.48662 9.95291 6.97973 10.46L3.97973 13.46C3.06894 14.403 2.56497 15.666 2.57636 16.977C2.58775 18.288 3.1136 19.542 4.04064 20.4691C4.96768 21.3961 6.22174 21.922 7.53272 21.9334C8.84371 21.9447 10.1067 21.4408 11.0497 20.53L12.7597 18.82"
120- stroke = "#F1F1F5"
121- strokeWidth = "2"
122- strokeLinecap = "round"
123- strokeLinejoin = "round"
124- />
125- </ svg >
126- App
127- </ a >
128- ) }
129- </ div >
130- < div className = "font-pp text-pink text-3xl" > { p . score } </ div >
148+ < path
149+ d = "M10.5195 13C10.949 13.5742 11.4969 14.0492 12.1261 14.393C12.7553 14.7367 13.451 14.9411 14.1662 14.9924C14.8813 15.0436 15.5991 14.9404 16.2709 14.6898C16.9426 14.4392 17.5526 14.0471 18.0595 13.54L21.0595 10.54C21.9703 9.59702 22.4743 8.334 22.4629 7.02302C22.4515 5.71204 21.9257 4.45797 20.9986 3.53093C20.0716 2.60389 18.8175 2.07805 17.5065 2.06666C16.1956 2.05526 14.9325 2.55924 13.9895 3.47003L12.2695 5.18003"
150+ stroke = "#F1F1F5"
151+ strokeWidth = "2"
152+ strokeLinecap = "round"
153+ strokeLinejoin = "round"
154+ />
155+ < path
156+ d = "M14.5197 11C14.0903 10.4259 13.5424 9.9508 12.9132 9.60704C12.284 9.26328 11.5882 9.05886 10.8731 9.00765C10.1579 8.95643 9.44014 9.05961 8.76839 9.3102C8.09663 9.56079 7.48662 9.95291 6.97973 10.46L3.97973 13.46C3.06894 14.403 2.56497 15.666 2.57636 16.977C2.58775 18.288 3.1136 19.542 4.04064 20.4691C4.96768 21.3961 6.22174 21.922 7.53272 21.9334C8.84371 21.9447 10.1067 21.4408 11.0497 20.53L12.7597 18.82"
157+ stroke = "#F1F1F5"
158+ strokeWidth = "2"
159+ strokeLinecap = "round"
160+ strokeLinejoin = "round"
161+ />
162+ </ svg >
163+ App
164+ </ a >
165+ ) }
131166 </ div >
132- ) ) }
167+ < div className = "text-pink flex flex-col md:items-end" >
168+ < div className = "md:hidden" > Score</ div >
169+ < span className = "font-pp text-3xl" > { p . score } </ span >
170+ </ div >
171+ </ div >
172+ ) ) }
133173 </ div >
134174 </ div >
135175 ) }
0 commit comments