Dr. Titel hinzugefügt und auch in den NOtizen
This commit is contained in:
parent
9b516a48c3
commit
1aef5a5749
@ -1,6 +1,10 @@
|
|||||||
const db = require("../db");
|
const db = require("../db");
|
||||||
const { createUser, getAllUsers } = require("../services/admin.service");
|
|
||||||
const bcrypt = require("bcrypt");
|
const bcrypt = require("bcrypt");
|
||||||
|
const {
|
||||||
|
createUser,
|
||||||
|
getAllUsers,
|
||||||
|
updateUserById,
|
||||||
|
} = require("../services/admin.service");
|
||||||
|
|
||||||
async function listUsers(req, res) {
|
async function listUsers(req, res) {
|
||||||
const { q } = req.query;
|
const { q } = req.query;
|
||||||
@ -34,6 +38,7 @@ function showCreateUser(req, res) {
|
|||||||
|
|
||||||
async function postCreateUser(req, res) {
|
async function postCreateUser(req, res) {
|
||||||
let {
|
let {
|
||||||
|
title,
|
||||||
first_name,
|
first_name,
|
||||||
last_name,
|
last_name,
|
||||||
username,
|
username,
|
||||||
@ -43,6 +48,7 @@ async function postCreateUser(req, res) {
|
|||||||
arztnummer,
|
arztnummer,
|
||||||
} = req.body;
|
} = req.body;
|
||||||
|
|
||||||
|
title = title?.trim();
|
||||||
first_name = first_name?.trim();
|
first_name = first_name?.trim();
|
||||||
last_name = last_name?.trim();
|
last_name = last_name?.trim();
|
||||||
username = username?.trim();
|
username = username?.trim();
|
||||||
@ -69,11 +75,13 @@ async function postCreateUser(req, res) {
|
|||||||
// Sicherheit: Mitarbeiter dürfen keine Arzt-Daten haben
|
// Sicherheit: Mitarbeiter dürfen keine Arzt-Daten haben
|
||||||
fachrichtung = null;
|
fachrichtung = null;
|
||||||
arztnummer = null;
|
arztnummer = null;
|
||||||
|
title = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await createUser(
|
await createUser(
|
||||||
db,
|
db,
|
||||||
|
title,
|
||||||
first_name,
|
first_name,
|
||||||
last_name,
|
last_name,
|
||||||
username,
|
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 = {
|
module.exports = {
|
||||||
listUsers,
|
listUsers,
|
||||||
showCreateUser,
|
showCreateUser,
|
||||||
@ -274,4 +326,5 @@ module.exports = {
|
|||||||
activateUser,
|
activateUser,
|
||||||
deactivateUser,
|
deactivateUser,
|
||||||
showInvoiceOverview,
|
showInvoiceOverview,
|
||||||
|
updateUser,
|
||||||
};
|
};
|
||||||
|
|||||||
@ -210,13 +210,14 @@ function moveToWaitingRoom(req, res) {
|
|||||||
`
|
`
|
||||||
UPDATE patients
|
UPDATE patients
|
||||||
SET waiting_room = 1,
|
SET waiting_room = 1,
|
||||||
discharged = 0
|
discharged = 0,
|
||||||
|
active = 1
|
||||||
WHERE id = ?
|
WHERE id = ?
|
||||||
`,
|
`,
|
||||||
[id],
|
[id],
|
||||||
(err) => {
|
(err) => {
|
||||||
if (err) return res.send("Fehler beim Verschieben ins Wartezimmer");
|
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 = `
|
const notesSql = `
|
||||||
SELECT *
|
SELECT
|
||||||
FROM patient_notes
|
pn.*,
|
||||||
WHERE patient_id = ?
|
u.title,
|
||||||
ORDER BY created_at DESC
|
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 = `
|
const medicationVariantsSql = `
|
||||||
SELECT
|
SELECT
|
||||||
@ -381,8 +387,9 @@ function addPatientNote(req, res) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
db.query(
|
db.query(
|
||||||
"INSERT INTO patient_notes (patient_id, note) VALUES (?, ?)",
|
"INSERT INTO patient_notes (patient_id, created_by, note) VALUES (?, ?, ?)",
|
||||||
[patientId, note],
|
[patientId, req.session.user.id, note],
|
||||||
|
|
||||||
(err) => {
|
(err) => {
|
||||||
if (err) return res.send("Fehler beim Speichern der Notiz");
|
if (err) return res.send("Fehler beim Speichern der Notiz");
|
||||||
res.redirect(`/patients/${patientId}/overview`);
|
res.redirect(`/patients/${patientId}/overview`);
|
||||||
@ -407,11 +414,21 @@ function dischargePatient(req, res) {
|
|||||||
const patientId = req.params.id;
|
const patientId = req.params.id;
|
||||||
|
|
||||||
db.query(
|
db.query(
|
||||||
"UPDATE patients SET discharged = 1 WHERE id = ?",
|
`
|
||||||
|
UPDATE patients
|
||||||
|
SET discharged = 1,
|
||||||
|
waiting_room = 0,
|
||||||
|
active = 0
|
||||||
|
WHERE id = ?
|
||||||
|
`,
|
||||||
[patientId],
|
[patientId],
|
||||||
(err) => {
|
(err) => {
|
||||||
if (err) return res.send("Fehler beim Entlassen des Patienten");
|
if (err) {
|
||||||
res.redirect("/waiting-room");
|
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
|
UPDATE patients
|
||||||
SET waiting_room = 1,
|
SET waiting_room = 1,
|
||||||
discharged = 0,
|
discharged = 0,
|
||||||
status = 'waiting'
|
status = 'waiting',
|
||||||
|
active = 1
|
||||||
WHERE id = ?
|
WHERE id = ?
|
||||||
`,
|
`,
|
||||||
[patientId],
|
[patientId],
|
||||||
@ -481,7 +499,7 @@ function movePatientToWaitingRoom(req, res) {
|
|||||||
message: "Patient wurde ins Wartezimmer gesetzt",
|
message: "Patient wurde ins Wartezimmer gesetzt",
|
||||||
};
|
};
|
||||||
|
|
||||||
res.redirect("/waiting-room");
|
return res.redirect("/dashboard");
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -62,3 +62,19 @@
|
|||||||
opacity: 0.4;
|
opacity: 0.4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.auto-hide-flash {
|
||||||
|
animation: flashFadeOut 3s forwards;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes flashFadeOut {
|
||||||
|
0% {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
70% {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
opacity: 0;
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -10,6 +10,7 @@ const {
|
|||||||
activateUser,
|
activateUser,
|
||||||
deactivateUser,
|
deactivateUser,
|
||||||
showInvoiceOverview,
|
showInvoiceOverview,
|
||||||
|
updateUser,
|
||||||
} = require("../controllers/admin.controller");
|
} = require("../controllers/admin.controller");
|
||||||
|
|
||||||
const { requireAdmin } = require("../middleware/auth.middleware");
|
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/activate/:id", requireAdmin, activateUser);
|
||||||
router.post("/users/deactivate/:id", requireAdmin, deactivateUser);
|
router.post("/users/deactivate/:id", requireAdmin, deactivateUser);
|
||||||
router.get("/invoices", requireAdmin, showInvoiceOverview);
|
router.get("/invoices", requireAdmin, showInvoiceOverview);
|
||||||
|
router.post("/users/update/:id", requireAdmin, updateUser);
|
||||||
|
|
||||||
module.exports = router;
|
module.exports = router;
|
||||||
|
|||||||
@ -2,6 +2,7 @@ const bcrypt = require("bcrypt");
|
|||||||
|
|
||||||
async function createUser(
|
async function createUser(
|
||||||
db,
|
db,
|
||||||
|
title,
|
||||||
first_name,
|
first_name,
|
||||||
last_name,
|
last_name,
|
||||||
username,
|
username,
|
||||||
@ -15,9 +16,18 @@ async function createUser(
|
|||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
db.query(
|
db.query(
|
||||||
`INSERT INTO users
|
`INSERT INTO users
|
||||||
(first_name, last_name, username, password, role, fachrichtung, arztnummer, active)
|
(title, first_name, last_name, username, password, role, fachrichtung, arztnummer, active)
|
||||||
VALUES (?, ?, ?, ?, ?, ?, ?, 1)`,
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, 1)`,
|
||||||
[first_name, last_name, username, hash, role, fachrichtung, arztnummer],
|
[
|
||||||
|
title,
|
||||||
|
first_name,
|
||||||
|
last_name,
|
||||||
|
username,
|
||||||
|
hash,
|
||||||
|
role,
|
||||||
|
fachrichtung,
|
||||||
|
arztnummer,
|
||||||
|
],
|
||||||
(err) => {
|
(err) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
if (err.code === "ER_DUP_ENTRY") {
|
if (err.code === "ER_DUP_ENTRY") {
|
||||||
@ -57,7 +67,27 @@ async function getAllUsers(db, search = null) {
|
|||||||
return rows;
|
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 = {
|
module.exports = {
|
||||||
createUser,
|
createUser,
|
||||||
getAllUsers,
|
getAllUsers,
|
||||||
|
updateUserById,
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,16 +1,15 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="de">
|
<html lang="de">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8" />
|
||||||
<title>Benutzer anlegen</title>
|
<title>Benutzer anlegen</title>
|
||||||
<link rel="stylesheet" href="/css/bootstrap.min.css">
|
<link rel="stylesheet" href="/css/bootstrap.min.css" />
|
||||||
</head>
|
</head>
|
||||||
<body class="bg-light">
|
<body class="bg-light">
|
||||||
|
<div class="container mt-5">
|
||||||
<div class="container mt-5">
|
|
||||||
<%- include("partials/flash") %>
|
<%- include("partials/flash") %>
|
||||||
|
|
||||||
<div class="card shadow mx-auto" style="max-width: 500px;">
|
<div class="card shadow mx-auto" style="max-width: 500px">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<h3 class="text-center mb-3">Benutzer anlegen</h3>
|
<h3 class="text-center mb-3">Benutzer anlegen</h3>
|
||||||
|
|
||||||
@ -19,56 +18,74 @@
|
|||||||
<% } %>
|
<% } %>
|
||||||
|
|
||||||
<form method="POST" action="/admin/create-user">
|
<form method="POST" action="/admin/create-user">
|
||||||
|
|
||||||
<!-- VORNAME -->
|
<!-- VORNAME -->
|
||||||
<input class="form-control mb-3"
|
<input
|
||||||
|
class="form-control mb-3"
|
||||||
name="first_name"
|
name="first_name"
|
||||||
placeholder="Vorname"
|
placeholder="Vorname"
|
||||||
required>
|
required
|
||||||
|
/>
|
||||||
|
|
||||||
<!-- NACHNAME -->
|
<!-- NACHNAME -->
|
||||||
<input class="form-control mb-3"
|
<input
|
||||||
|
class="form-control mb-3"
|
||||||
name="last_name"
|
name="last_name"
|
||||||
placeholder="Nachname"
|
placeholder="Nachname"
|
||||||
required>
|
required
|
||||||
|
/>
|
||||||
|
|
||||||
|
<!-- TITEL -->
|
||||||
|
<input
|
||||||
|
class="form-control mb-3"
|
||||||
|
name="title"
|
||||||
|
placeholder="Titel (z.B. Dr., Prof.)"
|
||||||
|
/>
|
||||||
|
|
||||||
<!-- BENUTZERNAME (LOGIN) -->
|
<!-- BENUTZERNAME (LOGIN) -->
|
||||||
<input class="form-control mb-3"
|
<input
|
||||||
|
class="form-control mb-3"
|
||||||
name="username"
|
name="username"
|
||||||
placeholder="Benutzername (Login)"
|
placeholder="Benutzername (Login)"
|
||||||
required>
|
required
|
||||||
|
/>
|
||||||
|
|
||||||
<!-- PASSWORT -->
|
<!-- PASSWORT -->
|
||||||
<input class="form-control mb-3"
|
<input
|
||||||
|
class="form-control mb-3"
|
||||||
type="password"
|
type="password"
|
||||||
name="password"
|
name="password"
|
||||||
placeholder="Passwort"
|
placeholder="Passwort"
|
||||||
required>
|
required
|
||||||
|
/>
|
||||||
|
|
||||||
<!-- ROLLE -->
|
<!-- ROLLE -->
|
||||||
<select class="form-select mb-3"
|
<select
|
||||||
|
class="form-select mb-3"
|
||||||
name="role"
|
name="role"
|
||||||
id="roleSelect"
|
id="roleSelect"
|
||||||
required>
|
required
|
||||||
|
>
|
||||||
<option value="">Rolle wählen</option>
|
<option value="">Rolle wählen</option>
|
||||||
<option value="mitarbeiter">Mitarbeiter</option>
|
<option value="mitarbeiter">Mitarbeiter</option>
|
||||||
<option value="arzt">Arzt</option>
|
<option value="arzt">Arzt</option>
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<!-- ARZT-FELDER -->
|
<!-- ARZT-FELDER -->
|
||||||
<div id="arztFields" style="display:none;">
|
<div id="arztFields" style="display: none">
|
||||||
<input class="form-control mb-3"
|
<input
|
||||||
|
class="form-control mb-3"
|
||||||
name="fachrichtung"
|
name="fachrichtung"
|
||||||
placeholder="Fachrichtung">
|
placeholder="Fachrichtung"
|
||||||
|
/>
|
||||||
|
|
||||||
<input class="form-control mb-3"
|
<input
|
||||||
|
class="form-control mb-3"
|
||||||
name="arztnummer"
|
name="arztnummer"
|
||||||
placeholder="Arztnummer">
|
placeholder="Arztnummer"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button class="btn btn-primary w-100">
|
<button class="btn btn-primary w-100">Benutzer erstellen</button>
|
||||||
Benutzer erstellen
|
|
||||||
</button>
|
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<div class="text-center mt-3">
|
<div class="text-center mt-3">
|
||||||
@ -76,15 +93,16 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
document.getElementById("roleSelect").addEventListener("change", function () {
|
document
|
||||||
|
.getElementById("roleSelect")
|
||||||
|
.addEventListener("change", function () {
|
||||||
const arztFields = document.getElementById("arztFields");
|
const arztFields = document.getElementById("arztFields");
|
||||||
arztFields.style.display = this.value === "arzt" ? "block" : "none";
|
arztFields.style.display = this.value === "arzt" ? "block" : "none";
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
<script src="/js/admin_create_user.js" defer></script>
|
<script src="/js/admin_create_user.js" defer></script>
|
||||||
|
</body>
|
||||||
</body>
|
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@ -1,100 +1,168 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="de">
|
<html lang="de">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8" />
|
||||||
<title>User Verwaltung</title>
|
<title>User Verwaltung</title>
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<!-- Bootstrap 5 -->
|
|
||||||
<link rel="stylesheet" href="/css/bootstrap.min.css">
|
<link rel="stylesheet" href="/css/bootstrap.min.css">
|
||||||
|
<link rel="stylesheet" href="/css/style.css">
|
||||||
<link rel="stylesheet" href="/bootstrap-icons/bootstrap-icons.min.css">
|
<link rel="stylesheet" href="/bootstrap-icons/bootstrap-icons.min.css">
|
||||||
|
<script src="/js/bootstrap.bundle.min.js"></script>
|
||||||
|
|
||||||
|
<!-- ✅ Inline Edit wie bei medications -->
|
||||||
|
<script src="/js/services-lock.js"></script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
input.form-control { box-shadow: none !important; }
|
||||||
|
|
||||||
|
input.form-control:disabled {
|
||||||
|
background-color: #fff !important;
|
||||||
|
color: #212529 !important;
|
||||||
|
opacity: 1 !important;
|
||||||
|
border: none !important;
|
||||||
|
box-shadow: none !important;
|
||||||
|
outline: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
input.form-control:disabled:focus {
|
||||||
|
box-shadow: none !important;
|
||||||
|
outline: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Inaktive User ROT */
|
||||||
|
tr.table-secondary > td {
|
||||||
|
background-color: #f8d7da !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="bg-light">
|
<body class="bg-light">
|
||||||
|
|
||||||
<!-- NAVBAR -->
|
|
||||||
<nav class="navbar navbar-dark bg-dark position-relative px-3">
|
<nav class="navbar navbar-dark bg-dark position-relative px-3">
|
||||||
|
<div class="position-absolute top-50 start-50 translate-middle d-flex align-items-center gap-2 text-white">
|
||||||
<!-- 🟢 ZENTRIERTER TITEL -->
|
|
||||||
<div class="position-absolute top-50 start-50 translate-middle
|
|
||||||
d-flex align-items-center gap-2 text-white">
|
|
||||||
<i class="bi bi-shield-lock fs-4"></i>
|
<i class="bi bi-shield-lock fs-4"></i>
|
||||||
<span class="fw-semibold fs-5">User Verwaltung</span>
|
<span class="fw-semibold fs-5">User Verwaltung</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 🔵 RECHTS: DASHBOARD -->
|
|
||||||
<div class="ms-auto">
|
<div class="ms-auto">
|
||||||
<a href="/dashboard" class="btn btn-outline-primary btn-sm">
|
<a href="/dashboard" class="btn btn-outline-light btn-sm">⬅️ Dashboard</a>
|
||||||
⬅️ Dashboard
|
|
||||||
</a>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
|
|
||||||
<!-- CONTENT -->
|
|
||||||
<div class="container mt-4">
|
<div class="container mt-4">
|
||||||
<%- include("partials/flash") %>
|
<%- include("partials/flash") %>
|
||||||
|
|
||||||
<div class="card shadow">
|
<div class="card shadow">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
|
|
||||||
<h4 class="mb-3">Benutzerübersicht</h4>
|
<h4 class="mb-3">Benutzerübersicht</h4>
|
||||||
|
|
||||||
<div class="table-responsive">
|
<!-- ➕ Neu -->
|
||||||
<div class="mb-3 text-end">
|
<div class="mb-3 text-end">
|
||||||
<a href="/admin/create-user" class="btn btn-primary">
|
<a href="/admin/create-user" class="btn btn-primary">
|
||||||
+ Neuen Benutzer anlegen
|
+ Neuen Benutzer anlegen
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="row mb-3 align-items-end">
|
|
||||||
<div class="col-md-6">
|
<!-- 🔍 Suche -->
|
||||||
<form method="GET" action="/admin/users" class="d-flex gap-2">
|
<form method="GET" action="/admin/users" class="d-flex gap-2 mb-3">
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
name="q"
|
name="q"
|
||||||
class="form-control"
|
class="form-control"
|
||||||
placeholder="🔍 Benutzer suchen (Name oder Username)"
|
placeholder="🔍 Benutzer suchen (Name oder Username)"
|
||||||
value="<%= query?.q || '' %>">
|
value="<%= query?.q || '' %>"
|
||||||
|
>
|
||||||
<button class="btn btn-outline-primary">
|
<button class="btn btn-outline-primary">Suchen</button>
|
||||||
Suchen
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<% if (query?.q) { %>
|
<% if (query?.q) { %>
|
||||||
<a href="/admin/users" class="btn btn-outline-secondary">
|
<a href="/admin/users" class="btn btn-outline-secondary">Reset</a>
|
||||||
Reset
|
|
||||||
</a>
|
|
||||||
<% } %>
|
<% } %>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
<div class="table-responsive">
|
||||||
|
<table class="table table-bordered table-hover table-sm align-middle">
|
||||||
|
|
||||||
<table class="table table-bordered table-hover align-middle">
|
|
||||||
<thead class="table-dark">
|
<thead class="table-dark">
|
||||||
<tr>
|
<tr>
|
||||||
<th>ID</th>
|
<th>ID</th>
|
||||||
<th>Name</th>
|
<th>Titel</th>
|
||||||
|
<th>Vorname</th>
|
||||||
|
<th>Nachname</th>
|
||||||
|
<th>Username</th>
|
||||||
<th>Rolle</th>
|
<th>Rolle</th>
|
||||||
<th>Status</th>
|
<th>Status</th>
|
||||||
<th style="width: 340px;">Aktionen</th>
|
<th style="width: 260px;">Aktionen</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
|
||||||
|
|
||||||
|
<tbody>
|
||||||
<% users.forEach(u => { %>
|
<% users.forEach(u => { %>
|
||||||
<tr>
|
|
||||||
|
<tr class="<%= u.active ? '' : 'table-secondary' %>">
|
||||||
|
|
||||||
|
<!-- ✅ UPDATE-FORM (wie medications) -->
|
||||||
|
<form method="POST" action="/admin/users/update/<%= u.id %>">
|
||||||
|
|
||||||
<td><%= u.id %></td>
|
<td><%= u.id %></td>
|
||||||
|
|
||||||
<td>
|
<td>
|
||||||
<strong><%= u.first_name %> <%= u.last_name %></strong><br>
|
<input
|
||||||
<small class="text-muted">@<%= u.username %></small>
|
type="text"
|
||||||
|
name="title"
|
||||||
|
value="<%= u.title || '' %>"
|
||||||
|
class="form-control form-control-sm"
|
||||||
|
disabled
|
||||||
|
>
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<td>
|
<td>
|
||||||
<% if (u.role === "arzt") { %>
|
<input
|
||||||
<span class="badge bg-warning text-dark">Arzt</span>
|
type="text"
|
||||||
<% } else { %>
|
name="first_name"
|
||||||
<span class="badge bg-info text-dark">Mitarbeiter</span>
|
value="<%= u.first_name %>"
|
||||||
<% } %>
|
class="form-control form-control-sm"
|
||||||
|
disabled
|
||||||
|
>
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<td>
|
<td>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
name="last_name"
|
||||||
|
value="<%= u.last_name %>"
|
||||||
|
class="form-control form-control-sm"
|
||||||
|
disabled
|
||||||
|
>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
name="username"
|
||||||
|
value="<%= u.username %>"
|
||||||
|
class="form-control form-control-sm"
|
||||||
|
disabled
|
||||||
|
>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td>
|
||||||
|
<select
|
||||||
|
name="role"
|
||||||
|
class="form-select form-select-sm"
|
||||||
|
disabled
|
||||||
|
>
|
||||||
|
<option value="mitarbeiter" <%= u.role === "mitarbeiter" ? "selected" : "" %>>
|
||||||
|
Mitarbeiter
|
||||||
|
</option>
|
||||||
|
<option value="arzt" <%= u.role === "arzt" ? "selected" : "" %>>
|
||||||
|
Arzt
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td class="text-center">
|
||||||
<% if (u.active === 0) { %>
|
<% if (u.active === 0) { %>
|
||||||
<span class="badge bg-secondary">Inaktiv</span>
|
<span class="badge bg-secondary">Inaktiv</span>
|
||||||
<% } else if (u.lock_until && new Date(u.lock_until) > new Date()) { %>
|
<% } else if (u.lock_until && new Date(u.lock_until) > new Date()) { %>
|
||||||
@ -104,78 +172,42 @@
|
|||||||
<% } %>
|
<% } %>
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<td>
|
<td class="d-flex gap-2">
|
||||||
|
|
||||||
|
<button class="btn btn-sm btn-outline-success save-btn" disabled>
|
||||||
|
💾
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button type="button" class="btn btn-sm btn-outline-warning lock-btn">
|
||||||
|
🔓
|
||||||
|
</button>
|
||||||
|
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<!-- ✅ Aktiv / Deaktiv separat -->
|
||||||
<% if (u.id !== currentUser.id) { %>
|
<% if (u.id !== currentUser.id) { %>
|
||||||
|
<form method="POST" action="/admin/users/<%= u.active ? "deactivate" : "activate" %>/<%= u.id %>">
|
||||||
<!-- AKTIV / INAKTIV -->
|
<button class="btn btn-sm <%= u.active ? "btn-outline-danger" : "btn-outline-success" %>">
|
||||||
<% if (u.active === 1) { %>
|
<%= u.active ? "⛔" : "✅" %>
|
||||||
<form method="POST"
|
|
||||||
action="/admin/users/deactivate/<%= u.id %>"
|
|
||||||
class="mb-1">
|
|
||||||
<button class="btn btn-sm btn-secondary w-100">
|
|
||||||
Deaktivieren
|
|
||||||
</button>
|
</button>
|
||||||
</form>
|
</form>
|
||||||
<% } else { %>
|
<% } else { %>
|
||||||
<form method="POST"
|
<span class="text-muted fst-italic small align-self-center">
|
||||||
action="/admin/users/activate/<%= u.id %>"
|
|
||||||
class="mb-1">
|
|
||||||
<button class="btn btn-sm btn-success w-100">
|
|
||||||
Aktivieren
|
|
||||||
</button>
|
|
||||||
</form>
|
|
||||||
<% } %>
|
|
||||||
|
|
||||||
<!-- ROLLE ÄNDERN -->
|
|
||||||
<form method="POST"
|
|
||||||
action="/admin/users/change-role/<%= u.id %>"
|
|
||||||
class="mb-1">
|
|
||||||
<select name="role"
|
|
||||||
class="form-select form-select-sm mb-1">
|
|
||||||
<option value="mitarbeiter"
|
|
||||||
<%= u.role === "mitarbeiter" ? "selected" : "" %>>
|
|
||||||
Mitarbeiter
|
|
||||||
</option>
|
|
||||||
<option value="arzt"
|
|
||||||
<%= u.role === "arzt" ? "selected" : "" %>>
|
|
||||||
Arzt
|
|
||||||
</option>
|
|
||||||
</select>
|
|
||||||
<button class="btn btn-sm btn-warning w-100">
|
|
||||||
Rolle ändern
|
|
||||||
</button>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
<!-- PASSWORT RESET -->
|
|
||||||
<form method="POST"
|
|
||||||
action="/admin/users/reset-password/<%= u.id %>">
|
|
||||||
<input type="password"
|
|
||||||
name="password"
|
|
||||||
class="form-control form-control-sm mb-1"
|
|
||||||
placeholder="Neues Passwort"
|
|
||||||
required>
|
|
||||||
<button class="btn btn-sm btn-danger w-100"
|
|
||||||
onclick="return confirm('Passwort wirklich zurücksetzen?')">
|
|
||||||
Passwort zurücksetzen
|
|
||||||
</button>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
<% } else { %>
|
|
||||||
<span class="text-muted fst-italic">
|
|
||||||
Du selbst
|
Du selbst
|
||||||
</span>
|
</span>
|
||||||
<% } %>
|
<% } %>
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<% }) %>
|
|
||||||
|
|
||||||
|
<% }) %>
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
@ -166,10 +166,6 @@
|
|||||||
<i class="bi bi-people"></i> Patienten
|
<i class="bi bi-people"></i> Patienten
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<a href="/waiting-room" class="nav-item">
|
|
||||||
<i class="bi bi-chair"></i> Wartezimmer
|
|
||||||
</a>
|
|
||||||
|
|
||||||
<a href="/medications" class="nav-item">
|
<a href="/medications" class="nav-item">
|
||||||
<i class="bi bi-capsule"></i> Medikamente
|
<i class="bi bi-capsule"></i> Medikamente
|
||||||
</a>
|
</a>
|
||||||
|
|||||||
@ -1,6 +1,9 @@
|
|||||||
<% if (flash) { %>
|
<% if (flash) { %>
|
||||||
<div class="alert alert-<%= flash.type %> alert-dismissible fade show" role="alert">
|
<div
|
||||||
|
class="alert alert-<%= flash.type %> alert-dismissible fade show auto-hide-flash"
|
||||||
|
role="alert"
|
||||||
|
>
|
||||||
<%= flash.message %>
|
<%= flash.message %>
|
||||||
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
|
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
|
||||||
</div>
|
</div>
|
||||||
<% } %>
|
<% } %>
|
||||||
|
|||||||
@ -84,13 +84,13 @@
|
|||||||
✏️ Patient bearbeiten
|
✏️ Patient bearbeiten
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<form
|
<form method="POST" action="/patients/<%= patient.id %>/discharge">
|
||||||
method="POST"
|
<button
|
||||||
action="/patients/<%= patient.id %>/discharge"
|
class="btn btn-danger btn-sm"
|
||||||
class="d-inline"
|
onclick="return confirm('Patient wirklich entlassen?')"
|
||||||
onsubmit="return confirm('Patient wirklich entlassen?')"
|
|
||||||
>
|
>
|
||||||
<button class="btn btn-danger">🟥 Entlassen</button>
|
✅ Entlassen
|
||||||
|
</button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -142,7 +142,9 @@
|
|||||||
<% } else { %> <% notes.forEach(n => { %>
|
<% } else { %> <% notes.forEach(n => { %>
|
||||||
<div class="mb-3 p-2 border rounded bg-light">
|
<div class="mb-3 p-2 border rounded bg-light">
|
||||||
<div class="small text-muted">
|
<div class="small text-muted">
|
||||||
<%= 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 %> <% } %>
|
||||||
</div>
|
</div>
|
||||||
<div><%= n.note %></div>
|
<div><%= n.note %></div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,67 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="de">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8" />
|
|
||||||
<title>Wartezimmer</title>
|
|
||||||
<link rel="stylesheet" href="/css/bootstrap.min.css" />
|
|
||||||
<link rel="stylesheet" href="/bootstrap-icons/bootstrap-icons.min.css" />
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<nav class="navbar navbar-dark bg-dark position-relative px-3">
|
|
||||||
<!-- 🟢 ZENTRIERTER TITEL -->
|
|
||||||
<div
|
|
||||||
class="position-absolute top-50 start-50 translate-middle d-flex align-items-center gap-2 text-white"
|
|
||||||
>
|
|
||||||
<span style="font-size: 1.4rem">🪑</span>
|
|
||||||
<span class="fw-semibold fs-5">Wartezimmer</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 🔵 RECHTS: DASHBOARD -->
|
|
||||||
<div class="ms-auto">
|
|
||||||
<a href="/dashboard" class="btn btn-outline-primary btn-sm">
|
|
||||||
⬅️ Dashboard
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</nav>
|
|
||||||
|
|
||||||
<div class="container mt-4">
|
|
||||||
<!-- ✅ EINMAL Flash anzeigen -->
|
|
||||||
<%- include("partials/flash") %> <% if (patients.length === 0) { %>
|
|
||||||
<div class="alert alert-info">Keine Patienten im Wartezimmer</div>
|
|
||||||
<% } else { %>
|
|
||||||
|
|
||||||
<table class="table table-bordered table-hover">
|
|
||||||
<thead class="table-light">
|
|
||||||
<tr>
|
|
||||||
<th>Name</th>
|
|
||||||
<th>Geburtstag</th>
|
|
||||||
<th>Aktion</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<% patients.forEach(p => { %>
|
|
||||||
<tr>
|
|
||||||
<td><strong><%= p.firstname %> <%= p.lastname %></strong></td>
|
|
||||||
<td><%= new Date(p.birthdate).toLocaleDateString("de-DE") %></td>
|
|
||||||
<td>
|
|
||||||
<% if (user.role === 'arzt') { %>
|
|
||||||
<form
|
|
||||||
method="POST"
|
|
||||||
action="patients/waiting-room/call/<%= p.id %>"
|
|
||||||
class="d-inline"
|
|
||||||
>
|
|
||||||
<button class="btn btn-sm btn-success">▶️ Aufrufen</button>
|
|
||||||
</form>
|
|
||||||
<% } else { %>
|
|
||||||
<span class="text-muted">🔒 Nur Arzt</span>
|
|
||||||
<% } %>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<% }) %>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<% } %>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
Loading…
Reference in New Issue
Block a user