Refactor case study page into nested routes with Overview/History/Contributors#96
Merged
Merged
Conversation
🚀 Release: master ⬅️ staging
🚀 Release: master ⬅️ staging
🚀 Release: master ⬅️ staging
🚀 Release: master ⬅️ staging
🚀 Release: master ⬅️ staging
- Move the parent "Case study of" callout below the title and badges, matching how issues render (id → title → badges → parent). - Hide the owner/collaborators panel behind a dedicated Contributors page and the change log behind a History page, reached via quiet meta links at the bottom of the overview — the same pattern issues and solutions use. Both are now nested routes under /case-study/[id]. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012MFHDAHHvfjqmUf7TycaJJ
🧹 Code quality
updated for |
- Extract the outcome/scale badge label+variant maps — previously copy-pasted across the case-study page, case-study card, tree node, and issue overview — into a single app/utils/case-study.ts. - Extract the shared "Contributors · History" overview footer into a NodeMetaLinks component, used by both the issue and case-study overviews, and the meta-page "← back" link into NodeBackLink. No visual change; purely removes duplication. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012MFHDAHHvfjqmUf7TycaJJ
- Pin vue-tsc (2.2.10) in devDependencies. CI runs `bunx vue-tsc`, which otherwise resolves vue-tsc@latest (v3) — incompatible with the pinned TypeScript on Node 24 (ERR_PACKAGE_PATH_NOT_EXPORTED './lib/tsc'), failing the required typecheck job repo-wide. A local pin makes bunx use a working version. - Apply vize formatting to the new/changed case-study files. - Extract case-study date-range + cost formatting into small pure helpers in app/utils/case-study.ts (shared, testable, lower per-fn complexity). - Extract the near-identical Sources/Links lists into CaseStudyLinkCard. - Flatten history.vue's template (derive viewerId/revisionCount in script). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012MFHDAHHvfjqmUf7TycaJJ
GitHub Actions did not schedule a run for the previous commit; empty commit to fire the pull_request:synchronize workflow. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012MFHDAHHvfjqmUf7TycaJJ
…ribution Resolves the conflict in app/pages/case-study/[id].vue (the refactor turned it into a <NuxtPage /> shell, so staging's safeUrl() hardening of the sources/links hrefs from #94 no longer applied there). Kept the shell and re-applied safeUrl() in the extracted CaseStudyLinkCard component so the security fix survives. Also scopes fallow-ignore comments on the shell + Overview templates: the refactor splits one monolithic template into two simpler ones (net complexity drop) but the diff-gate re-attributes each touched template as introduced — same pattern as createCaseStudy (bb3550c). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EzhVToTww4v85fHmuWyPEh
…n id
- Remove provide('caseStudyParent') — no child route injects it (the parent
callout is rendered in the shell itself).
- Key the pending-banner revisions fetch on the case-study id so client
navigation between two studies can't briefly surface the previous count.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EzhVToTww4v85fHmuWyPEh
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Restructures the case study detail page (
/case-study/[id]) from a monolithic view into a nested route layout with three child pages: Overview (default), History, and Contributors. This mirrors the pattern used for issues/solutions and improves separation of concerns by keeping the main record view focused while moving metadata (change history, team) to quiet meta links.Key Changes
Parent layout (
[id].vue): Now acts as a shell that loads the case study data once and provides it to child routes viaprovide(). Handles edit modal, pending revision banner (with smart link to history tab), and renders<NuxtPage />for child content.NuxtLinkto/case-study/[id]/historycaseStudy,caseStudyParent,caseStudyCanApply, andcaseStudyRefreshto childrenNew Overview page (
[id]/index.vue): Renders all structured case study fields as cards (implementer, timeline, location map, description, metrics, funding, lessons learned, sources, links, documentation metadata). Includes quiet meta links at the bottom to Contributors and History pages.New History page (
[id]/history.vue): Full revision timeline with owner/admin approval controls. Loads complete revision list (not just pending count). Includes back link to overview.New Contributors page (
[id]/contributors.vue): NodeMembers panel for team management. Includes back link to overview.Notable Implementation Details
provide()/inject()to share loaded study data and callbacks across nested routes, avoiding duplicate fetchescanApplyis true (owner/admin), withimmediate: falseto defer until neededonHistoryTabcomputed)https://claude.ai/code/session_012MFHDAHHvfjqmUf7TycaJJ