Medikamente übersicht geändert.

This commit is contained in:
Cay 2026-01-11 18:54:58 +00:00
parent 8754c22dc4
commit 961c024252
7 changed files with 352 additions and 146 deletions

90
app.js
View File

@ -1,16 +1,13 @@
const express = require("express"); const express = require("express");
const session = require("express-session"); const session = require("express-session");
const bcrypt = require("bcrypt");
const db = require("./db");
const fs = require("fs");
const path = require("path");
const { requireLogin, requireAdmin} = require("./middleware/auth.middleware");
const adminRoutes = require("./routes/admin.routes");
const dashboardRoutes = require("./routes/dashboard.routes");
const helmet = require("helmet"); const helmet = require("helmet");
const sessionStore = require("./config/session"); const sessionStore = require("./config/session");
require("dotenv").config();
const adminRoutes = require("./routes/admin.routes");
const dashboardRoutes = require("./routes/dashboard.routes");
const patientRoutes = require("./routes/patient.routes"); const patientRoutes = require("./routes/patient.routes");
const medicationRoutes = require("./routes/medication.routes"); const medicationRoutes = require("./routes/medications.routes");
const patientMedicationRoutes = require("./routes/patientMedication.routes"); const patientMedicationRoutes = require("./routes/patientMedication.routes");
const waitingRoomRoutes = require("./routes/waitingRoom.routes"); const waitingRoomRoutes = require("./routes/waitingRoom.routes");
const serviceRoutes = require("./routes/service.routes"); const serviceRoutes = require("./routes/service.routes");
@ -18,10 +15,7 @@ const patientServiceRoutes = require("./routes/patientService.routes");
const invoiceRoutes = require("./routes/invoice.routes"); const invoiceRoutes = require("./routes/invoice.routes");
const patientFileRoutes = require("./routes/patientFile.routes"); const patientFileRoutes = require("./routes/patientFile.routes");
const companySettingsRoutes = require("./routes/companySettings.routes"); const companySettingsRoutes = require("./routes/companySettings.routes");
const authRoutes = require("./routes/auth.routes");
require("dotenv").config();
const app = express(); const app = express();
@ -31,37 +25,31 @@ const app = express();
app.use(express.urlencoded({ extended: true })); app.use(express.urlencoded({ extended: true }));
app.use(helmet()); app.use(helmet());
app.use(session({ app.use(
session({
name: "praxis.sid", name: "praxis.sid",
secret: process.env.SESSION_SECRET, secret: process.env.SESSION_SECRET,
store: sessionStore, store: sessionStore,
resave: false, resave: false,
saveUninitialized: false saveUninitialized: false,
})); })
);
const flashMiddleware = require("./middleware/flash.middleware"); const flashMiddleware = require("./middleware/flash.middleware");
app.use(flashMiddleware); app.use(flashMiddleware);
app.use(express.static("public")); app.use(express.static("public"));
app.use("/uploads", express.static("uploads"));
app.set("view engine", "ejs"); app.set("view engine", "ejs");
app.use("/patients", require("./routes/patient.routes"));
app.use("/uploads", express.static("uploads"));
/* =============================== /* ===============================
COMPANYDATA COMPANY SETTINGS
================================ */ ================================ */
app.use(companySettingsRoutes); app.use(companySettingsRoutes);
/* =============================== /* ===============================
LOGIN AUTH / LOGIN
================================ */ ================================ */
const authRoutes = require("./routes/auth.routes");
app.use("/", authRoutes); app.use("/", authRoutes);
/* =============================== /* ===============================
@ -70,7 +58,7 @@ app.use("/", authRoutes);
app.use("/dashboard", dashboardRoutes); app.use("/dashboard", dashboardRoutes);
/* =============================== /* ===============================
Mitarbeiter ADMIN
================================ */ ================================ */
app.use("/admin", adminRoutes); app.use("/admin", adminRoutes);
@ -78,29 +66,33 @@ app.use("/admin", adminRoutes);
PATIENTEN PATIENTEN
================================ */ ================================ */
app.use("/patients", patientRoutes); app.use("/patients", patientRoutes);
app.use("/patients", patientMedicationRoutes);
app.use("/patients", patientServiceRoutes);
/* ===============================
MEDIKAMENTE
================================ */
app.use("/medications", medicationRoutes);
console.log("🧪 /medications Router mounted");
/* ===============================
LEISTUNGEN
================================ */
app.use("/services", serviceRoutes);
/* ===============================
DATEIEN
================================ */
app.use("/", patientFileRoutes); app.use("/", patientFileRoutes);
/* =============================== /* ===============================
MEDIKAMENTENÜBERSICHT WARTEZIMMER
================================ */ ================================ */
app.use("/medications", medicationRoutes);
app.use("/patients", patientMedicationRoutes);
// ===============================
// PATIENT INS WARTEZIMMER
// ===============================
app.use("/", waitingRoomRoutes); app.use("/", waitingRoomRoutes);
// =============================== /* ===============================
// Leistungen RECHNUNGEN
// =============================== ================================ */
app.use("/services", serviceRoutes);
app.use("/patients", patientServiceRoutes);
// ===============================
// RECHNUNGEN
// ===============================
app.use("/", invoiceRoutes); app.use("/", invoiceRoutes);
/* =============================== /* ===============================
@ -110,9 +102,9 @@ app.get("/logout", (req, res) => {
req.session.destroy(() => res.redirect("/")); req.session.destroy(() => res.redirect("/"));
}); });
// =============================== /* ===============================
// ERROR HANDLING (IMMER ZUM SCHLUSS) ERROR HANDLING
// =============================== ================================ */
app.use((err, req, res, next) => { app.use((err, req, res, next) => {
console.error(err); console.error(err);
res.status(500).send("Interner Serverfehler"); res.status(500).send("Interner Serverfehler");
@ -121,8 +113,8 @@ app.use((err, req, res, next) => {
/* =============================== /* ===============================
SERVER SERVER
================================ */ ================================ */
const PORT = 51777; // garantiert frei const PORT = 51777;
const HOST = "127.0.0.1"; // kein HTTP.sys const HOST = "127.0.0.1";
app.listen(PORT, HOST, () => { app.listen(PORT, HOST, () => {
console.log(`Server läuft auf http://${HOST}:${PORT}`); console.log(`Server läuft auf http://${HOST}:${PORT}`);

View File

@ -2,25 +2,50 @@ const db = require("../db");
// 📋 LISTE // 📋 LISTE
function listMedications(req, res, next) { function listMedications(req, res, next) {
const sql = ` const { q, onlyActive } = req.query;
let sql = `
SELECT SELECT
v.id, v.id,
m.id AS medication_id,
m.name AS medication, m.name AS medication,
m.active,
f.name AS form, f.name AS form,
v.dosage, v.dosage,
v.package v.package
FROM medication_variants v FROM medication_variants v
JOIN medications m ON v.medication_id = m.id JOIN medications m ON v.medication_id = m.id
JOIN medication_forms f ON v.form_id = f.id JOIN medication_forms f ON v.form_id = f.id
ORDER BY m.name, v.dosage WHERE 1=1
`; `;
db.query(sql, (err, rows) => { const params = [];
if (q) {
sql += `
AND (
m.name LIKE ?
OR f.name LIKE ?
OR v.dosage LIKE ?
OR v.package LIKE ?
)
`;
params.push(`%${q}%`, `%${q}%`, `%${q}%`, `%${q}%`);
}
if (onlyActive === "1") {
sql += " AND m.active = 1";
}
sql += " ORDER BY m.name, v.dosage";
db.query(sql, params, (err, rows) => {
if (err) return next(err); if (err) return next(err);
res.render("medications", { res.render("medications", {
rows, rows,
user: req.session.user query: { q, onlyActive },
user: req.session.user,
}); });
}); });
} }
@ -38,7 +63,7 @@ function updateMedication(req, res, next) {
WHERE id = ? WHERE id = ?
`; `;
db.query(sql, [dosage, pkg, id], err => { db.query(sql, [dosage, pkg, id], (err) => {
if (err) return next(err); if (err) return next(err);
req.session.flash = { type: "success", message: "Medikament gespeichert" }; req.session.flash = { type: "success", message: "Medikament gespeichert" };
@ -46,8 +71,67 @@ function updateMedication(req, res, next) {
}); });
} }
function toggleMedication(req, res, next) {
const id = req.params.id;
db.query(
"UPDATE medications SET active = NOT active WHERE id = ?",
[id],
(err) => {
if (err) return next(err);
res.redirect("/medications");
}
);
}
function showCreateMedication(req, res) {
const sql = "SELECT id, name FROM medication_forms ORDER BY name";
db.query(sql, (err, forms) => {
if (err) return res.send("DB Fehler");
res.render("medication_create", {
forms,
user: req.session.user,
error: null,
});
});
}
function createMedication(req, res) {
const { name, form_id, dosage, package: pkg } = req.body;
if (!name || !form_id || !dosage) {
return res.send("Pflichtfelder fehlen");
}
db.query(
"INSERT INTO medications (name, active) VALUES (?, 1)",
[name],
(err, result) => {
if (err) return res.send("Fehler Medikament");
const medicationId = result.insertId;
db.query(
`INSERT INTO medication_variants
(medication_id, form_id, dosage, package)
VALUES (?, ?, ?, ?)`,
[medicationId, form_id, dosage, pkg || null],
(err) => {
if (err) return res.send("Fehler Variante");
res.redirect("/medications");
}
);
}
);
}
module.exports = { module.exports = {
listMedications, listMedications,
updateMedication updateMedication,
toggleMedication,
showCreateMedication,
createMedication,
}; };

Binary file not shown.

View File

@ -4,12 +4,26 @@ const router = express.Router();
const { requireLogin } = require("../middleware/auth.middleware"); const { requireLogin } = require("../middleware/auth.middleware");
const { const {
listMedications, listMedications,
updateMedication updateMedication,
toggleMedication,
showCreateMedication,
createMedication,
} = require("../controllers/medication.controller"); } = require("../controllers/medication.controller");
console.log("✅ medication.routes geladen");
router.get("/", requireLogin, listMedications); router.get("/", requireLogin, listMedications);
// 🆕 Formular anzeigen
router.get("/create", requireLogin, showCreateMedication);
// 🆕 Speichern
router.post("/create", requireLogin, createMedication);
// 🆕 UPDATE pro Zeile // 🆕 UPDATE pro Zeile
router.post("/update/:id", requireLogin, updateMedication); router.post("/update/:id", requireLogin, updateMedication);
// 🆕 Toggle
router.post("/toggle/:id", requireLogin, toggleMedication);
module.exports = router; module.exports = router;

View File

@ -6,13 +6,16 @@ const {
addPatientService, addPatientService,
deletePatientService, deletePatientService,
updatePatientServicePrice, updatePatientServicePrice,
updatePatientServiceQuantity updatePatientServiceQuantity,
} = require("../controllers/patientService.controller"); } = require("../controllers/patientService.controller");
router.post("/:id/services", requireLogin, addPatientService); router.post("/:id/services", requireLogin, addPatientService);
router.post("/services/delete/:id", requireAdmin, deletePatientService); router.post("/services/delete/:id", requireAdmin, deletePatientService);
router.post("/services/update-price/:id", requireAdmin, updatePatientServicePrice); router.post(
router.post("/patients/services/update-quantity/:id", updatePatientServiceQuantity); "/services/update-price/:id",
requireAdmin,
updatePatientServicePrice
);
router.post("/services/update-quantity/:id", updatePatientServiceQuantity);
module.exports = router; module.exports = router;

View File

@ -0,0 +1,45 @@
<!DOCTYPE html>
<html>
<head>
<title>Neues Medikament</title>
<link rel="stylesheet" href="/css/bootstrap.min.css" />
</head>
<body class="bg-light">
<div class="container mt-4">
<h4> Neues Medikament</h4>
<% if (error) { %>
<div class="alert alert-danger"><%= error %></div>
<% } %>
<form method="POST" action="/medications/create">
<div class="mb-3">
<label class="form-label">Medikament</label>
<input name="name" class="form-control" required />
</div>
<div class="mb-3">
<label class="form-label">Darreichungsform</label>
<select name="form_id" class="form-control" required>
<% forms.forEach(f => { %>
<option value="<%= f.id %>"><%= f.name %></option>
<% }) %>
</select>
</div>
<div class="mb-3">
<label class="form-label">Dosierung</label>
<input name="dosage" class="form-control" required />
</div>
<div class="mb-3">
<label class="form-label">Packung</label>
<input name="package" class="form-control" />
</div>
<button class="btn btn-success">Speichern</button>
<a href="/medications" class="btn btn-secondary">Abbrechen</a>
</form>
</div>
</body>
</html>

View File

@ -1,87 +1,156 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="de"> <html lang="de">
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8" />
<title>Medikamentenübersicht</title> <title>Medikamentenübersicht</title>
<link rel="stylesheet" href="/css/bootstrap.min.css"> <link rel="stylesheet" href="/css/bootstrap.min.css" />
<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 Medikamente ROT */
tr.table-secondary > td {
background-color: #f8d7da !important;
}
</style>
</head> </head>
<body class="bg-light"> <body class="bg-light">
<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 --> <span style="font-size:1.3rem">💊</span>
<div class="position-absolute top-50 start-50 translate-middle
d-flex align-items-center gap-2 text-white">
<span style="font-size:1.3rem;">💊</span>
<span class="fw-semibold fs-5">Medikamentenübersicht</span> <span class="fw-semibold fs-5">Medikamentenübersicht</span>
</div> </div>
<!-- 🔵 RECHTS: DASHBOARD -->
<div class="ms-auto"> <div class="ms-auto">
<a href="/dashboard" class="btn btn-outline-light btn-sm"> <a href="/dashboard" class="btn btn-outline-light btn-sm">⬅️ Dashboard</a>
⬅️ Dashboard
</a>
</div> </div>
</nav> </nav>
<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">
<!-- 🔍 Suche -->
<form method="GET" action="/medications" class="row g-2 mb-3">
<div class="col-md-6">
<input type="text"
name="q"
class="form-control"
placeholder="🔍 Suche nach Medikament, Form, Dosierung"
value="<%= query?.q || '' %>">
</div>
<div class="col-md-3 d-flex gap-2">
<button class="btn btn-primary w-100">Suchen</button>
<a href="/medications" class="btn btn-secondary w-100">Reset</a>
</div>
<div class="col-md-3 d-flex align-items-center">
<div class="form-check">
<input class="form-check-input"
type="checkbox"
name="onlyActive"
value="1"
<%= query?.onlyActive === "1" ? "checked" : "" %>>
<label class="form-check-label">
Nur aktive Medikamente
</label>
</div>
</div>
</form>
<!-- Neu -->
<a href="/medications/create" class="btn btn-success mb-3">
Neues Medikament
</a>
<div class="table-responsive"> <div class="table-responsive">
<table class="table table-bordered table-hover table-sm align-middle"> <table class="table table-bordered table-hover table-sm align-middle">
<thead class="table-dark"> <thead class="table-dark">
<tr> <tr>
<th>Medikament</th> <th>Medikament</th>
<th>Darreichungsform</th> <th>Darreichungsform</th>
<th>Dosierung</th> <th>Dosierung</th>
<th>Packung</th> <th>Packung</th>
<th>Status</th>
<th>Aktionen</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<% rows.forEach(r => { %> <% rows.forEach(r => { %>
<tr>
<form method="POST"
action="/medications/update/<%= r.id %>">
<td> <tr class="<%= r.active ? '' : 'table-secondary' %>">
<input type="text"
name="medication"
value="<%= r.medication %>"
class="form-control form-control-sm"
required>
</td>
<td> <!-- UPDATE-FORM -->
<input type="text" <form method="POST" action="/medications/update/<%= r.id %>">
name="form"
value="<%= r.form %>" <td><%= r.medication %></td>
class="form-control form-control-sm"> <td><%= r.form %></td>
</td>
<td> <td>
<input type="text" <input type="text"
name="dosage" name="dosage"
value="<%= r.dosage %>" value="<%= r.dosage %>"
class="form-control form-control-sm"> class="form-control form-control-sm"
disabled>
</td> </td>
<td class="d-flex gap-2"> <td>
<input type="text" <input type="text"
name="package" name="package"
value="<%= r.package %>" value="<%= r.package %>"
class="form-control form-control-sm"> class="form-control form-control-sm"
disabled>
<button class="btn btn-sm btn-outline-success"
type="submit">
💾
</button>
</td> </td>
<td class="text-center">
<%= r.active ? "Aktiv" : "Inaktiv" %>
</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> </form>
<!-- TOGGLE-FORM (separat!) -->
<form method="POST" action="/medications/toggle/<%= r.medication_id %>">
<button class="btn btn-sm <%= r.active ? 'btn-outline-danger' : 'btn-outline-success' %>">
<%= r.active ? "⛔" : "✅" %>
</button>
</form>
</td>
</tr> </tr>
<% }) %> <% }) %>
</tbody> </tbody>
@ -90,7 +159,6 @@
</div> </div>
</div> </div>
</div> </div>
</body> </body>