Skip to content

Implement course detail panel component #14

Description

@AJaccP

As a student using the Explorer, I want to click a course and see its full details (title, credits, description, prerequisites, preclusions) in a side panel, so I don't have to recognise a course from its code alone.


🧠 Context

A shared CourseDetailPanel component has already been scaffolded at src/components/CourseDetailPanel.tsx. The contract and wiring are done — this ticket fills in the body and styling.

What's already in place (do not change):

  • Props contract: { course: Course | null; onClose: () => void }. The component is intentionally prop-driven and page-agnostic (no store imports) so it can be reused elsewhere later. Keep it that way.
  • Open/close behaviour: renders null when course is null; otherwise a right-side drawer.
  • Explorer integration: it's already wired into src/pages/Explorer.tsx — clicking a node sets selectedCourse, which feeds the panel; the ✕ button calls onClose. You don't need to touch the Explorer wiring.

The body is currently a skeleton — just the course code and a close button, with a TODO. Your job is to render the rest of the fields and style it.

Prereq display: render course.prereqRaw as plain text. A nicer rendering of the parsed prereq AST is a separate future enhancement — not this ticket.


🛠️ Implementation Plan

  1. Open src/components/CourseDetailPanel.tsx. Keep the props, the null guard, and the <aside> drawer shell as they are.
  2. In the body, render the remaining Course fields: title, credits, description, prereqRaw (plain text), and precludes (e.g. a comma-separated list, only shown when non-empty). Avoid rendering misleading content for empty fields.
  3. Style it with Tailwind to match the rest of the app. Keep it readable within the drawer width.
  4. Accessibility: close on Escape as well as the ✕ button, and manage focus sensibly (move focus into the panel on open, return it on close). The ✕ already has an aria-label.
  5. Mobile: the fixed right drawer may need a different treatment on narrow screens (e.g. close to full-width or a bottom sheet). At minimum, it must not break the layout.
  6. Test in the Explorer (pnpm dev): clicking a node opens the panel with that course's details; ✕ / Escape closes it; selecting a different node swaps the content.
  7. Run pnpm typecheck, pnpm test, and pnpm lint / pnpm format.

🚫 Out of scope (do not do in this ticket)

  • Wiring the panel into the Planner — that's a separate future ticket. The component stays prop-driven so that integration is purely additive later.
  • Rendering the parsed prereq AST — use prereqRaw text only; the richer view is a future enhancement.

✅ Acceptance Criteria

  • Clicking a node in the Explorer opens the panel showing the selected course's code, title, credits, description, prerequisites (raw text), and precludes
  • The panel closes via both the ✕ button and the Escape key, with sensible focus handling
  • Selecting a different course updates the panel content
  • Empty fields (e.g. an empty prereqRaw, or no precludes) don't render misleading or broken-looking content
  • The component remains prop-driven — no store imports are added (keeps it reusable by the Planner later)
  • Layout does not break on smaller screen widths
  • Planner integration is not included (separate ticket)
  • pnpm typecheck and pnpm test pass

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

Status
Done

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions