GithubHelp home page GithubHelp logo

gt-scheduler / website Goto Github PK

View Code? Open in Web Editor NEW
92.0 2.0 22.0 284.1 MB

Scheduling application designed to mitigate some of the pain-points present throughout Georgia Tech's registration process.

Home Page: https://gt-scheduler.org

License: GNU Affero General Public License v3.0

HTML 0.50% SCSS 12.70% TypeScript 86.79%

website's Introduction

GT Scheduler

Georgia Tech Scheduler lets you find the schedule that fits you best among all the possible combinations of courses.

๐Ÿ“ƒ License & Copyright Notice

This work is a derivative of the original and spectacular GT Scheduler project created by Jinseo Park. The original work and all modifications are licensed under the AGPL v3.0 license.

Original Work

Copyright (c) 2020 Jinseo Park ([email protected])

Modifications

Copyright (c) 2020 the Bits of Good "GT Scheduler" team

๐Ÿ” Overview

The app is a React single-page application (SPA) (built using create-react-app) that forms the frontend website users interact with when they go to https://gt-scheduler.org/. It is written in TypeScript (a typed superset of JavaScript), and uses SCSS for styling (a superset of CSS that supports advanced features).

To implement its goal of facilitating schedule creation and class exploration, GT Scheduler stores all data locally in cookies. Then, it sources any relevant data at runtime from a variety of sources, such as:

Once features are merged into the main branch, they are automatically deployed to the gh-pages branch using a GitHub Action workflow. This branch is set up to serve traffic to the public site, https://gt-scheduler.org/, using the GitHub Pages service.

The website uses Google Analytics for aggregate analytics and information about how many people are using the app. It also utilizes Sentry for automatic error reporting.

๐Ÿš€ Running Locally

Requisite software

  • Node.js (any recent version will probably work)
  • Installation of the yarn package manager version 1 (support for version 2 is untested)

Running the app

After cloning the repository to your local computer, run the following command in the repo folder:

yarn install

This may take a couple minutes and will create a new folder called node_modules with all of the dependencies installed within. This only needs to be run once.

Then, to start a local development version of the frontend app, run:

yarn start

The app should then be viewable at http://localhost:3000, which you can open a new browser tab to view.

With that, you're able to make changes to the code and have them be re-built and viewable after a short delay in the same tab. This is the main workflow for adding new features or fixing bugs and testing them in the actual app.

Warning

When running the development server (and when building the site), a large number of warnings may appear in the console that look something like:

WARNING in ./node_modules/parse5/dist/common/token.js
Module Warning (from ./node_modules/source-map-loader/dist/cjs.js):
Failed to parse source map from '.../website/node_modules/parse5/dist/common/token.js.map' file: Error: ENOENT: no such file or directory, open '.../website/node_modules/parse5/dist/common/token.js.map'
 @ ./node_modules/parse5/dist/index.js 13:0-44 14:0-27
 @ ...

These can be safely ignored.

They are due to a combination of misconfiguration in a few transitive dependencies (such as parse5, /@firebase/auth, and exponential-backoff) and the overzealousness of create-react-app's default configuration in reporting non-issues.

See facebook/create-react-app#11767 for more details.

Secrets (only for BoG Developers)

  • yarn run secrets:linux - obtain app secrets for Linux and MacOS; ask Engineering Manager for password
  • yarn run secrets:windows - obtain app secrets for Windows; ask Engineering Manager for password

Linting

The project uses pre-commit hooks using Husky and lint-staged to run linting (via ESLint) and formatting (via Prettier). These can be run manually from the command line to format/lint the code on-demand, using the following commands:

  • yarn run lint - runs ESLint and reports all linting errors without fixing them
  • yarn run lint:fix - runs ESLint and reports all linting errors, attempting to fix any auto-fixable ones
  • yarn run format - runs Prettier and automatically formats the entire codebase
  • yarn run format:check - runs Prettier and reports formatting errors without fixing them

๐Ÿ‘ฉโ€๐Ÿ’ป Contributing

The GT Scheduler project welcomes (and encourages) contributions from the community. Regular development is performed by the project owners (Jason Park and Bits of Good), but we still encourage others to work on adding new features or fixing existing bugs and make the registration process better for the Georgia Tech community.

More information on how to contribute can be found in the contributing guide.

website's People

Contributors

jazeved0 avatar 64json avatar abhitirumala avatar karpawich avatar yatharth-b avatar arthelon avatar justinh11235 avatar samarth52 avatar jz1116 avatar nhatnghiho avatar kw143 avatar adityavidyadharan avatar sophiazlin avatar jackdimarco avatar ematthews35 avatar charleskimbac avatar izou3 avatar joannacheng21 avatar kieranlblack avatar luke9kim8 avatar madelinehartlage avatar roboticwater avatar flipfloop avatar ethankeystone avatar huangvincent170 avatar sgao88 avatar vkameswaran avatar

Stargazers

Ryan Thomas Lynch avatar  avatar Rohan Godha avatar Amani Bobo avatar Noah Buchanan avatar Anthony Zang avatar Porter Zach avatar Mark Volovoi avatar  avatar Anson avatar Mike Odnis avatar  avatar Shane Michael Downs avatar Brandon Ho avatar  avatar  avatar  avatar Richard Barrezueta avatar Taye Beckford avatar  avatar Zhen Li avatar Denis Koshelev avatar Nathan Abraham avatar Nelson Rodriguez avatar Dmitri K. avatar Advay Balakrishnan avatar Yan-Tong Lin avatar Dylan Kelly avatar Nick avatar colin avatar Alex Jenkins avatar Kevin Chen avatar Vaibhav kumar avatar  avatar Ethan Kiang avatar Shiv Trivedi avatar Bianca Smart avatar  avatar Alex Latz avatar Haojun Song avatar Yaseen avatar William Gitta avatar Frank Gao avatar  avatar Sahil Khose avatar Yunho Cho avatar  avatar Ansh Gandhi avatar Akash Patel avatar Avinash Swaminathan avatar Mahesh Natamai avatar Nathan Gong avatar  avatar Michael avatar LE avatar Cynthia avatar Jaeyoung Lee avatar zsliu98 avatar Ruijian Huang avatar john avatar Henry Le Berre avatar Giam Nguyen avatar kukibar avatar Y. Yang avatar  avatar Gannon Prudhomme avatar Trent Johnson avatar  avatar  avatar Shuyang Wu avatar Akshay Deodhar avatar Lucien avatar Owen Oertell avatar Matthew Free avatar John Wright Stanly avatar David L. avatar blw avatar Matthew Perry avatar  avatar Bits of Good avatar  avatar  avatar Aidan avatar  avatar  avatar Austin Jackson avatar Gabriel Britain avatar  avatar  avatar Sean Fish avatar  avatar  avatar

Watchers

James Cloos avatar Nathan Gong avatar

website's Issues

Modify GPA Fetch Mechanism to Use (New/Experimental?) Course Critique API

Problem Description

Currently, GT Scheduler retrieves the course GPA of classes by making requests to the Course Critique page for that course. For example, to get the average course GPA for CS 4510: Automata and Complexity Theory, GT Scheduler retrieves https://critique.gatech.edu/course?courseID=CS%204510 and then parses its HTML to extract the desired GPA information.

Recently, however, it seems that Course Critique has changed to a React-based single-page-application architecture where the course GPA (and other data) is fetched once the page loads into the browser and is not in the HTML that the browser initially loads (similar to how GT Scheduler works). As a result, the HTML parsing logic no longer works and the GPA always appears as "N/A":

course_gpa_na

However, their modification has a side effect: it's now much easier for us to consume the same data that they use in Course Critique. The API that they make requests to within Course Critique provides the desired information in JSON form:

https://c4citk6s9k.execute-api.us-east-1.amazonaws.com/test/data/course?courseID=CS%204510

Note that, based on the URL, it's likely that this is an experimental/test API URL that will need to be changed in the future when they (presumably) stabilize it. For now, though, it will allow us to restore the functionality of the course GPA feature.

Your Goal

  • Modify the course scraping logic in beans/Course.js to instead make requests to a URL with the following format:
    • {base}/course?courseID={course}
      • where {base} is a constant that is currently "https://c4citk6s9k.execute-api.us-east-1.amazonaws.com/test/data" and can be changed in the future
      • {course} is the combined course subject + number ("CS 4510") that has been URL encoded
  • Once the request has been made, parse the JSON and use the data in the header field to return the course GPA and the GPA for each instructor in a map:
    • The "averageGpa" key should contain the overall average GPA of all instructors, as a string
    • Each instructor should have a key with the format of "{firstName} {lastName}" and the value should be the average GPA for them, as a string
  • A good course to look at that contains multiple instructors is CS 1331: https://c4citk6s9k.execute-api.us-east-1.amazonaws.com/test/data/course?courseID=CS%201331
Formatted JSON for CS 1331
{
    "header":[
        {
            "course_name":"Introduction to Object Oriented Programming",
            "description":"Introduction to techniques and methods of object-oriented programming such an encapsulation inheritance and polymorphism. Emphasis on software development and individual programming skills.",
            "credits":3,
            "avg_gpa":3.03,
            "avg_a":38.5,
            "avg_b":30.5,
            "avg_c":14.2,
            "avg_d":5.0,
            "avg_f":3.7,
            "avg_w":8.1,
            "full_name":"CS 1331 - Introduction to Object Oriented Programming"
        }
    ],
    "raw":[
        {
            "instructor_gt_username":"rlandry9",
            "instructor_name":"Landry, Richard",
            "class_size_group":"Very Large (50 students or more)",
            "GPA":3.0,
            "A":44.7,
            "B":25.8,
            "C":11.4,
            "D":5.2,
            "F":7.3,
            "W":5.6,
            "sections":2
        },
        {
            "instructor_gt_username":"gtg242z",
            "instructor_name":"Lillethun, David J",
            "class_size_group":"Very Large (50 students or more)",
            "GPA":3.19,
            "A":49.0,
            "B":23.0,
            "C":12.3,
            "D":4.7,
            "F":3.3,
            "W":7.7,
            "sections":6
        },
        {
            "instructor_gt_username":"mmcdaniel43",
            "instructor_name":"McDaniel, Melinda Hardy",
            "class_size_group":"Large (31-49 students)",
            "GPA":3.1,
            "A":39.4,
            "B":30.8,
            "C":12.2,
            "D":4.8,
            "F":2.8,
            "W":10.0,
            "sections":29
        },
        {
            "instructor_gt_username":"oomojokun3",
            "instructor_name":"Omojokun, Olufisayo A",
            "class_size_group":"Large (31-49 students)",
            "GPA":3.02,
            "A":38.4,
            "B":32.4,
            "C":14.9,
            "D":5.2,
            "F":3.7,
            "W":5.5,
            "sections":37
        },
        {
            "instructor_gt_username":"jqu7",
            "instructor_name":"Qu, Junfeng",
            "class_size_group":"Small (10-20 students)",
            "GPA":3.7,
            "A":70.0,
            "B":30.0,
            "C":0.0,
            "D":0.0,
            "F":0.0,
            "W":0.0,
            "sections":1
        },
        {
            "instructor_gt_username":"cs257",
            "instructor_name":"Simpkins, Christopher L",
            "class_size_group":"Large (31-49 students)",
            "GPA":3.11,
            "A":41.8,
            "B":28.1,
            "C":13.2,
            "D":4.6,
            "F":3.1,
            "W":9.2,
            "sections":102
        },
        {
            "instructor_gt_username":"js71",
            "instructor_name":"Stasko, John T",
            "class_size_group":"Large (31-49 students)",
            "GPA":2.81,
            "A":31.5,
            "B":31.2,
            "C":16.9,
            "D":6.2,
            "F":6.8,
            "W":7.3,
            "sections":39
        },
        {
            "instructor_gt_username":"ms351",
            "instructor_name":"Sweat, Monica",
            "class_size_group":"Very Large (50 students or more)",
            "GPA":2.81,
            "A":26.0,
            "B":38.2,
            "C":21.9,
            "D":5.4,
            "F":3.7,
            "W":4.8,
            "sections":10
        },
        {
            "instructor_gt_username":"swatson38",
            "instructor_name":"Watson-Phillips, Susan Gayle",
            "class_size_group":"Large (31-49 students)",
            "GPA":3.06,
            "A":36.1,
            "B":34.8,
            "C":13.4,
            "D":4.8,
            "F":2.5,
            "W":8.2,
            "sections":25
        }
    ]
}

Memoize Recurring Events

Description

ScheduleContext contains all information about added courses, selected sections, colors, etc., and this information is accessible by all components. To store and render custom blocks, we need to add information about recurring events into here. Check for any breaking changes.

Acceptance Criteria

  • A new Event type is created in src/types.ts
  • ScheduleContext is updated with correct typing.

Other Notes

N/A

Gray Screen when logging in; likely a cookie issue

There is a gray Screen when opening up the app; it is likely a cookie issue.

Cookie Dump
[
{
    "domain": ".gt-scheduler.org",
    "expirationDate": 1680996433,
    "hostOnly": false,
    "httpOnly": false,
    "name": "_ga",
    "path": "/",
    "sameSite": "unspecified",
    "secure": false,
    "session": false,
    "storeId": "0",
    "value": "GA1.1.394932681.1617642774",
    "id": 1
},
{
    "domain": ".gt-scheduler.org",
    "expirationDate": 1680996433,
    "hostOnly": false,
    "httpOnly": false,
    "name": "_ga_TPJQQ46MS9",
    "path": "/",
    "sameSite": "unspecified",
    "secure": false,
    "session": false,
    "storeId": "0",
    "value": "GS1.1.1617924433.3.0.1617924433.0",
    "id": 2
},
{
    "domain": "www.gt-scheduler.org",
    "expirationDate": 1743183297,
    "hostOnly": true,
    "httpOnly": false,
    "name": "202108",
    "path": "/",
    "sameSite": "unspecified",
    "secure": false,
    "session": false,
    "storeId": "0",
    "value": "{%22desiredCourses%22:[%22CS%204641%22%2C%22CS%203630%22%2C%22CS%202110%22%2C%22CS%204510%22%2C%22SOC%201101%22]%2C%22pinnedCrns%22:[%2287568%22%2C%2290781%22%2C%2284968%22%2C%2280311%22%2C%2289264%22]%2C%22excludedCrns%22:[]%2C%22colorMap%22:{%22CS%204641%22:%22#333333%22%2C%22CS%203630%22:%22#B0BC00%22%2C%22CS%202110%22:%22#808080%22%2C%22CS%204510%22:%22#AB149E%22%2C%22SOC%201101%22:%22#9F0500%22}%2C%22sortingOptionIndex%22:0}",
    "id": 3
},
{
    "domain": "www.gt-scheduler.org",
    "expirationDate": 1744068433,
    "hostOnly": true,
    "httpOnly": false,
    "name": "term",
    "path": "/",
    "sameSite": "unspecified",
    "secure": false,
    "session": false,
    "storeId": "0",
    "value": "undefined",
    "id": 4
},
{
    "domain": "www.gt-scheduler.org",
    "expirationDate": 1647986106,
    "hostOnly": true,
    "httpOnly": false,
    "name": "visited-merge-notice",
    "path": "/",
    "sameSite": "unspecified",
    "secure": false,
    "session": false,
    "storeId": "0",
    "value": "true",
    "id": 5
}
]

Implement course catalog active course selection

Problem Description

The course catalog tab will have a leftmost pane that handles selecting the "active" course to be displayed, which will allow users to compare various courses by viewing information about the professor, sections, and course itself.

Mockups (link to Figma)

Individual item:
image

List with none selected:
image

List with a single item selected:
image

Your Goal

Create a component and a flexbox container to align the layout of the course catalog and create the left-most pane.

In the pane component, create a list of buttons that can be clicked to select that course. The list itself should be synchronized with the Schedule tab, such that any course that appears in the left list on the Schedule tab should also appear on the leftmost pane of the Catalog tab.

Each item should display the combined course ID (subject + number) and should use the same color that is used for the course in the Schedule tab.

Each item has a delete button, which will remove it from the list (which should also remove it from the Schedule tab).

A single item can be selected at once (which will cause all other items to be faded out and will cause the selected item to have a selection "halo"), and the navigation component should have, at the least, two props:

  • selectedCourse: string | null -- the currently selected course's id, as a string, or null if no course is selected
  • setSelectedCourse: (newCourseId: string) => void -- a callback

The component should obtain the list of courses to display from the root TermContext value -- namely, the desiredCourses key from the TermData type.

Note: when branching / making a PR, please use the course-guide branch as the base

Apostrophes displayed incorrectly

Describe the bug
Apostrophes in names are replaced with ' in the "Signed in as:" dropdown.

To Reproduce

  1. Create an account with an apostrophe in the first/last name
  2. Sign in
  3. Click on the profile button in the top left

Expected behavior
Display the ' correctly

Screenshots
Actual:
image
Expected:
image

Additional context
N/A

Markers for classes in the same location overlap

When multiple classes on the same day have the same building location, their markers will overlap and only one of them will show.

Reproduction:

  1. Add MATH 4022 AU and MATH 4221 AU to the schedule (Both are located on Skiles on Tuesday)
  2. Navigate to Map

image

Product feedback / feature requests

Feedback results

After reviewing the Airtable data (need to be logged in to view; table access is restricted to maintainers) that comes from the feedback widget in the bottom-right of the web app, there are numerous feature requests/friction points that have been reported by our users.

Date Updated Number of responses Average rating (since the beginning of time)
2021-05-16 176 4.67
2021-09-14 375 4.71

The following table shows each feature/bug, in order of the number of people that reported/asked for it:

Number of requests Feature request/friction point
18 Schedule versions (implemented in #23)
11 Account/sync feature (related to #27 & implemented in #93) to let users sync between devices
3 Add custom blocks to the schedule (for work/research)
3 Add walk times / path planning to the map tab
2 Lab matching for auto-generated schedules seems to be broken when sections don't share common prefix
2 Users can't find the links to RateMyProfessor (they are confused and think the web app doesn't contain links to them for each professor)
2 Add the ability to add a course by its CRN
2 Integrate final exam schedule information (#92)
1 Factor in professor GPA for auto-suggested schedules (consider making "Max GPA" a sort option)
1 Add note for how often course data is updated (under "Course data fetched 31 minutes ago" on the left)
1 Ability to share schedules with friends
1 Ability to adjust/override credit hours for certain special courses (such as undergrad research)
1 Better CRN copying for registration directly into Oscar
1 Seats information isn't live after initial load, which is confusing when the page has been open for a long time (make the data load more often)
1 Have seats shown directly without needing tooltip
1 Include filter that hides full classes
1 Add additional UI themes other than dark/light
1 Add historical course syllabi
1 Add 3-day weekend mode/preference for the schedule generation feature
1 Location is cut off when the line is too long
1 Add instructions/docs for the site
1 Location wrongly assigned - VIP 3601 VXG assigned to Van Leer 483B
1 Integrate wioth the ORE-GT Oscar Registration Extension
1 Calendar export into Apple Calendar may be broken
1 Include course location in course info card
1 View all classes at once in map view
1 Search for courses that fit within time slot
1 Add async classes to calendar export / calendar view
1 Location search on the map (or maybe somehow exporting it to Google Maps where the user can search?)
1 Are classes in Boggs properly matched?
1 Better way to see average GPA of courses when searching

Additional desired features

Some additional features have been discussed as potential future additions to the product, such as:

  • Final exam matrix scraping to include as a component of the course catalog data, such that the dates/times of each final exam can be given for a schedule (and each class-section pair in it).

ICS File Time Zone Missing

Describe the bug
ICS calendar export files do not include time zone information.

To Reproduce
Steps to reproduce the behavior. Example:

  1. Set your Google Calendar to a time zone that isn't eastern time (for example, pacific time) by clicking the settings icon > drop down the settings on the desired calendar > calendar settings > choose default time zone
  2. On GT Scheduler home page, click Export > ICS (Calendar) file
  3. On Google Calendar, click the Settings Icon > Import & Export > Upload the ics file > choose the pacific time Calendar from the dropdown > import
  4. Observe that the classes are shifted by three hours (i.e. a class at 8am Atlanta time will show up as 8am pacific time)

Expected behavior
Classes will not shift according to the default time zone's offset from Atlanta. (for example, the 8am class will show up as 5am on a pacific time calendar)

Screenshots

Additional context
I was doing registration from the West Coast, added my classes to my calendar, but then had to redo this upon returning to Atlanta

Implement search/query pane in the course catalog

Problem Description

A major component of the course catalog feature is to allow users to search and filter for specific courses so that they can compare them. This task involves implementing the middle pane in the course catalog, which displays a search interface similar to the existing one on the Schedule tab in the live app (but will will surface more options than the filter/search interface on the Schedule tab).

Mockups (link to Figma)

Note: the Figma also has useful interaction flow annotations

Collapsed filters
image

Fully expanded filters
image

Dropdown states
image

Result item variants (top: when the corresponding course is selected (either on the left or as a preview), bottom: default)
image

Overall mockup
image

Your Goal

  • Implement the search/query pane as a component that allows the user to search for classes using a modified version of the same query components used on the front page (note: you will probably need to modify this existing component to add togglable support for the additional filters)
  • Implement a list of search results
    • Each item has the combined course ID (subject + number), the course name, and two buttons:
      • The "plus" button will 1. add the course to the user's set of courses if it is not already there and 2. select the course to become the active course to display
      • The "i" button will simply set the course to become the active course to display
    • If there are no courses that fit the user's query, then there will be a placeholder instead (see the Figma document)

Add Course Catalog Description component

Problem Description

This sprint, we're going to start adding some components for displaying detailed information about a course on a new tab, the "Course Catalog" tab. We want to display information about the currently selected course (which is currently just a hard-coded constant in src/components/CourseGuide/CourseGuide.tsx and its sections in a detailed view (in addition to the name, which is a separate task: #8).

Mockups (link to Figma)

Update 3-7-2021: used updated mockup from Figma that changed the alignment/spacing on waitlist/actual seating info

dark-description

Your Goal

  • Add CourseCatalogSections component that looks like the mockup and shows the relevant sections/information about a couse.
    • Add any sub-components as neccessary
  • Add the component to the CourseGuide component so that it displays the information for the currently selected (but constant for now) course

Note: please create a new branch off of (and make PRs to) the course-guide branch (not development)

Fetch all required data for course details pane in Course Catalog tab

Problem Description

Right now, the course header component provides the functionality to display the overall course information for a single course, but the data has not been hooked up yet.

Additionally, the course description component (table of sections) is currently in development and will need to be supplied with the appropriate data to make it functional.

(Link to Figma)

Your Goal

  1. Determine a list of what data needs to be fetched in order to make the course information pane fully functional
  • See what data currently hasn't been fetched
  • At the very least, I can think of:
    • We have no way to fetch seating information for all sections in a course
    • Our parsing of course GPA from Course Critique currently ignores professors' GPA distribution, which we'll need here
  1. Implement any data fetching as needed
  • This will likely include 1. determining what page on Oscar contains all of the seating information for all sections in a course 2. adding a new proxy route to the backend repository to make requests to Oscar on our behalf and 3. some functionality to parse the Oscar HTML into a list of per-section seating information
  1. Prepare the data to be passed in to the <CourseHeader> and <CourseDescription> components
  • Work with the current assignees for #9 to determine what props the component expects

Search resets after selecting class

Originally posted by @RoboticWater

Currently, after a user selects a class from the search results, the search bar resets. While this saves the user from having to scroll up after selecting a course (assuming they're scrolled at all), it also means that if they wanted to select multiple classes from a single search (e.g. CS 6460, CS 6474 from the search "CS 64"), they have to retype their search query.

I propose that the user's search should remain after selecting a class, so we can avoid unnecessary retyping. A** "clear input" button should also be added to the search input**, so users can quickly reset the search. These changes should minimize user inputs and frustration.

If you're worried that there wouldn't be feedback for selecting a class when a user is scrolled down so far that they can't see their current selected classes, then perhaps you could add some kind of notification pop up at the top. Like so:

demo

(Sorry for potato quality)

Lecture Lab section matching

2 problems I found:

MATH 1553 reversed section/labs

see OSCAR

Proposed solution

Try matching both ways (if a lab is A and a lecture is A03, don't just check if lab.id.startsWith(lecture.id), but also check the reverse

PHYS 2211/2212 no longer clearly indicate which labs go with which lectures (page 4)

also see OSCAR

Proposed solution

Associate Lecture/Labs if they have the same profs. More precisely,
Associate Lecture/Labs if the intersection of prof names is non-empty.

Implementation

In the existing code for matching lecture/labs for lab classes, try the first method (match by section letter), then if that returns 0 results, try the second method.

Testing

I have an implementation that works for the above classes, but has not been tested on any other classes

Create reusable empty-list component

Problem Description

In multiple frontend components, we would like to show an "empty" state for when no items are available. In order to make it consistent and re-use components, we want a single <Empty> component that displays the appropriate contents:

Mockups (link to Figma)

image

The correct SVG images to use are in the #gt-scheduler slack channel.

Your Goal

  • Add <Empty> component that takes in the following props:
    • title: string -- larger text
    • description: string -- smaller text
    • position: number -- top padding to move it down
    • className?: string & style?: React.CSSProperties -- passthrough style/className props
  • The component should be horizontally middle-aligned in whatever container it is in, and have 0 top/bottom padding (except for any additional padding added by the position prop)
  • The component should include the SVG image in the middle
  • The component should look appropriate on both light/dark mode

TypeError while resolving color from color map

When resolving the color from the color map for a single section, it's possible for the map to not contain the desired course ID. It's unclear what the underlying reason/steps to reproduce for this are, but it causes the getContentClassName function in utils.js to throw a TypeError (link to public Sentry stacktrace).

A simple solution would involve some default, fallback color being used when the map doesn't contain the course ID. Additionally, further investigation may be warranted into the conditions that cause this error to happen.

Related Sentry issue (Private)

(Must be logged in to view; only maintainers have access.)

https://sentry.io/organizations/gt-scheduler/issues/2279669214/

Estimated user impact

Sentry errors have been logged for 46 users in the issue linked above.

Add Course Catalog Header component

Problem Description

This sprint, we're going to start adding some components for displaying detailed information about a course on a new tab, the "Course Catalog" tab. We want to display the currently selected course (which is currently just a hard-coded constant in src/components/CourseGuide/CourseGuide.tsx but the app will eventually have a selection pane) at the top of the page, with additional information below it (which is a separate task: #9).

Mockups (link to Figma)

header

Example of prerequisites for CS 4510 (a class with a complex set of prereqs)
cs-4510-prereqs

Your Goal

  • Add CourseCatalogHeader component that looks like the mockup and shows the relevant global information for a course
    • Add any sub-components as neccessary
  • Add the component to the CourseGuide component so that it displays the information for the currently selected (but constant for now) course

Note: please create a new branch off of (and make PRs to) the course-guide branch (not development)

Color each component individually.

The feature
I would like to be able to color each session in the schedule individually. Most classes include all class sessions, labs, recitations, and testing periods in one course on OSCAR. This is particularly annoying as the only option for color coding on this app is to color by course, and while this is nice, it's not particularly useful for schedule visualization purposes.

Detailed explanation
Perhaps the existing coloring system remains, but each individual entry on the schedule has visualization options like size, information shown, color. This could be implemented with a cog icon that only appears when hovering over the course, then once a change has been made, another icon will appear beside the cog, like an eraser, which denotes clearing all specified formatting. There could also be schedule wide formatting options that apply to the whole document, and maybe a button that clears all specified formatting.

Mockups

Additional context

Cannot read location with hover

The feature
Give a clear 2-3 sentence description of your feature here.
Would like to see the full location, including room number when hovered over.
Detailed explanation
Elaborate on your initial description of the feature, including its components.
Now I've to manually expand the width of my browser to see the full location
Mockups
If available, include design mockups or examples of similar features in existing products that others can use as reference.
This is the current view:
image

Expanded view:
image

Expected view:
image

Additional context
Add any other context or screenshots about the feature request here.

Add Visual Feedback Upon CRN Copying

Problem Description

Right now, when copying a list of CRNs for the currently selected courses, the GT scheduler interface does add the CRNs to the user's clipboard but doesn't provide any indicator that it did. This is confusing for users, as it's unclear when the action of copying has been successfully performed.

current

Your Goal

  • Upon clicking the copy CRN button:
    • The CRNs should be added to the user's clipboard as before
    • A tooltip should be displayed on the button that contains some text like "Copied to clipboard!"
      • The tooltip should remain for a few seconds before disappearing -- its "visible duration"
      • The tooltip should remain visible until it finishes its visible duration (regardless of whether the user's mouse is hovering over it)
      • If the user presses the copy CRN button again while the tooltip is still being shown, then the tooltip's visible duration should be reset to the original visible duration

mockup

Implement a Component to View and Edit Custom Blocks

Description

We need a way for users to view all their custom blocks/events and make changes as needed. In this ticket, you will implement a card called Event that displays information about the events and contains buttons to edit, change color, and delete the event.

image

Refer to Figma for more design details.

Acceptance Criteria

UI Requirements

  • Event name field can handle text overflow.
  • Works with mobile view.

Functional Requirements

  • Use ScheduleContext, which stores info about custom blocks, to populate and color the card.
  • Users can change color with the palette icon.
  • Delete icon deletes the event from ScheduleContext.

Other Notes

  • Event should be quite similar to an existing component called Course. Refer to Course to make your life easier :).
  • All new components must be added to src/components/index.tsx.

Plans for an account feature?

Love your work here! Absolutely incredible; the best scheduler tool to use, no question.

For my friends and I, however, the essential feature for this scheduler to take over from CourseOff is the ability to save my schedule with my account, so I can access it on any device and not lose it every time that I clear cookies.

Are there plans for this? If so, do you need any help?

Make the crawler self-host its index

Right now, the frontend uses the GitHub API in an unauthenticated mode to list all of the term data documents that the crawler has prepared. While this is nice in that it requires no code from us, it's causing some users to run into IP-based rate limits, causing them to get 403's and an error screen to appear when launching the app.

Fixing this requires a change to the crawler to make it host its own index file, which can be as simple as a JSON file called index.json that contains {"terms": ["202008", "202108"]}.

Enumerating all Course Combinations causes page to freeze

Some combinations of courses generate way too many combinations of sections, causing the website to slow down

This issue was inspired by this reddit post

Steps to replicate:

  • Add a few courses with lots of lab/lecture combinations
    • eg. PHYS 2211, MATH 1554, CS 1100, CS 1301, CS1301R, ECE2031 (a theoretical 14 credit schedule) gives 402,292 combinations and takes a few seconds to load on my (pretty chonky) laptop

Screenshot from 2021-07-08 14-18-19

Proposed fix:

  • Limit the number of section combinations enumerated to a reasonable number, eg. 1000
    • beans/Oscar.js/getCombinations could be modified to simply exit the recursive function once 1000 combinations have been enumerated
    • Another possibility would be to load these lazily based on the scrollbar (when user scrolls to the end, get 1000 more combinations) but this would be more difficult.

Fix Broken Schedule Download on Certain Browsers

Problem Description

When downloading a user's schedule on certain operating systems/browser combinations, the resultant image appears broken and malformed:

Broken result

broken

Expected result

expected

download

The mechanism for taking a screenshot involves a hidden "second shadow schedule" pane (here and here) that shows the sames courses that are currently selected and is used to take screenshots of the schedule. It's unclear whether the bug is completely related to the browser or if it is also a result of other factors.

Previously reported at 64json/gt-scheduler#18 and GTBitsOfGood/gt-scheduler#28.

Known Broken Contexts

  • Windows 10 / Google Chrome
  • Windows 10 / Firefox (64-bit)
  • Ubuntu / Google Chrome

Your Goal

This issue is heavy on investigation and involves in first identifying the problem before solving it.

  • Create a reproducable situation that consistently results in a broken download on your local development instance of GT scheduler
  • Observe the state of the hidden "second shadow schedule" (likely by making it visible for debugging) when the download button is clicked
  • Fix the downloading mechanism so that it consistently produces expected images on all browser/operating system combinations.

Add finals schedule for courses

The feature
Give a clear 2-3 sentence description of your feature here.

Detailed explanation
Elaborate on your initial description of the feature, including its components.

Mockups
If available, include design mockups or examples of similar features in existing products that others can use as reference.

Additional context
Add any other context or screenshots about the feature request here.

Classes in the color black do not appear selected

Describe the bug
When a class is selected in the Scheduler tab, it is typically shaded a darker color than its unshaded counterparts. However, when a class is colored black, all sections of the class appear to be selected.

To Reproduce
Steps to reproduce the behavior. Example:

  1. Open GT Scheduler on any platform.
  2. Add a class with more than one section available.
  3. Select at least one (but not all) sections.
  4. Change the class color to black.
  5. Observe that all the sections appear black even though not all are selected.

Expected behavior
Unselected classes should be a lighter shade of black, like how other colored courses appear.

Screenshots
image
A regular class with no selected sections.

image
The same class with the A section selected.

image
A class in the color black with no selected sections.

image
The same class with the A section selected.

Additional context
Tested on Microsoft Edge on Windows 10 21H1 and Microsoft Edge on Android 11.

AM/PM suffix for end time inherited from start time for select classes on Map view sidebar

The AM/PM suffix of the end time for a class is inherited from the start time for select classes on the Map view sidebar.

For example, AE 3330 is listed as being from 11am-12:15am on the Map view. The bug is easily replicable if you just add AE 3330 to your classes, select the 11am-12:15pm time slot, and then go to the Monday section of the Map view. I personally replicated it across two computers.

bug

Happy bug fixing!

Empty Page and Lost Data after Course removed

I had signed up for a course VIP 4062 section VPV, and then it was subsequently removed by the registrar after the VIP was cancelled. I'm pretty sure this caused a bug in the gt-scheduler application. I see a bunch of type errors in the console:

instrument.ts:129 TypeError: Cannot read property 'meetings' of undefined at h (index.js:57) at index.js:61 at Array.sort (<anonymous>) at Y (index.js:61) at Yo (react-dom.production.min.js:153) at vs (react-dom.production.min.js:261) at ul (react-dom.production.min.js:246) at sl (react-dom.production.min.js:246) at $s (react-dom.production.min.js:239) at react-dom.production.min.js:123 at e.unstable_runWithPriority (scheduler.production.min.js:19) at Hi (react-dom.production.min.js:122) at Wi (react-dom.production.min.js:123) at Gi (react-dom.production.min.js:122) at Ys (react-dom.production.min.js:230) at ma (react-dom.production.min.js:163) at index.js:87

and

TypeError: Cannot read property 'credits' of undefined at index.tsx:56 at Array.reduce (<anonymous>) at index.tsx:55 at Object.useMemo (react-dom.production.min.js:165) at e.useMemo (react.production.min.js:25) at me (index.tsx:54) at Yo (react-dom.production.min.js:153) at vs (react-dom.production.min.js:261) at ul (react-dom.production.min.js:246) at sl (react-dom.production.min.js:246) at $s (react-dom.production.min.js:239) at react-dom.production.min.js:123 at e.unstable_runWithPriority (scheduler.production.min.js:19) at Hi (react-dom.production.min.js:122) at Wi (react-dom.production.min.js:123) at Gi (react-dom.production.min.js:122) at Ys (react-dom.production.min.js:230) at ma (react-dom.production.min.js:163) at index.js:87

and nothing renders on the page:

image

I'm guessing some kind of incorrect data is left in the browser's cache and this is causing objects to be undefined. Note that this problem doesn't occur if I open the page in a new browser or incognito mode. However, I do lose all my data in these cases.

There's also not a very intuitive way of restoring service in Chrome when this error happens short of deleting all browser cache.

Jazz classes appear smaller

Describe the bug
The courses MUSI 3321 and 3311 appear bunched to the right in the scheduler. No problem in the left sidebar, but in the schedule, the courses appear way too small and as a result some information about the course (time, location, teacher) cannot be read.

To Reproduce
Steps to reproduce the behavior. Example:

  1. Pick the course MUSI 3321 or 3311.
  2. Pick the available timeslots to put them in the scheduler.
  3. Observe.

Expected behavior
I expected the course to appear as normal in the schedule.

Screenshots
image

Additional context
I am not aware of this being a problem for any other courses including the rest of the MUSI courses, but there may be others with this same issue.

Separate Courses vs. Recurring Events tabs

Description

We will use the leftmost pane to take inputs for custom blocks. However, this pane is being used for searching and adding courses. So in this ticket, we need to divide this pane into 2 subsections: Courses and Recurring Events.

image image

Everything that currently lives in this pane will go under the Courses tab. New components for custom blocks will go under the Recurring Events tab. Refer to Figma for more design details.

Acceptance Criteria

UI Requirements

  • Two tabs exist for Courses and Recurring Events
  • Clicking on the tab should show the correct view.
  • Works for both light and dark modes.
  • Works with mobile view.

Other Notes

  • Feel free to use CourseContainer, Scheduler, Tab, and NavMenu to get a sense of how similar features were implemented, for better consistency.
  • All new components must be added to src/components/index.tsx.

TypeError while constructing courseDateMap in Map component

When building the courseDateMap data structure within the Map component, it's possible for the map to not contain the desired day, in which case the array will be undefined and invoking push on it will result in a TypeError. It's unclear what the underlying reason/steps to reproduce for this are.

A simple solution would be to ignore any days that don't exist in the courseDateMap. Additionally, further investigation may be warranted into the conditions that cause this error to happen.

Related Sentry issue (Private)

(Must be logged in to view; only maintainers have access.)

https://sentry.io/organizations/gt-scheduler/issues/2307136753/

Estimated user impact

Sentry errors have been logged for 4 users in the issue linked above.

Unhandled promise rejections during term list/data fetching

Upon fetching either the list of terms (https://api.github.com/repos/gt-scheduler/crawler/contents?ref=gh-pages) or the data for a single term (e.g. https://gt-scheduler.github.io/crawler/202108.json), it is possible (and many errors have been recorded in Sentry) for the promises to be rejected (due to a network error/timeout or similar). As expected, neither of the two (terms, term data) handle a rejection, so this should be added.

Because errors while fetching either data source cause the app functionality to not work, it's unclear what the best behavior is for when an error does occur. Possible handling strategies include:

  • Retry logic to attempt the fetches again
  • Some way to surface the fact that the server can't be reached to the user (this might be as simple as a call to window.alert)

Related Sentry issues (Private)

(Must be logged in to view; only maintainers have access.)

https://sentry.io/organizations/gt-scheduler/issues/2279317503/
https://sentry.io/organizations/gt-scheduler/issues/2325975065/
https://sentry.io/organizations/gt-scheduler/issues/2293382436/

Estimated user impact

Sentry errors have been logged for 119 users between the 3 issues above.

Add multiple schedule "versions" and functionality to create, delete, and select them

Problem Description

A commonly-requested feature of the GT Scheduler is to include the ability to have users to create and switch between different schedule versions in order to explore different schedules. This feature will involve adding a selection box to the top-left of the app toolbar:

Mockups

The latest mockups can be found on the Figma document under the "Schedule Switch Mini-Tab" section

Your Goal

  • Add the ability to switch between different schedule variants that are persisted to the user's cookies
    • This feature must be backwards-compatible with the current storage format; those old schedules should become a schedule on the user's "schedule list" called something like "Primary"
  • Add a dropdown component to the header to switch between different schedule versions. Each term should have a different set of schedule versions, so both dropdown components will be relevant to determining what the current 'active schedule' is.
    • The actively selected schedule should be used throughout the app
    • The last option in the dropdown should be to create a new schedule, and should open a dialog where the user can input the name of the schedule
  • Next to each item in the dropdown should be a small delete button where the user can delete a schedule version.
    • Upon clicking the button, the user should be presented with a confirmation modal. Only after confirming should the schedule version be deleted
    • If they delete the last schedule version, then the previous schedule version should be deleted and a new empty version should be created with a default name.
  • Next to each item in the dropdown should also be a small edit button where the user can edit the name of the schedule version in-line

Remove uses of SweetAlert in favor of a custom solution

While SweetAlert is nice in that it makes it easy to show a modal using the promise-based API, we don't really use any of its main features (like automatic animated icons, button types/using the resolved promise action, loading state). Also, it was a major pain-point when implementing #93 due to the React wrapper (seemingly) not rendering the JSX children in an actual React context (it doesn't run lifecycle hooks or schedule re-renders when hook state changes).

A custom solution can be simple, and only needs the following features:

  • Managed state via open: boolean and onClose: () => void
  • Mounted in a portal at the app root, with an overlay surrounding it
    • The overlay should close the modal
  • A modal content and button row, with a customizable set of buttons (buttons: { label: React.ReactNode; onClick: () => void; className?: string; style?: React.CSSProperties }[])

This should be straightforward to implement using react-overlays, which is a really useful library for implementing modals, dropdowns, and tooltips without bringing in its own styles (instead, it implements all of the complex positioning, portaling, accessibility, keyboard interaction, etc. for you).

ical export event UID conflict

Describe the bug
Export to ical uses event UIDs which conflict on the default UID domain. Current behavior is to assign UIDs 0, 1, 2, ... in the default domain. This causes any other events in the default domain with the same UIDs will be overwritten upon ical import, for example, courses imported last semester.

To Reproduce

  1. Create a schedule with classes from most recent semester
  2. Export calendar file
  3. Import calendar file in Google calendar
  4. Create a second schedule with classes from previous semester
  5. Export calendar file
  6. Import calendar file in Google calendar
  7. Classes from most recent semester will no longer all be present as there is an event UID conflict

Expected behavior
UIDs should not be conflicting, schedule from different terms should not replace each other in a calendar environment.

Additional context
Consider this generated event for example, in particular the UIDL6@default line.

BEGIN:VEVENT
UID:6@default
CLASS:PUBLIC
DESCRIPTION:VIP Proj Team: SR I
RRULE:FREQ=WEEKLY;UNTIL=20221216T000000Z;BYDAY=FR
DTSTAMP;VALUE=DATE-TIME:20230114T000546
DTSTART;VALUE=DATE-TIME:20220826T153000
DTEND;VALUE=DATE-TIME:20220826T162000
LOCATION:TBA
SUMMARY;LANGUAGE=en-us:VIP 4601
TRANSP:TRANSPARENT
END:VEVENT

Make GT Scheduler more friendly for open source contribution!

This repo is already quite friendly to open source contribution, but I think we can do even better! Suggested additions include:

  • Issue & PR templates (see example)
  • CONTRIBUTING.md (see example)
  • CODE_OF_CONDUCT.md (custom, not pure template!)

Many of the suggested changes above can also be applied to the other two repos:

If you can think of others, please comment them, and I can add them to the Issue! I'll open a PR to get things started.

Share a Schedule with a Unique URL

I'm an academic advisor. I'd like students to be able to share a link with me to their schedule, whether it be a fixed set of sections or a link that updates as the student makes adjustments (I'd be happy with either).

I understand this might take a lot of database storage to implement, but I figured I'd ask!

Saturday/Sunday courses present an edge case for various parts of the scheduler

Describe the bug
Saturday/Sunday classes are still an edge case with various parts of the scheduler, such as the schedule view (where they wrap around in a buggy way). Additionally, they aren't displayed on the map view at all.

To Reproduce
Steps to reproduce the behavior. Example:

  1. Go to the app and select the Fall 2021 catalog
  2. Add LMC 2661 A and LMC 2662 (crns: 85479 and 85480)

Expected behavior
Classes on Saturday/Sunday should be better handled. In the schedule view, they shouldn't wrap around in a buggy way, and it would be nice if they were displayed in some way. For both the schedule view and map view, having some not-displayed-by-default category for classes on Saturday/Sunday seems like a satisfactory solution that is displayed as-needed only when such classes are pinned.

Screenshots
Screenshot_20210905_014748

Add frontend for feedback form

Problem Description

We would like a way for users to submit feedback while inside the application. To do this, we will have a small button in the bottom-right corner of the app that can be expanded to show an interactive feedback form:

Mockups (link to Figma)

Update 3-7-2021: added 'thanks' screen mockups

Dark Theme:
dark-theme-new

Light Theme:
light-theme-new

Your Goal

  • Create a new component that is always visible in the bottom-right corner of the screen ("floating" above the rest of the UI) and is the collapsed button form.
  • Upon clicking the button, the expanded form should become visible in the bottom-right corner, and the button should be hidden.
  • The expanded form should have:
    • An option for users to provide a numeric (1-5) score
    • An optional textbox for users to provide more details
    • A submit button
    • A close button that can be clicked to return the form to the collapsed button state
  • Upon submitting:
    • An empty callback function should be invoked (that we will eventually wire up to the backend)
    • The feedback form should say something like "Thanks for the feedback"

Implement an Input Form for Custom Block

Description

We need a form for users to create and edit custom blocks. In this ticket, you will implement that form, named EventAdd.

image

Refer to Figma for more design details.

Acceptance Criteria

UI Requirements

  • Name field can handle text overflow.
  • Users can pick multiple days.
  • Works for both light and dark modes.
  • Works with mobile view.

Functional Requirements

  • Submitting the form updates the list of events in ScheduleContext, the context that stores all info about courses and custom blocks.
  • When submitted, start and end time should be converted to a numeric format of hh * 60 + mm (e.g., 11:15am -> 11 * 60 + 15 = 675, 3:30pm or 15:30 -> 15 * 60 + 30 = 930).
  • New events should be assigned a unique id.
  • New events should be assigned a random color.

Other Notes

  • EventAdd should be quite similar similar to an existing component called CourseAdd, which is the form used to search for and add courses. Refer to CourseAdd to make your life easier :).
  • All new components must be added to src/components/index.tsx.

Show class location and professor in mobile site

The feature
Show the class location and professor on the "Courses" and/or "Calendar" section on the mobile site (specifically any device with a horizontal resolution <1024px). If the text is too long to display fully and exceeds the height of the box, then there should be an option to click on the box to open up some sort of dialog box where we can then see the class location and professor.

Detailed explanation
I'm not able to see the class location and professor in the mobile site. It seems like this information is hidden with display: none since having this information displayed can sometimes exceed the height of the box (in which the height is based on the duration of the class).

Although there is already a map view where we can see the general building of where the class takes place, having this location information displayed would be useful since students often need to know the exact room number and location of the class from their phone while commuting.

Additional context
Here's how it looks on desktop:
Screen Shot 2022-08-23 at 8 50 36 PM

Here's how it looks on mobile:
Screen Shot 2022-08-23 at 8 50 25 PM

Switch to using "main" as the main branch

Of the three repositories in the gt-scheduler organization, this is the only one that does not use main as the main branch (instead, it uses development). There is no good reason for this, making it consistent would be nice and would let us simplify the contributing guide.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.