implement report feature

This commit is contained in:
Maximilian 2025-06-10 12:46:53 +02:00
parent 4218ee6b7d
commit d6d47f714a
31 changed files with 2472 additions and 8 deletions

View file

@ -0,0 +1,104 @@
{% extends "admin/reports/base.html" %}
{% load i18n %}
{% block title %}{% trans "Automatischen Report löschen" %}{% endblock %}
{% block content %}
<div class="report-content">
<div class="card">
<div class="card-header">
<h3>{% trans "Automatischen Report löschen" %}</h3>
</div>
<div class="card-body">
<div class="alert alert-warning">
<strong>{% trans "Achtung!" %}</strong>
{% trans "Sind Sie sicher, dass Sie den automatischen Report" %}
<strong>"{{ object.name }}"</strong>
{% trans "löschen möchten?" %}
</div>
<div class="report-details">
<h4>{% trans "Report-Details:" %}</h4>
<ul>
<li><strong>{% trans "Name:" %}</strong> {{ object.name }}</li>
<li><strong>{% trans "Häufigkeit:" %}</strong> {{ object.get_frequency_display }}</li>
<li><strong>{% trans "Status:" %}</strong>
{% if object.is_active %}
<span class="badge badge-success">{% trans "Aktiv" %}</span>
{% else %}
<span class="badge badge-secondary">{% trans "Inaktiv" %}</span>
{% endif %}
</li>
<li><strong>{% trans "Erstellt am:" %}</strong> {{ object.created_at|date:"d.m.Y H:i" }}</li>
<li><strong>{% trans "E-Mail-Adressen:" %}</strong>
<ul>
{% for email in object.email_addresses.all %}
<li>{{ email.email }}</li>
{% endfor %}
</ul>
</li>
</ul>
</div>
<div class="alert alert-info">
<strong>{% trans "Hinweis:" %}</strong>
{% trans "Das Löschen des automatischen Reports stoppt alle zukünftigen automatischen Versendungen. Bereits gesendete Reports bleiben im Report-Log erhalten." %}
</div>
<form method="post" class="delete-form">
{% csrf_token %}
<div class="form-actions">
<button type="submit" class="btn btn-danger">
<i class="fas fa-trash"></i> {% trans "Ja, löschen" %}
</button>
<a href="{% url 'reports:automatic_reports' %}" class="btn btn-secondary">
<i class="fas fa-arrow-left"></i> {% trans "Abbrechen" %}
</a>
</div>
</form>
</div>
</div>
</div>
<style>
.report-details {
background-color: #f8f9fa;
padding: 15px;
border-radius: 5px;
margin: 15px 0;
}
.report-details ul {
margin-bottom: 0;
}
.report-details ul li {
margin-bottom: 8px;
}
.report-details ul ul {
margin-top: 5px;
margin-left: 20px;
}
.delete-form {
margin-top: 20px;
}
.badge {
padding: 4px 8px;
border-radius: 4px;
font-size: 0.875em;
}
.badge-success {
background-color: #28a745;
color: white;
}
.badge-secondary {
background-color: #6c757d;
color: white;
}
</style>
{% endblock %}

View file

@ -0,0 +1,145 @@
{% extends "admin/reports/base.html" %}
{% load i18n %}
{% block title %}
{% if object %}
{% trans "Automatischen Report bearbeiten" %}
{% else %}
{% trans "Automatischen Report erstellen" %}
{% endif %}
{% endblock %}
{% block content %}
<div class="report-content">
<div class="card">
<div class="card-header">
<h3>
{% if object %}
{% trans "Automatischen Report bearbeiten" %}
{% else %}
{% trans "Automatischen Report erstellen" %}
{% endif %}
</h3>
</div>
<div class="card-body">
<form method="post" class="report-form">
{% csrf_token %}
<div class="form-row">
<div class="form-group">
<label for="{{ form.name.id_for_label }}">{{ form.name.label }}</label>
{{ form.name }}
{% if form.name.help_text %}
<small class="form-text text-muted">{{ form.name.help_text }}</small>
{% endif %}
{% if form.name.errors %}
<div class="error-messages">
{% for error in form.name.errors %}
<div class="error">{{ error }}</div>
{% endfor %}
</div>
{% endif %}
</div>
</div>
<div class="form-row">
<div class="form-group">
<label for="{{ form.email_addresses.id_for_label }}">{{ form.email_addresses.label }}</label>
{{ form.email_addresses }}
{% if form.email_addresses.help_text %}
<small class="form-text text-muted">{{ form.email_addresses.help_text }}</small>
{% endif %}
{% if form.email_addresses.errors %}
<div class="error-messages">
{% for error in form.email_addresses.errors %}
<div class="error">{{ error }}</div>
{% endfor %}
</div>
{% endif %}
</div>
</div>
<div class="form-row">
<div class="form-group col-md-6">
<label for="{{ form.frequency.id_for_label }}">{{ form.frequency.label }}</label>
{{ form.frequency }}
{% if form.frequency.errors %}
<div class="error-messages">
{% for error in form.frequency.errors %}
<div class="error">{{ error }}</div>
{% endfor %}
</div>
{% endif %}
</div>
<div class="form-group col-md-6">
<label for="{{ form.is_active.id_for_label }}">{{ form.is_active.label }}</label>
<div class="checkbox-wrapper">
{{ form.is_active }}
</div>
{% if form.is_active.errors %}
<div class="error-messages">
{% for error in form.is_active.errors %}
<div class="error">{{ error }}</div>
{% endfor %}
</div>
{% endif %}
</div>
</div>
<div class="form-section">
<h4>{% trans "Filter-Optionen" %}</h4>
<div class="form-row">
<div class="form-group col-md-6">
<div class="checkbox-wrapper">
{{ form.include_naturschutzbehörde }}
<label for="{{ form.include_naturschutzbehörde.id_for_label }}">{{ form.include_naturschutzbehörde.label }}</label>
</div>
{% if form.include_naturschutzbehörde.errors %}
<div class="error-messages">
{% for error in form.include_naturschutzbehörde.errors %}
<div class="error">{{ error }}</div>
{% endfor %}
</div>
{% endif %}
</div>
<div class="form-group col-md-6">
<div class="checkbox-wrapper">
{{ form.include_jagdbehörde }}
<label for="{{ form.include_jagdbehörde.id_for_label }}">{{ form.include_jagdbehörde.label }}</label>
</div>
{% if form.include_jagdbehörde.errors %}
<div class="error-messages">
{% for error in form.include_jagdbehörde.errors %}
<div class="error">{{ error }}</div>
{% endfor %}
</div>
{% endif %}
</div>
</div>
</div>
{% if form.non_field_errors %}
<div class="error-messages">
{% for error in form.non_field_errors %}
<div class="error">{{ error }}</div>
{% endfor %}
</div>
{% endif %}
<div class="form-actions">
<button type="submit" class="btn btn-primary">
{% if object %}
{% trans "Speichern" %}
{% else %}
{% trans "Erstellen" %}
{% endif %}
</button>
<a href="{% url 'reports:automatic_reports' %}" class="btn btn-secondary">
{% trans "Abbrechen" %}
</a>
</div>
</form>
</div>
</div>
</div>
{% endblock %}

View file

@ -0,0 +1,157 @@
{% extends "admin/reports/base.html" %}
{% load i18n %}
{% block reports_content %}
<div class="automatic-reports">
<h1>⚙️ Automatische Reports</h1>
<p>Verwalten Sie automatische Reports, die regelmäßig versendet werden.</p>
<div class="actions">
<a href="{% url 'reports:create_automatic_report' %}" class="btn btn-primary"> Neuen automatischen Report erstellen</a>
</div>
{% if reports %}
<div class="reports-table">
<table>
<thead>
<tr>
<th>Name</th>
<th>Häufigkeit</th>
<th>Filter</th>
<th>E-Mail-Adressen</th>
<th>Status</th>
<th>Zuletzt gesendet</th>
<th>Aktionen</th>
</tr>
</thead>
<tbody>
{% for report in reports %}
<tr>
<td>
<strong>{{ report.name }}</strong>
{% if report.description %}<br><small>{{ report.description|truncatechars:50 }}</small>{% endif %}
</td>
<td>{{ report.get_frequency_display }}</td>
<td>
{% if report.include_naturschutzbehoerde %}
<span class="badge badge-naturschutz">Naturschutzbehörde</span>
{% endif %}
{% if report.include_jagdbehoerde %}
<span class="badge badge-jagd">Jagdbehörde</span>
{% endif %}
</td>
<td>{{ report.email_addresses.count }} Adresse(n)</td>
<td>
{% if report.is_active %}
<span class="status status-active">✅ Aktiv</span>
{% else %}
<span class="status status-inactive">❌ Inaktiv</span>
{% endif %}
</td>
<td>
{% if report.last_sent %}
{{ report.last_sent|date:"d.m.Y H:i" }}
{% else %}
<em>Noch nie gesendet</em>
{% endif %}
</td>
<td class="actions-cell">
<a href="{% url 'reports:edit_automatic_report' report.id %}" class="btn btn-small btn-edit">✏️ Bearbeiten</a>
<a href="{% url 'reports:delete_automatic_report' report.id %}" class="btn btn-small btn-delete">🗑️ Löschen</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% else %}
<div class="empty-state">
<h3>Keine automatischen Reports konfiguriert</h3>
<p>Sie haben noch keine automatischen Reports erstellt. Klicken Sie auf den Button oben, um Ihren ersten automatischen Report zu erstellen.</p>
</div>
{% endif %}
</div>
<style>
.actions {
margin-bottom: 30px;
}
.reports-table {
background: white;
border-radius: 8px;
overflow: hidden;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
.reports-table table {
width: 100%;
border-collapse: collapse;
}
.reports-table th {
background: #417690;
color: white;
padding: 15px;
text-align: left;
font-weight: bold;
}
.reports-table td {
padding: 15px;
border-bottom: 1px solid #eee;
vertical-align: top;
}
.reports-table tr:hover {
background: #f8f9fa;
}
.badge {
display: inline-block;
padding: 4px 8px;
border-radius: 12px;
font-size: 0.8em;
font-weight: bold;
margin: 2px;
}
.badge-naturschutz {
background: #e8f5e8;
color: #2e7d32;
}
.badge-jagd {
background: #fff3e0;
color: #f57c00;
}
.status {
font-weight: bold;
}
.status-active {
color: #2e7d32;
}
.status-inactive {
color: #d32f2f;
}
.actions-cell {
white-space: nowrap;
}
.btn-small {
padding: 6px 12px;
font-size: 0.9em;
margin: 2px;
}
.btn-edit {
background: #1976d2;
color: white;
}
.btn-delete {
background: #d32f2f;
color: white;
}
.empty-state {
text-align: center;
padding: 60px 20px;
background: white;
border-radius: 8px;
color: #666;
}
.empty-state h3 {
color: #417690;
margin-bottom: 15px;
}
</style>
{% endblock %}

View file

@ -0,0 +1,72 @@
{% extends "admin/base_site.html" %}
{% load i18n admin_urls static admin_list %}
{% block title %}{{ title }} | {{ site_title|default:_('Django site admin') }}{% endblock %}
{% block branding %}
<h1 id="site-name"><a href="{% url 'admin:index' %}">Django FBF Administration</a></h1>
{% endblock %}
{% block nav-global %}
<div class="nav-global">
<a href="{% url 'reports:dashboard' %}" class="{% if request.resolver_match.url_name == 'dashboard' %}current{% endif %}">📊 Dashboard</a>
<a href="{% url 'reports:manual_report' %}" class="{% if request.resolver_match.url_name == 'manual_report' %}current{% endif %}">📝 Report erstellen</a>
<a href="{% url 'reports:automatic_reports' %}" class="{% if request.resolver_match.url_name == 'automatic_reports' %}current{% endif %}">⚙️ Automatischer Report</a>
<a href="{% url 'reports:report_logs' %}" class="{% if request.resolver_match.url_name == 'report_logs' %}current{% endif %}">📋 Protokoll</a>
</div>
{% endblock %}
{% block content %}
<div class="reports-content">
{% if messages %}
<div class="messagelist">
{% for message in messages %}
<div class="alert alert-{{ message.tags }}">{{ message }}</div>
{% endfor %}
</div>
{% endif %}
{% block reports_content %}
{% endblock %}
</div>
{% endblock %}
{% block extrahead %}
{{ block.super }}
<style>
.nav-global {
background: #417690;
padding: 10px 20px;
margin: 0 -20px 20px -20px;
}
.nav-global a {
color: white;
text-decoration: none;
margin-right: 20px;
padding: 8px 12px;
border-radius: 4px;
}
.nav-global a:hover, .nav-global a.current {
background: rgba(255,255,255,0.2);
}
.reports-content {
max-width: 1200px;
}
.alert {
padding: 12px;
margin-bottom: 20px;
border: 1px solid transparent;
border-radius: 4px;
}
.alert-success {
color: #155724;
background-color: #d4edda;
border-color: #c3e6cb;
}
.alert-error {
color: #721c24;
background-color: #f8d7da;
border-color: #f5c6cb;
}
</style>
{% endblock %}

View file

@ -0,0 +1,85 @@
{% extends "admin/reports/base.html" %}
{% load i18n %}
{% block reports_content %}
<div class="dashboard">
<h1>📊 Reports Dashboard</h1>
<p>Willkommen zum Reports-System der Django FBF Anwendung. Hier können Sie Berichte über gefallene Vögel erstellen und verwalten.</p>
<div class="dashboard-modules">
<div class="module">
<h2>📝 Report erstellen</h2>
<p>Erstellen Sie sofort einen benutzerdefinierten Report für einen bestimmten Zeitraum.</p>
<ul>
<li>Zeitraum auswählen (Standard: letzte 3 Monate)</li>
<li>Filter nach Naturschutzbehörde/Jagdbehörde</li>
<li>E-Mail versenden oder als CSV herunterladen</li>
</ul>
<a href="{% url 'reports:manual_report' %}" class="btn btn-primary">Report erstellen</a>
</div>
<div class="module">
<h2>⚙️ Automatischer Report</h2>
<p>Konfigurieren Sie automatische Reports, die regelmäßig versendet werden.</p>
<ul>
<li>Wöchentliche, monatliche oder vierteljährliche Reports</li>
<li>Vordefinierte E-Mail-Empfänger</li>
<li>Automatische Zeitraum-Berechnung</li>
</ul>
<a href="{% url 'reports:automatic_reports' %}" class="btn btn-primary">Automatische Reports verwalten</a>
</div>
<div class="module">
<h2>📋 Report-Protokoll</h2>
<p>Übersicht über alle erstellten und versendeten Reports.</p>
<ul>
<li>Historie aller Reports</li>
<li>Status der E-Mail-Versendung</li>
<li>Filter und Statistiken</li>
</ul>
<a href="{% url 'reports:report_logs' %}" class="btn btn-primary">Protokoll anzeigen</a>
</div>
</div>
</div>
<style>
.dashboard-modules {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 20px;
margin-top: 30px;
}
.module {
background: white;
border: 1px solid #ddd;
border-radius: 8px;
padding: 20px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
.module h2 {
color: #417690;
margin-top: 0;
}
.module ul {
margin: 15px 0;
padding-left: 20px;
}
.module li {
margin-bottom: 8px;
color: #666;
}
.btn {
display: inline-block;
padding: 10px 20px;
background: #417690;
color: white;
text-decoration: none;
border-radius: 4px;
margin-top: 15px;
}
.btn:hover {
background: #2e5a70;
color: white;
}
</style>
{% endblock %}

View file

@ -0,0 +1,178 @@
{% extends "admin/reports/base.html" %}
{% load i18n crispy_forms_tags %}
{% block reports_content %}
<div class="manual-report">
<h1>📝 Report erstellen</h1>
<p>Erstellen Sie einen benutzerdefinierten Report für einen bestimmten Zeitraum.</p>
<form method="post" class="report-form">
{% csrf_token %}
<fieldset class="fieldset">
<legend>📅 Zeitraum</legend>
<div class="form-row">
<div class="form-group">
<label for="{{ form.date_from.id_for_label }}">{{ form.date_from.label }}</label>
{{ form.date_from }}
{% if form.date_from.help_text %}<p class="help">{{ form.date_from.help_text }}</p>{% endif %}
{% if form.date_from.errors %}<ul class="errorlist">{% for error in form.date_from.errors %}<li>{{ error }}</li>{% endfor %}</ul>{% endif %}
</div>
<div class="form-group">
<label for="{{ form.date_to.id_for_label }}">{{ form.date_to.label }}</label>
{{ form.date_to }}
{% if form.date_to.help_text %}<p class="help">{{ form.date_to.help_text }}</p>{% endif %}
{% if form.date_to.errors %}<ul class="errorlist">{% for error in form.date_to.errors %}<li>{{ error }}</li>{% endfor %}</ul>{% endif %}
</div>
</div>
</fieldset>
<fieldset class="fieldset">
<legend>🎯 Filter</legend>
<div class="form-row">
<div class="form-group checkbox-group">
{{ form.include_naturschutzbehoerde }}
<label for="{{ form.include_naturschutzbehoerde.id_for_label }}">{{ form.include_naturschutzbehoerde.label }}</label>
{% if form.include_naturschutzbehoerde.help_text %}<p class="help">{{ form.include_naturschutzbehoerde.help_text }}</p>{% endif %}
</div>
<div class="form-group checkbox-group">
{{ form.include_jagdbehoerde }}
<label for="{{ form.include_jagdbehoerde.id_for_label }}">{{ form.include_jagdbehoerde.label }}</label>
{% if form.include_jagdbehoerde.help_text %}<p class="help">{{ form.include_jagdbehoerde.help_text }}</p>{% endif %}
</div>
</div>
{% if form.include_naturschutzbehoerde.errors or form.include_jagdbehoerde.errors %}
<ul class="errorlist">
{% for error in form.include_naturschutzbehoerde.errors %}<li>{{ error }}</li>{% endfor %}
{% for error in form.include_jagdbehoerde.errors %}<li>{{ error }}</li>{% endfor %}
</ul>
{% endif %}
</fieldset>
<fieldset class="fieldset">
<legend>📧 E-Mail-Adressen</legend>
<div class="form-group">
<label>{{ form.email_addresses.label }}</label>
{{ form.email_addresses }}
{% if form.email_addresses.help_text %}<p class="help">{{ form.email_addresses.help_text }}</p>{% endif %}
{% if form.email_addresses.errors %}<ul class="errorlist">{% for error in form.email_addresses.errors %}<li>{{ error }}</li>{% endfor %}</ul>{% endif %}
</div>
<div class="form-group">
<label for="{{ form.custom_email.id_for_label }}">{{ form.custom_email.label }}</label>
{{ form.custom_email }}
{% if form.custom_email.help_text %}<p class="help">{{ form.custom_email.help_text }}</p>{% endif %}
{% if form.custom_email.errors %}<ul class="errorlist">{% for error in form.custom_email.errors %}<li>{{ error }}</li>{% endfor %}</ul>{% endif %}
</div>
</fieldset>
<fieldset class="fieldset">
<legend>🎬 Aktion</legend>
<div class="form-group">
{{ form.action }}
{% if form.action.errors %}<ul class="errorlist">{% for error in form.action.errors %}<li>{{ error }}</li>{% endfor %}</ul>{% endif %}
</div>
</fieldset>
{% if form.non_field_errors %}
<div class="form-errors">
{{ form.non_field_errors }}
</div>
{% endif %}
<div class="form-actions">
<button type="submit" class="btn btn-primary">Report erstellen</button>
<a href="{% url 'reports:dashboard' %}" class="btn btn-secondary">Abbrechen</a>
</div>
</form>
</div>
<style>
.report-form {
max-width: 800px;
}
.fieldset {
border: 1px solid #ddd;
border-radius: 8px;
padding: 20px;
margin-bottom: 20px;
background: white;
}
.fieldset legend {
font-weight: bold;
color: #417690;
padding: 0 10px;
}
.form-row {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 20px;
}
.form-group {
margin-bottom: 15px;
}
.form-group label {
display: block;
font-weight: bold;
margin-bottom: 5px;
color: #333;
}
.form-group input, .form-group select {
width: 100%;
padding: 8px;
border: 1px solid #ddd;
border-radius: 4px;
}
.checkbox-group {
display: flex;
align-items: center;
gap: 8px;
}
.checkbox-group input {
width: auto;
}
.checkbox-group label {
margin-bottom: 0;
}
.help {
font-size: 0.9em;
color: #666;
margin-top: 5px;
}
.errorlist {
color: #d32f2f;
list-style: none;
padding: 0;
margin: 5px 0;
}
.form-errors {
background: #ffebee;
border: 1px solid #f5c6cb;
border-radius: 4px;
padding: 10px;
margin-bottom: 20px;
}
.form-actions {
margin-top: 30px;
}
.btn {
display: inline-block;
padding: 10px 20px;
border: none;
border-radius: 4px;
text-decoration: none;
cursor: pointer;
margin-right: 10px;
}
.btn-primary {
background: #417690;
color: white;
}
.btn-secondary {
background: #6c757d;
color: white;
}
.btn:hover {
opacity: 0.9;
}
</style>
{% endblock %}

View file

@ -0,0 +1,278 @@
{% extends "admin/reports/base.html" %}
{% load i18n %}
{% block title %}{% trans "Report-Protokoll" %}{% endblock %}
{% block content %}
<div class="report-content">
<div class="card">
<div class="card-header d-flex justify-content-between align-items-center">
<h3>{% trans "Report-Protokoll" %}</h3>
<div class="header-actions">
<span class="badge badge-info">{{ report_logs|length }} {% trans "Einträge" %}</span>
</div>
</div>
<div class="card-body">
{% if report_logs %}
<div class="table-responsive">
<table class="table table-striped table-hover">
<thead class="thead-light">
<tr>
<th>{% trans "Datum/Zeit" %}</th>
<th>{% trans "Typ" %}</th>
<th>{% trans "Name" %}</th>
<th>{% trans "Zeitraum" %}</th>
<th>{% trans "Anzahl Patienten" %}</th>
<th>{% trans "E-Mail gesendet an" %}</th>
<th>{% trans "Status" %}</th>
<th>{% trans "Aktionen" %}</th>
</tr>
</thead>
<tbody>
{% for log in report_logs %}
<tr>
<td>
<div class="datetime-cell">
<div class="date">{{ log.created_at|date:"d.m.Y" }}</div>
<div class="time text-muted">{{ log.created_at|time:"H:i" }}</div>
</div>
</td>
<td>
{% if log.automatic_report %}
<span class="badge badge-primary">
<i class="fas fa-clock"></i> {% trans "Automatisch" %}
</span>
{% else %}
<span class="badge badge-secondary">
<i class="fas fa-hand-paper"></i> {% trans "Manuell" %}
</span>
{% endif %}
</td>
<td>
{% if log.automatic_report %}
{{ log.automatic_report.name }}
{% else %}
{% trans "Manueller Report" %}
{% endif %}
</td>
<td>
<div class="date-range">
<div>{{ log.date_from|date:"d.m.Y" }}</div>
<div class="text-muted">{% trans "bis" %}</div>
<div>{{ log.date_to|date:"d.m.Y" }}</div>
</div>
</td>
<td>
<span class="patient-count">{{ log.patient_count }}</span>
</td>
<td>
{% if log.email_sent_to %}
<div class="email-list">
{% for email in log.email_sent_to %}
<span class="email-badge">{{ email }}</span>
{% endfor %}
</div>
{% else %}
<span class="text-muted">{% trans "Download" %}</span>
{% endif %}
</td>
<td>
{% if log.email_sent_to %}
<span class="badge badge-success">
<i class="fas fa-envelope"></i> {% trans "Gesendet" %}
</span>
{% else %}
<span class="badge badge-info">
<i class="fas fa-download"></i> {% trans "Heruntergeladen" %}
</span>
{% endif %}
</td>
<td>
<div class="action-buttons">
{% if log.csv_file %}
<a href="{{ log.csv_file.url }}" class="btn btn-sm btn-outline-primary" title="{% trans 'CSV herunterladen' %}">
<i class="fas fa-download"></i>
</a>
{% endif %}
<button class="btn btn-sm btn-outline-info"
onclick="showReportDetails({{ log.id }})"
title="{% trans 'Details anzeigen' %}">
<i class="fas fa-eye"></i>
</button>
</div>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<!-- Pagination (falls notwendig) -->
{% if is_paginated %}
<nav aria-label="Report log pagination">
<ul class="pagination justify-content-center">
{% if page_obj.has_previous %}
<li class="page-item">
<a class="page-link" href="?page={{ page_obj.previous_page_number }}">
<i class="fas fa-chevron-left"></i>
</a>
</li>
{% endif %}
{% for num in page_obj.paginator.page_range %}
{% if page_obj.number == num %}
<li class="page-item active">
<span class="page-link">{{ num }}</span>
</li>
{% elif num > page_obj.number|add:'-3' and num < page_obj.number|add:'3' %}
<li class="page-item">
<a class="page-link" href="?page={{ num }}">{{ num }}</a>
</li>
{% endif %}
{% endfor %}
{% if page_obj.has_next %}
<li class="page-item">
<a class="page-link" href="?page={{ page_obj.next_page_number }}">
<i class="fas fa-chevron-right"></i>
</a>
</li>
{% endif %}
</ul>
</nav>
{% endif %}
{% else %}
<div class="empty-state">
<div class="text-center py-5">
<i class="fas fa-file-alt fa-3x text-muted mb-3"></i>
<h4 class="text-muted">{% trans "Noch keine Reports erstellt" %}</h4>
<p class="text-muted">{% trans "Erstellen Sie Ihren ersten Report über das Dashboard." %}</p>
<a href="{% url 'reports:dashboard' %}" class="btn btn-primary">
<i class="fas fa-plus"></i> {% trans "Report erstellen" %}
</a>
</div>
</div>
{% endif %}
</div>
</div>
</div>
<!-- Report Details Modal -->
<div class="modal fade" id="reportDetailsModal" tabindex="-1" role="dialog">
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">{% trans "Report-Details" %}</h5>
<button type="button" class="close" data-dismiss="modal">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<div id="reportDetailsContent">
<!-- Content wird via JavaScript geladen -->
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">
{% trans "Schließen" %}
</button>
</div>
</div>
</div>
</div>
<style>
.datetime-cell .date {
font-weight: 500;
}
.datetime-cell .time {
font-size: 0.875em;
}
.date-range {
text-align: center;
}
.patient-count {
font-weight: 600;
color: #007bff;
}
.email-list {
max-width: 200px;
}
.email-badge {
display: inline-block;
background-color: #e9ecef;
color: #495057;
padding: 2px 6px;
border-radius: 3px;
font-size: 0.8em;
margin: 1px;
}
.action-buttons {
display: flex;
gap: 5px;
}
.empty-state {
min-height: 300px;
display: flex;
align-items: center;
justify-content: center;
}
.badge {
font-size: 0.75em;
padding: 4px 8px;
}
.badge-primary {
background-color: #007bff;
}
.badge-secondary {
background-color: #6c757d;
}
.badge-success {
background-color: #28a745;
}
.badge-info {
background-color: #17a2b8;
}
</style>
<script>
function showReportDetails(logId) {
// Placeholder für AJAX-Aufruf zum Laden der Report-Details
// In einer vollständigen Implementierung würde hier ein AJAX-Request
// an eine entsprechende View gemacht werden
const modal = $('#reportDetailsModal');
const content = $('#reportDetailsContent');
content.html(`
<div class="text-center">
<i class="fas fa-spinner fa-spin fa-2x"></i>
<p class="mt-2">{% trans "Lade Details..." %}</p>
</div>
`);
modal.modal('show');
// Simulierter Inhalt (in echter Implementierung via AJAX)
setTimeout(() => {
content.html(`
<div class="alert alert-info">
<strong>{% trans "Hinweis:" %}</strong>
{% trans "Die Detail-Ansicht wird in einer zukünftigen Version implementiert." %}
</div>
`);
}, 1000);
}
</script>
{% endblock %}