336 lines
11 KiB
Plaintext
336 lines
11 KiB
Plaintext
<!DOCTYPE html>
|
|
<html lang="de">
|
|
<head>
|
|
<meta charset="UTF-8" />
|
|
<title><%= t.adminInvoice.invoiceOverview %></title>
|
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
|
|
<link rel="stylesheet" href="/css/bootstrap.min.css" />
|
|
<link rel="stylesheet" href="/bootstrap-icons/bootstrap-icons.min.css" />
|
|
|
|
<style>
|
|
body {
|
|
margin: 0;
|
|
background: #f4f6f9;
|
|
font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI",
|
|
Roboto, Ubuntu;
|
|
}
|
|
|
|
.layout {
|
|
display: flex;
|
|
min-height: 100vh;
|
|
}
|
|
|
|
/* Sidebar */
|
|
.sidebar {
|
|
width: 240px;
|
|
background: #111827;
|
|
color: white;
|
|
padding: 20px;
|
|
display: flex;
|
|
flex-direction: column;
|
|
}
|
|
|
|
.logo {
|
|
font-size: 18px;
|
|
font-weight: 700;
|
|
margin-bottom: 30px;
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 10px;
|
|
}
|
|
|
|
.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;
|
|
}
|
|
|
|
.nav-item:hover {
|
|
background: #1f2937;
|
|
color: white;
|
|
}
|
|
|
|
.nav-item.active {
|
|
background: #2563eb;
|
|
color: white;
|
|
}
|
|
|
|
.sidebar .spacer {
|
|
flex: 1;
|
|
}
|
|
|
|
/* Main */
|
|
.main {
|
|
flex: 1;
|
|
padding: 0;
|
|
background: #f4f6f9;
|
|
overflow: hidden;
|
|
display: flex;
|
|
flex-direction: column;
|
|
}
|
|
</style>
|
|
</head>
|
|
|
|
<body>
|
|
<%
|
|
// ✅ active aus view setzen (view kommt vom Controller)
|
|
let active = "sales_year";
|
|
if (view === "quarter") active = "sales_quarter";
|
|
if (view === "month") active = "sales_month";
|
|
if (view === "patient") active = "sales_patient";
|
|
if (view === "year") active = "sales_year";
|
|
%>
|
|
|
|
<div class="layout">
|
|
<!-- ✅ neue Invoice Sidebar -->
|
|
<%- include("../partials/invoice_sidebar", { active, t }) %>
|
|
|
|
<!-- MAIN CONTENT -->
|
|
<div class="main">
|
|
<!-- =========================
|
|
NAVBAR
|
|
========================== -->
|
|
<nav class="navbar navbar-dark bg-dark position-relative px-3">
|
|
<div
|
|
class="position-absolute top-50 start-50 translate-middle d-flex align-items-center gap-2 text-white"
|
|
>
|
|
<i class="bi bi-calculator fs-4"></i>
|
|
<span class="fw-semibold fs-5"><%= t.adminInvoice.invoiceOverview %></span>
|
|
</div>
|
|
|
|
<div class="ms-auto">
|
|
<a href="/dashboard" class="btn btn-outline-primary btn-sm">
|
|
⬅️ <%= t.global.dashboard %>
|
|
</a>
|
|
</div>
|
|
</nav>
|
|
|
|
<!-- =========================
|
|
FILTER: JAHR VON / BIS
|
|
========================== -->
|
|
<div class="container-fluid mt-4">
|
|
<form method="get" class="row g-2 mb-4">
|
|
<!-- ✅ view beibehalten -->
|
|
<input type="hidden" name="view" value="<%= view %>" />
|
|
|
|
<div class="col-auto">
|
|
<input
|
|
type="number"
|
|
name="fromYear"
|
|
class="form-control"
|
|
placeholder="Von Jahr"
|
|
value="<%= fromYear %>"
|
|
/>
|
|
</div>
|
|
|
|
<div class="col-auto">
|
|
<input
|
|
type="number"
|
|
name="toYear"
|
|
class="form-control"
|
|
placeholder="Bis Jahr"
|
|
value="<%= toYear %>"
|
|
/>
|
|
</div>
|
|
|
|
<div class="col-auto">
|
|
<button class="btn btn-outline-secondary">
|
|
Filter
|
|
</button>
|
|
</div>
|
|
</form>
|
|
|
|
<!-- ✅ NUR EINE TABELLE -->
|
|
<div class="row g-3">
|
|
<% if (view === "year") { %>
|
|
|
|
<!-- Jahresumsatz -->
|
|
<div class="col-12">
|
|
<div class="card h-100">
|
|
<div class="card-header fw-semibold">
|
|
<%= t.adminInvoice.annualSales %>
|
|
</div>
|
|
<div class="card-body p-0">
|
|
<table class="table table-striped mb-0">
|
|
<thead>
|
|
<tr>
|
|
<th><%= t.global.year %></th>
|
|
<th class="text-end">€</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<% if (yearly.length === 0) { %>
|
|
<tr>
|
|
<td colspan="2" class="text-center text-muted">
|
|
Keine Daten
|
|
</td>
|
|
</tr>
|
|
<% } %>
|
|
|
|
<% yearly.forEach(y => { %>
|
|
<tr>
|
|
<td><%= y.year %></td>
|
|
<td class="text-end fw-semibold"><%= Number(y.total).toFixed(2) %></td>
|
|
</tr>
|
|
<% }) %>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<% } else if (view === "quarter") { %>
|
|
|
|
<!-- Quartalsumsatz -->
|
|
<div class="col-12">
|
|
<div class="card h-100">
|
|
<div class="card-header fw-semibold">
|
|
<%= t.adminInvoice.quarterlySales %>
|
|
</div>
|
|
<div class="card-body p-0">
|
|
<table class="table table-striped mb-0">
|
|
<thead>
|
|
<tr>
|
|
<th><%= t.global.year %></th>
|
|
<th>Q</th>
|
|
<th class="text-end">€</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<% if (quarterly.length === 0) { %>
|
|
<tr>
|
|
<td colspan="3" class="text-center text-muted">
|
|
Keine Daten
|
|
</td>
|
|
</tr>
|
|
<% } %>
|
|
|
|
<% quarterly.forEach(q => { %>
|
|
<tr>
|
|
<td><%= q.year %></td>
|
|
<td>Q<%= q.quarter %></td>
|
|
<td class="text-end fw-semibold"><%= Number(q.total).toFixed(2) %></td>
|
|
</tr>
|
|
<% }) %>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<% } else if (view === "month") { %>
|
|
|
|
<!-- Monatsumsatz -->
|
|
<div class="col-12">
|
|
<div class="card h-100">
|
|
<div class="card-header fw-semibold">
|
|
<%= t.adminInvoice.monthSales %>
|
|
</div>
|
|
<div class="card-body p-0">
|
|
<table class="table table-striped mb-0">
|
|
<thead>
|
|
<tr>
|
|
<th><%= t.global.month %></th>
|
|
<th class="text-end">€</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<% if (monthly.length === 0) { %>
|
|
<tr>
|
|
<td colspan="2" class="text-center text-muted">
|
|
Keine Daten
|
|
</td>
|
|
</tr>
|
|
<% } %>
|
|
|
|
<% monthly.forEach(m => { %>
|
|
<tr>
|
|
<td><%= m.month %></td>
|
|
<td class="text-end fw-semibold"><%= Number(m.total).toFixed(2) %></td>
|
|
</tr>
|
|
<% }) %>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<% } else if (view === "patient") { %>
|
|
|
|
<!-- Umsatz pro Patient -->
|
|
<div class="col-12">
|
|
<div class="card h-100">
|
|
<div class="card-header fw-semibold">
|
|
<%= t.adminInvoice.patientsSales %>
|
|
</div>
|
|
<div class="card-body p-2">
|
|
<form method="get" class="mb-2 d-flex gap-2">
|
|
<!-- ✅ view beibehalten -->
|
|
<input type="hidden" name="view" value="<%= view %>" />
|
|
<input type="hidden" name="fromYear" value="<%= fromYear %>" />
|
|
<input type="hidden" name="toYear" value="<%= toYear %>" />
|
|
|
|
<input
|
|
type="text"
|
|
name="q"
|
|
value="<%= search %>"
|
|
class="form-control form-control-sm"
|
|
placeholder="<%= t.adminInvoice.patientsSales %>"
|
|
/>
|
|
|
|
<button class="btn btn-sm btn-outline-primary">
|
|
<%= t.adminInvoice.search %>
|
|
</button>
|
|
|
|
<a
|
|
href="/admin/invoices?view=patient&fromYear=<%= fromYear %>&toYear=<%= toYear %>"
|
|
class="btn btn-sm btn-outline-secondary"
|
|
>
|
|
<%= t.global.reset %>
|
|
</a>
|
|
</form>
|
|
|
|
<table class="table table-striped mb-0">
|
|
<thead>
|
|
<tr>
|
|
<th><%= t.adminInvoice.patient %></th>
|
|
<th class="text-end">€</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<% if (patients.length === 0) { %>
|
|
<tr>
|
|
<td colspan="2" class="text-center text-muted">
|
|
Keine Daten
|
|
</td>
|
|
</tr>
|
|
<% } %>
|
|
|
|
<% patients.forEach(p => { %>
|
|
<tr>
|
|
<td><%= p.patient %></td>
|
|
<td class="text-end fw-semibold"><%= Number(p.total).toFixed(2) %></td>
|
|
</tr>
|
|
<% }) %>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<% } %>
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</body>
|
|
</html>
|