Upload der Dateien bei den Patienten klappt nun wieder.
This commit is contained in:
parent
65bb75d437
commit
fbe1b34b25
@ -33,12 +33,12 @@ async function listPatients(req, res) {
|
|||||||
const params = [];
|
const params = [];
|
||||||
|
|
||||||
if (firstname) {
|
if (firstname) {
|
||||||
sql += " AND firstname LIKE ?";
|
sql += " AND LOWER(firstname) LIKE LOWER(?)";
|
||||||
params.push(`%${firstname}%`);
|
params.push(`%${firstname}%`);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lastname) {
|
if (lastname) {
|
||||||
sql += " AND lastname LIKE ?";
|
sql += " AND LOWER(lastname) LIKE LOWER(?)";
|
||||||
params.push(`%${lastname}%`);
|
params.push(`%${lastname}%`);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -79,7 +79,7 @@ async function listPatients(req, res) {
|
|||||||
|
|
||||||
// ✅ Sidebar dynamisch
|
// ✅ Sidebar dynamisch
|
||||||
sidebarPartial: selectedPatient
|
sidebarPartial: selectedPatient
|
||||||
? "partials/patient-sidebar"
|
? "partials/patient_sidebar"
|
||||||
: "partials/sidebar",
|
: "partials/sidebar",
|
||||||
|
|
||||||
// ✅ Active dynamisch
|
// ✅ Active dynamisch
|
||||||
@ -114,7 +114,7 @@ function showEditPatient(req, res) {
|
|||||||
|
|
||||||
res.render("patient_edit", {
|
res.render("patient_edit", {
|
||||||
title: "Patient bearbeiten",
|
title: "Patient bearbeiten",
|
||||||
sidebarPartial: "partials/patient-sidebar",
|
sidebarPartial: "partials/patient_sidebar",
|
||||||
active: "patient_edit",
|
active: "patient_edit",
|
||||||
|
|
||||||
patient: results[0],
|
patient: results[0],
|
||||||
@ -538,7 +538,7 @@ function showMedicationPlan(req, res) {
|
|||||||
|
|
||||||
res.render("patient_plan", {
|
res.render("patient_plan", {
|
||||||
title: "Medikationsplan",
|
title: "Medikationsplan",
|
||||||
sidebarPartial: "partials/patient-sidebar",
|
sidebarPartial: "partials/patient_sidebar",
|
||||||
active: "patient_plan",
|
active: "patient_plan",
|
||||||
|
|
||||||
patient: patients[0],
|
patient: patients[0],
|
||||||
@ -675,7 +675,7 @@ async function showPatientOverviewDashborad(req, res) {
|
|||||||
|
|
||||||
res.render("patient_overview_dashboard", {
|
res.render("patient_overview_dashboard", {
|
||||||
title: "Patient Dashboard",
|
title: "Patient Dashboard",
|
||||||
sidebarPartial: "partials/patient-sidebar",
|
sidebarPartial: "partials/patient_sidebar",
|
||||||
active: "patient_dashboard",
|
active: "patient_dashboard",
|
||||||
|
|
||||||
patient,
|
patient,
|
||||||
|
|||||||
@ -287,7 +287,7 @@ async function listOpenServices(req, res, next) {
|
|||||||
|
|
||||||
res.render("open_services", {
|
res.render("open_services", {
|
||||||
title: "Offene Leistungen",
|
title: "Offene Leistungen",
|
||||||
sidebarPartial: "partials/sidebar-empty",
|
sidebarPartial: "partials/patient_sidebar",
|
||||||
active: "services",
|
active: "services",
|
||||||
|
|
||||||
rows,
|
rows,
|
||||||
|
|||||||
@ -40,7 +40,7 @@ document.addEventListener("DOMContentLoaded", () => {
|
|||||||
|
|
||||||
radios.forEach((radio) => {
|
radios.forEach((radio) => {
|
||||||
radio.addEventListener("change", () => {
|
radio.addEventListener("change", () => {
|
||||||
const id = radio.dataset.id;
|
const id = radio.value;
|
||||||
const firstname = radio.dataset.firstname;
|
const firstname = radio.dataset.firstname;
|
||||||
const lastname = radio.dataset.lastname;
|
const lastname = radio.dataset.lastname;
|
||||||
|
|
||||||
|
|||||||
@ -42,5 +42,6 @@
|
|||||||
<!-- ✅ externes JS (CSP safe) -->
|
<!-- ✅ externes JS (CSP safe) -->
|
||||||
<script src="/js/datetime.js"></script>
|
<script src="/js/datetime.js"></script>
|
||||||
<script src="/js/patient-select.js" defer></script>
|
<script src="/js/patient-select.js" defer></script>
|
||||||
|
<script src="/js/patient_sidebar.js" defer></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@ -1,71 +1,157 @@
|
|||||||
|
<%
|
||||||
|
// =========================
|
||||||
|
// BASISDATEN
|
||||||
|
// =========================
|
||||||
|
const role = user?.role || null;
|
||||||
|
|
||||||
|
// Arzt + Mitarbeiter dürfen Patienten bedienen
|
||||||
|
const canPatientArea = role === "arzt" || role === "mitarbeiter";
|
||||||
|
|
||||||
|
const pid = patient && patient.id ? patient.id : null;
|
||||||
|
const isActive = patient && patient.active ? true : false;
|
||||||
|
const isWaiting = patient && patient.waiting_room ? true : false;
|
||||||
|
|
||||||
|
const canUsePatient = canPatientArea && !!pid;
|
||||||
|
|
||||||
|
function lockClass(allowed) {
|
||||||
|
return allowed ? "" : "locked";
|
||||||
|
}
|
||||||
|
|
||||||
|
function hrefIfAllowed(allowed, href) {
|
||||||
|
return allowed ? href : "#";
|
||||||
|
}
|
||||||
|
%>
|
||||||
|
|
||||||
|
|
||||||
<div class="sidebar">
|
<div class="sidebar">
|
||||||
<div class="sidebar-header">
|
|
||||||
<div class="logo">
|
|
||||||
<i class="bi bi-person-lines-fill"></i>
|
|
||||||
Patient
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- ✅ Patient Info wird per JS ersetzt -->
|
<!-- ✅ Logo -->
|
||||||
<div class="patient-badge" id="sidebarPatientInfo">
|
<div style="margin-bottom:30px; display:flex; flex-direction:column; gap:10px;">
|
||||||
<div class="patient-name">
|
<div style="padding:20px; text-align:center;">
|
||||||
<strong>Kein Patient gewählt</strong>
|
<div class="logo" style="margin:0;">🩺 Praxis System</div>
|
||||||
</div>
|
|
||||||
<div class="patient-meta text-muted">Bitte Patient auswählen</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- ✅ Übersicht -->
|
<!-- ✅ Zurück -->
|
||||||
<a id="sbOverview" href="#" class="nav-item disabled">
|
<a href="<%= backUrl || '/patients' %>" class="nav-item">
|
||||||
<i class="bi bi-clipboard2-check"></i> Übersicht
|
<i class="bi bi-arrow-left-circle"></i> Zurück
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<!-- ✅ Verlauf -->
|
<div style="margin:10px 0; border-top:1px solid rgba(255,255,255,0.12);"></div>
|
||||||
<a id="sbHistory" href="#" class="nav-item disabled">
|
|
||||||
<i class="bi bi-clock-history"></i> Verlauf
|
|
||||||
</a>
|
|
||||||
|
|
||||||
<!-- ✅ Bearbeiten -->
|
<!-- ✅ Kein Patient gewählt -->
|
||||||
<a id="sbEdit" href="#" class="nav-item disabled">
|
<% if (!pid) { %>
|
||||||
<i class="bi bi-pencil-square"></i> Bearbeiten
|
<div class="nav-item locked" style="opacity:0.7;">
|
||||||
</a>
|
<i class="bi bi-info-circle"></i> Bitte Patient auswählen
|
||||||
|
<span style="margin-left:auto;"><i class="bi bi-lock-fill"></i></span>
|
||||||
|
</div>
|
||||||
|
<% } %>
|
||||||
|
|
||||||
<!-- ✅ Medikamente -->
|
<!-- =========================
|
||||||
<a id="sbMeds" href="#" class="nav-item disabled">
|
WARTEZIMMER
|
||||||
<i class="bi bi-capsule"></i> Medikamente
|
========================= -->
|
||||||
</a>
|
<% if (pid && canPatientArea) { %>
|
||||||
|
|
||||||
<!-- ✅ Wartezimmer -->
|
<% if (isWaiting) { %>
|
||||||
<div id="sbWaitingRoomWrapper">
|
<div class="nav-item locked" style="opacity:0.75;">
|
||||||
<div class="nav-item disabled">
|
<i class="bi bi-hourglass-split"></i> Wartet bereits
|
||||||
|
<span style="margin-left:auto;"><i class="bi bi-check-circle-fill"></i></span>
|
||||||
|
</div>
|
||||||
|
<% } else { %>
|
||||||
|
<form method="POST" action="/patients/waiting-room/<%= pid %>">
|
||||||
|
<button
|
||||||
|
type="submit"
|
||||||
|
class="nav-item"
|
||||||
|
style="width:100%; border:none; background:transparent; text-align:left;"
|
||||||
|
title="Patient ins Wartezimmer setzen"
|
||||||
|
>
|
||||||
<i class="bi bi-door-open"></i> Ins Wartezimmer
|
<i class="bi bi-door-open"></i> Ins Wartezimmer
|
||||||
</div>
|
</button>
|
||||||
</div>
|
</form>
|
||||||
|
<% } %>
|
||||||
|
|
||||||
<!-- ✅ Sperren / Entsperren -->
|
<% } else { %>
|
||||||
<div id="sbActiveWrapper">
|
<div class="nav-item locked" style="opacity:0.7;">
|
||||||
<div class="nav-item disabled">
|
<i class="bi bi-door-open"></i> Ins Wartezimmer
|
||||||
<i class="bi bi-lock-fill"></i> Sperren / Entsperren
|
<span style="margin-left:auto;"><i class="bi bi-lock-fill"></i></span>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
<% } %>
|
||||||
|
|
||||||
|
<!-- =========================
|
||||||
|
BEARBEITEN
|
||||||
|
========================= -->
|
||||||
|
<a
|
||||||
|
href="<%= hrefIfAllowed(canUsePatient, '/patients/edit/' + pid) %>"
|
||||||
|
class="nav-item <%= active === 'patient_edit' ? 'active' : '' %> <%= lockClass(canUsePatient) %>"
|
||||||
|
title="<%= canUsePatient ? '' : 'Bitte zuerst einen Patienten auswählen' %>"
|
||||||
|
>
|
||||||
|
<i class="bi bi-pencil-square"></i> Bearbeiten
|
||||||
|
<% if (!canUsePatient) { %>
|
||||||
|
<span style="margin-left:auto;"><i class="bi bi-lock-fill"></i></span>
|
||||||
|
<% } %>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<!-- =========================
|
||||||
|
ÜBERSICHT (Dashboard)
|
||||||
|
========================= -->
|
||||||
|
<a
|
||||||
|
href="<%= hrefIfAllowed(canUsePatient, '/patients/' + pid) %>"
|
||||||
|
class="nav-item <%= active === 'patient_dashboard' ? 'active' : '' %> <%= lockClass(canUsePatient) %>"
|
||||||
|
title="<%= canUsePatient ? '' : 'Bitte zuerst einen Patienten auswählen' %>"
|
||||||
|
>
|
||||||
|
<i class="bi bi-clipboard2-heart"></i> Übersicht
|
||||||
|
<% if (!canUsePatient) { %>
|
||||||
|
<span style="margin-left:auto;"><i class="bi bi-lock-fill"></i></span>
|
||||||
|
<% } %>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<!-- =========================
|
||||||
|
STATUS TOGGLE
|
||||||
|
========================= -->
|
||||||
|
<form
|
||||||
|
method="POST"
|
||||||
|
action="<%= canUsePatient ? (isActive ? '/patients/deactivate/' + pid : '/patients/activate/' + pid) : '#' %>"
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
type="submit"
|
||||||
|
class="nav-item <%= lockClass(canUsePatient) %>"
|
||||||
|
style="width:100%; border:none; background:transparent; text-align:left;"
|
||||||
|
<%= canUsePatient ? '' : 'disabled' %>
|
||||||
|
title="<%= canUsePatient ? 'Status wechseln' : 'Bitte zuerst einen Patienten auswählen' %>"
|
||||||
|
>
|
||||||
|
<% if (isActive) { %>
|
||||||
|
<i class="bi bi-x-circle"></i> Patient sperren (Inaktiv)
|
||||||
|
<% } else { %>
|
||||||
|
<i class="bi bi-check-circle"></i> Patient aktivieren
|
||||||
|
<% } %>
|
||||||
|
|
||||||
|
<% if (!canUsePatient) { %>
|
||||||
|
<span style="margin-left:auto;"><i class="bi bi-lock-fill"></i></span>
|
||||||
|
<% } %>
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
<!-- ✅ Upload -->
|
<!-- ✅ Upload -->
|
||||||
<div class="sidebar-upload">
|
<div class="sidebar-upload <%= lockClass(canUsePatient) %>">
|
||||||
|
|
||||||
<div style="font-weight: 600; margin: 10px 0 6px 0; color: #e5e7eb">
|
<div style="font-weight: 600; margin: 10px 0 6px 0; color: #e5e7eb">
|
||||||
<i class="bi bi-paperclip"></i> Datei Upload
|
<i class="bi bi-paperclip"></i> Datei Upload
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<% if (canUsePatient) { %>
|
||||||
<form
|
<form
|
||||||
id="sbUploadForm"
|
action="/patients/<%= pid %>/files"
|
||||||
method="POST"
|
method="POST"
|
||||||
action="#"
|
|
||||||
enctype="multipart/form-data"
|
enctype="multipart/form-data"
|
||||||
>
|
>
|
||||||
|
<% } %>
|
||||||
|
|
||||||
<input
|
<input
|
||||||
id="sbUploadInput"
|
id="sbUploadInput"
|
||||||
type="file"
|
type="file"
|
||||||
name="file"
|
name="file"
|
||||||
class="form-control form-control-sm mb-2"
|
class="form-control form-control-sm mb-2"
|
||||||
disabled
|
<%= canUsePatient ? "" : "disabled" %>
|
||||||
required
|
required
|
||||||
/>
|
/>
|
||||||
|
|
||||||
@ -73,105 +159,23 @@
|
|||||||
id="sbUploadBtn"
|
id="sbUploadBtn"
|
||||||
type="submit"
|
type="submit"
|
||||||
class="btn btn-sm btn-outline-light w-100"
|
class="btn btn-sm btn-outline-light w-100"
|
||||||
disabled
|
<%= canUsePatient ? "" : "disabled" %>
|
||||||
>
|
>
|
||||||
📎 Hochladen
|
📎 Hochladen
|
||||||
|
<% if (!canUsePatient) { %>
|
||||||
|
<span class="ms-2"><i class="bi bi-lock-fill"></i></span>
|
||||||
|
<% } %>
|
||||||
</button>
|
</button>
|
||||||
</form>
|
|
||||||
|
|
||||||
<div class="sidebar-muted" style="margin-top: 6px">
|
<div class="sidebar-muted" style="margin-top: 6px">
|
||||||
Nur aktiv nach Patientenauswahl
|
Nur aktiv nach Patientenauswahl
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
<% if (canUsePatient) { %>
|
||||||
|
</form>
|
||||||
|
<% } %>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="spacer"></div>
|
<div class="spacer"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<style>
|
|
||||||
.sidebar {
|
|
||||||
width: 240px;
|
|
||||||
background: #111827;
|
|
||||||
color: white;
|
|
||||||
padding: 20px;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
min-height: 100vh;
|
|
||||||
}
|
|
||||||
|
|
||||||
.logo {
|
|
||||||
font-size: 18px;
|
|
||||||
font-weight: 700;
|
|
||||||
margin-bottom: 18px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.patient-badge {
|
|
||||||
background: rgba(255, 255, 255, 0.06);
|
|
||||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
|
||||||
border-radius: 12px;
|
|
||||||
padding: 12px;
|
|
||||||
margin-bottom: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.patient-name {
|
|
||||||
font-size: 14px;
|
|
||||||
margin-bottom: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.patient-meta {
|
|
||||||
font-size: 12px;
|
|
||||||
opacity: 0.85;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-item {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 12px;
|
|
||||||
padding: 12px 15px;
|
|
||||||
border-radius: 8px;
|
|
||||||
color: #cbd5e1;
|
|
||||||
text-decoration: none;
|
|
||||||
margin-bottom: 6px;
|
|
||||||
font-size: 14px;
|
|
||||||
border: 0;
|
|
||||||
background: transparent;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-item:hover {
|
|
||||||
background: #1f2937;
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-item.active {
|
|
||||||
background: #2563eb;
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-item.disabled {
|
|
||||||
opacity: 0.45;
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-btn {
|
|
||||||
cursor: pointer;
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidebar-upload {
|
|
||||||
margin-top: 10px;
|
|
||||||
padding-top: 10px;
|
|
||||||
border-top: 1px solid rgba(255, 255, 255, 0.12);
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidebar-muted {
|
|
||||||
font-size: 12px;
|
|
||||||
opacity: 0.75;
|
|
||||||
}
|
|
||||||
|
|
||||||
.spacer {
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|||||||
@ -1,5 +1,20 @@
|
|||||||
<div class="sidebar sidebar-empty">
|
<div class="sidebar-empty">
|
||||||
|
<!-- ✅ Logo -->
|
||||||
|
<div
|
||||||
|
style="
|
||||||
|
margin-bottom: 30px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 10px;
|
||||||
|
"
|
||||||
|
>
|
||||||
<div style="padding: 20px; text-align: center">
|
<div style="padding: 20px; text-align: center">
|
||||||
<div class="logo" style="margin: 0">🩺 Praxis System</div>
|
<div class="logo" style="margin: 0">🩺 Praxis System</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- ✅ Zurück -->
|
||||||
|
<a href="<%= backUrl || '/patients' %>" class="nav-item">
|
||||||
|
<i class="bi bi-arrow-left-circle"></i> Zurück
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
144
views/partials/sidebar-invoices.ejs
Normal file
144
views/partials/sidebar-invoices.ejs
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
<%
|
||||||
|
// =========================
|
||||||
|
// BASISDATEN
|
||||||
|
// =========================
|
||||||
|
const role = user?.role || null;
|
||||||
|
|
||||||
|
// Arzt + Mitarbeiter dürfen Patienten bedienen
|
||||||
|
const canPatientArea = role === "arzt" || role === "mitarbeiter";
|
||||||
|
|
||||||
|
const pid = patient && patient.id ? patient.id : null;
|
||||||
|
const isActive = patient && patient.active ? true : false;
|
||||||
|
const isWaiting = patient && patient.waiting_room ? true : false;
|
||||||
|
|
||||||
|
const canUsePatient = canPatientArea && !!pid;
|
||||||
|
|
||||||
|
function lockClass(allowed) {
|
||||||
|
return allowed ? "" : "locked";
|
||||||
|
}
|
||||||
|
|
||||||
|
function hrefIfAllowed(allowed, href) {
|
||||||
|
return allowed ? href : "#";
|
||||||
|
}
|
||||||
|
%>
|
||||||
|
|
||||||
|
<div class="sidebar">
|
||||||
|
|
||||||
|
<!-- ✅ Logo -->
|
||||||
|
<div style="margin-bottom:30px; display:flex; flex-direction:column; gap:10px;">
|
||||||
|
<div style="padding:20px; text-align:center;">
|
||||||
|
<div class="logo" style="margin:0;">🩺 Praxis System</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- ✅ Zurück -->
|
||||||
|
<a href="<%= backUrl || '/patients' %>" class="nav-item">
|
||||||
|
<i class="bi bi-arrow-left-circle"></i> Zurück
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<div style="margin:10px 0; border-top:1px solid rgba(255,255,255,0.12);"></div>
|
||||||
|
|
||||||
|
<!-- ✅ Kein Patient gewählt -->
|
||||||
|
<% if (!pid) { %>
|
||||||
|
<div class="nav-item locked" style="opacity:0.7;">
|
||||||
|
<i class="bi bi-info-circle"></i> Bitte Patient auswählen
|
||||||
|
<span style="margin-left:auto;"><i class="bi bi-lock-fill"></i></span>
|
||||||
|
</div>
|
||||||
|
<% } %>
|
||||||
|
|
||||||
|
<!-- =========================
|
||||||
|
Rechnungen
|
||||||
|
========================= -->
|
||||||
|
<a
|
||||||
|
href="<%= hrefIfAllowed(canDoctorAndStaff, '/patients') %>"
|
||||||
|
class="nav-item <%= active === 'patients' ? 'active' : '' %> <%= lockClass(canDoctorAndStaff) %>"
|
||||||
|
title="<%= canDoctorAndStaff ? '' : 'Nur Arzt + Mitarbeiter' %>"
|
||||||
|
>
|
||||||
|
<i class="bi bi-people"></i> <%= t.sidebar.patients %>
|
||||||
|
<% if (!canDoctorAndStaff) { %>
|
||||||
|
<span style="margin-left:auto;"><i class="bi bi-lock-fill"></i></span>
|
||||||
|
<% } %>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<a
|
||||||
|
href="<%= hrefIfAllowed(canDoctorAndStaff, '/patients') %>"
|
||||||
|
class="nav-item <%= active === 'patients' ? 'active' : '' %> <%= lockClass(canDoctorAndStaff) %>"
|
||||||
|
title="<%= canDoctorAndStaff ? '' : 'Nur Arzt + Mitarbeiter' %>"
|
||||||
|
>
|
||||||
|
<i class="bi bi-people"></i> <%= t.sidebar.patients %>
|
||||||
|
<% if (!canDoctorAndStaff) { %>
|
||||||
|
<span style="margin-left:auto;"><i class="bi bi-lock-fill"></i></span>
|
||||||
|
<% } %>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<a
|
||||||
|
href="<%= hrefIfAllowed(canDoctorAndStaff, '/patients') %>"
|
||||||
|
class="nav-item <%= active === 'patients' ? 'active' : '' %> <%= lockClass(canDoctorAndStaff) %>"
|
||||||
|
title="<%= canDoctorAndStaff ? '' : 'Nur Arzt + Mitarbeiter' %>"
|
||||||
|
>
|
||||||
|
<i class="bi bi-people"></i> <%= t.sidebar.patients %>
|
||||||
|
<% if (!canDoctorAndStaff) { %>
|
||||||
|
<span style="margin-left:auto;"><i class="bi bi-lock-fill"></i></span>
|
||||||
|
<% } %>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<a
|
||||||
|
href="<%= hrefIfAllowed(canDoctorAndStaff, '/patients') %>"
|
||||||
|
class="nav-item <%= active === 'patients' ? 'active' : '' %> <%= lockClass(canDoctorAndStaff) %>"
|
||||||
|
title="<%= canDoctorAndStaff ? '' : 'Nur Arzt + Mitarbeiter' %>"
|
||||||
|
>
|
||||||
|
<i class="bi bi-people"></i> <%= t.sidebar.patients %>
|
||||||
|
<% if (!canDoctorAndStaff) { %>
|
||||||
|
<span style="margin-left:auto;"><i class="bi bi-lock-fill"></i></span>
|
||||||
|
<% } %>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- =========================
|
||||||
|
ÜBERSICHT (Dashboard)
|
||||||
|
========================= -->
|
||||||
|
<a
|
||||||
|
href="<%= hrefIfAllowed(canUsePatient, '/patients/' + pid) %>"
|
||||||
|
class="nav-item <%= active === 'patient_dashboard' ? 'active' : '' %> <%= lockClass(canUsePatient) %>"
|
||||||
|
title="<%= canUsePatient ? '' : 'Bitte zuerst einen Patienten auswählen' %>"
|
||||||
|
>
|
||||||
|
<i class="bi bi-clipboard2-heart"></i> Übersicht
|
||||||
|
<% if (!canUsePatient) { %>
|
||||||
|
<span style="margin-left:auto;"><i class="bi bi-lock-fill"></i></span>
|
||||||
|
<% } %>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<!-- =========================
|
||||||
|
STATUS TOGGLE
|
||||||
|
========================= -->
|
||||||
|
<form
|
||||||
|
method="POST"
|
||||||
|
action="<%= canUsePatient ? (isActive ? '/patients/deactivate/' + pid : '/patients/activate/' + pid) : '#' %>"
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
type="submit"
|
||||||
|
class="nav-item <%= lockClass(canUsePatient) %>"
|
||||||
|
style="width:100%; border:none; background:transparent; text-align:left;"
|
||||||
|
<%= canUsePatient ? '' : 'disabled' %>
|
||||||
|
title="<%= canUsePatient ? 'Status wechseln' : 'Bitte zuerst einen Patienten auswählen' %>"
|
||||||
|
>
|
||||||
|
<% if (isActive) { %>
|
||||||
|
<i class="bi bi-x-circle"></i> Patient sperren (Inaktiv)
|
||||||
|
<% } else { %>
|
||||||
|
<i class="bi bi-check-circle"></i> Patient aktivieren
|
||||||
|
<% } %>
|
||||||
|
|
||||||
|
<% if (!canUsePatient) { %>
|
||||||
|
<span style="margin-left:auto;"><i class="bi bi-lock-fill"></i></span>
|
||||||
|
<% } %>
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<div class="spacer"></div>
|
||||||
|
|
||||||
|
<!-- ✅ Logout -->
|
||||||
|
<a href="/logout" class="nav-item">
|
||||||
|
<i class="bi bi-box-arrow-right"></i> Logout
|
||||||
|
</a>
|
||||||
|
|
||||||
|
</div>
|
||||||
@ -12,7 +12,7 @@
|
|||||||
<!-- Aktionen oben -->
|
<!-- Aktionen oben -->
|
||||||
<div class="d-flex gap-2 mb-3">
|
<div class="d-flex gap-2 mb-3">
|
||||||
<a href="/patients/create" class="btn btn-success">
|
<a href="/patients/create" class="btn btn-success">
|
||||||
+ <%=t.patienteoverview.newpatient%>
|
+ <%= t.patienteoverview.newpatient %>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -26,7 +26,7 @@
|
|||||||
type="text"
|
type="text"
|
||||||
name="firstname"
|
name="firstname"
|
||||||
class="form-control"
|
class="form-control"
|
||||||
placeholder=<%=t.global.firstname%>
|
placeholder="<%= t.global.firstname %>"
|
||||||
value="<%= query?.firstname || '' %>"
|
value="<%= query?.firstname || '' %>"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@ -36,7 +36,7 @@
|
|||||||
type="text"
|
type="text"
|
||||||
name="lastname"
|
name="lastname"
|
||||||
class="form-control"
|
class="form-control"
|
||||||
placeholder=<%=t.global.lastname%>
|
placeholder="<%= t.global.lastname %>"
|
||||||
value="<%= query?.lastname || '' %>"
|
value="<%= query?.lastname || '' %>"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@ -51,33 +51,40 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-md-3 d-flex gap-2">
|
<div class="col-md-3 d-flex gap-2">
|
||||||
<button class="btn btn-primary w-100"><%=t.global.search%></button>
|
<button class="btn btn-primary w-100"><%= t.global.search %></button>
|
||||||
<a href="/patients" class="btn btn-secondary w-100">
|
<a href="/patients" class="btn btn-secondary w-100">
|
||||||
<%=t.global.reset2%>
|
<%= t.global.reset2 %>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<!-- Tabelle -->
|
<!-- ✅ EINE Form für ALLE Radiobuttons -->
|
||||||
|
<form method="GET" action="/patients">
|
||||||
|
|
||||||
|
<!-- Filter beibehalten -->
|
||||||
|
<input type="hidden" name="firstname" value="<%= query?.firstname || '' %>">
|
||||||
|
<input type="hidden" name="lastname" value="<%= query?.lastname || '' %>">
|
||||||
|
<input type="hidden" name="birthdate" value="<%= query?.birthdate || '' %>">
|
||||||
|
|
||||||
<div class="table-responsive">
|
<div class="table-responsive">
|
||||||
<table class="table table-bordered table-hover align-middle table-sm">
|
<table class="table table-bordered table-hover align-middle table-sm">
|
||||||
|
|
||||||
<thead class="table-dark">
|
<thead class="table-dark">
|
||||||
<tr>
|
<tr>
|
||||||
<th style="width:40px;"></th>
|
<th style="width:40px;"></th>
|
||||||
<th>ID</th>
|
<th>ID</th>
|
||||||
<th><%=t.global.name%></th>
|
<th><%= t.global.name %></th>
|
||||||
<th>N.I.E. / DNI</th>
|
<th>DNI</th>
|
||||||
<th><%=t.global.gender%></th>
|
<th><%= t.global.gender %></th>
|
||||||
<th><%=t.global.birthday%></th>
|
<th><%= t.global.birthday %></th>
|
||||||
<th><%=t.global.email%></th>
|
<th><%= t.global.email %></th>
|
||||||
<th><%=t.global.phone%></th>
|
<th><%= t.global.phone %></th>
|
||||||
<th><%=t.global.address%></th>
|
<th><%= t.global.address %></th>
|
||||||
<th><%=t.global.country%></th>
|
<th><%= t.global.country %></th>
|
||||||
<th><%=t.global.status%></th>
|
<th><%= t.global.status %></th>
|
||||||
<th><%=t.global.notice%></th>
|
<th><%= t.global.notice %></th>
|
||||||
<th><%=t.global.create%></th>
|
<th><%= t.global.create %></th>
|
||||||
<th><%=t.global.change%></th>
|
<th><%= t.global.change %></th>
|
||||||
<th><%=t.global.action%></th>
|
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
|
|
||||||
@ -85,7 +92,7 @@
|
|||||||
<% if (patients.length === 0) { %>
|
<% if (patients.length === 0) { %>
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="15" class="text-center text-muted">
|
<td colspan="15" class="text-center text-muted">
|
||||||
<%=t.patientoverview.nopatientfound%>
|
<%= t.patientoverview.nopatientfound %>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<% } %>
|
<% } %>
|
||||||
@ -93,23 +100,16 @@
|
|||||||
<% patients.forEach(p => { %>
|
<% patients.forEach(p => { %>
|
||||||
<tr>
|
<tr>
|
||||||
|
|
||||||
<!-- ✅ RADIOBUTTON ganz vorne -->
|
<!-- ✅ EIN Radiobutton – korrekt gruppiert -->
|
||||||
<td class="text-center">
|
<td class="text-center">
|
||||||
<form method="GET" action="/patients">
|
|
||||||
<!-- Filter beibehalten -->
|
|
||||||
<input type="hidden" name="firstname" value="<%= query.firstname || '' %>">
|
|
||||||
<input type="hidden" name="lastname" value="<%= query.lastname || '' %>">
|
|
||||||
<input type="hidden" name="birthdate" value="<%= query.birthdate || '' %>">
|
|
||||||
|
|
||||||
<input
|
<input
|
||||||
class="patient-radio"
|
class="patient-radio"
|
||||||
type="radio"
|
type="radio"
|
||||||
name="selectedPatientId"
|
name="selectedPatientId"
|
||||||
value="<%= p.id %>"
|
value="<%= p.id %>"
|
||||||
<%= selectedPatientId === p.id ? "checked" : "" %>
|
<%= selectedPatientId === p.id ? "checked" : "" %>
|
||||||
|
onchange="this.form.submit()"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
</form>
|
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<td><%= p.id %></td>
|
<td><%= p.id %></td>
|
||||||
@ -118,26 +118,17 @@
|
|||||||
<td><%= p.dni || "-" %></td>
|
<td><%= p.dni || "-" %></td>
|
||||||
|
|
||||||
<td>
|
<td>
|
||||||
<% if (p.gender === 'm') { %>
|
<%= p.gender === 'm' ? 'm' :
|
||||||
m
|
p.gender === 'w' ? 'w' :
|
||||||
<% } else if (p.gender === 'w') { %>
|
p.gender === 'd' ? 'd' : '-' %>
|
||||||
w
|
|
||||||
<% } else if (p.gender === 'd') { %>
|
|
||||||
d
|
|
||||||
<% } else { %>
|
|
||||||
-
|
|
||||||
<% } %>
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td>
|
|
||||||
<%= new Date(p.birthdate).toLocaleDateString("de-DE") %>
|
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
|
<td><%= new Date(p.birthdate).toLocaleDateString("de-DE") %></td>
|
||||||
<td><%= p.email || "-" %></td>
|
<td><%= p.email || "-" %></td>
|
||||||
<td><%= p.phone || "-" %></td>
|
<td><%= p.phone || "-" %></td>
|
||||||
|
|
||||||
<td>
|
<td>
|
||||||
<%= p.street || "" %> <%= p.house_number || "" %><br />
|
<%= p.street || "" %> <%= p.house_number || "" %><br>
|
||||||
<%= p.postal_code || "" %> <%= p.city || "" %>
|
<%= p.postal_code || "" %> <%= p.city || "" %>
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
@ -151,84 +142,9 @@
|
|||||||
<% } %>
|
<% } %>
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<td style="max-width: 200px">
|
<td><%= p.notes ? p.notes.substring(0, 80) : "-" %></td>
|
||||||
<%= p.notes ? p.notes.substring(0, 80) : "-" %>
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td><%= new Date(p.created_at).toLocaleString("de-DE") %></td>
|
<td><%= new Date(p.created_at).toLocaleString("de-DE") %></td>
|
||||||
<td><%= new Date(p.updated_at).toLocaleString("de-DE") %></td>
|
<td><%= new Date(p.updated_at).toLocaleString("de-DE") %></td>
|
||||||
|
|
||||||
<td class="text-nowrap">
|
|
||||||
<div class="dropdown">
|
|
||||||
<button class="btn btn-sm btn-outline-secondary" data-bs-toggle="dropdown">
|
|
||||||
<%=t.global.selection%> ▾
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<ul class="dropdown-menu dropdown-menu-end">
|
|
||||||
|
|
||||||
<li>
|
|
||||||
<a class="dropdown-item" href="/patients/edit/<%= p.id %>">
|
|
||||||
✏️ <%=t.global.edit%>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li><hr class="dropdown-divider" /></li>
|
|
||||||
|
|
||||||
<% if (p.waiting_room) { %>
|
|
||||||
<li>
|
|
||||||
<span class="dropdown-item text-muted">🪑 <%=t.global.waiting%></span>
|
|
||||||
</li>
|
|
||||||
<% } else { %>
|
|
||||||
<li>
|
|
||||||
<form method="POST" action="/patients/waiting-room/<%= p.id %>">
|
|
||||||
<button class="dropdown-item">🪑 <%=t.global.towaitingroom%></button>
|
|
||||||
</form>
|
|
||||||
</li>
|
|
||||||
<% } %>
|
|
||||||
|
|
||||||
<li><hr class="dropdown-divider" /></li>
|
|
||||||
|
|
||||||
<li>
|
|
||||||
<a class="dropdown-item" href="/patients/<%= p.id %>/medications">
|
|
||||||
💊 <%=t.sidebar.medications%>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li><hr class="dropdown-divider" /></li>
|
|
||||||
|
|
||||||
<li>
|
|
||||||
<% if (p.active) { %>
|
|
||||||
<form method="POST" action="/patients/deactivate/<%= p.id %>">
|
|
||||||
<button class="dropdown-item text-warning">🔒 <%=t.global.lock%><</button>
|
|
||||||
</form>
|
|
||||||
<% } else { %>
|
|
||||||
<form method="POST" action="/patients/activate/<%= p.id %>">
|
|
||||||
<button class="dropdown-item text-success">🔓 <%=t.global.unlock%><</button>
|
|
||||||
</form>
|
|
||||||
<% } %>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li>
|
|
||||||
<a class="dropdown-item" href="/patients/<%= p.id %>">
|
|
||||||
📋 <%=t.global.overview%>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li><hr class="dropdown-divider" /></li>
|
|
||||||
|
|
||||||
<li class="px-3 py-2">
|
|
||||||
<form method="POST" action="/patients/<%= p.id %>/files" enctype="multipart/form-data">
|
|
||||||
<input type="file" name="file" class="form-control form-control-sm mb-2" required />
|
|
||||||
<button class="btn btn-sm btn-secondary w-100">
|
|
||||||
📎 <%=t.global.upload%>
|
|
||||||
</button>
|
|
||||||
</form>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
|
|
||||||
</tr>
|
</tr>
|
||||||
<% }) %>
|
<% }) %>
|
||||||
</tbody>
|
</tbody>
|
||||||
@ -236,7 +152,7 @@
|
|||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,35 +1,13 @@
|
|||||||
<!DOCTYPE html>
|
<%- include("partials/page-header", {
|
||||||
<html lang="de">
|
user,
|
||||||
<head>
|
title: t.patienteoverview.patienttitle,
|
||||||
<meta charset="UTF-8">
|
subtitle: "",
|
||||||
<title>Leistungen</title>
|
showUserName: true
|
||||||
<link rel="stylesheet" href="/css/bootstrap.min.css">
|
}) %>
|
||||||
<script src="/js/services-lock.js"></script> ✔ erlaubt
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
|
|
||||||
<!-- NAVBAR -->
|
|
||||||
<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.3rem;">🧾</span>
|
|
||||||
<span class="fw-semibold fs-5">Leistungen</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- DASHBOARD -->
|
|
||||||
<div class="ms-auto">
|
|
||||||
<a href="/dashboard" class="btn btn-outline-light btn-sm">
|
|
||||||
⬅️ Dashboard
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</nav>
|
|
||||||
|
|
||||||
<!-- CONTENT -->
|
<!-- CONTENT -->
|
||||||
<div class="container mt-4">
|
<div class="container mt-4">
|
||||||
|
<%- include("partials/flash") %>
|
||||||
<h4>Leistungen</h4>
|
<h4>Leistungen</h4>
|
||||||
|
|
||||||
<!-- SUCHFORMULAR -->
|
<!-- SUCHFORMULAR -->
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user