Erste lauffähige Version

This commit is contained in:
2026-05-21 10:36:16 +02:00
commit 6a103adac4
98 changed files with 4107 additions and 0 deletions
+25
View File
@@ -0,0 +1,25 @@
<div hx-get="{% url 'job-detail' job.id %}" hx-trigger="every 2s" hx-swap="outerHTML">
<p><strong>Vorlage:</strong> {{ job.template.name }}</p>
<p><strong>Status:</strong>
<span class="status-{{ job.status }}">{{ job.get_status_display }}</span>
</p>
<p><strong>Fortschritt:</strong> {{ job.processed_rows }} / {{ job.total_rows }}</p>
{% if job.status == "done" %}
<p><a class="btn" href="{% url 'job-download' job.id %}">PDF herunterladen</a></p>
{% endif %}
{% if job.error_message %}
<p style="color:#dc2626"><strong>Fehler:</strong> {{ job.error_message }}</p>
{% endif %}
<h3>Log</h3>
<div class="log">
{% for entry in logs %}
<div class="level-{{ entry.level }}">
[{{ entry.timestamp|date:"H:i:s" }}] {{ entry.level|upper }} {{ entry.message }}
</div>
{% empty %}
<em>Keine Einträge.</em>
{% endfor %}
</div>
</div>
+40
View File
@@ -0,0 +1,40 @@
{% extends "base.html" %}
{% block content %}
<h1>Übersicht</h1>
<h2>Vorlagen</h2>
<a class="btn" href="{% url 'template-upload' %}">Neue Vorlage hochladen</a>
<table>
<thead><tr><th>Name</th><th>Platzhalter</th><th>Erstellt</th></tr></thead>
<tbody>
{% for t in templates %}
<tr>
<td><a href="{% url 'template-detail' t.id %}">{{ t.name }}</a></td>
<td>{{ t.placeholders|join:", " }}</td>
<td>{{ t.created_at|date:"d.m.Y H:i" }}</td>
</tr>
{% empty %}
<tr><td colspan="3"><em>Noch keine Vorlagen vorhanden.</em></td></tr>
{% endfor %}
</tbody>
</table>
<h2>Aufträge</h2>
<a class="btn" href="{% url 'job-create' %}">Neuen Serienbrief erstellen</a>
<table>
<thead><tr><th>ID</th><th>Vorlage</th><th>Status</th><th>Fortschritt</th><th>Erstellt</th></tr></thead>
<tbody>
{% for j in jobs %}
<tr>
<td><a href="{% url 'job-detail' j.id %}">{{ j.id|stringformat:"s"|slice:":8" }}…</a></td>
<td>{{ j.template.name }}</td>
<td class="status-{{ j.status }}">{{ j.get_status_display }}</td>
<td>{{ j.processed_rows }} / {{ j.total_rows }}</td>
<td>{{ j.created_at|date:"d.m.Y H:i" }}</td>
</tr>
{% empty %}
<tr><td colspan="5"><em>Noch keine Aufträge.</em></td></tr>
{% endfor %}
</tbody>
</table>
{% endblock %}
+12
View File
@@ -0,0 +1,12 @@
{% extends "base.html" %}
{% block content %}
<h1>Auftrag {{ job.id|stringformat:"s"|slice:":8" }}…</h1>
<div hx-get="{% url 'job-detail' job.id %}"
hx-trigger="every 2s"
hx-swap="outerHTML">
{% include "mailmerge/_job_status.html" %}
</div>
<script src="https://unpkg.com/htmx.org@2.0.3" integrity="sha384-0895/pl2MU10Hqc6jd4RvrthNlDiE9U1tWmX7WRESftEDRosgxNsQG/Ze9YMRzHq" crossorigin="anonymous"></script>
{% endblock %}
+10
View File
@@ -0,0 +1,10 @@
{% extends "base.html" %}
{% block content %}
<h1>Neuer Serienbrief</h1>
<p>Vorlage und Empfänger-CSV auswählen. Die Spaltennamen der CSV müssen mit den Platzhaltern der Vorlage übereinstimmen (erste Zeile = Spaltennamen).</p>
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p }}
<button type="submit" class="btn">Erstellen und starten</button>
</form>
{% endblock %}
@@ -0,0 +1,11 @@
{% extends "base.html" %}
{% block content %}
<h1>{{ template.name }}</h1>
<p>{{ template.description }}</p>
<p><strong>Datei:</strong> {{ template.file.name }}</p>
<p><strong>Erkannte Platzhalter:</strong></p>
<ul>
{% for p in template.placeholders %}<li><code>{{ p }}</code></li>{% empty %}<li><em>Keine gefunden.</em></li>{% endfor %}
</ul>
<a class="btn" href="{% url 'job-create' %}">Serienbrief mit dieser Vorlage erstellen</a>
{% endblock %}
@@ -0,0 +1,10 @@
{% extends "base.html" %}
{% block content %}
<h1>Neue Vorlage hochladen</h1>
<p>DOCX-Datei mit Platzhaltern wie <code>&#123;&#123; vorname &#125;&#125;</code>, <code>&#123;&#123; nachname &#125;&#125;</code>, … Die Spaltennamen der späteren CSV müssen mit den Platzhaltern übereinstimmen.</p>
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p }}
<button type="submit" class="btn">Hochladen</button>
</form>
{% endblock %}