feat: make skill pills clickable in company export preview

Clicking a skill pill in the frontmatter card now navigates to the
corresponding skills/<slug>/SKILL.md file in the export tree, expanding
parent directories as needed. No page reload required.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
Dotta
2026-03-16 08:27:21 -05:00
parent 173e7915a7
commit 4e146f0075

View File

@@ -501,7 +501,13 @@ const FRONTMATTER_FIELD_LABELS: Record<string, string> = {
targetDate: "Target date", targetDate: "Target date",
}; };
function FrontmatterCard({ data }: { data: FrontmatterData }) { function FrontmatterCard({
data,
onSkillClick,
}: {
data: FrontmatterData;
onSkillClick?: (skill: string) => void;
}) {
return ( return (
<div className="rounded-md border border-border bg-accent/20 px-4 py-3 mb-4"> <div className="rounded-md border border-border bg-accent/20 px-4 py-3 mb-4">
<dl className="grid grid-cols-[auto_minmax(0,1fr)] gap-x-4 gap-y-1.5 text-sm"> <dl className="grid grid-cols-[auto_minmax(0,1fr)] gap-x-4 gap-y-1.5 text-sm">
@@ -514,12 +520,17 @@ function FrontmatterCard({ data }: { data: FrontmatterData }) {
{Array.isArray(value) ? ( {Array.isArray(value) ? (
<div className="flex flex-wrap gap-1.5"> <div className="flex flex-wrap gap-1.5">
{value.map((item) => ( {value.map((item) => (
<span <button
key={item} key={item}
className="inline-flex items-center rounded-md border border-border bg-background px-2 py-0.5 text-xs" type="button"
className={cn(
"inline-flex items-center rounded-md border border-border bg-background px-2 py-0.5 text-xs",
key === "skills" && onSkillClick && "cursor-pointer hover:bg-accent/50 hover:border-foreground/30 transition-colors",
)}
onClick={() => key === "skills" && onSkillClick?.(item)}
> >
{item} {item}
</span> </button>
))} ))}
</div> </div>
) : ( ) : (
@@ -538,9 +549,11 @@ function FrontmatterCard({ data }: { data: FrontmatterData }) {
function ExportPreviewPane({ function ExportPreviewPane({
selectedFile, selectedFile,
content, content,
onSkillClick,
}: { }: {
selectedFile: string | null; selectedFile: string | null;
content: string | null; content: string | null;
onSkillClick?: (skill: string) => void;
}) { }) {
if (!selectedFile || content === null) { if (!selectedFile || content === null) {
return ( return (
@@ -559,7 +572,7 @@ function ExportPreviewPane({
<div className="min-h-[560px] px-5 py-5"> <div className="min-h-[560px] px-5 py-5">
{parsed ? ( {parsed ? (
<> <>
<FrontmatterCard data={parsed.data} /> <FrontmatterCard data={parsed.data} onSkillClick={onSkillClick} />
{parsed.body.trim() && <MarkdownBody>{parsed.body}</MarkdownBody>} {parsed.body.trim() && <MarkdownBody>{parsed.body}</MarkdownBody>}
</> </>
) : isMarkdown ? ( ) : isMarkdown ? (
@@ -737,6 +750,21 @@ export function CompanyExport() {
} }
} }
function handleSkillClick(skillSlug: string) {
if (!exportData) return;
// Find the SKILL.md file for this skill slug
const skillPath = `skills/${skillSlug}/SKILL.md`;
if (!(skillPath in exportData.files)) return;
// Select the file and expand parent dirs
setSelectedFile(skillPath);
setExpandedDirs((prev) => {
const next = new Set(prev);
next.add("skills");
next.add(`skills/${skillSlug}`);
return next;
});
}
function handleDownload() { function handleDownload() {
if (!exportData) return; if (!exportData) return;
downloadTar(exportData, checkedFiles); downloadTar(exportData, checkedFiles);
@@ -841,7 +869,7 @@ export function CompanyExport() {
</div> </div>
</aside> </aside>
<div className="min-w-0 overflow-y-auto pl-6"> <div className="min-w-0 overflow-y-auto pl-6">
<ExportPreviewPane selectedFile={selectedFile} content={previewContent} /> <ExportPreviewPane selectedFile={selectedFile} content={previewContent} onSkillClick={handleSkillClick} />
</div> </div>
</div> </div>
</div> </div>