diff --git a/locales/en.json b/locales/en.json index 5fcb0ff..20fcab2 100644 --- a/locales/en.json +++ b/locales/en.json @@ -60,7 +60,9 @@ "departmentsManagement": "Departments management", "manageDepartments": "Manage departments", "user": "User", - "permissions": "Permissions" + "permissions": "Permissions", + "firstDate": "First date", + "lastDate": "Last date" }, "firstName": "First name", "lastName": "Last name", diff --git a/locales/fr.json b/locales/fr.json index f16b6de..82ed843 100644 --- a/locales/fr.json +++ b/locales/fr.json @@ -60,7 +60,9 @@ "departmentsManagement": "Gestion des départements", "manageDepartments": "Gérer les départements", "user": "Utilisateur", - "permissions": "Autorisations" + "permissions": "Autorisations", + "firstDate": "Première date", + "lastDate": "Dernière date" }, "firstName": "Prénom", "lastName": "Nom de famille", diff --git a/middlewares/sessionCheck.js b/middlewares/sessionCheck.js index 91551c7..ee9d1a2 100644 --- a/middlewares/sessionCheck.js +++ b/middlewares/sessionCheck.js @@ -7,7 +7,8 @@ function sessionCheck(permission) { req.session.save(() => res.redirect("/login")); } else if (req.session.user.permissions < permission) return error(req, res, "Permission denied !", 403); - next(); + else + next(); } } diff --git a/models/data.js b/models/data.js new file mode 100644 index 0000000..231b32d --- /dev/null +++ b/models/data.js @@ -0,0 +1,24 @@ +"use strict"; +const { + Model +} = require("sequelize"); +module.exports = (sequelize, DataTypes) => { + class Data extends Model { + static associate(models) { + } + } + Data.init({ + key: { + type: DataTypes.STRING, + primaryKey: true + }, + value: { + type: DataTypes.STRING, + allowNull: false + } + }, { + sequelize, + modelName: "Data", + }); + return Data; +}; diff --git a/public/javascripts/index.js b/public/javascripts/index.js index eb9e52a..95d62bd 100644 --- a/public/javascripts/index.js +++ b/public/javascripts/index.js @@ -5,6 +5,7 @@ const locals = { sandwich: document.querySelector("label[for='sandwich1']").innerHTML, day: document.querySelector("label[for='day1']").innerHTML }; +const [min, max] = [document.getElementById("day1").min, document.getElementById("day1").max]; function lastOrderId() { let list = document.querySelectorAll("div.order h2"); @@ -21,7 +22,7 @@ document.getElementById("add-order").addEventListener("click", () => {
- +
`); document.getElementById("order"+lastOrderId()).scrollIntoView({behavior: "smooth"}); diff --git a/routes/admin/orders/date.js b/routes/admin/orders/date.js new file mode 100644 index 0000000..ebd829b --- /dev/null +++ b/routes/admin/orders/date.js @@ -0,0 +1,43 @@ +let express = require("express"); +let router = express.Router(); +let sessionCheck = require("../../../middlewares/sessionCheck"); +let models = require("../../../models"); +let error = require("../../utils/error"); + + +router.get("/", sessionCheck(3), async (req, res) => { + let firstDate = await models.Data.findByPk("firstDate"); + let lastDate = await models.Data.findByPk("lastDate"); + + if ((!firstDate || !firstDate.value) || (!lastDate || !lastDate.value)) + [firstDate, lastDate] = [undefined, undefined]; + + res.render("admin/orders/date", { + title: "SOD - Orders administration", + date: {firstDate: firstDate.value, lastDate: lastDate.value} + }); +}).post("/", sessionCheck(3), async (req, res) => { + if (!req.body.firstDate || ! req.body.lastDate) + return error(req, res, "Fail to set date !", 400, "Missing args"); + + let firstDate = await models.Data.findByPk("firstDate"); + let lastDate = await models.Data.findByPk("lastDate"); + + if (!firstDate) + firstDate = await models.Data.create({key: "firstDate", value: ""}); + if (!lastDate) + lastDate = await models.Data.create({key: "lastDate", value: ""}); + + try { + [firstDate.value, lastDate.value] = [(new Date(req.body.firstDate)).toISOString().substring(0,10), + (new Date(req.body.lastDate)).toISOString().substring(0,10)]; + await firstDate.save(); + await lastDate.save(); + } catch { + return error(req, res, "Fail to set date !", 400, "Invalid date"); + } + + res.redirect("/admin"); +}); + +module.exports = router; diff --git a/routes/admin/orders.js b/routes/admin/orders/index.js similarity index 85% rename from routes/admin/orders.js rename to routes/admin/orders/index.js index 0b9bb8e..096d51e 100644 --- a/routes/admin/orders.js +++ b/routes/admin/orders/index.js @@ -1,8 +1,8 @@ let express = require("express"); let router = express.Router(); -let sessionCheck = require("../../middlewares/sessionCheck"); -let models = require("../../models"); -let error = require("../utils/error"); +let sessionCheck = require("../../../middlewares/sessionCheck"); +let models = require("../../../models"); +let error = require("../../utils/error"); router.get("/", sessionCheck(3), async (req, res) => { @@ -33,6 +33,7 @@ router.get("/", sessionCheck(3), async (req, res) => { error(req, res, "Fail to remove sandwich !"); throw e; } -}); +}) + .use("/date", require("./date")); module.exports = router; diff --git a/routes/index.js b/routes/index.js index 8d3f130..902d16b 100644 --- a/routes/index.js +++ b/routes/index.js @@ -3,9 +3,27 @@ let router = express.Router(); let models = require("../models"); router.get("/", async (req, res) => { - let departments = await models.Department.findAll(); - let sandwiches = await models.Sandwich.findAll(); - res.render("index", { title: "SOD - Home", departments: departments, sandwiches: sandwiches }); + let now = new Date(); + let firstDate = await models.Data.findByPk("firstDate"); + + if (firstDate && firstDate.value) { + firstDate = new Date(firstDate.value); + if (firstDate.getTime() < now.getTime()) + firstDate = now; + } else + firstDate = now; + + firstDate = firstDate.toISOString().substring(0, 10); + + res.render("index", { + title: "SOD - Home", + departments: await models.Department.findAll(), + sandwiches: await models.Sandwich.findAll(), + date: { + firstDate: firstDate, + lastDate: await models.Data.findByPk("lastDate") + } + }); }); module.exports = router; diff --git a/routes/order.js b/routes/order.js index 0167540..ed96e59 100644 --- a/routes/order.js +++ b/routes/order.js @@ -22,7 +22,31 @@ router.post("/", async (req, res) => { if (!sandwich) return error(req, res, "Invalid order !", 400, "Invalid sandwich: "+req.body["sandwich" + i]); - sandwiches.push([sandwich.name, req.body["date" + i]]); + let date = new Date(req.body["date" + i]); + let firstDate, lastDate; + + [firstDate, lastDate] = [await models.Data.findByPk("firstDate"), + await models.Data.findByPk("lastDate")]; + + let now = new Date(); + now.setUTCHours(0,0,0,0); + + if (firstDate && firstDate.value && lastDate && lastDate.value) { + [firstDate, lastDate] = [new Date(firstDate.value), new Date(lastDate.value)]; + firstDate.setUTCHours(0,0,0,0); + lastDate.setUTCHours(0,0,0,0); + + if (now.getTime() > date.getTime() || + firstDate.getTime() > date.getTime() || + lastDate.getTime() < date.getTime()) + return error(req, res, "Invalid order !", 400, "Date not available"); + } + + try { + sandwiches.push([sandwich.name, date.toISOString().substring(0, 10)]); + } catch { + return error(req, res, "Invalid order !", 400, "Invalid date"); + } price += sandwich.price; } @@ -40,7 +64,7 @@ router.post("/", async (req, res) => { await models.SandwichOrder.create({OrderId: order.id, SandwichName: data[0], date: data[1]}); } catch (e) { await order.destroy(); - error(req, res, "Invalid order !", 400, "Invalid date"); + error(req, res, "Invalid order !", 500); throw e; } res.send("Ok"); diff --git a/views/admin/orders/date.pug b/views/admin/orders/date.pug new file mode 100644 index 0000000..9b9b45f --- /dev/null +++ b/views/admin/orders/date.pug @@ -0,0 +1,14 @@ +extends ../../layout + +block content + div.card#ordersManagement + h1=__("admin.ordersDate") + form(action="/admin/orders/date" method="POST") + div.field + label(for="firstDate")=__("admin.firstDate") + input#firstDate(type="date" name="firstDate" value=date? date.firstDate: "" required) + div.field + label(for="lastDate")=__("admin.lastDate") + input#lastDate(type="date" name="lastDate" value=date? date.lastDate: "" required) + div.field + input(type="submit" value=__("save")) diff --git a/views/admin/orders.pug b/views/admin/orders/index.pug similarity index 97% rename from views/admin/orders.pug rename to views/admin/orders/index.pug index 6b04be8..d3f645c 100644 --- a/views/admin/orders.pug +++ b/views/admin/orders/index.pug @@ -1,4 +1,4 @@ -extends ../layout +extends ../../layout block content div.card#ordersManagement diff --git a/views/index.pug b/views/index.pug index ef2aac7..352aea7 100644 --- a/views/index.pug +++ b/views/index.pug @@ -26,7 +26,7 @@ block content input#sandwich1(type="list" list="sandwich-list" name="sandwich1" autocomplete="off" required) div.field label(for="day1")=__("index.day")+":" - input#day1(type="date" name="date1" required) + input#day1(type="date" min=date ? date.firstDate : "" max=date ? date.lastDate.value : "" name="date1" required) div#order-action a#add-order +