Skip to content

Instantly share code, notes, and snippets.

@DominicTremblay
Last active June 12, 2019 17:24
Show Gist options
  • Save DominicTremblay/e9fdd366fbefeaeff379bbcb70ee3286 to your computer and use it in GitHub Desktop.
Save DominicTremblay/e9fdd366fbefeaeff379bbcb70ee3286 to your computer and use it in GitHub Desktop.
schoodle
<!DOCTYPE html>
<html lang="en">
<head>
<title>Results</title>
<link rel="stylesheet" href="/vendor/normalize-4.1.1.css" type="text/css" />
<link rel="stylesheet" href="/vendor/border-box.css" type="text/css" />
<link rel="stylesheet" href="/styles/layout.css" type="text/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">
<script type="text/javascript" src="/vendor/jquery-3.0.0.js"></script>
<script type="text/javascript" src="/scripts/app.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
</head>
<body>
<header>
<div class="nav">
<a href="/"><img
src="/schoodlelogo2.png"
alt="schoodle"
width="230px"
height="80px"
></a>
</div>
</header>
<section class="block3">
<h1>
Event title
</h1>
<h5>
eventDescription
</h5>
<div id="shareBox">
<h6>Share event with guests: </h6>
<textarea name="shareURL" id="myInput">http://localhost:8080/events/<%= eventData.eventUrl%></textarea>
<h6>↪️</h6>
</div>
<div class="container3">
<table class="table table-striped table-bordered table-hover" id=table>
<tr class="table-row">
<th><h6>Dates</h6></th>
<% for (const timeslotObj of eventData.timeslots) { %>
<td><h6><%= timeslotObj.timeslot %></h6></td>
<% } %>
<td></td>
</tr>
<% for (const user in eventData.usersVotes) { %>
<tr>
<td><%= user %></td>
<% for (const vote of eventData.usersVotes[user].sort(
(a, b) => a.timeslotId - b.timeslotId
)) { %>
<td><input type='checkbox' name="<%= vote.timeslotId %>" <%= vote.checked ? 'checked' : null %>></td>
<% } %>
</tr>
<% } %>
<form action="/events/<%= eventData.eventUrl%>" method="POST">
<tr>
<td>
<input type='text' class="textAreaTable" name="name" cols="7" rows="2" placeholder="your name"></textarea>
<input type='text' class="textAreaTable" name="email" cols="7" rows="2" placeholder="your email"></textarea>
</td>
<% for (const timeslotObj of eventData.timeslots) { %>
<td><input class="form-check-input" name="<%= timeslotObj.timeslotId %>" type="checkbox"</td>
<% } %>
<td><button type="submit" class="btn-success-btn-lg" value="submit">Save</button></td>
</tr>
</form>
</table>
</div>
</section>
<footer></footer>
</body>
</html>
'use strict';
require('dotenv').config();
const PORT = process.env.PORT || 8080;
const ENV = process.env.ENV || 'development';
const express = require('express');
const bodyParser = require('body-parser');
const sass = require('node-sass-middleware');
const app = express();
const knexConfig = require('./knexfile');
const knex = require('knex')(knexConfig[ENV]);
const morgan = require('morgan');
const knexLogger = require('knex-logger');
// Seperated Routes for each Resource
const usersRoutes = require('./routes/users');
// Load the logger first so all (static) HTTP requests are logged to STDOUT
// 'dev' = Concise output colored by response status for development use.
// The :status token will be colored red for server error codes, yellow for client error codes, cyan for redirection codes, and uncolored for all other codes.
app.use(morgan('dev'));
// Log knex SQL queries to STDOUT as well
app.use(knexLogger(knex));
app.set('view engine', 'ejs');
app.use(bodyParser.urlencoded({ extended: true }));
app.use(
'/styles',
sass({
src: __dirname + '/styles',
dest: __dirname + '/public/styles',
debug: true,
outputStyle: 'compressed',
})
);
app.use(express.static('public'));
// Mount all resource routes
app.use('/api/users', usersRoutes(knex));
// app.use("/api/events", usersRoutes(knex));
// app.use("/api/timeslots", usersRoutes(knex));
// app.use("/api/attendees", usersRoutes(knex));
//String randomizing function
function generateRandomString() {
let randomize = Math.random()
.toString(36)
.substring(7);
return randomize;
}
const votesByName = (votesArr, timeslotIds) => {
const votesObj = {};
for (const voteObj of votesArr) {
const key = voteObj.name;
votesObj[key] =
votesObj[key] ||
timeslotIds.map(timeslotId => ({
timeslotId,
checked: false,
}));
const timeslot = votesObj[key].find(
timeslotObj => voteObj.timeslotId === timeslotObj.timeslotId
);
timeslot.checked = true;
votesObj[key] = [
timeslot,
...votesObj[key].filter(
timeslotObj => timeslotObj.timeslotId !== timeslot.timeslotId
),
];
}
return votesObj;
};
// Home page - redirects (create button) to /events/new
app.get('/', (req, res) => {
res.render('index');
});
app.get('/events/new', (req, res) => {
res.render('events_new');
});
// Save new event and redirect to event poll page
app.post('/events/new', (req, res) => {
// Add new URL and form entries to "event" DB table & "timeslot" DB table
// Redirect to event page "/events/:url"
let shortURL = generateRandomString();
//input parameters
let name = req.body.name;
let email = req.body.email;
let event = req.body.event;
let description = req.body.description;
let timeslot1 = req.body.timeslot1;
let timeslot2 = req.body.timeslot2;
let timeslot3 = req.body.timeslot3;
knex('users')
.insert({ name, email })
.returning('id')
.then(bunchOfIds => {
knex('events')
.insert({
title: event,
description,
url: shortURL,
user_id: bunchOfIds[0],
})
.returning('id')
.then(eventIds => {
knex('timeslots')
.insert({ timeslot: timeslot1, event_id: eventIds[0] })
.then(result => console.log('ok'));
knex('timeslots')
.insert({ timeslot: timeslot2, event_id: eventIds[0] })
.then(result => console.log('ok'));
knex('timeslots')
.insert({ timeslot: timeslot3, event_id: eventIds[0] })
.then(result =>
res.redirect(`http://localhost:8080/events/${shortURL}`)
);
});
});
});
// Event form - enter event info & timeslots
app.get('/events/:id', (req, res) => {
let templateVars;
const { id: eventUrl } = req.params;
knex
.select('timeslots.id as timeslotId', 'timeslots.timeslot')
.from('events')
.where('url', eventUrl)
.innerJoin('timeslots', 'events.id', 'timeslots.event_id')
.then(timeslots => {
const eventData = {};
eventData.eventUrl = eventUrl;
eventData.timeslots = timeslots;
// getting only the ids in an array
const timeslotIds = eventData.timeslots.map(
timeslotObj => timeslotObj.timeslotId
);
// console.log('timeslotIds', timeslotIds);
knex
.select(
'users.name',
'users.id as userId',
'votes.timeslot_id as timeslotId'
)
.from('votes')
.innerJoin('users', 'votes.user_id', 'users.id')
.whereIn('timeslot_id', timeslotIds)
.then(votes => {
// console.log('Votes', votes);
const usersVotes = votesByName(votes, timeslotIds);
// console.log('usersVotes:', usersVotes);
eventData.usersVotes = usersVotes;
// console.log('Event Data', eventData.usersVotes);
res.render('events_results', { eventData });
// res.json(eventData);
});
});
// knex('votes')
// .select(
// 'votes.id as voteid',
// 'name',
// 'email',
// 'timeslot',
// 'title',
// 'description'
// )
// .innerJoin('users', 'votes.user_id', 'users.id')
// .innerJoin('timeslots', 'votes.timeslot_id', 'timeslots.id')
// .innerJoin('events', 'timeslots.event_id', 'events.id')
// // .orderBy('timeslots.id')
// .orderBy('name')
// .then(result => {
// console.log(result);
// const templateVars = {
// shareURL: req.params.id,
// eventTitle: result[0].title,
// eventDescription: result[0].description,
// result: result,
// };
// res.render('events_results', templateVars);
// });
});
app.get('/u/:shortURL', (req, res) => {
res.render('events_results');
});
// Save button actions - allows user to save new vote
app.post('/events/:shareURL', (req, res) => {
// Save new vote entry to: (a) Users table, (b) Votes table
// Redirect to same page (reload)
// let shareURL = req.params.shareURL;
console.log('Adding a new vote');
console.log(req.body);
let shareURL = req.params.shareURL;
let name = req.body.name;
let email = req.body.email;
// extracting timeslot Ids from req.body into an array
const timeslotIds = Object.keys(req.body).filter(
key => req.body[key] === 'on'
);
console.log('timeslotIds', timeslotIds);
knex('users')
.insert({ name, email })
.returning('id')
.then(([userId]) => {
// creating the array of votes
const votesArr = timeslotIds.map(timeslotId => ({
user_id: userId,
timeslot_id: Number(timeslotId),
}));
console.log('votesArr', votesArr);
knex('votes')
.insert(votesArr)
.then(result =>
res.redirect(`http://localhost:8080/events/${shareURL}`)
);
});
// knex("events")
// .insert({ title: event, description, url: shortURL, user_id: id })
// .then(result => console.log(result));
// knex("users")
// .insert({ name, email })
// .returning("id")
// .then((bunchOfIds) => {
// knex("votes")
// .insert({
// user_id: bunchOfIds[0],
// timeslot_id: time
// // (knex('events')
// // .select('id')
// // .innerJoin('timeslots', 'id', 'event_id')
// // .where('url', 'shareURL'))
// })
// .then(result => console.log(result));
// })
});
// Edit button actions - allows user to edit existing vote
// app.post("/users/:userid/events/:url", (req, res) => {
// // Update votes table (in DB) with new availabilities
// // Redirect to same page (reload)
// });
app.listen(PORT, () => {
console.log('Example app listening on port ' + PORT);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment