diff --git a/ui/src/components/LanguageBar.tsx b/ui/src/components/LanguageBar.tsx new file mode 100644 index 0000000..af18af8 --- /dev/null +++ b/ui/src/components/LanguageBar.tsx @@ -0,0 +1,35 @@ +export function LanguageBar({ languages, colorMap, compact }: { + languages: Record; + colorMap: Record; + compact?: boolean; +}) { + const total = Object.values(languages).reduce((a, b) => a + b, 0); + if (total === 0) return null; + + const sorted = Object.entries(languages).sort(([, a], [, b]) => b - a); + + return ( +
+
+ {sorted.map(([lang, bytes]) => ( +
+ ))} +
+ {!compact && ( +
+ {sorted.slice(0, 8).map(([lang, bytes]) => ( + + + {lang} {((bytes / total) * 100).toFixed(1)}% + + ))} +
+ )} +
+ ); +} diff --git a/ui/src/pages/DashPage.tsx b/ui/src/pages/DashPage.tsx index dad7932..1629e34 100644 --- a/ui/src/pages/DashPage.tsx +++ b/ui/src/pages/DashPage.tsx @@ -5,6 +5,7 @@ import Col from 'react-bootstrap/Col'; import Row from 'react-bootstrap/Row'; import { fetchProjects, fetchRepoLanguages, type ProjectSummary } from '../api/client'; +import { LanguageBar } from '../components/LanguageBar'; import { ContributionGraph, AllTimeGraph } from '../components/ContributionGraph'; import { LanguageStreamGraph } from '../components/LanguageStreamGraph'; @@ -31,6 +32,14 @@ export function DashPage() { return map; }, [langsQ.data]); + const langColors = useMemo(() => { + const map: Record = {}; + for (const e of langsQ.data ?? []) { + if (e.color && !map[e.language]) map[e.language] = e.color; + } + return map; + }, [langsQ.data]); + const projects = projectsQ.data ?? []; const ranked = rankProjects(projects); @@ -54,7 +63,7 @@ export function DashPage() { {ranked.map((p) => ( - + ))} @@ -62,17 +71,12 @@ export function DashPage() { ); } -function ProjectCard({ project: p, langs }: { project: ProjectSummary; langs: Record | null }) { - const topLangs = langs ? topLanguages(langs, 3) : null; - +function ProjectCard({ project: p, langs, colorMap }: { project: ProjectSummary; langs: Record | null; colorMap: Record }) { return (
{p.source}{p.repo}
- - {p.source} - {topLangs && ` ยท ${topLangs}`} - + {langs && }
{p.commit_count > 0 && {p.commit_count} commits} {p.issue_count > 0 && {p.issue_count} issues} @@ -95,14 +99,6 @@ function forgeIcon(source: string): string { } } -function topLanguages(langs: Record, n: number): string { - return Object.entries(langs) - .sort(([, a], [, b]) => b - a) - .slice(0, n) - .map(([lang]) => lang.toLowerCase()) - .join(', '); -} - function formatRange(first: string | null, last: string | null): string { const fmt = (iso: string) => new Date(iso).toLocaleDateString('en-GB', { month: 'short', year: 'numeric' }).toLowerCase(); diff --git a/ui/src/pages/ProjectPage.tsx b/ui/src/pages/ProjectPage.tsx index 490e0ff..a0be294 100644 --- a/ui/src/pages/ProjectPage.tsx +++ b/ui/src/pages/ProjectPage.tsx @@ -7,6 +7,7 @@ import ReactMarkdown from 'react-markdown'; import { VerticalTimeline } from 'react-vertical-timeline-component'; import { fetchEvents, fetchReadme, fetchRepoLanguages, fetchProjects, type Source } from '../api/client'; +import { LanguageBar } from '../components/LanguageBar'; import { TimelineEntry } from '../components/TimelineEntry'; export function ProjectPage() { @@ -73,7 +74,7 @@ export function ProjectPage() {

{source}{repo}

- {langs && } + {langs && }
@@ -125,32 +126,3 @@ function forgeIcon(source: string): string { } } -function LanguageBar({ languages, colorMap }: { languages: Record; colorMap: Record }) { - const total = Object.values(languages).reduce((a, b) => a + b, 0); - if (total === 0) return null; - - const sorted = Object.entries(languages).sort(([, a], [, b]) => b - a); - - return ( -
-
- {sorted.map(([lang, bytes]) => ( -
- ))} -
-
- {sorted.slice(0, 8).map(([lang, bytes]) => ( - - - {lang} {((bytes / total) * 100).toFixed(1)}% - - ))} -
-
- ); -}