@@ -17,31 +17,9 @@ import { useFilterStore } from "@/store/useFilterStore";
1717import { usePathname } from "next/navigation" ;
1818import { MagnifyingGlassIcon } from "@heroicons/react/24/outline" ;
1919
20- type ProjectsContainerProps = {
21- projects : DashboardProjectsProps [ ] ;
22- } ;
23-
24- interface languageColorsTypes {
25- [ key : string ] : string ;
26- javascript : string ;
27- typescript : string ;
28- python : string ;
29- go : string ;
30- rust : string ;
31- java : string ;
32- "c#" : string ;
33- "c++" : string ;
34- c : string ;
35- php : string ;
36- swift : string ;
37- kotlin : string ;
38- ruby : string ;
39- scala : string ;
40- html : string ;
41- elixir : string ;
42- }
20+ type ProjectsContainerProps = { projects : DashboardProjectsProps [ ] } ;
4321
44- const languageColors : languageColorsTypes = {
22+ const languageColors : Record < string , string > = {
4523 javascript : "bg-yellow-500/15 text-yellow-500" ,
4624 typescript : "bg-blue-500/15 text-blue-500" ,
4725 python : "bg-emerald-500/15 text-emerald-500" ,
@@ -60,11 +38,8 @@ const languageColors: languageColorsTypes = {
6038 elixir : "bg-purple-600/15 text-purple-600" ,
6139} ;
6240
63- const getColor = ( color : string ) : string => {
64- const lowerColorCase = color . toLowerCase ( ) ;
65- const _color = languageColors [ lowerColorCase ] || "bg-gray-200 text-gray-800" ;
66- return _color ;
67- } ;
41+ const getColor = ( c ?: string ) =>
42+ languageColors [ ( c || "" ) . toLowerCase ( ) ] || "bg-gray-200/10 text-gray-300" ;
6843
6944const tableColumns = [
7045 "Project" ,
@@ -82,15 +57,10 @@ export default function ProjectsContainer({
8257 const pathname = usePathname ( ) ;
8358 const { projectTitle } = useProjectTitleStore ( ) ;
8459 const { setShowFilters } = useFilterStore ( ) ;
85-
86- const handleClick = ( link : string ) => {
87- window . open ( link , "_blank" ) ;
88- } ;
89-
9060 const isProjectsPage = pathname === "/dashboard/projects" ;
9161
9262 return (
93- < div className = "w-full p-6 sm:p-8 " >
63+ < div className = "w-full p-6 sm:p-6 " >
9464 < div className = "flex items-center justify-between pb-6" >
9565 < h2 className = "text-xl sm:text-2xl md:text-3xl font-semibold text-white tracking-tight" >
9666 { projectTitle }
@@ -104,66 +74,88 @@ export default function ProjectsContainer({
10474 </ Button >
10575 ) }
10676 </ div >
77+
10778 { projects && projects . length > 0 ? (
108- < div className = "w-full overflow-x-auto bg-[#15161a] border border-[#1a1a1d] rounded-lg" >
109- < Table className = "w-full" >
110- < TableHeader className = "w-full border" >
111- < TableRow className = "w-full border-[#1a1a1d] border-b" >
112- { tableColumns . map ( ( name , index ) => (
79+ < div
80+ className = "
81+ w-full bg-[#15161a] border border-[#1a1a1d] rounded-lg
82+ h-[80vh] overflow-y-auto overflow-x-auto relative
83+ [&::-webkit-scrollbar]:w-1
84+ [&::-webkit-scrollbar]:hover:w-2
85+ [&::-webkit-scrollbar]:h-1
86+ [&::-webkit-scrollbar-track]:bg-transparent
87+ [&::-webkit-scrollbar-thumb]:bg-ox-purple/30
88+ [&::-webkit-scrollbar-thumb]:rounded-full
89+ [&::-webkit-scrollbar-thumb]:hover:bg-ox-purple/50
90+ "
91+ >
92+ < Table className = "w-full min-w-[820px] table-fixed" >
93+ { /* Sticky header row */ }
94+ < TableHeader >
95+ < TableRow className = "border-b border-[#1a1a1d]" >
96+ { tableColumns . map ( ( name , i ) => (
11397 < TableHead
114- key = { index }
115- className = { `flex-1 text-center font-semibold text-ox-purple text-[12px] sm:text-sm` }
98+ key = { name }
99+ className = { [
100+ "px-3 py-3 font-semibold text-ox-purple text-[12px] sm:text-sm whitespace-nowrap" ,
101+ "sticky top-0 z-30 bg-[#15161a]" , // <- stick
102+ i === 0 ? "text-left" : "text-center" ,
103+ ] . join ( " " ) }
116104 >
117105 { name }
118106 </ TableHead >
119107 ) ) }
120108 </ TableRow >
121109 </ TableHeader >
110+
122111 < TableBody >
123- { projects . map ( ( project ) => (
112+ { projects . map ( ( p ) => (
124113 < TableRow
125- key = { project . id }
126- className = "border-ox-gray border-y cursor-pointer"
127- onClick = { ( ) => {
128- handleClick ( project . url ) ;
129- } }
114+ key = { p . id }
115+ className = "border-y border-ox-gray cursor-pointer hover:bg-white/5 transition-colors"
116+ onClick = { ( ) => window . open ( p . url , "_blank" ) }
130117 >
131- < TableCell className = "flex items-center gap-1 p-1 sm:p-2" >
132- < div className = "rounded-full overflow-hidden inline-block h-4 w-4 sm:h-6 sm:w-6 border" >
133- < Image
134- src = { project . avatarUrl }
135- className = "w-full h-full object-cover"
136- alt = { project . name }
137- width = { 10 }
138- height = { 10 }
139- />
118+ < TableCell className = "p-1 sm:p-2" >
119+ < div className = "flex items-center gap-2" >
120+ < div className = "rounded-full overflow-hidden inline-block h-4 w-4 sm:h-6 sm:w-6 border" >
121+ < Image
122+ src = { p . avatarUrl }
123+ className = "w-full h-full object-cover"
124+ alt = { p . name }
125+ width = { 24 }
126+ height = { 24 }
127+ />
128+ </ div >
129+ < span className = "text-white text-[10px] sm:text-xs font-semibold" >
130+ { p . name }
131+ </ span >
140132 </ div >
141- < TableCell className = "text-white text-[10px] sm:text-xs text-ox-white font-semibold" >
142- { project . name }
143- </ TableCell >
144133 </ TableCell >
145- < TableCell className = "text-white text-[10px] sm:text-xs text-center text-ox-white p-1 sm:p-2" >
146- { project . totalIssueCount }
134+
135+ < TableCell className = "text-white text-[10px] sm:text-xs text-center p-1 sm:p-2 whitespace-nowrap" >
136+ { p . totalIssueCount }
147137 </ TableCell >
138+
148139 < TableCell className = "text-center p-1 sm:p-2" >
149140 < Badge
150141 variant = "secondary"
151- className = { `${ getColor ( project . primaryLanguage ) } text-[10px] sm:text-xs` }
142+ className = { `${ getColor ( p . primaryLanguage ) } text-[10px] sm:text-xs whitespace-nowrap ` }
152143 >
153- { project . primaryLanguage }
144+ { p . primaryLanguage }
154145 </ Badge >
155146 </ TableCell >
156- < TableCell className = "text-white text-[10px] sm:text-xs text-center text-ox-white font-semibold p-1 sm:p-2" >
157- { project . popularity }
147+
148+ < TableCell className = "text-white text-[10px] sm:text-xs text-center font-semibold p-1 sm:p-2 whitespace-nowrap" >
149+ { p . popularity }
158150 </ TableCell >
159- < TableCell className = "text-white text-[10px] sm:text-xs text-center text-ox-white font-semibold md:table-cell p-1 sm:p-2" >
160- { project . stage }
151+ < TableCell className = "text-white text-[10px] sm:text-xs text-center font-semibold p-1 sm:p-2 whitespace-nowrap " >
152+ { p . stage }
161153 </ TableCell >
162- < TableCell className = "text-white text-[10px] sm:text-xs text-center text-ox-white font-semibold md:table-cell p-1 sm:p-2" >
163- { project . competition }
154+ < TableCell className = "text-white text-[10px] sm:text-xs text-center font-semibold p-1 sm:p-2 whitespace-nowrap " >
155+ { p . competition }
164156 </ TableCell >
165- < TableCell className = "text-white text-[10px] sm:text-xs text-center text-ox-white font-semibold md:table-cell p-1 sm:p-2" >
166- { project . activity }
157+ < TableCell className = "text-white text-[10px] sm:text-xs text-center font-semibold p-1 sm:p-2 whitespace-nowrap " >
158+ { p . activity }
167159 </ TableCell >
168160 </ TableRow >
169161 ) ) }
0 commit comments