Course Planner

Course Planner

Overview

For this assignment, you will build a web application using HTML, CSS and Javascript for planning a semester schedule. Courses are grouped by academic department, and you will build up a schedule by picking courses from one or more departments. Your app will keep track of the total credit hours in the schedule, and warn the student when they are under a full-time load or overloaded.

Client-0 Startup: Your first web page

Overview and Setup

See the client project introduction page for the Client-0 overview and setup instructions.

Requirements

You will implement the following controls and behaviour for your webpage (index.html)

  • Set the default font to ‘Segoe UI’
  • Add a title using the <h1> tag to the top of the page with the following text ‘swen-610 Web Assignment 0’
    • Set the font to Bold, Verdana, with a size of 36px (Use the style property) and centre the title.
  • Add a sub-heading with the <h2> tag.
    • The text content should be ‘Section xx’, where ‘xx’ is your section number. Set the font to “Impact”
    • Center the text.
  • Add a dropdown list control with the following values (names of the departments)
    • Software Engineering
    • Computer Science
    • Mathematics
    • Physics
    • Humanities
    • Use the <select> tag with those options. There should also be a default selection with an empty value (blank). Make sure it is a dropdown list as shown in the sample below.
  • Add a set of radio buttons with the following values (the term)
    • Fall
    • Spring
    • Summer
    • Use the <input type="radio"> tag. Make sure the radio buttons operate as a group. i.e. only one item can be selected at a time!
  • Add a box that displays the details of each department. Each time the dropdown selection changes, the details of the department will change in this box. The details will include:
    • Department Name (This will be the same name selected in the dropdown)
    • Department Code (e.g. SWEN, CSCI, MATH …)
    • Building (pick a building name or number … your choice)
    • The selected term from the radio buttons (e.g. “Courses offered for: Fall”)
  • Also, provide a different background colour for each department, and make sure the font color is also adjusted to make the text readable with the background - perhaps Software Engineering is orange background with black text; Physics is navy background with white text.
  • Add a small javascript function (place in <HEAD> ) that will control changing the information in the box based on the value of the selection of the SELECT tag, and the currently selected term. The box should update when either control changes.
    • HINT: Use the onchange event, document.getElementById and document.getElementsByName
  • Use style attributes to adjust the position of controls (so everything is not at the edges or clustered together). Look at the sample page and try to get as close as possible to the centering and left/ right/ top/ bottom positioning shown in the screen-shot. NOTE: In part-0, we want you to put the styles in-line, and not use CSS. That will come later.

Grading

Grading: 10 points total

Web Page and Actions:

  • Title & Headings: 1 point
  • Dropdown list: 1 points
  • Radio buttons: 1 points
  • Display box: 1 points
  • Layout & Alignment: 2
  • Javascript dynamic updates: 4

Sample Output

None! This is a new project. Do your best to come up with a reasonable UI– maybe yours will be featured here in the future (with your permission, of course).

Client 1

Setup

You will create a new branch (dev-client-1) in your gitlab group repo (client-abc123) which you created for Client-0. When you finish this project merge to master and apply a tag client-1. You will continue to use the gitlab pages as before. You will place your HTML code in public/index-1.html and add a .css file for styles (e.g. clubs.css or nutrikit.css) and a .js file for your javascript code.

NOTE: To avoid conflict with client-0 files, we are having you implement your HTML page for client-1 in a different file i.e. public/index-1.html.

Use the same support file (.gitlab-ci.yml) from the prior project.

This CI file will publish your webpage (index.html) to the gitlab web server. You can find the URL (to check your webpage) on the settings/pages link in gitlab

Client-1 Initial UI

Your app maintains a list of courses for 5 departments. For each department, there is a list of 5 courses in that department. A user can select a course and add it to their schedule. As each course is added (or removed), the total credit hours for the schedule are summarized, and colour coded according to the student’s load.

The following are the behaviour expectations

  • Set the default font to ‘Segoe UI’ Add a title using the <h1> tag, centred, to the top of the page with the following text ‘Course Planner’
  • Add a sub-heading, <h3>, centred, with the following text Pick courses from each department to build your semester schedule
  • Use a pull-down menu with a <select> with options for the following departments - “Software Engineering”, “Computer Science”, “Mathematics”, “Physics”, “Humanities”
  • Provide a listbox that can hold 5 items, and as a department is selected, populate the listbox with the matching courses.
    • Each course also has a number of credit hours associated with it. The data is shown below. You will need to decide how to represent that data in your code. Remember, there is no database (yet), so you need to keep this all client side!
Software Engineering Credits
SWEN-601 Software Construction 3
SWEN-610 Foundations of Software Engineering 3
SWEN-640 Research Methods 3
SWEN-732 Collaborative Software Development 3
SWEN-790 Capstone 6
Computer Science Credits
CSCI-605 Advanced OO Programming 3
CSCI-620 Data Management 3
CSCI-630 Artificial Intelligence 3
CSCI-661 Data Structures 3
CSCI-698 Seminar 1
Mathematics Credits
MATH-181 Calculus I 4
MATH-182 Calculus II 4
MATH-190 Discrete Mathematics 3
MATH-241 Linear Algebra 3
MATH-251 Probability and Statistics 3
Physics Credits
PHYS-211 University Physics I 4
PHYS-212 University Physics II 4
PHYS-206 Physics Lab 1
PHYS-220 Astronomy 3
PHYS-225 Modern Physics 3
Humanities Credits
ENGL-150 Writing Seminar 3
PHIL-102 Ethics 3
HIST-160 World History 3
ARTH-135 Art History 3
MUSC-110 Music Appreciation 2

There will be a second list box, for the student’s schedule. Between the two list boxes, there will be a button to add/ remove courses from the schedule. Once the courses for the department are populated, the user can click the button to add a course to the schedule.

  • When you click a course in the first listbox (with the courses you can add), the button will be configured to add the selected course to your schedule.
  • When you click a course in your schedule, the button will be configured to remove the course from the schedule.
  • The course that is added will appear in the schedule. As the course is added, the total credit hours (total of all courses in the schedule) will be shown below the schedule.
  • A course can be removed from the schedule, and the credit total will also update when a course is removed.
  • The schedule can hold any number of courses, and can be a mix of courses from all departments. However, a course can only appear in the schedule once. If the user tries to add a course that is already scheduled, do not add it again (you may disable the button, or show a message - your choice).

Credit load display behaviour: (Show the total with the indicated colour, and the corresponding message)

  • If the total credit hours are < 12, the total will be yellow: Part-time
  • If the total credit hours are >= 12 and <= 18, the total will be green: Full-time
  • If the total credit hours are > 18, the total will be red: Overload - advisor approval required!

Place all the styles for the different display elements in your .css file. Place all your javascript code in your .js file.

Use the screenshots below as an additional reference for your web page design requirements.

Grading

Points: 40 points total

Web Page and Actions:

  • Pulldown menu selection: 5 points
  • Populating listboxes: 5
  • Headings, Layout & Alignment: 5
  • Good coding style of css: 5
  • Good coding style of javascript: 5
  • Following all requirements: 15

Sample Output

UI Specifications are often page mockups. Your page should be similar to this…

Client-2: Port to React

Your branch name should be client2-dev. When you have merged, the tag should be client2.

Now you have seen what it looks like to have a tiny bit of dynamic functionality on a webpage, let’s start thinking bigger. Modern websites that have a lot of client-side functionality use component-based frameworks. We’ll be using React.js, which is one of the most popular ones out there today.

Our goal with this iteration is to achieve feature parity, perhaps with some improvements along the way. Your app will hopefully look and act nearly exactly as before, but will be easier to build upon for future features.

Getting Started with React

Everyone must do this part, even if you think you are familiar with React.js.

  1. Do our React Setup instructions. Be sure to review the walkthrough explanation of all the files.
  2. Review the resources available to you at Getting Started with React. We have found these resources to be very well-written and helpful.
  3. They have a Tic Tac Toe tutorial that shows everything together. Please do this tutorial, as it will prepare you for your assignment.

Commit your tutorial code to your repository, to the branch client2-dev into a separate folder.

  • i.e. create a sub-folder in your repo called ‘react-guide’, and place your files for the tutorial you used in there.

Porting to React

Once you’ve gotten set up and done the tutorials, let’s do the following, in this order:

  1. Decide what your app’s state will look like. This is the minimum amount of data that needs to be maintained to represent what the app tracks at any given time. Define your initial state in your top-level component (e.g. App, or whatever you want to rename yours to), typically with hooks like useState. Consider which other components need their own local state. Minimize the complexity of state management, but make sure you make components as independent as possible so you don’t always rely on a single ‘master’ object. This is the basics of good O-O design.

  2. Create function components to represent elements of your UI. Put each component in a separate file.

  3. Next, make each component return JSX. Hard-code all your numbers first. Just get the JSX working so the site looks the same.

  4. Next, pass the state from your top-level component to the properties of the child components. Make the hard-coded aspects of your UI dynamic based on the state/properties of the component. Again, aim for the UI to look the same way as you do this.

  5. Finally, figure out your event listeners. The tic-tac-toe tutorial mentioned earlier is a useful reference on the proper way to pass around event listeners.

Course Planner Specifics

  • Your state will likely be a collection of the courses and which ones are in the schedule.
  • Your state would also likely need to store which department is currently selected. Perhaps that needs to be in the top-level state, or perhaps that’s a state variable for the component representing the course list.
  • You DON’T need to store the total credits or the load colour - those react to the state and are computed when rendering.

Grading Client-2

Points: 50 points

  • (10 points) Completed the setup instructions and the React tutorials.
  • (10 points) Works on the CI and deployed to GitLab Pages
  • (20 points) Refactored to React components
  • (5 points) Proper use of props for passing data to components
  • (5 points) Proper use of state for updating dynamic elements

Client-3: Responsive Design, New Features

Your branch name should be client3-dev. When you have merged, the tag should be client3.

Be sure to update your .gitlab-ci.yml to update the PROJECT_NAME3 variable

In this iteration, you will be focusing on both expanding the functionality and incorporating responsive design into your project.

Client 3 setup

Create a NEW React app.

  • In your root directory, create a new app npx create-react-app abc123-react-client3 (again, abc123 is YOUR id)
  • You will now have a directory structure similar to this:
.  
├── .git/  
├── .gitlab-ci.yml  
├── README.md  
├── abc123-react-client2/  
│   ├── .gitignore  
│   ├── README.md  
│   ├── node_modules/  
│   ├── package-lock.json  
│   ├── package.json  
│   ├── public/  
│   └── src/  
├── abc123-react-client3/  
│   ├── .gitignore  
│   ├── README.md  
│   ├── node_modules/  
│   ├── package-lock.json  
│   ├── package.json  
│   ├── public/  
│   └── src/  
├── public/    
│   ├── index.html  
│   └── index_1.html

Note: This is a new project, so you should copy over any files you need from client2 into client3

Responsive Design

We would like you to research and incorporate Reactstrap into your project. Reactstrap is a library that creates React components for incorporating Bootstrap features easily. Install using the npm install command they show (not the CDN install). Be sure to review About the Project for an explanation of how it integrates the two.

We would like you to:

  • Use the Reactstrap components (also see Bootstrap). We will give an overview of this in class, so be sure to review the lecture. If a Reactstrap equivalent component doesn’t exist, you can use basic Bootstrap or HTML, but try use use Reactstrap for the majority of the work.
  • Your application must be usable on a desktop, and usable on an iPhone X, i.e. 375 x 812 px. We want the following:
    • Use the Grid System to lay out your UI and place the Reactstrap components. I like to use Container, Row, Col for layout and Card, Dropdown, FormGroup for data etc. … but feel free to expand your horizons.
    • The UI must adjust on the desktop vs. on mobile, i.e. take advantage of the Bootstrap breakpoints, enable the layout to ‘flow’
    • When on a mobile device, the components need to be arranged to maximize the screen real estate
    • No horizontal scrolling on either desktop or mobile
    • All UI components should be big enough to be usable by touchscreen, i.e. “fat finger compatible”
    • Minimize the number of “clicks” or “taps” needed to use your UI
    • This is still a simple application, but keep basic usability in your implementation.
    • Ensure error cases are cleanly handled. Now that you have a ‘real’ UI, this is an important task for development. Make sure you test for error cases, not just ‘happy path’

Test out your application in the browser’s Development Tools used to simulate devices. In Chrome it’s called Device Mode and Firefox it’s Responsive Design Mode. Note that just resizing the window is not a perfect simulation of what it would look like on a device.

Course Planner Specifics

  • Make the add and remove two separate buttons for the schedule.
  • Add additional course information, including the instructor, meeting days (e.g. Mon/ Wed), start time, end time, and seats available. Assume this data is pre-loaded, as before. Make up reasonable values for your built-in data. Adapt for your code as needed.
  • Add a simple weekly calendar view of the schedule (days across the top, times down the side), showing each scheduled course in its time slot(s).
  • Detect time conflicts. If two scheduled courses meet on the same day at overlapping times, show a visual indicator (e.g. colors, icons, visual cues) on both courses, in both the schedule list and the calendar view.
  • Provide a way to edit a course’s information. Populate the existing values in the edit dialog so it is easy to modify.
  • Use pop-up Reactstrap Modal dialogs to make data-entry easy
  • Add a degree credit goal and show the progress toward that, counting the scheduled credits plus credits already completed. We recommend the Progress Bar as a simple way to represent this. Default to 30 credits required and 0 completed, but allow people to change both numbers.
  • Improve the UI according keeping in mind UI design guidlines, simplifying as best you can.

Grading Client-3

Points: 60 points total

  • (5 points) Builds on the CI by Lab Day
  • (5 points) Quality feedback given
  • (5 points) 2 buttons for add/ remove
  • (5 points) Additional course information loaded, with edit capability
  • (15 points) Responsive features and guidelines
  • (15 points) Weekly calendar view with time conflict indicators
  • (10 points) Degree credit goal progress bar, with edit capability for goal

Client-4: Full Stack

In this assignment, you will retain functional parity with client-3, but move all your persitent data from the client side to the DB server. You will again be using PostgreSQL and FastAPI based RESTful APIs as your mechanism for accessing the DB. Your branch name should be client4-dev. When you have merged, the tag should be client4.

Be sure to update your .gitlab-ci.yml to update the PROJECT_NAME4 variable

Setup

Once again, create a new React app (from the root of your directory). e.g. npx create-react-app abc123-react-client4 (abc123 is YOUR id). You should copy over any files you need from client3 into client4

You will need to add a FastAPI server to your project to host the RESTful API and the DB. There is no skeleton code for this - you’ve already built one in REST, so set it up the same way. Create a folder named server in your project, at the same level as your abc123-react-client4 folder, and give it the same structure you used in REST: a src folder with api and db packages (along with any __init__.py files), a config folder for your db.yml, and a requirements.txt with the same packages you used in REST (fastapi, uvicorn, psycopg2, PyYAML). Bring over the pieces you can reuse, like your DB utilities and management endpoints, and write your own schema and test data for this assignment.

Remember to keep db.yml out of version control. For your .gitlab-ci.yml, use the version from client-3 and update as needed.

Your directory structure should look similar to this:

├── abc123-react-client4
│   ├── public
│   └── src
├── server
│   ├── config
│   │   └── db.yml
│   ├── requirements.txt
│   └── src
│       ├── __init__.py
│       ├── server.py
│       ├── api
│       │   ├── __init__.py
│       │   └── ...            // your routers
│       └── db
│           ├── __init__.py
│           ├── schema.sql
│           ├── test_data.sql
│           └── swen610_db_utils.py

Items to Note

  • Since the DB is on the server, it must be initialized when the FastAPI server starts. Use a lifespan function in server.py to load your schema and data (exec_sql_file(...)) before the server starts accepting requests, just like you did in REST.
  • Use the Javascript fetch method to call your RESTful APIs from React.
    • To get the initial DB data when your page loads, kick off the fetch from a useEffect hook (or componentDidMount, if you are using class components).
  • You can still write python tests with the requests library to confirm your API functionality, as you did in REST. You are not required to create any client-side python code for this project.

Running the FastAPI server

To make sure your Client can talk to your Server, we need to make some changes to avoid CORS errors.

Your React pages are served from one origin (http://localhost:3000) and your API from another (http://localhost:8000), so the browser will block the API calls unless the server says they’re allowed. FastAPI has CORS support built in, so there’s no extra package to install - you just add the CORSMiddleware to your app.

Add something like this to your server.py:

from fastapi.middleware.cors import CORSMiddleware

app = FastAPI(lifespan=lifespan)  # create FastAPI instance

app.add_middleware(  # Enable CORS so the React dev server can call the API
    CORSMiddleware,
    allow_origins=['http://localhost:3000', 'http://127.0.0.1:3000'],
    allow_methods=['*'],
    allow_headers=['*'],
)

app.include_router(example_router)  # api router(s)

As before, run your API (FastAPI) server by typing python server/src/server.py. You need to start up the FastAPI server before running your React client. Remember that you can check your endpoints at http://localhost:8000/docs before wiring them into React.

Running your React Client code

  • Calling the endpoints
    • Make sure you call the endpoints in your javascript code with the full URL http://localhost:8000 (do not use a relative path to the endpoint)
  • Mac Users
    • If you needed to change your server previously (in REST) to run on a different port (e.g. 8001), then you will need to do that again when making the API calls.
    • Similarly, if you needed to use 127.0.0.1 instead of localhost, do that.
  • Running the web page server
    • We have a backend server with FastAPI, but now we will also be running the front end web server for the React pages. Use a separate console window and type npm start to run the Nodejs server and bring up your web pages.
      • This will run your web pages on port 3000.

CI/ gitlab pages

Since the data is now loaded from a backend database (which will not exist in the gitlab deployment), the gitlab webpages will no longer be provide full functionality. Just make sure your webpage display handles that situation (i.e. handles the fact that the API call will fail), and provides a reasonable default behaviour.

Course Planner Specifics

  • Keep the initial department and course data in a DB on the ‘server side’. Include all information in a table/ tables of your own design. When your page loads, it should get the data from the server. Provide a GET API to retrieve that data. Provide any filters necessary for your design for retrieving data (e.g. courses by department).
  • Allow the ability to modify information for existing courses, update the DB accordingly (PUT API)
  • Add the ability to create new courses in an existing department (POST API)
  • Add the ability to delete a particular course (DELETE API). If the course is in the current schedule, remove it from the schedule as well.
  • Keep the degree credit goal and completed credits in the DB, so they persist between visits. Update them with a PUT API.
  • Keep the functionality for moving courses between the department list and the schedule, but you do not need to update the DB with that information, since it is transitory information.
  • In all cases, the web page should be displaying the data it retrieves from the DB using the REST API
    • Don’t leave modified data that should be committed to the DB cached in browser/ client data
    • When the user is filling in a form for new or modified data, don’t commit the data to the DB until the user confirms the changes. Make sure the user can cancel the action if they choose to do so.

Grading Client-4

Points: 60 points total

  • (5 points) Builds on the CI by Lab Day
  • (5 points) Quality feedback given
  • (10 points) FastAPI server and DB properly setup and initialized
  • (10 points) API to load initial data on client (GET)
  • (20 points) API to add/ modify data (POST/ PUT)
  • (10 points) API to delete data (DELETE)

Published: Oct 6, 2026