Skip to content

Refactored react_modal.js.jsx into modular functional TypeScript comp… - #1822

Merged
david-yz-liu merged 4 commits into
Courseography:masterfrom
danielrafailov:refactor-react-modal
Oct 31, 2026
Merged

david-yz-liu merged 4 commits into
Courseography:masterfrom
danielrafailov:refactor-react-modal

Conversation

@danielrafailov

@danielrafailov danielrafailov commented Oct 24, 2026 •

Copy link
Copy Markdown
Contributor

Proposed Changes

  • As per the PR title, I refactored react_modal.js.jsx by converting legacy class-based components into modular functional components. I also converted the files from JavaScript to TypeScript as requested to catch bugs at compile time and encourage documentation.
  • Specifically, I factored out CampusMap, CourseModal, DayBox, Description, FocusModal, MapModal, and MapSidebar into their own functional components, and created type interfaces for all of their props and state variables.
  • Dead code removal: I know we already discussed this, but as a reminder I have highlighted removed code and why it was removed below:
    • ModalContent: Removed because it was simply a wrapper for Description, which CourseModal was already rendering.
    • Unused references removed:
      • Video class
      • focusInfo state variable
      • formatCourseName helper function

Type of Change

Type Applies?
🚨 Breaking change (fix or feature that would cause existing functionality to change)
✨ New feature (non-breaking change that adds functionality)
🐛 Bug fix (non-breaking change that fixes an issue)
🎨 User interface change (change to user interface; provide screenshots)
♻️ Refactoring (internal change to codebase, without changing functionality) X
🚦 Test update (change that only adds or modifies tests)
📦 Dependency update (change that updates a dependency) X
🔧 Internal (change that only affects developers or continuous integration)

Checklist

Before opening your pull request:

  • I have performed a self-review of my changes.
    • Check that all changed files included in this pull request are intentional changes.
    • Check that all changes are relevant to the purpose of this pull request, as described above.
  • I have added tests for my changes, if applicable.
    • This is required for all bug fixes and new features.
  • I have updated the project documentation, if applicable.
    • This is required for new features.
  • If this is my first contribution, I have added myself to the list of contributors.
  • I have updated the project Changelog (this is required for all changes).

After opening your pull request:

  • I have verified that the CI checks have passed.
  • I have reviewed the test coverage changes reported by Coveralls.
  • I have requested a review from a project maintainer.

Questions and Comments

  • While refactoring CampusMap.tsx, I noticed a bug where the Leaflet map does not render when opening the Campus Map modal from the timetable view. I asked gemini about this and it said that this is a known CSS issue where the Leaflet map container defaults to a height of 0px (or does not render properly until resized).
  • To keep this PR focused strictly on the TypeScript and functional component refactoring, I left existing styling as-is.
  • Could I take this on as a follow-up task/issue once this PR is reviewed? I'd be happy to open a dedicated PR to fix the container sizing.
  • Additionally, I was thinking about adding JSDoc comments to types.ts to document what each type represents and where it is used across the components. Let me know what you think of this.

@coveralls

coveralls commented Oct 24, 2026 •

Copy link
Copy Markdown

Coverage Report for CI Build 40797021318

Warning

Build has drifted: This PR's base is out of sync with its target branch, so coverage data may include unrelated changes.
Quick fix: rebase this PR. Learn more →

Coverage increased (+0.2%) to 60.608%

Details

  • Coverage increased (+0.2%) from the base build.
  • Patch coverage: 106 uncovered changes across 6 files (102 of 208 lines covered, 49.04%).
  • 138 coverage regressions across 5 files.

Uncovered Changes

File Changed Covered %
js/components/common/MapModal.tsx 58 15 25.86%
js/components/common/CampusMap.tsx 32 0 0.0%
js/components/common/DayBox.tsx 15 0 0.0%
js/components/common/FocusModal.tsx 13 7 53.85%
js/components/common/MapSidebar.tsx 6 0 0.0%
js/components/common/utils.ts 4 0 0.0%
Total (8 files) 208 102 49.04%

Coverage Regressions

138 previously-covered lines in 5 files lost coverage.

File Lines Losing Coverage Coverage
js/components/graph/Graph.js 89 76.73%
js/components/generate/GenerateForm.js 36 30.52%
app/Database/Migrations.hs 7 40.48%
app/Svg/Parser.hs 5 70.91%
app/Models/Time.hs 1 64.29%

Coverage Stats

Coverage Status
Relevant Lines: 4312
Covered Lines: 2677
Line Coverage: 62.08%
Relevant Branches: 1014
Covered Branches: 551
Branch Coverage: 54.34%
Branches in Coverage %: Yes
Coverage Strength: 159.53 hits per line

💛 - Coveralls

@david-yz-liu david-yz-liu left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice work, @danielrafailov! Sorry it took me a while to review this one. I left a few inline comments. In response to your comments/questions:

  • Please make a new PR to give the Leaflet map modal rendering, and thanks for pointing this out
  • Please go ahead in this PR and add JSDoc comments to types.ts. That's a great contribution to the code quality and certainly consistent with the bulk of the work you're doing here already.

Comment thread js/components/common/CampusMap.tsx Outdated
@@ -0,0 +1,162 @@
import { JSX, useRef } from "react"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the JSX, use a type-only import (if it's only being used as a type annotation). This applies broadly across all files; please also review all imports to see if there are other type-only imports.

Comment thread js/components/common/Description.tsx Outdated
export function Description({ course, sessions }: DescriptionProps): JSX.Element {
const timetableUnavailable =
Object.keys(sessions).length !== 0 &&
sessions.F?.length === 0 &&

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems to change the explicit logic, as undefined === 0 is false.

I think we can instead check whether these lengths are falsy (0, undefined)

Comment thread js/components/common/Description.tsx Outdated
//We want to use the Timetable component, but that component needs to be independent before using it here
return (
<div>
{/* Description does not have a strong label prefix */}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure what "strong label" means here. Also I would be explicit about why this matters, saying something like "and so is rendered separately"

Comment thread js/components/common/CourseModal.tsx Outdated
* Generate the data needed for the course modal table based on the meeting times corresponding
* to a course in a given session.
* @param {MeetingItem[]} allMeetTimes An array of MeetingData objects corresponding to a particular course.
* @param {string} session The session (F, S, Y) to query.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please tighten this type constraint, and other session uses, to literal types: https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types.

(I'm not sure how much of a cascade of issues this might create, so let me know if this seems unwieldy.)

Comment thread js/components/common/CourseModal.tsx Outdated

/**
* Manages state for currVisitedIndex when we click the forward button to
* gp to the next course in visitedCourses

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a typo on the word "gp". But also the wording on this line should match the wording on the navegateBack docstring

@david-yz-liu david-yz-liu left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice work, @danielrafailov!

@david-yz-liu
david-yz-liu merged commit 7791ea1 into Courseography:master Oct 31, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants