@@ -12,80 +12,79 @@ interface RepoListProps {
1212
1313const StatusBadge = ( { status } : { status : string } ) => {
1414 const isIndexed = status === 'indexed'
15- const isPending = status === 'cloned' || status === 'cloning' || status === 'indexing'
15+
16+ if ( isIndexed ) {
17+ return (
18+ < span className = "inline-flex items-center gap-1.5 px-2.5 py-1 text-xs font-medium rounded-full bg-blue-500/10 text-blue-400 border border-blue-500/20" >
19+ < span className = "w-1.5 h-1.5 rounded-full bg-blue-400" />
20+ Indexed
21+ </ span >
22+ )
23+ }
1624
1725 return (
18- < span className = { `inline-flex items-center gap-1.5 px-2.5 py-1 text-xs font-medium rounded-full border
19- ${ isIndexed
20- ? 'bg-blue-500/10 text-blue-400 border-blue-500/20'
21- : isPending
22- ? 'bg-zinc-500/10 text-zinc-400 border-zinc-500/20'
23- : 'bg-red-500/10 text-red-400 border-red-500/20'
24- } `}
25- >
26- < span className = { `w-1.5 h-1.5 rounded-full ${ isIndexed ? 'bg-blue-400' : isPending ? 'bg-zinc-400 animate-pulse' : 'bg-red-400' } ` } />
27- { isIndexed ? 'Indexed' : isPending ? 'Pending' : 'Error' }
26+ < span className = "inline-flex items-center gap-1.5 px-2.5 py-1 text-xs font-medium rounded-full bg-zinc-800 text-zinc-400 border border-zinc-700" >
27+ < span className = "w-1.5 h-1.5 rounded-full bg-zinc-500 animate-pulse" />
28+ Pending
2829 </ span >
2930 )
3031}
3132
33+ // Featured card - tall, prominent
3234const FeaturedRepoCard = ( { repo, totalFunctions, onSelect } : {
3335 repo : Repository
3436 totalFunctions : number
3537 onSelect : ( ) => void
3638} ) => {
3739 const cardRef = useRef < HTMLButtonElement > ( null )
38- const [ mousePosition , setMousePosition ] = useState ( { x : 0 , y : 0 } )
39- const [ isHovering , setIsHovering ] = useState ( false )
40- const percentage = totalFunctions > 0 ? Math . round ( ( repo . file_count || 0 ) / totalFunctions * 100 ) : 0
41-
42- const handleMouseMove = ( e : React . MouseEvent ) => {
43- if ( ! cardRef . current ) return
44- const rect = cardRef . current . getBoundingClientRect ( )
45- setMousePosition ( { x : e . clientX - rect . left , y : e . clientY - rect . top } )
46- }
40+ const [ mousePos , setMousePos ] = useState ( { x : 0 , y : 0 } )
41+ const [ hovering , setHovering ] = useState ( false )
42+ const pct = totalFunctions > 0 ? Math . round ( ( repo . file_count || 0 ) / totalFunctions * 100 ) : 0
4743
4844 return (
4945 < motion . button
5046 ref = { cardRef }
5147 initial = { { opacity : 0 , y : 20 } }
5248 animate = { { opacity : 1 , y : 0 } }
53- transition = { { duration : 0.4 } }
54- whileHover = { { y : - 2 } }
49+ whileHover = { { y : - 3 } }
5550 onClick = { onSelect }
56- onMouseMove = { handleMouseMove }
57- onMouseEnter = { ( ) => setIsHovering ( true ) }
58- onMouseLeave = { ( ) => setIsHovering ( false ) }
59- className = "group relative text-left rounded-2xl overflow-hidden w-full h-full
60- bg-[#111113] border border-white/[0.06] hover:border-blue-500/30
61- focus:outline-none focus:ring-2 focus:ring-blue-500/40 p-6"
51+ onMouseMove = { ( e ) => {
52+ if ( ! cardRef . current ) return
53+ const rect = cardRef . current . getBoundingClientRect ( )
54+ setMousePos ( { x : e . clientX - rect . left , y : e . clientY - rect . top } )
55+ } }
56+ onMouseEnter = { ( ) => setHovering ( true ) }
57+ onMouseLeave = { ( ) => setHovering ( false ) }
58+ className = "group relative text-left rounded-2xl overflow-hidden w-full h-full min-h-[300px]
59+ bg-[#111113] border border-white/[0.06] hover:border-blue-500/40
60+ focus:outline-none focus:ring-2 focus:ring-blue-500/50 p-6 transition-colors"
6261 >
63- { /* Mouse glow */ }
64- { isHovering && (
62+ { /* Mouse glow - BLUE only */ }
63+ { hovering && (
6564 < div
66- className = "pointer-events-none absolute inset-0 transition-opacity duration-300 "
65+ className = "pointer-events-none absolute inset-0"
6766 style = { {
68- background : `radial-gradient(400px circle at ${ mousePosition . x } px ${ mousePosition . y } px, rgba(59, 130, 246 , 0.08 ), transparent 50%)` ,
67+ background : `radial-gradient(500px circle at ${ mousePos . x } px ${ mousePos . y } px, rgba(37, 99, 235 , 0.1 ), transparent 50%)` ,
6968 } }
7069 />
7170 ) }
7271
73- { /* Top gradient line */ }
74- < div className = "absolute top-0 left-0 right-0 h-[2px] bg-gradient-to-r from- blue-500 to-violet -500" />
72+ { /* Top accent - solid blue */ }
73+ < div className = "absolute top-0 left-0 right-0 h-[2px] bg-blue-500" />
7574
7675 < div className = "relative flex flex-col h-full" >
7776 { /* Header */ }
7877 < div className = "flex items-start justify-between mb-6" >
79- < div className = "w-14 h-14 rounded-xl bg-gradient-to-br from- blue-500/10 to-violet-500/10 border border-white/[0.08] flex items-center justify-center" >
80- < svg className = "w-7 h-7 text-blue-400 " fill = "none" viewBox = "0 0 24 24" stroke = "currentColor" >
78+ < div className = "w-14 h-14 rounded-xl bg-blue-500/10 border border-blue-500/20 flex items-center justify-center" >
79+ < svg className = "w-7 h-7 text-blue-500 " fill = "none" viewBox = "0 0 24 24" stroke = "currentColor" >
8180 < path strokeLinecap = "round" strokeLinejoin = "round" strokeWidth = { 1.5 } d = "M3 7v10a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2h-6l-2-2H5a2 2 0 00-2 2z" />
8281 </ svg >
8382 </ div >
8483 < StatusBadge status = { repo . status } />
8584 </ div >
8685
8786 { /* Title */ }
88- < h3 className = "text-xl font-semibold text-white mb-1 group-hover:text-blue-400 transition-colors" >
87+ < h3 className = "text-2xl font-semibold text-white mb-1 group-hover:text-blue-400 transition-colors" >
8988 { repo . name }
9089 </ h3 >
9190 < p className = "text-sm text-zinc-500 font-mono mb-auto" > { repo . branch } </ p >
@@ -94,22 +93,23 @@ const FeaturedRepoCard = ({ repo, totalFunctions, onSelect }: {
9493 < div className = "pt-6 mt-6 border-t border-white/[0.06]" >
9594 < div className = "flex items-end justify-between mb-3" >
9695 < span className = "text-sm text-zinc-500" > Functions indexed</ span >
97- < span className = "text-3xl font-bold text-transparent bg-clip-text bg-gradient-to-r from- blue-400 to-violet-400 " >
96+ < span className = "text-4xl font-bold text-blue-500 " >
9897 { ( repo . file_count || 0 ) . toLocaleString ( ) }
9998 </ span >
10099 </ div >
101100
101+ { /* Progress bar */ }
102102 { totalFunctions > 0 && repo . file_count > 0 && (
103103 < div className = "space-y-2" >
104- < div className = "h-1 bg-white/[0.06] rounded-full overflow-hidden" >
104+ < div className = "h-1.5 bg-zinc-800 rounded-full overflow-hidden" >
105105 < motion . div
106106 initial = { { width : 0 } }
107- animate = { { width : `${ percentage } %` } }
108- transition = { { duration : 0.8 , ease : "easeOut" , delay : 0.2 } }
109- className = "h-full bg-gradient-to-r from- blue-500 to-violet -500 rounded-full"
107+ animate = { { width : `${ pct } %` } }
108+ transition = { { duration : 0.8 , ease : "easeOut" , delay : 0.3 } }
109+ className = "h-full bg-blue-500 rounded-full"
110110 />
111111 </ div >
112- < p className = "text-xs text-zinc-600" > { percentage } % of total</ p >
112+ < p className = "text-xs text-zinc-600" > { pct } % of total indexed </ p >
113113 </ div >
114114 ) }
115115 </ div >
@@ -118,51 +118,50 @@ const FeaturedRepoCard = ({ repo, totalFunctions, onSelect }: {
118118 )
119119}
120120
121+ // Regular card - compact
121122const RepoCard = ( { repo, index, onSelect } : {
122123 repo : Repository
123124 index : number
124125 onSelect : ( ) => void
125126} ) => {
126127 const cardRef = useRef < HTMLButtonElement > ( null )
127- const [ mousePosition , setMousePosition ] = useState ( { x : 0 , y : 0 } )
128- const [ isHovering , setIsHovering ] = useState ( false )
129-
130- const handleMouseMove = ( e : React . MouseEvent ) => {
131- if ( ! cardRef . current ) return
132- const rect = cardRef . current . getBoundingClientRect ( )
133- setMousePosition ( { x : e . clientX - rect . left , y : e . clientY - rect . top } )
134- }
128+ const [ mousePos , setMousePos ] = useState ( { x : 0 , y : 0 } )
129+ const [ hovering , setHovering ] = useState ( false )
135130
136131 return (
137132 < motion . button
138133 ref = { cardRef }
139134 initial = { { opacity : 0 , y : 20 } }
140135 animate = { { opacity : 1 , y : 0 } }
141- transition = { { delay : index * 0.1 , duration : 0.4 } }
142- whileHover = { { y : - 2 } }
136+ transition = { { delay : index * 0.1 } }
137+ whileHover = { { y : - 3 } }
143138 onClick = { onSelect }
144- onMouseMove = { handleMouseMove }
145- onMouseEnter = { ( ) => setIsHovering ( true ) }
146- onMouseLeave = { ( ) => setIsHovering ( false ) }
147- className = "group relative text-left rounded-2xl overflow-hidden w-full
148- bg-[#111113] border border-white/[0.06] hover:border-white/[0.12]
149- focus:outline-none focus:ring-2 focus:ring-blue-500/40 p-5"
139+ onMouseMove = { ( e ) => {
140+ if ( ! cardRef . current ) return
141+ const rect = cardRef . current . getBoundingClientRect ( )
142+ setMousePos ( { x : e . clientX - rect . left , y : e . clientY - rect . top } )
143+ } }
144+ onMouseEnter = { ( ) => setHovering ( true ) }
145+ onMouseLeave = { ( ) => setHovering ( false ) }
146+ className = "group relative text-left rounded-2xl overflow-hidden w-full h-full
147+ bg-[#111113] border border-white/[0.06] hover:border-white/[0.15]
148+ focus:outline-none focus:ring-2 focus:ring-blue-500/50 p-5 transition-colors"
150149 >
151150 { /* Mouse glow */ }
152- { isHovering && (
151+ { hovering && (
153152 < div
154- className = "pointer-events-none absolute inset-0 transition-opacity duration-300 "
153+ className = "pointer-events-none absolute inset-0"
155154 style = { {
156- background : `radial-gradient(250px circle at ${ mousePosition . x } px ${ mousePosition . y } px, rgba(59, 130, 246 , 0.06 ), transparent 50%)` ,
155+ background : `radial-gradient(300px circle at ${ mousePos . x } px ${ mousePos . y } px, rgba(37, 99, 235 , 0.08 ), transparent 50%)` ,
157156 } }
158157 />
159158 ) }
160159
161- < div className = "relative" >
160+ < div className = "relative flex flex-col h-full " >
162161 { /* Header */ }
163162 < div className = "flex items-start justify-between mb-4" >
164- < div className = "w-10 h-10 rounded-xl bg-gradient-to-br from-blue-500/10 to-violet-500/10 border border-white/[0.08] flex items-center justify-center" >
165- < svg className = "w-5 h-5 text-blue -400/70 " fill = "none" viewBox = "0 0 24 24" stroke = "currentColor" >
163+ < div className = "w-10 h-10 rounded-lg bg-zinc-800 border border-zinc-700 flex items-center justify-center" >
164+ < svg className = "w-5 h-5 text-zinc -400" fill = "none" viewBox = "0 0 24 24" stroke = "currentColor" >
166165 < path strokeLinecap = "round" strokeLinejoin = "round" strokeWidth = { 1.5 } d = "M3 7v10a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2h-6l-2-2H5a2 2 0 00-2 2z" />
167166 </ svg >
168167 </ div >
@@ -173,13 +172,13 @@ const RepoCard = ({ repo, index, onSelect }: {
173172 < h3 className = "font-semibold text-white mb-0.5 group-hover:text-blue-400 transition-colors" >
174173 { repo . name }
175174 </ h3 >
176- < p className = "text-xs text-zinc-500 font-mono mb-4 " > { repo . branch } </ p >
175+ < p className = "text-xs text-zinc-500 font-mono mb-auto " > { repo . branch } </ p >
177176
178177 { /* Stats */ }
179- < div className = "pt-3 border-t border-white/[0.04]" >
178+ < div className = "pt-4 mt-4 border-t border-white/[0.04]" >
180179 < div className = "flex items-center justify-between" >
181180 < span className = "text-xs text-zinc-500" > Functions</ span >
182- < span className = "text-lg font-semibold text-transparent bg-clip-text bg-gradient-to-r from- blue-400 to-violet-400 " >
181+ < span className = "text-xl font-bold text-blue-500 " >
183182 { ( repo . file_count || 0 ) . toLocaleString ( ) }
184183 </ span >
185184 </ div >
@@ -199,8 +198,10 @@ export function RepoList({ repos, selectedRepo, onSelect, loading }: RepoListPro
199198 animate = { { opacity : 1 } }
200199 className = "bg-[#111113] border border-white/[0.06] rounded-2xl p-16 text-center"
201200 >
202- < div className = "w-16 h-16 mx-auto mb-4 rounded-xl bg-gradient-to-br from-blue-500/10 to-violet-500/10 border border-white/[0.06] flex items-center justify-center" >
203- < span className = "text-2xl" > 📦</ span >
201+ < div className = "w-14 h-14 mx-auto mb-4 rounded-xl bg-blue-500/10 border border-blue-500/20 flex items-center justify-center" >
202+ < svg className = "w-6 h-6 text-blue-500" fill = "none" viewBox = "0 0 24 24" stroke = "currentColor" >
203+ < path strokeLinecap = "round" strokeLinejoin = "round" strokeWidth = { 1.5 } d = "M12 4v16m8-8H4" />
204+ </ svg >
204205 </ div >
205206 < h3 className = "text-lg font-semibold mb-2 text-white" > No repositories yet</ h3 >
206207 < p className = "text-sm text-zinc-500 max-w-xs mx-auto" >
@@ -210,7 +211,7 @@ export function RepoList({ repos, selectedRepo, onSelect, loading }: RepoListPro
210211 )
211212 }
212213
213- // Sort: indexed first, then by function count
214+ // Sort: indexed first, then by function count desc
214215 const sortedRepos = useMemo ( ( ) => {
215216 return [ ...repos ] . sort ( ( a , b ) => {
216217 if ( a . status === 'indexed' && b . status !== 'indexed' ) return - 1
@@ -223,10 +224,10 @@ export function RepoList({ repos, selectedRepo, onSelect, loading }: RepoListPro
223224 const [ featured , ...rest ] = sortedRepos
224225
225226 return (
226- < div className = "grid grid-cols-1 lg:grid-cols-3 gap-4" >
227- { /* Featured - spans 2 rows */ }
227+ < div className = "grid grid-cols-1 lg:grid-cols-3 gap-4 auto-rows-fr " >
228+ { /* Featured - spans 2 rows on desktop */ }
228229 { featured && (
229- < div className = "lg:row-span-2 min-h-[320px] " >
230+ < div className = "lg:row-span-2" >
230231 < FeaturedRepoCard
231232 repo = { featured }
232233 totalFunctions = { totalFunctions }
@@ -235,7 +236,7 @@ export function RepoList({ repos, selectedRepo, onSelect, loading }: RepoListPro
235236 </ div >
236237 ) }
237238
238- { /* Rest */ }
239+ { /* Other repos */ }
239240 { rest . map ( ( repo , index ) => (
240241 < RepoCard
241242 key = { repo . id }
0 commit comments