From 88c0c9b8982709db4807bb7fa3364b2155351f7c Mon Sep 17 00:00:00 2001 From: Prad Nukala Date: Mon, 5 Oct 2026 12:34:23 -0400 Subject: [PATCH] refactor(components): add appendix tag icons and drop list badge --- apps/docs/components/BacklinksList.astro | 7 ++-- apps/docs/components/ProblemBadges.astro | 44 +++++++++--------------- 2 files changed, 20 insertions(+), 31 deletions(-) diff --git a/apps/docs/components/BacklinksList.astro b/apps/docs/components/BacklinksList.astro index 2d06413..09f7cfe 100644 --- a/apps/docs/components/BacklinksList.astro +++ b/apps/docs/components/BacklinksList.astro @@ -1,9 +1,10 @@ --- /** * The `PageFooter` slot: an Obsidian-style backlinks list under a topic landing - * or guide page — every problem page that points at it, as ` ` - * rows in LeetCode-number order. Pages nothing points at (problem pages, the - * overview, the changelog) render nothing. + * page — every problem page that points at it, as ` ` rows in + * LeetCode-number order. Pages nothing points at (problem pages, the + * overview) render nothing; a tag no topic teaches lists its problems on its + * Appendix card instead (`pages/appendix.astro`), from the same answer. * * A problem points at a page when either * - one of its topic badges links there — the same `tagTarget()` answer diff --git a/apps/docs/components/ProblemBadges.astro b/apps/docs/components/ProblemBadges.astro index ddd8b15..0790f7d 100644 --- a/apps/docs/components/ProblemBadges.astro +++ b/apps/docs/components/ProblemBadges.astro @@ -11,28 +11,27 @@ * * - `topics:` (problem pages, written by `apps/cli/sync.ts`) is LeetCode's own * topic tags. A tag the campaign teaches (`topic-landings.ts`) links to that - * topic's landing page and is filled; any other tag links to its guide - * page in the Appendix, `/appendix/` (sync creates one per such tag), and is outlined. + * topic's landing page and is filled; any other tag links to its card on the + * Appendix glossary, `/appendix#` (`appendix.ts`), and is outlined. * `tagTarget()` picks the route (and between two landings, e.g. DFS); the - * `PageFooter` backlinks list reads the same answer. Each tag badge is a - * pill carrying the icon its target shows in the sidebar (the topic's - * `meta.ts` icon, the guide's `icon:`) and the tag's own colour - * (`lib/tag-colors.ts`), assigned over every tag the site has a page for — - * no two tags share one, and tags that share problem pages are spread - * furthest apart. A tag with no page (the LeetCode-list fallback) stays - * gray and iconless. + * `PageFooter` backlinks list and the Appendix page read the same answer. + * Each tag badge is a pill carrying the icon its target shows (a topic's + * `meta.ts` icon in the sidebar, a term's `icon` on its card) and the tag's + * own colour (`lib/tag-colors.ts`), assigned over every tag the site has a + * page or card for — no two tags share one, and tags that share problem + * pages are spread furthest apart. A tag with neither (the LeetCode-list + * fallback) stays gray and iconless. * - `video:` (problem pages, written by `apps/cli/videos.ts`) is the NeetCode * walkthrough's YouTube id, the red "Explanation" badge. * - `issue:` (problem pages, written by sync) is the problem's GitHub issue * URL, a neutral "Issue #N" badge with the GitHub mark, right after * "Explanation" at the end of the row. - * - `list:` (guide pages, written by sync on create) is the tag's LeetCode - * problem list, an orange "LeetCode list" badge. */ import { getEntry } from "astro:content"; import data from "blume:data"; import Badge from "blume/components/content/Badge.astro"; import { stripBase, withBase } from "blume/components/islands/base-path.ts"; +import { APPENDIX } from "../appendix.ts"; import { tagColors } from "../lib/tag-colors.ts"; import { TOPIC_LANDINGS, tagTarget, type TopicTag } from "../topic-landings.ts"; @@ -46,7 +45,6 @@ const at = data.routes.find((r: { path: string }) => r.path === route); const entry = at ? await getEntry(at.collection, at.entryId) : undefined; const tags: TopicTag[] = entry?.data.topics ?? []; const video: string | undefined = entry?.data.video; -const list: string | undefined = entry?.data.list; const issue: string | undefined = entry?.data.issue; const served = new Set(data.routes.map((r: { path: string }) => r.path)); @@ -67,15 +65,12 @@ const walk = (nodes: NavNode[]) => { }; walk(data.navigation.sidebar); -// Every tag with a page — the ones a landing teaches, plus every served guide — -// coloured against how problem pages (`. ` titles, the shape sync -// writes) combine them. Only a page with tags needs the answer. +// Every tag with a landing or an Appendix card, coloured against how problem +// pages (`. ` titles, the shape sync writes) combine them. Only a +// page with tags needs the answer. const colors = tags.length ? tagColors( - [ - ...Object.keys(TOPIC_LANDINGS), - ...[...served].flatMap((path) => path.match(/^\/appendix\/([^/]+)$/u)?.slice(1) ?? []), - ], + [...Object.keys(TOPIC_LANDINGS), ...Object.keys(APPENDIX)], await Promise.all( data.routes .filter((r: { title: string }) => /^\d+\.\s/u.test(r.title)) @@ -94,7 +89,7 @@ const badges = tags.map((tag) => { name: tag.name, href: external ? target.href : withBase(target.href), external, - icon: external ? undefined : icons.get(target.href), + icon: target.kind === "appendix" ? APPENDIX[tag.slug]?.icon : external ? undefined : icons.get(target.href), color: external ? undefined : colors.get(tag.slug), stroke: target.kind !== "landing", }; @@ -104,7 +99,7 @@ const linkClass = "no-underline transition-opacity hover:opacity-80"; --- { - (badges.length > 0 || video || list || issue) && ( + (badges.length > 0 || video || issue) && (
{badges.map((b) => ( )} - {list && ( - - - LeetCode list - - - )}
) }