@@ -11,23 +11,24 @@ interface RepoListProps {
1111}
1212
1313const StatusBadge = ( { status } : { status : string } ) => {
14- const config = {
15- indexed : { bg : 'bg-emerald-500/10' , text : 'text-emerald-400' , border : 'border-emerald-500/20' , label : 'Indexed' , dot : 'bg-emerald-400' } ,
16- cloned : { bg : 'bg-blue-500/10' , text : 'text-blue-400' , border : 'border-blue-500/20' , label : 'Pending Index' , dot : 'bg-blue-400' } ,
17- indexing : { bg : 'bg-amber-500/10' , text : 'text-amber-400' , border : 'border-amber-500/20' , label : 'Indexing...' , dot : 'bg-amber-400 animate-pulse' } ,
18- cloning : { bg : 'bg-amber-500/10' , text : 'text-amber-400' , border : 'border-amber-500/20' , label : 'Cloning...' , dot : 'bg-amber-400 animate-pulse' } ,
19- error : { bg : 'bg-red-500/10' , text : 'text-red-400' , border : 'border-red-500/20' , label : 'Error' , dot : 'bg-red-400' } ,
20- } [ status ] || { bg : 'bg-white/5' , text : 'text-gray-400' , border : 'border-white/10' , label : status , dot : 'bg-gray-400' }
21-
14+ const isIndexed = status === 'indexed'
15+ const isPending = status === 'cloned' || status === 'cloning' || status === 'indexing'
16+
2217 return (
23- < span className = { `inline-flex items-center gap-1.5 px-2.5 py-1 text-xs font-medium rounded-full ${ config . bg } ${ config . text } border ${ config . border } ` } >
24- < span className = { `w-1.5 h-1.5 rounded-full ${ config . dot } ` } />
25- { config . label }
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' }
2628 </ span >
2729 )
2830}
2931
30- // Featured card - larger, more info
3132const FeaturedRepoCard = ( { repo, totalFunctions, onSelect } : {
3233 repo : Repository
3334 totalFunctions : number
@@ -49,95 +50,74 @@ const FeaturedRepoCard = ({ repo, totalFunctions, onSelect }: {
4950 ref = { cardRef }
5051 initial = { { opacity : 0 , y : 20 } }
5152 animate = { { opacity : 1 , y : 0 } }
52- transition = { { duration : 0.4 , ease : [ 0.25 , 0.46 , 0.45 , 0.94 ] } }
53- whileHover = { { y : - 4 , transition : { duration : 0.2 } } }
53+ transition = { { duration : 0.4 } }
54+ whileHover = { { y : - 2 } }
5455 onClick = { onSelect }
5556 onMouseMove = { handleMouseMove }
5657 onMouseEnter = { ( ) => setIsHovering ( true ) }
5758 onMouseLeave = { ( ) => setIsHovering ( false ) }
58- className = "group relative text-left rounded-2xl overflow-hidden h-full min-h-[280px]
59- bg-gradient-to-br from-[#0f1114] via-[#0d0f12] to-[#0a0c0f]
60- border border-white/[0.08] hover:border-blue-500/30
61- hover:shadow-2xl hover:shadow-blue-500/10
62- focus:outline-none focus:ring-2 focus:ring-blue-500/40 p-7"
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"
6362 >
64- { /* Mouse-following glow */ }
63+ { /* Mouse glow */ }
6564 { isHovering && (
6665 < div
6766 className = "pointer-events-none absolute inset-0 transition-opacity duration-300"
6867 style = { {
69- background : `radial-gradient(500px circle at ${ mousePosition . x } px ${ mousePosition . y } px, rgba(59, 130, 246, 0.15 ), transparent 50%)` ,
68+ background : `radial-gradient(400px circle at ${ mousePosition . x } px ${ mousePosition . y } px, rgba(59, 130, 246, 0.08 ), transparent 50%)` ,
7069 } }
7170 />
7271 ) }
7372
74- { /* Top accent line */ }
75- < div className = "absolute top-0 left-0 right-0 h-[2px] bg-gradient-to-r from-blue-500 via-purple-500 to-pink -500 opacity-60 " />
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" />
7675
77- { /* Content */ }
7876 < div className = "relative flex flex-col h-full" >
79- { /* Badge */ }
80- < div className = "flex items-center gap-2 mb-4" >
81- < span className = "text-xs text-blue-400 font-medium px-2 py-0.5 bg-blue-500/10 rounded-full border border-blue-500/20" >
82- ★ Most Functions
83- </ span >
84- </ div >
85-
8677 { /* Header */ }
8778 < div className = "flex items-start justify-between mb-6" >
88- < div className = "w-16 h-16 rounded-2xl bg-gradient-to-br from-blue-500/20 to-purple -500/20 border border-white/10 flex items-center justify-center group-hover:scale-105 group-hover:border-blue-500/30 transition-all duration-300 " >
89- < svg className = "w-8 h-8 text-blue-400" fill = "none" viewBox = "0 0 24 24" stroke = "currentColor" >
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" >
9081 < 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" />
9182 </ svg >
9283 </ div >
9384 < StatusBadge status = { repo . status } />
9485 </ div >
9586
9687 { /* Title */ }
97- < div className = "flex-1" >
98- < h3 className = "text-2xl font-bold text-white mb-1 group-hover:text-blue-400 transition-colors duration-200" >
99- { repo . name }
100- </ h3 >
101- < p className = "text-sm text-gray-500 font-mono" > { repo . branch } </ p >
102- </ div >
88+ < h3 className = "text-xl font-semibold text-white mb-1 group-hover:text-blue-400 transition-colors" >
89+ { repo . name }
90+ </ h3 >
91+ < p className = "text-sm text-zinc-500 font-mono mb-auto" > { repo . branch } </ p >
10392
10493 { /* Stats */ }
105- < div className = "pt-5 mt-auto border-t border-white/[0.06] space-y-4 " >
106- < div className = "flex items-end justify-between" >
107- < span className = "text-sm text-gray-400 " > Functions indexed</ span >
108- < span className = "text-3xl font-bold font-mono text-transparent bg-clip-text bg-gradient-to-r from-blue-400 to-purple -400" >
94+ < div className = "pt-6 mt-6 border-t border-white/[0.06]" >
95+ < div className = "flex items-end justify-between mb-3 " >
96+ < 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" >
10998 { ( repo . file_count || 0 ) . toLocaleString ( ) }
11099 </ span >
111100 </ div >
112101
113- { /* Progress bar */ }
114- { totalFunctions > 0 && (
102+ { totalFunctions > 0 && repo . file_count > 0 && (
115103 < div className = "space-y-2" >
116- < div className = "h-1.5 bg-white/5 rounded-full overflow-hidden" >
104+ < div className = "h-1 bg-white/[0.06] rounded-full overflow-hidden" >
117105 < motion . div
118106 initial = { { width : 0 } }
119107 animate = { { width : `${ percentage } %` } }
120- transition = { { duration : 1 , ease : "easeOut" , delay : 0.3 } }
121- className = "h-full bg-gradient-to-r from-blue-500 to-purple -500 rounded-full"
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"
122110 />
123111 </ div >
124- < p className = "text-xs text-gray-500 " > { percentage } % of total indexed functions </ p >
112+ < p className = "text-xs text-zinc-600 " > { percentage } % of total</ p >
125113 </ div >
126114 ) }
127115 </ div >
128-
129- { /* Hover CTA */ }
130- < div className = "absolute bottom-6 right-6 opacity-0 group-hover:opacity-100 transition-all duration-200 transform translate-x-2 group-hover:translate-x-0" >
131- < span className = "text-sm text-white flex items-center gap-2 bg-blue-500/20 px-4 py-2 rounded-xl border border-blue-500/30 backdrop-blur-sm" >
132- Explore < span > →</ span >
133- </ span >
134- </ div >
135116 </ div >
136117 </ motion . button >
137118 )
138119}
139120
140- // Regular card - compact
141121const RepoCard = ( { repo, index, onSelect } : {
142122 repo : Repository
143123 index : number
@@ -146,7 +126,6 @@ const RepoCard = ({ repo, index, onSelect }: {
146126 const cardRef = useRef < HTMLButtonElement > ( null )
147127 const [ mousePosition , setMousePosition ] = useState ( { x : 0 , y : 0 } )
148128 const [ isHovering , setIsHovering ] = useState ( false )
149- const isPending = repo . status === 'cloned' || repo . status === 'cloning'
150129
151130 const handleMouseMove = ( e : React . MouseEvent ) => {
152131 if ( ! cardRef . current ) return
@@ -159,56 +138,48 @@ const RepoCard = ({ repo, index, onSelect }: {
159138 ref = { cardRef }
160139 initial = { { opacity : 0 , y : 20 } }
161140 animate = { { opacity : 1 , y : 0 } }
162- transition = { { delay : index * 0.08 , duration : 0.4 , ease : [ 0.25 , 0.46 , 0.45 , 0.94 ] } }
163- whileHover = { { y : - 4 , transition : { duration : 0.2 } } }
141+ transition = { { delay : index * 0.1 , duration : 0.4 } }
142+ whileHover = { { y : - 2 } }
164143 onClick = { onSelect }
165144 onMouseMove = { handleMouseMove }
166145 onMouseEnter = { ( ) => setIsHovering ( true ) }
167146 onMouseLeave = { ( ) => setIsHovering ( false ) }
168- className = { `group relative text-left rounded-2xl overflow-hidden h-full min-h-[140px]
169- border transition-all duration-300
170- focus:outline-none focus:ring-2 focus:ring-blue-500/40 p-5
171- ${ isPending
172- ? 'bg-gradient-to-br from-[#0f1114] to-[#0d0f12] border-dashed border-white/[0.08] hover:border-blue-500/30'
173- : 'bg-gradient-to-br from-[#0f1114] to-[#0d0f12] border-white/[0.08] hover:border-white/[0.15]'
174- }
175- hover:shadow-xl hover:shadow-blue-500/[0.06]` }
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"
176150 >
177- { /* Mouse-following glow */ }
151+ { /* Mouse glow */ }
178152 { isHovering && (
179153 < div
180154 className = "pointer-events-none absolute inset-0 transition-opacity duration-300"
181155 style = { {
182- background : `radial-gradient(300px circle at ${ mousePosition . x } px ${ mousePosition . y } px, rgba(59, 130, 246, 0.1 ), transparent 50%)` ,
156+ background : `radial-gradient(250px circle at ${ mousePosition . x } px ${ mousePosition . y } px, rgba(59, 130, 246, 0.06 ), transparent 50%)` ,
183157 } }
184158 />
185159 ) }
186160
187- { /* Content */ }
188- < div className = "relative flex flex-col h-full" >
161+ < div className = "relative" >
189162 { /* Header */ }
190- < div className = "flex items-start justify-between mb-3 " >
191- < div className = "w-10 h-10 rounded-xl bg-gradient-to-br from-blue-500/15 to-purple -500/15 border border-white/[0.08] flex items-center justify-center group-hover:scale-105 group-hover:border-blue-500/20 transition-all duration-300 " >
192- < svg className = "w-5 h-5 text-blue-400/80 " fill = "none" viewBox = "0 0 24 24" stroke = "currentColor" >
163+ < 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" >
193166 < 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" />
194167 </ svg >
195168 </ div >
196169 < StatusBadge status = { repo . status } />
197170 </ div >
198171
199172 { /* Title */ }
200- < div className = "flex-1" >
201- < h3 className = "font-semibold text-white mb-0.5 truncate group-hover:text-blue-400 transition-colors duration-200" >
202- { repo . name }
203- </ h3 >
204- < p className = "text-xs text-gray-500 font-mono" > { repo . branch } </ p >
205- </ div >
173+ < h3 className = "font-semibold text-white mb-0.5 group-hover:text-blue-400 transition-colors" >
174+ { repo . name }
175+ </ h3 >
176+ < p className = "text-xs text-zinc-500 font-mono mb-4" > { repo . branch } </ p >
206177
207178 { /* Stats */ }
208- < div className = "pt-3 mt-auto border-t border-white/[0.04]" >
179+ < div className = "pt-3 border-t border-white/[0.04]" >
209180 < div className = "flex items-center justify-between" >
210- < span className = "text-xs text-gray -500" > Functions</ span >
211- < span className = { ` text-lg font-bold font-mono ${ isPending ? ' text-gray-500' : 'text- transparent bg-clip-text bg-gradient-to-r from-blue-400 to-purple -400' } ` } >
181+ < 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" >
212183 { ( repo . file_count || 0 ) . toLocaleString ( ) }
213184 </ span >
214185 </ div >
@@ -219,54 +190,43 @@ const RepoCard = ({ repo, index, onSelect }: {
219190}
220191
221192export function RepoList ( { repos, selectedRepo, onSelect, loading } : RepoListProps ) {
222- if ( loading ) {
223- return < RepoGridSkeleton count = { 3 } />
224- }
193+ if ( loading ) return < RepoGridSkeleton count = { 3 } />
225194
226195 if ( repos . length === 0 ) {
227196 return (
228197 < motion . div
229- initial = { { opacity : 0 , scale : 0.95 } }
230- animate = { { opacity : 1 , scale : 1 } }
231- className = "bg-gradient-to-br from- [#111113] to-[#0a0a0c ] border border-white/[0.06] rounded-2xl p-16 text-center"
198+ initial = { { opacity : 0 } }
199+ animate = { { opacity : 1 } }
200+ className = "bg-[#111113] border border-white/[0.06] rounded-2xl p-16 text-center"
232201 >
233- < div className = "w-20 h-20 mx-auto mb-6 rounded-2xl bg-gradient-to-br from-blue-500/10 to-purple -500/10 border border-white/[0.06] flex items-center justify-center" >
234- < span className = "text-4xl " > 📦</ span >
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 >
235204 </ div >
236205 < h3 className = "text-lg font-semibold mb-2 text-white" > No repositories yet</ h3 >
237- < p className = "text-sm text-gray-400 max-w-sm mx-auto" >
238- Add your first repository to start searching code semantically with AI
206+ < p className = "text-sm text-zinc-500 max-w-xs mx-auto" >
207+ Add your first repository to start searching code with AI
239208 </ p >
240209 </ motion . div >
241210 )
242211 }
243212
244- // Sort repos : indexed first, then by file_count descending
213+ // Sort: indexed first, then by function count
245214 const sortedRepos = useMemo ( ( ) => {
246215 return [ ...repos ] . sort ( ( a , b ) => {
247- // Indexed repos first
248216 if ( a . status === 'indexed' && b . status !== 'indexed' ) return - 1
249217 if ( b . status === 'indexed' && a . status !== 'indexed' ) return 1
250- // Then by file count
251218 return ( b . file_count || 0 ) - ( a . file_count || 0 )
252219 } )
253220 } , [ repos ] )
254221
255222 const totalFunctions = repos . reduce ( ( acc , r ) => acc + ( r . file_count || 0 ) , 0 )
256223 const [ featured , ...rest ] = sortedRepos
257224
258- // Determine grid layout based on repo count
259- const gridClass = rest . length === 0
260- ? 'grid-cols-1'
261- : rest . length === 1
262- ? 'grid-cols-1 lg:grid-cols-2'
263- : 'grid-cols-1 lg:grid-cols-3'
264-
265225 return (
266- < div className = { ` grid ${ gridClass } gap-4` } >
267- { /* Featured repo - spans full width on mobile, left column on desktop */ }
226+ < div className = " grid grid-cols-1 lg:grid-cols-3 gap-4" >
227+ { /* Featured - spans 2 rows */ }
268228 { featured && (
269- < div className = { rest . length > 0 ? ' lg:row-span-2' : '' } >
229+ < div className = " lg:row-span-2 min-h-[320px]" >
270230 < FeaturedRepoCard
271231 repo = { featured }
272232 totalFunctions = { totalFunctions }
@@ -275,7 +235,7 @@ export function RepoList({ repos, selectedRepo, onSelect, loading }: RepoListPro
275235 </ div >
276236 ) }
277237
278- { /* Rest of repos */ }
238+ { /* Rest */ }
279239 { rest . map ( ( repo , index ) => (
280240 < RepoCard
281241 key = { repo . id }
0 commit comments