Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
82 commits
Select commit Hold shift + click to select a range
9ad43f7
Proposal updated
seansta18 Sep 27, 2022
5face1c
Update Proposal.md
jrkimbaek Sep 29, 2022
48b4662
Set up main html as well as different folders for the project
seansta18 Oct 4, 2022
3165b30
Merge branch 'main' of https://github.com/seansta18/final_project
seansta18 Oct 4, 2022
34a80fe
add files & begin implementing games
Jacobvs Oct 7, 2022
2051c48
Fix styles and remove old code
Jacobvs Oct 7, 2022
581b3b9
more style changes & optimization
Jacobvs Oct 7, 2022
d5fcfbc
Add placeholder documents for all pages
Jacobvs Oct 7, 2022
622ed19
Add reaction time game client-side
Jacobvs Oct 7, 2022
52fafbe
Fix shifting issue
Jacobvs Oct 7, 2022
93bb6c3
Fix login text
Jacobvs Oct 7, 2022
d6f0784
incomplete addition of accuracy test game
lbfoucault Oct 8, 2022
87dd706
Add more buttons
Jacobvs Oct 8, 2022
08db462
Merge pull request #1 from seansta18/dev
Jacobvs Oct 8, 2022
b6e76d6
add cps game
Jacobvs Oct 8, 2022
80e7252
Merge pull request #2 from seansta18/dev
Jacobvs Oct 8, 2022
d958fad
added game status msgs and fixed random positioning
lbfoucault Oct 9, 2022
095f140
Add preliminary support for mongodb results
Jacobvs Oct 9, 2022
2b426f1
feat: random hidden btn in acc
jrkimbaek Oct 9, 2022
5a61d8b
Merge pull request #4
Jacobvs Oct 9, 2022
606ffa4
Add aim training & merge versions together
Jacobvs Oct 9, 2022
4cd32dd
Merge pull request #5
Jacobvs Oct 9, 2022
4dfd92f
Add support for putting data in db
Jacobvs Oct 9, 2022
36ec9e3
Fix event firing & send data back from all games after completion
Jacobvs Oct 9, 2022
31fbd53
Fix hiding scores
Jacobvs Oct 9, 2022
3bdb3be
graph attempt
jrkimbaek Oct 10, 2022
65e37bb
Set up leaderboard page with buttons and table
seansta18 Oct 10, 2022
4df7400
Added button functionality with changing tables
seansta18 Oct 10, 2022
05ae219
Set up GET requests on the client side
seansta18 Oct 10, 2022
b33dcc6
Set up skeleton GET requests
seansta18 Oct 10, 2022
391a4b8
Merge branch 'backend' into lbf
lbfoucault Oct 10, 2022
992ba71
fixed aim training
lbfoucault Oct 10, 2022
b409310
reaction test fixed. needs color change
lbfoucault Oct 11, 2022
2af7b68
Added functionality to update table with all scores
seansta18 Oct 11, 2022
fde9a35
updated all buttons to work
seansta18 Oct 11, 2022
e6883fa
Displays usernames with their scores on the leaderboard
seansta18 Oct 12, 2022
c1a1d65
Bug fixes
seansta18 Oct 12, 2022
a5ad2cd
bugs
seansta18 Oct 12, 2022
2fbd0d9
Bug fixes
seansta18 Oct 12, 2022
e347012
Fix timing
Jacobvs Oct 12, 2022
559e016
Merge pull request #6
Jacobvs Oct 12, 2022
b2454f8
Merge pull request #7
Jacobvs Oct 12, 2022
c92b30f
make text non-selectable
Jacobvs Oct 12, 2022
94217d4
Merge pull request #8
Jacobvs Oct 12, 2022
5e2d141
Added Aim to Leaderboard and fixed timing order
seansta18 Oct 12, 2022
b45bb46
bug fixes
seansta18 Oct 12, 2022
199c208
bugs
seansta18 Oct 12, 2022
1f232ad
aim training result
jrkimbaek Oct 12, 2022
20314b2
changed to bootstrap table with hovering
seansta18 Oct 12, 2022
5efb38e
Personal Scores Page
seansta18 Oct 12, 2022
87da949
fixed 100 accessibility lighthouse score
lbfoucault Oct 12, 2022
1fba4f3
Added personal scores to the bottom of leaderboard
seansta18 Oct 13, 2022
387665b
Merge pull request #9 from seansta18/updateleaderboard
seansta18 Oct 13, 2022
f5e8498
Bug Fix
seansta18 Oct 13, 2022
04f3330
Changed Index page name to Home
seansta18 Oct 13, 2022
802f9ef
Text change on leaderboards
seansta18 Oct 13, 2022
333b11c
update readme
lbfoucault Oct 13, 2022
a806c2a
Add index page
Jacobvs Oct 13, 2022
8982aa7
Merge pull request #10
Jacobvs Oct 13, 2022
76021a2
shows graph
jrkimbaek Oct 13, 2022
cf8ed3c
add images
Jacobvs Oct 13, 2022
b1779c7
fixed coef
jrkimbaek Oct 13, 2022
d09cd18
fix leaderboard
Jacobvs Oct 13, 2022
1d1bfea
applied to all games
jrkimbaek Oct 13, 2022
f2d3b36
Merge branch 'main' into result-graph
jrkimbaek Oct 13, 2022
d6766eb
Merge pull request #11 from seansta18/result-graph
jrkimbaek Oct 13, 2022
9cc4d2c
Merge branch 'main' into accessibility
Jacobvs Oct 13, 2022
83e8476
Merge pull request #12 from seansta18/accessibility
Jacobvs Oct 13, 2022
4890a91
fix btns and reaction test bug
Jacobvs Oct 13, 2022
cbfe42a
reaction timing
Jacobvs Oct 13, 2022
ae8bf7d
Added pic of lighthouse test
seansta18 Oct 13, 2022
50f9153
Merge branch 'main' of https://github.com/seansta18/final_project
seansta18 Oct 13, 2022
d7e41a8
update readme
seansta18 Oct 13, 2022
ee1552b
update readme
seansta18 Oct 13, 2022
3550fd7
update readme
Jacobvs Oct 13, 2022
55775f5
Update readme
seansta18 Oct 13, 2022
da22459
Merge branch 'main' of https://github.com/seansta18/final_project
seansta18 Oct 13, 2022
a8baae4
cps graph fix
jrkimbaek Oct 13, 2022
1a40cca
Merge branch 'main' of https://github.com/seansta18/final_project
jrkimbaek Oct 13, 2022
d33677d
readme updated
seansta18 Oct 13, 2022
ecfb763
Update README.md
Jacobvs Oct 13, 2022
2ad5973
Update README.md
jrkimbaek Oct 13, 2022
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
61 changes: 61 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# Runtime data
pids
*.pid
*.seed
*.pid.lock

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

# Coverage directory used by tools like istanbul
coverage

# nyc test coverage
.nyc_output

# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt

# Bower dependency directory (https://bower.io/)
bower_components

# node-waf configuration
.lock-wscript

# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release

# Dependency directories
node_modules/
jspm_packages/

# Typescript v1 declaration files
typings/

# Optional npm cache directory
.npm

# Optional eslint cache
.eslintcache

# Optional REPL history
.node_repl_history

# Output of 'npm pack'
*.tgz

# Yarn Integrity file
.yarn-integrity

# dotenv environment variables file
.env

# next.js build output
.next
Binary file added Lighthouse_test.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions Proposal.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Final Project Proposal (due 9/27)
# By Sean McMillan, Liliana Foucault, Jin Ryoul Kim, and Jacob Van Steyn

For our project, we are planning on creating a webpage with three seperate clicking games. There will be a main page with a login option along with buttons to move to different games. The three games we are planning on creating are a clicks per second test, reaction time test, and a mouse accuracy test. The clicks per second test will have a single button that the user will click for 10 seconds. During this time, we will record the number of clicks to calculate their clicks per second. For the reaction time test, three buttons will show up with only one of them being green. The overall score for this test will be calculated by overall time plus extra time for clicking the wrong button. And for the mouse accuracy test, a button will randomly appear somewhere on a screen and, once it is clicked, another will appear in a different location. This games score will be calculated by overall time it takes to click 10 buttons. Along with these games, there will be a leaderboard with the best scored from each of the games which users can be added to once logged in.

We plan on using a few different libraries and technologies for this project. For authentication and the leaderboard, we plan on using MongoDB to keep consistent data across different clients. We also plan on using React for some of the games like placing buttons randomly on the screen. We also plan on using express along with express middleware packages for the server.
56 changes: 14 additions & 42 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,49 +1,21 @@
# Final Project
*Due before the start of class, October 13th (final day of the term)*
# Reaction Tests
# By Sean McMillan, Liliana Foucault, Jin Ryoul Kim, and Jacob Van Steyn

For your final project, you'll implement a web application that exhibits understanding of the course materials.
This project should provide an opportunity to both be creative and to pursue individual research and learning goals.
Site Link (Heroku): https://reactiontests.herokuapp.com/

## General description
Your project should consist of a complete Web application, exhibiting facets of the three main sections of the course material:
Overview video: (link): https://youtu.be/gmtfIiOumqo

- Static web page content and design. You should have a project that is accessible, easily navigable, and features significant content.
- Dynamic behavior implemented with JavaScript (TypeScript is also allowed if your group wants to explore it).
- Server-side programming *using Node.js*. Typically this will take the form of some sort of persistent data (database), authentication, and possibly server-side computation.
- A video (less than five minutes) where each group member explains some aspect of the project. An easy way to produce this video is for you all the groups members to join a Zoom call that is recorded; each member can share their screen when they discuss the project or one member can "drive" the interface while other members narrate (this second option will probably work better.) The video should be posted on YouTube or some other accessible video hosting service. Make sure your video is less than five minutes, but long enough to successfully explain your project and show it in action. There is no minimum video length.
# Introduction
Our website has a collection of 4 different timed tests for a user to take. One example is the Accuracy Test, where 5 buttons are shown in random places on the game screen. The user is timed by how long it takes to click all 5 buttons with no mis-click time penalty. There is leaderboard page that displays the top scores for each minigame on the website which only include logged-in user names. If the user is logged in, then underneath the leaderboard they can view all of their past scores. A user can login using a GitHub account, or play without being logged in. Users not logged in can still play and view the leaderboard.

## Project ideation
Excellent projects typically serve someone/some group; for this assignment you need to define your users and stakeholders. I encourage you to identify projects that will have impact, either artistically, politically, or in terms of productivity.
# Technologies
We used ejs for the pages and components, and Boostrap for styling. Additional styling is defined in "style.css". The database of scores is stored using MongoDB. The website can be run locally and is also hosted on Heroku.

### Deliverables
# Team Responsibilities
The majority of work was divided into client-server communication/set up, minigames, leaderboard, and login authentication. Sean worked on the leaderboard, personal scores, and client-server communication. Liliana worked on the frontend minigames, styling, and website accessibility. JR worked on the minigames, score graphs, backend... Jacob worked on the backend, login authentication, overall site styling (bootstrap & css), accuracy game, mongodb/mongoose, & Express.

#### Form Team (due 9/25)
Students are will work in teams of 3-5 students for the project; teams of two can be approved with the permission of the instructor. Working in teams should help enable you to build a good project in a limited amount of time. Use the `#project-logistics` channel in Discord to pitch ideas for final projects and/or find fellow team members as needed.
# Challenges
There were two major challenges for this project. The first was having the UI look nice while also being accessible. We had to make some tough decisions when it came to the lighthouse test because while the test disliked some of our styling choices, we thought they looked nice. The other challenge was with chart.js. This was a new package to all of us and connecting it with the database became very challenging.

Teams must be in place by end of day on Sunday, September 25th. If you have not identified a team at this point, you will be assigned a team. You will be given some class time on Monday to work on your proposal, but please plan on reserving additional time outside of class as needed.

#### Proposal (due 9/27)
Provide an outline of your project direction and the names of associated team members.
The outline should have enough detail so that staff can determine if it meets the minimum expectations, or if it goes too far to be reasonable by the deadline. Please include a general description of a project, and list of key technologies/libraries you plan on using (e.g. React, Three.js, Svelte, TypeScript etc.). Two to four paragraps should provide enough level of detail. Name the file proposal.md and submit a pull request by Tuesday, September 27th at 11:59 PM (end of day). Only one pull request is required per team.

There are no other scheduled checkpoints for your project.

#### Turning in Your Project
Submit a second PR on the final project repo to turn in your app and code. Again, only one pull request per team.

Deploy your app, in the form of a webpage, to Glitch/Heroku/Digital Ocean or some other service; it is critical that the application functions correctly wherever you post it.

The README for your second pull request doesn’t need to be a formal report, but it should contain:

1. A brief description of what you created, and a link to the project itself (two paragraphs of text)
2. Any additional instructions that might be needed to fully use your project (login information etc.)
3. An outline of the technologies you used and how you used them.
4. What challenges you faced in completing the project.
5. What each group member was responsible for designing / developing.
6. A link to your project video.

Think of 1,3, and 4 in particular in a similar vein to the design / tech achievements for A1—A4… make a case for why what you did was challenging and why your implementation deserves a grade of 100%.

## FAQs

- **Can I use XYZ framework?** You can use any web-based frameworks or tools available, but for your server programming you need to use Node.js. Your client-side scripting language should be either JavaScript or TypeScript.
# Achievements
As with previous assignments, we ensure Lighthouse scores of 100 in 3 categories with accessibility scoring a 97. We added a screenshot of the test called Lighthouse_test.png. Pages are easy to access given both header and footer links and descriptions. Our website has multiple fun minigames to test a user's abilities but also compare to an average score. We also added graphics using ChartJS to make the leaderboard and average scores per game more visually interesting.
78 changes: 78 additions & 0 deletions app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
require('dotenv').config();

const createError = require('http-errors');
const express = require('express');
const path = require('path');
const cookieParser = require('cookie-parser');
const session = require('express-session');
const csrf = require('csurf');
const passport = require('passport');
const logger = require('morgan');
const mongoose = require('mongoose');


var indexRouter = require('./routes/index');
var authRouter = require('./routes/auth');
var gamesRouter = require('./routes/games');
var scoresRouter = require('./routes/scores');
const { Timestamp, Int32 } = require('mongodb');

var app = express();

mongoose.Promise = global.Promise;
mongoose.connect(process.env['URI'])
.then(() => console.log('Connected to MongoDB'))
.catch((err) => console.error(err));

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');

app.use(logger('common'));
app.use(cookieParser());
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(express.static(path.join(__dirname, 'public')));
app.use(session({
secret: 'secRet!',
resave: true,
saveUninitialized: false
}));
app.use(passport.initialize());
app.use(passport.session())
app.use(csrf());
//app.use(passport.authenticate('session'));
app.use(function(req, res, next) {
var msgs = req.session.messages || [];
res.locals.messages = msgs;
res.locals.hasMessages = !! msgs.length;
req.session.messages = [];
next();
});
app.use(function(req, res, next) {
res.locals.csrfToken = req.csrfToken();
next();
});

app.use('/', indexRouter);
app.use('/', authRouter);
app.use('/', gamesRouter);
app.use('/', scoresRouter);

// catch 404 and forward to error handler
app.use(function(req, res, next) {
next(createError(404));
});

// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};

// render the error page
res.status(err.status || 500);
res.render('error');
});

module.exports = app;
90 changes: 90 additions & 0 deletions bin/www
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
#!/usr/bin/env node

/**
* Module dependencies.
*/

var app = require('../app');
var debug = require('debug')('final-project:server');
var http = require('http');

/**
* Get port from environment and store in Express.
*/

var port = normalizePort(process.env.PORT || '3000');
app.set('port', port);

/**
* Create HTTP server.
*/

var server = http.createServer(app);

/**
* Listen on provided port, on all network interfaces.
*/

server.listen(port);
server.on('error', onError);
server.on('listening', onListening);

/**
* Normalize a port into a number, string, or false.
*/

function normalizePort(val) {
var port = parseInt(val, 10);

if (isNaN(port)) {
// named pipe
return val;
}

if (port >= 0) {
// port number
return port;
}

return false;
}

/**
* Event listener for HTTP server "error" event.
*/

function onError(error) {
if (error.syscall !== 'listen') {
throw error;
}

var bind = typeof port === 'string'
? 'Pipe ' + port
: 'Port ' + port;

// handle specific listen errors with friendly messages
switch (error.code) {
case 'EACCES':
console.error(bind + ' requires elevated privileges');
process.exit(1);
break;
case 'EADDRINUSE':
console.error(bind + ' is already in use');
process.exit(1);
break;
default:
throw error;
}
}

/**
* Event listener for HTTP server "listening" event.
*/

function onListening() {
var addr = server.address();
var bind = typeof addr === 'string'
? 'pipe ' + addr
: 'port ' + addr.port;
debug('Listening on ' + bind);
}
45 changes: 45 additions & 0 deletions models/Results.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
const mongoose = require("mongoose");
let Schema = mongoose.Schema;

let ResultsSchema = new Schema(
{
owner_id: {type: String, required: true},
game_type: {type: String, required: true, enum: ["cps", "accuracy", "reaction", "aimtraining"]},
score: {
type: Number,
required: [true, "A score is required!"]},
time: {type: Date, default: new Date()}
},
{ timestamps: true }
);

ResultsSchema.index({ game_type: 1, score: 1 });

ResultsSchema.statics.findOrCreate = require("find-or-create");

ResultsSchema.statics.getAllResultsForGame = function(game) {
return this.find({game_type: game})
}

ResultsSchema.statics.getTopResultsForGame = function(game_type, n_scores) {
return this.find({game_type: game_type}).sort({score: "desc"}).limit(n_scores)
}

ResultsSchema.statics.getTopResultsForTimeGame = function(game_type, n_scores) {
return this.find({game_type: game_type}).sort({score: "asc"}).limit(n_scores)
}

ResultsSchema.statics.getResultsForUserId = function(user_id) {
return this.find({owner_id: user_id})
}

ResultsSchema.statics.getSpecificGameResultsForUserId = function(user_id, game_type) {
return this.find({owner_id: user_id, game_type: game_type})
}

ResultsSchema.statics.getRankforScore = function(game, score) {
var numGreaterThan = this.distinct({game_type: game, score: { $gt: score}}).count();
return null;
}

module.exports = mongoose.model("results", ResultsSchema, "results");
22 changes: 22 additions & 0 deletions models/User.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
const mongoose = require("mongoose");
let Schema = mongoose.Schema;

let UserSchema = new Schema(
{
id: { type: String, sparse: true},
email: {
type: String,
required: [true, "Email is required!"],
unique: [true, "Email already registered"],
sparse: true },
username: {type: String, required: true},
displayName: String,
profilePhoto: String,
lastVisited: { type: Date, default: new Date() },
},
{ timestamps: true }
);

UserSchema.statics.findOrCreate = require("find-or-create");

module.exports = mongoose.model("user", UserSchema, "users");
Loading