- New sidebar layout (6 sections: Dashboard, Personen, Land, Finanzen, Dokumente, System) - Collapsible sidebar with localStorage persistence - Top bar with user dropdown and breadcrumbs - Dashboard cockpit with live KPI cards (Destinataere, Foerderungen, Zahlungen, Laendereien) - Action items: overdue Nachweise, pending payments, upcoming events, new emails, expiring leases - Quick actions panel and recent audit log - HTMX (2.0.4) and Alpine.js (3.14.8) integration via CDN - django-htmx middleware and CSRF token setup - Fix IMAP_PORT empty string handling in settings Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
301 lines
14 KiB
HTML
301 lines
14 KiB
HTML
{% extends "base.html" %}
|
|
|
|
{% block title %}Dashboard - Stiftungsverwaltung{% endblock %}
|
|
|
|
{% block content %}
|
|
<!-- KPI Cards Row -->
|
|
<div class="row g-3 mb-4">
|
|
<div class="col-xl-3 col-md-6">
|
|
<div class="card stat-card border-left-primary">
|
|
<div class="card-body d-flex align-items-center">
|
|
<div class="stat-icon me-3" style="background: var(--racing-green);">
|
|
<i class="fas fa-users"></i>
|
|
</div>
|
|
<div>
|
|
<div class="stat-value">{{ destinataer_count }}</div>
|
|
<div class="stat-label">Destinataere</div>
|
|
</div>
|
|
<a href="{% url 'stiftung:destinataer_list' %}" class="stretched-link"></a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-xl-3 col-md-6">
|
|
<div class="card stat-card border-left-success">
|
|
<div class="card-body d-flex align-items-center">
|
|
<div class="stat-icon me-3" style="background: var(--racing-green-light);">
|
|
<i class="fas fa-gift"></i>
|
|
</div>
|
|
<div>
|
|
<div class="stat-value">{{ foerderung_active }}</div>
|
|
<div class="stat-label">Aktive Foerderungen</div>
|
|
</div>
|
|
<a href="{% url 'stiftung:foerderung_list' %}" class="stretched-link"></a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-xl-3 col-md-6">
|
|
<div class="card stat-card border-left-warning">
|
|
<div class="card-body d-flex align-items-center">
|
|
<div class="stat-icon me-3" style="background: var(--orange-accent);">
|
|
<i class="fas fa-euro-sign"></i>
|
|
</div>
|
|
<div>
|
|
<div class="stat-value">{{ pending_payment_total|floatformat:0 }}</div>
|
|
<div class="stat-label">Offene Zahlungen €</div>
|
|
</div>
|
|
<a href="{% url 'stiftung:unterstuetzungen_all' %}" class="stretched-link"></a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-xl-3 col-md-6">
|
|
<div class="card stat-card border-left-info">
|
|
<div class="card-body d-flex align-items-center">
|
|
<div class="stat-icon me-3" style="background: var(--grey-medium);">
|
|
<i class="fas fa-map"></i>
|
|
</div>
|
|
<div>
|
|
<div class="stat-value">{{ land_count }}</div>
|
|
<div class="stat-label">Laendereien</div>
|
|
</div>
|
|
<a href="{% url 'stiftung:land_list' %}" class="stretched-link"></a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Main Action Row -->
|
|
<div class="row g-3">
|
|
<!-- Left Column: Action Items -->
|
|
<div class="col-lg-8">
|
|
|
|
{% if overdue_events %}
|
|
<!-- Overdue Events Alert -->
|
|
<div class="card border-left-danger mb-3">
|
|
<div class="card-header bg-danger text-white">
|
|
<i class="fas fa-exclamation-triangle me-2"></i>Ueberfaellige Termine ({{ overdue_events|length }})
|
|
</div>
|
|
<div class="card-body p-0">
|
|
<div class="action-list">
|
|
{% for event in overdue_events %}
|
|
<div class="action-item">
|
|
<div class="action-icon bg-danger text-white">
|
|
<i class="{{ event.icon }}"></i>
|
|
</div>
|
|
<div class="action-text">
|
|
<div class="action-title">{{ event.title }}</div>
|
|
<div class="action-desc">{{ event.description }}</div>
|
|
</div>
|
|
<span class="badge bg-danger">{{ event.date }}</span>
|
|
</div>
|
|
{% endfor %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
|
|
{% if overdue_nachweise %}
|
|
<!-- Overdue Nachweise -->
|
|
<div class="card border-left-warning mb-3">
|
|
<div class="card-header">
|
|
<i class="fas fa-file-alt me-2 text-warning"></i>Ausstehende Nachweise Q{{ current_quarter }}/{{ current_year }}
|
|
</div>
|
|
<div class="card-body p-0">
|
|
<div class="action-list">
|
|
{% for nachweis in overdue_nachweise %}
|
|
<a class="action-item" href="{% url 'stiftung:destinataer_detail' nachweis.destinataer.pk %}">
|
|
<div class="action-icon" style="background: rgba(253,126,20,0.15); color: var(--orange-accent);">
|
|
<i class="fas fa-clock"></i>
|
|
</div>
|
|
<div class="action-text">
|
|
<div class="action-title">{{ nachweis.destinataer.vorname }} {{ nachweis.destinataer.nachname }}</div>
|
|
<div class="action-desc">{{ nachweis.get_status_display }}</div>
|
|
</div>
|
|
<span class="badge bg-warning">{{ nachweis.get_status_display }}</span>
|
|
</a>
|
|
{% endfor %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
|
|
{% if pending_payments %}
|
|
<!-- Pending Payments -->
|
|
<div class="card border-left-primary mb-3">
|
|
<div class="card-header">
|
|
<i class="fas fa-hand-holding-usd me-2 text-primary"></i>Offene Zahlungen
|
|
</div>
|
|
<div class="card-body p-0">
|
|
<div class="action-list">
|
|
{% for payment in pending_payments %}
|
|
<a class="action-item" href="{% url 'stiftung:destinataer_detail' payment.destinataer.pk %}">
|
|
<div class="action-icon" style="background: rgba(0,66,37,0.1); color: var(--racing-green);">
|
|
<i class="fas fa-euro-sign"></i>
|
|
</div>
|
|
<div class="action-text">
|
|
<div class="action-title">{{ payment.destinataer.vorname }} {{ payment.destinataer.nachname }}</div>
|
|
<div class="action-desc">{{ payment.beschreibung|default:"Unterstuetzung" }} · {{ payment.betrag|floatformat:2 }} €</div>
|
|
</div>
|
|
<span class="badge bg-{% if payment.faellig_am < today %}danger{% else %}primary{% endif %}">{{ payment.faellig_am|date:"d.m.Y" }}</span>
|
|
</a>
|
|
{% endfor %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
|
|
<!-- Upcoming Events -->
|
|
<div class="card mb-3">
|
|
<div class="card-header">
|
|
<i class="fas fa-calendar-alt me-2 text-primary"></i>Anstehende Termine
|
|
<a href="{% url 'stiftung:kalender' %}" class="float-end text-decoration-none" style="font-size: 0.75rem;">Alle anzeigen →</a>
|
|
</div>
|
|
<div class="card-body p-0">
|
|
<div class="action-list">
|
|
{% for event in upcoming_events %}
|
|
<div class="action-item">
|
|
<div class="action-icon" style="background: rgba(0,66,37,0.1); color: var(--racing-green);">
|
|
<i class="{{ event.icon }}"></i>
|
|
</div>
|
|
<div class="action-text">
|
|
<div class="action-title">{{ event.title }}</div>
|
|
{% if event.description %}
|
|
<div class="action-desc">{{ event.description }}</div>
|
|
{% endif %}
|
|
</div>
|
|
<span class="badge bg-{{ event.color }}">{{ event.date }}</span>
|
|
</div>
|
|
{% empty %}
|
|
<div class="text-center py-4 text-muted">
|
|
<i class="fas fa-calendar-check fa-2x mb-2 d-block"></i>
|
|
Keine Termine in den naechsten 14 Tagen.
|
|
</div>
|
|
{% endfor %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Right Column: Quick Actions & Info -->
|
|
<div class="col-lg-4">
|
|
|
|
<!-- Quick Actions -->
|
|
<div class="card mb-3">
|
|
<div class="card-header bg-success text-white">
|
|
<i class="fas fa-bolt me-2"></i>Schnellzugriff
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="d-grid gap-2">
|
|
<a href="{% url 'stiftung:destinataer_create' %}" class="btn btn-outline-primary btn-sm">
|
|
<i class="fas fa-user-plus me-1"></i>Neuer Destinataer
|
|
</a>
|
|
<a href="{% url 'stiftung:unterstuetzung_create' %}" class="btn btn-outline-primary btn-sm">
|
|
<i class="fas fa-euro-sign me-1"></i>Neue Zahlung
|
|
</a>
|
|
<a href="{% url 'stiftung:kalender_create' %}" class="btn btn-outline-primary btn-sm">
|
|
<i class="fas fa-calendar-plus me-1"></i>Neuer Termin
|
|
</a>
|
|
<a href="{% url 'stiftung:foerderung_create' %}" class="btn btn-outline-primary btn-sm">
|
|
<i class="fas fa-gift me-1"></i>Neue Foerderung
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{% if new_emails %}
|
|
<!-- New Emails -->
|
|
<div class="card mb-3">
|
|
<div class="card-header">
|
|
<i class="fas fa-envelope me-2 text-warning"></i>Neue E-Mails
|
|
<span class="badge bg-warning float-end">{{ new_email_count }}</span>
|
|
</div>
|
|
<div class="card-body p-0">
|
|
<div class="action-list">
|
|
{% for email in new_emails %}
|
|
<div class="action-item">
|
|
<div class="action-icon" style="background: rgba(253,126,20,0.15); color: var(--orange-accent);">
|
|
<i class="fas fa-envelope"></i>
|
|
</div>
|
|
<div class="action-text">
|
|
<div class="action-title">{{ email.absender_name|default:email.absender_email|truncatechars:30 }}</div>
|
|
<div class="action-desc">{{ email.betreff|truncatechars:40 }}</div>
|
|
</div>
|
|
</div>
|
|
{% endfor %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
|
|
{% if expiring_leases %}
|
|
<!-- Expiring Leases -->
|
|
<div class="card mb-3">
|
|
<div class="card-header">
|
|
<i class="fas fa-handshake me-2 text-info"></i>Auslaufende Pachtvertraege
|
|
</div>
|
|
<div class="card-body p-0">
|
|
<div class="action-list">
|
|
{% for lease in expiring_leases %}
|
|
<a class="action-item" href="{% url 'stiftung:verpachtung_detail' lease.pk %}">
|
|
<div class="action-icon" style="background: rgba(108,117,125,0.15); color: var(--grey-medium);">
|
|
<i class="fas fa-file-contract"></i>
|
|
</div>
|
|
<div class="action-text">
|
|
<div class="action-title">{{ lease.paechter.vorname }} {{ lease.paechter.nachname }}</div>
|
|
<div class="action-desc">{{ lease.land.bezeichnung|truncatechars:30 }}</div>
|
|
</div>
|
|
<span class="badge bg-info">{{ lease.pachtende|date:"d.m.Y" }}</span>
|
|
</a>
|
|
{% endfor %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
|
|
<!-- Stats Overview -->
|
|
<div class="card mb-3">
|
|
<div class="card-header">
|
|
<i class="fas fa-chart-pie me-2 text-primary"></i>Uebersicht
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="d-flex justify-content-between mb-2">
|
|
<span class="text-muted" style="font-size: 0.8rem;">Destinataere</span>
|
|
<strong>{{ destinataer_count }}</strong>
|
|
</div>
|
|
<div class="d-flex justify-content-between mb-2">
|
|
<span class="text-muted" style="font-size: 0.8rem;">Paechter</span>
|
|
<strong>{{ paechter_count }}</strong>
|
|
</div>
|
|
<div class="d-flex justify-content-between mb-2">
|
|
<span class="text-muted" style="font-size: 0.8rem;">Laendereien</span>
|
|
<strong>{{ land_count }}</strong>
|
|
</div>
|
|
<div class="d-flex justify-content-between">
|
|
<span class="text-muted" style="font-size: 0.8rem;">Aktive Foerderungen</span>
|
|
<strong>{{ foerderung_active }}</strong>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{% if recent_audit %}
|
|
<!-- Recent Activity -->
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<i class="fas fa-history me-2"></i>Letzte Aktivitaeten
|
|
</div>
|
|
<div class="card-body p-0">
|
|
<div class="action-list">
|
|
{% for entry in recent_audit %}
|
|
<div class="action-item" style="padding: 0.4rem 0.75rem;">
|
|
<div class="action-text">
|
|
<div class="action-title">{{ entry.get_action_display }} - {{ entry.get_entity_type_display }}</div>
|
|
<div class="action-desc">{{ entry.username }} · {{ entry.timestamp|timesince }} her</div>
|
|
</div>
|
|
</div>
|
|
{% endfor %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
{% endblock %} |