Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c521f2670b | ||
|
|
cbadac55c5 | ||
|
|
82b0604247 | ||
|
|
0c6564db3b | ||
|
|
62ff08624d |
61
README.md
61
README.md
@@ -0,0 +1,61 @@
|
|||||||
|
# Restaurant Reiskorn
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
1. Herunterladen des aktuellen [Release](https://gogs.sebse.de/Caesar2011/html5-restaurant/releases).
|
||||||
|
2. Starten der `main.js` im Hauptprojekt-Ordner.
|
||||||
|
- `node path/to/main.js`
|
||||||
|
- Relative und absolute Pfade erlaubt
|
||||||
|
3. Aufrufen [der lokalen Node-Anwendung](http://localhost:3000) oder [dem gehosteten Service](http://restaurant.sebse.de)
|
||||||
|
|
||||||
|
## Dateistruktur
|
||||||
|
|
||||||
|
### data
|
||||||
|
|
||||||
|
- Daten zur Speicherung der
|
||||||
|
- Reservierungen
|
||||||
|
- Speisekarte
|
||||||
|
- Benutzerliste
|
||||||
|
- Mit jeweiligen Beispielwerten zum manuellen Einladen
|
||||||
|
|
||||||
|
### modules
|
||||||
|
|
||||||
|
- eigene nodejs-Module
|
||||||
|
- entspricht im MVC-Modell einem Model
|
||||||
|
- CRUD-Routinen
|
||||||
|
- Reservierungen
|
||||||
|
- Speisekarte
|
||||||
|
- Benutzerliste
|
||||||
|
|
||||||
|
### node_modules
|
||||||
|
|
||||||
|
- von npm installierte Pakete
|
||||||
|
|
||||||
|
### public
|
||||||
|
|
||||||
|
- Client-Assets
|
||||||
|
- CSS
|
||||||
|
- Client-JS
|
||||||
|
- Bilder
|
||||||
|
- Bootstrap/AngularJS
|
||||||
|
- werden über HTML nachgeladen
|
||||||
|
|
||||||
|
### views
|
||||||
|
|
||||||
|
- JADE-Views
|
||||||
|
- HTML-Template-Engine
|
||||||
|
|
||||||
|
## Requests
|
||||||
|
|
||||||
|
| Min. Vers. | Methode | URI | Parameter | Beschreibung | Benötige Rechte |
|
||||||
|
|--------|--------|--------|--------|--------|--------|
|
||||||
|
| 0.1 | GET | / | keine | Zeigt die Startseite an | keine |
|
||||||
|
| 0.1 | GET | /speisekarte | keine | Zeigt die Speisekarte an | keine (Bearbeitungsfunktionen mit MENU) |
|
||||||
|
| 0.1 | POST | /speisekarte | nametag:<br> `[f\|d]-[Index in der Liste "food"/"drinks"]-new`<br>name:<br> `[Name des Gerichts]`<br>desc:<br> `[Beschreibung des Menüeintrags]` | Hinzufügen eines Menüeintrags | MENU |
|
||||||
|
| 0.1 | POST | /speisekarte | nametag:<br> `[f\|d]-[Index in der Liste "food"/"drinks"]-[Index in der Liste "items"]`<br>name:<br> `[Name des Gerichts]`<br>desc:<br> `[Beschreibung des Menüeintrags]` | Aktualisieren der Informationen eines Eintrages | MENU |
|
||||||
|
| 0.1 | POST | /speisekarte | nametag:<br> `[f\|d]-[Index in der Liste "food"/"drinks"]-[Index in der Liste "items"]-del` | Löschen eines Eintages aus der Speisekarte | MENU |
|
||||||
|
| 0.1 | GET | /kontakt | keine | Zeigt die Kontaktseite an | keine:<br> Reservierungsformular<br>RESERVATION:<br>Liste aller eingegangenen Reservierungen |
|
||||||
|
| 1.0 | GET | /kontakt | nametag:<br> `[Index der Reservierung]` | Öffnet das Fenster zum Bearbeiten eines Eintages | RESERVATION |
|
||||||
|
| 1.0 | POST | /kontakt | nametag:<br> `new`<br>name:<br> `[Name des Reservierenden]`<br>desc:<br> `[Kommentarfeld]`<br>email:<br> `[gülige E-Mail-Adresse]`<br>person:<br> `[positive, natürliche Zahl]`<br>time:<br> `^(([01][0-9]\|2[0-4]):[0-5][0-9])$`<br>date:<br> `^(([0-2][0-9]\|3[01]).(0[0-9]\|1[012]).[0-9]{4})$` | Hinzufügen einer Reservierung | keine |
|
||||||
|
| 1.0 | POST | /kontakt | nametag:<br> `[Index der Reservierung]`<br>name:<br> `[Name des Reservierenden]`<br>desc:<br> `[Kommentarfeld]`<br>email:<br> `[gülige E-Mail-Adresse]`<br>person:<br> `[positive, natürliche Zahl]`<br>time:<br> `^(([01][0-9]\|2[0-4]):[0-5][0-9])$`<br>date:<br> `^(([0-2][0-9]\|3[01]).(0[0-9]\|1[012]).[0-9]{4})$` | Aktualisieren der Informationen einer Reservierung | RESERVATION |
|
||||||
|
| 1.0 | POST | /kontakt | nametag:<br> `[Index der Reservierung]-del` | Löschen einer Reservierung aus der Liste | RESERVATION |
|
||||||
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.5,
|
"price": 5.50,
|
||||||
"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.4,
|
"price": 6.40,
|
||||||
"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.4,
|
"price": 7.40,
|
||||||
"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.9,
|
"price": 7.90,
|
||||||
"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.9,
|
"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"
|
"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.9,
|
"price": 3.90,
|
||||||
"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.2,
|
"price": 4.20,
|
||||||
"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.2,
|
"price": 2.20,
|
||||||
"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.8,
|
"price": 6.80,
|
||||||
"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.3,
|
"price": 3.30,
|
||||||
"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.2,
|
"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"
|
"desc": "Ein großes, paniertes Schnitzel in Form des Landes china dazu Tibet-formender Reis, Ente im Pazifik und Hähnchen als Peking geformt"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Reis mit Reis",
|
"name": "Reis mit Reis",
|
||||||
"price": 14.8,
|
"price": 14.80,
|
||||||
"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.5,
|
"price": 13.50,
|
||||||
"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.3,
|
"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"
|
"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.2,
|
"price": 14.20,
|
||||||
"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.9,
|
"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é"
|
"desc": "Goldfarbener Reis 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.6,
|
"price": 11.60,
|
||||||
"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.7,
|
"price": 7.70,
|
||||||
"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.6,
|
"price": 5.60,
|
||||||
"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.3,
|
"price": 6.30,
|
||||||
"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.1,
|
"price": 4.10,
|
||||||
"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,
|
"price": 5.00,
|
||||||
"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 eingearbeitetem Reis, dazu feinster Powidl (regional auch Pflaumenmuß) genannt"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Süßes Reisotto",
|
"name": "Süßes Reisotto",
|
||||||
"price": 8.7,
|
"price": 8.70,
|
||||||
"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.6,
|
"price": 5.60,
|
||||||
"desc": "In Blätterteil gewickelter Reis mit Milchcreme und Minze, dazu Vanillesoße und eine Kugel Vanilleeis"
|
"desc": "In Blätterteig 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.9,
|
"price": 3.90,
|
||||||
"desc": "Exquisiter Reiswein mit leiter gelblicher Färbung aus eigener Herstellung mit über 1337 Jahren Erfahrung (Alkoholgehalt 13,37%)"
|
"desc": "Exquisiter Reiswein mit leicht gelblicher Färbung aus eigener Herstellung mit über 1337 Jahren Erfahrung (Alkoholgehalt 13,37%)"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Reisschnaps",
|
"name": "Reisschnaps",
|
||||||
"price": 2.1,
|
"price": 2.10,
|
||||||
"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.5,
|
"price": 3.50,
|
||||||
"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.2,
|
"price": 1.20,
|
||||||
"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.4,
|
"price": 3.40,
|
||||||
"desc": "Verschidene Sorten nur diesen Framstag im Angebot!"
|
"desc": "Verschiedene Sorten nur diesen Framstag im Angebot!"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Softdrinks (0,3l)",
|
"name": "Softdrinks (0,3l)",
|
||||||
"price": 2.9,
|
"price": 2.90,
|
||||||
"desc": "Verschidene Sorten nur diesen Framstag im Angebot!"
|
"desc": "Verschidene Sorten nur diesen Framstag im Angebot!"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Wasser (1l)",
|
"name": "Wasser (1l)",
|
||||||
"price": 4.1,
|
"price": 4.10,
|
||||||
"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.5,
|
"price": 3.50,
|
||||||
"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,
|
"price": 3.00,
|
||||||
"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.4,
|
"price": 2.40,
|
||||||
"desc": "Tsingtao-Exportbier"
|
"desc": "Tsingtao-Exportbier"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Chinesisches Bier (0,42l)",
|
"name": "Chinesisches Bier (0,42l)",
|
||||||
"price": 1.9,
|
"price": 1.90,
|
||||||
"desc": "Tsingtao-Exportbier"
|
"desc": "Tsingtao-Exportbier"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Rislinger Wein (0,2l)",
|
"name": "Rislinger Wein (0,2l)",
|
||||||
"price": 4.2,
|
"price": 4.20,
|
||||||
"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.2,
|
"price": 13.20,
|
||||||
"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.5,
|
"price": 1.50,
|
||||||
"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.6,
|
"price": 1.60,
|
||||||
"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.3,
|
"price": 9.30,
|
||||||
"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.6,
|
"price": 5.60,
|
||||||
"desc": "Ausgefuchste Kombination von Schwanz und Schwanz des Hans und Franz"
|
"desc": "Ausgefuchste Kombination vom Schwanz und Schwanz des Hans und Franz"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Der Reisende",
|
"name": "Der Reisende",
|
||||||
"price": 8.9,
|
"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)"
|
"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": "Piña Reisolada",
|
||||||
"price": 6.1,
|
"price": 6.10,
|
||||||
"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"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -53,7 +53,7 @@
|
|||||||
{
|
{
|
||||||
"name": "Henker's Mahlzeit",
|
"name": "Henker's Mahlzeit",
|
||||||
"price": 6.80,
|
"price": 6.80,
|
||||||
"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",
|
||||||
@@ -69,7 +69,7 @@
|
|||||||
{
|
{
|
||||||
"name": "Grillplatte \"China\"",
|
"name": "Grillplatte \"China\"",
|
||||||
"price": 11.20,
|
"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"
|
"desc": "Ein großes, paniertes Schnitzel in Form des Landes china dazu Tibet-formender Reis, Ente im Pazifik und Hähnchen als Peking geformt"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Reis mit Reis",
|
"name": "Reis mit Reis",
|
||||||
@@ -94,7 +94,7 @@
|
|||||||
{
|
{
|
||||||
"name": "Money Boy",
|
"name": "Money Boy",
|
||||||
"price": 95.90,
|
"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é"
|
"desc": "Goldfarbener Reis mit in Gold überzogener Hähnchenbrust in Champagner-Soße dazu goldfarbenes Brot aus Provìnce de uberteuereé"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Reis-otto",
|
"name": "Reis-otto",
|
||||||
@@ -141,7 +141,7 @@
|
|||||||
{
|
{
|
||||||
"name": "Eierreiskuchen",
|
"name": "Eierreiskuchen",
|
||||||
"price": 5.00,
|
"price": 5.00,
|
||||||
"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 eingearbeitetem Reis, dazu feinster Powidl (regional auch Pflaumenmuß) genannt"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Süßes Reisotto",
|
"name": "Süßes Reisotto",
|
||||||
@@ -151,7 +151,7 @@
|
|||||||
{
|
{
|
||||||
"name": "Reisstrudel",
|
"name": "Reisstrudel",
|
||||||
"price": 5.60,
|
"price": 5.60,
|
||||||
"desc": "In Blätterteil gewickelter Reis mit Milchcreme und Minze, dazu Vanillesoße und eine Kugel Vanilleeis"
|
"desc": "In Blätterteig gewickelter Reis mit Milchcreme und Minze, dazu Vanillesoße und eine Kugel Vanilleeis"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -164,7 +164,7 @@
|
|||||||
{
|
{
|
||||||
"name": "Reiswein",
|
"name": "Reiswein",
|
||||||
"price": 3.90,
|
"price": 3.90,
|
||||||
"desc": "Exquisiter Reiswein mit leiter gelblicher Färbung aus eigener Herstellung mit über 1337 Jahren Erfahrung (Alkoholgehalt 13,37%)"
|
"desc": "Exquisiter Reiswein mit leicht gelblicher Färbung aus eigener Herstellung mit über 1337 Jahren Erfahrung (Alkoholgehalt 13,37%)"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Reisschnaps",
|
"name": "Reisschnaps",
|
||||||
@@ -190,7 +190,7 @@
|
|||||||
{
|
{
|
||||||
"name": "Softdrinks (0,5l)",
|
"name": "Softdrinks (0,5l)",
|
||||||
"price": 3.40,
|
"price": 3.40,
|
||||||
"desc": "Verschidene Sorten nur diesen Framstag im Angebot!"
|
"desc": "Verschiedene Sorten nur diesen Framstag im Angebot!"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Softdrinks (0,3l)",
|
"name": "Softdrinks (0,3l)",
|
||||||
@@ -268,7 +268,7 @@
|
|||||||
{
|
{
|
||||||
"name": "Schwanz-Schwanz",
|
"name": "Schwanz-Schwanz",
|
||||||
"price": 5.60,
|
"price": 5.60,
|
||||||
"desc": "Ausgefuchste Kombination von Schwanz und Schwanz des Hans und Franz"
|
"desc": "Ausgefuchste Kombination vom Schwanz und Schwanz des Hans und Franz"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Der Reisende",
|
"name": "Der Reisende",
|
||||||
@@ -276,7 +276,7 @@
|
|||||||
"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": "Piña Reisolada",
|
||||||
"price": 6.10,
|
"price": 6.10,
|
||||||
"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"
|
||||||
}
|
}
|
||||||
|
|||||||
31
data/reservation.json
Normal file
31
data/reservation.json
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
{
|
||||||
|
"items": [
|
||||||
|
{
|
||||||
|
"name": "Hans Bauer",
|
||||||
|
"desc": "Kleine Familienfeier zu meinem 80. Geburtstag",
|
||||||
|
"email": "hans@gmx.de",
|
||||||
|
"person": 20,
|
||||||
|
"time": "20:15",
|
||||||
|
"date": "16.05.2016",
|
||||||
|
"read": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Micha Müller",
|
||||||
|
"desc": "Ich will meiner geliebten Ursula einen Heiratsantrag machen. Ich suche ein gemütliches Eckchen.",
|
||||||
|
"email": "micha@mueller.de",
|
||||||
|
"person": 3,
|
||||||
|
"time": "21:00",
|
||||||
|
"date": "14.3.2016",
|
||||||
|
"read": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Spa Mer",
|
||||||
|
"desc": "Das ist eine <b>versuchte</b> Injection\r\nmit mehreren Zeilen.",
|
||||||
|
"email": "ano.ny@mus.com",
|
||||||
|
"person": 1337,
|
||||||
|
"time": "00:00",
|
||||||
|
"date": "01.01.2016",
|
||||||
|
"read": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
31
data/reservation.json.example
Normal file
31
data/reservation.json.example
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
{
|
||||||
|
"items": [
|
||||||
|
{
|
||||||
|
"name": "Hans Bauer",
|
||||||
|
"desc": "Kleine Familienfeier zu meinem 80. Geburtstag",
|
||||||
|
"email": "hans@gmx.de",
|
||||||
|
"person": 20,
|
||||||
|
"time": "20:15",
|
||||||
|
"date": "16.05.2016",
|
||||||
|
"read": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Micha Müller",
|
||||||
|
"desc": "Ich will meiner geliebten Ursula einen Heiratsantrag machen. Ich suche ein gemütliches Eckchen.",
|
||||||
|
"email": "micha@mueller.de",
|
||||||
|
"person": 3,
|
||||||
|
"time": "21:00",
|
||||||
|
"date": "14.3.2016",
|
||||||
|
"read": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Spa Mer",
|
||||||
|
"desc": "Das ist eine <b>versuchte</b> Injection\r\nmit mehreren Zeilen.",
|
||||||
|
"email": "ano.ny@mus.com",
|
||||||
|
"person": 1337,
|
||||||
|
"time": "00:00",
|
||||||
|
"date": "01.01.2016",
|
||||||
|
"read": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
20
data/users.json
Normal file
20
data/users.json
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"Richard Reis": {
|
||||||
|
"pwd": "secret",
|
||||||
|
"rights": [
|
||||||
|
null,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"Ursula Ulstein": {
|
||||||
|
"pwd": "ultimativ",
|
||||||
|
"rights": [
|
||||||
|
null,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
false
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
20
data/users.json.example
Normal file
20
data/users.json.example
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"Richard Reis": {
|
||||||
|
"pwd": "secret",
|
||||||
|
"rights": [
|
||||||
|
null,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"Ursula Ulstein": {
|
||||||
|
"pwd": "ultimativ",
|
||||||
|
"rights": [
|
||||||
|
null,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
false
|
||||||
|
]
|
||||||
|
},
|
||||||
|
}
|
||||||
87
main.js
87
main.js
@@ -4,7 +4,7 @@ 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 menuMod = require('./modules/menu');
|
var menuMod = require('./modules/menu');
|
||||||
//var path = require('path');
|
var reservationMod = require('./modules/reservation');
|
||||||
var fs = require('fs');
|
var fs = require('fs');
|
||||||
|
|
||||||
var app = express();
|
var app = express();
|
||||||
@@ -17,7 +17,7 @@ var app = express();
|
|||||||
// **************************
|
// **************************
|
||||||
|
|
||||||
app.set('view engine', 'jade');
|
app.set('view engine', 'jade');
|
||||||
app.set('rundir', '.');
|
app.set('rundir', __dirname);
|
||||||
app.set('views', app.get('rundir') + '/views');
|
app.set('views', app.get('rundir') + '/views');
|
||||||
|
|
||||||
|
|
||||||
@@ -46,7 +46,9 @@ app.use('/bin', express.static(app.get('rundir') + '/public'));
|
|||||||
// INIT
|
// INIT
|
||||||
// **************************
|
// **************************
|
||||||
|
|
||||||
|
loginMod.init(app.get('rundir') + '/data/users.json');
|
||||||
menuMod.init(app.get('rundir') + '/data/menu.json');
|
menuMod.init(app.get('rundir') + '/data/menu.json');
|
||||||
|
reservationMod.init(app.get('rundir') + '/data/reservation.json');
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -87,22 +89,91 @@ app.post('/speisekarte', function(req, res) {
|
|||||||
error = menuMod.updateValue(name, desc, price, nametag);
|
error = menuMod.updateValue(name, desc, price, nametag);
|
||||||
else if (action == menuMod.MenuAction.DELETE)
|
else if (action == menuMod.MenuAction.DELETE)
|
||||||
error = menuMod.deleteValue(nametag);
|
error = menuMod.deleteValue(nametag);
|
||||||
console.log(error);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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: menuMod.getJSON()
|
menuJSON: menuMod.getJSON(),
|
||||||
|
statusMessage: menuMod.getStatusMessage(error, action, nametag)
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
app.get('/kontakt', function(req, res) {
|
app.get('/kontakt', function(req, res) {
|
||||||
|
var showItem = null;
|
||||||
|
var nametag = req.query.nametag;
|
||||||
|
if (loginMod.hasAccess(req, loginMod.AdminRight.RESERVATION)) {
|
||||||
|
var action = reservationMod.determineAction(nametag);
|
||||||
|
if (action == reservationMod.MenuAction.SHOW) {
|
||||||
|
showItem = reservationMod.showValue(nametag);
|
||||||
|
}
|
||||||
|
}
|
||||||
res.render('contact', {
|
res.render('contact', {
|
||||||
title: 'Restaurant Reiskorn | Kontakt',
|
title: 'Restaurant Reiskorn | Kontakt',
|
||||||
loginName: loginMod.getName(req),
|
loginName: loginMod.getName(req),
|
||||||
menuJSON: menuMod.getJSON()
|
isAdmin: loginMod.hasAccess(req, loginMod.AdminRight.RESERVATION),
|
||||||
|
menuJSON: menuMod.getJSON(),
|
||||||
|
editItem: showItem,
|
||||||
|
listItem: reservationMod.getJSON()["items"]
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
app.post('/kontakt', function(req, res) {
|
||||||
|
var nametag = req.body.nametag;
|
||||||
|
var name = req.body.name;
|
||||||
|
var desc = req.body.desc;
|
||||||
|
var email = req.body.email;
|
||||||
|
var person = req.body.person;
|
||||||
|
var time = req.body.time;
|
||||||
|
var date = req.body.date;
|
||||||
|
|
||||||
|
var action = reservationMod.determineAction(nametag);
|
||||||
|
var error = 0;
|
||||||
|
var showItem = null;
|
||||||
|
|
||||||
|
if (action == reservationMod.MenuAction.CREATE) {
|
||||||
|
error = reservationMod.addValue(name, desc, person, email, date, time, nametag);
|
||||||
|
if (error) {
|
||||||
|
showItem = {
|
||||||
|
name: name,
|
||||||
|
desc: desc,
|
||||||
|
email: email,
|
||||||
|
person: person,
|
||||||
|
time: time,
|
||||||
|
date: date
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (loginMod.hasAccess(req, loginMod.AdminRight.RESERVATION)) {
|
||||||
|
if (action == reservationMod.MenuAction.UPDATE) {
|
||||||
|
error = reservationMod.updateValue(name, desc, person, email, date, time, nametag);
|
||||||
|
if (error) {
|
||||||
|
showItem = {
|
||||||
|
name: name,
|
||||||
|
desc: desc,
|
||||||
|
email: email,
|
||||||
|
person: person,
|
||||||
|
time: time,
|
||||||
|
date: date,
|
||||||
|
id: nametag
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (action == reservationMod.MenuAction.DELETE)
|
||||||
|
error = reservationMod.deleteValue(nametag);
|
||||||
|
else if (action == reservationMod.MenuAction.READ)
|
||||||
|
error = reservationMod.readValue(nametag);
|
||||||
|
}
|
||||||
|
|
||||||
|
res.render('contact', {
|
||||||
|
title: 'Restaurant Reiskorn | Kontakt',
|
||||||
|
loginName: loginMod.getName(req),
|
||||||
|
isAdmin: loginMod.hasAccess(req, loginMod.AdminRight.RESERVATION),
|
||||||
|
menuJSON: menuMod.getJSON(),
|
||||||
|
editItem: showItem,
|
||||||
|
listItem: reservationMod.getJSON()["items"],
|
||||||
|
statusMessage: reservationMod.getStatusMessage(error, action)
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -143,9 +214,13 @@ app.post('/login', function(req, res) {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
app.get('/api/specialOffer.json', function(req, res) {
|
||||||
|
res.json({ rice: "Neuer Waldreis" });
|
||||||
|
});
|
||||||
|
|
||||||
var server = app.listen(3000, function() {
|
var server = app.listen(3000, function() {
|
||||||
var host = server.address().address;
|
var host = server.address().address;
|
||||||
var port = server.address().port;
|
var port = server.address().port;
|
||||||
|
|
||||||
console.log('Example app listening at http://%s:%s', host, port);
|
console.log('App listening at http://%s:%s', host, port);
|
||||||
});
|
});
|
||||||
@@ -1,20 +1,20 @@
|
|||||||
var admins = {
|
var fs = require('fs');
|
||||||
"Richard Reis": {
|
|
||||||
pwd: "secret",
|
var admins = {};
|
||||||
rights: {
|
|
||||||
1: true,
|
var FILENAME = false;
|
||||||
2: true,
|
|
||||||
3: true
|
module.exports.init = function(userfile) {
|
||||||
}
|
FILENAME = userfile;
|
||||||
},
|
module.exports.loadFile();
|
||||||
"Ursula Ulstein": {
|
}
|
||||||
pwd: "ultimativ",
|
|
||||||
rights: {
|
module.exports.loadFile = function() {
|
||||||
1: true,
|
if (!FILENAME) throw "No file for user JSON specified";
|
||||||
2: true,
|
fs.readFile(FILENAME, 'utf8', function(err, data) {
|
||||||
3: false
|
if (err) throw err;
|
||||||
}
|
admins = JSON.parse(data);
|
||||||
},
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports.AdminRight = {
|
module.exports.AdminRight = {
|
||||||
|
|||||||
@@ -8,7 +8,28 @@ var menuJSON = {
|
|||||||
var REGEX_CREATE = /^[fd]-[0-9]+-new$/;
|
var REGEX_CREATE = /^[fd]-[0-9]+-new$/;
|
||||||
var REGEX_UPDATE = /^[fd]-[0-9]+-[0-9]+$/;
|
var REGEX_UPDATE = /^[fd]-[0-9]+-[0-9]+$/;
|
||||||
var REGEX_DELETE = /^[fd]-[0-9]+-[0-9]+-del$/;
|
var REGEX_DELETE = /^[fd]-[0-9]+-[0-9]+-del$/;
|
||||||
var REGEX_FLOAT = /^(\-|\+)?([0-9]+(\.[0-9]+)?)$/;
|
|
||||||
|
var REGEX_FLOAT = /^([0-9]+(\.[0-9]+)?)$/;
|
||||||
|
|
||||||
|
var LANG = {};
|
||||||
|
LANG["ACTIONS"] = {
|
||||||
|
1: "Das Ertellen des Menüeintrags",
|
||||||
|
2: "Das Aktualisieren der Informationen",
|
||||||
|
3: "Das Löschen des Menüeintrags"
|
||||||
|
};
|
||||||
|
LANG["ERROR_MESSAGES"] = {
|
||||||
|
1: "Das Feld \"Name\" darf nicht leer sein.",
|
||||||
|
2: "Das Feld \"Beschreibung\" darf nicht leer sein.",
|
||||||
|
4: "Das Feld \"Preis\" darf nicht leer und muss eine positive Zahl sein.",
|
||||||
|
8: "Beim Verarbeiten der Anfrage ist ein interner Fehler aufgetreten."
|
||||||
|
};
|
||||||
|
LANG["MESSAGES"] = {
|
||||||
|
"success": "%action% war erfolgreich.",
|
||||||
|
"failure": "%action% konnte nicht durchgeführt werden."
|
||||||
|
};
|
||||||
|
LANG["INTERNAL"] = {
|
||||||
|
"noinput": "No input file for menu JSON specified!"
|
||||||
|
};
|
||||||
|
|
||||||
var FILENAME = false;
|
var FILENAME = false;
|
||||||
|
|
||||||
@@ -18,7 +39,7 @@ module.exports.init = function(menufile) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
module.exports.loadFile = function() {
|
module.exports.loadFile = function() {
|
||||||
if (!FILENAME) throw "No file for menu JSON specified";
|
if (!FILENAME) throw LANG["MESSAGES"]["noinput"];
|
||||||
fs.readFile(FILENAME, 'utf8', function(err, data) {
|
fs.readFile(FILENAME, 'utf8', function(err, data) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
menuJSON = JSON.parse(data);
|
menuJSON = JSON.parse(data);
|
||||||
@@ -26,7 +47,7 @@ module.exports.loadFile = function() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
module.exports.saveJSON = function() {
|
module.exports.saveJSON = function() {
|
||||||
if (!FILENAME) throw "No file for menu JSON specified";
|
if (!FILENAME) throw LANG["MESSAGES"]["noinput"];
|
||||||
fs.writeFile(FILENAME, JSON.stringify(menuJSON, null, 4), function(err) {
|
fs.writeFile(FILENAME, JSON.stringify(menuJSON, null, 4), function(err) {
|
||||||
if(err) {
|
if(err) {
|
||||||
console.log(err);
|
console.log(err);
|
||||||
@@ -50,6 +71,36 @@ module.exports.ErrorCode = {
|
|||||||
NOFLOAT_PRICE: 4,
|
NOFLOAT_PRICE: 4,
|
||||||
WRONG_ACTION: 8
|
WRONG_ACTION: 8
|
||||||
}
|
}
|
||||||
|
module.exports.ErrorCode["MAX"] = sum(module.exports.ErrorCode);
|
||||||
|
|
||||||
|
module.exports.getStatusMessage = function(errorCode, action, nametag) {
|
||||||
|
if (action) {
|
||||||
|
var position = splitNameTag(nametag, action);
|
||||||
|
if (!errorCode) {
|
||||||
|
return {
|
||||||
|
type: "success",
|
||||||
|
message: LANG["MESSAGES"]["success"].replace("%action%", LANG["ACTIONS"][action]),
|
||||||
|
reasons: null,
|
||||||
|
anchor: menuJSON[position.category][position.section]["anchor"]
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
var reasons = [];
|
||||||
|
for (var i = 1; i < module.exports.ErrorCode["MAX"]; i=i*2) {
|
||||||
|
if (errorCode & i) { // bit-wise comparing
|
||||||
|
reasons.push(LANG["ERROR_MESSAGES"][i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
type: "danger",
|
||||||
|
message: LANG["MESSAGES"]["failure"].replace("%action%", LANG["ACTIONS"][action]),
|
||||||
|
reasons: reasons,
|
||||||
|
anchor: menuJSON[position.category][position.section]["anchor"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
module.exports.determineAction = function(nametag) {
|
module.exports.determineAction = function(nametag) {
|
||||||
if (nametag && REGEX_CREATE.test(nametag)) { // new
|
if (nametag && REGEX_CREATE.test(nametag)) { // new
|
||||||
@@ -136,6 +187,16 @@ var filterFloat = function(value) {
|
|||||||
return NaN;
|
return NaN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function sum(obj) {
|
||||||
|
var sum = 0;
|
||||||
|
for(var el in obj) {
|
||||||
|
if(obj.hasOwnProperty(el)) {
|
||||||
|
sum += parseFloat(obj[el]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sum;
|
||||||
|
}
|
||||||
|
|
||||||
var splitNameTag = function(nametag, action) {
|
var splitNameTag = function(nametag, action) {
|
||||||
if (action) { // create, update & delete
|
if (action) { // create, update & delete
|
||||||
var splitArr = nametag.split("-");
|
var splitArr = nametag.split("-");
|
||||||
|
|||||||
272
modules/reservation.js
Normal file
272
modules/reservation.js
Normal file
@@ -0,0 +1,272 @@
|
|||||||
|
var fs = require('fs');
|
||||||
|
|
||||||
|
var reservationJSON = {
|
||||||
|
"items": []
|
||||||
|
};
|
||||||
|
|
||||||
|
var REGEX_CREATE = /^new$/;
|
||||||
|
var REGEX_UPDATE = /^[0-9]+$/;
|
||||||
|
var REGEX_DELETE = /^[0-9]+-del$/;
|
||||||
|
var REGEX_SHOW = /^[0-9]+-edit$/;
|
||||||
|
var REGEX_READ = /^[0-9]+-read$/;
|
||||||
|
|
||||||
|
var REGEX_INT = /^(\-|\+)?([0-9]+)$/;
|
||||||
|
var REGEX_EMAIL = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
|
||||||
|
var REGEX_TIME = /^(([01][0-9]|2[0-4]):[0-5][0-9])$/;
|
||||||
|
var REGEX_DATE = /^(([0-2][0-9]|3[01]).(0[0-9]|1[012]).[0-9]{4})$/;
|
||||||
|
|
||||||
|
var LANG = {};
|
||||||
|
LANG["ACTIONS"] = {
|
||||||
|
1: "Das Reservieren",
|
||||||
|
2: "Das Aktualisieren der Informationen",
|
||||||
|
3: "Das Löschen der Reservierung",
|
||||||
|
4: "Das Anzeigen der Inforationen",
|
||||||
|
5: "Das Setzen des Gelesen-Status"
|
||||||
|
};
|
||||||
|
LANG["ERROR_MESSAGES"] = {
|
||||||
|
1: "Das Feld \"Name\" darf nicht leer sein.",
|
||||||
|
2: "Das Feld \"Kommentar\" darf nicht leer sein.",
|
||||||
|
4: "Das Feld \"Anzahl der Personen\" darf nicht leer und muss eine ganze, positive Zahl sein.",
|
||||||
|
8: "Das Feld \"Datum\" darf nicht leer sein und muss einem gültigen Datum im Format TT.MM.JJJJ entsprechen.",
|
||||||
|
16: "Das Feld \"Uhrzeit\" darf nicht leer sein und muss einer gültigen Uhrzeit im Format HH:MM entsprechen.",
|
||||||
|
32: "Das Feld \"E-Mail\" darf nicht leer und muss eine gültige E-Mail-Adresse sein.",
|
||||||
|
64: "Beim Verarbeiten der Anfrage ist ein interner Fehler aufgetreten."
|
||||||
|
};
|
||||||
|
LANG["MESSAGES"] = {
|
||||||
|
"success": "%action% war erfolgreich.",
|
||||||
|
"failure": "%action% konnte nicht durchgeführt werden."
|
||||||
|
};
|
||||||
|
LANG["INTERNAL"] = {
|
||||||
|
"noinput": "No input file for reservation JSON specified!"
|
||||||
|
};
|
||||||
|
|
||||||
|
var FILENAME = false;
|
||||||
|
|
||||||
|
module.exports.init = function(reservationfile) {
|
||||||
|
FILENAME = reservationfile;
|
||||||
|
module.exports.loadFile();
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports.loadFile = function() {
|
||||||
|
if (!FILENAME) throw LANG["MESSAGES"]["noinput"];
|
||||||
|
fs.readFile(FILENAME, 'utf8', function(err, data) {
|
||||||
|
if (err) throw err;
|
||||||
|
reservationJSON = JSON.parse(data);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports.saveJSON = function() {
|
||||||
|
if (!FILENAME) throw LANG["MESSAGES"]["noinput"];
|
||||||
|
fs.writeFile(FILENAME, JSON.stringify(reservationJSON, null, 4), function(err) {
|
||||||
|
if(err) {
|
||||||
|
console.log(err);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports.MenuAction = {
|
||||||
|
ERROR: 0,
|
||||||
|
CREATE: 1,
|
||||||
|
UPDATE: 2,
|
||||||
|
DELETE: 3,
|
||||||
|
SHOW: 4,
|
||||||
|
READ: 5
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports.ErrorCode = {
|
||||||
|
SUCCESS: 0,
|
||||||
|
NOSTRING_NAME: 1,
|
||||||
|
NOSTRING_DESC: 2,
|
||||||
|
NONUMBER_PERS: 4,
|
||||||
|
NODATE_DATE: 8,
|
||||||
|
NOTIME_TIME: 16,
|
||||||
|
NOEMAIL_MAIL: 32,
|
||||||
|
WRONG_ACTION: 64
|
||||||
|
}
|
||||||
|
module.exports.ErrorCode["MAX"] = sum(module.exports.ErrorCode);
|
||||||
|
|
||||||
|
module.exports.getStatusMessage = function(errorCode, action) {
|
||||||
|
if (action) {
|
||||||
|
if (!errorCode) {
|
||||||
|
return {
|
||||||
|
type: "success",
|
||||||
|
message: LANG["MESSAGES"]["success"].replace("%action%", LANG["ACTIONS"][action]),
|
||||||
|
reasons: null
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
var reasons = [];
|
||||||
|
for (var i = 1; i < module.exports.ErrorCode["MAX"]; i=i*2) {
|
||||||
|
if (errorCode & i) { // bit-wise comparing
|
||||||
|
reasons.push(LANG["ERROR_MESSAGES"][i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
type: "danger",
|
||||||
|
message: LANG["MESSAGES"]["failure"].replace("%action%", LANG["ACTIONS"][action]),
|
||||||
|
reasons: reasons
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
} else if (nametag && REGEX_SHOW.test(nametag)) { // show
|
||||||
|
return module.exports.MenuAction.SHOW;
|
||||||
|
} else if (nametag && REGEX_READ.test(nametag)) { // read
|
||||||
|
return module.exports.MenuAction.READ;
|
||||||
|
}
|
||||||
|
return module.exports.MenuAction.ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports.checkValidity = function(name, desc, person, email, date, time) {
|
||||||
|
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(filterInt(person)))
|
||||||
|
errorCode += module.exports.ErrorCode.NONUMBER_PERS;
|
||||||
|
if (!REGEX_EMAIL.test(email))
|
||||||
|
errorCode += module.exports.ErrorCode.NOEMAIL_MAIL;
|
||||||
|
if (!REGEX_DATE.test(date))
|
||||||
|
errorCode += module.exports.ErrorCode.NODATE_DATE;
|
||||||
|
if (!REGEX_TIME.test(time))
|
||||||
|
errorCode += module.exports.ErrorCode.NOTIME_TIME;
|
||||||
|
|
||||||
|
return errorCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports.addValue = function(name, desc, person, email, date, time, nametag) {
|
||||||
|
var errorCode = module.exports.checkValidity(name, desc, person, email, date, time);
|
||||||
|
var action = module.exports.determineAction(nametag);
|
||||||
|
if (action !== module.exports.MenuAction.CREATE) {
|
||||||
|
errorCode += module.exports.ErrorCode.WRONG_ACTION;
|
||||||
|
}
|
||||||
|
if (!errorCode) {
|
||||||
|
person = filterInt(person);
|
||||||
|
reservationJSON["items"].push({
|
||||||
|
name: name,
|
||||||
|
desc: desc,
|
||||||
|
email: email,
|
||||||
|
person: person,
|
||||||
|
time: time,
|
||||||
|
date: date,
|
||||||
|
read: false
|
||||||
|
});
|
||||||
|
module.exports.saveJSON();
|
||||||
|
}
|
||||||
|
return errorCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports.updateValue = function(name, desc, person, email, date, time, nametag) {
|
||||||
|
var errorCode = module.exports.checkValidity(name, desc, person, email, date, time);
|
||||||
|
var action = module.exports.determineAction(nametag);
|
||||||
|
if (action !== module.exports.MenuAction.UPDATE) {
|
||||||
|
errorCode += module.exports.ErrorCode.WRONG_ACTION;
|
||||||
|
}
|
||||||
|
if (!errorCode) {
|
||||||
|
person = filterInt(person);
|
||||||
|
var position = splitNameTag(nametag, action);
|
||||||
|
reservationJSON["items"][position.id] = {
|
||||||
|
name: name,
|
||||||
|
desc: desc,
|
||||||
|
email: email,
|
||||||
|
person: person,
|
||||||
|
time: time,
|
||||||
|
date: date,
|
||||||
|
read: true
|
||||||
|
};
|
||||||
|
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);
|
||||||
|
reservationJSON["items"].splice(position.id, 1);
|
||||||
|
module.exports.saveJSON();
|
||||||
|
}
|
||||||
|
return errorCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports.showValue = function(nametag) {
|
||||||
|
var errorCode = module.exports.ErrorCode.SUCCESS;
|
||||||
|
var action = module.exports.determineAction(nametag);
|
||||||
|
if (action !== module.exports.MenuAction.SHOW) {
|
||||||
|
errorCode += module.exports.ErrorCode.WRONG_ACTION;
|
||||||
|
}
|
||||||
|
if (!errorCode) {
|
||||||
|
var position = splitNameTag(nametag, action);
|
||||||
|
result = reservationJSON["items"][position.id];
|
||||||
|
result.id = position.id;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
return errorCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports.readValue = function(nametag) {
|
||||||
|
var errorCode = module.exports.ErrorCode.SUCCESS;
|
||||||
|
var action = module.exports.determineAction(nametag);
|
||||||
|
if (action !== module.exports.MenuAction.READ) {
|
||||||
|
errorCode += module.exports.ErrorCode.WRONG_ACTION;
|
||||||
|
}
|
||||||
|
if (!errorCode) {
|
||||||
|
var position = splitNameTag(nametag, action);
|
||||||
|
reservationJSON["items"][position.id]["read"] = !reservationJSON["items"][position.id]["read"];
|
||||||
|
module.exports.saveJSON();
|
||||||
|
}
|
||||||
|
return errorCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports.getJSON = function() {
|
||||||
|
return reservationJSON;
|
||||||
|
}
|
||||||
|
|
||||||
|
var filterInt = function(value) {
|
||||||
|
if(REGEX_INT.test(value))
|
||||||
|
return Number(value);
|
||||||
|
return NaN;
|
||||||
|
}
|
||||||
|
|
||||||
|
function sum(obj) {
|
||||||
|
var sum = 0;
|
||||||
|
for(var el in obj) {
|
||||||
|
if(obj.hasOwnProperty(el)) {
|
||||||
|
sum += parseFloat(obj[el]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
var splitNameTag = function(nametag, action) {
|
||||||
|
if (action) { // create, update, show, read & delete
|
||||||
|
var splitArr = nametag.split("-");
|
||||||
|
var result = {};
|
||||||
|
result.type = action;
|
||||||
|
if (action == module.exports.MenuAction.CREATE) { // create
|
||||||
|
result.id = null;
|
||||||
|
} else { // update, show, read & delete
|
||||||
|
result.id = parseInt(splitArr[0]);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -81,7 +81,6 @@ textarea {
|
|||||||
#carousel-home_carousel {
|
#carousel-home_carousel {
|
||||||
max-width: 1170px;
|
max-width: 1170px;
|
||||||
margin: auto;
|
margin: auto;
|
||||||
padding: 0 15px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn {
|
.btn {
|
||||||
@@ -89,6 +88,10 @@ textarea {
|
|||||||
margin-right: auto;
|
margin-right: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
/* Login menu */
|
/* Login menu */
|
||||||
|
|
||||||
#loginDropdown {
|
#loginDropdown {
|
||||||
@@ -119,4 +122,21 @@ textarea {
|
|||||||
#loginDropdown {
|
#loginDropdown {
|
||||||
min-width: 300px;
|
min-width: 300px;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* reservation form */
|
||||||
|
|
||||||
|
@media only screen and (min-width : 992px) {
|
||||||
|
.no-padding-md {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Carousel Fix
|
||||||
|
*/
|
||||||
|
|
||||||
|
.carousel-fullwidth {
|
||||||
|
padding-left: 0;
|
||||||
|
padding-right: 0;
|
||||||
}
|
}
|
||||||
12
public/js/angular-init.js
vendored
12
public/js/angular-init.js
vendored
@@ -1,4 +1,16 @@
|
|||||||
var app = angular.module('myApp', []);
|
var app = angular.module('myApp', []);
|
||||||
|
|
||||||
|
app.controller("indexController", function ($scope, specialService) {
|
||||||
|
$scope.rice = "Hello World";
|
||||||
|
specialService.success(function(data) {
|
||||||
|
$scope.rice = data.rice;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
app.factory("specialService", function ($http) {
|
||||||
|
return $http.get('/api/specialOffer.json');
|
||||||
|
});
|
||||||
|
|
||||||
app.directive('rrMap', function() {
|
app.directive('rrMap', function() {
|
||||||
return {
|
return {
|
||||||
restrict: 'A',
|
restrict: 'A',
|
||||||
|
|||||||
@@ -1,4 +1,97 @@
|
|||||||
extends ./wrapper
|
extends ./wrapper
|
||||||
|
|
||||||
|
mixin reservation-form(id, name, desc, email, person, time, date, message)
|
||||||
|
.row
|
||||||
|
form.col-md-10.col-md-offset-1.orange(method="post",action="/kontakt")
|
||||||
|
if message
|
||||||
|
+status-message(message.type, message.message, message.reasons)
|
||||||
|
.row
|
||||||
|
.col-md-6
|
||||||
|
+input-val("name","id-name","Max Mustermann","Name:","name",name)
|
||||||
|
+input-val("number","id-person","2","Anzahl der Personen:","person",person)
|
||||||
|
.col-md-6.no-padding-md
|
||||||
|
.row
|
||||||
|
.col-sm-6
|
||||||
|
+input-val("date","id-date","TT.MM.JJJJ","Datum:","date",date)
|
||||||
|
.col-sm-6
|
||||||
|
+input-val("datetime-local","id-time","HH:MM","Uhrzeit:","time",time)
|
||||||
|
.row
|
||||||
|
.col-md-12
|
||||||
|
+input-val("email","id-mail","max.mustermann@mail.de","E-Mail-Adresse:","email",email)
|
||||||
|
.row
|
||||||
|
.col-md-12
|
||||||
|
+textarea-val("id-desc","Weitere Kontaktdaten, Spezielle Essens-, Platzwünsche, ...","Kommentare:","desc",desc,"7")
|
||||||
|
.row
|
||||||
|
.col-md-3.col-md-offset-3.text-center
|
||||||
|
input(type='hidden',name='nametag',value='#{id}')
|
||||||
|
if id="new"
|
||||||
|
button(type="submit",class="btn btn-success") Reservieren
|
||||||
|
else
|
||||||
|
button(type="submit",class="btn btn-success") Reservierung ändern
|
||||||
|
.col-md-3.text-center
|
||||||
|
button(type="reset",class="btn btn-danger") Eingaben löschen
|
||||||
|
|
||||||
|
mixin reservation-list(entries, message)
|
||||||
|
.row
|
||||||
|
if entries.length
|
||||||
|
.col-md-10.col-md-offset-1.stripe
|
||||||
|
if message
|
||||||
|
+status-message(message.type, message.message, message.reasons)
|
||||||
|
each entry, index in entries
|
||||||
|
+reservation-entry(entry.name, entry.desc, entry.person, entry.time, entry.date, entry.read, entry.email, index)
|
||||||
|
else
|
||||||
|
.col-md-10.col-md-offset-1.orange Keine Reservierungen vorhanden.
|
||||||
|
|
||||||
|
mixin reservation-entry(name, desc, person, time, date, read, email, index)
|
||||||
|
.row
|
||||||
|
.col-md-1
|
||||||
|
form(style="display:inline",method="post",action="")
|
||||||
|
input(type='hidden',name='nametag',value="#{index+'-del'}")
|
||||||
|
button.btn.btn-sm.btn-danger(type="submit")
|
||||||
|
+icon("remove")
|
||||||
|
span.hidden-md.hidden-lg Entfernen
|
||||||
|
form(style="display:inline",method="get",action="")
|
||||||
|
input(type='hidden',name='nametag',value="#{index+'-edit'}")
|
||||||
|
button.btn.btn-sm.btn-primary(type="submit")
|
||||||
|
+icon("edit")
|
||||||
|
span.hidden-md.hidden-lg Bearbeiten
|
||||||
|
form(style="display:inline",method="post",action="")
|
||||||
|
input(type='hidden',name='nametag',value="#{index+'-read'}")
|
||||||
|
button.btn.btn-sm.btn-info(type="submit")
|
||||||
|
if read
|
||||||
|
+icon("check")
|
||||||
|
span.hidden-md.hidden-lg Als ungelesen markieren
|
||||||
|
else
|
||||||
|
+icon("unchecked")
|
||||||
|
span.hidden-md.hidden-lg Als gelesen markieren
|
||||||
|
.col-md-7
|
||||||
|
span.lead= name
|
||||||
|
br
|
||||||
|
span.small !{desc.substr(0, 300).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"').replace(/\n/g, '<br/>')}
|
||||||
|
.col-md-4
|
||||||
|
.row
|
||||||
|
.col-md-12= person
|
||||||
|
.row
|
||||||
|
.col-md-12= time
|
||||||
|
.row
|
||||||
|
.col-md-12= date
|
||||||
|
.row
|
||||||
|
.col-md-12= email
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
mixin reservation(item, list, isadmin, message)
|
||||||
|
if isadmin
|
||||||
|
if item
|
||||||
|
+reservation-form(item.id, item.name, item.desc, item.email, item.person, item.time, item.date, message)
|
||||||
|
else
|
||||||
|
+reservation-list(list, message)
|
||||||
|
else
|
||||||
|
if item
|
||||||
|
+reservation-form("new", item.name, item.desc, item.email, item.person, item.time, item.date, message)
|
||||||
|
else
|
||||||
|
+reservation-form("new", "", "", "", "", "", "", message)
|
||||||
|
|
||||||
block vars
|
block vars
|
||||||
- var pageTitle = 'Kontakt'
|
- var pageTitle = 'Kontakt'
|
||||||
block content
|
block content
|
||||||
@@ -6,25 +99,7 @@ block content
|
|||||||
a(name="reservierung")
|
a(name="reservierung")
|
||||||
h1 Reservierung
|
h1 Reservierung
|
||||||
.container
|
.container
|
||||||
.row
|
+reservation(editItem, listItem, isAdmin, statusMessage)
|
||||||
.col-md-10.col-md-offset-1.orange
|
|
||||||
.row
|
|
||||||
.col-md-6
|
|
||||||
+input("name","id-name","Max Mustermann","Name:")
|
|
||||||
+input("number","id-person","2","Anzahl der Personen:")
|
|
||||||
.col-md-6
|
|
||||||
+input("datetime-local","id-date","TT.MM.JJJJ HH:MM","Datum und Uhrzeit des Besuchs:")
|
|
||||||
+input("email","id-mail","max.mustermann@mail.de","E-Mail-Adresse:")
|
|
||||||
.row
|
|
||||||
.col-md-12
|
|
||||||
.form-group
|
|
||||||
label(for="id-desc") Kommentare:
|
|
||||||
textarea(id="id-desc",class="form-control",type="datetime-local",placeholder="Weitere Kontaktdaten, Spezielle Essens-, Platzwünsche, ...",rows="7")
|
|
||||||
.row
|
|
||||||
.col-md-2.col-md-offset-4
|
|
||||||
button(type="submit",class="btn btn-success") Submit
|
|
||||||
.col-md-2
|
|
||||||
button(type="reset",class="btn btn-danger") Submit
|
|
||||||
a(name="anfahrt")
|
a(name="anfahrt")
|
||||||
h1 Anfahrt
|
h1 Anfahrt
|
||||||
.container
|
.container
|
||||||
@@ -46,7 +121,7 @@ block content
|
|||||||
p
|
p
|
||||||
| 030 110 112 1337
|
| 030 110 112 1337
|
||||||
br
|
br
|
||||||
a(href='reis@korn.de') reis@korn.de
|
a(href='mailto://reis@korn.de') reis@korn.de
|
||||||
a(name="impressum")
|
a(name="impressum")
|
||||||
h1 Impressum
|
h1 Impressum
|
||||||
.container
|
.container
|
||||||
|
|||||||
@@ -2,52 +2,57 @@ extends ./wrapper
|
|||||||
block vars
|
block vars
|
||||||
- var pageTitle = 'Home'
|
- var pageTitle = 'Home'
|
||||||
block content
|
block content
|
||||||
+carousel("home_carousel",[
|
|
||||||
{
|
|
||||||
image:"/bin/image/restaurant-1-chairs.jpg",
|
|
||||||
h1:"Romantisches Dinner",
|
|
||||||
p:"Wie wäre es mit einem Kerzenabend zu zweit?",
|
|
||||||
button:{
|
|
||||||
caption:"Reservieren",
|
|
||||||
url:"/kontakt#reservieren"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
image:"/bin/image/restaurant-2-hall.jpg",
|
|
||||||
h1:"Konferenzraum",
|
|
||||||
p:"Viel Platz für über 200 Gäste",
|
|
||||||
button:{
|
|
||||||
caption:"Reservieren",
|
|
||||||
url:"/kontakt#reservieren"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
image:"/bin/image/restaurant-3-pillar.jpg",
|
|
||||||
h1:"Gemütliche Räumlichkeiten",
|
|
||||||
p:"Bei schlechten Wetter verträumt im fernen Osten",
|
|
||||||
button:{
|
|
||||||
caption:"Anfahrt",
|
|
||||||
url:"/kontakt#anfahrt"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
image:"/bin/image/restaurant-4-buffet.jpg",
|
|
||||||
h1:"Buffet",
|
|
||||||
p:"Vielfältige Auswahl an Speisen und Getränken",
|
|
||||||
button:{
|
|
||||||
caption:"Speisekarte",
|
|
||||||
url:"/speisekarte"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
])
|
|
||||||
.container
|
.container
|
||||||
|
.row
|
||||||
|
.col-md-12.carousel-fullwidth
|
||||||
|
+carousel("home_carousel",[
|
||||||
|
{
|
||||||
|
image:"/bin/image/restaurant-1-chairs.jpg",
|
||||||
|
h1:"Romantisches Dinner",
|
||||||
|
p:"Wie wäre es mit einem Kerzenabend zu zweit?",
|
||||||
|
button:{
|
||||||
|
caption:"Reservieren",
|
||||||
|
url:"/kontakt#reservieren"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
image:"/bin/image/restaurant-2-hall.jpg",
|
||||||
|
h1:"Konferenzraum",
|
||||||
|
p:"Viel Platz für über 200 Gäste",
|
||||||
|
button:{
|
||||||
|
caption:"Reservieren",
|
||||||
|
url:"/kontakt#reservieren"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
image:"/bin/image/restaurant-3-pillar.jpg",
|
||||||
|
h1:"Gemütliche Räumlichkeiten",
|
||||||
|
p:"Bei schlechten Wetter verträumt im fernen Osten",
|
||||||
|
button:{
|
||||||
|
caption:"Anfahrt",
|
||||||
|
url:"/kontakt#anfahrt"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
image:"/bin/image/restaurant-4-buffet.jpg",
|
||||||
|
h1:"Buffet",
|
||||||
|
p:"Vielfältige Auswahl an Speisen und Getränken",
|
||||||
|
button:{
|
||||||
|
caption:"Speisekarte",
|
||||||
|
url:"/speisekarte"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
])
|
||||||
.row
|
.row
|
||||||
.col-md-6.graygray
|
.col-md-6.graygray
|
||||||
+img-responsive-center("/bin/image/rice-world.png","Welt voller Reis")
|
+img-responsive-center("/bin/image/rice-world.png","Welt voller Reis")
|
||||||
.col-md-6.orange Wir bieten Ihnen Reis aus aller Welt. Wählen Sie zwischen 52 verschiedenen Sorten oder lassen Sie sich durch die perfekte Wahl des Chefkochs überraschen.
|
.col-md-6.orange Wir bieten Ihnen Reis aus aller Welt. Wählen Sie zwischen 52 verschiedenen Sorten oder lassen Sie sich durch die perfekte Wahl des Chefkochs überraschen.
|
||||||
|
p.ng-cloak(data-ng-controller="indexController") Die heutige Empfehlung unseres Chefkochs ist "{{rice}}". Alle Gerichte, die mit dieser Reissorte bestellt werden, sind um 1€ vergünstigt!
|
||||||
.row
|
.row
|
||||||
.col-md-6.orange Zur Zubereitung wird regional angebautes Gemüse verwendet. Somit schmeckt das Essen noch frischer und die Umwelt wird geschont. Der Reis stammt aus einem fairen Handel mit Kleinbauern in ganz Asien. Nur so kann der originale Geschmack des Reis gewährt werden und er schmeckt besonders kräftig und intensiv!
|
.col-md-6.graygray.hidden-md.hidden-lg
|
||||||
.col-md-6.graygray
|
+img-responsive-center("/bin/image/vegetables.png","Gemüse")
|
||||||
|
.col-md-6.orange Zur Zubereitung wird regional angebautes Gemüse verwendet, denn nur so schmeckt das Essen noch frischer und die Umwelt wird geschont. Der Reis stammt aus einem fairen Handel mit Kleinbauern in ganz Asien. Nur so kann der originale Geschmack des Reis gewährt werden und er schmeckt besonders kräftig und intensiv!
|
||||||
|
.col-md-6.graygray.hidden-xs.hidden-sm
|
||||||
+img-responsive-center("/bin/image/vegetables.png","Gemüse")
|
+img-responsive-center("/bin/image/vegetables.png","Gemüse")
|
||||||
.row
|
.row
|
||||||
.col-md-6.graygray
|
.col-md-6.graygray
|
||||||
|
|||||||
@@ -1,19 +1,19 @@
|
|||||||
extends ./wrapper
|
extends ./wrapper
|
||||||
|
|
||||||
mixin menu-item-adm(name, desc, price, prefix, newItem)
|
mixin menu-item-adm(name, anchor, desc, price, prefix, newItem)
|
||||||
.row
|
.row
|
||||||
.col-md-1
|
.col-md-1
|
||||||
if newItem
|
if newItem
|
||||||
button.btn.btn-sm.btn-success(type="submit",form="#{prefix}")
|
button.btn.btn-sm.btn-success(type="submit",form="#{prefix}")
|
||||||
+icon("ok")
|
+icon("ok")
|
||||||
else
|
else
|
||||||
form(style="display:inline",method="post",action="")
|
form(style="display:inline",method="post",action="#{'/speisekarte#' + anchor}")
|
||||||
input(type='hidden',name='nametag',value="#{prefix + '-del'}")
|
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}")
|
||||||
+icon("edit")
|
+icon("edit")
|
||||||
form.col-md-11(id="#{prefix}",method="post",action="")
|
form.col-md-11(id="#{prefix}",method="post",action="#{'/speisekarte#' + anchor}")
|
||||||
.col-md-9
|
.col-md-9
|
||||||
input(type='hidden',name='nametag',value='#{prefix}')
|
input(type='hidden',name='nametag',value='#{prefix}')
|
||||||
+input-val-simple("text",prefix + "-name","Name","name","name",name)
|
+input-val-simple("text",prefix + "-name","Name","name","name",name)
|
||||||
@@ -32,16 +32,20 @@ mixin menu-item(name, desc, price)
|
|||||||
p.text-right #{price.toFixed(2).replace(/(\d)(?=(\d{3})+\,)/g, '$1,').replace(/^(.*)\.(.*)$/g, '$1,$2€')}
|
p.text-right #{price.toFixed(2).replace(/(\d)(?=(\d{3})+\,)/g, '$1,').replace(/^(.*)\.(.*)$/g, '$1,$2€')}
|
||||||
|
|
||||||
|
|
||||||
mixin menu-cat(name, anchor, content, adm, prefix)
|
mixin menu-cat(name, anchor, content, adm, prefix, message)
|
||||||
a(name= anchor)
|
a(name= anchor)
|
||||||
h2= name
|
h2= name
|
||||||
.container
|
.container
|
||||||
.row
|
.row
|
||||||
.col-md-10.col-md-offset-1.stripe
|
.col-md-10.col-md-offset-1.stripe
|
||||||
|
if anchor
|
||||||
|
if message
|
||||||
|
if anchor==message.anchor
|
||||||
|
+status-message(message.type, message.message, message.reasons)
|
||||||
if adm
|
if adm
|
||||||
each val, index in content
|
each val, index in content
|
||||||
+menu-item-adm(val.name, val.desc, val.price, prefix + "-" + index, "")
|
+menu-item-adm(val.name, anchor, val.desc, val.price, prefix + "-" + index, "")
|
||||||
+menu-item-adm("", "", "", prefix + "-new", "x")
|
+menu-item-adm("", anchor, "", "", prefix + "-new", "x")
|
||||||
else
|
else
|
||||||
each val, index in content
|
each val, index in content
|
||||||
+menu-item(val.name, val.desc, val.price)
|
+menu-item(val.name, val.desc, val.price)
|
||||||
@@ -49,7 +53,7 @@ mixin menu-cat(name, anchor, content, adm, prefix)
|
|||||||
|
|
||||||
mixin menu-part(part, adm, prefix)
|
mixin menu-part(part, adm, prefix)
|
||||||
each val, index in part
|
each val, index in part
|
||||||
+menu-cat(val.name, val.anchor, val.items, adm, prefix + "-" + index)
|
+menu-cat(val.name, val.anchor, val.items, adm, prefix + "-" + index, statusMessage)
|
||||||
|
|
||||||
block vars
|
block vars
|
||||||
- var pageTitle = 'Speisekarte'
|
- var pageTitle = 'Speisekarte'
|
||||||
|
|||||||
@@ -3,6 +3,11 @@ doctype html
|
|||||||
extends ../node_modules/jade-bootstrap/_bootstrap
|
extends ../node_modules/jade-bootstrap/_bootstrap
|
||||||
|
|
||||||
|
|
||||||
|
mixin textarea-val(id,placeholder,label,name,value,rows)
|
||||||
|
.form-group
|
||||||
|
label(for="#{id}") #{label}
|
||||||
|
textarea.form-control(id="#{id}",placeholder="#{placeholder}",name="#{name}",rows="#{rows}")= value
|
||||||
|
|
||||||
mixin input-val(type,id,placeholder,label,name,value)
|
mixin input-val(type,id,placeholder,label,name,value)
|
||||||
.form-group
|
.form-group
|
||||||
label(for="#{id}") #{label}
|
label(for="#{id}") #{label}
|
||||||
@@ -13,6 +18,13 @@ mixin input-val-simple(type,id,placeholder,label,name,value)
|
|||||||
input.form-control(type="#{type}",id="#{id}",placeholder="#{placeholder}",name="#{name}",value="#{value}")
|
input.form-control(type="#{type}",id="#{id}",placeholder="#{placeholder}",name="#{name}",value="#{value}")
|
||||||
|
|
||||||
|
|
||||||
|
mixin status-message(type, message, reasons)
|
||||||
|
div(class="alert alert-#{type}" role="alert")= message
|
||||||
|
if reasons
|
||||||
|
ul
|
||||||
|
each val in reasons
|
||||||
|
li= val
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
mixin navbar-main(style)
|
mixin navbar-main(style)
|
||||||
@@ -50,7 +62,8 @@ mixin loginBox
|
|||||||
.col-sm-7.text-center
|
.col-sm-7.text-center
|
||||||
a.btn.btn-default(href="/login#admin") Admin-Panel
|
a.btn.btn-default(href="/login#admin") Admin-Panel
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
block styles
|
block styles
|
||||||
//link(rel="stylesheet",type="text/css",href="/bin/bootstrap/css/bootstrap.min.css")
|
//link(rel="stylesheet",type="text/css",href="/bin/bootstrap/css/bootstrap.min.css")
|
||||||
link(rel="stylesheet",type="text/css",href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css")
|
link(rel="stylesheet",type="text/css",href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css")
|
||||||
|
|||||||
Reference in New Issue
Block a user