Weitere übersetzungen
This commit is contained in:
parent
3f70e1f7f9
commit
65bb75d437
@ -13,14 +13,27 @@ const safe = (v) => {
|
||||
* GET: Firmendaten anzeigen
|
||||
*/
|
||||
async function getCompanySettings(req, res) {
|
||||
const [[company]] = await db.promise().query(
|
||||
"SELECT * FROM company_settings LIMIT 1"
|
||||
);
|
||||
try {
|
||||
const [[company]] = await db
|
||||
.promise()
|
||||
.query("SELECT * FROM company_settings LIMIT 1");
|
||||
|
||||
res.render("admin/company-settings", {
|
||||
user: req.user,
|
||||
company: company || {}
|
||||
});
|
||||
res.render("admin/company-settings", {
|
||||
layout: "layout", // 🔥 wichtig
|
||||
title: "Firmendaten", // 🔥 DAS FEHLTE
|
||||
active: "companySettings", // 🔥 Sidebar aktiv
|
||||
sidebarPartial: "partials/admin-sidebar",
|
||||
|
||||
company: company || {},
|
||||
|
||||
user: req.session.user, // 🔥 konsistent
|
||||
lang: req.session.lang || "de"
|
||||
// t kommt aus res.locals
|
||||
});
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
res.status(500).send("Datenbankfehler");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -8,9 +8,15 @@ async function showDashboard(req, res) {
|
||||
const waitingPatients = await getWaitingPatients(db);
|
||||
|
||||
res.render("dashboard", {
|
||||
|
||||
layout: "layout", // 🔥 DAS FEHLTE
|
||||
|
||||
title: "Dashboard",
|
||||
active: "dashboard",
|
||||
sidebarPartial: "partials/sidebar",
|
||||
|
||||
waitingPatients,
|
||||
user: req.session.user,
|
||||
waitingPatients
|
||||
lang: req.session.lang || "de"
|
||||
});
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
|
||||
@ -66,7 +66,8 @@
|
||||
"dashboard": {
|
||||
"welcome": "Willkommen",
|
||||
"waitingRoom": "Wartezimmer-Monitor",
|
||||
"noWaitingPatients": "Keine Patienten im Wartezimmer."
|
||||
"noWaitingPatients": "Keine Patienten im Wartezimmer.",
|
||||
"title":"Dashboard"
|
||||
},
|
||||
|
||||
"adminSidebar": {
|
||||
@ -75,7 +76,8 @@
|
||||
"user":"Benutzer",
|
||||
"invocieoverview":"Rechnungsübersicht",
|
||||
"seriennumber":"Seriennummer",
|
||||
"databasetable":"Datenbank"
|
||||
"databasetable":"Datenbank",
|
||||
"companysettings":"Firmendaten"
|
||||
},
|
||||
|
||||
"adminuseroverview": {
|
||||
|
||||
@ -39,7 +39,7 @@
|
||||
"birthday":"Fecha de nacimiento",
|
||||
"email":"Correo electrónico",
|
||||
"phone":"Teléfono",
|
||||
"address":"AdreDirecciónsse",
|
||||
"address":"Dirección",
|
||||
"country":"País",
|
||||
"notice":"Notas",
|
||||
"create":"Creado",
|
||||
@ -67,7 +67,8 @@
|
||||
"dashboard": {
|
||||
"welcome": "Bienvenido",
|
||||
"waitingRoom": "Monitor sala de espera",
|
||||
"noWaitingPatients": "No hay pacientes en la sala de espera."
|
||||
"noWaitingPatients": "No hay pacientes en la sala de espera.",
|
||||
"title":"Dashboard"
|
||||
},
|
||||
|
||||
"adminSidebar": {
|
||||
@ -76,7 +77,8 @@
|
||||
"user":"usuario",
|
||||
"invocieoverview":"Resumen de facturas",
|
||||
"seriennumber":"número de serie",
|
||||
"databasetable":"base de datos"
|
||||
"databasetable":"base de datos",
|
||||
"companysettings":"Datos de la empresa"
|
||||
},
|
||||
|
||||
"adminuseroverview": {
|
||||
|
||||
@ -6,6 +6,7 @@ const path = require("path");
|
||||
const { exec } = require("child_process");
|
||||
const multer = require("multer");
|
||||
const { NodeSSH } = require("node-ssh");
|
||||
const uploadLogo = require("../middleware/uploadLogo");
|
||||
|
||||
|
||||
// ✅ Upload Ordner für Restore Dumps
|
||||
@ -31,6 +32,13 @@ const { loadConfig, saveConfig } = require("../config-manager");
|
||||
// ✅ DB (für resetPool)
|
||||
const db = require("../db");
|
||||
|
||||
// ✅ Firmendaten
|
||||
const {
|
||||
getCompanySettings,
|
||||
saveCompanySettings
|
||||
} = require("../controllers/companySettings.controller");
|
||||
|
||||
|
||||
/* ==========================
|
||||
✅ VERWALTUNG (NUR ADMIN)
|
||||
========================== */
|
||||
@ -485,4 +493,20 @@ router.post("/database/restore", requireAdmin, async (req, res) => {
|
||||
========================== */
|
||||
router.get("/invoices", requireAdmin, showInvoiceOverview);
|
||||
|
||||
/* ==========================
|
||||
✅ Firmendaten
|
||||
========================== */
|
||||
router.get(
|
||||
"/company-settings",
|
||||
requireAdmin,
|
||||
getCompanySettings
|
||||
);
|
||||
|
||||
router.post(
|
||||
"/company-settings",
|
||||
requireAdmin,
|
||||
uploadLogo.single("logo"),
|
||||
saveCompanySettings
|
||||
);
|
||||
|
||||
module.exports = router;
|
||||
|
||||
@ -1,19 +1,21 @@
|
||||
const express = require("express");
|
||||
const router = express.Router();
|
||||
const { requireArzt } = require("../middleware/auth.middleware");
|
||||
const { requireAdmin } = require("../middleware/auth.middleware");
|
||||
const uploadLogo = require("../middleware/uploadLogo");
|
||||
const {
|
||||
getCompanySettings,
|
||||
saveCompanySettings,
|
||||
} = require("../controllers/companySettings.controller");
|
||||
|
||||
router.get("/admin/company-settings", requireArzt, getCompanySettings);
|
||||
// ✅ NUR der relative Pfad
|
||||
router.get("/company-settings", requireAdmin, getCompanySettings);
|
||||
|
||||
router.post(
|
||||
"/admin/company-settings",
|
||||
requireArzt,
|
||||
uploadLogo.single("logo"), // 🔑 MUSS VOR DEM CONTROLLER KOMMEN
|
||||
saveCompanySettings,
|
||||
"/company-settings",
|
||||
requireAdmin,
|
||||
uploadLogo.single("logo"),
|
||||
saveCompanySettings
|
||||
);
|
||||
|
||||
module.exports = router;
|
||||
|
||||
|
||||
@ -1,132 +1,196 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Firmendaten</title>
|
||||
<link rel="stylesheet" href="/css/bootstrap.min.css">
|
||||
</head>
|
||||
<body class="bg-light">
|
||||
<%- include("../partials/page-header", {
|
||||
user,
|
||||
title,
|
||||
subtitle: "",
|
||||
showUserName: true
|
||||
}) %>
|
||||
|
||||
<div class="container mt-4">
|
||||
<h3 class="mb-4">🏢 Firmendaten</h3>
|
||||
<div class="content p-4">
|
||||
|
||||
<form method="POST" action="/admin/company-settings" enctype="multipart/form-data">
|
||||
<%- include("../partials/flash") %>
|
||||
|
||||
<div class="row g-3">
|
||||
<div class="container-fluid">
|
||||
|
||||
<div class="card shadow-sm">
|
||||
<div class="card-body">
|
||||
|
||||
<h5 class="mb-4">
|
||||
<i class="bi bi-building"></i>
|
||||
<%= title %>
|
||||
</h5>
|
||||
|
||||
<form
|
||||
method="POST"
|
||||
action="/admin/company-settings"
|
||||
enctype="multipart/form-data"
|
||||
>
|
||||
|
||||
<div class="row g-3">
|
||||
|
||||
<div class="col-md-6">
|
||||
<label class="form-label">Firmenname</label>
|
||||
<input class="form-control" name="company_name"
|
||||
value="<%= company.company_name || '' %>" required>
|
||||
<label class="form-label">Firmenname</label>
|
||||
<input
|
||||
class="form-control"
|
||||
name="company_name"
|
||||
value="<%= settings.company_name || '' %>"
|
||||
required
|
||||
>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6">
|
||||
<label class="form-label">Rechtsform</label>
|
||||
<input class="form-control" name="company_legal_form"
|
||||
value="<%= company.company_legal_form || '' %>">
|
||||
<label class="form-label">Rechtsform</label>
|
||||
<input
|
||||
class="form-control"
|
||||
name="company_legal_form"
|
||||
value="<%= settings.company_legal_form || '' %>"
|
||||
>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6">
|
||||
<label class="form-label">Inhaber / Geschäftsführer</label>
|
||||
<input class="form-control" name="company_owner"
|
||||
value="<%= company.company_owner || '' %>">
|
||||
<label class="form-label">Inhaber / Geschäftsführer</label>
|
||||
<input
|
||||
class="form-control"
|
||||
name="company_owner"
|
||||
value="<%= settings.company_owner || '' %>"
|
||||
>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6">
|
||||
<label class="form-label">E-Mail</label>
|
||||
<input class="form-control" name="email"
|
||||
value="<%= company.email || '' %>">
|
||||
<label class="form-label">E-Mail</label>
|
||||
<input
|
||||
class="form-control"
|
||||
name="email"
|
||||
value="<%= settings.email || '' %>"
|
||||
>
|
||||
</div>
|
||||
|
||||
<div class="col-md-8">
|
||||
<label class="form-label">Straße</label>
|
||||
<input class="form-control" name="street"
|
||||
value="<%= company.street || '' %>">
|
||||
<label class="form-label">Straße</label>
|
||||
<input
|
||||
class="form-control"
|
||||
name="street"
|
||||
value="<%= settings.street || '' %>"
|
||||
>
|
||||
</div>
|
||||
|
||||
<div class="col-md-4">
|
||||
<label class="form-label">Hausnummer</label>
|
||||
<input class="form-control" name="house_number"
|
||||
value="<%= company.house_number || '' %>">
|
||||
<label class="form-label">Hausnummer</label>
|
||||
<input
|
||||
class="form-control"
|
||||
name="house_number"
|
||||
value="<%= settings.house_number || '' %>"
|
||||
>
|
||||
</div>
|
||||
|
||||
<div class="col-md-4">
|
||||
<label class="form-label">PLZ</label>
|
||||
<input class="form-control" name="postal_code"
|
||||
value="<%= company.postal_code || '' %>">
|
||||
<label class="form-label">PLZ</label>
|
||||
<input
|
||||
class="form-control"
|
||||
name="postal_code"
|
||||
value="<%= settings.postal_code || '' %>"
|
||||
>
|
||||
</div>
|
||||
|
||||
<div class="col-md-8">
|
||||
<label class="form-label">Ort</label>
|
||||
<input class="form-control" name="city"
|
||||
value="<%= company.city || '' %>">
|
||||
<label class="form-label">Ort</label>
|
||||
<input
|
||||
class="form-control"
|
||||
name="city"
|
||||
value="<%= settings.city || '' %>"
|
||||
>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6">
|
||||
<label class="form-label">Land</label>
|
||||
<input class="form-control" name="country"
|
||||
value="<%= company.country || 'Deutschland' %>">
|
||||
<label class="form-label">Land</label>
|
||||
<input
|
||||
class="form-control"
|
||||
name="country"
|
||||
value="<%= settings.country || 'Deutschland' %>"
|
||||
>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6">
|
||||
<label class="form-label">USt-ID / Steuernummer</label>
|
||||
<input class="form-control" name="vat_id"
|
||||
value="<%= company.vat_id || '' %>">
|
||||
<label class="form-label">USt-ID / Steuernummer</label>
|
||||
<input
|
||||
class="form-control"
|
||||
name="vat_id"
|
||||
value="<%= settings.vat_id || '' %>"
|
||||
>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6">
|
||||
<label class="form-label">Bank</label>
|
||||
<input class="form-control" name="bank_name"
|
||||
value="<%= company.bank_name || '' %>">
|
||||
<label class="form-label">Bank</label>
|
||||
<input
|
||||
class="form-control"
|
||||
name="bank_name"
|
||||
value="<%= settings.bank_name || '' %>"
|
||||
>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6">
|
||||
<label class="form-label">IBAN</label>
|
||||
<input class="form-control" name="iban"
|
||||
value="<%= company.iban || '' %>">
|
||||
<label class="form-label">IBAN</label>
|
||||
<input
|
||||
class="form-control"
|
||||
name="iban"
|
||||
value="<%= settings.iban || '' %>"
|
||||
>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6">
|
||||
<label class="form-label">BIC</label>
|
||||
<input class="form-control" name="bic"
|
||||
value="<%= company.bic || '' %>">
|
||||
<label class="form-label">BIC</label>
|
||||
<input
|
||||
class="form-control"
|
||||
name="bic"
|
||||
value="<%= settings.bic || '' %>"
|
||||
>
|
||||
</div>
|
||||
|
||||
<div class="col-12">
|
||||
<label class="form-label">Rechnungs-Footer</label>
|
||||
<textarea class="form-control" rows="3"
|
||||
name="invoice_footer_text"><%= company.invoice_footer_text || '' %></textarea>
|
||||
<label class="form-label">Rechnungs-Footer</label>
|
||||
<textarea
|
||||
class="form-control"
|
||||
rows="3"
|
||||
name="invoice_footer_text"
|
||||
><%= settings.invoice_footer_text || '' %></textarea>
|
||||
</div>
|
||||
|
||||
<div class="col-12">
|
||||
<label class="form-label">Firmenlogo</label>
|
||||
<input
|
||||
type="file"
|
||||
name="logo"
|
||||
class="form-control"
|
||||
accept="image/png, image/jpeg"
|
||||
>
|
||||
<label class="form-label">Firmenlogo</label>
|
||||
<input
|
||||
type="file"
|
||||
name="logo"
|
||||
class="form-control"
|
||||
accept="image/png, image/jpeg"
|
||||
>
|
||||
|
||||
<% if (company.invoice_logo_path) { %>
|
||||
<div class="mt-2">
|
||||
<small class="text-muted">Aktuelles Logo:</small><br>
|
||||
<img
|
||||
src="<%= company.invoice_logo_path %>"
|
||||
style="max-height:80px; border:1px solid #ccc; padding:4px;"
|
||||
>
|
||||
</div>
|
||||
<% } %>
|
||||
<% if (settings.invoice_logo_path) { %>
|
||||
<div class="mt-2">
|
||||
<small class="text-muted">Aktuelles Logo:</small><br>
|
||||
<img
|
||||
src="<%= settings.invoice_logo_path %>"
|
||||
style="max-height:80px; border:1px solid #ccc; padding:4px;"
|
||||
>
|
||||
</div>
|
||||
<% } %>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-4">
|
||||
<button class="btn btn-primary">💾 Speichern</button>
|
||||
<a href="/dashboard" class="btn btn-secondary">Zurück</a>
|
||||
</div>
|
||||
<div class="mt-4 d-flex gap-2">
|
||||
<button class="btn btn-primary">
|
||||
<i class="bi bi-save"></i>
|
||||
<%= t.global.save %>
|
||||
</button>
|
||||
|
||||
</form>
|
||||
<a href="/dashboard" class="btn btn-secondary">
|
||||
Zurück
|
||||
</a>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@ -1,66 +1,43 @@
|
||||
<div class="layout">
|
||||
<!-- KEIN layout, KEINE sidebar, KEIN main -->
|
||||
|
||||
<!-- ✅ SIDEBAR -->
|
||||
<%- include("partials/sidebar", { user, active: "patients", lang }) %>
|
||||
<%- include("partials/page-header", {
|
||||
user,
|
||||
title: t.dashboard.title,
|
||||
subtitle: "",
|
||||
showUserName: true,
|
||||
hideDashboardButton: true
|
||||
}) %>
|
||||
|
||||
<!-- ✅ MAIN -->
|
||||
<div class="main">
|
||||
<div class="content p-4">
|
||||
|
||||
<!-- ✅ HEADER (inkl. Uhrzeit) -->
|
||||
<%- include("partials/page-header", {
|
||||
user,
|
||||
title: "Dashboard",
|
||||
subtitle: "",
|
||||
showUserName: true,
|
||||
hideDashboardButton: true
|
||||
}) %>
|
||||
<%- include("partials/flash") %>
|
||||
|
||||
<div class="content p-4">
|
||||
<div class="waiting-monitor">
|
||||
<h5 class="mb-3">🪑 <%= t.dashboard.waitingRoom %></h5>
|
||||
|
||||
<!-- Flash Messages -->
|
||||
<%- include("partials/flash") %>
|
||||
|
||||
<!-- =========================
|
||||
WARTEZIMMER MONITOR
|
||||
========================= -->
|
||||
<div class="waiting-monitor">
|
||||
<h5 class="mb-3">🪑 <%=t.global.waitingroomtext%></h5>
|
||||
|
||||
<div class="waiting-grid">
|
||||
<% if (waitingPatients && waitingPatients.length > 0) { %>
|
||||
|
||||
<% waitingPatients.forEach(p => { %>
|
||||
|
||||
<% if (user.role === 'arzt') { %>
|
||||
<form method="POST" action="/patients/<%= p.id %>/call" style="width:100%; margin:0;">
|
||||
<button type="submit" class="waiting-slot occupied clickable waiting-btn">
|
||||
<div class="patient-text">
|
||||
<div class="name"><%= p.firstname %> <%= p.lastname %></div>
|
||||
<div class="birthdate">
|
||||
<%= new Date(p.birthdate).toLocaleDateString("de-DE") %>
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
</form>
|
||||
<% } else { %>
|
||||
<div class="waiting-slot occupied">
|
||||
<div class="patient-text">
|
||||
<div class="name"><%= p.firstname %> <%= p.lastname %></div>
|
||||
<div class="birthdate">
|
||||
<%= new Date(p.birthdate).toLocaleDateString("de-DE") %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<% } %>
|
||||
|
||||
<% }) %>
|
||||
<div class="waiting-grid">
|
||||
<% if (waitingPatients && waitingPatients.length > 0) { %>
|
||||
<% waitingPatients.forEach(p => { %>
|
||||
|
||||
<% if (user.role === "arzt") { %>
|
||||
<form method="POST" action="/patients/<%= p.id %>/call">
|
||||
<button class="waiting-slot occupied clickable">
|
||||
<div><%= p.firstname %> <%= p.lastname %></div>
|
||||
</button>
|
||||
</form>
|
||||
<% } else { %>
|
||||
<div class="text-muted"><%=t.global.waitingroomtextnopatient%></div>
|
||||
<div class="waiting-slot occupied">
|
||||
<div><%= p.firstname %> <%= p.lastname %></div>
|
||||
</div>
|
||||
<% } %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<% }) %>
|
||||
<% } else { %>
|
||||
<div class="text-muted">
|
||||
<%= t.dashboard.noWaitingPatients %>
|
||||
</div>
|
||||
<% } %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
@ -20,7 +20,6 @@
|
||||
|
||||
<body>
|
||||
<div class="layout">
|
||||
|
||||
<!-- ✅ Sidebar dynamisch -->
|
||||
<% if (typeof sidebarPartial !== "undefined" && sidebarPartial) { %>
|
||||
<%- include(sidebarPartial, {
|
||||
|
||||
@ -26,6 +26,18 @@
|
||||
|
||||
<div class="sidebar-menu">
|
||||
|
||||
<!-- ✅ Firmendaten Verwaltung -->
|
||||
<a
|
||||
href="<%= hrefIfAllowed(isAdmin, '/admin/company-settings') %>"
|
||||
class="nav-item <%= active === 'companySettings' ? 'active' : '' %> <%= lockClass(isAdmin) %>"
|
||||
title="<%= isAdmin ? '' : 'Nur Admin' %>"
|
||||
>
|
||||
<i class="bi bi-people"></i> <%= t.adminSidebar.companysettings %>
|
||||
<% if (!isAdmin) { %>
|
||||
<span style="margin-left:auto;"><i class="bi bi-lock-fill"></i></span>
|
||||
<% } %>
|
||||
</a>
|
||||
|
||||
<!-- ✅ User Verwaltung -->
|
||||
<a
|
||||
href="<%= hrefIfAllowed(isAdmin, '/admin/users') %>"
|
||||
|
||||
Loading…
Reference in New Issue
Block a user