diff --git a/controllers/admin.controller.js b/controllers/admin.controller.js index 0ae9390..1801c20 100644 --- a/controllers/admin.controller.js +++ b/controllers/admin.controller.js @@ -1,13 +1,23 @@ const db = require("../db"); -const { createUser, getAllUsers} = require("../services/admin.service"); +const { createUser, getAllUsers } = require("../services/admin.service"); const bcrypt = require("bcrypt"); async function listUsers(req, res) { + const { q } = req.query; + try { - const users = await getAllUsers(db); + let users; + + if (q) { + users = await getAllUsers(db, q); + } else { + users = await getAllUsers(db); + } + res.render("admin_users", { users, - currentUser: req.session.user + currentUser: req.session.user, + query: { q }, }); } catch (err) { console.error(err); @@ -18,7 +28,7 @@ async function listUsers(req, res) { function showCreateUser(req, res) { res.render("admin_create_user", { error: null, - user: req.session.user + user: req.session.user, }); } @@ -30,20 +40,20 @@ async function postCreateUser(req, res) { password, role, fachrichtung, - arztnummer + arztnummer, } = req.body; - first_name = first_name?.trim(); - last_name = last_name?.trim(); - username = username?.trim(); + first_name = first_name?.trim(); + last_name = last_name?.trim(); + username = username?.trim(); fachrichtung = fachrichtung?.trim(); - arztnummer = arztnummer?.trim(); + arztnummer = arztnummer?.trim(); // 🔴 Grundvalidierung if (!first_name || !last_name || !username || !password || !role) { return res.render("admin_create_user", { error: "Alle Pflichtfelder müssen ausgefüllt sein", - user: req.session.user + user: req.session.user, }); } @@ -52,7 +62,7 @@ async function postCreateUser(req, res) { if (!fachrichtung || !arztnummer) { return res.render("admin_create_user", { error: "Für Ärzte sind Fachrichtung und Arztnummer Pflicht", - user: req.session.user + user: req.session.user, }); } } else { @@ -75,20 +85,18 @@ async function postCreateUser(req, res) { req.session.flash = { type: "success", - message: "Benutzer erfolgreich angelegt" + message: "Benutzer erfolgreich angelegt", }; res.redirect("/admin/users"); - } catch (error) { res.render("admin_create_user", { error, - user: req.session.user + user: req.session.user, }); } } - async function changeUserRole(req, res) { const userId = req.params.id; const { role } = req.body; @@ -98,19 +106,21 @@ async function changeUserRole(req, res) { return res.redirect("/admin/users"); } - db.query( - "UPDATE users SET role = ? WHERE id = ?", - [role, userId], - err => { - if (err) { - console.error(err); - req.session.flash = { type: "danger", message: "Fehler beim Ändern der Rolle" }; - } else { - req.session.flash = { type: "success", message: "Rolle erfolgreich geändert" }; - } - res.redirect("/admin/users"); + db.query("UPDATE users SET role = ? WHERE id = ?", [role, userId], (err) => { + if (err) { + console.error(err); + req.session.flash = { + type: "danger", + message: "Fehler beim Ändern der Rolle", + }; + } else { + req.session.flash = { + type: "success", + message: "Rolle erfolgreich geändert", + }; } - ); + res.redirect("/admin/users"); + }); } async function resetUserPassword(req, res) { @@ -123,27 +133,74 @@ async function resetUserPassword(req, res) { } const hash = await bcrypt.hash(password, 10); - + db.query( "UPDATE users SET password = ? WHERE id = ?", [hash, userId], - err => { + (err) => { if (err) { console.error(err); - req.session.flash = { type: "danger", message: "Fehler beim Zurücksetzen" }; + req.session.flash = { + type: "danger", + message: "Fehler beim Zurücksetzen", + }; } else { - req.session.flash = { type: "success", message: "Passwort zurückgesetzt" }; + req.session.flash = { + type: "success", + message: "Passwort zurückgesetzt", + }; } res.redirect("/admin/users"); } ); } +function activateUser(req, res) { + const userId = req.params.id; + + db.query("UPDATE users SET active = 1 WHERE id = ?", [userId], (err) => { + if (err) { + console.error(err); + req.session.flash = { + type: "danger", + message: "Benutzer konnte nicht aktiviert werden", + }; + } else { + req.session.flash = { + type: "success", + message: "Benutzer wurde aktiviert", + }; + } + res.redirect("/admin/users"); + }); +} + +function deactivateUser(req, res) { + const userId = req.params.id; + + db.query("UPDATE users SET active = 0 WHERE id = ?", [userId], (err) => { + if (err) { + console.error(err); + req.session.flash = { + type: "danger", + message: "Benutzer konnte nicht deaktiviert werden", + }; + } else { + req.session.flash = { + type: "success", + message: "Benutzer wurde deaktiviert", + }; + } + res.redirect("/admin/users"); + }); +} module.exports = { listUsers, showCreateUser, postCreateUser, changeUserRole, - resetUserPassword + resetUserPassword, + activateUser, + deactivateUser, }; diff --git a/controllers/patient.controller.js b/controllers/patient.controller.js index c871b41..2021378 100644 --- a/controllers/patient.controller.js +++ b/controllers/patient.controller.js @@ -10,7 +10,7 @@ function createPatient(req, res) { db.query( "INSERT INTO patients (firstname, lastname, birthdate, active) VALUES (?, ?, ?, 1)", [firstname, lastname, birthdate], - err => { + (err) => { if (err) { console.error(err); return res.send("Datenbankfehler"); @@ -26,15 +26,28 @@ function listPatients(req, res) { let sql = "SELECT * FROM patients WHERE 1=1"; const params = []; - if (firstname) { sql += " AND firstname LIKE ?"; params.push(`%${firstname}%`); } - if (lastname) { sql += " AND lastname LIKE ?"; params.push(`%${lastname}%`); } - if (birthdate) { sql += " AND birthdate = ?"; params.push(birthdate); } + if (firstname) { + sql += " AND firstname LIKE ?"; + params.push(`%${firstname}%`); + } + if (lastname) { + sql += " AND lastname LIKE ?"; + params.push(`%${lastname}%`); + } + if (birthdate) { + sql += " AND birthdate = ?"; + params.push(birthdate); + } sql += " ORDER BY lastname, firstname"; db.query(sql, params, (err, patients) => { if (err) return res.send("Datenbankfehler"); - res.render("patients", { patients, query: req.query, user: req.session.user}); + res.render("patients", { + patients, + query: req.query, + user: req.session.user, + }); }); } @@ -43,12 +56,13 @@ function showEditPatient(req, res) { "SELECT * FROM patients WHERE id = ?", [req.params.id], (err, results) => { - if (err || results.length === 0) return res.send("Patient nicht gefunden"); + if (err || results.length === 0) + return res.send("Patient nicht gefunden"); res.render("patient_edit", { patient: results[0], error: null, user: req.session.user, - returnTo: req.query.returnTo || null + returnTo: req.query.returnTo || null, }); } ); @@ -71,13 +85,13 @@ function updatePatient(req, res) { postal_code, city, country, - notes + notes, } = req.body; if (!firstname || !lastname || !birthdate) { req.session.flash = { type: "warning", - message: "Vorname, Nachname und Geburtsdatum sind Pflichtfelder" + message: "Vorname, Nachname und Geburtsdatum sind Pflichtfelder", }; return res.redirect("back"); } @@ -112,9 +126,9 @@ function updatePatient(req, res) { city || null, country || null, notes || null, - id + id, ], - err => { + (err) => { if (err) { console.error(err); return res.send("Fehler beim Speichern"); @@ -174,14 +188,15 @@ function showPatientMedications(req, res) { if (err) return res.send("Medikamente konnten nicht geladen werden"); db.query(currentSql, [patientId], (err, currentMeds) => { - if (err) return res.send("Aktuelle Medikation konnte nicht geladen werden"); + if (err) + return res.send("Aktuelle Medikation konnte nicht geladen werden"); res.render("patient_medications", { patient: patients[0], meds, currentMeds, user: req.session.user, - returnTo + returnTo, }); }); }); @@ -199,7 +214,7 @@ function moveToWaitingRoom(req, res) { WHERE id = ? `, [id], - err => { + (err) => { if (err) return res.send("Fehler beim Verschieben ins Wartezimmer"); res.redirect("/patients"); } @@ -214,7 +229,7 @@ function showWaitingRoom(req, res) { res.render("waiting_room", { patients, - user: req.session.user + user: req.session.user, }); } ); @@ -236,15 +251,17 @@ function showPatientOverview(req, res) { ORDER BY created_at DESC `; - // 🔤 Services dynamisch nach Sprache laden - const servicesSql = (nameField) => ` + const medicationVariantsSql = ` SELECT - id, - ${nameField} AS name, - price - FROM services - WHERE active = 1 - ORDER BY ${nameField} + mv.id AS variant_id, + m.name AS medication_name, + mf.name AS form_name, + mv.dosage, + mv.package + FROM medication_variants mv + JOIN medications m ON mv.medication_id = m.id + JOIN medication_forms mf ON mv.form_id = mf.id + ORDER BY m.name, mf.name, mv.dosage `; db.query(patientSql, [patientId], (err, patients) => { @@ -254,12 +271,22 @@ function showPatientOverview(req, res) { const patient = patients[0]; - // 🇪🇸 / 🇩🇪 Sprache bestimmen + // 🇪🇸 / 🇩🇪 Sprache für Leistungen const serviceNameField = patient.country === "ES" ? "COALESCE(NULLIF(name_es, ''), name_de)" : "name_de"; + const servicesSql = ` + SELECT + id, + ${serviceNameField} AS name, + price + FROM services + WHERE active = 1 + ORDER BY ${serviceNameField} + `; + const todayServicesSql = ` SELECT ps.id, @@ -279,18 +306,23 @@ function showPatientOverview(req, res) { db.query(notesSql, [patientId], (err, notes) => { if (err) return res.send("Fehler Notizen"); - db.query(servicesSql(serviceNameField), (err, services) => { + db.query(servicesSql, (err, services) => { if (err) return res.send("Fehler Leistungen"); db.query(todayServicesSql, [patientId], (err, todayServices) => { if (err) return res.send("Fehler heutige Leistungen"); - res.render("patient_overview", { - patient, - notes, - services, - todayServices, - user: req.session.user + db.query(medicationVariantsSql, (err, medicationVariants) => { + if (err) return res.send("Fehler Medikamente"); + + res.render("patient_overview", { + patient, + notes, + services, + todayServices, + medicationVariants, + user: req.session.user, + }); }); }); }); @@ -298,6 +330,47 @@ function showPatientOverview(req, res) { }); } +function assignMedicationToPatient(req, res) { + const patientId = req.params.id; + const { medication_variant_id, dosage_instruction, start_date, end_date } = + req.body; + + if (!medication_variant_id) { + req.session.flash = { + type: "warning", + message: "Bitte ein Medikament auswählen", + }; + return res.redirect(`/patients/${patientId}/overview`); + } + + db.query( + ` + INSERT INTO patient_medications + (patient_id, medication_variant_id, dosage_instruction, start_date, end_date) + VALUES (?, ?, ?, ?, ?) + `, + [ + patientId, + medication_variant_id, + dosage_instruction || null, + start_date || new Date(), + end_date || null, + ], + (err) => { + if (err) { + console.error(err); + return res.send("Fehler beim Verordnen"); + } + + req.session.flash = { + type: "success", + message: "Medikament erfolgreich verordnet", + }; + + res.redirect(`/patients/${patientId}/overview`); + } + ); +} function addPatientNote(req, res) { const patientId = req.params.id; @@ -310,7 +383,7 @@ function addPatientNote(req, res) { db.query( "INSERT INTO patient_notes (patient_id, note) VALUES (?, ?)", [patientId, note], - err => { + (err) => { if (err) return res.send("Fehler beim Speichern der Notiz"); res.redirect(`/patients/${patientId}/overview`); } @@ -323,7 +396,7 @@ function callFromWaitingRoom(req, res) { db.query( "UPDATE patients SET waiting_room = 0 WHERE id = ?", [patientId], - err => { + (err) => { if (err) return res.send("Fehler beim Entfernen aus dem Wartezimmer"); res.redirect(`/patients/${patientId}/overview`); } @@ -336,7 +409,7 @@ function dischargePatient(req, res) { db.query( "UPDATE patients SET discharged = 1 WHERE id = ?", [patientId], - err => { + (err) => { if (err) return res.send("Fehler beim Entlassen des Patienten"); res.redirect("/waiting-room"); } @@ -375,7 +448,7 @@ function showMedicationPlan(req, res) { res.render("patient_plan", { patient: patients[0], - meds + meds, }); }); }); @@ -392,19 +465,19 @@ function movePatientToWaitingRoom(req, res) { WHERE id = ? `, [patientId], - err => { + (err) => { if (err) { console.error(err); req.session.flash = { type: "danger", - message: "Fehler beim Zurücksetzen ins Wartezimmer" + message: "Fehler beim Zurücksetzen ins Wartezimmer", }; return res.redirect(`/patients/${patientId}/overview`); } req.session.flash = { type: "success", - message: "Patient wurde ins Wartezimmer gesetzt" + message: "Patient wurde ins Wartezimmer gesetzt", }; res.redirect("/waiting-room"); @@ -415,55 +488,107 @@ function movePatientToWaitingRoom(req, res) { function deactivatePatient(req, res) { const id = req.params.id; - db.query( - "UPDATE patients SET active = 0 WHERE id = ?", - [id], - err => { - if (err) { - console.error(err); - req.session.flash = { - type: "danger", - message: "Patient konnte nicht gesperrt werden" - }; - return res.redirect("/patients"); - } - + db.query("UPDATE patients SET active = 0 WHERE id = ?", [id], (err) => { + if (err) { + console.error(err); req.session.flash = { - type: "success", - message: "Patient wurde gesperrt" + type: "danger", + message: "Patient konnte nicht gesperrt werden", }; - - res.redirect("/patients"); + return res.redirect("/patients"); } - ); + + req.session.flash = { + type: "success", + message: "Patient wurde gesperrt", + }; + + res.redirect("/patients"); + }); } function activatePatient(req, res) { const id = req.params.id; - db.query( - "UPDATE patients SET active = 1 WHERE id = ?", - [id], - err => { - if (err) { - console.error(err); - req.session.flash = { - type: "danger", - message: "Patient konnte nicht entsperrt werden" - }; - return res.redirect("/patients"); - } - + db.query("UPDATE patients SET active = 1 WHERE id = ?", [id], (err) => { + if (err) { + console.error(err); req.session.flash = { - type: "success", - message: "Patient wurde entsperrt" + type: "danger", + message: "Patient konnte nicht entsperrt werden", }; - - res.redirect("/patients"); + return res.redirect("/patients"); } - ); + + req.session.flash = { + type: "success", + message: "Patient wurde entsperrt", + }; + + res.redirect("/patients"); + }); } +async function showPatientOverviewDashborad(req, res) { + const patientId = req.params.id; + + try { + // 👤 Patient + const [[patient]] = await db + .promise() + .query("SELECT * FROM patients WHERE id = ?", [patientId]); + + if (!patient) { + return res.redirect("/patients"); + } + + // 💊 AKTUELLE MEDIKAMENTE (end_date IS NULL) + const [medications] = await db.promise().query( + ` + SELECT + m.name AS medication_name, + mv.dosage AS variant_dosage, + pm.dosage_instruction, + pm.start_date + FROM patient_medications pm + JOIN medication_variants mv + ON pm.medication_variant_id = mv.id + JOIN medications m + ON mv.medication_id = m.id + WHERE pm.patient_id = ? + AND pm.end_date IS NULL + ORDER BY pm.start_date DESC + `, + [patientId] + ); + + // 🧾 RECHNUNGEN + const [invoices] = await db.promise().query( + ` + SELECT + id, + invoice_date, + total_amount, + file_path, + status + FROM invoices + WHERE patient_id = ? + ORDER BY invoice_date DESC + `, + [patientId] + ); + + res.render("patient_overview_dashboard", { + patient, + medications, + invoices, + user: req.session.user, + }); + } catch (err) { + console.error(err); + res.send("Datenbankfehler"); + } +} module.exports = { listPatients, @@ -481,5 +606,7 @@ module.exports = { showMedicationPlan, movePatientToWaitingRoom, deactivatePatient, - activatePatient + activatePatient, + showPatientOverviewDashborad, + assignMedicationToPatient, }; diff --git a/public/invoices/2026/invoice-2026-0037.pdf b/public/invoices/2026/invoice-2026-0037.pdf new file mode 100644 index 0000000..dcb197f Binary files /dev/null and b/public/invoices/2026/invoice-2026-0037.pdf differ diff --git a/public/invoices/2026/invoice-2026-0038.pdf b/public/invoices/2026/invoice-2026-0038.pdf new file mode 100644 index 0000000..f73d673 Binary files /dev/null and b/public/invoices/2026/invoice-2026-0038.pdf differ diff --git a/routes/admin.routes.js b/routes/admin.routes.js index 74bec4b..a39dad3 100644 --- a/routes/admin.routes.js +++ b/routes/admin.routes.js @@ -6,7 +6,9 @@ const { showCreateUser, postCreateUser, changeUserRole, - resetUserPassword + resetUserPassword, + activateUser, + deactivateUser, } = require("../controllers/admin.controller"); const { requireAdmin } = require("../middleware/auth.middleware"); @@ -17,6 +19,7 @@ router.post("/create-user", requireAdmin, postCreateUser); router.post("/users/change-role/:id", requireAdmin, changeUserRole); router.post("/users/reset-password/:id", requireAdmin, resetUserPassword); +router.post("/users/activate/:id", requireAdmin, activateUser); +router.post("/users/deactivate/:id", requireAdmin, deactivateUser); module.exports = router; - diff --git a/routes/patient.routes.js b/routes/patient.routes.js index 271dc1f..7641a87 100644 --- a/routes/patient.routes.js +++ b/routes/patient.routes.js @@ -1,10 +1,7 @@ const express = require("express"); const router = express.Router(); -const { - requireLogin, - requireAdmin -} = require("../middleware/auth.middleware"); +const { requireLogin, requireAdmin } = require("../middleware/auth.middleware"); const { listPatients, @@ -20,7 +17,9 @@ const { dischargePatient, showMedicationPlan, deactivatePatient, - activatePatient + activatePatient, + showPatientOverviewDashborad, + assignMedicationToPatient, } = require("../controllers/patient.controller"); router.get("/", requireLogin, listPatients); @@ -35,8 +34,9 @@ router.post("/:id/notes", requireLogin, addPatientNote); router.post("/waiting-room/call/:id", requireAdmin, callFromWaitingRoom); router.post("/:id/discharge", requireLogin, dischargePatient); router.get("/:id/plan", requireLogin, showMedicationPlan); -router.post("/deactivate/:id", requireLogin, deactivatePatient); -router.post("/activate/:id", requireLogin, activatePatient); +router.post("/deactivate/:id", requireLogin, deactivatePatient); +router.post("/activate/:id", requireLogin, activatePatient); +router.get("/:id", requireLogin, showPatientOverviewDashborad); +router.post("/:id/medications/assign", requireLogin, assignMedicationToPatient); module.exports = router; - diff --git a/services/admin.service.js b/services/admin.service.js index 9e21dd7..5846c1b 100644 --- a/services/admin.service.js +++ b/services/admin.service.js @@ -17,16 +17,8 @@ async function createUser( `INSERT INTO users (first_name, last_name, username, password, role, fachrichtung, arztnummer, active) VALUES (?, ?, ?, ?, ?, ?, ?, 1)`, - [ - first_name, - last_name, - username, - hash, - role, - fachrichtung, - arztnummer - ], - err => { + [first_name, last_name, username, hash, role, fachrichtung, arztnummer], + (err) => { if (err) { if (err.code === "ER_DUP_ENTRY") { return reject("Benutzername existiert bereits"); @@ -39,28 +31,33 @@ async function createUser( }); } -function getAllUsers(db) { - return new Promise((resolve, reject) => { - db.query( - `SELECT - id, - first_name, - last_name, - username, - role, - active, - lock_until - FROM users - ORDER BY last_name, first_name`, - (err, users) => { - if (err) return reject(err); - resolve(users); - } - ); - }); +async function getAllUsers(db, search = null) { + let sql = ` + SELECT * + FROM users + WHERE 1=1 + `; + const params = []; + + if (search) { + sql += ` + AND ( + first_name LIKE ? + OR last_name LIKE ? + OR username LIKE ? + ) + `; + const q = `%${search}%`; + params.push(q, q, q); + } + + sql += " ORDER BY last_name, first_name"; + + const [rows] = await db.promise().query(sql, params); + return rows; } module.exports = { createUser, - getAllUsers + getAllUsers, }; diff --git a/views/admin_users.ejs b/views/admin_users.ejs index 84faeb6..44f7e03 100644 --- a/views/admin_users.ejs +++ b/views/admin_users.ejs @@ -44,6 +44,30 @@ + Neuen Benutzer anlegen +
+
+
+ + + + + <% if (query?.q) { %> + + Reset + + <% } %> +
+
+
+ + diff --git a/views/patient_medications.ejs b/views/patient_medications.ejs index 80605c3..13065f1 100644 --- a/views/patient_medications.ejs +++ b/views/patient_medications.ejs @@ -38,60 +38,6 @@ function formatDate(d) { <% if (user && user.role === 'arzt') { %>
-
- -
➕ Medikament hinzufügen
- -
- -
- - -
- -
- - -
- -
-
- - -
-
- - -
-
- - - - -
-
<% } else { %> diff --git a/views/patient_overview.ejs b/views/patient_overview.ejs index 5160157..052c869 100644 --- a/views/patient_overview.ejs +++ b/views/patient_overview.ejs @@ -1,282 +1,274 @@ - - - Patientenübersicht – <%= patient.firstname %> <%= patient.lastname %> - - + + + + Patientenübersicht – <%= patient.firstname %> <%= patient.lastname %> + + + + - - + + +
- - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Vorname<%= patient.firstname %>
Nachname<%= patient.lastname %>
Geburtsdatum - <%= patient.birthdate - ? new Date(patient.birthdate).toLocaleDateString("de-DE") - : "-" %> -
Geschlecht - <% if (patient.gender === 'm') { %>Männlich - <% } else if (patient.gender === 'w') { %>Weiblich - <% } else if (patient.gender === 'd') { %>Divers - <% } else { %>–<% } %> -
E-Mail<%= patient.email || "-" %>
Telefon<%= patient.phone || "-" %>
Adresse - <%= patient.street || "" %> <%= patient.house_number || "" %>
- <%= patient.postal_code || "" %> <%= patient.city || "" %>
- <%= patient.country || "" %> -
- - - - -
- - - 💊 Medikation - - - - 📄 Medikationsplan - - - - ✏️ Patient bearbeiten - - -
- +
+ + +
+ -
+
+ <%- include("partials/flash") %> - -
+ +
+
+

Patientendaten

+ + + + + + + + + + + + + + + + + + + + + +
Vorname<%= patient.firstname %>
Nachname<%= patient.lastname %>
Geburtsdatum + <%= patient.birthdate ? new + Date(patient.birthdate).toLocaleDateString("de-DE") : "-" %> +
E-Mail<%= patient.email || "-" %>
Telefon<%= patient.phone || "-" %>
+
+
- -
+ +
+ + 💊 Medikation verwalten + -
-
+ + ✏️ Patient bearbeiten + -
Notizen
+
+ +
+
-
+ +
+ +
+
+
+
📝 Notizen
- + + + + - - - -
- - <% if (!notes || notes.length === 0) { %> -

Keine Notizen vorhanden

- <% } else { %> - <% notes.forEach(n => { %> -
-
- <%= new Date(n.created_at).toLocaleString("de-DE") %> -
-
<%= n.note %>
-
- <% }) %> - <% } %> +
+
+ <% if (!notes || notes.length === 0) { %> +

Keine Notizen vorhanden

+ <% } else { %> <% notes.forEach(n => { %> +
+
+ <%= new Date(n.created_at).toLocaleString("de-DE") %> +
+
<%= n.note %>
+ <% }) %> <% } %> +
- +
- -
+ +
+
+
+
💊 Rezept erstellen
-
-
+
+ -
Heutige Leistungen
+ - - + -
- - -
+ -
- - -
- -
- - -
- - -
- -
- - - <% if (!todayServices || todayServices.length === 0) { %> -

- Noch keine Leistungen für heute erfasst. -

- <% } else { %> - - <% todayServices.forEach(ls => { %> -
- - <%= ls.name %>
- - Menge: <%= ls.quantity %>
- Preis: <%= Number(ls.price).toFixed(2) %> €
- - Arzt: <%= ls.doctor || "—" %> - - - -
- - -
- - -
- - -
- -
- -
-
- <% }) %> - - <% } %> - -
+ +
- +
+ +
+
+
+
🧾 Heutige Leistungen
+ +
+ + + + + + + +
+ +
+ +
+ <% if (!todayServices || todayServices.length === 0) { %> +

Noch keine Leistungen für heute.

+ <% } else { %> <% todayServices.forEach(ls => { %> +
+ <%= ls.name %>
+ Menge: <%= ls.quantity %>
+ Preis: <%= Number(ls.price).toFixed(2) %> € +
+ <% }) %> <% } %> +
+
+
+
+
- -
- - + diff --git a/views/patient_overview_dashboard.ejs b/views/patient_overview_dashboard.ejs new file mode 100644 index 0000000..95b28e9 --- /dev/null +++ b/views/patient_overview_dashboard.ejs @@ -0,0 +1,163 @@ + + + + + Patientenübersicht + + + + + + + + +
+ +
+
+

👤 <%= patient.firstname %> <%= patient.lastname %>

+ +

+ Geboren am <%= new + Date(patient.birthdate).toLocaleDateString("de-DE") %> +

+ +
    +
  • + E-Mail: <%= patient.email || "-" %> +
  • +
  • + Telefon: <%= patient.phone || "-" %> +
  • +
  • + Adresse: + <%= patient.street || "" %> <%= patient.house_number || "" %>, <%= + patient.postal_code || "" %> <%= patient.city || "" %> +
  • +
+
+
+ + +
+ +
+
+
+
💊 Aktuelle Medikamente
+ +
+ <% if (medications.length === 0) { %> +

Keine aktiven Medikamente

+ <% } else { %> + + + + + + + + + + <% medications.forEach(m => { %> + + + + + + <% }) %> + +
MedikamentVarianteAnweisung
<%= m.medication_name %><%= m.variant_dosage %><%= m.dosage_instruction || "-" %>
+ <% } %> +
+
+
+
+ + +
+
+
+
🧾 Rechnungen
+ +
+ <% if (invoices.length === 0) { %> +

Keine Rechnungen vorhanden

+ <% } else { %> + + + + + + + + + + <% invoices.forEach(i => { %> + + + + + + <% }) %> + +
DatumBetragPDF
+ <%= new Date(i.invoice_date).toLocaleDateString("de-DE") + %> + <%= Number(i.total_amount).toFixed(2) %> € + <% if (i.file_path) { %> + + 📄 Öffnen + + <% } else { %> - <% } %> +
+ <% } %> +
+
+
+
+
+
+ + diff --git a/views/patient_plan.ejs b/views/patient_plan.ejs deleted file mode 100644 index ec40bce..0000000 --- a/views/patient_plan.ejs +++ /dev/null @@ -1,74 +0,0 @@ - - - - - Medikationsplan – <%= patient.firstname %> <%= patient.lastname %> - - - - - - - -
- <%- include("partials/flash") %> -
-
- - - - - - - - - - - - - - - <% if (meds.length === 0) { %> - - - - <% } %> - - <% meds.forEach(m => { %> - - - - - - - - - <% }) %> - -
MedikamentFormDosierungPackungAnweisungZeitraum
- Keine aktuelle Medikation -
<%= m.medication %><%= m.form %><%= m.dosage %><%= m.package %><%= m.dosage_instruction || "-" %> - <%= m.start_date - ? new Date(m.start_date).toLocaleDateString("de-DE") - : "-" %> - – - <%= m.end_date - ? new Date(m.end_date).toLocaleDateString("de-DE") - : "laufend" %> -
- -
-
- -
- - - diff --git a/views/patients.ejs b/views/patients.ejs index bf0f191..d5b2cef 100644 --- a/views/patients.ejs +++ b/views/patients.ejs @@ -1,257 +1,270 @@ - - + + Patientenübersicht - - - - - + + + + -
- <%- include("partials/flash") %> +
+ <%- include("partials/flash") %> - - + + -
+
- - -
- -
- -
- -
- -
- -
- -
- -
- - - Zurücksetzen - -
- -
- - -
- - - - - - - - - - - - - - - - - - - - - - <% if (patients.length === 0) { %> - - - - <% } %> - - <% patients.forEach(p => { %> - - - - - - - - - - - - - - - - - - - - - - - - - - - - <% }) %> - - -
IDNameN.I.E. / DNIGeschlechtGeburtstagE-MailTelefonAdresseLandStatusNotizenErstelltGeändertAktionen
- Keine Patienten gefunden -
<%= p.id %><%= p.firstname %> <%= p.lastname %><%= p.dni || "-" %> - <% if (p.gender === 'm') { %>m - <% } else if (p.gender === 'w') { %>w - <% } else if (p.gender === 'd') { %>d - <% } else { %>-<% } %> - <%= new Date(p.birthdate).toLocaleDateString("de-DE") %><%= p.email || "-" %><%= p.phone || "-" %> - <%= p.street || "" %> <%= p.house_number || "" %>
- <%= p.postal_code || "" %> <%= p.city || "" %> -
<%= p.country || "-" %> - <% if (p.active) { %> - Aktiv - <% } else { %> - Inaktiv - <% } %> - - <%= p.notes ? p.notes.substring(0, 80) : "-" %> - <%= new Date(p.created_at).toLocaleString("de-DE") %><%= new Date(p.updated_at).toLocaleString("de-DE") %> - - - -
+ +
+
+
-
-
+
+ +
-
- - +
+ +
+ +
+ + + Zurücksetzen + +
+ + + +
+ + + + + + + + + + + + + + + + + + + + + <% if (patients.length === 0) { %> + + + + <% } %> <% patients.forEach(p => { %> + + + + + + + + + + + + + + + + + + + + + + + + + + + + <% }) %> + +
IDNameN.I.E. / DNIGeschlechtGeburtstagE-MailTelefonAdresseLandStatusNotizenErstelltGeändertAktionen
+ Keine Patienten gefunden +
<%= p.id %><%= p.firstname %> <%= p.lastname %><%= p.dni || "-" %> + <% if (p.gender === 'm') { %>m <% } else if (p.gender === + 'w') { %>w <% } else if (p.gender === 'd') { %>d <% } else { + %>-<% } %> + + <%= new Date(p.birthdate).toLocaleDateString("de-DE") %> + <%= p.email || "-" %><%= p.phone || "-" %> + <%= p.street || "" %> <%= p.house_number || "" %>
+ <%= p.postal_code || "" %> <%= p.city || "" %> +
<%= p.country || "-" %> + <% if (p.active) { %> + Aktiv + <% } else { %> + Inaktiv + <% } %> + + <%= p.notes ? p.notes.substring(0, 80) : "-" %> + <%= new Date(p.created_at).toLocaleString("de-DE") %><%= new Date(p.updated_at).toLocaleString("de-DE") %> + +
+
+
+
+
+ +