Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
*.DS_Store
node_modules/
package-lock.json
113 changes: 41 additions & 72 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,74 +1,43 @@
Assignment 3 - Persistence: Two-tier Web Application with Flat File Database, Express server, and CSS template
===

Due: September 16th, by 11:59 AM.

This assignnment continues where we left off, extending it to use the most popular Node.js server framework (express), a flat file database suitable for small applications (lowdb), and a CSS application framework / template of your choice (Boostrap, Material Design, Semantic UI, Pure etc.)


Baseline Requirements
---

Your application is required to implement the following functionalities:

- a `Server`, created using Express (no alternatives will be accepted for this assignment)
- a `Results` functionality which shows the entire dataset residing in the server's memory
- a `Form/Entry` functionality which allows users to add, modify, and delete data items (must be all three!) associated with their user name / account.
- Use of at least five [Express middleware packages](https://expressjs.com/en/resources/middleware.html). Explore!
- Basic authentication using the [Passport middleware](http://www.passportjs.org) for Express (this counts as one of your five middleware packages). We encourage using the Local strategy, but OAuth (Open Authentication) can also be used for additional technical achievement. The course staff cannot help you with the various flavors of OAuth strategies. YOU MUST PROVIDE US WITH ACCOUNT CREDENTIALS TO LOGIN TO YOUR APPLICATION IF YOU USE OAUTH. The course staff cannot be expected to have credentials for any particular OAuth service.
- Persistent data storage in between server sessions. [lowdb](https://github.com/typicode/lowdb) is a suitable database package for this assignment and will be discussed in class.
- Use of a [CSS framework or template](https://github.com/troxler/awesome-css-frameworks). This should do the bulk of your styling/CSS for you and be appropriate to your application. For example, don't use [NES.css](https://nostalgic-css.github.io/NES.css/) (which is awesome!) unless you're creating a game or some type of retro 80s site.

Your application is required to demonstrate the use of the following concepts:

HTML:
- HTML input tags and form fields of various flavors (`<textarea>`, `<input>`, checkboxes, radio buttons etc.)
- HTML that can display all data *for a particular authenticated user*. Note that this is different from the last assignnment, which required the display of all data in memory on the server.

Note that it might make sense to have two simple pages for this assignment, one that handles login / authentication, and one that contains the rest of your application. For this assignment, it is acceptable to simply create new user accounts upon login if none exist, however, you must alert your users to this fact. If you're not using OAuth

CSS:
- CSS styling should primarily be provided by your chosen template/framework. Oftentimes a great deal of care has been put into designing CSS templates; don't override their stylesheets unless you are extremely confident in your graphic design capabilities. The idea is to use CSS templates that give you a professional looking design aesthetic without requiring you to be a graphic designer yourself.

JavaScript:
- At minimum, a small amount of front-end JavaScript to get / fetch data from the server. See the [previous assignment](https://github.com/cs4241-19a/a2-shortstack) for reference.

Node.js:
- A server using Express, at least five pieces of Express middleware, and a persistent database (a flat file using lowdb is great).

Deliverables
---

Do the following to complete this assignment:

1. Implement your project with the above requirements. A good potential starting point is to use the "hello-express" project template inside of Glitch; this appears as an option when you hit the "New Project" button. Use the work you did in the last assignment as a reference to implement functionality, as well as the notes from class on 9/9 and 9/12.
2. If you developed your project locally, deploy your project to Glitch, and fill in the appropriate fields in your package.json file.
3. Test your project to make sure that when someone goes to your main page on Glitch, it displays correctly.
4. Ensure that your project has the proper naming scheme `a3-yourname` so we can find it.
5. Fork this repository and modify the README to the specifications below. You do not need to include any of your project files in this repo (we will see those on Glitch), you only need to update and commit the README file.
6. Create and submit a Pull Request to the original repo. Name the pull request using the following template: `a3-gitname-firstname-lastname`.

Sample Readme (delete the above when you're ready to submit, and modify the below so with your links and descriptions)
---

## Your Web Application Title

your glitch link e.g. http://a3-charlieroberts.glitch.me

Include a very brief summary of your project here. Images are encouraged, along with concise, high-level text. Be sure to include:

- the goal of the application
- challenges you faced in realizing the application
- what authentication strategy / database you chose to use and why (choosing one because it seemed the easiest to implement is perfectly acceptable)
- what CSS framework you used and why.
- include any modifications to the CSS framework you made via custom CSS you authored.
- the five Express middleware packages you used and a short (one sentence) summary of what each one does.

## Technical Achievements
- **Tech Achievement 1**: I used OAuth authentication via the GitHub strategy
- **Tech Achievement 2**: I used over ten Express middleware packages, enabling me to create a server that...
### When To Meet (2.0) - http://a3-jgerulskis.glitch.me
This project is a continuation of A2, hence a lot of the technical and design acheivements remain the same. In the previous iteration of this application there were numerous issues that I needed to address. For starters, I had the ability to show my application's event generation, but users weren't able to take advantage of it. Every time a new event was made it overrided the previous one. Now every new event is given a unique ID. The application can store as many events as it has memory for.

Another issue was the page redirection. After post requests were made, the site navigated to a success page. Now when events are made users are redirected right to the planning page. When you make a post request with your availabilty, the event planning page is refreshed.

### Requirements
- **Server**: Created in express
- **Results**: ViewEvent shows entire dataset for a specific event
- **Add**: Create an event adds a JSON file
- **Modify**: The viewEvent.html page allows users to modify the event JSON
- **Delete**: GarbageCollector deletes expired events using node-schedule on every sunday. An event is expired if last planning date is more than 2 days before current date.
- **Middleware**: Serve-Favicon, Express.Static, Body-Parser, Timeout
- **Persistent Data Storage**: Lowdb to track event expiration and works closely with the GarbageCollector. Also use the file system to store event jsons.
- **CSS Framework**: Bootstrap, Flatpickr (for date/time selector)

### Technical Achievements
- **Tech Achievement 1**: 2 post request types (1 in eventCreationHandler.js, 1 in eventViewerHandler.js), one creates an event, another modifys the events availibilty (2 forms)
- **Tech Achievement 2**: Front end and back end post request validation to prevent malicous intent ('FormValidation'). It mainly checks the input to make sure it is properly formatted.
- **Tech Achievement 3**: Dynamically created table based on a event details JSON file (In eventViewerHandler.js)
- **Tech Achievement 4**: Dynamically created tabled cell 'click' event callbacks utilizing closure (In eventViewerHandler.js)
- **Tech Achievement 5**: The ability to create infinite events
- **Tech Acheivement 6**: JQuery to bind UI elements to HTML, and dynamically inject navbar
- **Tech Acheivement 7**: Used library MomentJS to do operation on DateTimes on the backend. Flatpicker gives the backend a range formatted like yyyy-mm-dd to yyyy-mm-dd. I convert that to an array of dates between the two. It is then given to the client when viewing the event like [yyyy-mm-dd, yyyy-mm-dd, yyyy-mm-dd, ....]
- **Tech Acheivement 8**: Used file system on backend to make events persist as JSONs
- **Tech Acheivement 9**: Garbage Collector removes old events using lowdb to track expiration.
- **Tech Acheivement 10**: Used node-schedule module to schedule GC purge.

### Design/Evaluation Achievements
- **Design Achievement 1**: I tested my application using screen reading software, and found that...
- **Design Achievement 2**: I followed best practices for accessibility, including providing alt attributes for images and using semantic HTML. There are no `<div>` or `<span>` elements in my document.
- **Design Achievement 3**: We tested the application with n=X users, finding that...
- **Design Achievement 1**: Bootstrap CDN to quickly create layouts / navigation bar
- **Design Achievement 2**: Used library Flatpickr to create the DateTime UIs on the event creation page. Used native UI on mobile browsers. Key to a user friendly mobile experience.
- **Design Achievement 3**: Custom logo in top left of nav bar.
- **Desgin Achievement 4**: On the event viewer page, the cells with some available people has a custom calculated alpha value intended to create a quick way to determine availabilty. Ex: a cell with 4/5 available people will be much less transperant than a cell with 1/5 availabilty. This makes it easy to view.
- **Design Achievement 5**: Added a gradient background to the body of the html.
- **Design Achievement 7**: CSS to cause form input fields to be horizontally centered on the page
- **Design Achievement 8**: CSS to cause table cells of elements to appear side-by-side
- **Design Achievement 9**: CSS defined in a maintainable, readable form, in external stylesheets

### Created with help from the following libraries

Flatpickr > https://flatpickr.js.org/getting-started/
MomentJS > https://momentjs.com/
LowDB > https://github.com/typicode/lowdb
Node-scehdule > https://www.npmjs.com/package/node-schedule
19 changes: 19 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"name": "",
"version": "",
"description": "A meeting planner",
"author": "Jack Gerulskis",
"scripts": {
"start-old": "node server.improved.js",
"start": "node server.express.js"
},
"dependencies": {
"connect-timeout": "^1.9.0",
"express": "^4.17.1",
"lowdb": "^1.0.0",
"mime": "^2.4.4",
"moment": "^2.24.0",
"node-schedule": "^1.3.2",
"serve-favicon": "^2.5.0"
}
}
4 changes: 4 additions & 0 deletions private/events/eventExpirationData.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"events": [],
"count": 0
}
Binary file added public/assets/banner_logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/assets/favicon.ico
Binary file not shown.
Binary file added public/assets/wtm.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
122 changes: 122 additions & 0 deletions public/css/style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
/*
FORMS
*/
input[type=text].eventCreationField {
border-radius: 10px;
color: #ffffff;
background: rgba(9, 28, 23, 0.5);;
opacity: 70%;
width: 70%;
height: 35px;
margin: 10px auto;
font-family: Helvetica, Arial, sans-serif;
font-size: 20px;
outline: none;
text-align: center;
position: relative;
left: 15%;
}

input[type=text].eventCreationField::placeholder {
color: #cecece;
}

button.submit {
border-radius: 10px;
color: #ffffff;
background-color: #091c17;
width: 70%;
height: 35px;
margin: 10px auto;
font-family: Helvetica, Arial, sans-serif;
font-size: 20px;
font-weight: bold;
outline: none;
text-align: center;
position: relative;
left: 15%;
}

.flatpickr-day.selected, .flatpickr-day.startRange, .flatpickr-day.endRange, .flatpickr-day.selected.inRange, .flatpickr-day.startRange.inRange, .flatpickr-day.endRange.inRange,
.flatpickr-day.selected:focus, .flatpickr-day.startRange:focus, .flatpickr-day.endRange:focus, .flatpickr-day.selected:hover, .flatpickr-day.startRange:hover, .flatpickr-day.endRange:hover,
.flatpickr-day.selected.prevMonthDay, .flatpickr-day.startRange.prevMonthDay, .flatpickr-day.endRange.prevMonthDay, .flatpickr-day.selected.nextMonthDay, .flatpickr-day.startRange.nextMonthDay,
.flatpickr-day.endRange.nextMonthDay{
background: #091c17 !important;
}

/* Nav Bar (Bootstrap) */
.bg-light {
background-color: #091c17 !important;
}

a.nav-link {
color: aqua !important;
font-weight: bold;
font-size: 25px;
margin-left: 10px;
}

a.nav-link:hover {
color:#87ceeb !important;
}

.navbarLogo {
height: 60px;
width: auto;
}

/*Index.html banner logo*/
.bannerLogo {
margin: 40px;
width: 40%;
height: auto;
margin-left: 30%;
position: relative;
}

body {
height: 100%;
margin: 0;
background-repeat: no-repeat;
background-attachment: fixed;
background-image: linear-gradient(aqua, blue);
}

/* Event Viewer */
table.eventTable {
border: 3px solid #091c17;
width: 95%;
position: relative;
left: 2.5%;
}

th {
border: 2px solid #091c17;
text-align: center;
}

td {
text-align: center;
border: 1px solid #091c17;
}

tr {
background-color: #ffffff;
}

td:hover {
background-color: grey !important;
}

.eventName {
font-size: 24px;
font-weight: bold;
margin: 10px;
margin-left: 2.5%;
}

.instructions {
font-size: 24px;
margin: 10px;
margin-left: 2.5%;
}
43 changes: 43 additions & 0 deletions public/howToUse.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<!doctype html>
<html lang="en">
<head>
<title>When To Meet</title>
<meta charset="utf-8">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/flatpickr/4.2.3/flatpickr.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/flatpickr/4.2.3/themes/airbnb.css">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<link rel="stylesheet" href="/css/style.css">
</head>
<body>

<div id="nav-placeholder"></div>

<img src="assets/banner_logo.png" class="bannerLogo">

<div class="instructions"><div class="instructions"><b>How to use:</b> <br><br>
<i>Creating an Event</i> <br>
1.) Give your event a name <br>
2.) Select a potential date range for your event <br>
3.) Select a start time, will be displayed in military <br>
4.) Select an end time, will be displayed in military <br>
5.) Select "Create Event", you will be redirected to your events viewing / planning page <br>
6.) Share the link to the viewing / planning page with your team <br><br>
<i>Adding and Viewing Availablity</i> <br>
1.) Select the times you are available (They will be highlighted in blue) <br>
2.) To unselect a time, click it again <br>
3.) To submit your availabiltiy click "add my availability" <br>
4.) That's it! revist this page to view everyone's availability
</div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/flatpickr/4.2.3/flatpickr.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>

<script>
$(function () {
$("#nav-placeholder").load("/nav.html");
});
</script>
</body>
</html>
36 changes: 36 additions & 0 deletions public/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<!doctype html>
<html lang="en">
<head>
<title>When To Meet</title>
<meta charset="utf-8">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/flatpickr/4.2.3/flatpickr.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/flatpickr/4.2.3/themes/airbnb.css">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<link rel="stylesheet" href="/css/style.css">
</head>
<body>

<div id="nav-placeholder"></div>

<img src="assets/banner_logo.png" class="bannerLogo">
<form>
<input type='text' class="eventCreationField" id='eventName' placeholder="Event Name">
<input type="text" class="eventCreationField" id="dateRange" placeholder="Potential Dates">
<input type="text" class="eventCreationField" id="startTime" placeholder="No Earlier Than">
<input type="text" class="eventCreationField" id="endTime" placeholder="No Later Than">
<button class="submit" onclick="FormValidation.validateThenSubmitForm()">Create Event</button>
</form>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/flatpickr/4.2.3/flatpickr.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
<script src="/js/eventCreationHandler.js"></script>

<script>
$(function () {
$("#nav-placeholder").load("/nav.html");
});
</script>
</body>
</html>
Loading