SemRow.jsx + SummerRow.jsx UI components

The timeline rows. SemRow renders a single non-summer semester (fall/spring/special). SummerRow renders a paired sumA+sumB layout side by side. Both are structurally similar and share the same interaction patterns.

Parent
Lines each
~850
Key prop
semId (or semIdA + semIdB for SummerRow)
Children
CourseCard ×N per semester

SemRow anatomy

graph TD SR["SemRow (semId)"] SR --> SH["Semester header: label + status dot + SH total"] SR --> CB["Co-op block (if workPl has entry for this semId)"] SR --> IB["Internship block (if internPl has entry)"] SR --> MC["Main courses drop zone"] MC --> CC["CourseCard ×N (credits ≥ 3)"] SR --> OC["Other credits toggle (credits ≤ 2)"] OC --> CC2["CourseCard ×N (small-SH courses)"] SR --> BSH["Bonus SH input"]

Semester header

Shows the semester label (e.g. "Fall 2026"), a status dot, and the total SH count for that semester.

Completed semesters render with reduced opacity for their course cards (dimmed, "already done" visual).

Co-op and internship blocks

If a co-op/internship is placed in this semester, a large block appears above the courses. The start row shows: type label + number (e.g. "CO-OP 1"), a CompanySearch field, a role/subline input, the company logo (via CompanyLogo), and a remove button.

Spanning blocks show a continuation row in the second semester. The continuation row shows the type label (e.g. "CO-OP CONTINUES"), the drag hint, and — if showContLogo is enabled — the same company logo at the same size as the start row. The logo is loaded from the same companyDomain field and stays hidden if the domain fails to load.

showContLogo is a global preference toggled in the Settings popup and persisted as ncp-show-cont-logo (default true).

Drop zone behavior

The entire main courses section is a drop zone. While dragging, the row highlights (hoveredSem === semId). On drop, calls onDrop(dragInfo.courseId, semId). The order of dropped courses within the row is managed by onDropOnCard() for reordering.

Bonus SH input

A small numeric input at the bottom of the row. Adding a number here increases the semester's SH total (for AP credit, transfer credit, or special arrangements). Stored in bonusSH[semId]. Shown in the SH total badge.

"Other credits" section

Courses with ≤2 SH (seminars, application fees, etc.) are segregated into a collapsible "+" section at the bottom. The collapseOtherCredits setting controls whether it starts collapsed. This prevents small-SH courses from cluttering the main course list.

SummerRow differences

SummerRow receives semIdA (sumA) and semIdB (sumB) and renders them side-by-side in two columns. Each column is functionally identical to a half-height SemRow. 4-month co-ops span one column; 6-month co-ops span both.