From 17522dcd65d2c8da009624e9dd93b08cd73e3e68 Mon Sep 17 00:00:00 2001 From: rgemm Date: Sat, 26 Apr 2025 13:05:22 +0200 Subject: [PATCH 01/13] =?UTF-8?q?Hinzuf=C3=BCgen=20der=20Finalen=20Seite?= =?UTF-8?q?=20der=20Bestellung?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/bestellformular/bestellformular.html | 2 +- public/bestellung/bestellung.html | 31 ++++++++++++ scripts/routes/other/route-index.js | 4 ++ .../bestellformular/bestellformular.css | 16 +++--- static/Styles/bestellung/bestellung.css | 49 +++++++++++++++++++ 5 files changed, 94 insertions(+), 8 deletions(-) create mode 100644 public/bestellung/bestellung.html create mode 100644 static/Styles/bestellung/bestellung.css diff --git a/public/bestellformular/bestellformular.html b/public/bestellformular/bestellformular.html index 3f353e3..56b2411 100644 --- a/public/bestellformular/bestellformular.html +++ b/public/bestellformular/bestellformular.html @@ -42,7 +42,7 @@ - + Bestellung absenden diff --git a/public/bestellung/bestellung.html b/public/bestellung/bestellung.html new file mode 100644 index 0000000..54e2885 --- /dev/null +++ b/public/bestellung/bestellung.html @@ -0,0 +1,31 @@ + + + + + + Ihre Bestellung + + + + + + +
+ +
+

Ihre Bestellung:

+
+ +
+

Kundennummer:

+

Produkt-ID:

+

Produktname:

+

Preis:

+
+
+
+ + + + + diff --git a/scripts/routes/other/route-index.js b/scripts/routes/other/route-index.js index d8577e4..3edcb01 100644 --- a/scripts/routes/other/route-index.js +++ b/scripts/routes/other/route-index.js @@ -70,4 +70,8 @@ router.get('/Warenkorb', (req, res) => { router.get('/bestellformular', (req, res) => { res.sendFile(path.join(__dirname, '../../../public/bestellformular/bestellformular.html')); }) + +router.get('/bestellung', (req, res) => { + res.sendFile(path.join(__dirname, '../../../public/bestellung/bestellung.html')); +}) module.exports = router; \ No newline at end of file diff --git a/static/Styles/bestellformular/bestellformular.css b/static/Styles/bestellformular/bestellformular.css index a252b41..e19c126 100644 --- a/static/Styles/bestellformular/bestellformular.css +++ b/static/Styles/bestellformular/bestellformular.css @@ -9,7 +9,7 @@ body { } .wrapper { - flex: 1; /* Der Hauptinhalt (Formular) nimmt den verfügbaren Platz ein */ + flex: 1; /* Der Hauptinhalt nimmt den verfügbaren Platz ein */ } .form-container { @@ -43,20 +43,22 @@ textarea { box-sizing: border-box; } -input[type="submit"] { +/* NEU: Styling für den Absende-Link */ +.button-submit { + display: inline-block; margin-top: 20px; background-color: #ff6600; color: white; - border: none; + text-decoration: none; padding: 12px; border-radius: 5px; font-size: 16px; cursor: pointer; width: 100%; + text-align: center; + box-sizing: border-box; /* Damit Breite + Padding sauber passen */ } -input[type="submit"]:hover { - background-color: #ff5500; /* Ein leicht dunklerer Farbton beim Hover */ +.button-submit:hover { + background-color: #ff6600; } - - diff --git a/static/Styles/bestellung/bestellung.css b/static/Styles/bestellung/bestellung.css new file mode 100644 index 0000000..849719f --- /dev/null +++ b/static/Styles/bestellung/bestellung.css @@ -0,0 +1,49 @@ +/* Allgemeine Layout-Stile */ +body { + font-family: Arial, sans-serif; + background-color: #f2f2f2; + padding: 20px; + margin: 0; + display: flex; + flex-direction: column; + min-height: 100vh; +} + +/* Container für die Bestellinformationen */ +#bestellung { + background-color: #fff; + padding: 20px; + border-radius: 8px; + box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); + margin-top: 20px; +} + +/* Titel */ +h2 { + text-align: center; + margin-bottom: 30px; + margin-top: 20px; +} + +/* Karte für Bestellinformationen */ +.bestell-info-card { + background-color: #fafafa; + padding: 15px; + border-radius: 8px; + margin-bottom: 15px; + box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1); +} + +/* Bestellinformationen formatieren */ +.bestell-info-card p { + font-size: 16px; + margin: 10px 0; +} + +/* Stile für die Label und Platzhalter */ +.bestell-info-card span { + font-weight: bold; + color: #333; +} + + -- 2.39.5 From 9165fb8776d5e2457df502ab12cd3d7f3731dc3d Mon Sep 17 00:00:00 2001 From: rgemm Date: Sat, 26 Apr 2025 13:37:49 +0200 Subject: [PATCH 02/13] anzeigen der Artikel nr. bei den Produkten im Shop --- public/shop/shop.html | 1 + public/shop/shop_lkw.html | 1 + public/shop/shop_motorrad.html | 1 + public/shop/shop_oldtimer.html | 1 + public/shop/shop_sportwagen.html | 1 + 5 files changed, 5 insertions(+) diff --git a/public/shop/shop.html b/public/shop/shop.html index 9e97320..efebcb9 100644 --- a/public/shop/shop.html +++ b/public/shop/shop.html @@ -38,6 +38,7 @@

${product.name}

Preis: ${product.price}€

${product.description}

+

Artikel Nr: ${product.id}

`; container.appendChild(card); diff --git a/public/shop/shop_lkw.html b/public/shop/shop_lkw.html index 2c1af94..8bc028e 100644 --- a/public/shop/shop_lkw.html +++ b/public/shop/shop_lkw.html @@ -35,6 +35,7 @@

${product.name}

Preis: ${product.price}€

${product.description}

+

Artikel Nr: ${product.id}

`; container.appendChild(card); diff --git a/public/shop/shop_motorrad.html b/public/shop/shop_motorrad.html index eacf581..cace4c7 100644 --- a/public/shop/shop_motorrad.html +++ b/public/shop/shop_motorrad.html @@ -36,6 +36,7 @@

${product.name}

Preis: ${product.price}€

${product.description}

+

Artikel Nr: ${product.id}

`; container.appendChild(card); diff --git a/public/shop/shop_oldtimer.html b/public/shop/shop_oldtimer.html index df7bb22..27e27c4 100644 --- a/public/shop/shop_oldtimer.html +++ b/public/shop/shop_oldtimer.html @@ -35,6 +35,7 @@

${product.name}

Preis: ${product.price}€

${product.description}

+

Artikel Nr: ${product.id}

`; container.appendChild(card); diff --git a/public/shop/shop_sportwagen.html b/public/shop/shop_sportwagen.html index e2ee0ae..28c645a 100644 --- a/public/shop/shop_sportwagen.html +++ b/public/shop/shop_sportwagen.html @@ -41,6 +41,7 @@

${product.name}

Preis: ${product.price}€

${product.description}

+

Artikel Nr: ${product.id}

`; container.appendChild(card); -- 2.39.5 From e19015a69798dfd5d00a447b33050b7e77d788c6 Mon Sep 17 00:00:00 2001 From: rgemm Date: Sat, 26 Apr 2025 15:18:11 +0200 Subject: [PATCH 03/13] -removed doppelter Login btn im header --- public/header_footer/header.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/header_footer/header.html b/public/header_footer/header.html index a9ac989..a98e75a 100644 --- a/public/header_footer/header.html +++ b/public/header_footer/header.html @@ -7,7 +7,7 @@
- + 0 -- 2.39.5 From 99d727c0a0d4100b623d47b36ea9c37d5e58a546 Mon Sep 17 00:00:00 2001 From: vextv Date: Sat, 26 Apr 2025 16:14:15 +0200 Subject: [PATCH 04/13] - added the function to register a user --- public/registrieren/registrieren.html | 42 +++++++++++++++++++++++---- server.js | 16 ++++++++++ 2 files changed, 53 insertions(+), 5 deletions(-) diff --git a/public/registrieren/registrieren.html b/public/registrieren/registrieren.html index e5dbf8e..5e472ee 100644 --- a/public/registrieren/registrieren.html +++ b/public/registrieren/registrieren.html @@ -18,19 +18,19 @@
-
+

Registrieren

- +
- +
- +
@@ -43,7 +43,7 @@
- +
+ diff --git a/server.js b/server.js index 0619c03..b412eba 100644 --- a/server.js +++ b/server.js @@ -127,6 +127,22 @@ app.get('/api/products/sportwagen', async (req, res) => { }); }); +app.post('/api/user/registration', (req,res)=> { + // SQL-Query für Nutzerregistration + const {name, lower_name, email, passwd} = req.body; + const sql = "INSERT INTO user (name, lower_name, email, passwd, passwd_hash_algo) VALUES (?, ?, ?, ?, 'none')" + + // Query abschicken + db.query(sql, [name, lower_name, email, passwd], (err, results) => { + if (err){ + console.error('Fehler beim Schreiben in die Datenbank: ', err); + res.status(500).send('Fehler beim Schreiben in die Datenbank'); + return; + } + res.status(201).json({message: 'Nutzer erfolgreich hinzugefügt', id: results.insertId}) + }) +}) + const getIndexRoute = require('./scripts/routes/other/route-index'); app.use('/', getIndexRoute); -- 2.39.5 From 353087e4588578c17f280c58508755642cfff840 Mon Sep 17 00:00:00 2001 From: vextv Date: Sat, 26 Apr 2025 17:08:22 +0200 Subject: [PATCH 05/13] - added the function to login with email and password - removed an unnecessary empty file --- public/login/login.html | 75 ++++++++---- public/registrieren/passwordValidation.js | 0 public/registrieren/registrieren.html | 133 +++++++++++----------- server.js | 33 +++++- 4 files changed, 148 insertions(+), 93 deletions(-) delete mode 100644 public/registrieren/passwordValidation.js diff --git a/public/login/login.html b/public/login/login.html index 441ef8f..f534d6f 100644 --- a/public/login/login.html +++ b/public/login/login.html @@ -10,31 +10,60 @@ Login - -
+ +
-
- -
+
+ +
- - + + + diff --git a/public/registrieren/passwordValidation.js b/public/registrieren/passwordValidation.js deleted file mode 100644 index e69de29..0000000 diff --git a/public/registrieren/registrieren.html b/public/registrieren/registrieren.html index 5e472ee..4c5135c 100644 --- a/public/registrieren/registrieren.html +++ b/public/registrieren/registrieren.html @@ -1,93 +1,94 @@ - - - - - - - Registrieren + + + + + + + Registrieren -
+
-
-
-

Registrieren

+
+ +

Registrieren

-
- - -
-
- - -
-
- - -
-
- - -
+
+ + +
+
+ + +
+
+ + +
+
+ + +
-
- - -
+
+ + +
- + - - -
+ + +
-
+
diff --git a/server.js b/server.js index b412eba..53a0685 100644 --- a/server.js +++ b/server.js @@ -3,7 +3,7 @@ const session = require('express-session'); const router = require('express').Router(); const path = require('path'); -require('dotenv').config({path:'process.env'}); +require('dotenv').config({path: 'process.env'}); const app = express(); const mysql = require('mysql'); @@ -32,7 +32,7 @@ app.use(session({ })); app.use(express.json()); -app.use(express.urlencoded({ extended: true })); +app.use(express.urlencoded({extended: true})); app.use(express.static(path.join(__dirname, '/scripts'))); app.use(express.static(path.join(__dirname, '/static'))); @@ -127,14 +127,14 @@ app.get('/api/products/sportwagen', async (req, res) => { }); }); -app.post('/api/user/registration', (req,res)=> { +app.post('/api/user/registration', (req, res) => { // SQL-Query für Nutzerregistration const {name, lower_name, email, passwd} = req.body; const sql = "INSERT INTO user (name, lower_name, email, passwd, passwd_hash_algo) VALUES (?, ?, ?, ?, 'none')" // Query abschicken db.query(sql, [name, lower_name, email, passwd], (err, results) => { - if (err){ + if (err) { console.error('Fehler beim Schreiben in die Datenbank: ', err); res.status(500).send('Fehler beim Schreiben in die Datenbank'); return; @@ -143,6 +143,31 @@ app.post('/api/user/registration', (req,res)=> { }) }) +app.post('/api/user/login', (req, res) => { + const {email, password} = req.body + const sql = 'SELECT * FROM user WHERE email = ?' + + db.query(sql, [email], (err, results) => { + if (err) { + console.error('Fehler beim Abrufen des Nutzers: ', err) + return res.status(500).json({message: 'Serverfehler'}) + } + if (results.length === 0) { + return res.status(401).json({message: 'E-Mail nicht gefunden'}) + } + const user = results[0] + + if (user.passwd !== password) { + return res.status(401).json({message: 'Falsches Passwort'}) + } + + req.session.userId = user.id; + req.session.email = user.email; + + res.json({message: 'Login erfolgreich', id: user.id}) + }) +}) + const getIndexRoute = require('./scripts/routes/other/route-index'); app.use('/', getIndexRoute); -- 2.39.5 From c5ef5d49c0be0a33753b2d37c0ac3c268e8adbfb Mon Sep 17 00:00:00 2001 From: rgemm Date: Sat, 26 Apr 2025 18:18:04 +0200 Subject: [PATCH 06/13] -bestellvorgang angefangen nicht fertig/funktionierend --- public/bestellformular/bestellformular.html | 39 +++++++++++++++++++-- public/bestellung/bestellung.html | 24 +++++++++++++ server.js | 35 ++++++++++++++++++ 3 files changed, 96 insertions(+), 2 deletions(-) diff --git a/public/bestellformular/bestellformular.html b/public/bestellformular/bestellformular.html index 56b2411..7678c66 100644 --- a/public/bestellformular/bestellformular.html +++ b/public/bestellformular/bestellformular.html @@ -15,7 +15,7 @@
-
+

Bestellformular

@@ -42,11 +42,46 @@ - Bestellung absenden + Bestellung absenden
+ +
diff --git a/public/bestellung/bestellung.html b/public/bestellung/bestellung.html index 54e2885..3916acd 100644 --- a/public/bestellung/bestellung.html +++ b/public/bestellung/bestellung.html @@ -25,6 +25,30 @@
+ + diff --git a/server.js b/server.js index 53a0685..53cf5ba 100644 --- a/server.js +++ b/server.js @@ -168,6 +168,41 @@ app.post('/api/user/login', (req, res) => { }) }) +app.post('/api/bestellung', (req, res) => { + const { userId, productId} = req.body; + + // 1. Produktpreis holen + const productSql = 'SELECT price FROM product WHERE productId = ?'; + const producNameSql = 'SELECT name FROM product WHERE productId = ?'; + + db.query(productSql, [productId], (err, productResults) => { + if (err || productResults.length === 0) { + console.error('Fehler beim Abrufen des Produkts: ', err); + return res.status(500).json({ message: 'Produkt nicht gefunden oder Serverfehler' }); + } + + const productPrice = productResults[0].price; + + }); +}); + +app.get('/api/bestellung/daten', (req, res) => { + + + db.query(sql, [userId], (err, results) => { + if (err) { + console.error('Fehler beim Abrufen der Bestellung: ', err); + return res.status(500).json({ message: 'Fehler beim Abrufen der Bestellung' }); + } + + if (results.length === 0) { + return res.status(404).json({ message: 'Keine Bestellung gefunden' }); + } + + res.json(results); + }); +}); + const getIndexRoute = require('./scripts/routes/other/route-index'); app.use('/', getIndexRoute); -- 2.39.5 From 40e5db6551ac46cce33febe6eeedaf5233dfe52c Mon Sep 17 00:00:00 2001 From: vextv Date: Sat, 26 Apr 2025 19:23:04 +0200 Subject: [PATCH 07/13] - WIP: reworked the order function and added error handling for it - added a function to save the user_id in the sessionStorage of the browser --- public/bestellformular/bestellformular.html | 125 ++++++++++---------- public/bestellung/bestellung.html | 41 ++++--- public/login/login.html | 5 +- public/registrieren/registrieren.html | 1 + server.js | 19 ++- 5 files changed, 100 insertions(+), 91 deletions(-) diff --git a/public/bestellformular/bestellformular.html b/public/bestellformular/bestellformular.html index 7678c66..4c81016 100644 --- a/public/bestellformular/bestellformular.html +++ b/public/bestellformular/bestellformular.html @@ -1,89 +1,86 @@ - - - Bestellformular - - - + + + Bestellformular + + +
- -
+ +
-
-
-
-

Bestellformular

+
+
+ +

Bestellformular

- - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + Bestellung absenden + +
+
- Bestellung absenden - -
-
+ - const result = await response.json(); - - if (response.ok) { - alert('Bestellung erfolgreich!'); - window.location.href = '/bestellung.html'; // Weiterleitung zur Bestellübersicht - } else { - alert('Fehler bei der Bestellung: ' + result.message); - } - } catch (error) { - console.error('Fehler:', error); - alert('Fehler beim Bestellen.'); - } - }); - - - - + +
diff --git a/public/bestellung/bestellung.html b/public/bestellung/bestellung.html index 3916acd..9edc202 100644 --- a/public/bestellung/bestellung.html +++ b/public/bestellung/bestellung.html @@ -27,26 +27,37 @@ diff --git a/public/login/login.html b/public/login/login.html index f534d6f..52d9e7a 100644 --- a/public/login/login.html +++ b/public/login/login.html @@ -37,8 +37,8 @@ document.getElementById('submit').addEventListener('click', async (event) => { event.preventDefault() - const email = document.getElementById('email').value; - const password = document.getElementById('password').value; + const email = document.getElementById('email').value + const password = document.getElementById('password').value try { const response = await fetch('/api/user/login', { @@ -50,6 +50,7 @@ }) if (response.ok) { const data = await response.json(); + sessionStorage.setItem("user_id", data.id) alert('Login erfolgreich!'); window.location.href = '/'; // Redirect to home page after login } else { diff --git a/public/registrieren/registrieren.html b/public/registrieren/registrieren.html index 4c5135c..f7ae6d6 100644 --- a/public/registrieren/registrieren.html +++ b/public/registrieren/registrieren.html @@ -75,6 +75,7 @@ }) if (response.ok) { const data = await response.json(); + sessionStorage.setItem("user_id", data.id) alert('Nutzer erfolgreich hinzugefügt! Ihre Kundennummer: ' + data.id) } else { alert('Fehler bei der Registrierung.') diff --git a/server.js b/server.js index 53cf5ba..7f40dd3 100644 --- a/server.js +++ b/server.js @@ -169,27 +169,26 @@ app.post('/api/user/login', (req, res) => { }) app.post('/api/bestellung', (req, res) => { - const { userId, productId} = req.body; - // 1. Produktpreis holen - const productSql = 'SELECT price FROM product WHERE productId = ?'; - const producNameSql = 'SELECT name FROM product WHERE productId = ?'; + const { user_id, product_id} = req.body; + const sql = 'INSERT INTO order_items (user_id, product_id, quantity) VALUES (?, ?, 1)' - db.query(productSql, [productId], (err, productResults) => { - if (err || productResults.length === 0) { + + db.query(sql, [user_id, product_id], (err, results) => { + if (err || results.length === 0) { console.error('Fehler beim Abrufen des Produkts: ', err); return res.status(500).json({ message: 'Produkt nicht gefunden oder Serverfehler' }); } - - const productPrice = productResults[0].price; - + res.status(201).json({message: 'Produkt bestellt', id: results.insertId}) }); }); app.get('/api/bestellung/daten', (req, res) => { + const user_id = req.body; - db.query(sql, [userId], (err, results) => { + const sql = 'SELECT * FROM order_items WHERE user_id = ? ' + db.query(sql, [user_id], (err, results) => { if (err) { console.error('Fehler beim Abrufen der Bestellung: ', err); return res.status(500).json({ message: 'Fehler beim Abrufen der Bestellung' }); -- 2.39.5 From c3636b0166e97a0259c9139e0dec068c8d6b9410 Mon Sep 17 00:00:00 2001 From: vextv Date: Sun, 27 Apr 2025 12:04:56 +0200 Subject: [PATCH 08/13] - added npm start script - modified packages --- package-lock.json | 36 +++++++++++++++++++++++++++++++++--- package.json | 10 +++++----- 2 files changed, 38 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index d926216..b3c988d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,11 +1,11 @@ { - "name": "sniper", + "name": "webshop", "version": "1.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "sniper", + "name": "webshop", "version": "1.0.0", "license": "ISC", "dependencies": { @@ -15,7 +15,9 @@ "express-session": "^1.18.1", "mysql": "^2.18.1", "mysql2": "^3.12.0", - "path": "^0.12.7" + "node": "^22.15.0", + "path": "^0.12.7", + "server.js": "^1.0.0" } }, "node_modules/accepts": { @@ -674,6 +676,28 @@ "node": ">= 0.6" } }, + "node_modules/node": { + "version": "22.15.0", + "resolved": "https://registry.npmjs.org/node/-/node-22.15.0.tgz", + "integrity": "sha512-qrOEL83lNt+Jbh9pekl5xQrZK+QRJz51m2IGGCu2NENgbG6Go0D1QUBvjbejP8jB2eokQpX1AorDLbKQ/FxuYA==", + "hasInstallScript": true, + "license": "ISC", + "dependencies": { + "node-bin-setup": "^1.0.0" + }, + "bin": { + "node": "bin/node" + }, + "engines": { + "npm": ">=5.0.0" + } + }, + "node_modules/node-bin-setup": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/node-bin-setup/-/node-bin-setup-1.1.3.tgz", + "integrity": "sha512-opgw9iSCAzT2+6wJOETCpeRYAQxSopqQ2z+N6BXwIMsQQ7Zj5M8MaafQY8JMlolRR6R1UXg2WmhKp0p9lSOivg==", + "license": "ISC" + }, "node_modules/object-inspect": { "version": "1.13.2", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", @@ -894,6 +918,12 @@ "node": ">= 0.8.0" } }, + "node_modules/server.js": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/server.js/-/server.js-1.0.0.tgz", + "integrity": "sha512-fO4IvzkZ09bBB++XU/gWGuzxJs0OpghSd/34mlW8coMoakLzj/+W5d1pHX+I+7H52GkBKu96UQU0K5vptNjaqg==", + "license": "ISC" + }, "node_modules/set-function-length": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", diff --git a/package.json b/package.json index a95f1e3..f34f8f5 100644 --- a/package.json +++ b/package.json @@ -1,10 +1,10 @@ { - "name": "sniper", + "name": "webshop", "version": "1.0.0", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", - "start": "node server.js" + "start": "npm install && node server.js" }, "keywords": [], "author": "", @@ -12,13 +12,13 @@ "description": "Webshop Autohändler", "dependencies": { "app-root-path": "^3.1.0", - "dotenv": "^16.4.5", - "express": "^4.21.1", "dotenv": "^16.4.7", "express": "^4.21.2", "express-session": "^1.18.1", "mysql": "^2.18.1", "mysql2": "^3.12.0", - "path": "^0.12.7" + "node": "^22.15.0", + "path": "^0.12.7", + "server.js": "^1.0.0" } } -- 2.39.5 From 34907bbdb5b17fc661fb40377fd71649aef2436d Mon Sep 17 00:00:00 2001 From: vextv Date: Sun, 27 Apr 2025 13:37:15 +0200 Subject: [PATCH 09/13] - added redirect after registration - WIP: order system to save orders and display them to the buyer --- public/bestellformular/bestellformular.html | 20 +++++++++----------- public/bestellung/bestellung.html | 2 ++ public/registrieren/registrieren.html | 1 + server.js | 19 ++++++++++++------- 4 files changed, 24 insertions(+), 18 deletions(-) diff --git a/public/bestellformular/bestellformular.html b/public/bestellformular/bestellformular.html index 4c81016..8f02250 100644 --- a/public/bestellformular/bestellformular.html +++ b/public/bestellformular/bestellformular.html @@ -39,36 +39,34 @@ - Bestellung absenden + Bestellung absenden + + + Ihre Bestellung + + +
-
+

Ihre Bestellung:

- -
-

Kundennummer:

-

Produkt-ID:

-

Produktname:

-

Preis:

-
+ +
+

Kundennummer:

+

Produkt-ID:

+

Produktname:

+

Preis:

+
-
+
diff --git a/server.js b/server.js index 899f6c2..388aba4 100644 --- a/server.js +++ b/server.js @@ -130,7 +130,7 @@ app.get('/api/products/sportwagen', async (req, res) => { app.post('/api/user/registration', (req, res) => { // SQL-Query für Nutzerregistration const {name, lower_name, email, passwd} = req.body; - const sql = "INSERT INTO user (name, lower_name, email, passwd, passwd_hash_algo) VALUES (?, ?, ?, ?, 'none')" + const sql = "INSERT INTO webshop.user (name, lower_name, email, passwd, passwd_hash_algo) VALUES (?, ?, ?, ?, 'none')" // Query abschicken db.query(sql, [name, lower_name, email, passwd], (err, results) => { @@ -172,8 +172,8 @@ app.post('/api/bestellung', (req, res) => { const {user_id, product_id} = req.body; - const sql1 = 'INSERT INTO order_details (, user_id, payment_id, total) VALUES (?, null, null)' - const sql2 = 'INSERT INTO order_items (user_id, product_id, quantity, order_id) VALUES (?, ?, 1, ?)'; + const sql1 = 'INSERT INTO webshop.order_details (user_id, payment_id, total) VALUES (?, 1, 0)' + const sql2 = 'INSERT INTO webshop.order_items (user_id, product_id, quantity, order_id) VALUES (?, ?, 1, ?)'; db.query(sql1, [user_id, 1, 100.00], (err1, result1) => { if (err1) { @@ -190,11 +190,11 @@ app.post('/api/bestellung', (req, res) => { }); }); -app.get('/api/bestellung/daten', (req, res) => { +app.post('/api/bestellung/daten', (req, res) => { const user_id = req.body; - const sql = 'SELECT oi.user_id, oi.product_id, p.product_name, p.price FROM order_items oi INNER JOIN product p ON oi.product_id = p.id WHERE user_id = ? ' + const sql = 'SELECT oi.user_id, oi.product_id, p.name AS product_name, p.price FROM order_items oi INNER JOIN product p ON oi.product_id = p.id WHERE oi.user_id = ? ' db.query(sql, [user_id], (err, results) => { if (err) { console.error('Fehler beim Abrufen der Bestellung: ', err); -- 2.39.5 From b66c54ff5774d59f2b525ca83a47925371016cb4 Mon Sep 17 00:00:00 2001 From: florianspengler Date: Mon, 28 Apr 2025 14:42:05 +0200 Subject: [PATCH 12/13] reworked bestellformular --- public/bestellformular/bestellformular.html | 235 +++++++++++++++++--- server.js | 77 ++++++- 2 files changed, 270 insertions(+), 42 deletions(-) diff --git a/public/bestellformular/bestellformular.html b/public/bestellformular/bestellformular.html index b3ece7d..793c685 100644 --- a/public/bestellformular/bestellformular.html +++ b/public/bestellformular/bestellformular.html @@ -15,7 +15,7 @@
-
+

Bestellformular

@@ -37,50 +37,221 @@ - +
+ + + +
+
+ Bestellung absenden
+ const payload = { + user_id: parseInt(userData.kundenNr, 10), + produkte: produkte + }; + + try { + const response = await fetch('/api/bestellung', { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify(payload) + }); + + const result = await response.json(); + + if (response.ok) { + // Bestellung erfolgreich -> Weiterleitung + window.location.href = "/bestellung"; + } else { + alert('Fehler: ' + result.message); + } + + } catch (error) { + console.error('Fehler beim Abschicken der Bestellung:', error); + alert('Serverfehler beim Abschicken der Bestellung.'); + } + }); + + // Artikelnummer prüfen bei Eingabe + formular.addEventListener('input', async function (event) { + if (event.target.classList.contains('ArtikelNrText')) { + if (event.target.value.trim() !== '') { + await pruefeVerfuegbarkeit(event.target); + fuegeNeuesArtikelFeldHinzu(); + } + } + }); + }); + + // Funktion: Verfügbarkeit prüfen + async function pruefeVerfuegbarkeit(inputFeld) { + const artikelnummer = inputFeld.value.trim(); + const verfuegbarkeitDiv = inputFeld.parentElement.querySelector('.verfuegbarkeit'); + const sendButton = document.getElementById('sendOrder'); + + if (artikelnummer.length === 0) { + verfuegbarkeitDiv.textContent = ""; + return; + } + + try { + const response = await fetch(`/api/pruefe-artikel?nummer=${encodeURIComponent(artikelnummer)}`); + const data = await response.json(); + + const artikelDivs = document.querySelectorAll('.Artikel'); + artikelVerfuegbarkeiten = []; + + artikelDivs.forEach(div => { + const artikelNrInput = div.querySelector('.ArtikelNrText'); + const verfDiv = div.querySelector('.verfuegbarkeit'); + + if (artikelNrInput.value.trim() !== '') { + if (artikelNrInput === inputFeld) { + if (data.verfuegbar) { + verfDiv.textContent = "Artikel verfügbar."; + verfDiv.style.color = "green"; + artikelVerfuegbarkeiten.push(true); + } else { + verfDiv.textContent = "Artikel nicht verfügbar!"; + verfDiv.style.color = "red"; + artikelVerfuegbarkeiten.push(false); + } + } else { + // Für andere Felder bisherige Anzeige berücksichtigen + if (verfDiv.textContent.includes("nicht verfügbar")) { + artikelVerfuegbarkeiten.push(false); + } else { + artikelVerfuegbarkeiten.push(true); + } + } + } + }); + + // Button sperren/freigeben + if (artikelVerfuegbarkeiten.every(status => status === true)) { + sendButton.disabled = false; + } else { + sendButton.disabled = true; + } + + } catch (error) { + console.error('Fehler bei der Artikelsuche:', error); + verfuegbarkeitDiv.textContent = "Fehler bei der Prüfung."; + verfuegbarkeitDiv.style.color = "orange"; + sendButton.disabled = true; + } + } + + // Funktion: Neues Artikelfeld hinzufügen + function fuegeNeuesArtikelFeldHinzu() { + const formular = document.getElementById('bestellform'); + const artikelnummerFelder = formular.querySelectorAll('.ArtikelNrText'); + const letztesFeld = artikelnummerFelder[artikelnummerFelder.length - 1]; + + if (letztesFeld && letztesFeld.value.trim() !== '') { + const neueArtikelDiv = document.createElement('div'); + neueArtikelDiv.className = 'Artikel'; + neueArtikelDiv.innerHTML = ` + + + +
+ `; + + const sendButton = document.getElementById('sendOrder'); + formular.insertBefore(neueArtikelDiv, sendButton); + } + } + + // Funktion: Artikel löschen + function loescheArtikel(button) { + const artikelDiv = button.parentElement; + artikelDiv.remove(); + } + + diff --git a/server.js b/server.js index 388aba4..45deb27 100644 --- a/server.js +++ b/server.js @@ -169,27 +169,64 @@ app.post('/api/user/login', (req, res) => { }) app.post('/api/bestellung', (req, res) => { + const { user_id, produkte } = req.body; + // produkte erwartet als Array: [{product_id: 1, quantity: 2}, {product_id: 5, quantity: 1}, ...] - const {user_id, product_id} = req.body; + if (!user_id || !Array.isArray(produkte) || produkte.length === 0) { + return res.status(400).json({ message: 'Ungültige Anfrage: user_id oder Produkte fehlen.' }); + } - const sql1 = 'INSERT INTO webshop.order_details (user_id, payment_id, total) VALUES (?, 1, 0)' - const sql2 = 'INSERT INTO webshop.order_items (user_id, product_id, quantity, order_id) VALUES (?, ?, 1, ?)'; + // Preise der Produkte abrufen + const productIds = produkte.map(p => p.product_id); - db.query(sql1, [user_id, 1, 100.00], (err1, result1) => { - if (err1) { - return res.status(500).json({message: 'Fehler beim Erstellen der Bestellung'}); + const priceQuery = 'SELECT id, price FROM webshop.product WHERE id IN (?)'; + db.query(priceQuery, [productIds], (err, priceResults) => { + if (err) { + console.error('Fehler beim Abrufen der Produktpreise:', err); + return res.status(500).json({ message: 'Serverfehler beim Abrufen der Produktpreise.' }); } - db.query(sql2, [user_id, product_id, result1.insertId], (err2, result2) => { - if (err2) { - return res.status(500).json({message: 'Fehler beim Hinzufügen des Produkts zur Bestellung'}); + if (priceResults.length !== productIds.length) { + return res.status(400).json({ message: 'Eines oder mehrere Produkte existieren nicht.' }); + } + + // Total berechnen + let total = 0; + produkte.forEach(p => { + const dbProduct = priceResults.find(pr => pr.id === p.product_id); + if (dbProduct) { + total += dbProduct.price * p.quantity; + } + }); + + const payment_id = 1; // Zahlungssystem-ID (z.B. 1 = Rechnung, 2 = PayPal, ...) + + const sqlOrder = 'INSERT INTO webshop.order_details (user_id, payment_id, total) VALUES (?, ?, ?)'; + db.query(sqlOrder, [user_id, payment_id, total], (err1, result1) => { + if (err1) { + console.error('Fehler beim Erstellen der Bestellung:', err1); + return res.status(500).json({ message: 'Fehler beim Erstellen der Bestellung.' }); } - res.status(201).json({message: 'Produkt bestellt', id: result2.insertId}); + const orderId = result1.insertId; + + const values = produkte.map(p => [user_id, p.product_id, p.quantity, orderId]); + const sqlItems = 'INSERT INTO webshop.order_items (user_id, product_id, quantity, order_id) VALUES ?'; + + db.query(sqlItems, [values], (err2, result2) => { + if (err2) { + console.error('Fehler beim Einfügen der Order-Items:', err2); + return res.status(500).json({ message: 'Fehler beim Hinzufügen der Produkte zur Bestellung.' }); + } + + res.status(201).json({ message: 'Bestellung erfolgreich!', order_id: orderId, total: total.toFixed(2) }); + }); }); }); }); + + app.post('/api/bestellung/daten', (req, res) => { const user_id = req.body; @@ -209,6 +246,26 @@ app.post('/api/bestellung/daten', (req, res) => { }); }); +app.get('/api/pruefe-artikel', (req, res) => { + const artikelnummer = req.query.nummer; + + if (!artikelnummer) { + return res.status(400).json({ error: 'Keine Artikelnummer angegeben.' }); + } + + const query = 'SELECT id FROM product WHERE id = ?'; + + db.query(query, [artikelnummer], (err, results) => { + if (err) { + console.error('Fehler bei der Artikelsuche:', err); + return res.status(500).json({ error: 'Serverfehler bei der Artikelsuche.' }); + } + + const verfuegbar = results.length > 0; + res.json({ verfuegbar }); + }); +}); + const getIndexRoute = require('./scripts/routes/other/route-index'); app.use('/', getIndexRoute); -- 2.39.5 From 7eb73216804c0cb35941877b283bd83cb49b0d2a Mon Sep 17 00:00:00 2001 From: florianspengler Date: Tue, 29 Apr 2025 09:39:11 +0200 Subject: [PATCH 13/13] repaired /bestellformular und /bestellung --- public/bestellung/bestellung.html | 90 ++++++++++++++++++++++--------- server.js | 30 ++++++++--- 2 files changed, 87 insertions(+), 33 deletions(-) diff --git a/public/bestellung/bestellung.html b/public/bestellung/bestellung.html index 065502a..0827942 100644 --- a/public/bestellung/bestellung.html +++ b/public/bestellung/bestellung.html @@ -27,39 +27,77 @@ - + + diff --git a/server.js b/server.js index 45deb27..59b3e21 100644 --- a/server.js +++ b/server.js @@ -225,21 +225,37 @@ app.post('/api/bestellung', (req, res) => { }); }); - - app.post('/api/bestellung/daten', (req, res) => { + const { user_id } = req.body; - const user_id = req.body; + const sql = ` + SELECT + od.id AS order_id, + od.total AS order_total, + oi.product_id, + oi.quantity, + p.name AS product_name, + p.price AS product_price + FROM + webshop.order_details od + INNER JOIN + webshop.order_items oi ON od.id = oi.order_id + INNER JOIN + webshop.product p ON oi.product_id = p.id + WHERE + od.user_id = ? + ORDER BY + od.id DESC + `; - const sql = 'SELECT oi.user_id, oi.product_id, p.name AS product_name, p.price FROM order_items oi INNER JOIN product p ON oi.product_id = p.id WHERE oi.user_id = ? ' db.query(sql, [user_id], (err, results) => { if (err) { - console.error('Fehler beim Abrufen der Bestellung: ', err); - return res.status(500).json({message: 'Fehler beim Abrufen der Bestellung'}); + console.error('Fehler beim Abrufen der Bestellungen: ', err); + return res.status(500).json({ message: 'Fehler beim Abrufen der Bestellungen' }); } if (results.length === 0) { - return res.status(404).json({message: 'Keine Bestellung gefunden'}); + return res.status(404).json({ message: 'Keine Bestellungen gefunden.' }); } res.json(results); -- 2.39.5