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
4 changes: 2 additions & 2 deletions api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
"npm": "^10.5.0"
},
"scripts": {
"dev": "nodemon src/index.mjs",
"start": "node src/index.mjs",
"dev": "nodemon src/index.js",
"start": "node src/index.js",
"format": "npx prettier . --write",
"check": "npx eslint . --fix"
},
Expand Down
52 changes: 52 additions & 0 deletions api/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,54 @@ import cors from "cors";
import bodyParser from "body-parser";
import knex from "./database_client.js";
import nestedRouter from "./routers/nested.js";
import mealsRouter from "./routers/meals.js";
import reservationsRouter from "./routers/reservations.js";
import reviewsRouter from "./routers/reviews.js";

const app = express();
app.use(cors());
app.use(bodyParser.json());

const apiRouter = express.Router();

//Future meals
apiRouter.get("/future-meals", async (req, res) => {
const meals = await knex("meal").select("*").where("when", ">", new Date());
res.json({ meals });
});

//Past meals
apiRouter.get("/past-meals", async (req, res) => {
const meals = await knex("meal").select("*").where("when", "<", new Date());
res.json({ meals });
});

//All meals sorted by ID
apiRouter.get("/all-meals", async (req, res) => {
const meals = await knex("meal").select("*").orderBy("id");
res.json({ meals });
});


//first meal
apiRouter.get("/first-meal", async (req, res) => {
const meal = await knex("meal").select("*").orderBy("id").first();
if (!meal) {
return res.status(404).json({ message: "No meals found" });
}
res.json({ meal });
});

//last meal
apiRouter.get("/last-meal", async (req, res) => {
const meal = await knex("meal").select("*").orderBy("id", "desc").first();
if (!meal) {
return res.status(404).json({ message: "No meals found" });
}
res.json({ meal });
});


// You can delete this route once you add your own routes
apiRouter.get("/", async (req, res) => {
const SHOW_TABLES_QUERY =
Expand All @@ -24,6 +65,17 @@ apiRouter.get("/", async (req, res) => {
// This nested router example can also be replaced with your own sub-router
apiRouter.use("/nested", nestedRouter);


//Sub-router for meals
apiRouter.use("/meals", mealsRouter);

//Sub-router for reservations
apiRouter.use("/reservations", reservationsRouter);

//sub-router for reviews
apiRouter.use("/reviews", reviewsRouter);


app.use("/api", apiRouter);

app.listen(process.env.PORT, () => {
Expand Down
146 changes: 146 additions & 0 deletions api/src/routers/meals.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
import express from "express";
import knex from "../database_client.js";
import bodyParser from "body-parser";

const mealsRouter = express.Router();

mealsRouter.use(express.json());
mealsRouter.use(bodyParser.json());
mealsRouter.use(bodyParser.urlencoded({ extended: true }));

// Get all meals
mealsRouter.get("/", async (req, res) => {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hell yeah!

let query = knex("meal");

const { maxPrice, availableReservations, title, dateAfter, dateBefore, limit, sortKey, sortDir } = req.query;

try {
if (maxPrice) {
query = query.where("price", "<=", maxPrice);
}

if (title) {
query = query.where("title", "like", `%${title}%`);
}

if (dateAfter) {
query = query.where("when", ">=", dateAfter);
}

if (dateBefore) {
query = query.where("when", "<=", dateBefore);
}

if (availableReservations) {
if (availableReservations === "true") {
query = query.whereExists(
knex("reservation")
.select("meal_id")
.whereRaw("meal.id = reservation.meal_id")
.groupBy("reservation.meal_id")
.havingRaw("meal.max_reservations > COUNT(reservation.id)")
);
} else {
query = query.whereNotExists(
knex("reservation")
.select("meal_id")
.whereRaw("meal.id = reservation.meal_id")
.groupBy("reservation.meal_id")
.havingRaw("meal.max_reservations > COUNT(reservation.id)")
);
}
}

if (sortKey && ["when", "max_reservations", "price"].includes(sortKey)) {
query = query.orderBy(sortKey, sortDir === "desc" ? "desc" : "asc");
}

if (limit) {
query = query.limit(Number(limit));
}

const meals = await query;
res.json({ meals });
} catch (error) {
console.error("Error fetching meals:", error);
res.status(500).json({ message: "Error fetching meals" });
}
});


//Adds a new meal to the database
mealsRouter.post("/", async (req, res) => {
const { title, description, location, when, max_reservations, price, created_date } = req.body;
if (!title || !description || !when || !max_reservations || !price || !created_date) {
return res.status(400).json({ message: "Please provide all fields" });
}
try {
// Insert the new meal
const insertQuery = `
INSERT INTO meal (title, description, location, when, max_reservations, price, created_date)
VALUES (?, ?, ?, ?, ?, ?, ?)
`;

await knex.raw(insertQuery, [title, description, location, when, max_reservations, price, created_date]);

// Get the ID of the last inserted record using LAST_INSERT_ID()
const result = await knex.raw('SELECT LAST_INSERT_ID() AS meal_id');
const mealId = result[0][0].meal_id;

// Retrieve the inserted meal using the mealId
const meal = await knex.raw('SELECT * FROM meal WHERE id = ?', [mealId]);


return res.status(201).json({ meal });
} catch (error) {
console.error("Error inserting meal:", error);
return res.status(500).json({ message: "Error adding meal" });
}
}
);

//get meal by id
mealsRouter.get("/:id", async (req, res) => {
const { id } = req.params;
const meal = await knex.raw("SELECT * FROM meal WHERE id = ?", [id]);
if (meal[0].length === 0) {
return res.status(404).json({ message: "Meal not found" });
}
res.json({ meal: meal[0][0] });
});

// update the meal by id
mealsRouter.put("/:id", async (req, res) => {
const { id } = req.params;
const { title, description, location, when, max_reservations, price, created_date } = req.body;
if (!title || !description || !when || !max_reservations || !price || !created_date) {
return res.status(400).json({ message: "Please provide all fields" });
}
try {
const updateQuery = `
UPDATE meal
SET title = ?, description = ?, location = ?, when = ?, max_reservations = ?, price = ?, created_date = ?
WHERE id = ?
`;
await knex.raw(updateQuery, [title, description, location, when, max_reservations, price, created_date, id]);
const meal = await knex.raw("SELECT * FROM meal WHERE id = ?", [id]);
res.json({ meal: meal[0][0] });
} catch (error) {
console.error("Error updating meal:", error);
return res.status(500).json({ message: "Error updating meal" });
}
});

//delete meal by id
mealsRouter.delete("/:id", async (req, res) => {
const { id } = req.params;
const meal = await knex.raw("SELECT * FROM meal WHERE id = ?", [id]);
if (meal[0].length === 0) {
return res.status(404).json({ message: "Meal not found" });
}
await knex.raw("DELETE FROM meal WHERE id = ?", [id]);
res.json({ message: "Meal deleted" });
});


export default mealsRouter;
112 changes: 112 additions & 0 deletions api/src/routers/reservations.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
import express from "express";
import knex from "../database_client.js";
import bodyParser from "body-parser";


const reservationsRouter = express.Router();
reservationsRouter.use(express.json());
reservationsRouter.use(bodyParser.json());
reservationsRouter.use(bodyParser.urlencoded({ extended: true }));

// Get all reservations
reservationsRouter.get("/", async (req, res) => {
const reservations = await knex.select("*").from("reservation");
res.json({ reservations });
});

//Adds a new reservation to the database
reservationsRouter.post("/", async (req, res) => {
const { number_of_guests, meal_id, contact_phone_number, contact_name, contact_email } = req.body;

if (!number_of_guests || !meal_id || !contact_phone_number || !contact_name || !contact_email) {
return res.status(400).json({ message: "Please provide all fields" });
}
try {
const created_date = new Date().toISOString().slice(0, 10);
// Insert the new reservation
const [reservation] = await knex('reservation')
.insert({
number_of_guests,
meal_id,
contact_phone_number,
contact_name,
contact_email,
created_date
})
.returning('*');

return res.status(201).json({ reservation });

} catch (error) {
console.error("Error inserting reservation:", error);
return res.status(500).json({ message: "Error adding reservation" });
}

});


//get reservation by id
reservationsRouter.get("/:id", async (req, res) => {
const { id } = req.params;
const reservation = await knex('reservation').where({ id });
if (reservation.length === 0) {
return res.status(404).json({ message: "Reservation not found" });
}
res.json({ reservation: reservation[0] });
});

// update the reservation by id
reservationsRouter.put("/:id", async (req, res) => {
const { id } = req.params;
const { number_of_guests, meal_id, contact_phone_number, contact_name, contact_email } = req.body;

if (!number_of_guests || !meal_id || !contact_phone_number || !contact_name || !contact_email) {
return res.status(400).json({ message: "Please provide all fields" });
}

try {
const updated_date = new Date().toISOString().slice(0, 10);
// Update the reservation
const [reservation] = await knex('reservation')
.where({ id })
.update({
number_of_guests,
meal_id,
contact_phone_number,
contact_name,
contact_email,
updated_date
})
.returning('*');

res.json({ reservation });

} catch (error) {
console.error("Error updating reservation:", error);
return res.status(500).json({ message: "Error updating reservation" });
}
});

//delete reservation by id
reservationsRouter.delete("/:id", async (req, res) => {
const { id } = req.params;
try {
const reservation = await knex('reservation').where({ id }).first();

if (!reservation) {
return res.status(404).json({ message: "Reservation not found" });
}

await knex('reservation').where({ id }).del();
res.json({ message: "Reservation deleted successfully" });

} catch (error) {
console.error("Error deleting reservation:", error);
res.status(500).json({ message: "Error deleting reservation" });
}
});




export default reservationsRouter;
Loading