Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ha create and list reservations #235

Open
wants to merge 76 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
76 commits
Select commit Hold shift + click to select a range
db5517f
created and seeded databas with migration andseed files, updated the …
halbert-anderson May 22, 2024
081a41d
First commit
halbert-anderson May 23, 2024
e3d9657
added Route /reservations/new to Routes.js file and craeted reservati…
halbert-anderson May 25, 2024
fc5cf84
switched to node version 16.20.0 to get the front end to connect to t…
halbert-anderson May 28, 2024
184183b
added some temporary code to the utils/api.js file to locally create …
halbert-anderson May 28, 2024
5278470
created separate databases for production, development, preview and t…
halbert-anderson May 31, 2024
bccf495
Merge pull request #1 from halbert-anderson/ha--create-and-list-reser…
halbert-anderson Jun 1, 2024
cf90f96
fixed typo in /backend/package.json file
halbert-anderson Jun 1, 2024
ddf6b9c
fixed typo in /backend/package.json file
halbert-anderson Jun 1, 2024
f9224ff
created the create() handler in the reservations controller.js file, …
halbert-anderson Jun 2, 2024
cae25ca
Updated the frontend src/utils/api file to Get /reservations, created…
halbert-anderson Jun 2, 2024
50a2dad
Merge pull request #2 from halbert-anderson/ha--create-and-list-reser…
halbert-anderson Jun 2, 2024
f756c83
fixed typo
halbert-anderson Jun 2, 2024
288e8e5
Merge pull request #3 from halbert-anderson/ha--create-and-list-reser…
halbert-anderson Jun 2, 2024
e8e9be2
Fixed typo in reservations.controller.js file: changed fisrt_name to …
halbert-anderson Jun 2, 2024
384263d
Merge pull request #4 from halbert-anderson/ha--create-and-list-reser…
halbert-anderson Jun 2, 2024
5923438
Chamged incprredtly labeled elements in reservations.controller.js fi…
halbert-anderson Jun 2, 2024
2e57960
Merge pull request #5 from halbert-anderson/ha--create-and-list-reser…
halbert-anderson Jun 2, 2024
8e51ac8
addded a console.log( reservation_date ) to the reservation.controlle…
halbert-anderson Jun 2, 2024
27c928a
Merge pull request #6 from halbert-anderson/ha--create-and-list-reser…
halbert-anderson Jun 2, 2024
d05fb80
made another change to reservations.controller.js file to test an input
halbert-anderson Jun 2, 2024
3bd61d1
Merge pull request #7 from halbert-anderson/ha--create-and-list-reser…
halbert-anderson Jun 2, 2024
51695c2
made another change to reservations.controller.js file to test an input
halbert-anderson Jun 2, 2024
2df727c
Merge pull request #8 from halbert-anderson/ha--create-and-list-reser…
halbert-anderson Jun 2, 2024
e77e97b
made another change to reservations.controller.js file to test an input
halbert-anderson Jun 3, 2024
5207197
Merge pull request #9 from halbert-anderson/ha--create-and-list-reser…
halbert-anderson Jun 3, 2024
58f1423
made another change to reservations.controller.js file regDate = /^\…
halbert-anderson Jun 3, 2024
ce5d702
Merge pull request #10 from halbert-anderson/ha--create-and-list-rese…
halbert-anderson Jun 3, 2024
b54de55
added code to reservations.service file to create a reservation entry…
halbert-anderson Jun 3, 2024
f65f7a6
Merge pull request #11 from halbert-anderson/ha--create-and-list-rese…
halbert-anderson Jun 3, 2024
5c1e50a
Revert "added code to reservations.service file to create a reservati…
halbert-anderson Jun 3, 2024
3bdddc5
Merge pull request #12 from halbert-anderson/revert-11-ha--create-and…
halbert-anderson Jun 3, 2024
bb410b5
added code to reservations.service file to create a reservation entry…
halbert-anderson Jun 3, 2024
042850e
Merge branch 'main' into ha--create-and-list-reservations
halbert-anderson Jun 3, 2024
929a9c8
Merge pull request #13 from halbert-anderson/ha--create-and-list-rese…
halbert-anderson Jun 3, 2024
5feb512
added src/error/asyncErrorBoundary.js file to handle errors form asyn…
halbert-anderson Jun 3, 2024
fac4337
Merge branch 'ha--create-and-list-reservations' of https://github.com…
halbert-anderson Jun 3, 2024
a4df9d1
added src/error/asyncErrorBoundary.js file to handle errors form asyn…
halbert-anderson Jun 3, 2024
e70b22a
Merge pull request #14 from halbert-anderson/ha--create-and-list-rese…
halbert-anderson Jun 3, 2024
35580fc
Added previous, today and next buttons and button handlers to the das…
halbert-anderson Jun 3, 2024
7d578c3
Merge pull request #15 from halbert-anderson/ha--create-and-list-rese…
halbert-anderson Jun 3, 2024
f71b36e
changed signature of loadDashboard fuction definition in the dashboar…
halbert-anderson Jun 3, 2024
c430247
Merge pull request #16 from halbert-anderson/ha--create-and-list-rese…
halbert-anderson Jun 3, 2024
6fe4cba
added Previous,Today and Next buttons with onClick handlers and adde…
halbert-anderson Jun 6, 2024
4b40a80
Merge pull request #17 from halbert-anderson/ha--create-and-list-rese…
halbert-anderson Jun 6, 2024
ba7d67f
added Previous,Today and Next buttons with onClick handlers and adde…
halbert-anderson Jun 6, 2024
62cdda8
Merge pull request #18 from halbert-anderson/ha--create-and-list-rese…
halbert-anderson Jun 6, 2024
25132c7
updated the list handler in the reservations.controller and reservati…
halbert-anderson Jun 7, 2024
55c07a8
Merge pull request #19 from halbert-anderson/ha--create-and-list-rese…
halbert-anderson Jun 7, 2024
1ebf202
updated the list handler in the reservations.controller and reservati…
halbert-anderson Jun 8, 2024
597b9f0
Merge pull request #20 from halbert-anderson/ha--create-and-list-rese…
halbert-anderson Jun 8, 2024
d2454d0
updated the list handler in the reservations.controller and reservati…
halbert-anderson Jun 8, 2024
93291aa
Merge pull request #21 from halbert-anderson/ha--create-and-list-rese…
halbert-anderson Jun 8, 2024
dcab664
cleaned up unused code
halbert-anderson Jun 13, 2024
d0e98a5
Merge branch 'Thinkful-Ed:main' into ha--create-and-list-reservations
halbert-anderson Jun 14, 2024
7ef566d
Merge pull request #22 from halbert-anderson/ha--create-and-list-rese…
halbert-anderson Jun 14, 2024
5c0e3d1
checked all code for errrors
halbert-anderson Jun 14, 2024
8069263
Merge branch 'main' of https://github.com/halbert-anderson/restaurant…
halbert-anderson Jun 14, 2024
fe4dec2
updates
halbert-anderson Jun 17, 2024
2888c96
updating changes made on another computer
halbert-anderson Jun 18, 2024
60f6049
Merge branch 'ha--create-and-list-reservations' of https://github.com…
halbert-anderson Jun 18, 2024
2d40dc7
updating changes made on another computer
halbert-anderson Jun 18, 2024
ed3fc4d
updated hasData() middleware function in the reservations.controller.…
halbert-anderson Jun 19, 2024
fa7e712
Merge branch 'main' into ha--create-and-list-reservations
halbert-anderson Jun 19, 2024
18716c6
moved buttons on dashboard to a seperate file,updated function call F…
halbert-anderson Jun 23, 2024
ec423de
moved buttons on dashboard to a seperate file,updated function call F…
halbert-anderson Jun 23, 2024
be0a550
cleaning up files
halbert-anderson Jun 24, 2024
bccd3b0
refactored some modules made a ReservationsForm.js file for the form…
halbert-anderson Jun 26, 2024
d5b59d5
cleaned up files
halbert-anderson Jun 26, 2024
d0b1d92
updated the ErrorAlert.js file so that it prints out error instead of…
halbert-anderson Jun 26, 2024
b4d7f77
typo
halbert-anderson Jun 26, 2024
67d6c10
updated the form validation for the first_name and last_name <input>…
halbert-anderson Jun 28, 2024
11b0b02
added some migration files
halbert-anderson Jul 10, 2024
a4a44ff
added some migration files
halbert-anderson Jul 10, 2024
4def030
added some migration files
halbert-anderson Jul 11, 2024
fd34c11
use case 1 is working
halbert-anderson Jul 11, 2024
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
1 change: 1 addition & 0 deletions .node-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
16.20.2
2 changes: 1 addition & 1 deletion back-end/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
.env.test.local
.env.production.local
.vercel

.env
npm-debug.log*
yarn-debug.log*
yarn-error.log*
4,308 changes: 1,320 additions & 2,988 deletions back-end/package-lock.json

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions back-end/package.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
{
"name": "starter-restaurant-reservation-back-end",
"name": "restaurant-reservation-system-back-end",
"version": "1.0.0",
"description": "Starter code for restaurant reservation backend",
"description": "Code for restaurant reservation system backend",
"main": "src/server.js",
"repository": {
"type": "git",
"url": "https://github.com/Thinkful-Ed/starter-restaurant-reservation",
"url": "https://github.com/halbert-anderson/restaurant-reservation-system",
"directory": "/back-end"
},
"scripts": {
Expand Down
8 changes: 5 additions & 3 deletions back-end/src/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,21 @@ require("dotenv").config({ path: path.join(__dirname, "..", ".env") });

const express = require("express");
const cors = require("cors");
const app = express();
const reservationsRouter = require("./reservations/reservations.router");

const errorHandler = require("./errors/errorHandler");
const notFound = require("./errors/notFound");
const reservationsRouter = require("./reservations/reservations.router");

const app = express();


app.use(cors());
app.use(express.json());


app.use("/reservations", reservationsRouter);

app.use(notFound);
app.use(errorHandler);

module.exports = app;
module.exports = app;
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
exports.up = function (knex) {
return knex.schema.createTable("reservations", (table) => {
table.increments("reservation_id").primary();
table.string("first_name").notNullable();
table.string("last_name").notNullable();
table.string("mobile_number").notNullable();
table.date("reservation_date").notNullable();
table.time("reservation_time").notNullable();
table.integer("people").unsigned().notNullable();
table.string("status").defaultTo("booked");
table.timestamps(true, true);
});
};

exports.down = function (knex) {
return knex.schema.dropTable("reservations");
};
};
14 changes: 14 additions & 0 deletions back-end/src/db/migrations/20240630144440_createTablesTable.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
exports.up = function (knex) {
return knex.schema.createTable("tables", (table) => {
table.increments("table_id").primary();
table.string("table_name").notNullable();
table.integer("capacity").notNullable();
table.integer('reservation_id').nullable();
table.foreign('reservation_id').references('reservation_id').inTable('reservations');
table.boolean('occupied').defaultTo(false).notNullable();
table.timestamps(true, true); });
};

exports.down = function (knex) {
return knex.schema.dropTable("tables");
};
7 changes: 6 additions & 1 deletion back-end/src/db/seeds/00-reservations.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
const reservations =require("./00-reservations.json");

exports.seed = function (knex) {
return knex.raw("TRUNCATE TABLE reservations RESTART IDENTITY CASCADE");
return knex.raw("TRUNCATE TABLE reservations RESTART IDENTITY CASCADE")
.then(function () {
return knex("reservations").insert(reservations);
});
};
15 changes: 15 additions & 0 deletions back-end/src/errors/asyncErrorBoundary.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
function asyncErrorBoundary(delegate, defaultStatus) {
return (request, response, next) => {
Promise.resolve()
.then(() => delegate(request, response, next))
.catch((error = {}) => {
const { status = defaultStatus, message = error } = error;
next({
status,
message,
});
});
};
}

module.exports = asyncErrorBoundary;
8 changes: 8 additions & 0 deletions back-end/src/errors/methodNotAllowed.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
function methodNotAllowed(req, res, next) {
next({
status: 405,
message: `${req.method} not allowed for ${req.originalUrl}`,
});
};

module.exports = methodNotAllowed;
122 changes: 119 additions & 3 deletions back-end/src/reservations/reservations.controller.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,128 @@
/**
* List handler for reservation resources
*/
async function list(req, res) {
const reservationsService = require("./reservations.service");
const asyncErrorBoundary = require("../errors/asyncErrorBoundary");


function hasData(req, res, next) {
console.log("hasData: ",req.body.data);
if (req.body.data) {
return next()
}
next({ status: 400, message: "body must have data property" })
}

function firstAndLastNameAreValid(req, res, next) {
const regName =/^[a-zA-Z0-9'-. ]+$/;
const { first_name, last_name } =req.body.data;
console.log("firstAndLastNameAreValid - First Name:", first_name, " Last Name: ",last_name);
if(!first_name ||!regName.test(first_name)){
next({ status: 400, message: "Must include valid first_name."})
}

if(!last_name || !regName.test(last_name)){
next({ status: 400, message: "Must include valid last_name." })
}

return next();
}

function mobileNumberIsValid(req, res, next) {
const { mobile_number } = req.body.data;
const regMobileNum = /^\d{3}-\d{3}-\d{4}$/
console.log("mobileNumberIsValid: ", mobile_number);
if(!regMobileNum.test(mobile_number)){
next({ status: 400, message: "Must include valid mobile_number (ex. ddd-ddd-dddd)." })
}
return next();
}

function reservationDateIsValid(req, res, next) {
const { reservation_date,reservation_time } = req.body.data;
const regDate = /^\d{4}\-\d{1,2}\-\d{1,2}$/;
console.log("ReservationDateIsValid: ", reservation_date);
if(!regDate.test(reservation_date)){
next({ status: 400, message: "Must include valid reservation_date (ex. dd/mm/yyyy)." })
}
// No reservations on Tuesdays
const day = new Date(reservation_date).getUTCDay();
if (day === 2) {
next({status: 400, message: "Restaurant is closed on Tuesdays." });
}

// No reservations in the past
const formattedDate = new Date(`${reservation_date}T${reservation_time}`);
if (formattedDate <= new Date()) {
next({status: 400, message: "Reservation must be in the future." } );
}
return next();
}


function reservationTimeIsValid(req, res, next) {
const { reservation_time } = req.body.data;
// const regTime = /^(\d{1,2}):(\d{2})(:00)?([ap]m)?$/;
const regTime = /^(\d{2}):(\d{2})$/;
console.log("ReservationTimeIsValid:", reservation_time);
if(!regTime.test(reservation_time)){
next({ status: 400, message: "Must include valid reservation_time (ex. hh:mm:[ap]m)." })
}

// No reservations before 10:30AM or after 9:30PM
const hours = Number(reservation_time.split(":")[0]);
const minutes = Number(reservation_time.split(":")[1]);
if (hours < 10 || (hours === 10 && minutes < 30)) {
next({status: 400, message: "Reservation must be after 10:30AM." });
}
if (hours > 21 || (hours === 21 && minutes > 30)) {
next({status: 400, message: "Reservation must be before 9:30PM." });
}

return next();
}
function peopleIsValid(req, res, next) {
const { people } = req.body.data;
console.log("peopleIsValid:", people);
// Check if people is not a number
if (!Number.isInteger(people)) {
return next({ status: 400, message: "people must be an integer" });
}

// Check if people is less than 1
if (people < 1) {
return next({ status: 400, message: "Must have 1 or more people ." });
}

// If validation passes
return next();
}


async function create(req, res) {
const newReservation = await reservationsService.create(req.body.data);
console.log("create - New Reservation: ",newReservation);
res.status(201).json({
data: newReservation
});
}

async function list(req, res, next) {
// console.log("req.query: ", req.query);
const date = req.query.date
// console.log("Date: ", date);
const data = await reservationsService.list(date);
// console.log("data: ",data);
res.json({
data: [],
data
});
}

module.exports = {
list,
list: asyncErrorBoundary(list),

create: [ hasData,firstAndLastNameAreValid,mobileNumberIsValid,reservationDateIsValid,reservationTimeIsValid, peopleIsValid, asyncErrorBoundary(create)],
};



13 changes: 10 additions & 3 deletions back-end/src/reservations/reservations.router.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,16 @@
* @type {Router}
*/

const router = require("express").Router();
const router = require("express").Router({ mergeParams: true });
const controller = require("./reservations.controller");
const methodNotAllowed =require("../errors/methodNotAllowed");

router.route("/").get(controller.list);
router.route("/")
.post(controller.create)
.get(controller.list)
.all(methodNotAllowed);



module.exports = router;

module.exports = router;
15 changes: 15 additions & 0 deletions back-end/src/reservations/reservations.service.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
const knex = require("../db/connection");

async function list(date) {
// const reservation_date = date;
return knex("reservations").select("*").where({reservation_date: date} ).orderBy("reservation_time","asc");
// return knex("reservations").select("*");
}

function create(newReservation) {
return knex("reservations").insert(newReservation).returning("*").then((createdRecords) => createdRecords[0]);
}

module.exports = {
list, create
};
1 change: 1 addition & 0 deletions back-end/test/jest.config.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
module.exports = {
setupFiles: ["./jest.setup.js"],
testTimeout: 20000,
};
3 changes: 3 additions & 0 deletions back-end/test/jest.setup.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
const TextEncodingPolyfill = require("text-encoding");
global.TextEncoder = TextEncodingPolyfill.TextEncoder;
global.TextDecoder = TextEncodingPolyfill.TextDecoder;
3 changes: 3 additions & 0 deletions back-end/test/us-01-create-and-list-reservations.test.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// const TextEncodingPolyfill = require("text-encoding");
// global.TextEncoder = TextEncodingPolyfill.TextEncoder;
// global.TextDecoder = TextEncodingPolyfill.TextDecoder;
const request = require("supertest");

const app = require("../src/app");
Expand Down
2 changes: 1 addition & 1 deletion front-end/e2e/jest.config.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module.exports = {
preset: "jest-puppeteer",
testTimeout: 8000,
testTimeout: 12000,
};
2 changes: 1 addition & 1 deletion front-end/e2e/us-01-create-and-list-reservation.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -92,4 +92,4 @@ describe("US-01 - Create and list reservations - E2E", () => {
expect(page.url()).toContain("/dashboard");
});
});
});
});
Loading