From 06f4e11d3f955071d470d9263e1cee70b77964cf Mon Sep 17 00:00:00 2001 From: daniel_huang <159147443+Danielncku@users.noreply.github.com> Date: Thu, 1 Oct 2026 22:00:27 +0800 Subject: [PATCH 1/3] Add local topic filtering Expose problem topics as local card metadata so candidates can narrow the lobby without revealing tags on each card. Keep recommendations inside the selected topic and cover combined filters in unit and browser tests. --- scripts/gen-problem-cards.py | 18 +- tests/browser/dom.js | 15 +- tests/browser/lobby-render.test.js | 9 +- tests/browser/lobby.test.js | 31 +++ tests/browser/practice-insights.test.js | 32 +++ web/app.js | 75 +++++- web/index.html | 315 ++++++++++++------------ web/practice-insights.js | 16 ++ web/styles.css | 42 +++- 9 files changed, 388 insertions(+), 165 deletions(-) create mode 100644 tests/browser/practice-insights.test.js create mode 100644 web/practice-insights.js diff --git a/scripts/gen-problem-cards.py b/scripts/gen-problem-cards.py index e6134eac..14b23b39 100644 --- a/scripts/gen-problem-cards.py +++ b/scripts/gen-problem-cards.py @@ -37,22 +37,24 @@ def parse_args() -> argparse.Namespace: def read_json(path: Path) -> object: - return json.loads(path.read_text()) + return json.loads(path.read_text(encoding="utf-8")) def card(problem: dict[str, object], page: str, title: str) -> str: """One lobby card, named the way the interview will name the exercise. - Keyed by page name, with the scenario title and no topic tags: the + Keyed by page name, with the scenario title and topic metadata: the recommendation line reads the title off this card, and "Recommended: Coin Change", a `coin-change` key or a "Dynamic Programming" tag tells the - candidate what they are about to be asked. The published title is not in - the page at all; the source slot is filled from the page map only when the - candidate turns that on to drill one problem by name. + candidate what they are about to be asked. Topics stay in data attributes + for local filtering and are not rendered on the card. The published title + is not in the page at all; the source slot is filled from the page map only + when the candidate turns that on to drill one problem by name. """ + topics = "|".join(str(topic) for topic in problem.get("topics", [])) return "\n".join( [ - f' +

+
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+ +