Upload der Dateien bei den Patienten klappt nun wieder.

This commit is contained in:
Cay 2026-02-02 16:45:55 +00:00
parent 65bb75d437
commit fbe1b34b25
10 changed files with 558 additions and 500 deletions

View File

@ -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,

View File

@ -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,

View File

@ -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;

View File

@ -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>

View File

@ -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>

View File

@ -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>

View 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>

View File

@ -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>

View File

@ -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 -->