From 61a8d484e6323641173561ae63210a88d0283bf7 Mon Sep 17 00:00:00 2001 From: Sebastian Seedorf Date: Fri, 25 Mar 2016 17:09:03 +0100 Subject: [PATCH] =?UTF-8?q?Men=C3=BC-Verwaltung=20in=20externe=20Datei=20v?= =?UTF-8?q?erschoben=20und=20User-Input-Save=20gemacht?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- data/menu.json | 568 +++++++++++++++++++++++------------------------ main.js | 104 ++++----- modules/login.js | 1 + modules/menu.js | 159 +++++++++++++ views/menu.jade | 2 +- 5 files changed, 494 insertions(+), 340 deletions(-) create mode 100644 modules/menu.js diff --git a/data/menu.json b/data/menu.json index 75e6738..046a19f 100644 --- a/data/menu.json +++ b/data/menu.json @@ -1,286 +1,286 @@ { - "food": [ - { - "name": "Vorspeisen", - "anchor": "vorspeise", - "items": [ - { - "name": "Reis-alat", - "price": 5.50, - "desc": "Frischer Blattsalat mit Basmati-Reis und würzigem Balsamico" - }, - { - "name": "Chinesisches Bauernfrühstück", - "price": 6.40, - "desc": "Feuriges Chili in gedämpftem, kaltem Reis mit heißem Gemüse" - }, - { - "name": "Thailändisches Arbeiterfrühstück", - "price": 7.40, - "desc": "Feuriges Chili in gedämpftem, kaltem Reis mit heißem Gemüse und Hähnchen" - }, - { - "name": "Viatnamesisches Denkerfrühstück", - "price": 7.90, - "desc": "Feuriges Chili in gedämpftem, kaltem Reis mit heißem Gemüse und Ente" - }, - { - "name": "90er-Reis-Plattenscheibe", - "price": 51.90, - "desc": "Für Retrofreunde die seltene Platte \"Blue Eyes\" von \"Brooky Ryes\" bestückt mit 5 verschiedenen Reissorten dazu etwas Gemüse in Vinyl-Optik" - } - ] - }, - { - "name": "Suppen", - "anchor": "suppe", - "items": [ - { - "name": "Reis-uppe", - "price": 3.90, - "desc": "Köstliche, klare Hühnerbrühe mit einem Schuss Soja und Reis" - }, - { - "name": "Tomatensuppe", - "price": 4.20, - "desc": "Cremige Tomatensuppe mit frischen Tomaten, Rahm und Reis sowie einer leckeren Petersilie als Dekör" - }, - { - "name": "Üppige Suppe", - "price": 2.20, - "desc": "Üppige Suppe mit üppigem Gemüse gewuppt mit zerruppten Gestrüpp" - }, - { - "name": "Henker's Mahlzeit", - "price": 6.80, - "desc": "Roter Reis mit scharfem Chili mit tomaten und roter Paprika" - }, - { - "name": "Nudelsuppe", - "price": 3.30, - "desc": "Leissuppe mit liesigel Poltion klingliger Knödel" - } - ] - }, - { - "name": "Hauptspeisen", - "anchor": "hauptspeise", - "items": [ - { - "name": "Grillplatte \"China\"", - "price": 11.20, - "desc": "Ein großes, paniertes Schnitzel in Form des Landes china dazu Tibet-formender Reis, Ente im Pazifik und Kähnchen als Peking geformt" - }, - { - "name": "Reis mit Reis", - "price": 14.80, - "desc": "Reis mit Reis dazu Reis als Beilage in Kombination mit Reis und Reis" - }, - { - "name": "O'jeh-gerl-schnitzel", - "price": 13.50, - "desc": "Deutsches Jägerschnitzel nach Art des Hauses mit Reis als Beilage" - }, - { - "name": "RisiBisi", - "price": 17.30, - "desc": "Lila Reis aus kontrolliertem Bio-Anbau mit knallgrünen erbsen, orangene Paprika und gelber Mais als Beilage mit sauerstoffarmem, blauem Schweinefleisch von glücklichen Tieren" - }, - { - "name": "Burger Duck", - "price": 14.20, - "desc": "Saftiger Burger mit aufregenden Gewürzen, Gewürzgurken, Gurken, Tomaten, BBQ-Sauce und knusprig überbackenem Entenfleisch, dazu Reis" - }, - { - "name": "Money Boy", - "price": 95.90, - "desc": "Goldfarbener Reis mit mit in Gold überzogener Hähnchenbrust in Champagner-Soße dazu goldfarbenes Brot aus Provìnce de uberteuereé" - }, - { - "name": "Reis-otto", - "price": 11.60, - "desc": "Risotto mit Brokkoli und Schinken, dazu etwas Parmesan und Thymian" - } - ] - }, - { - "name": "Junior-Reisesser", - "anchor": "junior", - "items": [ - { - "name": "\"Chinesischer Seeräuber\"-Teller", - "price": 0, - "desc": "Ein Messer, eine Gabel, ein Teller und nur eine Aufgabe: Das Essen des Nachbars! (auf Wunsch mit Seeräuber-Hut)" - }, - { - "name": "Käpt'n Reisbart", - "price": 7.70, - "desc": "Süß-Sauer-Soße mit Hähnchenschiffchen in Reis gebadet" - }, - { - "name": "Spagetti Reisonese", - "price": 5.60, - "desc": "Spaghetti mit Tomatensoße und Reis" - } - ] - }, - { - "name": "Desserts", - "anchor": "dessert", - "items": [ - { - "name": "Milchreis", - "price": 6.30, - "desc": "Leckerer Milchreis aus der Tüte vom Großhändler mit heißen Sauerkirschen aus der Konservenbüchse" - }, - { - "name": "R-Eis", - "price": 4.10, - "desc": "Gemischtes Eis mit Kokos-reis-Streumaterial; 3 Kugeln nach Wahl" - }, - { - "name": "Eierreiskuchen", - "price": 5.00, - "desc": "2 köstliche Palatschinken (regional auch Eierkuchen genannt) mit im Teig eingearbeitetetem Reis, dazu feinster Powidl (regional auch Pflaumenmuß) genannt" - }, - { - "name": "Süßes Reisotto", - "price": 8.70, - "desc": "Reis mit bunten Früchten und viel Joghurt, angerichtet mit etweas Zimt und einem Schuss Honig" - }, - { - "name": "Reisstrudel", - "price": 5.60, - "desc": "In Blätterteil gewickelter Reis mit Milchcreme und Minze, dazu Vanillesoße und eine Kugel Vanilleeis" - } - ] - } - ], - "drinks": [ - { - "name": "Auf Art des Hauses", - "anchor": "haus", - "items": [ - { - "name": "Reiswein", - "price": 3.90, - "desc": "Exquisiter Reiswein mit leiter gelblicher Färbung aus eigener Herstellung mit über 1337 Jahren Erfahrung (Alkoholgehalt 13,37%)" - }, - { - "name": "Reisschnaps", - "price": 2.10, - "desc": "Starker Reisschnaps als Absacker geeignet mit feiner Süße im Abgang (Alkoholgehalt 69%)" - }, - { - "name": "Reisbier", - "price": 3.50, - "desc": "Aus der Reispflanze gewonnenes Bier mit Hopfen nach chinesischem Reinheitsgebot (Alkoholgehalt 4,2%)" - }, - { - "name": "Reissud", - "price": 1.20, - "desc": "Heißer beim Reis kochen entstandener Sud; alkoholfrei, warm und jedes Mal je nach Reissorte ein individueller, neuer Geschmack" - } - ] - }, - { - "name": "Alkoholfrei", - "anchor": "alkoholfrei", - "items": [ - { - "name": "Softdrinks (0,5l)", - "price": 3.40, - "desc": "Verschidene Sorten nur diesen Framstag im Angebot!" - }, - { - "name": "Softdrinks (0,3l)", - "price": 2.90, - "desc": "Verschidene Sorten nur diesen Framstag im Angebot!" - }, - { - "name": "Wasser (1l)", - "price": 4.10, - "desc": "Das Wasser trüb, die Luft ist rein, Franz-Josef muss ertrunken sein." - } - ] - }, - { - "name": "Alkohol", - "anchor": "alkohol", - "items": [ - { - "name": "Bier vom Fass (0,5l)", - "price": 3.50, - "desc": "Wählen sie zwischen Becks, Sternburg und Berliner Kindl" - }, - { - "name": "Bier vom Fass (0,3l)", - "price": 3.00, - "desc": "Wählen sie zwischen Becks, Sternburg und Berliner Kindl" - }, - { - "name": "Chinesisches Bier (0,69l)", - "price": 2.40, - "desc": "Tsingtao-Exportbier" - }, - { - "name": "Chinesisches Bier (0,42l)", - "price": 1.90, - "desc": "Tsingtao-Exportbier" - }, - { - "name": "Rislinger Wein (0,2l)", - "price": 4.20, - "desc": "Asiatischer Wein mit unbekanntem Ursprung aus gezüchteten, von Monsanto genmanipulierten Weintrauben" - }, - { - "name": "Radler (0,5l)", - "price": 13.20, - "desc": "Für echte Vampire" - } - ] - }, - { - "name": "Spriritus", - "anchor": "spirituose", - "items": [ - { - "name": "Asiatische Freude", - "price": 1.50, - "desc": "Auf 45 Grad erwärmter Reisschnaps mit Raucharoma für natürliches Pekinger Stadtklima" - }, - { - "name": "Sprit-Tussi", - "price": 1.60, - "desc": "Diesel (Cola-Bier-Gemisch) in einem 0,1cl-Glas, um es teurer verkaufen zu können" - } - ] - }, - { - "name": "Cocktails", - "anchor": "cocktails", - "items": [ - { - "name": "Beste Freundschaft", - "price": 9.30, - "desc": "Lila Livo-Liva mit weißem Rohrzucker und Limettensaft mit frischer, grüner Limette" - }, - { - "name": "Schwanz-Schwanz", - "price": 5.60, - "desc": "Ausgefuchste Kombination von Schwanz und Schwanz des Hans und Franz" - }, - { - "name": "Der Reisende", - "price": 8.90, - "desc": "Du schmeckst eh nichts anderes mehr, so viel Alk ist hier drin, und nach einem davon reist du durch die ganze Welt (zumindest im Kopf)" - }, - { - "name": "Pina Reisolada", - "price": 6.10, - "desc": "Mit Ananas und Kokos aufgemixte Mixtur in Reisschaum, mit Reisschnaps und fast dem ganzen Glas voller Eis" - } - ] - } - ] + "food": [ + { + "name": "Vorspeisen", + "anchor": "vorspeise", + "items": [ + { + "name": "Reis-alat", + "price": 5.5, + "desc": "Frischer Blattsalat mit Basmati-Reis und würzigem Balsamico" + }, + { + "name": "Chinesisches Bauernfrühstück", + "price": 6.4, + "desc": "Feuriges Chili in gedämpftem, kaltem Reis mit heißem Gemüse" + }, + { + "name": "Thailändisches Arbeiterfrühstück", + "price": 7.4, + "desc": "Feuriges Chili in gedämpftem, kaltem Reis mit heißem Gemüse und Hähnchen" + }, + { + "name": "Viatnamesisches Denkerfrühstück", + "price": 7.9, + "desc": "Feuriges Chili in gedämpftem, kaltem Reis mit heißem Gemüse und Ente" + }, + { + "name": "90er-Reis-Plattenscheibe", + "price": 51.9, + "desc": "Für Retrofreunde die seltene Platte \"Blue Eyes\" von \"Brooky Ryes\" bestückt mit 5 verschiedenen Reissorten dazu etwas Gemüse in Vinyl-Optik" + } + ] + }, + { + "name": "Suppen", + "anchor": "suppe", + "items": [ + { + "name": "Reis-uppe", + "price": 3.9, + "desc": "Köstliche, klare Hühnerbrühe mit einem Schuss Soja und Reis" + }, + { + "name": "Tomatensuppe", + "price": 4.2, + "desc": "Cremige Tomatensuppe mit frischen Tomaten, Rahm und Reis sowie einer leckeren Petersilie als Dekör" + }, + { + "name": "Üppige Suppe", + "price": 2.2, + "desc": "Üppige Suppe mit üppigem Gemüse gewuppt mit zerruppten Gestrüpp" + }, + { + "name": "Henker's Mahlzeit", + "price": 6.8, + "desc": "Roter Reis mit scharfem Chili mit tomaten und roter Paprika" + }, + { + "name": "Nudelsuppe", + "price": 3.3, + "desc": "Leissuppe mit liesigel Poltion klingliger Knödel" + } + ] + }, + { + "name": "Hauptspeisen", + "anchor": "hauptspeise", + "items": [ + { + "name": "Grillplatte \"China\"", + "price": 11.2, + "desc": "Ein großes, paniertes Schnitzel in Form des Landes china dazu Tibet-formender Reis, Ente im Pazifik und Kähnchen als Peking geformt" + }, + { + "name": "Reis mit Reis", + "price": 14.8, + "desc": "Reis mit Reis dazu Reis als Beilage in Kombination mit Reis und Reis" + }, + { + "name": "O'jeh-gerl-schnitzel", + "price": 13.5, + "desc": "Deutsches Jägerschnitzel nach Art des Hauses mit Reis als Beilage" + }, + { + "name": "RisiBisi", + "price": 17.3, + "desc": "Lila Reis aus kontrolliertem Bio-Anbau mit knallgrünen erbsen, orangene Paprika und gelber Mais als Beilage mit sauerstoffarmem, blauem Schweinefleisch von glücklichen Tieren" + }, + { + "name": "Burger Duck", + "price": 14.2, + "desc": "Saftiger Burger mit aufregenden Gewürzen, Gewürzgurken, Gurken, Tomaten, BBQ-Sauce und knusprig überbackenem Entenfleisch, dazu Reis" + }, + { + "name": "Money Boy", + "price": 95.9, + "desc": "Goldfarbener Reis mit mit in Gold überzogener Hähnchenbrust in Champagner-Soße dazu goldfarbenes Brot aus Provìnce de uberteuereé" + }, + { + "name": "Reis-otto", + "price": 11.6, + "desc": "Risotto mit Brokkoli und Schinken, dazu etwas Parmesan und Thymian" + } + ] + }, + { + "name": "Junior-Reisesser", + "anchor": "junior", + "items": [ + { + "name": "\"Chinesischer Seeräuber\"-Teller", + "price": 0, + "desc": "Ein Messer, eine Gabel, ein Teller und nur eine Aufgabe: Das Essen des Nachbars! (auf Wunsch mit Seeräuber-Hut)" + }, + { + "name": "Käpt'n Reisbart", + "price": 7.7, + "desc": "Süß-Sauer-Soße mit Hähnchenschiffchen in Reis gebadet" + }, + { + "name": "Spagetti Reisonese", + "price": 5.6, + "desc": "Spaghetti mit Tomatensoße und Reis" + } + ] + }, + { + "name": "Desserts", + "anchor": "dessert", + "items": [ + { + "name": "Milchreis", + "price": 6.3, + "desc": "Leckerer Milchreis aus der Tüte vom Großhändler mit heißen Sauerkirschen aus der Konservenbüchse" + }, + { + "name": "R-Eis", + "price": 4.1, + "desc": "Gemischtes Eis mit Kokos-reis-Streumaterial; 3 Kugeln nach Wahl" + }, + { + "name": "Eierreiskuchen", + "price": 5, + "desc": "2 köstliche Palatschinken (regional auch Eierkuchen genannt) mit im Teig eingearbeitetetem Reis, dazu feinster Powidl (regional auch Pflaumenmuß) genannt" + }, + { + "name": "Süßes Reisotto", + "price": 8.7, + "desc": "Reis mit bunten Früchten und viel Joghurt, angerichtet mit etweas Zimt und einem Schuss Honig" + }, + { + "name": "Reisstrudel", + "price": 5.6, + "desc": "In Blätterteil gewickelter Reis mit Milchcreme und Minze, dazu Vanillesoße und eine Kugel Vanilleeis" + } + ] + } + ], + "drinks": [ + { + "name": "Auf Art des Hauses", + "anchor": "haus", + "items": [ + { + "name": "Reiswein", + "price": 3.9, + "desc": "Exquisiter Reiswein mit leiter gelblicher Färbung aus eigener Herstellung mit über 1337 Jahren Erfahrung (Alkoholgehalt 13,37%)" + }, + { + "name": "Reisschnaps", + "price": 2.1, + "desc": "Starker Reisschnaps als Absacker geeignet mit feiner Süße im Abgang (Alkoholgehalt 69%)" + }, + { + "name": "Reisbier", + "price": 3.5, + "desc": "Aus der Reispflanze gewonnenes Bier mit Hopfen nach chinesischem Reinheitsgebot (Alkoholgehalt 4,2%)" + }, + { + "name": "Reissud", + "price": 1.2, + "desc": "Heißer beim Reis kochen entstandener Sud; alkoholfrei, warm und jedes Mal je nach Reissorte ein individueller, neuer Geschmack" + } + ] + }, + { + "name": "Alkoholfrei", + "anchor": "alkoholfrei", + "items": [ + { + "name": "Softdrinks (0,5l)", + "price": 3.4, + "desc": "Verschidene Sorten nur diesen Framstag im Angebot!" + }, + { + "name": "Softdrinks (0,3l)", + "price": 2.9, + "desc": "Verschidene Sorten nur diesen Framstag im Angebot!" + }, + { + "name": "Wasser (1l)", + "price": 4.1, + "desc": "Das Wasser trüb, die Luft ist rein, Franz-Josef muss ertrunken sein." + } + ] + }, + { + "name": "Alkohol", + "anchor": "alkohol", + "items": [ + { + "name": "Bier vom Fass (0,5l)", + "price": 3.5, + "desc": "Wählen sie zwischen Becks, Sternburg und Berliner Kindl" + }, + { + "name": "Bier vom Fass (0,3l)", + "price": 3, + "desc": "Wählen sie zwischen Becks, Sternburg und Berliner Kindl" + }, + { + "name": "Chinesisches Bier (0,69l)", + "price": 2.4, + "desc": "Tsingtao-Exportbier" + }, + { + "name": "Chinesisches Bier (0,42l)", + "price": 1.9, + "desc": "Tsingtao-Exportbier" + }, + { + "name": "Rislinger Wein (0,2l)", + "price": 4.2, + "desc": "Asiatischer Wein mit unbekanntem Ursprung aus gezüchteten, von Monsanto genmanipulierten Weintrauben" + }, + { + "name": "Radler (0,5l)", + "price": 13.2, + "desc": "Für echte Vampire" + } + ] + }, + { + "name": "Spriritus", + "anchor": "spirituose", + "items": [ + { + "name": "Asiatische Freude", + "price": 1.5, + "desc": "Auf 45 Grad erwärmter Reisschnaps mit Raucharoma für natürliches Pekinger Stadtklima" + }, + { + "name": "Sprit-Tussi", + "price": 1.6, + "desc": "Diesel (Cola-Bier-Gemisch) in einem 0,1cl-Glas, um es teurer verkaufen zu können" + } + ] + }, + { + "name": "Cocktails", + "anchor": "cocktails", + "items": [ + { + "name": "Beste Freundschaft", + "price": 9.3, + "desc": "Lila Livo-Liva mit weißem Rohrzucker und Limettensaft mit frischer, grüner Limette" + }, + { + "name": "Schwanz-Schwanz", + "price": 5.6, + "desc": "Ausgefuchste Kombination von Schwanz und Schwanz des Hans und Franz" + }, + { + "name": "Der Reisende", + "price": 8.9, + "desc": "Du schmeckst eh nichts anderes mehr, so viel Alk ist hier drin, und nach einem davon reist du durch die ganze Welt (zumindest im Kopf)" + }, + { + "name": "Pina Reisolada", + "price": 6.1, + "desc": "Mit Ananas und Kokos aufgemixte Mixtur in Reisschaum, mit Reisschnaps und fast dem ganzen Glas voller Eis" + } + ] + } + ] } \ No newline at end of file diff --git a/main.js b/main.js index 2b2f7fe..5cb5c1b 100644 --- a/main.js +++ b/main.js @@ -3,17 +3,30 @@ var jade = require('jade'); var bodyParser = require('body-parser'); var session = require('express-session'); var loginMod = require('./modules/login'); -var path = require('path'); +var menuMod = require('./modules/menu'); +//var path = require('path'); var fs = require('fs'); -var menuJSON; - var app = express(); + + + +// ************************** +// APP VARS +// ************************** + app.set('view engine', 'jade'); app.set('rundir', '.'); app.set('views', app.get('rundir') + '/views'); + + + +// ************************** +// MIDDLEWARE +// ************************** + app.use(session({ secret: 'Jk0Z850cD2MXkcIRXDg1M4X6c1VKkJTb6VYQfbWUKw2XwqaBmqqaKu7K0Q8WlGZVqupF2fzXaavt1hNf', resave: true, @@ -26,16 +39,27 @@ app.use(bodyParser.urlencoded({ app.use('/bin', express.static(app.get('rundir') + '/public')); -fs.readFile(app.get('rundir') + '/data/menu.json', 'utf8', function (err, data) { - if (err) throw err; - menuJSON = JSON.parse(data); -}); + + + +// ************************** +// INIT +// ************************** + +menuMod.init(app.get('rundir') + '/data/menu.json'); + + + + +// ************************** +// ROUTES +// ************************** app.get('/', function(req, res) { res.render('index', { title: 'Restaurant Reiskorn | Home', loginName: loginMod.getName(req), - menuJSON: menuJSON + menuJSON: menuMod.getJSON() }); }); @@ -44,71 +68,41 @@ app.get('/speisekarte', function(req, res) { title: 'Restaurant Reiskorn | Speisekarte', loginName: loginMod.getName(req), isAdmin: loginMod.hasAccess(req, loginMod.AdminRight.MENU), - menuJSON: menuJSON + menuJSON: menuMod.getJSON() }); }); app.post('/speisekarte', function(req, res) { - var del = req.body.del; - var item = req.body.nametag; + var nametag = req.body.nametag; var name = req.body.name; var desc = req.body.desc; var price = req.body.price; - if (item && /^[fd]-[0-9]+-new$/.test(item)) { // new - var splitArr = item.split("-"); - if (splitArr[0] == "f") { - splitArr[0] = "food"; - } else { - splitArr[0] = "drinks"; - } - price = parseInt(price); - menuJSON[splitArr[0]][parseInt(splitArr[1])]["items"].push({ - name: name, - desc: desc, - price: price - }); - } else if (item && /^[fd]-[0-9]+-[0-9]+$/.test(item)) { // edit - var splitArr = item.split("-"); - if (splitArr[0] == "f") { - splitArr[0] = "food"; - } else { - splitArr[0] = "drinks"; - } - price = parseInt(price); - menuJSON[splitArr[0]][parseInt(splitArr[1])]["items"][parseInt(splitArr[2])] = { - name: name, - desc: desc, - price: price - }; - } else if (del && /^[fd]-[0-9]+-[0-9]+$/.test(del)) { // delete - var splitArr = del.split("-"); - if (splitArr[0] == "f") { - splitArr[0] = "food"; - } else { - splitArr[0] = "drinks"; - } - menuJSON[splitArr[0]][parseInt(splitArr[1])]["items"].splice(parseInt(splitArr[2]), 1); + + if (loginMod.hasAccess(req, loginMod.AdminRight.MENU)) { + var action = menuMod.determineAction(nametag); + var error = 0; + if (action == menuMod.MenuAction.CREATE) + error = menuMod.addValue(name, desc, price, nametag); + else if (action == menuMod.MenuAction.UPDATE) + error = menuMod.updateValue(name, desc, price, nametag); + else if (action == menuMod.MenuAction.DELETE) + error = menuMod.deleteValue(nametag); + console.log(error); } res.render('menu', { title: 'Restaurant Reiskorn | Speisekarte', loginName: loginMod.getName(req), isAdmin: loginMod.hasAccess(req, loginMod.AdminRight.MENU), - menuJSON: menuJSON + menuJSON: menuMod.getJSON() }); - - fs.writeFile(app.get('rundir') + '/data/menu.json', JSON.stringify(menuJSON, null, 4), function(err) { - if(err) { - console.log(err); - } - }); }); app.get('/kontakt', function(req, res) { res.render('contact', { title: 'Restaurant Reiskorn | Kontakt', loginName: loginMod.getName(req), - menuJSON: menuJSON + menuJSON: menuMod.getJSON() }); }); @@ -117,7 +111,7 @@ app.get('/login', function(req, res) { title: 'Restaurant Reiskorn | Login', loginName: loginMod.getName(req), isAdmin: loginMod.hasAccess(req, loginMod.AdminRight.ADMIN), - menuJSON: menuJSON + menuJSON: menuMod.getJSON() }); }); @@ -144,7 +138,7 @@ app.post('/login', function(req, res) { title: 'Restaurant Reiskorn | Login', loginName: loginMod.getName(req), isAdmin: loginMod.hasAccess(req, loginMod.AdminRight.ADMIN), - menuJSON: menuJSON, + menuJSON: menuMod.getJSON(), loginAction: action }); }); diff --git a/modules/login.js b/modules/login.js index c168298..6f57bce 100644 --- a/modules/login.js +++ b/modules/login.js @@ -34,6 +34,7 @@ module.exports.checkCredentials = function(name, pwd) { }; module.exports.hasAccess = function(req, section) { + return true; var name = module.exports.getName(req); return (name && admins[name] && admins[name].rights && admins[name].rights[section] && admins[name].rights[module.exports.AdminRight.ADMIN]); }; diff --git a/modules/menu.js b/modules/menu.js new file mode 100644 index 0000000..27ef2ed --- /dev/null +++ b/modules/menu.js @@ -0,0 +1,159 @@ +var fs = require('fs'); + +var menuJSON = { + "food": {}, + "drinks": {} +}; + +var REGEX_CREATE = /^[fd]-[0-9]+-new$/; +var REGEX_UPDATE = /^[fd]-[0-9]+-[0-9]+$/; +var REGEX_DELETE = /^[fd]-[0-9]+-[0-9]+-del$/; +var REGEX_FLOAT = /^(\-|\+)?([0-9]+(\.[0-9]+)?)$/; + +var FILENAME = false; + +module.exports.init = function(menufile) { + FILENAME = menufile; + module.exports.loadFile(); +} + +module.exports.loadFile = function() { + if (!FILENAME) throw "No file for menu JSON specified"; + fs.readFile(FILENAME, 'utf8', function(err, data) { + if (err) throw err; + menuJSON = JSON.parse(data); + }); +} + +module.exports.saveJSON = function() { + if (!FILENAME) throw "No file for menu JSON specified"; + fs.writeFile(FILENAME, JSON.stringify(menuJSON, null, 4), function(err) { + if(err) { + console.log(err); + return false; + } + }); + return true; +} + +module.exports.MenuAction = { + ERROR: 0, + CREATE: 1, + UPDATE: 2, + DELETE: 3 +} + +module.exports.ErrorCode = { + SUCCESS: 0, + NOSTRING_NAME: 1, + NOSTRING_DESC: 2, + NOFLOAT_PRICE: 4, + WRONG_ACTION: 8 +} + +module.exports.determineAction = function(nametag) { + if (nametag && REGEX_CREATE.test(nametag)) { // new + return module.exports.MenuAction.CREATE; + } else if (nametag && REGEX_UPDATE.test(nametag)) { // update + return module.exports.MenuAction.UPDATE; + } else if (nametag && REGEX_DELETE.test(nametag)) { // delete + return module.exports.MenuAction.DELETE; + } + return module.exports.MenuAction.ERROR; +} + +module.exports.checkValidity = function(name, desc, price) { + var errorCode = 0; + + if (!name || !(typeof name === 'string' || name instanceof String)) + errorCode += module.exports.ErrorCode.NOSTRING_NAME; + if (!desc || !(typeof desc === 'string' || desc instanceof String)) + errorCode += module.exports.ErrorCode.NOSTRING_DESC; + if (isNaN(filterFloat(price))) + errorCode += module.exports.ErrorCode.NOFLOAT_PRICE; + return errorCode; +} + +module.exports.addValue = function(name, desc, price, nametag) { + var errorCode = module.exports.checkValidity(name, desc, price); + var action = module.exports.determineAction(nametag); + if (action !== module.exports.MenuAction.CREATE) { + errorCode += module.exports.ErrorCode.WRONG_ACTION; + } + if (!errorCode) { + price = filterFloat(price); + var position = splitNameTag(nametag, action); + menuJSON[position.category][position.section]["items"].push({ + name: name, + desc: desc, + price: price + }); + module.exports.saveJSON(); + } + return errorCode; +} + +module.exports.updateValue = function(name, desc, price, nametag) { + var errorCode = module.exports.checkValidity(name, desc, price); + var action = module.exports.determineAction(nametag); + if (action !== module.exports.MenuAction.UPDATE) { + errorCode += module.exports.ErrorCode.WRONG_ACTION; + } + if (!errorCode) { + price = filterFloat(price); + var position = splitNameTag(nametag, action); + menuJSON[position.category][position.section]["items"][position.id] = { + name: name, + desc: desc, + price: price + }; + module.exports.saveJSON(); + } + return errorCode; +} + +module.exports.deleteValue = function(nametag) { + var errorCode = module.exports.ErrorCode.SUCCESS; + var action = module.exports.determineAction(nametag); + if (action !== module.exports.MenuAction.DELETE) { + errorCode += module.exports.ErrorCode.WRONG_ACTION; + } + if (!errorCode) { + var position = splitNameTag(nametag, action); + menuJSON[position.category][position.section]["items"].splice(position.id, 1); + module.exports.saveJSON(); + } + return errorCode; +} + +module.exports.getJSON = function() { + return menuJSON; +} + +var filterFloat = function(value) { + if(REGEX_FLOAT.test(value)) + return parseFloat(value); + return NaN; +} + +var splitNameTag = function(nametag, action) { + if (action) { // create, update & delete + var splitArr = nametag.split("-"); + var result = {}; + if (splitArr[0] == "f") { + result.category = "food"; + } else { + result.category = "drinks"; + } + result.section = parseInt(splitArr[1]); + result.type = action; + if (action == module.exports.MenuAction.CREATE) { // create + result.id = null; + } else { // update & delete + result.id = parseInt(splitArr[2]); + } + return result; + } else { + return false; + } +} \ No newline at end of file diff --git a/views/menu.jade b/views/menu.jade index a67846f..239a3fe 100644 --- a/views/menu.jade +++ b/views/menu.jade @@ -8,7 +8,7 @@ mixin menu-item-adm(name, desc, price, prefix, newItem) +icon("ok") else form(style="display:inline",method="post",action="") - input(type='hidden',name='del',value='#{prefix}') + input(type='hidden',name='nametag',value="#{prefix + '-del'}") button.btn.btn-sm.btn-danger(type="submit") +icon("remove") button.btn.btn-sm.btn-primary(type="submit",form="#{prefix}")