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 %}

View file

@ -0,0 +1,32 @@
{% load i18n %}{% autoescape off %}
Hallo,
anbei erhalten Sie den angeforderten Report der Wildvogelhilfe Jena.
Report-Details:
- Zeitraum: {{ date_from }} bis {{ date_to }}
- Anzahl Patienten: {{ patient_count }}
{% if filter_naturschutzbehörde and filter_jagdbehörde %}
- Filter: Naturschutzbehörde und Jagdbehörde
{% elif filter_naturschutzbehörde %}
- Filter: Nur Naturschutzbehörde
{% elif filter_jagdbehörde %}
- Filter: Nur Jagdbehörde
{% endif %}
{% if automatic_report %}
- Automatischer Report: {{ automatic_report.name }}
{% else %}
- Report-Typ: Manuell erstellt
{% endif %}
Der Report liegt als CSV-Datei im Anhang bei und kann in Excel oder anderen Tabellenkalkulationsprogrammen geöffnet werden.
Bei Fragen zum Report wenden Sie sich bitte an das Team der Wildvogelhilfe Jena.
Mit freundlichen Grüßen
Wildvogelhilfe Jena e.V.
---
Diese E-Mail wurde automatisch generiert.
Erstellt am: {{ created_at }}
{% endautoescape %}

View file

@ -0,0 +1 @@
{% load i18n %}{% autoescape off %}{% blocktrans with site_name=current_site.name %}Wildvogelhilfe Jena Report von {{ date_from }} bis {{ date_to }}{% endblocktrans %}{% endautoescape %}