diff --git a/controllers/admin.controller.js b/controllers/admin.controller.js
index ad2d5f8..87a6c7e 100644
--- a/controllers/admin.controller.js
+++ b/controllers/admin.controller.js
@@ -1,6 +1,10 @@
const db = require("../db");
-const { createUser, getAllUsers } = require("../services/admin.service");
const bcrypt = require("bcrypt");
+const {
+ createUser,
+ getAllUsers,
+ updateUserById,
+} = require("../services/admin.service");
async function listUsers(req, res) {
const { q } = req.query;
@@ -34,6 +38,7 @@ function showCreateUser(req, res) {
async function postCreateUser(req, res) {
let {
+ title,
first_name,
last_name,
username,
@@ -43,6 +48,7 @@ async function postCreateUser(req, res) {
arztnummer,
} = req.body;
+ title = title?.trim();
first_name = first_name?.trim();
last_name = last_name?.trim();
username = username?.trim();
@@ -69,11 +75,13 @@ async function postCreateUser(req, res) {
// Sicherheit: Mitarbeiter dürfen keine Arzt-Daten haben
fachrichtung = null;
arztnummer = null;
+ title = null;
}
try {
await createUser(
db,
+ title,
first_name,
last_name,
username,
@@ -265,6 +273,50 @@ async function showInvoiceOverview(req, res) {
}
}
+async function updateUser(req, res) {
+ const userId = req.params.id;
+
+ let { title, first_name, last_name, username, role } = req.body;
+
+ title = title?.trim() || null;
+ first_name = first_name?.trim();
+ last_name = last_name?.trim();
+ username = username?.trim();
+ role = role?.trim();
+
+ try {
+ // ✅ Fehlende Felder aus DB holen (weil disabled inputs nicht gesendet werden)
+ const [rows] = await db
+ .promise()
+ .query("SELECT * FROM users WHERE id = ?", [userId]);
+
+ if (!rows.length) {
+ req.session.flash = { type: "danger", message: "User nicht gefunden" };
+ return res.redirect("/admin/users");
+ }
+
+ const current = rows[0];
+
+ // ✅ Fallback: wenn Felder nicht gesendet wurden -> alte Werte behalten
+ const updatedData = {
+ title: title ?? current.title,
+ first_name: first_name ?? current.first_name,
+ last_name: last_name ?? current.last_name,
+ username: username ?? current.username,
+ role: role ?? current.role,
+ };
+
+ await updateUserById(db, userId, updatedData);
+
+ req.session.flash = { type: "success", message: "User aktualisiert ✅" };
+ return res.redirect("/admin/users");
+ } catch (err) {
+ console.error(err);
+ req.session.flash = { type: "danger", message: "Fehler beim Speichern" };
+ return res.redirect("/admin/users");
+ }
+}
+
module.exports = {
listUsers,
showCreateUser,
@@ -274,4 +326,5 @@ module.exports = {
activateUser,
deactivateUser,
showInvoiceOverview,
+ updateUser,
};
diff --git a/controllers/patient.controller.js b/controllers/patient.controller.js
index 089a21a..ffdfc2b 100644
--- a/controllers/patient.controller.js
+++ b/controllers/patient.controller.js
@@ -210,13 +210,14 @@ function moveToWaitingRoom(req, res) {
`
UPDATE patients
SET waiting_room = 1,
- discharged = 0
+ discharged = 0,
+ active = 1
WHERE id = ?
`,
[id],
(err) => {
if (err) return res.send("Fehler beim Verschieben ins Wartezimmer");
- res.redirect("/patients");
+ return res.redirect("/dashboard"); // optional: direkt Dashboard
}
);
}
@@ -245,11 +246,16 @@ function showPatientOverview(req, res) {
`;
const notesSql = `
- SELECT *
- FROM patient_notes
- WHERE patient_id = ?
- ORDER BY created_at DESC
- `;
+ SELECT
+ pn.*,
+ u.title,
+ u.first_name,
+ u.last_name
+ FROM patient_notes pn
+ LEFT JOIN users u ON pn.created_by = u.id
+ WHERE pn.patient_id = ?
+ ORDER BY pn.created_at DESC
+`;
const medicationVariantsSql = `
SELECT
@@ -381,8 +387,9 @@ function addPatientNote(req, res) {
}
db.query(
- "INSERT INTO patient_notes (patient_id, note) VALUES (?, ?)",
- [patientId, note],
+ "INSERT INTO patient_notes (patient_id, created_by, note) VALUES (?, ?, ?)",
+ [patientId, req.session.user.id, note],
+
(err) => {
if (err) return res.send("Fehler beim Speichern der Notiz");
res.redirect(`/patients/${patientId}/overview`);
@@ -407,11 +414,21 @@ function dischargePatient(req, res) {
const patientId = req.params.id;
db.query(
- "UPDATE patients SET discharged = 1 WHERE id = ?",
+ `
+ UPDATE patients
+ SET discharged = 1,
+ waiting_room = 0,
+ active = 0
+ WHERE id = ?
+ `,
[patientId],
(err) => {
- if (err) return res.send("Fehler beim Entlassen des Patienten");
- res.redirect("/waiting-room");
+ if (err) {
+ console.error(err);
+ return res.send("Fehler beim Entlassen des Patienten");
+ }
+
+ return res.redirect("/dashboard");
}
);
}
@@ -462,7 +479,8 @@ function movePatientToWaitingRoom(req, res) {
UPDATE patients
SET waiting_room = 1,
discharged = 0,
- status = 'waiting'
+ status = 'waiting',
+ active = 1
WHERE id = ?
`,
[patientId],
@@ -481,7 +499,7 @@ function movePatientToWaitingRoom(req, res) {
message: "Patient wurde ins Wartezimmer gesetzt",
};
- res.redirect("/waiting-room");
+ return res.redirect("/dashboard");
}
);
}
diff --git a/public/css/style.css b/public/css/style.css
index 618583e..5d3a129 100644
--- a/public/css/style.css
+++ b/public/css/style.css
@@ -3,51 +3,51 @@
========================= */
.waiting-monitor {
- border: 3px solid #343a40;
- border-radius: 10px;
- padding: 15px;
- min-height: 45vh; /* untere Hälfte */
- background-color: #f8f9fa;
+ border: 3px solid #343a40;
+ border-radius: 10px;
+ padding: 15px;
+ min-height: 45vh; /* untere Hälfte */
+ background-color: #f8f9fa;
}
.waiting-grid {
- display: grid;
- grid-template-columns: repeat(7, 1fr);
- grid-template-rows: repeat(3, 1fr);
- gap: 10px;
- height: 100%;
+ display: grid;
+ grid-template-columns: repeat(7, 1fr);
+ grid-template-rows: repeat(3, 1fr);
+ gap: 10px;
+ height: 100%;
}
.waiting-slot {
- border: 2px dashed #adb5bd;
- border-radius: 6px;
- padding: 10px;
- background-color: #ffffff;
- display: flex;
- flex-direction: column;
- justify-content: center;
- align-items: center;
- text-align: center;
+ border: 2px dashed #adb5bd;
+ border-radius: 6px;
+ padding: 10px;
+ background-color: #ffffff;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ text-align: center;
}
.waiting-slot.occupied {
- border-style: solid;
- border-color: #198754;
- background-color: #e9f7ef;
+ border-style: solid;
+ border-color: #198754;
+ background-color: #e9f7ef;
}
.waiting-slot .name {
- font-weight: bold;
+ font-weight: bold;
}
.waiting-slot .birthdate {
- font-size: 0.8rem;
- color: #6c757d;
+ font-size: 0.8rem;
+ color: #6c757d;
}
.waiting-slot .placeholder {
- color: #adb5bd;
- font-style: italic;
+ color: #adb5bd;
+ font-style: italic;
}
.waiting-slot.empty {
@@ -62,3 +62,19 @@
opacity: 0.4;
}
+.auto-hide-flash {
+ animation: flashFadeOut 3s forwards;
+}
+
+@keyframes flashFadeOut {
+ 0% {
+ opacity: 1;
+ }
+ 70% {
+ opacity: 1;
+ }
+ 100% {
+ opacity: 0;
+ visibility: hidden;
+ }
+}
diff --git a/routes/admin.routes.js b/routes/admin.routes.js
index e868f73..ed2e1e2 100644
--- a/routes/admin.routes.js
+++ b/routes/admin.routes.js
@@ -10,6 +10,7 @@ const {
activateUser,
deactivateUser,
showInvoiceOverview,
+ updateUser,
} = require("../controllers/admin.controller");
const { requireAdmin } = require("../middleware/auth.middleware");
@@ -23,5 +24,6 @@ router.post("/users/reset-password/:id", requireAdmin, resetUserPassword);
router.post("/users/activate/:id", requireAdmin, activateUser);
router.post("/users/deactivate/:id", requireAdmin, deactivateUser);
router.get("/invoices", requireAdmin, showInvoiceOverview);
+router.post("/users/update/:id", requireAdmin, updateUser);
module.exports = router;
diff --git a/services/admin.service.js b/services/admin.service.js
index 5846c1b..77c47da 100644
--- a/services/admin.service.js
+++ b/services/admin.service.js
@@ -2,6 +2,7 @@ const bcrypt = require("bcrypt");
async function createUser(
db,
+ title,
first_name,
last_name,
username,
@@ -15,9 +16,18 @@ async function createUser(
return new Promise((resolve, reject) => {
db.query(
`INSERT INTO users
- (first_name, last_name, username, password, role, fachrichtung, arztnummer, active)
- VALUES (?, ?, ?, ?, ?, ?, ?, 1)`,
- [first_name, last_name, username, hash, role, fachrichtung, arztnummer],
+ (title, first_name, last_name, username, password, role, fachrichtung, arztnummer, active)
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, 1)`,
+ [
+ title,
+ first_name,
+ last_name,
+ username,
+ hash,
+ role,
+ fachrichtung,
+ arztnummer,
+ ],
(err) => {
if (err) {
if (err.code === "ER_DUP_ENTRY") {
@@ -57,7 +67,27 @@ async function getAllUsers(db, search = null) {
return rows;
}
+async function updateUserById(db, userId, data) {
+ const { title, first_name, last_name, username, role } = data;
+
+ const [result] = await db.promise().query(
+ `
+ UPDATE users
+ SET title = ?,
+ first_name = ?,
+ last_name = ?,
+ username = ?,
+ role = ?
+ WHERE id = ?
+ `,
+ [title, first_name, last_name, username, role, userId]
+ );
+
+ return result;
+}
+
module.exports = {
createUser,
getAllUsers,
+ updateUserById,
};
diff --git a/views/admin_create_user.ejs b/views/admin_create_user.ejs
index 5a3c341..d24a06b 100644
--- a/views/admin_create_user.ejs
+++ b/views/admin_create_user.ejs
@@ -1,90 +1,108 @@
-
-
+
+
Benutzer anlegen
-
-
-
+
+
+
+
+ <%- include("partials/flash") %>
-
- <%- include("partials/flash") %>
-
-
+
-
Benutzer anlegen
+
Benutzer anlegen
- <% if (error) { %>
-
<%= error %>
- <% } %>
+ <% if (error) { %>
+
<%= error %>
+ <% } %>
-
-
-
-
-
-
+
+
+
diff --git a/views/admin_users.ejs b/views/admin_users.ejs
index 44f7e03..68d50b2 100644
--- a/views/admin_users.ejs
+++ b/views/admin_users.ejs
@@ -1,181 +1,213 @@
-
-
User Verwaltung
-
-
-
-
+
+
User Verwaltung
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
- <%- include("partials/flash") %>
-
-
+ <%- include("partials/flash") %>
-
Benutzerübersicht
+
-
+
diff --git a/views/dashboard.ejs b/views/dashboard.ejs
index 6c4a80c..b85e78e 100644
--- a/views/dashboard.ejs
+++ b/views/dashboard.ejs
@@ -166,10 +166,6 @@
Patienten
-
- Wartezimmer
-
-
Medikamente
diff --git a/views/partials/flash.ejs b/views/partials/flash.ejs
index 01e3c42..f4538f4 100644
--- a/views/partials/flash.ejs
+++ b/views/partials/flash.ejs
@@ -1,6 +1,9 @@
<% if (flash) { %>
-
- <%= flash.message %>
-
-
+
+ <%= flash.message %>
+
+
<% } %>
diff --git a/views/patient_overview.ejs b/views/patient_overview.ejs
index 052c869..1d2c891 100644
--- a/views/patient_overview.ejs
+++ b/views/patient_overview.ejs
@@ -84,13 +84,13 @@
✏️ Patient bearbeiten
-
@@ -142,7 +142,9 @@
<% } else { %> <% notes.forEach(n => { %>
- <%= new Date(n.created_at).toLocaleString("de-DE") %>
+ <%= new Date(n.created_at).toLocaleString("de-DE") %> <% if
+ (n.first_name && n.last_name) { %> – <%= (n.title ? n.title
+ + " " : "") %><%= n.first_name %> <%= n.last_name %> <% } %>
<%= n.note %>
diff --git a/views/waiting_room.ejs b/views/waiting_room.ejs
deleted file mode 100644
index 1cfcc68..0000000
--- a/views/waiting_room.ejs
+++ /dev/null
@@ -1,67 +0,0 @@
-
-
-
-
-
Wartezimmer
-
-
-
-
-
-
-
-
- <%- include("partials/flash") %> <% if (patients.length === 0) { %>
-
Keine Patienten im Wartezimmer
- <% } else { %>
-
-
-
-
- | Name |
- Geburtstag |
- Aktion |
-
-
-
- <% patients.forEach(p => { %>
-
- | <%= p.firstname %> <%= p.lastname %> |
- <%= new Date(p.birthdate).toLocaleDateString("de-DE") %> |
-
- <% if (user.role === 'arzt') { %>
-
- <% } else { %>
- 🔒 Nur Arzt
- <% } %>
- |
-
- <% }) %>
-
-
-
- <% } %>
-
-
-