Replaces the old multi-card layout (1368 lines) with a compact, modern tabbed interface (Stammdaten | Nachweise | Zahlungen | Timeline | Dokumente | Notizen). All information is now accessible from one page without excessive clicking. - Add timeline events to destinataer_detail view (merged from timeline view logic) - Compact profile header with avatar initials, status badges, key contact info - Inline editing preserved with table-based layout for cleaner data display - Tab state persisted in URL hash for bookmarkable deep links - Dropdown menu for less-used actions (export, archive, delete) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
847 lines
57 KiB
HTML
847 lines
57 KiB
HTML
{% extends 'base.html' %}
|
||
{% load static %}
|
||
|
||
{% block title %}{{ destinataer.get_full_name }} - Destinataer{% endblock %}
|
||
|
||
{% block content %}
|
||
<div class="container-fluid px-4">
|
||
|
||
{# ── Profile Header ── #}
|
||
<div class="card shadow-sm mb-4 border-0" style="background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);">
|
||
<div class="card-body py-3">
|
||
<div class="row align-items-center">
|
||
<div class="col-auto">
|
||
<div class="rounded-circle bg-primary text-white d-flex align-items-center justify-content-center" style="width:56px;height:56px;font-size:1.4rem;">
|
||
{{ destinataer.vorname|first }}{{ destinataer.nachname|first }}
|
||
</div>
|
||
</div>
|
||
<div class="col">
|
||
<h4 class="mb-1">
|
||
{{ destinataer.get_full_name }}
|
||
{% if destinataer.aktiv %}
|
||
<span class="badge bg-success ms-2" style="font-size:.65rem;vertical-align:middle;">Aktiv</span>
|
||
{% else %}
|
||
<span class="badge bg-secondary ms-2" style="font-size:.65rem;vertical-align:middle;">Inaktiv</span>
|
||
{% endif %}
|
||
{% if destinataer.finanzielle_notlage %}
|
||
<span class="badge bg-danger ms-1" style="font-size:.65rem;vertical-align:middle;"><i class="fas fa-exclamation-triangle me-1"></i>Notlage</span>
|
||
{% endif %}
|
||
</h4>
|
||
<div class="text-muted small">
|
||
{% if destinataer.familienzweig %}<span class="me-3"><i class="fas fa-sitemap me-1"></i>{{ destinataer.get_familienzweig_display }}</span>{% endif %}
|
||
{% if destinataer.email %}<span class="me-3"><i class="fas fa-envelope me-1"></i><a href="mailto:{{ destinataer.email }}">{{ destinataer.email }}</a></span>{% endif %}
|
||
{% if destinataer.telefon %}<span class="me-3"><i class="fas fa-phone me-1"></i>{{ destinataer.telefon }}</span>{% endif %}
|
||
{% if destinataer.iban %}<span class="me-3"><i class="fas fa-university me-1"></i>{{ destinataer.iban }}</span>{% endif %}
|
||
</div>
|
||
</div>
|
||
<div class="col-auto">
|
||
{% if destinataer.vierteljaehrlicher_betrag %}
|
||
<div class="text-end">
|
||
<div class="text-muted small">Quartalsbetrag</div>
|
||
<div class="h5 text-success mb-0">€{{ destinataer.vierteljaehrlicher_betrag|floatformat:2 }}</div>
|
||
</div>
|
||
{% endif %}
|
||
</div>
|
||
<div class="col-auto">
|
||
<div class="btn-group">
|
||
<button id="edit-btn" class="btn btn-outline-primary btn-sm" onclick="enableEditMode()">
|
||
<i class="fas fa-pen me-1"></i>Bearbeiten
|
||
</button>
|
||
<button id="save-btn" class="btn btn-success btn-sm" onclick="saveChanges()" style="display:none;">
|
||
<i class="fas fa-save me-1"></i>Speichern
|
||
</button>
|
||
<button id="cancel-btn" class="btn btn-outline-secondary btn-sm" onclick="cancelEdit()" style="display:none;">
|
||
<i class="fas fa-times"></i>
|
||
</button>
|
||
</div>
|
||
<a href="{% url 'stiftung:unterstuetzung_create' %}?destinataer={{ destinataer.pk }}" class="btn btn-success btn-sm ms-1">
|
||
<i class="fas fa-heart me-1"></i>Zahlung
|
||
</a>
|
||
<div class="btn-group ms-1">
|
||
<button class="btn btn-outline-secondary btn-sm dropdown-toggle" data-bs-toggle="dropdown">
|
||
<i class="fas fa-ellipsis-v"></i>
|
||
</button>
|
||
<ul class="dropdown-menu dropdown-menu-end">
|
||
<li><a class="dropdown-item" href="{% url 'stiftung:destinataer_export' pk=destinataer.pk %}"><i class="fas fa-download me-2"></i>Export</a></li>
|
||
<li>
|
||
<form method="post" action="{% url 'stiftung:destinataer_toggle_archiv' pk=destinataer.pk %}" class="d-inline">
|
||
{% csrf_token %}
|
||
{% if destinataer.aktiv %}
|
||
<button type="submit" class="dropdown-item" onclick="return confirm('Destinataer archivieren?')">
|
||
<i class="fas fa-archive me-2"></i>Archivieren
|
||
</button>
|
||
{% else %}
|
||
<button type="submit" class="dropdown-item" onclick="return confirm('Destinataer reaktivieren?')">
|
||
<i class="fas fa-undo me-2"></i>Reaktivieren
|
||
</button>
|
||
{% endif %}
|
||
</form>
|
||
</li>
|
||
<li><hr class="dropdown-divider"></li>
|
||
<li><a class="dropdown-item text-danger" href="{% url 'stiftung:destinataer_delete' pk=destinataer.pk %}"><i class="fas fa-trash me-2"></i>Loeschen</a></li>
|
||
</ul>
|
||
</div>
|
||
<a href="{% url 'stiftung:destinataer_list' %}" class="btn btn-outline-secondary btn-sm ms-1" title="Zurueck">
|
||
<i class="fas fa-arrow-left"></i>
|
||
</a>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
{# ── Tab Navigation ── #}
|
||
<ul class="nav nav-tabs mb-3" id="destTabs" role="tablist">
|
||
<li class="nav-item">
|
||
<button class="nav-link active" id="tab-stamm" data-bs-toggle="tab" data-bs-target="#pane-stamm" type="button">
|
||
<i class="fas fa-id-card me-1"></i>Stammdaten
|
||
</button>
|
||
</li>
|
||
<li class="nav-item">
|
||
<button class="nav-link" id="tab-nachweise" data-bs-toggle="tab" data-bs-target="#pane-nachweise" type="button">
|
||
<i class="fas fa-calendar-check me-1"></i>Nachweise
|
||
<span class="badge bg-primary ms-1">{{ quarterly_confirmations|length }}</span>
|
||
</button>
|
||
</li>
|
||
<li class="nav-item">
|
||
<button class="nav-link" id="tab-zahlungen" data-bs-toggle="tab" data-bs-target="#pane-zahlungen" type="button">
|
||
<i class="fas fa-money-bill-wave me-1"></i>Zahlungen
|
||
<span class="badge bg-success ms-1">{{ unterstuetzungen.count }}</span>
|
||
</button>
|
||
</li>
|
||
<li class="nav-item">
|
||
<button class="nav-link" id="tab-timeline" data-bs-toggle="tab" data-bs-target="#pane-timeline" type="button">
|
||
<i class="fas fa-stream me-1"></i>Timeline
|
||
</button>
|
||
</li>
|
||
<li class="nav-item">
|
||
<button class="nav-link" id="tab-dokumente" data-bs-toggle="tab" data-bs-target="#pane-dokumente" type="button">
|
||
<i class="fas fa-file-alt me-1"></i>Dokumente
|
||
<span class="badge bg-secondary ms-1">{{ verknuepfte_dokumente.count }}</span>
|
||
</button>
|
||
</li>
|
||
<li class="nav-item">
|
||
<button class="nav-link" id="tab-notizen" data-bs-toggle="tab" data-bs-target="#pane-notizen" type="button">
|
||
<i class="fas fa-sticky-note me-1"></i>Notizen
|
||
<span class="badge bg-secondary ms-1">{{ notizen_eintraege.count }}</span>
|
||
</button>
|
||
</li>
|
||
</ul>
|
||
|
||
{# ── Tab Content ── #}
|
||
<div class="tab-content" id="destTabContent">
|
||
|
||
{# ════════ TAB: Stammdaten ════════ #}
|
||
<div class="tab-pane fade show active" id="pane-stamm" role="tabpanel">
|
||
<form id="edit-form" method="post" action="{% url 'stiftung:destinataer_update' pk=destinataer.pk %}" style="display:contents;">
|
||
{% csrf_token %}
|
||
<div class="row g-3">
|
||
{# Left column – Personal + Contact #}
|
||
<div class="col-lg-6">
|
||
<div class="card shadow-sm mb-3">
|
||
<div class="card-header py-2"><i class="fas fa-user me-2 text-primary"></i><strong>Persoenliche Daten</strong></div>
|
||
<div class="card-body py-2">
|
||
<table class="table table-sm table-borderless mb-0">
|
||
<tbody>
|
||
<tr>
|
||
<td class="text-muted" style="width:140px;">Vorname</td>
|
||
<td>
|
||
<span class="view-mode">{{ destinataer.vorname }}</span>
|
||
<input type="text" name="vorname" value="{{ destinataer.vorname }}" class="form-control form-control-sm edit-mode" style="display:none;" required>
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="text-muted">Nachname</td>
|
||
<td>
|
||
<span class="view-mode">{{ destinataer.nachname }}</span>
|
||
<input type="text" name="nachname" value="{{ destinataer.nachname }}" class="form-control form-control-sm edit-mode" style="display:none;" required>
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="text-muted">Geburtsdatum</td>
|
||
<td>
|
||
<span class="view-mode">{% if destinataer.geburtsdatum %}{{ destinataer.geburtsdatum|date:"d.m.Y" }}{% else %}<em class="text-muted">-</em>{% endif %}</span>
|
||
<input type="date" name="geburtsdatum" value="{% if destinataer.geburtsdatum %}{{ destinataer.geburtsdatum|date:'Y-m-d' }}{% endif %}" class="form-control form-control-sm edit-mode" style="display:none;">
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="text-muted">Familienzweig</td>
|
||
<td>
|
||
<span class="view-mode"><span class="badge bg-info">{{ destinataer.get_familienzweig_display|default:"-" }}</span></span>
|
||
<select name="familienzweig" class="form-select form-select-sm edit-mode" style="display:none;">
|
||
<option value="">---</option>
|
||
<option value="hauptzweig" {% if destinataer.familienzweig == 'hauptzweig' %}selected{% endif %}>Hauptzweig</option>
|
||
<option value="nebenzweig" {% if destinataer.familienzweig == 'nebenzweig' %}selected{% endif %}>Nebenzweig</option>
|
||
<option value="verwandt" {% if destinataer.familienzweig == 'verwandt' %}selected{% endif %}>Verwandt</option>
|
||
<option value="anderer" {% if destinataer.familienzweig == 'anderer' %}selected{% endif %}>Anderer</option>
|
||
</select>
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="text-muted">Berufsgruppe</td>
|
||
<td>
|
||
<span class="view-mode"><span class="badge bg-secondary">{{ destinataer.get_berufsgruppe_display|default:"-" }}</span></span>
|
||
<select name="berufsgruppe" class="form-select form-select-sm edit-mode" style="display:none;">
|
||
<option value="">---</option>
|
||
<option value="student" {% if destinataer.berufsgruppe == 'student' %}selected{% endif %}>Student/Studentin</option>
|
||
<option value="wissenschaftler" {% if destinataer.berufsgruppe == 'wissenschaftler' %}selected{% endif %}>Wissenschaftler/in</option>
|
||
<option value="kuenstler" {% if destinataer.berufsgruppe == 'künstler' %}selected{% endif %}>Kuenstler/in</option>
|
||
<option value="sozialarbeiter" {% if destinataer.berufsgruppe == 'sozialarbeiter' %}selected{% endif %}>Sozialarbeiter/in</option>
|
||
<option value="umweltschuetzer" {% if destinataer.berufsgruppe == 'umweltschützer' %}selected{% endif %}>Umweltschuetzer/in</option>
|
||
<option value="andere" {% if destinataer.berufsgruppe == 'andere' %}selected{% endif %}>Andere</option>
|
||
</select>
|
||
</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="card shadow-sm mb-3">
|
||
<div class="card-header py-2"><i class="fas fa-address-book me-2 text-info"></i><strong>Kontakt & Adresse</strong></div>
|
||
<div class="card-body py-2">
|
||
<table class="table table-sm table-borderless mb-0">
|
||
<tbody>
|
||
<tr>
|
||
<td class="text-muted" style="width:140px;">E-Mail</td>
|
||
<td>
|
||
<span class="view-mode">{% if destinataer.email %}<a href="mailto:{{ destinataer.email }}">{{ destinataer.email }}</a>{% else %}<em class="text-muted">-</em>{% endif %}</span>
|
||
<input type="email" name="email" value="{{ destinataer.email|default:'' }}" class="form-control form-control-sm edit-mode" style="display:none;">
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="text-muted">Telefon</td>
|
||
<td>
|
||
<span class="view-mode">{{ destinataer.telefon|default:"<em class='text-muted'>-</em>" }}</span>
|
||
<input type="tel" name="telefon" value="{{ destinataer.telefon|default:'' }}" class="form-control form-control-sm edit-mode" style="display:none;">
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="text-muted">IBAN</td>
|
||
<td>
|
||
<span class="view-mode">{{ destinataer.iban|default:"<em class='text-muted'>-</em>" }}</span>
|
||
<input type="text" name="iban" value="{{ destinataer.iban|default:'' }}" class="form-control form-control-sm edit-mode" style="display:none;">
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="text-muted">Strasse</td>
|
||
<td>
|
||
<span class="view-mode">{{ destinataer.strasse|default:"<em class='text-muted'>-</em>" }}</span>
|
||
<input name="strasse" value="{{ destinataer.strasse|default:'' }}" class="form-control form-control-sm edit-mode" style="display:none;">
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="text-muted">PLZ / Ort</td>
|
||
<td>
|
||
<span class="view-mode">{% if destinataer.plz or destinataer.ort %}{{ destinataer.plz }} {{ destinataer.ort }}{% else %}<em class="text-muted">-</em>{% endif %}</span>
|
||
<div class="edit-mode" style="display:none;">
|
||
<div class="row g-2">
|
||
<div class="col-4"><input name="plz" value="{{ destinataer.plz|default:'' }}" class="form-control form-control-sm" placeholder="PLZ"></div>
|
||
<div class="col-8"><input name="ort" value="{{ destinataer.ort|default:'' }}" class="form-control form-control-sm" placeholder="Ort"></div>
|
||
</div>
|
||
</div>
|
||
</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
{# Right column – Financial + Study #}
|
||
<div class="col-lg-6">
|
||
<div class="card shadow-sm mb-3">
|
||
<div class="card-header py-2"><i class="fas fa-euro-sign me-2 text-warning"></i><strong>Finanzen & Foerderung</strong></div>
|
||
<div class="card-body py-2">
|
||
<table class="table table-sm table-borderless mb-0">
|
||
<tbody>
|
||
<tr>
|
||
<td class="text-muted" style="width:180px;">Quartalsbetrag</td>
|
||
<td>
|
||
<span class="view-mode fw-bold text-success">{% if destinataer.vierteljaehrlicher_betrag %}€{{ destinataer.vierteljaehrlicher_betrag|floatformat:2 }}{% else %}-{% endif %}</span>
|
||
<input type="number" name="vierteljaehrlicher_betrag" value="{{ destinataer.vierteljaehrlicher_betrag|default:'' }}" class="form-control form-control-sm edit-mode" style="display:none;" step="0.01">
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="text-muted">Monatliche Bezuege</td>
|
||
<td>
|
||
<span class="view-mode">{% if destinataer.monatliche_bezuege %}€{{ destinataer.monatliche_bezuege|floatformat:2 }}{% else %}-{% endif %}</span>
|
||
<input type="number" name="monatliche_bezuege" value="{{ destinataer.monatliche_bezuege|default:'' }}" class="form-control form-control-sm edit-mode" style="display:none;" step="0.01">
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="text-muted">Jaehrliches Einkommen</td>
|
||
<td>
|
||
<span class="view-mode">{% if destinataer.jaehrliches_einkommen %}€{{ destinataer.jaehrliches_einkommen|floatformat:2 }}{% else %}-{% endif %}</span>
|
||
<input type="number" name="jaehrliches_einkommen" value="{{ destinataer.jaehrliches_einkommen|default:'' }}" class="form-control form-control-sm edit-mode" style="display:none;" step="0.01">
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="text-muted">Vermoegen</td>
|
||
<td>
|
||
<span class="view-mode">{% if destinataer.vermoegen %}€{{ destinataer.vermoegen|floatformat:2 }}{% else %}-{% endif %}</span>
|
||
<input type="number" name="vermoegen" value="{{ destinataer.vermoegen|default:'' }}" class="form-control form-control-sm edit-mode" style="display:none;" step="0.01">
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="text-muted">Haushaltsgroesse</td>
|
||
<td>
|
||
<span class="view-mode">{{ destinataer.haushaltsgroesse|default:"-" }}</span>
|
||
<input type="number" name="haushaltsgroesse" value="{{ destinataer.haushaltsgroesse }}" class="form-control form-control-sm edit-mode" style="display:none;" min="1">
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="text-muted">Standardkonto</td>
|
||
<td>
|
||
<span class="view-mode">{{ destinataer.standard_konto|default:"-" }}</span>
|
||
<select name="standard_konto" class="form-select form-select-sm edit-mode" style="display:none;">
|
||
<option value="">---</option>
|
||
{% for konto in stiftungskonten %}
|
||
<option value="{{ konto.pk }}" {% if destinataer.standard_konto_id == konto.pk %}selected{% endif %}>{{ konto.kontoname }}</option>
|
||
{% endfor %}
|
||
</select>
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="text-muted">Finanzielle Notlage</td>
|
||
<td>
|
||
<span class="view-mode">
|
||
{% if destinataer.finanzielle_notlage %}<span class="badge bg-danger">Ja</span>{% else %}<span class="badge bg-success">Nein</span>{% endif %}
|
||
</span>
|
||
<div class="edit-mode" style="display:none;">
|
||
<div class="form-check"><input type="checkbox" name="finanzielle_notlage" id="finanzielle_notlage" class="form-check-input" {% if destinataer.finanzielle_notlage %}checked{% endif %}><label class="form-check-label" for="finanzielle_notlage">Ja</label></div>
|
||
</div>
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="text-muted">Unterstuetzung bestaetigt</td>
|
||
<td>
|
||
<span class="view-mode">
|
||
{% if destinataer.unterstuetzung_bestaetigt %}<span class="badge bg-success">Ja</span>{% else %}<span class="badge bg-secondary">Nein</span>{% endif %}
|
||
</span>
|
||
<div class="edit-mode" style="display:none;">
|
||
<div class="form-check"><input type="checkbox" name="unterstuetzung_bestaetigt" id="unterstuetzung_bestaetigt" class="form-check-input" {% if destinataer.unterstuetzung_bestaetigt %}checked{% endif %}><label class="form-check-label" for="unterstuetzung_bestaetigt">Ja</label></div>
|
||
</div>
|
||
</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="card shadow-sm mb-3">
|
||
<div class="card-header py-2"><i class="fas fa-graduation-cap me-2 text-secondary"></i><strong>Studium & Voraussetzungen</strong></div>
|
||
<div class="card-body py-2">
|
||
<table class="table table-sm table-borderless mb-0">
|
||
<tbody>
|
||
<tr>
|
||
<td class="text-muted" style="width:180px;">Abkoemmling gem. Satzung</td>
|
||
<td>
|
||
<span class="view-mode">{% if destinataer.ist_abkoemmling %}<span class="badge bg-success">Ja</span>{% else %}<span class="badge bg-secondary">Nein</span>{% endif %}</span>
|
||
<div class="edit-mode" style="display:none;">
|
||
<div class="form-check"><input type="checkbox" name="ist_abkoemmling" id="ist_abkoemmling" class="form-check-input" {% if destinataer.ist_abkoemmling %}checked{% endif %}><label class="form-check-label" for="ist_abkoemmling">Ja</label></div>
|
||
</div>
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="text-muted">Ausbildungsstand</td>
|
||
<td>
|
||
<span class="view-mode">{{ destinataer.ausbildungsstand|default:"-" }}</span>
|
||
<input name="ausbildungsstand" value="{{ destinataer.ausbildungsstand|default:'' }}" class="form-control form-control-sm edit-mode" style="display:none;">
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="text-muted">Institution</td>
|
||
<td>
|
||
<span class="view-mode">{{ destinataer.institution|default:"-" }}</span>
|
||
<input name="institution" value="{{ destinataer.institution|default:'' }}" class="form-control form-control-sm edit-mode" style="display:none;">
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="text-muted">Studiennachweis erf.</td>
|
||
<td>
|
||
<span class="view-mode">{% if destinataer.studiennachweis_erforderlich %}<span class="badge bg-info">Ja</span>{% else %}<span class="badge bg-secondary">Nein</span>{% endif %}</span>
|
||
<div class="edit-mode" style="display:none;">
|
||
<div class="form-check"><input type="checkbox" name="studiennachweis_erforderlich" id="studiennachweis_erforderlich" class="form-check-input" {% if destinataer.studiennachweis_erforderlich %}checked{% endif %}><label class="form-check-label" for="studiennachweis_erforderlich">Ja</label></div>
|
||
</div>
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="text-muted">Letzter Nachweis</td>
|
||
<td>
|
||
<span class="view-mode">{% if destinataer.letzter_studiennachweis %}{{ destinataer.letzter_studiennachweis|date:"d.m.Y" }}{% else %}-{% endif %}</span>
|
||
<input type="date" name="letzter_studiennachweis" value="{% if destinataer.letzter_studiennachweis %}{{ destinataer.letzter_studiennachweis|date:'Y-m-d' }}{% endif %}" class="form-control form-control-sm edit-mode" style="display:none;">
|
||
</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
|
||
{# Projektbeschreibung + Notizen #}
|
||
<div class="card shadow-sm mb-3">
|
||
<div class="card-header py-2"><i class="fas fa-sticky-note me-2 text-secondary"></i><strong>Beschreibung & Notizen</strong></div>
|
||
<div class="card-body py-2">
|
||
<div class="mb-2">
|
||
<small class="text-muted">Projektbeschreibung</small>
|
||
<div class="view-mode">{% if destinataer.projekt_beschreibung %}{{ destinataer.projekt_beschreibung|linebreaks }}{% else %}<em class="text-muted">-</em>{% endif %}</div>
|
||
<textarea name="projekt_beschreibung" class="form-control form-control-sm edit-mode" style="display:none;" rows="3">{{ destinataer.projekt_beschreibung|default:'' }}</textarea>
|
||
</div>
|
||
<div>
|
||
<small class="text-muted">Notizen</small>
|
||
<div class="view-mode">{% if destinataer.notizen %}{{ destinataer.notizen|linebreaks }}{% else %}<em class="text-muted">-</em>{% endif %}</div>
|
||
<textarea name="notizen" class="form-control form-control-sm edit-mode" style="display:none;" rows="3">{{ destinataer.notizen|default:'' }}</textarea>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
{# Hidden fields for edit form #}
|
||
<div class="edit-mode" style="display:none;">
|
||
<div class="form-check mb-2"><input type="checkbox" name="aktiv" id="aktiv_edit" class="form-check-input" {% if destinataer.aktiv %}checked{% endif %}><label class="form-check-label" for="aktiv_edit">Aktiv</label></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</form>
|
||
</div>
|
||
|
||
{# ════════ TAB: Nachweise ════════ #}
|
||
<div class="tab-pane fade" id="pane-nachweise" role="tabpanel">
|
||
<div class="d-flex justify-content-between align-items-center mb-3">
|
||
<div>
|
||
<small class="text-muted">Studiennachweis: 15. Maerz / 15. September | Zahlung: vierteljaehrlich im Voraus</small>
|
||
</div>
|
||
<button type="button" class="btn btn-primary btn-sm" data-bs-toggle="modal" data-bs-target="#addQuarterModal">
|
||
<i class="fas fa-plus me-1"></i>Quartal hinzufuegen
|
||
</button>
|
||
</div>
|
||
{% if quarterly_confirmations %}
|
||
<div class="table-responsive">
|
||
<table class="table table-hover table-sm align-middle">
|
||
<thead class="table-light">
|
||
<tr>
|
||
<th style="width:80px;">Zeitraum</th>
|
||
<th style="width:100px;">Status</th>
|
||
<th style="width:70px;">Fortschritt</th>
|
||
<th style="width:120px;">Fristen</th>
|
||
<th style="width:40px;text-align:center;" title="Studiennachweis"><i class="fas fa-graduation-cap"></i></th>
|
||
<th style="width:40px;text-align:center;" title="Einkommen"><i class="fas fa-euro-sign"></i></th>
|
||
<th style="width:40px;text-align:center;" title="Vermoegen"><i class="fas fa-piggy-bank"></i></th>
|
||
<th style="width:100px;">Aktionen</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
{% for nachweis in quarterly_confirmations %}
|
||
<tr {% if nachweis.is_overdue %}class="table-warning"{% endif %}>
|
||
<td>
|
||
<strong>{{ nachweis.jahr }} Q{{ nachweis.quartal }}</strong>
|
||
{% if nachweis.is_overdue %}<br><small class="text-danger"><i class="fas fa-exclamation-triangle"></i></small>{% endif %}
|
||
</td>
|
||
<td>
|
||
{% if nachweis.status == 'offen' %}<span class="badge bg-secondary">Offen</span>
|
||
{% elif nachweis.status == 'teilweise' %}<span class="badge bg-warning">Teilweise</span>
|
||
{% elif nachweis.status == 'eingereicht' %}<span class="badge bg-info">Eingereicht</span>
|
||
{% elif nachweis.status == 'geprueft' %}<span class="badge bg-success">Freigegeben</span>
|
||
{% elif nachweis.status == 'auto_geprueft' %}<span class="badge bg-success"><i class="fas fa-magic"></i> Auto</span>
|
||
{% elif nachweis.status == 'nachbesserung' %}<span class="badge bg-warning">Nachbesserung</span>
|
||
{% elif nachweis.status == 'abgelehnt' %}<span class="badge bg-danger">Abgelehnt</span>
|
||
{% endif %}
|
||
</td>
|
||
<td>
|
||
{% with completion=nachweis.get_completion_percentage %}
|
||
<div class="progress" style="height:18px;" title="{{ completion }}%">
|
||
<div class="progress-bar {% if completion == 100 %}bg-success{% elif completion >= 70 %}bg-info{% elif completion >= 30 %}bg-warning{% else %}bg-danger{% endif %}"
|
||
style="width:{{ completion }}%" role="progressbar">{{ completion }}%</div>
|
||
</div>
|
||
{% endwith %}
|
||
</td>
|
||
<td>
|
||
<div class="small" style="line-height:1.4;">
|
||
{% if nachweis.studiennachweis_faelligkeitsdatum %}
|
||
<div class="mb-1"><i class="fas fa-graduation-cap text-primary"></i>
|
||
<span class="{% if nachweis.is_study_proof_overdue %}text-danger fw-bold{% endif %}">{{ nachweis.studiennachweis_faelligkeitsdatum|date:"d.m.Y" }}</span>
|
||
{% if nachweis.is_study_proof_overdue %}<i class="fas fa-exclamation-triangle text-danger"></i>{% endif %}
|
||
</div>
|
||
{% endif %}
|
||
{% if nachweis.zahlung_faelligkeitsdatum %}
|
||
<div><i class="fas fa-euro-sign text-success"></i>
|
||
<span class="{% if nachweis.is_payment_overdue %}text-danger fw-bold{% endif %}">{{ nachweis.zahlung_faelligkeitsdatum|date:"d.m.Y" }}</span>
|
||
{% if nachweis.is_payment_overdue %}<i class="fas fa-exclamation-triangle text-danger"></i>{% endif %}
|
||
</div>
|
||
{% endif %}
|
||
</div>
|
||
</td>
|
||
<td class="text-center">
|
||
{% if nachweis.studiennachweis_eingereicht %}
|
||
{% if nachweis.studiennachweis_datei %}<a href="{{ nachweis.studiennachweis_datei.url }}" target="_blank" class="text-success"><i class="fas fa-file-pdf"></i></a>
|
||
{% elif nachweis.studiennachweis_bemerkung %}<i class="fas fa-comment text-info"></i>
|
||
{% else %}<i class="fas fa-check text-success"></i>{% endif %}
|
||
{% else %}<i class="fas fa-times text-muted"></i>{% endif %}
|
||
</td>
|
||
<td class="text-center">
|
||
{% if nachweis.einkommenssituation_bestaetigt %}
|
||
{% if nachweis.einkommenssituation_datei %}<a href="{{ nachweis.einkommenssituation_datei.url }}" target="_blank" class="text-success"><i class="fas fa-file-pdf"></i></a>
|
||
{% elif nachweis.einkommenssituation_text %}<i class="fas fa-comment text-info" title="{{ nachweis.einkommenssituation_text|truncatechars:50 }}"></i>
|
||
{% else %}<i class="fas fa-check text-success"></i>{% endif %}
|
||
{% else %}<i class="fas fa-times text-muted"></i>{% endif %}
|
||
</td>
|
||
<td class="text-center">
|
||
{% if nachweis.vermogenssituation_bestaetigt %}
|
||
{% if nachweis.vermogenssituation_datei %}<a href="{{ nachweis.vermogenssituation_datei.url }}" target="_blank" class="text-success"><i class="fas fa-file-pdf"></i></a>
|
||
{% elif nachweis.vermogenssituation_text %}<i class="fas fa-comment text-info" title="{{ nachweis.vermogenssituation_text|truncatechars:50 }}"></i>
|
||
{% else %}<i class="fas fa-check text-success"></i>{% endif %}
|
||
{% else %}<i class="fas fa-times text-muted"></i>{% endif %}
|
||
</td>
|
||
<td>
|
||
<div class="btn-group btn-group-sm">
|
||
<a href="{% url 'stiftung:quarterly_confirmation_edit' nachweis.id %}" class="btn btn-outline-primary btn-sm" title="Bearbeiten"><i class="fas fa-edit"></i></a>
|
||
{% if user.is_staff %}
|
||
{% if nachweis.status == 'eingereicht' %}
|
||
<button type="button" class="btn btn-outline-success btn-sm" onclick="approveQuarterly('{{ nachweis.id }}')" title="Freigeben"><i class="fas fa-check"></i></button>
|
||
{% elif nachweis.status == 'geprueft' %}
|
||
<button type="button" class="btn btn-outline-success btn-sm" onclick="approveQuarterly('{{ nachweis.id }}')" title="Erneut freigeben"><i class="fas fa-sync"></i></button>
|
||
<button type="button" class="btn btn-outline-warning btn-sm" onclick="resetQuarterly('{{ nachweis.id }}')" title="Zuruecksetzen"><i class="fas fa-undo"></i></button>
|
||
{% endif %}
|
||
{% endif %}
|
||
</div>
|
||
</td>
|
||
</tr>
|
||
{% endfor %}
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
{% else %}
|
||
<div class="text-center py-4 text-muted">
|
||
<i class="fas fa-calendar-check fa-2x mb-2"></i>
|
||
<p>Keine Nachweise vorhanden.</p>
|
||
</div>
|
||
{% endif %}
|
||
</div>
|
||
|
||
{# ════════ TAB: Zahlungen ════════ #}
|
||
<div class="tab-pane fade" id="pane-zahlungen" role="tabpanel">
|
||
<div class="d-flex justify-content-end mb-3">
|
||
<a href="{% url 'stiftung:unterstuetzung_create' %}?destinataer={{ destinataer.pk }}" class="btn btn-success btn-sm">
|
||
<i class="fas fa-plus me-1"></i>Neue Unterstuetzung
|
||
</a>
|
||
</div>
|
||
{% if unterstuetzungen %}
|
||
<div class="table-responsive">
|
||
<table class="table table-hover table-sm align-middle">
|
||
<thead class="table-light">
|
||
<tr>
|
||
<th>Faellig am</th>
|
||
<th>Betrag</th>
|
||
<th>Status</th>
|
||
<th>Beschreibung</th>
|
||
<th></th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
{% for u in unterstuetzungen %}
|
||
<tr>
|
||
<td>{{ u.faellig_am|date:"d.m.Y" }}</td>
|
||
<td class="text-success fw-bold">€{{ u.betrag|floatformat:2 }}</td>
|
||
<td>
|
||
{% if u.status == 'ausgezahlt' %}<span class="badge bg-success">Ausgezahlt</span>
|
||
{% elif u.status == 'in_bearbeitung' %}<span class="badge bg-warning">In Bearbeitung</span>
|
||
{% elif u.status == 'geplant' %}<span class="badge bg-secondary">Geplant</span>
|
||
{% else %}<span class="badge bg-danger">{{ u.get_status_display }}</span>{% endif %}
|
||
</td>
|
||
<td>{{ u.beschreibung|truncatechars:50 }}</td>
|
||
<td><a href="{% url 'stiftung:unterstuetzung_detail' pk=u.pk %}" class="btn btn-sm btn-outline-primary"><i class="fas fa-eye"></i></a></td>
|
||
</tr>
|
||
{% endfor %}
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
{% else %}
|
||
<div class="text-center py-4 text-muted">
|
||
<i class="fas fa-money-bill-wave fa-2x mb-2"></i>
|
||
<p>Keine Zahlungen vorhanden.</p>
|
||
</div>
|
||
{% endif %}
|
||
|
||
{% if foerderungen %}
|
||
<h6 class="mt-4 mb-2"><i class="fas fa-gift me-1"></i>Foerderungen ({{ foerderungen.count }})</h6>
|
||
<div class="table-responsive">
|
||
<table class="table table-hover table-sm align-middle">
|
||
<thead class="table-light">
|
||
<tr><th>Jahr</th><th>Betrag</th><th>Kategorie</th><th>Status</th><th>Nachweis</th><th></th></tr>
|
||
</thead>
|
||
<tbody>
|
||
{% for f in foerderungen %}
|
||
<tr>
|
||
<td>{{ f.jahr }}</td>
|
||
<td class="text-success fw-bold">€{{ f.betrag|floatformat:2 }}</td>
|
||
<td>{{ f.get_kategorie_display }}</td>
|
||
<td>
|
||
{% if f.status == 'bewilligt' %}<span class="badge bg-success">Bewilligt</span>
|
||
{% elif f.status == 'abgelehnt' %}<span class="badge bg-danger">Abgelehnt</span>
|
||
{% elif f.status == 'in_bearbeitung' %}<span class="badge bg-warning">In Bearbeitung</span>
|
||
{% else %}<span class="badge bg-secondary">{{ f.get_status_display }}</span>{% endif %}
|
||
</td>
|
||
<td>{% if f.verwendungsnachweis %}<i class="fas fa-check text-success"></i>{% else %}<i class="fas fa-times text-muted"></i>{% endif %}</td>
|
||
<td><a href="{% url 'stiftung:foerderung_detail' pk=f.pk %}" class="btn btn-sm btn-outline-primary"><i class="fas fa-eye"></i></a></td>
|
||
</tr>
|
||
{% endfor %}
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
{% endif %}
|
||
</div>
|
||
|
||
{# ════════ TAB: Timeline ════════ #}
|
||
<div class="tab-pane fade" id="pane-timeline" role="tabpanel">
|
||
{% if timeline_events %}
|
||
<div class="timeline-list">
|
||
{% for event in timeline_events %}
|
||
<div class="d-flex align-items-start mb-3">
|
||
<div class="me-3 text-center" style="min-width:40px;">
|
||
<div class="rounded-circle bg-{{ event.farbe }} text-white d-inline-flex align-items-center justify-content-center" style="width:32px;height:32px;">
|
||
<i class="fas {{ event.icon }}" style="font-size:.75rem;"></i>
|
||
</div>
|
||
</div>
|
||
<div class="flex-grow-1 border-bottom pb-2">
|
||
<div class="d-flex justify-content-between">
|
||
<strong>{{ event.titel }}</strong>
|
||
<small class="text-muted">{{ event.datum|date:"d.m.Y" }}</small>
|
||
</div>
|
||
{% if event.beschreibung %}<div class="text-muted small">{{ event.beschreibung }}</div>{% endif %}
|
||
{% if event.status %}<span class="badge bg-{{ event.farbe }} mt-1" style="font-size:.7rem;">{{ event.status }}</span>{% endif %}
|
||
</div>
|
||
</div>
|
||
{% endfor %}
|
||
</div>
|
||
{% else %}
|
||
<div class="text-center py-4 text-muted">
|
||
<i class="fas fa-stream fa-2x mb-2"></i>
|
||
<p>Keine Ereignisse vorhanden.</p>
|
||
</div>
|
||
{% endif %}
|
||
</div>
|
||
|
||
{# ════════ TAB: Dokumente ════════ #}
|
||
<div class="tab-pane fade" id="pane-dokumente" role="tabpanel">
|
||
<div class="d-flex justify-content-end mb-3">
|
||
<a href="{% url 'stiftung:dokument_management' %}" class="btn btn-success btn-sm">
|
||
<i class="fas fa-plus me-1"></i>Dokument verknuepfen
|
||
</a>
|
||
</div>
|
||
{% if verknuepfte_dokumente %}
|
||
<div class="table-responsive">
|
||
<table class="table table-hover table-sm align-middle">
|
||
<thead class="table-light">
|
||
<tr><th>Dokument</th><th>Kontext</th><th>Beschreibung</th><th></th></tr>
|
||
</thead>
|
||
<tbody>
|
||
{% for d in verknuepfte_dokumente %}
|
||
<tr>
|
||
<td><strong>{{ d.titel }}</strong><br><small class="text-muted">ID: {{ d.paperless_document_id }}</small></td>
|
||
<td><span class="badge bg-secondary">{{ d.get_kontext_display }}</span></td>
|
||
<td>{{ d.beschreibung|default:"-"|truncatewords:10 }}</td>
|
||
<td>
|
||
<div class="btn-group btn-group-sm">
|
||
<a href="{{ d.get_paperless_url }}" target="_blank" class="btn btn-outline-primary" title="In Paperless oeffnen"><i class="fas fa-external-link-alt"></i></a>
|
||
<a href="{% url 'stiftung:dokument_update' d.pk %}" class="btn btn-outline-warning" title="Bearbeiten"><i class="fas fa-edit"></i></a>
|
||
<a href="{% url 'stiftung:dokument_delete' d.pk %}" class="btn btn-outline-danger" title="Loeschen"><i class="fas fa-unlink"></i></a>
|
||
</div>
|
||
</td>
|
||
</tr>
|
||
{% endfor %}
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
{% else %}
|
||
<div class="text-center py-4 text-muted">
|
||
<i class="fas fa-file-alt fa-2x mb-2"></i>
|
||
<p>Keine Dokumente verknuepft.</p>
|
||
</div>
|
||
{% endif %}
|
||
</div>
|
||
|
||
{# ════════ TAB: Notizen ════════ #}
|
||
<div class="tab-pane fade" id="pane-notizen" role="tabpanel">
|
||
<div class="d-flex justify-content-end mb-3">
|
||
<a class="btn btn-primary btn-sm" href="{% url 'stiftung:destinataer_notiz_create' pk=destinataer.pk %}">
|
||
<i class="fas fa-plus me-1"></i>Notiz hinzufuegen
|
||
</a>
|
||
</div>
|
||
{% if notizen_eintraege %}
|
||
<div class="list-group">
|
||
{% for n in notizen_eintraege %}
|
||
<div class="list-group-item py-2">
|
||
<div class="d-flex justify-content-between">
|
||
<div>
|
||
<strong>{{ n.erstellt_am|date:"d.m.Y H:i" }}</strong>
|
||
{% if n.erstellt_von %}<span class="text-muted">- {{ n.erstellt_von.username }}</span>{% endif %}
|
||
</div>
|
||
{% if n.datei %}<a href="{{ n.datei.url }}" target="_blank" class="btn btn-sm btn-outline-secondary"><i class="fas fa-paperclip"></i></a>{% endif %}
|
||
</div>
|
||
{% if n.titel %}<div class="mt-1"><em>{{ n.titel }}</em></div>{% endif %}
|
||
{% if n.text %}<div class="mt-1 small">{{ n.text|linebreaks }}</div>{% endif %}
|
||
</div>
|
||
{% endfor %}
|
||
</div>
|
||
{% else %}
|
||
<div class="text-center py-4 text-muted">
|
||
<i class="fas fa-sticky-note fa-2x mb-2"></i>
|
||
<p>Keine Notizen vorhanden.</p>
|
||
</div>
|
||
{% endif %}
|
||
</div>
|
||
|
||
</div>{# /tab-content #}
|
||
</div>
|
||
|
||
{# ── Add Quarter Modal ── #}
|
||
<div class="modal fade" id="addQuarterModal" tabindex="-1">
|
||
<div class="modal-dialog">
|
||
<div class="modal-content">
|
||
<div class="modal-header">
|
||
<h5 class="modal-title"><i class="fas fa-plus me-2"></i>Neues Quartal</h5>
|
||
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
||
</div>
|
||
<form method="post" action="{% url 'stiftung:quarterly_confirmation_create' destinataer.pk %}" id="addQuarterForm">
|
||
{% csrf_token %}
|
||
<div class="modal-body">
|
||
<div class="row">
|
||
<div class="col-6">
|
||
<label class="form-label">Jahr</label>
|
||
<select class="form-select" name="jahr" required>
|
||
{% for year in available_years %}
|
||
<option value="{{ year }}" {% if year == current_year %}selected{% endif %}>{{ year }}</option>
|
||
{% endfor %}
|
||
</select>
|
||
</div>
|
||
<div class="col-6">
|
||
<label class="form-label">Quartal</label>
|
||
<select class="form-select" name="quartal" required>
|
||
<option value="1">Q1</option>
|
||
<option value="2">Q2</option>
|
||
<option value="3">Q3</option>
|
||
<option value="4">Q4</option>
|
||
</select>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="modal-footer">
|
||
<button type="button" class="btn btn-secondary btn-sm" data-bs-dismiss="modal">Abbrechen</button>
|
||
<button type="submit" class="btn btn-primary btn-sm"><i class="fas fa-plus me-1"></i>Erstellen</button>
|
||
</div>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
{% endblock %}
|
||
|
||
{% block javascript %}
|
||
<style>
|
||
.edit-mode-active .view-mode { display: none !important; }
|
||
.edit-mode-active .edit-mode { display: block !important; }
|
||
.edit-notification { position: fixed; top: 20px; right: 20px; z-index: 1050; max-width: 300px; }
|
||
</style>
|
||
<script>
|
||
let originalFormData = {};
|
||
let isEditMode = false;
|
||
|
||
document.addEventListener('DOMContentLoaded', function() {
|
||
storeOriginalData();
|
||
// Restore active tab from URL hash
|
||
const hash = window.location.hash;
|
||
if (hash) {
|
||
const tab = document.querySelector(`[data-bs-target="${hash.replace('#','#pane-')}"]`);
|
||
if (tab) new bootstrap.Tab(tab).show();
|
||
}
|
||
// Save tab to URL hash
|
||
document.querySelectorAll('#destTabs button[data-bs-toggle="tab"]').forEach(btn => {
|
||
btn.addEventListener('shown.bs.tab', e => {
|
||
history.replaceState(null, null, '#' + e.target.dataset.bsTarget.replace('#pane-',''));
|
||
});
|
||
});
|
||
});
|
||
|
||
function storeOriginalData() {
|
||
const form = document.getElementById('edit-form');
|
||
if (!form) return;
|
||
const formData = new FormData(form);
|
||
originalFormData = {};
|
||
for (let [key, value] of formData.entries()) originalFormData[key] = value;
|
||
form.querySelectorAll('input[type="checkbox"]').forEach(cb => { originalFormData[cb.name] = cb.checked; });
|
||
}
|
||
|
||
function enableEditMode() {
|
||
isEditMode = true;
|
||
document.body.classList.add('edit-mode-active');
|
||
document.getElementById('edit-btn').style.display = 'none';
|
||
document.getElementById('save-btn').style.display = 'inline-block';
|
||
document.getElementById('cancel-btn').style.display = 'inline-block';
|
||
// Switch to Stammdaten tab
|
||
new bootstrap.Tab(document.getElementById('tab-stamm')).show();
|
||
showNotification('Bearbeitungsmodus aktiviert', 'info');
|
||
}
|
||
|
||
function cancelEdit() {
|
||
const form = document.getElementById('edit-form');
|
||
Object.keys(originalFormData).forEach(key => {
|
||
const el = form.querySelector(`[name="${key}"]`);
|
||
if (el) { el.type === 'checkbox' ? el.checked = originalFormData[key] : el.value = originalFormData[key] || ''; }
|
||
});
|
||
disableEditMode();
|
||
showNotification('Aenderungen verworfen', 'warning');
|
||
}
|
||
|
||
function disableEditMode() {
|
||
isEditMode = false;
|
||
document.body.classList.remove('edit-mode-active');
|
||
document.getElementById('edit-btn').style.display = 'inline-block';
|
||
document.getElementById('save-btn').style.display = 'none';
|
||
document.getElementById('cancel-btn').style.display = 'none';
|
||
}
|
||
|
||
function saveChanges() {
|
||
const form = document.getElementById('edit-form');
|
||
const formData = new FormData(form);
|
||
const saveBtn = document.getElementById('save-btn');
|
||
const orig = saveBtn.innerHTML;
|
||
saveBtn.innerHTML = '<i class="fas fa-spinner fa-spin me-1"></i>...';
|
||
saveBtn.disabled = true;
|
||
fetch(form.action, { method: 'POST', body: formData, headers: { 'X-Requested-With': 'XMLHttpRequest' } })
|
||
.then(r => r.json())
|
||
.then(data => {
|
||
if (data.success) { location.reload(); }
|
||
else { showNotification('Fehler: ' + (data.error || 'Unbekannt'), 'danger'); saveBtn.innerHTML = orig; saveBtn.disabled = false; }
|
||
})
|
||
.catch(() => { showNotification('Fehler beim Speichern', 'danger'); saveBtn.innerHTML = orig; saveBtn.disabled = false; });
|
||
}
|
||
|
||
function showNotification(msg, type) {
|
||
const existing = document.querySelector('.edit-notification');
|
||
if (existing) existing.remove();
|
||
const el = document.createElement('div');
|
||
el.className = `alert alert-${type} alert-dismissible fade show edit-notification`;
|
||
el.innerHTML = `${msg}<button type="button" class="btn-close" data-bs-dismiss="alert"></button>`;
|
||
document.body.appendChild(el);
|
||
setTimeout(() => { if (el.parentNode) el.remove(); }, 3000);
|
||
}
|
||
|
||
document.addEventListener('keydown', function(e) {
|
||
if (isEditMode) {
|
||
if (e.key === 'Escape') cancelEdit();
|
||
if (e.ctrlKey && e.key === 's') { e.preventDefault(); saveChanges(); }
|
||
}
|
||
});
|
||
|
||
function approveQuarterly(id) {
|
||
if (!confirm('Nachweis freigeben?')) return;
|
||
fetch(`/quarterly-confirmations/${id}/approve/`, { method: 'POST', headers: { 'X-CSRFToken': document.querySelector('[name=csrfmiddlewaretoken]').value, 'Content-Type': 'application/json' } })
|
||
.then(r => { if (r.ok) location.reload(); else alert('Fehler'); }).catch(() => alert('Fehler'));
|
||
}
|
||
|
||
function resetQuarterly(id) {
|
||
if (!confirm('Nachweis zuruecksetzen?')) return;
|
||
fetch(`/quarterly-confirmations/${id}/reset/`, { method: 'POST', headers: { 'X-CSRFToken': document.querySelector('[name=csrfmiddlewaretoken]').value, 'Content-Type': 'application/json' } })
|
||
.then(r => { if (r.ok) location.reload(); else alert('Fehler'); }).catch(() => alert('Fehler'));
|
||
}
|
||
</script>
|
||
{% endblock %}
|