Aenderungen der Dashboard Icons

This commit is contained in:
Cay 2026-01-06 18:56:37 +00:00
parent 851250a734
commit 7ab67a839b
23 changed files with 2660 additions and 181 deletions

1
app.js
View File

@ -77,6 +77,7 @@ app.use("/", patientFileRoutes);
app.use("/medications", medicationRoutes); app.use("/medications", medicationRoutes);
app.use("/patients", patientMedicationRoutes); app.use("/patients", patientMedicationRoutes);
// =============================== // ===============================
// PATIENT INS WARTEZIMMER // PATIENT INS WARTEZIMMER
// =============================== // ===============================

View File

@ -22,13 +22,19 @@ async function createInvoicePdf(req, res) {
const [rows] = await db.promise().query(` const [rows] = await db.promise().query(`
SELECT SELECT
ps.quantity, ps.quantity,
s.name, COALESCE(ps.price_override, s.price) AS price,
COALESCE(ps.price_override, s.price) AS price
CASE
WHEN UPPER(TRIM(?)) = 'ES'
THEN COALESCE(NULLIF(s.name_es, ''), s.name_de)
ELSE s.name_de
END AS name
FROM patient_services ps FROM patient_services ps
JOIN services s ON ps.service_id = s.id JOIN services s ON ps.service_id = s.id
WHERE ps.patient_id = ? WHERE ps.patient_id = ?
AND ps.invoice_id IS NULL AND ps.invoice_id IS NULL
`, [patientId]); `, [patient.country, patientId]);
if (rows.length === 0) { if (rows.length === 0) {
return res.send("Keine Leistungen vorhanden"); return res.send("Keine Leistungen vorhanden");
@ -36,7 +42,7 @@ async function createInvoicePdf(req, res) {
const services = rows.map(s => ({ const services = rows.map(s => ({
quantity: Number(s.quantity), quantity: Number(s.quantity),
name_de: s.name, name: s.name,
price: Number(s.price), price: Number(s.price),
total: Number(s.price) * Number(s.quantity) total: Number(s.price) * Number(s.quantity)
})); }));

View File

@ -1,8 +1,10 @@
const db = require("../db"); const db = require("../db");
function listMedications(req, res) { // 📋 LISTE
function listMedications(req, res, next) {
const sql = ` const sql = `
SELECT SELECT
v.id,
m.name AS medication, m.name AS medication,
f.name AS form, f.name AS form,
v.dosage, v.dosage,
@ -14,9 +16,38 @@ function listMedications(req, res) {
`; `;
db.query(sql, (err, rows) => { db.query(sql, (err, rows) => {
if (err) return res.send("Datenbankfehler"); if (err) return next(err);
res.render("medications", { rows });
res.render("medications", {
rows,
user: req.session.user
});
}); });
} }
module.exports = { listMedications }; // 💾 UPDATE
function updateMedication(req, res, next) {
const { medication, form, dosage, package: pkg } = req.body;
const id = req.params.id;
const sql = `
UPDATE medication_variants
SET
dosage = ?,
package = ?
WHERE id = ?
`;
db.query(sql, [dosage, pkg, id], err => {
if (err) return next(err);
req.session.flash = { type: "success", message: "Medikament gespeichert"};
res.redirect("/medications");
});
}
module.exports = {
listMedications,
updateMedication
};

View File

@ -60,6 +60,50 @@ function listServices(req, res) {
} }
} }
function listServicesAdmin(req, res) {
const { q, onlyActive } = req.query;
let sql = `
SELECT
id,
name_de,
name_es,
category,
price,
price_c70,
active
FROM services
WHERE 1=1
`;
const params = [];
if (q) {
sql += `
AND (
name_de LIKE ?
OR name_es LIKE ?
OR category LIKE ?
)
`;
params.push(`%${q}%`, `%${q}%`, `%${q}%`);
}
if (onlyActive === "1") {
sql += " AND active = 1";
}
sql += " ORDER BY name_de";
db.query(sql, params, (err, services) => {
if (err) return res.send("Datenbankfehler");
res.render("services", {
services,
user: req.session.user,
query: { q, onlyActive }
});
});
}
function showCreateService(req, res) { function showCreateService(req, res) {
res.render("service_create", { res.render("service_create", {
@ -184,15 +228,26 @@ function listOpenServices(req, res, next) {
p.id AS patient_id, p.id AS patient_id,
p.firstname, p.firstname,
p.lastname, p.lastname,
p.country,
ps.id AS patient_service_id, ps.id AS patient_service_id,
ps.quantity, ps.quantity,
COALESCE(ps.price_override, s.price) AS price, COALESCE(ps.price_override, s.price) AS price,
s.name
-- 🌍 Sprachabhängiger Servicename
CASE
WHEN UPPER(TRIM(p.country)) = 'ES'
THEN COALESCE(NULLIF(s.name_es, ''), s.name_de)
ELSE s.name_de
END AS name
FROM patient_services ps FROM patient_services ps
JOIN patients p ON ps.patient_id = p.id JOIN patients p ON ps.patient_id = p.id
JOIN services s ON ps.service_id = s.id JOIN services s ON ps.service_id = s.id
WHERE ps.invoice_id IS NULL WHERE ps.invoice_id IS NULL
ORDER BY p.lastname, p.firstname ORDER BY
p.lastname,
p.firstname,
name
`; `;
db.query(sql, (err, rows) => { db.query(sql, (err, rows) => {
@ -206,6 +261,7 @@ function listOpenServices(req, res, next) {
} }
function showServiceLogs(req, res) { function showServiceLogs(req, res) {
db.query( db.query(
` `
@ -238,5 +294,6 @@ module.exports = {
updateServicePrice, updateServicePrice,
toggleService, toggleService,
listOpenServices, listOpenServices,
showServiceLogs showServiceLogs,
listServicesAdmin
}; };

17
package-lock.json generated
View File

@ -10,6 +10,7 @@
"dependencies": { "dependencies": {
"bcrypt": "^6.0.0", "bcrypt": "^6.0.0",
"bootstrap": "^5.3.8", "bootstrap": "^5.3.8",
"bootstrap-icons": "^1.13.1",
"docxtemplater": "^3.67.6", "docxtemplater": "^3.67.6",
"dotenv": "^17.2.3", "dotenv": "^17.2.3",
"ejs": "^3.1.10", "ejs": "^3.1.10",
@ -1951,6 +1952,22 @@
"@popperjs/core": "^2.11.8" "@popperjs/core": "^2.11.8"
} }
}, },
"node_modules/bootstrap-icons": {
"version": "1.13.1",
"resolved": "https://registry.npmjs.org/bootstrap-icons/-/bootstrap-icons-1.13.1.tgz",
"integrity": "sha512-ijombt4v6bv5CLeXvRWKy7CuM3TRTuPEuGaGKvTV5cz65rQSY8RQ2JcHt6b90cBBAC7s8fsf2EkQDldzCoXUjw==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/twbs"
},
{
"type": "opencollective",
"url": "https://opencollective.com/bootstrap"
}
],
"license": "MIT"
},
"node_modules/brace-expansion": { "node_modules/brace-expansion": {
"version": "2.0.2", "version": "2.0.2",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",

View File

@ -14,6 +14,7 @@
"dependencies": { "dependencies": {
"bcrypt": "^6.0.0", "bcrypt": "^6.0.0",
"bootstrap": "^5.3.8", "bootstrap": "^5.3.8",
"bootstrap-icons": "^1.13.1",
"docxtemplater": "^3.67.6", "docxtemplater": "^3.67.6",
"dotenv": "^17.2.3", "dotenv": "^17.2.3",
"ejs": "^3.1.10", "ejs": "^3.1.10",

2106
public/bootstrap-icons/bootstrap-icons.css vendored Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

Binary file not shown.

Binary file not shown.

7
public/js/bootstrap.bundle.min.js vendored Normal file

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,28 @@
document.addEventListener("DOMContentLoaded", () => {
document.querySelectorAll(".lock-btn").forEach(btn => {
btn.addEventListener("click", () => {
const row = btn.closest("tr");
// Alle Zeilen sperren
document.querySelectorAll("tr").forEach(r => {
r.querySelectorAll("input").forEach(i => i.disabled = true);
const save = r.querySelector(".save-btn");
if (save) save.disabled = true;
});
// Aktuelle Zeile entsperren
row.querySelectorAll("input").forEach(i => i.disabled = false);
row.querySelector(".save-btn").disabled = false;
// Button ändern
btn.textContent = "🔒";
btn.title = "Bearbeitung gesperrt";
// Fokus
const firstInput = row.querySelector("input");
if (firstInput) firstInput.focus();
});
});
});

View File

@ -2,8 +2,14 @@ const express = require("express");
const router = express.Router(); const router = express.Router();
const { requireLogin } = require("../middleware/auth.middleware"); const { requireLogin } = require("../middleware/auth.middleware");
const { listMedications } = require("../controllers/medication.controller"); const {
listMedications,
updateMedication
} = require("../controllers/medication.controller");
router.get("/", requireLogin, listMedications); router.get("/", requireLogin, listMedications);
// 🆕 UPDATE pro Zeile
router.post("/update/:id", requireLogin, updateMedication);
module.exports = router; module.exports = router;

View File

@ -9,9 +9,11 @@ const {
updateServicePrice, updateServicePrice,
toggleService, toggleService,
listOpenServices, listOpenServices,
showServiceLogs showServiceLogs,
listServicesAdmin
} = require("../controllers/service.controller"); } = require("../controllers/service.controller");
router.get("/", requireLogin, listServicesAdmin);
router.get("/", requireAdmin, listServices); router.get("/", requireAdmin, listServices);
router.get("/create", requireAdmin, showCreateService); router.get("/create", requireAdmin, showCreateService);
router.post("/create", requireAdmin, createService); router.post("/create", requireAdmin, createService);

View File

@ -7,11 +7,25 @@
</head> </head>
<body> <body>
<nav class="navbar navbar-dark bg-dark px-3"> <nav class="navbar navbar-dark bg-dark position-relative px-3">
<span class="navbar-brand">📜 Service-Änderungsprotokoll</span>
<a href="/dashboard" class="btn btn-outline-light btn-sm">Dashboard</a> <!-- 🟢 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">Service-Änderungsprotokoll</span>
</div>
<!-- 🔵 RECHTS: DASHBOARD -->
<div class="ms-auto">
<a href="/dashboard" class="btn btn-outline-light btn-sm">
⬅️ Dashboard
</a>
</div>
</nav> </nav>
<div class="container mt-4"> <div class="container mt-4">
<table class="table table-sm table-bordered"> <table class="table table-sm table-bordered">

View File

@ -6,18 +6,30 @@
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Bootstrap 5 --> <!-- Bootstrap 5 -->
<link rel="stylesheet" href="/css/bootstrap.min.css"> <link rel="stylesheet" href="/css/bootstrap.min.css">
<link rel="stylesheet" href="/bootstrap-icons/bootstrap-icons.min.css">
</head> </head>
<body class="bg-light"> <body class="bg-light">
<!-- NAVBAR --> <!-- NAVBAR -->
<nav class="navbar navbar-dark bg-dark px-3"> <nav class="navbar navbar-dark bg-dark position-relative px-3">
<span class="navbar-brand">User Verwaltung</span>
<div> <!-- 🟢 ZENTRIERTER TITEL -->
<a href="/dashboard" class="btn btn-outline-light btn-sm me-2">Dashboard</a> <div class="position-absolute top-50 start-50 translate-middle
<a href="/logout" class="btn btn-outline-danger btn-sm">Logout</a> d-flex align-items-center gap-2 text-white">
<i class="bi bi-shield-lock fs-4"></i>
<span class="fw-semibold fs-5">User Verwaltung</span>
</div> </div>
<!-- 🔵 RECHTS: DASHBOARD -->
<div class="ms-auto">
<a href="/dashboard" class="btn btn-outline-primary btn-sm">
⬅️ Dashboard
</a>
</div>
</nav> </nav>
<!-- CONTENT --> <!-- CONTENT -->
<div class="container mt-4"> <div class="container mt-4">
<%- include("partials/flash") %> <%- include("partials/flash") %>

View File

@ -6,14 +6,30 @@
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="/css/bootstrap.min.css"> <link rel="stylesheet" href="/css/bootstrap.min.css">
<link rel="stylesheet" href="/css/style.css"> <link rel="stylesheet" href="/css/style.css">
<link rel="stylesheet" href="/bootstrap-icons/bootstrap-icons.min.css">
</head> </head>
<body class="bg-light"> <body class="bg-light">
<nav class="navbar navbar-dark bg-dark px-3"> <nav class="navbar navbar-dark bg-dark position-relative px-3">
<span class="navbar-brand">Dashboard</span>
<a href="/logout" class="btn btn-outline-light btn-sm">Logout</a> <!-- 🟢 ZENTRIERTER TITEL -->
<div class="position-absolute top-50 start-50 translate-middle
d-flex align-items-center gap-2 text-white">
<i class="bi bi-speedometer2 fs-4"></i>
<span class="fw-semibold fs-5">Dashboard</span>
</div>
<!-- 🔴 RECHTS: LOGOUT -->
<div class="ms-auto">
<a href="/logout" class="btn btn-outline-light btn-sm">
Logout
</a>
</div>
</nav> </nav>
<div class="container-fluid mt-4"> <div class="container-fluid mt-4">
<!-- Flash Messages --> <!-- Flash Messages -->

View File

@ -7,9 +7,22 @@
</head> </head>
<body class="bg-light"> <body class="bg-light">
<nav class="navbar navbar-dark bg-dark px-3"> <nav class="navbar navbar-dark bg-dark position-relative px-3">
<span class="navbar-brand">Medikamentenübersicht</span>
<a href="/dashboard" class="btn btn-outline-light btn-sm">Dashboard</a> <!-- 🟢 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">Medikamentenübersicht</span>
</div>
<!-- 🔵 RECHTS: DASHBOARD -->
<div class="ms-auto">
<a href="/dashboard" class="btn btn-outline-light btn-sm">
⬅️ Dashboard
</a>
</div>
</nav> </nav>
<div class="container mt-4"> <div class="container mt-4">
@ -30,13 +43,48 @@
<tbody> <tbody>
<% rows.forEach(r => { %> <% rows.forEach(r => { %>
<tr> <tr>
<td><%= r.medication %></td> <form method="POST"
<td><%= r.form %></td> action="/medications/update/<%= r.id %>">
<td><%= r.dosage %></td>
<td><%= r.package %></td> <td>
<input type="text"
name="medication"
value="<%= r.medication %>"
class="form-control form-control-sm"
required>
</td>
<td>
<input type="text"
name="form"
value="<%= r.form %>"
class="form-control form-control-sm">
</td>
<td>
<input type="text"
name="dosage"
value="<%= r.dosage %>"
class="form-control form-control-sm">
</td>
<td class="d-flex gap-2">
<input type="text"
name="package"
value="<%= r.package %>"
class="form-control form-control-sm">
<button class="btn btn-sm btn-outline-success"
type="submit">
💾
</button>
</td>
</form>
</tr> </tr>
<% }) %> <% }) %>
</tbody> </tbody>
</table> </table>
</div> </div>

View File

@ -8,7 +8,24 @@
<body> <body>
<div class="container mt-4"> <div class="container mt-4">
<h3>🧾 Offene Leistungen</h3> <div class="position-relative mb-3">
<!-- 🟢 ZENTRIERTER TITEL -->
<div class="position-absolute top-50 start-50 translate-middle
d-flex align-items-center gap-2">
<span style="font-size:1.4rem;">📄</span>
<h3 class="mb-0">Offene Rechnungen</h3>
</div>
<!-- 🔵 RECHTS: DASHBOARD -->
<div class="text-end">
<a href="/dashboard" class="btn btn-outline-primary btn-sm">
⬅️ Dashboard
</a>
</div>
</div>
<% let currentPatient = null; %> <% let currentPatient = null; %>
@ -39,7 +56,7 @@
<div class="border rounded p-2 mb-2 d-flex align-items-center gap-2"> <div class="border rounded p-2 mb-2 d-flex align-items-center gap-2">
<strong class="flex-grow-1"> <strong class="flex-grow-1">
<%= r.name_de %> <%= r.name %>
</strong> </strong>
<form method="POST" <form method="POST"

View File

@ -219,7 +219,7 @@
<hr> <hr>
<!-- Heutige Leistungen anzeigen alle--> <!-- Heutige Leistungen anzeigen-->
<% if (!todayServices || todayServices.length === 0) { %> <% if (!todayServices || todayServices.length === 0) { %>
<p class="text-muted"> <p class="text-muted">
Noch keine Leistungen für heute erfasst. Noch keine Leistungen für heute erfasst.

View File

@ -8,9 +8,22 @@
</head> </head>
<body class="bg-light"> <body class="bg-light">
<nav class="navbar navbar-dark bg-dark px-3"> <nav class="navbar navbar-dark bg-dark position-relative px-3">
<span class="navbar-brand">Patientenübersicht</span>
<a href="/dashboard" class="btn btn-outline-light btn-sm">Dashboard</a> <!-- 🟢 ZENTRIERTER TITEL -->
<div class="position-absolute top-50 start-50 translate-middle
d-flex align-items-center gap-2 text-white">
<span style="font-size: 1.4rem;">👥</span>
<span class="fw-semibold fs-5">Patientenübersicht</span>
</div>
<!-- 🔵 RECHTS: DASHBOARD -->
<div class="ms-auto">
<a href="/dashboard" class="btn btn-outline-primary btn-sm">
⬅️ Dashboard
</a>
</div>
</nav> </nav>
<div class="container-fluid mt-4"> <div class="container-fluid mt-4">
@ -136,77 +149,98 @@
<td><%= new Date(p.updated_at).toLocaleString("de-DE") %></td> <td><%= new Date(p.updated_at).toLocaleString("de-DE") %></td>
<!-- AKTIONEN --> <!-- AKTIONEN -->
<td> <td class="text-nowrap">
<!-- 🔘 OBERE AKTIONEN -->
<div class="d-flex flex-wrap gap-1 mb-2"> <div class="dropdown">
<button class="btn btn-sm btn-outline-secondary"
data-bs-toggle="dropdown">
Auswahl ▾
</button>
<ul class="dropdown-menu dropdown-menu-end position-fixed">
<!-- ✏️ BEARBEITEN -->
<li>
<a class="dropdown-item"
href="/patients/edit/<%= p.id %>">
✏️ Bearbeiten
</a>
</li>
<li><hr class="dropdown-divider"></li>
<!-- 🪑 WARTEZIMMER --> <!-- 🪑 WARTEZIMMER -->
<% if (p.waiting_room) { %> <% if (p.waiting_room) { %>
<button class="btn btn-sm btn-secondary" disabled> <li>
🪑 Wartet <span class="dropdown-item text-muted">
</button> 🪑 Wartet bereits
</span>
</li>
<% } else { %> <% } else { %>
<li>
<form method="POST" <form method="POST"
action="/patients/waiting-room/<%= p.id %>" action="/patients/waiting-room/<%= p.id %>">
class="d-inline"> <button class="dropdown-item">
<button class="btn btn-sm btn-outline-primary"> 🪑 Ins Wartezimmer
🪑 Wartezimmer
</button> </button>
</form> </form>
</li>
<% } %> <% } %>
<!-- ✏️ BEARBEITEN --> <li><hr class="dropdown-divider"></li>
<a href="/patients/edit/<%= p.id %>"
class="btn btn-sm btn-info">
✏️ Bearbeiten
</a>
<!-- 💊 MEDIKAMENTE --> <!-- 💊 MEDIKAMENTE -->
<a href="/patients/<%= p.id %>/medications" <li>
class="btn btn-sm btn-outline-primary"> <a class="dropdown-item"
href="/patients/<%= p.id %>/medications">
💊 Medikamente 💊 Medikamente
</a> </a>
</li>
<!-- 🔒 AKTIV / INAKTIV --> <li><hr class="dropdown-divider"></li>
<!-- 🔒 STATUS -->
<li>
<% if (p.active) { %> <% if (p.active) { %>
<form method="POST" <form method="POST"
action="/patients/deactivate/<%= p.id %>" action="/patients/deactivate/<%= p.id %>">
class="d-inline"> <button class="dropdown-item text-warning">
<button class="btn btn-sm btn-warning"> 🔒 Sperren
Sperren
</button> </button>
</form> </form>
<% } else { %> <% } else { %>
<form method="POST" <form method="POST"
action="/patients/activate/<%= p.id %>" action="/patients/activate/<%= p.id %>">
class="d-inline"> <button class="dropdown-item text-success">
<button class="btn btn-sm btn-danger"> 🔓 Entsperren
Entsperren
</button> </button>
</form> </form>
<% } %> <% } %>
</li>
<li><hr class="dropdown-divider"></li>
<!-- 📎 DATEI-UPLOAD -->
<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">
📎 Hochladen
</button>
</form>
</li>
</ul>
</div> </div>
<!-- 📎 DATEI-UPLOAD (UNTEN) -->
<form method="POST"
action="/patients/<%= p.id %>/files"
enctype="multipart/form-data"
class="d-flex gap-1">
<input type="file"
name="file"
required
class="form-control form-control-sm"
style="max-width:220px">
<button class="btn btn-sm btn-secondary">
📎 Datei hochladen
</button>
</form>
</td> </td>
</tr> </tr>
<% }) %> <% }) %>
@ -218,6 +252,6 @@
</div> </div>
</div> </div>
<script src="/js/bootstrap.bundle.min.js"></script>
</body> </body>
</html> </html>

View File

@ -4,18 +4,35 @@
<meta charset="UTF-8"> <meta charset="UTF-8">
<title>Leistungen</title> <title>Leistungen</title>
<link rel="stylesheet" href="/css/bootstrap.min.css"> <link rel="stylesheet" href="/css/bootstrap.min.css">
<script src="/js/services-lock.js"></script> ✔ erlaubt
</head> </head>
<body> <body>
<nav class="navbar navbar-dark bg-dark px-3"> <!-- NAVBAR -->
<span class="navbar-brand">🧾 Leistungen</span> <nav class="navbar navbar-dark bg-dark position-relative px-3">
<a href="/dashboard" class="btn btn-outline-light btn-sm">Dashboard</a>
<!-- 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> </nav>
<!-- CONTENT -->
<div class="container mt-4"> <div class="container mt-4">
<h4>Leistungen</h4> <h4>Leistungen</h4>
<!-- SUCHFORMULAR -->
<form method="GET" action="/services" class="row g-2 mb-3"> <form method="GET" action="/services" class="row g-2 mb-3">
<div class="col-md-6"> <div class="col-md-6">
@ -50,11 +67,24 @@
</form> </form>
<!-- NEUE LEISTUNG -->
<a href="/services/create" class="btn btn-success mb-3"> <a href="/services/create" class="btn btn-success mb-3">
Neue Leistung Neue Leistung
</a> </a>
<!-- TABELLE -->
<table class="table table-bordered table-sm align-middle"> <table class="table table-bordered table-sm align-middle">
<!-- FIXE SPALTENBREITEN -->
<colgroup>
<col style="width:35%">
<col style="width:25%">
<col style="width:10%">
<col style="width:10%">
<col style="width:8%">
<col style="width:12%">
</colgroup>
<thead class="table-light"> <thead class="table-light">
<tr> <tr>
<th>Bezeichnung (DE)</th> <th>Bezeichnung (DE)</th>
@ -65,44 +95,70 @@
<th>Aktionen</th> <th>Aktionen</th>
</tr> </tr>
</thead> </thead>
<tbody>
<tbody>
<% services.forEach(s => { %> <% services.forEach(s => { %>
<tr class="<%= s.active ? '' : 'table-secondary' %>"> <tr class="<%= s.active ? '' : 'table-secondary' %>">
<td><%= s.name %></td>
<!-- DE -->
<td><%= s.name_de %></td>
<!-- ES -->
<td><%= s.name_es || "-" %></td>
<!-- FORM BEGINNT -->
<form method="POST" action="/services/<%= s.id %>/update-price"> <form method="POST" action="/services/<%= s.id %>/update-price">
<!-- PREIS -->
<td> <td>
<input name="price" <input name="price"
value="<%= s.price %>" value="<%= s.price %>"
class="form-control form-control-sm"> class="form-control form-control-sm text-end w-100"
disabled>
</td> </td>
<!-- PREIS C70 -->
<td> <td>
<input name="price_c70" <input name="price_c70"
value="<%= s.price_c70 %>" value="<%= s.price_c70 %>"
class="form-control form-control-sm"> class="form-control form-control-sm text-end w-100"
disabled>
</td> </td>
<td>
<!-- STATUS -->
<td class="text-center">
<%= s.active ? 'Aktiv' : 'Inaktiv' %> <%= s.active ? 'Aktiv' : 'Inaktiv' %>
</td> </td>
<td class="d-flex gap-1">
<button class="btn btn-sm btn-primary"> <!-- AKTIONEN -->
💾 Speichern <td class="d-flex justify-content-center gap-2">
<!-- SPEICHERN -->
<button type="submit"
class="btn btn-sm btn-primary save-btn"
disabled>
💾
</button> </button>
<!-- SPERREN / ENTSPERREN -->
<button type="button"
class="btn btn-sm btn-outline-warning lock-btn"
title="Bearbeiten freigeben">
🔓
</button>
</td>
</form> </form>
<form method="POST" action="/services/<%= s.id %>/toggle">
<button class="btn btn-sm btn-outline-warning">
🔄 Aktiv/Inaktiv
</button>
</form>
</td>
</tr> </tr>
<% }) %> <% }) %>
</tbody> </tbody>
</table> </table>
</div> </div>
</body> </body>
</html> </html>

View File

@ -4,14 +4,29 @@
<meta charset="UTF-8"> <meta charset="UTF-8">
<title>Wartezimmer</title> <title>Wartezimmer</title>
<link rel="stylesheet" href="/css/bootstrap.min.css"> <link rel="stylesheet" href="/css/bootstrap.min.css">
<link rel="stylesheet" href="/bootstrap-icons/bootstrap-icons.min.css">
</head> </head>
<body> <body>
<nav class="navbar navbar-dark bg-dark px-3"> <nav class="navbar navbar-dark bg-dark position-relative px-3">
<span class="navbar-brand">🪑 Wartezimmer</span>
<a href="/dashboard" class="btn btn-outline-light btn-sm">Dashboard</a> <!-- 🟢 ZENTRIERTER TITEL -->
<div class="position-absolute top-50 start-50 translate-middle
d-flex align-items-center gap-2 text-white">
<span style="font-size:1.4rem;">🪑</span>
<span class="fw-semibold fs-5">Wartezimmer</span>
</div>
<!-- 🔵 RECHTS: DASHBOARD -->
<div class="ms-auto">
<a href="/dashboard" class="btn btn-outline-primary btn-sm">
⬅️ Dashboard
</a>
</div>
</nav> </nav>
<div class="container mt-4"> <div class="container mt-4">
<!-- ✅ EINMAL Flash anzeigen --> <!-- ✅ EINMAL Flash anzeigen -->