import {
escapeHtml,
getGitHubUrl,
getLastUpdatedHtml,
} from "../utils";
import { renderEmptyStateHtml, renderSharedCardHtml } from "./card-render";
export interface RenderableSkillFile {
name: string;
path: string;
}
export interface RenderableSkill {
id: string;
title: string;
description?: string;
path: string;
skillFile: string;
category: string;
hasAssets: boolean;
assetCount: number;
files: RenderableSkillFile[];
lastUpdated?: string | null;
}
export type SkillSortOption = "title" | "lastUpdated";
/**
* Build the URL of a skill's dedicated detail page.
*/
export function getSkillDetailUrl(id: string): string {
return `/skill/${id}/`;
}
export function sortSkills(
items: T[],
sort: SkillSortOption
): T[] {
return [...items].sort((a, b) => {
if (sort === "lastUpdated") {
const dateA = a.lastUpdated ? new Date(a.lastUpdated).getTime() : 0;
const dateB = b.lastUpdated ? new Date(b.lastUpdated).getTime() : 0;
return dateB - dateA;
}
return a.title.localeCompare(b.title);
});
}
export function renderSkillsHtml(items: RenderableSkill[]): string {
if (items.length === 0) {
return renderEmptyStateHtml("No skills found", "No skills are available right now.");
}
return items
.map((item) => {
const metaHtml = `
${
item.hasAssets
? `${item.assetCount} asset${
item.assetCount === 1 ? "" : "s"
}`
: ""
}
${item.files.length} file${
item.files.length === 1 ? "" : "s"
}
${getLastUpdatedHtml(item.lastUpdated)}
`;
const actionsHtml = `
GitHub
`;
return renderSharedCardHtml({
title: item.title,
description: item.description || "No description",
href: getSkillDetailUrl(item.id),
articleAttributes: {
"data-path": item.skillFile,
"data-skill-id": item.id,
},
metaHtml,
actionsHtml,
});
})
.join("");
}