@@ -57,7 +57,15 @@ interface DashboardProps {
5757 theme : Theme ;
5858}
5959
60- const COLORS = [ '#2563eb' , '#06b6d4' , '#10b981' , '#f59e0b' , '#ef4444' , '#8b5cf6' ] ;
60+ // Use CSS variables so the tracker section follows the website theme
61+ const COLORS = [
62+ 'var(--color-primary)' ,
63+ 'var(--color-accent)' ,
64+ 'var(--color-success)' ,
65+ 'var(--color-danger)' ,
66+ 'var(--color-accent)' ,
67+ 'var(--color-primary)'
68+ ] ;
6169
6270const formatMonthLabel = ( date : Date ) =>
6371 date . toLocaleDateString ( undefined , { month : 'short' , year : 'numeric' } ) ;
@@ -182,36 +190,30 @@ const RepositoryAnalyticsDashboard = ({
182190 label : 'Total repositories' ,
183191 value : analytics . repoCount ,
184192 icon : Database ,
185- accentStart : '#2563eb ' ,
186- accentEnd : '#06b6d4 ' ,
193+ accentStart : 'var(--color-primary) ' ,
194+ accentEnd : 'var(--color-accent) ' ,
187195 } ,
188196 {
189197 label : 'Total stars' ,
190198 value : analytics . totalStars ,
191199 icon : Star ,
192- accentStart : '#f59e0b' ,
193- accentEnd : '#f97316' ,
194- } ,
195- {
196- label : 'Total forks' ,
197- value : analytics . totalForks ,
198- icon : GitFork ,
199- accentStart : '#10b981' ,
200- accentEnd : '#14b8a6' ,
200+ accentStart : 'var(--color-danger)' ,
201+ accentEnd : 'var(--color-danger)' ,
201202 } ,
203+ // forks card intentionally removed to keep the summary concise and horizontal
202204 {
203205 label : 'Most used language' ,
204206 value : analytics . mostUsedLanguage ,
205207 icon : Languages ,
206- accentStart : '#8b5cf6 ' ,
207- accentEnd : '#d946ef ' ,
208+ accentStart : 'var(--color-accent) ' ,
209+ accentEnd : 'var(--color-accent) ' ,
208210 } ,
209211 {
210212 label : 'Total contributions' ,
211213 value : totalContributions ,
212214 icon : Activity ,
213- accentStart : '#0ea5e9 ' ,
214- accentEnd : '#6366f1 ' ,
215+ accentStart : 'var(--color-primary) ' ,
216+ accentEnd : 'var(--color-accent) ' ,
215217 } ,
216218 ] ;
217219
@@ -264,7 +266,7 @@ const RepositoryAnalyticsDashboard = ({
264266 p : { xs : 3 , md : 4 } ,
265267 borderRadius : 6 ,
266268 color : 'white' ,
267- background : 'linear-gradient(135deg, rgba(15,23,42,0.98 ), rgba(29,78,216,0.92) 45%, rgba(8,145,178,0.9 ))' ,
269+ background : 'linear-gradient(135deg, var(--color-primary ), var(--color-accent ))' ,
268270 boxShadow : '0 24px 80px rgba(15,23,42,0.24)' ,
269271 border : '1px solid rgba(255,255,255,0.12)' ,
270272 position : 'relative' ,
@@ -293,7 +295,15 @@ const RepositoryAnalyticsDashboard = ({
293295
294296 < Box sx = { { display : 'grid' , gap : 2.5 , gridTemplateColumns : { xs : '1fr' , md : 'minmax(0, 1.4fr) minmax(0, 0.9fr)' } , alignItems : 'end' } } >
295297 < Box >
296- < Typography variant = "h4" sx = { { fontWeight : 900 , lineHeight : 1.05 , maxWidth : 720 } } >
298+ < Typography
299+ variant = "h4"
300+ sx = { {
301+ fontWeight : 900 ,
302+ lineHeight : 1.05 ,
303+ maxWidth : 720 ,
304+ fontSize : { xs : '1.4rem' , md : '1.8rem' } , // slightly reduced on small and medium screens
305+ } }
306+ >
297307 Track stars, forks, languages, and contribution momentum in one place.
298308 </ Typography >
299309 < Typography sx = { { mt : 1.5 , maxWidth : 760 , color : 'rgba(255,255,255,0.8)' } } >
@@ -350,13 +360,11 @@ const RepositoryAnalyticsDashboard = ({
350360
351361 < Box
352362 sx = { {
353- display : 'grid ' ,
363+ display : 'flex ' ,
354364 gap : 2 ,
355- gridTemplateColumns : {
356- xs : '1fr' ,
357- sm : 'repeat(2, minmax(0, 1fr))' ,
358- xl : 'repeat(5, minmax(0, 1fr))' ,
359- } ,
365+ flexDirection : { xs : 'column' , md : 'row' } ,
366+ alignItems : 'stretch' ,
367+ justifyContent : 'space-between' ,
360368 mb : 3 ,
361369 } }
362370 >
@@ -370,7 +378,8 @@ const RepositoryAnalyticsDashboard = ({
370378 sx = { {
371379 p : 2.5 ,
372380 borderRadius : 4 ,
373- height : '100%' ,
381+ minWidth : { md : '18%' } ,
382+ flex : { xs : '1 1 auto' , md : '1 1 0' } ,
374383 position : 'relative' ,
375384 overflow : 'hidden' ,
376385 background : theme . palette . background . paper ,
@@ -387,14 +396,36 @@ const RepositoryAnalyticsDashboard = ({
387396 } ,
388397 } }
389398 >
390- < Box sx = { { display : 'flex' , alignItems : 'flex-start ' , justifyContent : 'space-between' , gap : 2 , pl : 1 } } >
399+ < Box sx = { { display : 'flex' , alignItems : 'center ' , justifyContent : 'space-between' , gap : 2 , pl : 1 } } >
391400 < Box >
392- < Typography variant = "caption" sx = { { letterSpacing : '0.18em' , textTransform : 'uppercase' , color : 'text.secondary' } } >
401+ < Typography sx = { { letterSpacing : '0.18em' , textTransform : 'uppercase' , color : 'text.secondary' , fontSize : { xs : '0.65rem' , md : '0.75rem' } } } >
393402 { card . label }
394403 </ Typography >
395- < Typography variant = "h4" sx = { { mt : 1 , fontWeight : 900 , lineHeight : 1 } } >
396- { card . value }
397- </ Typography >
404+ {
405+ ( ( ) => {
406+ const isLanguage = card . label && card . label . toLowerCase ( ) . includes ( 'language' ) ;
407+ const valueFont = isLanguage
408+ ? { xs : '1rem' , md : 'clamp(1.1rem, 2.2vw, 1.6rem)' }
409+ : { xs : '1.6rem' , md : '2.25rem' } ;
410+ return (
411+ < Typography
412+ title = { isLanguage ? String ( card . value ) : undefined }
413+ sx = { {
414+ mt : 1 ,
415+ fontWeight : 900 ,
416+ lineHeight : 1 ,
417+ fontSize : valueFont ,
418+ whiteSpace : 'nowrap' ,
419+ overflow : 'visible' ,
420+ textOverflow : 'clip' ,
421+ maxWidth : '100%' ,
422+ } }
423+ >
424+ { card . value }
425+ </ Typography >
426+ ) ;
427+ } ) ( )
428+ }
398429 </ Box >
399430 < Box
400431 sx = { {
@@ -427,19 +458,19 @@ const RepositoryAnalyticsDashboard = ({
427458 background :
428459 theme . palette . mode === 'dark'
429460 ? 'linear-gradient(180deg, rgba(15,23,42,0.78), rgba(15,23,42,0.96))'
430- : 'linear-gradient(180deg, #ffffff, #f8fbff )' ,
461+ : 'linear-gradient(180deg, var(--color-surface), rgba(248,250,252,1) )' ,
431462 border : `1px solid ${ theme . palette . divider } ` ,
432463 boxShadow : '0 18px 40px rgba(15,23,42,0.06)' ,
433464 position : 'relative' ,
434465 overflow : 'hidden' ,
435- '&::after' : {
466+ '&::after' : {
436467 content : '""' ,
437468 position : 'absolute' ,
438469 left : 0 ,
439470 top : 0 ,
440471 right : 0 ,
441472 height : 5 ,
442- background : 'linear-gradient(90deg, #2563eb, #06b6d4, #10b981 )' ,
473+ background : 'linear-gradient(90deg, var(--color-primary), var(--color-accent), var(--color-success) )' ,
443474 } ,
444475 } }
445476 >
@@ -465,9 +496,9 @@ const RepositoryAnalyticsDashboard = ({
465496 < YAxis stroke = { theme . palette . text . secondary } width = { 30 } />
466497 < Tooltip contentStyle = { { backgroundColor : theme . palette . background . paper , color : theme . palette . text . primary , borderRadius : 16 , border : `1px solid ${ theme . palette . divider } ` } } />
467498 < Legend />
468- < Area type = "monotone" dataKey = "repositories" stroke = "#2563eb " fill = "#2563eb " fillOpacity = { 0.18 } />
469- < Line type = "monotone" dataKey = "stars" stroke = "#f59e0b " strokeWidth = { 3 } dot = { false } />
470- < Line type = "monotone" dataKey = "forks" stroke = "#10b981 " strokeWidth = { 3 } dot = { false } />
499+ < Area type = "monotone" dataKey = "repositories" stroke = "var(--color-primary) " fill = "var(--color-primary) " fillOpacity = { 0.18 } />
500+ < Line type = "monotone" dataKey = "stars" stroke = "var(--color-danger) " strokeWidth = { 3 } dot = { false } />
501+ < Line type = "monotone" dataKey = "forks" stroke = "var(--color-success) " strokeWidth = { 3 } dot = { false } />
471502 </ ComposedChart >
472503 </ ResponsiveContainer >
473504 ) : (
@@ -500,28 +531,67 @@ const RepositoryAnalyticsDashboard = ({
500531 </ Box >
501532
502533 { analytics . languageDistribution . length > 0 ? (
503- < ResponsiveContainer width = "100%" height = "82%" >
534+ < >
535+ < ResponsiveContainer width = "100%" height = { "70%" } >
504536 < PieChart >
537+ { /* compute language total for legend percentages */ }
538+ { /* Pie: remove in-chart labels; use bottom legend instead */ }
505539 < Pie
506540 data = { analytics . languageDistribution }
507541 dataKey = "value"
508542 nameKey = "name"
509543 cx = "50%"
510- cy = "50 %"
511- outerRadius = { 120 }
512- innerRadius = { 68 }
513- paddingAngle = { 5 }
544+ cy = "42 %"
545+ outerRadius = { 110 }
546+ innerRadius = { 64 }
547+ paddingAngle = { 6 }
514548 labelLine = { false }
515- label = { ( { name , percent } ) => ` ${ name } ${ percent && percent > 0.1 ? ` ${ Math . round ( percent * 100 ) } %` : '' } ` }
549+ label = { false }
516550 >
517551 { analytics . languageDistribution . map ( ( entry , index ) => (
518552 < Cell key = { `${ entry . name } -${ index } ` } fill = { COLORS [ index % COLORS . length ] } />
519553 ) ) }
520554 </ Pie >
521555 < Tooltip contentStyle = { { backgroundColor : theme . palette . background . paper , color : theme . palette . text . primary , borderRadius : 16 , border : `1px solid ${ theme . palette . divider } ` } } />
522- < Legend verticalAlign = "bottom" />
556+ { /* Legend rendered below the chart (custom) */ }
523557 </ PieChart >
524- </ ResponsiveContainer >
558+ </ ResponsiveContainer >
559+
560+ { /* Custom legend placed inside the card so it always stays within bounds */ }
561+ < Box sx = { { display : 'flex' , justifyContent : 'center' , flexWrap : 'wrap' , gap : 12 , mt : 2 } } >
562+ { ( ( ) => {
563+ const languageTotal = analytics . languageDistribution . reduce ( ( s , e ) => s + ( e . value ?? 0 ) , 0 ) ;
564+ const topThree = analytics . languageDistribution . slice ( 0 , 3 ) ;
565+ const othersCount = analytics . languageDistribution . length - topThree . length ;
566+
567+ return (
568+ < >
569+ { topThree . map ( ( entry , index ) => {
570+ const pct = languageTotal > 0 ? Math . round ( ( ( entry . value ?? 0 ) / languageTotal ) * 100 ) : 0 ;
571+ const color = COLORS [ index % COLORS . length ] ;
572+ return (
573+ < Box key = { entry . name } sx = { { display : 'flex' , alignItems : 'center' , gap : 1 } } >
574+ < Box sx = { { width : 10 , height : 10 , borderRadius : '50%' , background : color } } />
575+ < Typography variant = "caption" sx = { { fontWeight : 700 , color : theme . palette . text . primary } } >
576+ { entry . name } { pct } %
577+ </ Typography >
578+ </ Box >
579+ ) ;
580+ } ) }
581+
582+ { othersCount > 0 && (
583+ < Box sx = { { display : 'flex' , alignItems : 'center' , gap : 1 } } >
584+ < Box sx = { { width : 10 , height : 10 , borderRadius : '50%' , background : 'rgba(0,0,0,0.08)' } } />
585+ < Typography variant = "caption" sx = { { color : theme . palette . text . secondary } } >
586+ +{ othersCount } others
587+ </ Typography >
588+ </ Box >
589+ ) }
590+ </ >
591+ ) ;
592+ } ) ( ) }
593+ </ Box >
594+ </ >
525595 ) : (
526596 < Box sx = { { display : 'grid' , placeItems : 'center' , height : '82%' , borderRadius : 3 , border : `1px dashed ${ theme . palette . divider } ` } } >
527597 < Typography color = "text.secondary" > No language data available.</ Typography >
@@ -540,7 +610,7 @@ const RepositoryAnalyticsDashboard = ({
540610 background :
541611 theme . palette . mode === 'dark'
542612 ? 'linear-gradient(180deg, rgba(15,23,42,0.72), rgba(15,23,42,0.94))'
543- : 'linear-gradient(180deg, #ffffff, #f9fbff )' ,
613+ : 'linear-gradient(180deg, var(--color-surface), rgba(249,251,255,1) )' ,
544614 border : `1px solid ${ theme . palette . divider } ` ,
545615 boxShadow : '0 18px 40px rgba(15,23,42,0.06)' ,
546616 } }
@@ -559,15 +629,15 @@ const RepositoryAnalyticsDashboard = ({
559629 < AreaChart data = { weeklyCommitActivity . map ( ( entry ) => ( { label : formatWeekLabel ( entry . week ) , commits : entry . commits } ) ) } >
560630 < defs >
561631 < linearGradient id = "commitFill" x1 = "0" y1 = "0" x2 = "0" y2 = "1" >
562- < stop offset = "5%" stopColor = "#06b6d4 " stopOpacity = { 0.45 } />
563- < stop offset = "95%" stopColor = "#06b6d4 " stopOpacity = { 0.03 } />
632+ < stop offset = "5%" stopColor = "var(--color-accent) " stopOpacity = { 0.45 } />
633+ < stop offset = "95%" stopColor = "var(--color-accent) " stopOpacity = { 0.03 } />
564634 </ linearGradient >
565635 </ defs >
566636 < CartesianGrid strokeDasharray = "3 3" stroke = { theme . palette . divider } opacity = { 0.8 } />
567637 < XAxis dataKey = "label" stroke = { theme . palette . text . secondary } tickMargin = { 10 } />
568638 < YAxis stroke = { theme . palette . text . secondary } width = { 30 } />
569639 < Tooltip contentStyle = { { backgroundColor : theme . palette . background . paper , color : theme . palette . text . primary , borderRadius : 16 , border : `1px solid ${ theme . palette . divider } ` } } />
570- < Area type = "monotone" dataKey = "commits" stroke = "#06b6d4 " strokeWidth = { 3 } fill = "url(#commitFill)" dot = { { r : 3 } } activeDot = { { r : 6 } } />
640+ < Area type = "monotone" dataKey = "commits" stroke = "var(--color-accent) " strokeWidth = { 3 } fill = "url(#commitFill)" dot = { { r : 3 } } activeDot = { { r : 6 } } />
571641 </ AreaChart >
572642 </ ResponsiveContainer >
573643 ) : (
@@ -601,14 +671,19 @@ const RepositoryAnalyticsDashboard = ({
601671
602672 { analytics . topRepositories . length > 0 ? (
603673 < ResponsiveContainer width = "100%" height = "84%" >
604- < BarChart data = { analytics . topRepositories } >
674+ < BarChart data = { analytics . topRepositories } margin = { { bottom : 20 } } >
605675 < CartesianGrid strokeDasharray = "3 3" stroke = { theme . palette . divider } opacity = { 0.8 } />
606- < XAxis dataKey = "name" stroke = { theme . palette . text . secondary } interval = { 0 } angle = { - 15 } textAnchor = "end" height = { 70 } tickMargin = { 10 } />
676+ { /* hide x-axis ticks to avoid overlap; show name on hover via Tooltip */ }
677+ < XAxis dataKey = "name" stroke = { theme . palette . text . secondary } interval = { 0 } tick = { false } />
607678 < YAxis stroke = { theme . palette . text . secondary } width = { 30 } />
608- < Tooltip contentStyle = { { backgroundColor : theme . palette . background . paper , color : theme . palette . text . primary , borderRadius : 16 , border : `1px solid ${ theme . palette . divider } ` } } />
679+ < Tooltip
680+ contentStyle = { { backgroundColor : theme . palette . background . paper , color : theme . palette . text . primary , borderRadius : 16 , border : `1px solid ${ theme . palette . divider } ` } }
681+ labelFormatter = { ( label ) => `Repository: ${ label } ` }
682+ formatter = { ( value , name ) => [ value , name ] }
683+ />
609684 < Legend />
610- < Bar dataKey = "stars" fill = "#f59e0b " radius = { [ 10 , 10 , 0 , 0 ] } />
611- < Bar dataKey = "forks" fill = "#10b981 " radius = { [ 10 , 10 , 0 , 0 ] } />
685+ < Bar dataKey = "stars" fill = "var(--color-danger) " radius = { [ 10 , 10 , 0 , 0 ] } />
686+ < Bar dataKey = "forks" fill = "var(--color-success) " radius = { [ 10 , 10 , 0 , 0 ] } />
612687 </ BarChart >
613688 </ ResponsiveContainer >
614689 ) : (
0 commit comments