Menü-Verwaltung in externe Datei verschoben und User-Input-Save gemacht
This commit is contained in:
568
data/menu.json
568
data/menu.json
@@ -1,286 +1,286 @@
|
|||||||
{
|
{
|
||||||
"food": [
|
"food": [
|
||||||
{
|
{
|
||||||
"name": "Vorspeisen",
|
"name": "Vorspeisen",
|
||||||
"anchor": "vorspeise",
|
"anchor": "vorspeise",
|
||||||
"items": [
|
"items": [
|
||||||
{
|
{
|
||||||
"name": "Reis-alat",
|
"name": "Reis-alat",
|
||||||
"price": 5.50,
|
"price": 5.5,
|
||||||
"desc": "Frischer Blattsalat mit Basmati-Reis und würzigem Balsamico"
|
"desc": "Frischer Blattsalat mit Basmati-Reis und würzigem Balsamico"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Chinesisches Bauernfrühstück",
|
"name": "Chinesisches Bauernfrühstück",
|
||||||
"price": 6.40,
|
"price": 6.4,
|
||||||
"desc": "Feuriges Chili in gedämpftem, kaltem Reis mit heißem Gemüse"
|
"desc": "Feuriges Chili in gedämpftem, kaltem Reis mit heißem Gemüse"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Thailändisches Arbeiterfrühstück",
|
"name": "Thailändisches Arbeiterfrühstück",
|
||||||
"price": 7.40,
|
"price": 7.4,
|
||||||
"desc": "Feuriges Chili in gedämpftem, kaltem Reis mit heißem Gemüse und Hähnchen"
|
"desc": "Feuriges Chili in gedämpftem, kaltem Reis mit heißem Gemüse und Hähnchen"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Viatnamesisches Denkerfrühstück",
|
"name": "Viatnamesisches Denkerfrühstück",
|
||||||
"price": 7.90,
|
"price": 7.9,
|
||||||
"desc": "Feuriges Chili in gedämpftem, kaltem Reis mit heißem Gemüse und Ente"
|
"desc": "Feuriges Chili in gedämpftem, kaltem Reis mit heißem Gemüse und Ente"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "90er-Reis-Plattenscheibe",
|
"name": "90er-Reis-Plattenscheibe",
|
||||||
"price": 51.90,
|
"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"
|
"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",
|
"name": "Suppen",
|
||||||
"anchor": "suppe",
|
"anchor": "suppe",
|
||||||
"items": [
|
"items": [
|
||||||
{
|
{
|
||||||
"name": "Reis-uppe",
|
"name": "Reis-uppe",
|
||||||
"price": 3.90,
|
"price": 3.9,
|
||||||
"desc": "Köstliche, klare Hühnerbrühe mit einem Schuss Soja und Reis"
|
"desc": "Köstliche, klare Hühnerbrühe mit einem Schuss Soja und Reis"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Tomatensuppe",
|
"name": "Tomatensuppe",
|
||||||
"price": 4.20,
|
"price": 4.2,
|
||||||
"desc": "Cremige Tomatensuppe mit frischen Tomaten, Rahm und Reis sowie einer leckeren Petersilie als Dekör"
|
"desc": "Cremige Tomatensuppe mit frischen Tomaten, Rahm und Reis sowie einer leckeren Petersilie als Dekör"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Üppige Suppe",
|
"name": "Üppige Suppe",
|
||||||
"price": 2.20,
|
"price": 2.2,
|
||||||
"desc": "Üppige Suppe mit üppigem Gemüse gewuppt mit zerruppten Gestrüpp"
|
"desc": "Üppige Suppe mit üppigem Gemüse gewuppt mit zerruppten Gestrüpp"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Henker's Mahlzeit",
|
"name": "Henker's Mahlzeit",
|
||||||
"price": 6.80,
|
"price": 6.8,
|
||||||
"desc": "Roter Reis mit scharfem Chili mit tomaten und roter Paprika"
|
"desc": "Roter Reis mit scharfem Chili mit tomaten und roter Paprika"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Nudelsuppe",
|
"name": "Nudelsuppe",
|
||||||
"price": 3.30,
|
"price": 3.3,
|
||||||
"desc": "Leissuppe mit liesigel Poltion klingliger Knödel"
|
"desc": "Leissuppe mit liesigel Poltion klingliger Knödel"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Hauptspeisen",
|
"name": "Hauptspeisen",
|
||||||
"anchor": "hauptspeise",
|
"anchor": "hauptspeise",
|
||||||
"items": [
|
"items": [
|
||||||
{
|
{
|
||||||
"name": "Grillplatte \"China\"",
|
"name": "Grillplatte \"China\"",
|
||||||
"price": 11.20,
|
"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"
|
"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",
|
"name": "Reis mit Reis",
|
||||||
"price": 14.80,
|
"price": 14.8,
|
||||||
"desc": "Reis mit Reis dazu Reis als Beilage in Kombination mit Reis und Reis"
|
"desc": "Reis mit Reis dazu Reis als Beilage in Kombination mit Reis und Reis"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "O'jeh-gerl-schnitzel",
|
"name": "O'jeh-gerl-schnitzel",
|
||||||
"price": 13.50,
|
"price": 13.5,
|
||||||
"desc": "Deutsches Jägerschnitzel nach Art des Hauses mit Reis als Beilage"
|
"desc": "Deutsches Jägerschnitzel nach Art des Hauses mit Reis als Beilage"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "RisiBisi",
|
"name": "RisiBisi",
|
||||||
"price": 17.30,
|
"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"
|
"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",
|
"name": "Burger Duck",
|
||||||
"price": 14.20,
|
"price": 14.2,
|
||||||
"desc": "Saftiger Burger mit aufregenden Gewürzen, Gewürzgurken, Gurken, Tomaten, BBQ-Sauce und knusprig überbackenem Entenfleisch, dazu Reis"
|
"desc": "Saftiger Burger mit aufregenden Gewürzen, Gewürzgurken, Gurken, Tomaten, BBQ-Sauce und knusprig überbackenem Entenfleisch, dazu Reis"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Money Boy",
|
"name": "Money Boy",
|
||||||
"price": 95.90,
|
"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é"
|
"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",
|
"name": "Reis-otto",
|
||||||
"price": 11.60,
|
"price": 11.6,
|
||||||
"desc": "Risotto mit Brokkoli und Schinken, dazu etwas Parmesan und Thymian"
|
"desc": "Risotto mit Brokkoli und Schinken, dazu etwas Parmesan und Thymian"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Junior-Reisesser",
|
"name": "Junior-Reisesser",
|
||||||
"anchor": "junior",
|
"anchor": "junior",
|
||||||
"items": [
|
"items": [
|
||||||
{
|
{
|
||||||
"name": "\"Chinesischer Seeräuber\"-Teller",
|
"name": "\"Chinesischer Seeräuber\"-Teller",
|
||||||
"price": 0,
|
"price": 0,
|
||||||
"desc": "Ein Messer, eine Gabel, ein Teller und nur eine Aufgabe: Das Essen des Nachbars! (auf Wunsch mit Seeräuber-Hut)"
|
"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",
|
"name": "Käpt'n Reisbart",
|
||||||
"price": 7.70,
|
"price": 7.7,
|
||||||
"desc": "Süß-Sauer-Soße mit Hähnchenschiffchen in Reis gebadet"
|
"desc": "Süß-Sauer-Soße mit Hähnchenschiffchen in Reis gebadet"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Spagetti Reisonese",
|
"name": "Spagetti Reisonese",
|
||||||
"price": 5.60,
|
"price": 5.6,
|
||||||
"desc": "Spaghetti mit Tomatensoße und Reis"
|
"desc": "Spaghetti mit Tomatensoße und Reis"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Desserts",
|
"name": "Desserts",
|
||||||
"anchor": "dessert",
|
"anchor": "dessert",
|
||||||
"items": [
|
"items": [
|
||||||
{
|
{
|
||||||
"name": "Milchreis",
|
"name": "Milchreis",
|
||||||
"price": 6.30,
|
"price": 6.3,
|
||||||
"desc": "Leckerer Milchreis aus der Tüte vom Großhändler mit heißen Sauerkirschen aus der Konservenbüchse"
|
"desc": "Leckerer Milchreis aus der Tüte vom Großhändler mit heißen Sauerkirschen aus der Konservenbüchse"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "R-Eis",
|
"name": "R-Eis",
|
||||||
"price": 4.10,
|
"price": 4.1,
|
||||||
"desc": "Gemischtes Eis mit Kokos-reis-Streumaterial; 3 Kugeln nach Wahl"
|
"desc": "Gemischtes Eis mit Kokos-reis-Streumaterial; 3 Kugeln nach Wahl"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Eierreiskuchen",
|
"name": "Eierreiskuchen",
|
||||||
"price": 5.00,
|
"price": 5,
|
||||||
"desc": "2 köstliche Palatschinken (regional auch Eierkuchen genannt) mit im Teig eingearbeitetetem Reis, dazu feinster Powidl (regional auch Pflaumenmuß) genannt"
|
"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",
|
"name": "Süßes Reisotto",
|
||||||
"price": 8.70,
|
"price": 8.7,
|
||||||
"desc": "Reis mit bunten Früchten und viel Joghurt, angerichtet mit etweas Zimt und einem Schuss Honig"
|
"desc": "Reis mit bunten Früchten und viel Joghurt, angerichtet mit etweas Zimt und einem Schuss Honig"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Reisstrudel",
|
"name": "Reisstrudel",
|
||||||
"price": 5.60,
|
"price": 5.6,
|
||||||
"desc": "In Blätterteil gewickelter Reis mit Milchcreme und Minze, dazu Vanillesoße und eine Kugel Vanilleeis"
|
"desc": "In Blätterteil gewickelter Reis mit Milchcreme und Minze, dazu Vanillesoße und eine Kugel Vanilleeis"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"drinks": [
|
"drinks": [
|
||||||
{
|
{
|
||||||
"name": "Auf Art des Hauses",
|
"name": "Auf Art des Hauses",
|
||||||
"anchor": "haus",
|
"anchor": "haus",
|
||||||
"items": [
|
"items": [
|
||||||
{
|
{
|
||||||
"name": "Reiswein",
|
"name": "Reiswein",
|
||||||
"price": 3.90,
|
"price": 3.9,
|
||||||
"desc": "Exquisiter Reiswein mit leiter gelblicher Färbung aus eigener Herstellung mit über 1337 Jahren Erfahrung (Alkoholgehalt 13,37%)"
|
"desc": "Exquisiter Reiswein mit leiter gelblicher Färbung aus eigener Herstellung mit über 1337 Jahren Erfahrung (Alkoholgehalt 13,37%)"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Reisschnaps",
|
"name": "Reisschnaps",
|
||||||
"price": 2.10,
|
"price": 2.1,
|
||||||
"desc": "Starker Reisschnaps als Absacker geeignet mit feiner Süße im Abgang (Alkoholgehalt 69%)"
|
"desc": "Starker Reisschnaps als Absacker geeignet mit feiner Süße im Abgang (Alkoholgehalt 69%)"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Reisbier",
|
"name": "Reisbier",
|
||||||
"price": 3.50,
|
"price": 3.5,
|
||||||
"desc": "Aus der Reispflanze gewonnenes Bier mit Hopfen nach chinesischem Reinheitsgebot (Alkoholgehalt 4,2%)"
|
"desc": "Aus der Reispflanze gewonnenes Bier mit Hopfen nach chinesischem Reinheitsgebot (Alkoholgehalt 4,2%)"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Reissud",
|
"name": "Reissud",
|
||||||
"price": 1.20,
|
"price": 1.2,
|
||||||
"desc": "Heißer beim Reis kochen entstandener Sud; alkoholfrei, warm und jedes Mal je nach Reissorte ein individueller, neuer Geschmack"
|
"desc": "Heißer beim Reis kochen entstandener Sud; alkoholfrei, warm und jedes Mal je nach Reissorte ein individueller, neuer Geschmack"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Alkoholfrei",
|
"name": "Alkoholfrei",
|
||||||
"anchor": "alkoholfrei",
|
"anchor": "alkoholfrei",
|
||||||
"items": [
|
"items": [
|
||||||
{
|
{
|
||||||
"name": "Softdrinks (0,5l)",
|
"name": "Softdrinks (0,5l)",
|
||||||
"price": 3.40,
|
"price": 3.4,
|
||||||
"desc": "Verschidene Sorten nur diesen Framstag im Angebot!"
|
"desc": "Verschidene Sorten nur diesen Framstag im Angebot!"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Softdrinks (0,3l)",
|
"name": "Softdrinks (0,3l)",
|
||||||
"price": 2.90,
|
"price": 2.9,
|
||||||
"desc": "Verschidene Sorten nur diesen Framstag im Angebot!"
|
"desc": "Verschidene Sorten nur diesen Framstag im Angebot!"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Wasser (1l)",
|
"name": "Wasser (1l)",
|
||||||
"price": 4.10,
|
"price": 4.1,
|
||||||
"desc": "Das Wasser trüb, die Luft ist rein, Franz-Josef muss ertrunken sein."
|
"desc": "Das Wasser trüb, die Luft ist rein, Franz-Josef muss ertrunken sein."
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Alkohol",
|
"name": "Alkohol",
|
||||||
"anchor": "alkohol",
|
"anchor": "alkohol",
|
||||||
"items": [
|
"items": [
|
||||||
{
|
{
|
||||||
"name": "Bier vom Fass (0,5l)",
|
"name": "Bier vom Fass (0,5l)",
|
||||||
"price": 3.50,
|
"price": 3.5,
|
||||||
"desc": "Wählen sie zwischen Becks, Sternburg und Berliner Kindl"
|
"desc": "Wählen sie zwischen Becks, Sternburg und Berliner Kindl"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Bier vom Fass (0,3l)",
|
"name": "Bier vom Fass (0,3l)",
|
||||||
"price": 3.00,
|
"price": 3,
|
||||||
"desc": "Wählen sie zwischen Becks, Sternburg und Berliner Kindl"
|
"desc": "Wählen sie zwischen Becks, Sternburg und Berliner Kindl"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Chinesisches Bier (0,69l)",
|
"name": "Chinesisches Bier (0,69l)",
|
||||||
"price": 2.40,
|
"price": 2.4,
|
||||||
"desc": "Tsingtao-Exportbier"
|
"desc": "Tsingtao-Exportbier"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Chinesisches Bier (0,42l)",
|
"name": "Chinesisches Bier (0,42l)",
|
||||||
"price": 1.90,
|
"price": 1.9,
|
||||||
"desc": "Tsingtao-Exportbier"
|
"desc": "Tsingtao-Exportbier"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Rislinger Wein (0,2l)",
|
"name": "Rislinger Wein (0,2l)",
|
||||||
"price": 4.20,
|
"price": 4.2,
|
||||||
"desc": "Asiatischer Wein mit unbekanntem Ursprung aus gezüchteten, von Monsanto genmanipulierten Weintrauben"
|
"desc": "Asiatischer Wein mit unbekanntem Ursprung aus gezüchteten, von Monsanto genmanipulierten Weintrauben"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Radler (0,5l)",
|
"name": "Radler (0,5l)",
|
||||||
"price": 13.20,
|
"price": 13.2,
|
||||||
"desc": "Für echte Vampire"
|
"desc": "Für echte Vampire"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Spriritus",
|
"name": "Spriritus",
|
||||||
"anchor": "spirituose",
|
"anchor": "spirituose",
|
||||||
"items": [
|
"items": [
|
||||||
{
|
{
|
||||||
"name": "Asiatische Freude",
|
"name": "Asiatische Freude",
|
||||||
"price": 1.50,
|
"price": 1.5,
|
||||||
"desc": "Auf 45 Grad erwärmter Reisschnaps mit Raucharoma für natürliches Pekinger Stadtklima"
|
"desc": "Auf 45 Grad erwärmter Reisschnaps mit Raucharoma für natürliches Pekinger Stadtklima"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Sprit-Tussi",
|
"name": "Sprit-Tussi",
|
||||||
"price": 1.60,
|
"price": 1.6,
|
||||||
"desc": "Diesel (Cola-Bier-Gemisch) in einem 0,1cl-Glas, um es teurer verkaufen zu können"
|
"desc": "Diesel (Cola-Bier-Gemisch) in einem 0,1cl-Glas, um es teurer verkaufen zu können"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Cocktails",
|
"name": "Cocktails",
|
||||||
"anchor": "cocktails",
|
"anchor": "cocktails",
|
||||||
"items": [
|
"items": [
|
||||||
{
|
{
|
||||||
"name": "Beste Freundschaft",
|
"name": "Beste Freundschaft",
|
||||||
"price": 9.30,
|
"price": 9.3,
|
||||||
"desc": "Lila Livo-Liva mit weißem Rohrzucker und Limettensaft mit frischer, grüner Limette"
|
"desc": "Lila Livo-Liva mit weißem Rohrzucker und Limettensaft mit frischer, grüner Limette"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Schwanz-Schwanz",
|
"name": "Schwanz-Schwanz",
|
||||||
"price": 5.60,
|
"price": 5.6,
|
||||||
"desc": "Ausgefuchste Kombination von Schwanz und Schwanz des Hans und Franz"
|
"desc": "Ausgefuchste Kombination von Schwanz und Schwanz des Hans und Franz"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Der Reisende",
|
"name": "Der Reisende",
|
||||||
"price": 8.90,
|
"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)"
|
"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",
|
"name": "Pina Reisolada",
|
||||||
"price": 6.10,
|
"price": 6.1,
|
||||||
"desc": "Mit Ananas und Kokos aufgemixte Mixtur in Reisschaum, mit Reisschnaps und fast dem ganzen Glas voller Eis"
|
"desc": "Mit Ananas und Kokos aufgemixte Mixtur in Reisschaum, mit Reisschnaps und fast dem ganzen Glas voller Eis"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
104
main.js
104
main.js
@@ -3,17 +3,30 @@ var jade = require('jade');
|
|||||||
var bodyParser = require('body-parser');
|
var bodyParser = require('body-parser');
|
||||||
var session = require('express-session');
|
var session = require('express-session');
|
||||||
var loginMod = require('./modules/login');
|
var loginMod = require('./modules/login');
|
||||||
var path = require('path');
|
var menuMod = require('./modules/menu');
|
||||||
|
//var path = require('path');
|
||||||
var fs = require('fs');
|
var fs = require('fs');
|
||||||
|
|
||||||
var menuJSON;
|
|
||||||
|
|
||||||
var app = express();
|
var app = express();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// **************************
|
||||||
|
// APP VARS
|
||||||
|
// **************************
|
||||||
|
|
||||||
app.set('view engine', 'jade');
|
app.set('view engine', 'jade');
|
||||||
app.set('rundir', '.');
|
app.set('rundir', '.');
|
||||||
app.set('views', app.get('rundir') + '/views');
|
app.set('views', app.get('rundir') + '/views');
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// **************************
|
||||||
|
// MIDDLEWARE
|
||||||
|
// **************************
|
||||||
|
|
||||||
app.use(session({
|
app.use(session({
|
||||||
secret: 'Jk0Z850cD2MXkcIRXDg1M4X6c1VKkJTb6VYQfbWUKw2XwqaBmqqaKu7K0Q8WlGZVqupF2fzXaavt1hNf',
|
secret: 'Jk0Z850cD2MXkcIRXDg1M4X6c1VKkJTb6VYQfbWUKw2XwqaBmqqaKu7K0Q8WlGZVqupF2fzXaavt1hNf',
|
||||||
resave: true,
|
resave: true,
|
||||||
@@ -26,16 +39,27 @@ app.use(bodyParser.urlencoded({
|
|||||||
|
|
||||||
app.use('/bin', express.static(app.get('rundir') + '/public'));
|
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) {
|
app.get('/', function(req, res) {
|
||||||
res.render('index', {
|
res.render('index', {
|
||||||
title: 'Restaurant Reiskorn | Home',
|
title: 'Restaurant Reiskorn | Home',
|
||||||
loginName: loginMod.getName(req),
|
loginName: loginMod.getName(req),
|
||||||
menuJSON: menuJSON
|
menuJSON: menuMod.getJSON()
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -44,71 +68,41 @@ app.get('/speisekarte', function(req, res) {
|
|||||||
title: 'Restaurant Reiskorn | Speisekarte',
|
title: 'Restaurant Reiskorn | Speisekarte',
|
||||||
loginName: loginMod.getName(req),
|
loginName: loginMod.getName(req),
|
||||||
isAdmin: loginMod.hasAccess(req, loginMod.AdminRight.MENU),
|
isAdmin: loginMod.hasAccess(req, loginMod.AdminRight.MENU),
|
||||||
menuJSON: menuJSON
|
menuJSON: menuMod.getJSON()
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
app.post('/speisekarte', function(req, res) {
|
app.post('/speisekarte', function(req, res) {
|
||||||
var del = req.body.del;
|
var nametag = req.body.nametag;
|
||||||
var item = req.body.nametag;
|
|
||||||
var name = req.body.name;
|
var name = req.body.name;
|
||||||
var desc = req.body.desc;
|
var desc = req.body.desc;
|
||||||
var price = req.body.price;
|
var price = req.body.price;
|
||||||
if (item && /^[fd]-[0-9]+-new$/.test(item)) { // new
|
|
||||||
var splitArr = item.split("-");
|
if (loginMod.hasAccess(req, loginMod.AdminRight.MENU)) {
|
||||||
if (splitArr[0] == "f") {
|
var action = menuMod.determineAction(nametag);
|
||||||
splitArr[0] = "food";
|
var error = 0;
|
||||||
} else {
|
if (action == menuMod.MenuAction.CREATE)
|
||||||
splitArr[0] = "drinks";
|
error = menuMod.addValue(name, desc, price, nametag);
|
||||||
}
|
else if (action == menuMod.MenuAction.UPDATE)
|
||||||
price = parseInt(price);
|
error = menuMod.updateValue(name, desc, price, nametag);
|
||||||
menuJSON[splitArr[0]][parseInt(splitArr[1])]["items"].push({
|
else if (action == menuMod.MenuAction.DELETE)
|
||||||
name: name,
|
error = menuMod.deleteValue(nametag);
|
||||||
desc: desc,
|
console.log(error);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
res.render('menu', {
|
res.render('menu', {
|
||||||
title: 'Restaurant Reiskorn | Speisekarte',
|
title: 'Restaurant Reiskorn | Speisekarte',
|
||||||
loginName: loginMod.getName(req),
|
loginName: loginMod.getName(req),
|
||||||
isAdmin: loginMod.hasAccess(req, loginMod.AdminRight.MENU),
|
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) {
|
app.get('/kontakt', function(req, res) {
|
||||||
res.render('contact', {
|
res.render('contact', {
|
||||||
title: 'Restaurant Reiskorn | Kontakt',
|
title: 'Restaurant Reiskorn | Kontakt',
|
||||||
loginName: loginMod.getName(req),
|
loginName: loginMod.getName(req),
|
||||||
menuJSON: menuJSON
|
menuJSON: menuMod.getJSON()
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -117,7 +111,7 @@ app.get('/login', function(req, res) {
|
|||||||
title: 'Restaurant Reiskorn | Login',
|
title: 'Restaurant Reiskorn | Login',
|
||||||
loginName: loginMod.getName(req),
|
loginName: loginMod.getName(req),
|
||||||
isAdmin: loginMod.hasAccess(req, loginMod.AdminRight.ADMIN),
|
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',
|
title: 'Restaurant Reiskorn | Login',
|
||||||
loginName: loginMod.getName(req),
|
loginName: loginMod.getName(req),
|
||||||
isAdmin: loginMod.hasAccess(req, loginMod.AdminRight.ADMIN),
|
isAdmin: loginMod.hasAccess(req, loginMod.AdminRight.ADMIN),
|
||||||
menuJSON: menuJSON,
|
menuJSON: menuMod.getJSON(),
|
||||||
loginAction: action
|
loginAction: action
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ module.exports.checkCredentials = function(name, pwd) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
module.exports.hasAccess = function(req, section) {
|
module.exports.hasAccess = function(req, section) {
|
||||||
|
return true;
|
||||||
var name = module.exports.getName(req);
|
var name = module.exports.getName(req);
|
||||||
return (name && admins[name] && admins[name].rights && admins[name].rights[section] && admins[name].rights[module.exports.AdminRight.ADMIN]);
|
return (name && admins[name] && admins[name].rights && admins[name].rights[section] && admins[name].rights[module.exports.AdminRight.ADMIN]);
|
||||||
};
|
};
|
||||||
|
|||||||
159
modules/menu.js
Normal file
159
modules/menu.js
Normal file
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -8,7 +8,7 @@ mixin menu-item-adm(name, desc, price, prefix, newItem)
|
|||||||
+icon("ok")
|
+icon("ok")
|
||||||
else
|
else
|
||||||
form(style="display:inline",method="post",action="")
|
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")
|
button.btn.btn-sm.btn-danger(type="submit")
|
||||||
+icon("remove")
|
+icon("remove")
|
||||||
button.btn.btn-sm.btn-primary(type="submit",form="#{prefix}")
|
button.btn.btn-sm.btn-primary(type="submit",form="#{prefix}")
|
||||||
|
|||||||
Reference in New Issue
Block a user