feat(ui): project readme, language bars, and per-card language summary
ProjectPage fetches README (raw markdown) and language breakdown from GitHub/Gitea REST APIs, rendering the readme as markdown and languages as a colored proportional bar with labels. Dashboard cards lazily fetch top 3 languages per repo and display them inline. Language color map covers common languages. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -101,3 +101,33 @@ export async function fetchProjects(): Promise<ProjectSummary[]> {
|
||||
if (!resp.ok) throw new Error(`projects: HTTP ${resp.status}`);
|
||||
return resp.json();
|
||||
}
|
||||
|
||||
/** Fetch repo README as rendered HTML or raw markdown. */
|
||||
export async function fetchReadme(source: Source, host: string, repo: string): Promise<string | null> {
|
||||
const baseUrl = source === 'github'
|
||||
? `https://api.github.com/repos/${repo}/readme`
|
||||
: source === 'gitea'
|
||||
? `https://${host}/api/v1/repos/${repo}/readme`
|
||||
: null;
|
||||
if (!baseUrl) return null;
|
||||
|
||||
const resp = await fetch(baseUrl, {
|
||||
headers: { 'Accept': 'application/vnd.github.raw+json' },
|
||||
});
|
||||
if (!resp.ok) return null;
|
||||
return resp.text();
|
||||
}
|
||||
|
||||
/** Fetch repo languages as { language: bytes } map. */
|
||||
export async function fetchLanguages(source: Source, host: string, repo: string): Promise<Record<string, number> | null> {
|
||||
const baseUrl = source === 'github'
|
||||
? `https://api.github.com/repos/${repo}/languages`
|
||||
: source === 'gitea'
|
||||
? `https://${host}/api/v1/repos/${repo}/languages`
|
||||
: null;
|
||||
if (!baseUrl) return null;
|
||||
|
||||
const resp = await fetch(baseUrl);
|
||||
if (!resp.ok) return null;
|
||||
return resp.json();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user