Nightclub Capacity


Nightclub Capacity App

Overview

For this assignment, you will build a web applications using HTML, CSS and Javascript for monitoring people entering and leaving your chain of nightclubs. You’ve been very successful in attracting crowds, but the fire-marshal has warned you about overcrowding. You are strictly monitoring people entering/ leaving, and bouncers at the door will track and control entry using the capacity app.

Client-0 Startup: Your first web page

Overview

This initial assignment will introduce you to the basics of HTML. In this initial assignment, we will not use CSS. Use style attributes on the appropriate HTML tags to adjust the appearance. When finished, tag the commit as client-0

Setup

Locate your project in your group (Named client-group-x) in gitlab, and clone the project
Once you clone this project, create a folder named public.
All your code for this assignment will go in this folder.
Inside public/, do the following:
Create a file, and name it index.html
- Your web markup (html) will go in this file (You can use the template below to get started)

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>Web Assignment 0</title>
  <meta name="description" content="First web assignment">
  <meta name="author" content="student name">
</head>
<body>
</body>
</html>

In the root directory, create a .gitlab-ci.yml file with this content:

image:
  name: node:18 #No special docker image.  Standard nodejs image from dockerhub
cache:
  paths:
  - node_modules/
before_script:
  - yarn install
  - node --version
pages:
  stage: deploy
  script:
    - ls -lFa public
  artifacts:
    paths:
    - public

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

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-344 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 nightclubs)
Club Arcane
Club Underground
Club Soda
Studio 52
Ciro’s
Paradisio Garage
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 box that displays the details of each club. Each time the listbox selection changes, the details of the club will change in this box. The details will include:
Club Name (This will be the same name selected in the listbox)
Club Location (Which city) Capacity (pick a variety of capacities … your choice)
Musical Theme (Rock, Pop, Metal, Grunge …)

Also, provide a different background colour for each Club, and make sure the font color is also adjusted to make the text readable with the background - perhaps Club Arcane is black background with white font; Club Soda is white background with black 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 (e.g. Club Arcane, Club Underground, …).

  • HINT: Use the onchange event and document.getElementById

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
Correct implemention for each of the controls and styles
Web Page and Actions:

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

Sample Output

../club-0.0.JPG

Sample Page-0


../club-0.1.JPG

Sample Page-1


../club-0.2.JPG

Sample Page-2

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) 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 iteration.

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 tracks 4 clubs. Each club starts at occupancy of zero, and each time someone enters or leaves a club, the occupancy is updated. There are 3 levels of occupancy, and a colour coding (shown below) that corresponds to each level.

  • Normal
  • Yellow Threshold/ Caution
  • Max Club Capacity

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 ‘Nightclub Capacity’ Add a sub-heading, <h3>, centred, with the following text Each time someone enters/ leaves the club, select the correct club and click the appropriate button

Use an appropriate HTML element to display each of the 4 clubs Each “club” will have rounded corners (HINT: use border-radius) Below each club will be the count for the respective club

Below the element displaying the club(s) and occupancy count there will be a set of radio buttons for each of the clubs, labelled with the club name/ location. Because of club layout, the capacities for each club vary. See below for the data-set describing that relationship. Remember, there is no database (yet), so you need to decide how to represent this data in your web code.

Club number Club name Max Capacity Yellow Threshold
1 Club Arcane 100 70
2 Club Underground 50 30
3 Club Soda 20 12
4 Studio 52 52 32

Below the radio buttons, there will be two buttons, labelled + and -.
- When + is clicked, the count for the selected club will increment.
- When - is clicked, the count for the selected club will decrement.
- For each change in count, the colour of the club will change as described below.
- For each change in count/ color, there will be a message in the club display element as stated below

Club occupancy display behaviour:

  • If the club occupancy count is < Yellow threshold, the club display will be green
  • If the club occupancy count is >= Yellow Threshold and < Max capacity, the club display will be yellow
  • If the club occupancy count is >= Max Capacity, the club display will be red.

Messaging behaviour: (Show the corresponding message with the indicated colour)

  • Green: Welcome!
  • Yellow: Warn the bouncers…
  • Red: No one allowed in!

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 Client-1

Points: 40 points total

Web Page and Actions:

  • Radio buttons: 5 points
  • Clubs: 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…

../nc-1.0.JPG

Sample Page-0

../nc-1.1.JPG

Sample Page-1

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 on the Getting Started with React. We have found these resources to be very well-written and helpful.
  3. Do one of these:
  • Either the Step-by-Step Guide, all the way through Thinking in React.
    OR
  • They have tutorials that build a Tic-Tac-Toe example.
    • The example that uses Classes/ Components (same as we will mainly use in this course) is at Tic Tac Toe Tutorial
    • There is also the new version that uses function/ hooks. You may also follow this one. Tic Tac Toe tutorial that shows everything together. Feel free to do this tutorial instead.
    • In either case, commit your code (again, into a separate folder)

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 intitial state in your top-level component (e.g. App, or whatever you want to rename yours to). Consider which other components need their own 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 component classes to represent elements of your UI. Put each component in a separate file.
  3. Next, make the render method for each component. 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.
  6. And remember … no more getElementById (or similar things)! And no widespread usage of refs or useEffect or other escape hatches .

Grading Client2

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

Nightclub Specifics

  • Your state will likely be a mapping of clubs and counts.
  • You DON’T need to store the color information - it reacts to the state and renders a color based on the counts.

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_NAME3variable

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 the About the Project for an explanation of how it 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.

Nightclub Specifics

  • Let’s change the UI to not have radio buttons anymore. Instead, each club will have it’s own increment/ decrement buttons.
  • Make the button to decrement and button to increment, are well separated (increment in the left corner, decrement in the right corner). Also, make the colours for each distinct, for easy user recognition (you can pick the colours)
    • Once the max capacity has been reached, disable the increment button. When the count goes below max capacity, re-enable the increment button.
    • Disable the decrement button if the count is zero; enable it when it is higher.
  • Add information for the club. Name, Location (city), music genre (rock, pop, synth, metal, …). Show this in the display for each club.
  • Add the ability to change the information of a given club. This includes the name, location, etc. and thresholds (all valid fields, basically). Populate the existing values in the edit dialog so it is easy to modify.
  • Add the ability to add new clubs and remove any clubs, including all of the information above.
    • Start off with a few initial clubs, and then allow add/ remove operations.
    • Provide defaults for the threshholds when adding a new club. Make the values realistic e.g. - If Max Capacity is 100, Yellow threshold is 80% of the capacity. Allow the user to override the defaults when they add a club. Obviously, the user will need to enter all other values.
    • Provide a simple way to delete a given club i.e. don’t force the user to type!
  • Use pop-up Reactstrap Modal dialogs to make data-entry easy
  • Filter which clubs are shown by their location city, e.g. “NYC or London …".

Grading Client-3

Points: 60 points total

  • (5 points) Builds on the CI by Lab Day
  • (5 points) Quality feedback given
  • (10 points) Decrement and increment buttons
  • (15 points) Responsive features and guidelines
  • (15 points) Club information and CRUD operations
  • (10 points) Filter clubs

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 Flask 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_NAME4variable

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 Flask server to your project to host the RESTful API and the DB. This will be similar to your prior REST work. Create a folder named server in your project. This should be at the same level as your abc123-react-client4 folder. Inside the server folder, create an api folder along with any __init__.py files. Add a db.yml file for your setup (in the api directory).
You can download example files for setting up full-stack server code here. Adapt for your code as necessary. There are no files in src in the example, but you can add any helper items there. There is a .gitlab-ci.yml file provided (to allow running this standalone), but for your project, you should use the version from client-3 and update as needed.

You can copy the files in the server folder into your project, and modify to fit your assignment. A starter .sql file is provided for testing purposes. You can delete this file and use your own schema for the project. You will need to add your own db.yml to the server/api folder.
Your directory stucture should look similar to this:

├── abc123-react-client4   
│   ├── public  
│   └── src  
├── public  
├── server  
│   ├── api  
│   ├──── __init__.py  
│   ├──── db.yml  
│   ├──── example_api.py  
│   ├──── people.sql  
│   ├──── swen_344_db_utils.py  
|   |── server.py  
│── __init__.py  

Items to Note:

  • Since the DB is on the server, it must be initialized when the Flask server starts. Notice that the server.py file loads the DB directly (exec_sql_file(...)).
  • There is a sample React file (mycomponent.js) provided that shows how to use the Javascript fetch method. Review this and adapt for your code.
    • The sample file also shows how you can use the React built-in event componentDidMount to trigger your code to kick off the fetch and get the initial DB data using a RESTful API.
  • There is a test folder in the sample code. This is just to show you that you can still run python client side code to confirm your API functionality. You are not required to create any client-side python code for this project.

Running the Flask server

To make sure your Client can talk to your Server, we need to make some changes to avoid CORS errors.
You will need to add a new module for the Flask server.

  • Type pip install flask_cors on the command line (pip3 for Mac).
    This will enable the Nodejs server to make API calls to another server (the Flask server) without CORS errors.
    You will see some additional code in server.py in the provided skeleton code. (Review this for your understanding)
app = Flask(__name__) #create Flask instance  

CORS(app) #Enable CORS for Flask  

api = Api(app) #api router  

As before, run your API (Flask) server by typing py server/server.py. You need to start up the Flask server before running your React client.

Running your React Client code

  • Calling the endpoints
    • Make sure you call the endpoints in your javascript code with the full URL http://localhost:5000 (do not use a relative path to the endpoint)
  • Mac Users
    • If you needed to change Flask previously (in REST) to run on a different port (e.g. 4999), 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 Flask, 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.

Nightclub Specifics

  • All prior features must work, but now with REST/ DB as listed below
  • Keep the initial 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.
  • When the button changes the current count, the code will update the data on the server (PUT), and the client code will retrieve the updated data from the server to refresh the display. Provide an appropriate API(s).
  • When you change the club information (name, location … ), use PUT to update the data on the server.
  • Provide a POST method to create a new club, and a DELETE method to remove a club. Update the DB accordingly.
  • 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) Flask 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)
    Full points awarded only if all prior functionality works AND is propertly implemented using RESTful specs and requirements