From bb5bb2ed7b55c18ddeb6c6a29f335c0e08252b8a Mon Sep 17 00:00:00 2001 From: Saahith <22772542+saahithjanapati@users.noreply.github.com> Date: Thu, 25 Sep 2025 11:58:15 -0400 Subject: [PATCH] Revamp catalog tables with responsive cards --- src/Catalog.css | 854 +++++++++++++++++++-------------------------- src/CatalogPage.js | 405 +++++++++++---------- 2 files changed, 591 insertions(+), 668 deletions(-) diff --git a/src/Catalog.css b/src/Catalog.css index 49037ad..7ea4d37 100644 --- a/src/Catalog.css +++ b/src/Catalog.css @@ -1,645 +1,521 @@ - - -table{ - width: 100%; /* Set the fixed width for the entire table */ - border: none; - border-spacing: 0; -} - -body{ - overflow-x: hidden; -} - - -.back-to-top { - position: fixed; - bottom: 20px; - right: 20px; - padding: 10px 20px; - background-color: #ffffff; /* White theme background */ - color: #000000; /* White theme text color */ - border: none; - border-radius: 5px; - cursor: pointer; - opacity: 0; /* Start with hidden */ - transition: opacity 0.3s ease-in-out, background-color 0.3s ease-in-out; - font-size: 15px; /* Default font size */ - font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', - 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', - sans-serif; - font-weight: bold; - z-index: 1000; /* Ensure it appears in front of other elements */ - border-radius: 50%; /* Make the button circular */ - -} - -.back-to-top:hover { - background-color: #d7d3d3; /* Light theme hover background */ -} - -.back-to-top.show { - opacity: 1; /* Fade in when the button should be visible */ -} - - -@media (prefers-color-scheme: light) { - .back-to-top { - border: 1px solid #000000; /* Add a black border in light mode */ - } +:root { + --catalog-card-bg: #ffffff; + --catalog-card-border: rgba(15, 23, 42, 0.15); + --catalog-card-text: #0f172a; + --catalog-muted: #475569; + --catalog-button-bg: #f3f4f6; + --catalog-button-text: #0f172a; + --catalog-button-border: rgba(15, 23, 42, 0.15); + --catalog-chip-bg: rgba(24, 66, 118, 0.08); + --catalog-accent: #184276; } - @media (prefers-color-scheme: dark) { - .back-to-top { - background-color: #ffffff; /* White theme background for dark mode */ - color: #000000; /* White theme text color for dark mode */ - } - - .back-to-top:hover { - background-color: #d7d3d3; /* Light theme hover background for dark mode */ + :root { + --catalog-card-bg: rgba(15, 23, 42, 0.92); + --catalog-card-border: rgba(148, 163, 184, 0.35); + --catalog-card-text: #f8fafc; + --catalog-muted: #cbd5f5; + --catalog-button-bg: rgba(255, 255, 255, 0.12); + --catalog-button-text: #f8fafc; + --catalog-button-border: rgba(148, 163, 184, 0.4); + --catalog-chip-bg: rgba(24, 66, 118, 0.35); + --catalog-accent: #4f8fe4; } } -@media (max-width: 768px) { - .back-to-top { - padding: 10px 20px; /* Increase padding for smaller screens */ - font-size: 15px; /* Increase font size for smaller screens */ - } +body { + overflow-x: hidden; } -@media (max-width: 480px) { - .back-to-top { - padding: 8px 16px; /* Increase padding for very small screens */ - font-size: 13px; /* Increase font size for very small screens */ - } +.sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border: 0; } -.department-container { - max-height: 0; - overflow: hidden; - transition: max-height 0.3s ease-out; +.catalogPage { + display: flex; + flex-direction: column; + gap: 32px; + padding-bottom: 56px; } -.department-container.expanded { - max-height: 1000px; /* Adjust this value based on your content */ - transition: max-height 0.5s ease-in; +.catalogPage__intro { + display: flex; + flex-direction: column; + gap: 12px; + align-items: flex-start; } -.department-table { - padding: 15px 0; +.department-title { margin: 0; - list-style-type: none; - display: grid; - grid-template-columns: repeat(2, 1fr); - grid-gap: 15px; - width: 100%; + font-size: clamp(1.9rem, 3.4vw, 2.6rem); + color: var(--catalog-card-text); } -.department-item { - background: rgba(255, 255, 255, 0.05); - border-radius: 8px; - transition: all 0.2s ease-in-out; - text-align: left; - box-sizing: border-box; +.catalogPage__controls { + display: flex; + flex-wrap: wrap; + align-items: center; + gap: 16px; } -.department-item:hover { - transform: translateY(-3px); - background: rgba(255, 255, 255, 0.1); +.catalogPage__semester-select select { + min-width: 220px; + padding: 10px 14px; + border-radius: 10px; + border: 1px solid var(--catalog-button-border); + background-color: var(--catalog-button-bg); + color: var(--catalog-button-text); + font-size: 1rem; + font-family: inherit; } -.department-item a { - display: block; - padding: 20px; - text-decoration: none; - color: inherit; +.catalogPage__last-updated { + color: var(--catalog-muted); + font-size: 0.95rem; + margin: 0; } -.department-item a .department-name { - color: #fff; - font-size: 16px; - font-weight: bold; +.toggle-button { + display: inline-flex; + align-items: center; + gap: 8px; + padding: 10px 16px; + border-radius: 999px; + border: 1px solid var(--catalog-button-border); + background-color: var(--catalog-button-bg); + color: var(--catalog-button-text); + font-size: 0.95rem; + font-weight: 600; + cursor: pointer; + transition: background-color 0.2s ease, transform 0.2s ease; +} + +.toggle-button:hover, +.toggle-button:focus-visible { + background-color: rgba(24, 66, 118, 0.12); + transform: translateY(-1px); +} + +.catalog-button { + display: inline-flex; + align-items: center; + justify-content: center; + padding: 8px 14px; + border-radius: 999px; + border: 1px solid var(--catalog-button-border); + background-color: var(--catalog-button-bg); + color: var(--catalog-button-text); + font-size: 0.95rem; + font-weight: 600; + text-decoration: none; + transition: background-color 0.2s ease, transform 0.2s ease; + white-space: nowrap; } - -/* .minimized-table td { - display: none; /* Hide the table contents }*/ - -/* CSS for Minimized Table */ -/* .minimized-table tr { - display: none; /* Hide the table contents */ -/* } */ - - - - -.expanded-table { - display: table; +.catalog-button:hover, +.catalog-button:focus-visible { + background-color: rgba(24, 66, 118, 0.12); + transform: translateY(-1px); } +.catalog-button--optional { + opacity: 0.9; +} -.catalog-section { +.subject-section { display: flex; flex-direction: column; - align-items: flex-start; - padding-bottom: 10px; - border-bottom: 1px solid #333; + gap: 20px; } -/* Example to limit the width of the entire catalog container */ -.catalog { - max-width: 800px; /* Adjust the max-width as needed */ - margin: 0 auto; /* Center the catalog in its parent container */ +.subject { + font-size: clamp(1.75rem, 3vw, 2.4rem); + margin: 0; + color: var(--catalog-card-text); } - - -.section-title { - display: flex; - justify-content: space-between; - align-items: center; - width: 100%; - font-size: 30px; - font-weight: bold; - color: white; - text-align: left; - cursor: pointer; - padding: 10px 0; +.subject-courses { + display: flex; + flex-direction: column; + gap: 20px; } -.chevron { - border-style: solid; - border-width: 0.1em 0.1em 0 0; - content: ''; - display: inline-block; - height: 0.3em; - width: 0.3em; - transform: rotate(135deg); - transition: transform 0.3s ease-out; - border-color: #888; +.course-card { + background-color: var(--catalog-card-bg); + color: var(--catalog-card-text); + border: 1px solid var(--catalog-card-border); + border-radius: 16px; + box-shadow: 0 18px 40px -32px rgba(15, 23, 42, 0.35); + transition: transform 0.2s ease, box-shadow 0.2s ease; + overflow: hidden; } -.chevron.expanded { - transform: rotate(-45deg); +.course-card--expanded { + box-shadow: 0 24px 44px -28px rgba(15, 23, 42, 0.45); } - -.button-container{ +.course-card__header { display: flex; - justify-content: flex-end; + align-items: center; + gap: 20px; + justify-content: space-between; + padding: 20px 24px; } - - - - -.section-type{ - width: 20% +.course-card__toggle { + display: flex; + align-items: center; + gap: 16px; + flex: 1; + background: none; + border: none; + padding: 0; + color: inherit; + text-align: left; + cursor: pointer; + font-size: clamp(1.05rem, 2.5vw, 1.35rem); + font-weight: 600; + font-family: inherit; } -.section-number{ - width: 5% +.course-card__toggle:focus-visible { + outline: 3px solid rgba(24, 66, 118, 0.4); + outline-offset: 4px; } -.instructor{ - width: 20% +.course-card__title { + flex: 1; } -.enrollment{ - +.course-card__chevron { + width: 12px; + height: 12px; + border-right: 2px solid currentColor; + border-bottom: 2px solid currentColor; + transform: rotate(45deg); + transition: transform 0.25s ease; } -.meeting-table{ - width: 100%; - vertical-align: top; +.course-card__chevron--open { + transform: rotate(-135deg); } -.meeting-table-head, -.meeting-table-content, -.meeting-row { - width: 100%; +.course-card__actions { + display: flex; + flex-wrap: wrap; + justify-content: flex-end; + gap: 10px; } -.meeting-table-head, -.meeting-row { - display: grid; - grid-template-columns: repeat(2, minmax(0, 1fr)); - column-gap: 12px; - text-align: center; +.course-card__content { + display: flex; + flex-direction: column; + padding-bottom: 8px; } -.meeting-table-content { +.course-grid { display: grid; - row-gap: 6px; + grid-template-columns: minmax(180px, 1.6fr) minmax(140px, 1fr) minmax(200px, 1.5fr) minmax(140px, 1fr) minmax(220px, 1.6fr); + gap: 18px; + align-items: stretch; + padding: 16px 24px; } -.meeting-row .days, -.meeting-row .time { - display: block; +.course-card__content .course-grid:nth-of-type(odd) { + background-color: transparent; } -.days{ +.course-card__content .course-grid:nth-of-type(even) { + background-color: var(--catalog-chip-bg); } -.time{ +.course-grid--header { + background-color: var(--catalog-accent); + color: #ffffff; + font-weight: 600; + text-transform: uppercase; + letter-spacing: 0.04em; + border-bottom: 1px solid var(--catalog-card-border); } -.custom-table button{ - /* background: #e88c42; */ - color: #000000; - font-size: 15px; - padding: 0.5em 0.5em; - border: none; - border-radius: 5px; - cursor: pointer; - font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', - 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', - sans-serif; - font-weight: bold; +.course-grid__cell { + display: flex; + flex-direction: column; + gap: 6px; + justify-content: center; + font-size: 0.95rem; } -a { - font-size: 16px; +.course-grid__cell--header { + align-items: center; + justify-content: center; + text-align: center; + font-size: 0.85rem; } -p{ - font-size: 16px; +.course-grid__cell--meetings { + justify-content: flex-start; } -tr{ - font-size: 16px; +.instructor-name { + margin: 0; } - -.catalogPage .custom-table { - width: 100%; - max-width: 1000px; /* Limit the table width on large screens */ - border: 1px solid #fff; - border-radius: 3px; - table-layout: fixed; +.meeting-table-content { + display: grid; + gap: 6px; } -.custom-table th, .custom-table td { - padding: 8px; /* Adjust padding as needed */ - text-align: center; /* Center-align text within cells */ -} -.custom-table td { - padding: 8px; /* Adjust padding as needed */ - text-align: center; -} -.custom-table th { - /* background-color: #656769; */ - background-color: #184276; +.meeting-row { + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: 10px; text-align: center; - /* background-color: #1d1d1e; */ -} - -.custom-table .column-names { - position: sticky; - /* top: 2.5em; */ + font-size: 0.9rem; } -.custom-table .title-header { - position: sticky; - /* top: 0; */ - - z-index: 5; /* Ensure the header appears above the table content */ -} - -.custom-table .title-header th{ - position: sticky; - text-align: left; - /* top: 0; */ - - z-index: 5; /* Ensure the header appears above the table content */ +.meeting-row .days, +.meeting-row .time { + display: inline-block; + font-variant-numeric: tabular-nums; } -.course-title{ - font-size: 30px; +.back-to-top { + position: fixed; + bottom: 20px; + right: 20px; + padding: 12px 20px; + background-color: #ffffff; + color: #000000; + border: 1px solid rgba(15, 23, 42, 0.1); + border-radius: 50%; + cursor: pointer; + opacity: 0; + transition: opacity 0.3s ease-in-out, background-color 0.3s ease-in-out; + font-size: 15px; + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif; font-weight: bold; - padding: 20px; - - text-align: left; - flex-grow: 1; + z-index: 1000; } -.external-buttons{ - width: 20%; - /* min-width: 350px; */ - text-align: right; +.back-to-top.show { + opacity: 1; } - - - - -.custom-table .expanded { - display: table-row; +.back-to-top:hover { + background-color: #d7d3d3; } -.custom-table .collapsed { - display: none; +@media (prefers-color-scheme: dark) { + .back-to-top { + background-color: #ffffff; + color: #000000; + } } - - - -.custom-table tr { - border: none; /* Remove all borders for data rows */ +.department-container { + max-height: 0; + overflow: hidden; + transition: max-height 0.3s ease-out; } -/* Style for even rows */ -.custom-table tr:nth-child(even) { - /* background-color: #1e2b53; Background color for odd rows */ - background-color: #1e2b53; /* Background color for odd rows */ - - +.department-container.expanded { + max-height: 1200px; + transition: max-height 0.5s ease-in; } -/* Style for odd rows */ -.custome-table tr:nth-child(odd) { - background-color: #191c21; /* Background color for even rows */ - +.department-table { + padding: 15px 0; + margin: 0; + list-style-type: none; + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 15px; + width: 100%; } - -/* Style for all rows of the inner table */ -.custom-table tr:nth-child(even) .meeting-table .meeting-row, -.custom-table tr:nth-child(odd) .meeting-table .meeting-row { - background-color: inherit; /* Inherit background color from outer table */ +.department-item { + background: var(--catalog-card-bg); + border: 1px solid var(--catalog-card-border); + border-radius: 12px; + transition: transform 0.2s ease, box-shadow 0.2s ease; + text-align: left; + box-sizing: border-box; } -h3, h2, .custom-table tr{ - color: #fff; +.department-item:hover { + transform: translateY(-3px); + box-shadow: 0 18px 30px -28px rgba(15, 23, 42, 0.45); } -h2{ - font-size: 30px; +.department-item a { + display: block; + padding: 20px; + text-decoration: none; + color: var(--catalog-card-text); } -ul { - list-style-type: none; +.department-item a .department-name { + font-size: 1rem; + font-weight: 600; } -.custom-table button:hover{ - background-color: #b4b0b0; +.catalog { + max-width: 800px; + margin: 0 auto; } - - - -tr.title-header:hover th{ - cursor: pointer; /* Optional: Change the cursor to a pointer to indicate it's clickable */ - text-decoration: underline; +.catalog-section { + display: flex; + flex-direction: column; + align-items: flex-start; + padding-bottom: 12px; + border-bottom: 1px solid var(--catalog-card-border); } -.toggle-button{ - /* background: #e88c42; */ - color: #000000; - font-size: 15px; - padding: 0.5em 0.5em; - border: none; - border-radius: 5px; +.section-title { + display: flex; + justify-content: space-between; + align-items: center; + width: 100%; + font-size: clamp(1.6rem, 3vw, 2rem); + font-weight: 700; + color: var(--catalog-card-text); + text-align: left; cursor: pointer; - font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', - 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', - sans-serif; - font-weight: bold; -} - -.toggle-button:hover{ - background-color: #d7d3d3; + padding: 14px 0; } - - - - - - -/* light / dark mode stuff */ - -@media (prefers-color-scheme: light) { - .section-title{ - color: #000000; - } - - .chevron { - border-color: #999; - } - - h1, h2, h3, h4, h5 { - color: #000000; - } - - .department-item { - background: #f1f1f1; - border: 1px solid #e5e5e5; - } - - .department-item:hover { - background: #e9e9e9; - border-color: #ddd; - } - - .department-item a .department-name { - color: #000; - } - - - .catalogPage .catalog-button:hover{ - background-color: #c1baba; - - } - - .toggle-button{ - background-color: #ffffff; - border: 1px solid #000000; - border-radius: 5px; - } - - .catalogPage .custom-table { - border: 1px solid #000000; - - } - .catalogPage .custom-table tr{ - color: #000000; - } - .catalogPage .custom-table th { - /* background-color: #ffdeb3; */ - background-color: #fff4e6; - background-color: #e7e7e7; - - } - /* Style for even rows */ - .catalogPage .custom-table tr:nth-child(even) { - /* background-color: #fff4e6; */ - background-color: #f0f0f0; - } - - /* Style for odd rows */ - .catalogPage .custom-table tr:nth-child(odd) { - background-color: #ffffff; /* Background color for even rows */ - - } - - /* Style for all rows of the inner table */ - .catalogPage .custom-table tr:nth-child(even) .meeting-table .meeting-row, - .catalogPage .custom-table tr:nth-child(odd) .meeting-table .meeting-row { - background-color: inherit; /* Inherit background color from outer table */ - } - - - .catalogPage .custom-table button{ - /* background: #e88c42; */ - background-color: #ffffff; - border: 1px solid #000000; - border-radius: 5px; - } - +.chevron { + border-style: solid; + border-width: 0.12em 0.12em 0 0; + content: ''; + display: inline-block; + height: 0.45em; + width: 0.45em; + transform: rotate(135deg); + transition: transform 0.3s ease-out; + border-color: var(--catalog-muted); } -.catalogPage .subject { - font-size: 35px; +.chevron.expanded { + transform: rotate(-45deg); } -@media (max-width: 1000px) { - .catalogPage h2{ - font-size: 14px - } - - .catalogPage h3{ - font-size: 14px; +@media (max-width: 1100px) { + .course-grid { + grid-template-columns: minmax(160px, 1.4fr) minmax(120px, 0.9fr) minmax(180px, 1.4fr) minmax(120px, 0.9fr) minmax(200px, 1.5fr); + gap: 14px; } +} - - .catalogPage .section-title{ - font-size: 20px; - cursor: pointer; - } - - /* .catalogPage .section-title:hover{ - cursor: pointer; - } */ - - - - .catalogPage .custom-table { - width: 90%; +@media (max-width: 900px) { + .catalogPage__controls { + flex-direction: column; + align-items: flex-start; } - @media (max-width: 768px) { - .catalogPage .hide-button { - display: none; - } + .course-card__header { + flex-direction: column; + align-items: flex-start; } - .catalogPage .catalog-button { - text-align: right; - font-size: 8px; - white-space: nowrap; - } - - .toggle-button { - font-size: 8px; + .course-card__actions { + justify-content: flex-start; } +} - .catalogPage .external-buttons { - padding: 0.2em 0.2em; - font-size: 8px; - width: 5%; +@media (max-width: 768px) { + .catalogPage { + gap: 24px; } - .catalogPage .course-title { - font-size: max(min(calc(4.5vw - 10px), 30px), 10px); + .course-grid--header { + display: none; } - .catalogPage .custom-table button{ - font-size: max(min(calc(4vw - 12px), 15px), 8px); + .course-grid { + grid-template-columns: 1fr; + gap: 12px; + padding: 18px; } - - .catalogPage table { - font-size: 8px; - border: none; - border-collapse: collapse; + .course-card__content .course-grid:nth-of-type(even) { + background-color: transparent; } - .catalogPage .subject { - font-size: max(min(calc(4.5vw - 10px), 35px), 15px); - } - - .catalogPage a { - font-size: max(min(calc(4vw - 12px), 15px), 7px); + .course-grid__cell { + position: relative; + padding-left: 0; } - .catalogPage p{ - font-size: max(min(calc(4vw - 12px), 15px), 7px); + .course-grid__cell::before { + content: attr(data-label); + font-weight: 600; + text-transform: uppercase; + letter-spacing: 0.04em; + color: var(--catalog-muted); + margin-bottom: 4px; + font-size: 0.75rem; } - .catalogPage tr{ - font-size: max(min(calc(4vw - 12px), 15px), 7px); + .course-grid__cell--meetings::before { + margin-bottom: 6px; } - .catalogPage .table-header { - font-size: max(min(calc(4vw - 12px), 15px), 7px); + .meeting-table-content { + gap: 8px; } - .catalogPage .section-type{ - width: 10%; - font-size: max(min(calc(4vw - 12px), 15px), 7px); - } - - .catalogPage .section-number{ - width: 10%; - padding: 0px; - font-size: max(min(calc(4vw - 12px), 15px), 7px); + .meeting-row { + display: flex; + justify-content: space-between; + text-align: left; + gap: 18px; } - .catalogPage .instructor{ - width: 10%; - padding: 0px; - font-size: max(min(calc(4vw - 12px), 15px), 8px); + .catalog-button, + .toggle-button { + width: 100%; + justify-content: center; } - .catalogPage .enrollment{ - width: 1%; - padding: 0px; - font-size: max(min(calc(4vw - 12px), 15px), 8px); - - } - .catalogPage .meeting-table{ - width: 10%; + .course-card__actions { + width: 100%; } - .catalogPage .days{ - width: 9%; + .back-to-top { + padding: 10px 18px; + font-size: 15px; } +} - .catalogPage .time{ - width: 9%; +@media (max-width: 600px) { + .catalog-button--optional { + display: none; } - .catalogPage .location{ - width: 9%; + .catalogPage__semester-select select { + width: 100%; } } -@media (max-width: 768px) { /* Adjust the breakpoint as needed */ - .section-title{ - font-size: 20px; - } - .catalog-section { - padding: 10px; /* Add some padding to the section for narrower screens */ - } +@media (max-width: 500px) { .department-table { - grid-template-columns: 1fr; /* One column when the screen is under 768 pixels */ - } - .department-item { - /* flex-basis: 100%; /* Set it to 100% to display one item per row on mobile */ - } - strong{ - font-size: 14px; + grid-template-columns: 1fr; } + .back-to-top { + padding: 8px 16px; + font-size: 13px; + } } diff --git a/src/CatalogPage.js b/src/CatalogPage.js index 48859dc..f97224f 100644 --- a/src/CatalogPage.js +++ b/src/CatalogPage.js @@ -1,11 +1,114 @@ -import React, { useState, useEffect, useCallback} from 'react'; -import { useParams, useNavigate} from 'react-router-dom'; -import './Catalog.css' -import './Catalog.css' +import React, { useState, useEffect, useCallback } from 'react'; +import { useParams, useNavigate } from 'react-router-dom'; +import './Catalog.css'; import { requirementMapping } from './RequirementMap'; +const CourseCard = ({ + course, + isExpanded, + onToggle, + getSisLink, + getCourseForumLink, + getVAGradesLink, + generateInstructorHTML, + generateMeetingTable, +}) => { + const tableKey = `${course.subject}${course.catalog_number}`; + const handleToggle = () => onToggle(tableKey); + + return ( +
{instructor.name}
); - } + if (!Array.isArray(instructors) || instructors.length === 0) { + returnTBA
; } - return elements; - } + + return instructors.map((instructor) => { + const key = `${instructor.name}-${instructor.email || 'no-email'}`; + + if (instructor.email && instructor.email.length > 0) { + return ( + + ); + } + + return ( ++ {instructor.name} +
+ ); + }); + }; const getSisLink = (subject, catalog_number) => { @@ -201,13 +311,12 @@ function CatalogPage() { } const getVAGradesLink = (subject, catalog_number) => { - return `https://vagrades.com/uva/${subject}${catalog_number}` - } - + return `https://vagrades.com/uva/${subject}${catalog_number}`; + }; const getCourseForumLink = (subject, catalog_number) => { - return `https://thecourseforum.com/course/${subject}/${catalog_number}` - } + return `https://thecourseforum.com/course/${subject}/${catalog_number}`; + }; const handleSemesterChange = (event) => { const newSemester = event.target.value; @@ -216,145 +325,83 @@ function CatalogPage() { }; - const elements = []; - - - async function addRequirementName() { - if (department.includes('-')) { - elements.push(