@@ -18,6 +18,12 @@ import {
1818 AlertDialogHeader ,
1919 AlertDialogTitle ,
2020} from "@/components/ui/alert-dialog" ;
21+ import {
22+ Tooltip ,
23+ TooltipContent ,
24+ TooltipProvider ,
25+ TooltipTrigger ,
26+ } from "@/components/ui/tooltip" ;
2127
2228const DiscordIcon = ( { className = "" } ) => (
2329 < svg
@@ -85,32 +91,50 @@ const LanguageBar = ({ languages }: { languages: Language }) => {
8591 < div className = "space-y-4" >
8692 < h2 className = "text-lg font-semibold text-white" > Languages</ h2 >
8793
88- < div className = "h-2 w-full flex rounded-full overflow-hidden" >
89- { percentages . map ( ( { name, percentage } ) => (
90- < div
91- key = { name }
92- style = { {
93- width : `${ percentage } %` ,
94- backgroundColor : languageColors [ name ] || '#ededed'
95- } }
96- />
97- ) ) }
98- </ div >
94+ < TooltipProvider >
95+ < div className = "h-2 w-full flex rounded-full overflow-hidden" >
96+ { percentages . map ( ( { name, percentage } ) => (
97+ < Tooltip key = { name } delayDuration = { 0 } >
98+ < TooltipTrigger asChild >
99+ < div
100+ style = { {
101+ width : `${ percentage } %` ,
102+ backgroundColor : languageColors [ name ] || '#ededed'
103+ } }
104+ className = "transition-opacity hover:opacity-80"
105+ />
106+ </ TooltipTrigger >
107+ < TooltipContent
108+ className = "bg-slate-800 border-slate-700 text-white"
109+ side = "top"
110+ >
111+ < div className = "flex items-center gap-2" >
112+ < div
113+ className = "w-3 h-3 rounded-full"
114+ style = { { backgroundColor : languageColors [ name ] || '#ededed' } }
115+ />
116+ < span > { name } : { percentage . toFixed ( 1 ) } %</ span >
117+ </ div >
118+ </ TooltipContent >
119+ </ Tooltip >
120+ ) ) }
121+ </ div >
122+ </ TooltipProvider >
99123
100124 < div className = "flex flex-wrap gap-4" >
101- { percentages
102- . filter ( ( { percentage } ) => percentage >= 2 )
103- . map ( ( { name, percentage } ) => (
104- < div key = { name } className = "flex items-center gap-2" >
105- < span
106- className = "w-3 h-3 rounded-full"
107- style = { { backgroundColor : languageColors [ name ] || '#ededed' } }
108- />
109- < span className = "font-medium text-white" > { name } </ span >
110- < span className = "text-gray-400" > { percentage . toFixed ( 1 ) } %</ span >
125+ { percentages
126+ . filter ( ( { percentage } ) => percentage >= 2 )
127+ . map ( ( { name, percentage } ) => (
128+ < div key = { name } className = "flex items-center gap-2" >
129+ < span
130+ className = "w-3 h-3 rounded-full"
131+ style = { { backgroundColor : languageColors [ name ] || '#ededed' } }
132+ />
133+ < span className = "font-medium text-white" > { name } </ span >
134+ < span className = "text-gray-400" > { percentage . toFixed ( 1 ) } %</ span >
135+ </ div >
136+ ) ) }
111137 </ div >
112- ) ) }
113- </ div >
114138 </ div >
115139 ) ;
116140} ;
@@ -272,70 +296,70 @@ export default function GithubProjectsPage() {
272296 </ div >
273297
274298 < div className = "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8 mb-8" >
275- { currentProjects . map ( ( project ) => {
276- const isSaved = savedProjects . includes ( project . name ) ;
277- return (
299+ { currentProjects . map ( ( project ) => {
300+ const isSaved = savedProjects . includes ( project . name ) ;
301+ return (
302+ < div
303+ key = { project . name }
304+ className = "group relative cursor-pointer"
305+ onClick = { ( ) => handleCardClick ( project . url ) }
306+ >
307+ < div className = { `absolute inset-0 ${ project . color } rounded-xl blur-md opacity-20 group-hover:opacity-30 transition-all duration-500` } > </ div >
308+ < Card className = "relative h-full bg-slate-800/50 border-slate-700 hover:border-slate-600 transition-all duration-500 backdrop-blur-sm transform-gpu hover:-translate-y-2 hover:scale-105" >
309+ < CardContent className = "p-6" >
310+ < div className = "flex justify-between items-start mb-4" >
311+ < h2 className = "text-2xl font-bold text-white group-hover:text-transparent group-hover:bg-gradient-to-r group-hover:from-blue-400 group-hover:via-purple-400 group-hover:to-pink-400 group-hover:bg-clip-text transition-all duration-300" >
312+ { project . name }
313+ </ h2 >
314+ < Button
315+ variant = "ghost"
316+ size = "sm"
317+ className = { `text-gray-400 ${ isSaved ? 'text-green-500' : 'hover:text-white' } ` }
318+ onClick = { ( e ) => {
319+ e . stopPropagation ( ) ;
320+ if ( isSaved ) {
321+ removeProject ( project . name ) ;
322+ } else {
323+ addProject ( project . name ) ;
324+ }
325+ } }
326+ >
327+ { isSaved ? 'Unsave' : 'Save' }
328+ </ Button >
329+ </ div >
330+ < p className = "text-gray-300 mb-6" > { project . description } </ p >
331+ < div className = "flex flex-wrap gap-2 mb-6" >
332+ { project . tags . map ( ( tag , tagIndex ) => (
278333 < div
279- key = { project . name }
280- className = "group relative cursor-pointer"
281- onClick = { ( ) => handleCardClick ( project . url ) }
334+ key = { tagIndex }
335+ onClick = { ( e ) => {
336+ e . stopPropagation ( ) ;
337+ setSearchTerm ( tag ) ;
338+ } }
339+ className = "bg-slate-700/50 text-gray-300 text-sm px-3 py-1 rounded-full flex items-center transform transition-all duration-300 hover:scale-105 hover:bg-slate-600/50"
282340 >
283- < div className = { `absolute inset-0 ${ project . color } rounded-xl blur-md opacity-20 group-hover:opacity-30 transition-all duration-500` } > </ div >
284- < Card className = "relative h-full bg-slate-800/50 border-slate-700 hover:border-slate-600 transition-all duration-500 backdrop-blur-sm transform-gpu hover:-translate-y-2 hover:scale-105" >
285- < CardContent className = "p-6" >
286- < div className = "flex justify-between items-start mb-4" >
287- < h2 className = "text-2xl font-bold text-white group-hover:text-transparent group-hover:bg-gradient-to-r group-hover:from-blue-400 group-hover:via-purple-400 group-hover:to-pink-400 group-hover:bg-clip-text transition-all duration-300" >
288- { project . name }
289- </ h2 >
290- < Button
291- variant = "ghost"
292- size = "sm"
293- className = { `text-gray-400 ${ isSaved ? 'text-green-500' : 'hover:text-white' } ` }
294- onClick = { ( e ) => {
295- e . stopPropagation ( ) ;
296- if ( isSaved ) {
297- removeProject ( project . name ) ;
298- } else {
299- addProject ( project . name ) ;
300- }
301- } }
302- >
303- { isSaved ? 'Unsave' : 'Save' }
304- </ Button >
305- </ div >
306-
307- < p className = "text-gray-300 mb-6" > { project . description } </ p >
308-
309- < div className = "flex flex-wrap gap-2 mb-6" >
310- { project . tags . map ( ( tag , tagIndex ) => (
311- < div
312- key = { tagIndex }
313- className = "bg-slate-700/50 text-gray-300 text-sm px-3 py-1 rounded-full flex items-center transform transition-all duration-300 hover:scale-105 hover:bg-slate-600/50"
314- >
315- < Tag className = "h-3 w-3 mr-1.5" />
316- { tag }
317- </ div >
318- ) ) }
319- </ div >
320-
321- < LanguageBar languages = { project . languages } />
322-
323- < div className = "flex justify-start gap-6 text-sm text-gray-400 mt-6" >
324- < span className = "flex items-center" >
325- < Star className = "h-4 w-4 mr-1.5 text-yellow-500" />
326- { project . stars }
327- </ span >
328- < span className = "flex items-center" >
329- < GitFork className = "h-4 w-4 mr-1.5" />
330- { project . forks }
331- </ span >
332- </ div >
333- </ CardContent >
334- </ Card >
341+ < Tag className = "h-3 w-3 mr-1.5" />
342+ { tag }
335343 </ div >
336- ) ;
337- } ) }
338- </ div >
344+ ) ) }
345+ </ div >
346+ < LanguageBar languages = { project . languages } />
347+ < div className = "flex justify-start gap-6 text-sm text-gray-400 mt-6" >
348+ < span className = "flex items-center" >
349+ < Star className = "h-4 w-4 mr-1.5 text-yellow-500" />
350+ { project . stars }
351+ </ span >
352+ < span className = "flex items-center" >
353+ < GitFork className = "h-4 w-4 mr-1.5" />
354+ { project . forks }
355+ </ span >
356+ </ div >
357+ </ CardContent >
358+ </ Card >
359+ </ div >
360+ ) ;
361+ } ) }
362+ </ div >
339363
340364 < div className = "flex justify-center gap-4 mb-16" >
341365 < Button
0 commit comments