From 0fd042c9ca0cd3edd3bd0c965a0b7088ca42ff2a Mon Sep 17 00:00:00 2001 From: "theis.gaedigk" Date: Sun, 22 Jun 2025 00:57:01 +0200 Subject: [PATCH] feat: add user management functions and update dashboard for create, update, and delete actions --- Dockerfile | 0 backend/database.js | 65 +++++++++++++++- backend/server.js | 41 ++++++++-- backend/views/dashboard.ejs | 146 +++++++++++++++++++++++++++++++----- docker-compose.yml | 0 5 files changed, 225 insertions(+), 27 deletions(-) create mode 100644 Dockerfile create mode 100644 docker-compose.yml diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..e69de29 diff --git a/backend/database.js b/backend/database.js index f04d01d..f8b65ad 100644 --- a/backend/database.js +++ b/backend/database.js @@ -18,7 +18,7 @@ export async function loginUser(username, password) { ); if (result.length > 0) { - console.log("User found: ", result[0]); + console.log("User found: ", result[0].username, " ", result[0].id); return { success: true, user: result[0] }; } else { console.error(`Invalid username or password!; ${result[0]}`); @@ -34,7 +34,6 @@ export async function createUser( email ) { try { - const [result] = await pool.query( "INSERT INTO users (username, first_name, last_name, password, email) VALUES (?, ?, ?, ?, ?)", [username, first_name, last_name, password, email] @@ -42,9 +41,69 @@ export async function createUser( console.log("User created successfully!"); return { success: true }; - } catch (error) { console.error("Error creating user: ", error); return { success: false, message: "Error creating user" }; } } + +export async function updateUser( + username, + first_name, + last_name, + password, + email +) { + try { + const [result] = await pool.query( + "UPDATE users SET first_name = ?, last_name = ?, password = ?, email = ? WHERE username = ?", + [first_name, last_name, password, email, username] + ); + return { + success: true, + message: "User updated successfully", + resultOfquery: result, + }; + } catch (error) { + console.error("Error updating user: ", error); + return { + success: false, + message: "Error updating user", + resultOfquery: result, + }; + } +} + +export async function deleteUser( + username, + first_name, + last_name, + password, + email +) { + try { + const [result] = await pool.query( + "DELETE FROM users WHERE username = ? AND password = ?", + [username, password] + ); + const resultOfquery = result.affectedRows; + + if (resultOfquery > 0) { + console.log("User deleted successfully!"); + return { + success: true, + message: "User deleted successfully", + resultOfquery: result, + }; + } + + if (resultOfquery === 0) { + console.log("Error deleting user."); + return { + success: false, + message: "Error deleting user", + resultOfquery: null, + }; + } + } catch (err) {} +} diff --git a/backend/server.js b/backend/server.js index 641fcd7..27013d0 100644 --- a/backend/server.js +++ b/backend/server.js @@ -3,7 +3,7 @@ import express from "express"; const app = express(); const port = 4000; -import { loginUser, createUser } from "./database.js"; +import { loginUser, createUser, updateUser, deleteUser } from "./database.js"; app.use(express.urlencoded({ extended: true })); app.set("view engine", "ejs"); @@ -29,6 +29,7 @@ app.use(express.static("public")); // Route to handle GET requests to the root URL app.get("/", (req, res) => { res.render("login.ejs", { error: null, reload: false }); + console.log("Frontend user requested frontend login page."); }); let latestUser; @@ -40,9 +41,10 @@ app.post("/login", (req, res) => { res.status(200).render("dashboard.ejs", { sqlResult: result, newLink: `/dashboard/${result.user.id}`, + alert: null, + success: null, }); latestUser = result; - console.log(latestUser); } else { res .status(401) @@ -51,26 +53,51 @@ app.post("/login", (req, res) => { }); }); -app.post("/createUser", (req, res) => { - createUser( +app.post(["/createUser", "/updateUser", "/deleteUser"], (req, res) => { + let action = req.path; + let funcName; + + if (action === "/createUser") { + funcName = createUser; + } else if (action === "/updateUser") { + funcName = updateUser; + } else if (action === "/deleteUser") { + if (latestUser && req.body.username !== latestUser.user.username) { + funcName = deleteUser; + } else { + res.status(400).render("dashboard.ejs", { + sqlResult: latestUser, + newLink: latestUser ? `/dashboard/${latestUser.id}` : "#", + alert: "Cannot delete the currently logged-in user!", + success: null, + }); + return; + } + } else { + res.status(400).send("Invalid action"); + return; + } + funcName( req.body.username, req.body.first_name, req.body.last_name, req.body.password, req.body.email ).then((result) => { - if (result.success) { + if (result.success === true) { res.status(201).render("dashboard.ejs", { sqlResult: latestUser, newLink: `/dashboard/${latestUser.id}`, + alert: null, + success: "User action successful!", }); - console.log(latestUser); } else { res.status(400).render("dashboard.ejs", { sqlResult: latestUser, newLink: `/dashboard/${latestUser.id}`, + alert: "User action failed!", + success: null, }); - console.log(latestUser); } }); }); diff --git a/backend/views/dashboard.ejs b/backend/views/dashboard.ejs index ba39803..25ecd3f 100644 --- a/backend/views/dashboard.ejs +++ b/backend/views/dashboard.ejs @@ -15,6 +15,38 @@ integrity="sha384-LN+7fdVzj6u52u30Kp6M/trliBMCMKTyK833zpbD+pXdCLuTusPj697FH4R/5mcr" crossorigin="anonymous" /> + + +
@@ -27,18 +59,29 @@

Welcome to your dashboard

- Logout + Logout
-

Create a new user

-
+

+ Create / + Update / + Delete + a user +

+
- +
- +
- +
- +
-
- +
+
+ <% if (alert !== null) { %> +
+ +
+ <% } else if (success !== null) { %> +
+ +
+ <% } %> +
-
-
+ +
+ +
+ +
+ +
- <% if (typeof status !== 'undefined') { %> <% if (status === - 'success') { %> -
User created successfully!
- <% } else if (status === 'error') { %> -
User creation failed.
- <% } %> <% } %> +
+
diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..e69de29