Files
stiftung-management-system/app/templates/portal/upload_formular.html
SysAdmin Agent aed540fe4b
Some checks failed
CI/CD Pipeline / test (push) Has been cancelled
CI/CD Pipeline / deploy (push) Has been cancelled
Code Quality / quality (push) Has been cancelled
Add Vorlagen editor, upload portal, onboarding, and participant import command
- Dokument-Vorlagen-Editor: create/edit/reset document templates (admin)
- Upload-Portal: public portal for Nachweis uploads via token
- Onboarding: invite Destinatäre via email with multi-step wizard
- Bestätigungsschreiben: preview and send confirmation letters
- Email settings: SMTP configuration UI
- Management command: import_veranstaltung_teilnehmer for bulk participant import

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-21 09:25:18 +00:00

170 lines
9.2 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Unterlagen hochladen vHTV-Stiftung</title>
<style>
*, *::before, *::after { box-sizing: border-box; }
body { font-family: Arial, sans-serif; font-size: 15px; color: #222; background: #f4f6f8; margin: 0; padding: 0; }
.container { max-width: 720px; margin: 40px auto; padding: 0 16px 40px; }
.header { background: #1a3a5c; color: #fff; padding: 24px 28px; border-radius: 8px 8px 0 0; }
.header h1 { margin: 0 0 4px; font-size: 20px; }
.header p { margin: 0; font-size: 13px; opacity: 0.8; }
.card { background: #fff; border-radius: 0 0 8px 8px; padding: 28px; box-shadow: 0 2px 10px rgba(0,0,0,0.08); }
.badge { display: inline-block; background: #e8f0fb; color: #1a3a5c; font-weight: bold; padding: 4px 12px; border-radius: 20px; font-size: 13px; margin-bottom: 12px; }
.info-box { background: #f0f6ff; border: 1px solid #b0cce8; border-radius: 6px; padding: 14px 16px; margin-bottom: 20px; font-size: 14px; }
.error-box { background: #fff3f3; border: 1px solid #e88; border-radius: 6px; padding: 12px 16px; margin-bottom: 16px; color: #c00; }
/* Category sections */
.kategorie { border: 1px solid #dde4ed; border-radius: 8px; padding: 20px; margin-bottom: 20px; }
.kategorie h3 { margin: 0 0 4px; font-size: 16px; color: #1a3a5c; }
.kategorie .hinweis { font-size: 13px; color: #666; margin: 0 0 12px; }
.kategorie.pflicht { border-left: 3px solid #1a3a5c; }
label { display: block; font-weight: bold; margin-bottom: 6px; font-size: 14px; }
.upload-area { border: 2px dashed #b0cce8; border-radius: 6px; padding: 20px; text-align: center; cursor: pointer; background: #fafcff; transition: border-color 0.2s; position: relative; }
.upload-area:hover, .upload-area.dragover { border-color: #1a3a5c; background: #e8f0fb; }
.upload-area input[type="file"] { position: absolute; inset: 0; opacity: 0; cursor: pointer; width: 100%; height: 100%; }
.upload-area .icon { font-size: 28px; margin-bottom: 4px; }
.upload-area p { margin: 2px 0; color: #555; font-size: 13px; }
.upload-area .hint { font-size: 11px; color: #888; }
.file-list { margin: 8px 0 0; font-size: 13px; color: #444; list-style: none; padding: 0; }
.file-list li { padding: 3px 0; border-bottom: 1px solid #f0f0f0; }
.oder-text { text-align: center; color: #999; font-size: 13px; margin: 10px 0; font-style: italic; }
textarea { width: 100%; border: 1px solid #ccc; border-radius: 5px; padding: 10px; font-family: inherit; font-size: 14px; resize: vertical; min-height: 60px; }
textarea:focus { border-color: #1a3a5c; outline: none; }
.submit-btn { display: block; width: 100%; background: #1a3a5c; color: #fff; border: none; border-radius: 5px; padding: 14px; font-size: 16px; font-weight: bold; cursor: pointer; margin-top: 20px; }
.submit-btn:hover { background: #14304e; }
.deadline { font-size: 13px; color: #888; margin-top: 16px; text-align: center; }
.footer { text-align: center; margin-top: 24px; font-size: 12px; color: #aaa; }
.pflicht-hinweis { font-size: 12px; color: #888; margin-bottom: 16px; }
</style>
</head>
<body>
<div class="container">
<div class="header">
<h1>van Hees-Theyssen-Vogel'sche Stiftung</h1>
<p>Sicheres Dokumenten-Upload-Portal</p>
</div>
<div class="card">
<div class="badge">{{ halbjahr_label }}</div>
<p>Guten Tag, <strong>{{ destinataer.vorname }} {{ destinataer.nachname }}</strong>,</p>
<p>bitte laden Sie hier Ihre Unterlagen für das <strong>{{ halbjahr_label }}</strong> hoch.
Für jede Kategorie können Sie eine Datei hochladen und/oder einen Text eingeben.</p>
<p class="pflicht-hinweis">Pro Kategorie muss mindestens eine Datei <em>oder</em> ein Texteintrag eingereicht werden.</p>
{% if fehler %}
<div class="error-box">{{ fehler }}</div>
{% endif %}
<form method="post" enctype="multipart/form-data" action="">
{% csrf_token %}
<!-- 1. Studiennachweis -->
<div class="kategorie pflicht">
<h3>Studiennachweis</h3>
<p class="hinweis">Semesterbescheinigung, Ausbildungsnachweis, Leistungsnachweise (Zeugnisse, Kreditpunkte etc.)</p>
<label for="studiennachweis">Datei hochladen:</label>
<div class="upload-area" data-target="studiennachweis">
<input type="file" name="studiennachweis" id="studiennachweis" accept=".pdf,.jpg,.jpeg,.png,.tiff,.tif">
<div class="icon">&#128196;</div>
<p>Datei hierher ziehen oder klicken</p>
<p class="hint">PDF, JPG, PNG, TIFF &bull; max. {{ max_dateigroesse_mb }} MB</p>
</div>
<ul class="file-list" data-list="studiennachweis"></ul>
<p class="oder-text">— oder Texteintrag —</p>
<textarea name="studiennachweis_text" placeholder="z.B. 'Semesterbescheinigung liegt bei' oder 'Kein Studium/Ausbildung mehr seit ...'">{{ studiennachweis_text|default:"" }}</textarea>
</div>
<!-- 2. Einkommenssituation -->
<div class="kategorie pflicht">
<h3>Einkommenssituation</h3>
<p class="hinweis">Einkommensteuerbescheid, Lohn-/Gehaltsnachweis, Rentenbescheid, Bescheinigung Pflegegrad etc.</p>
<label for="einkommenssituation">Datei hochladen:</label>
<div class="upload-area" data-target="einkommenssituation">
<input type="file" name="einkommenssituation" id="einkommenssituation" accept=".pdf,.jpg,.jpeg,.png,.tiff,.tif">
<div class="icon">&#128196;</div>
<p>Datei hierher ziehen oder klicken</p>
<p class="hint">PDF, JPG, PNG, TIFF &bull; max. {{ max_dateigroesse_mb }} MB</p>
</div>
<ul class="file-list" data-list="einkommenssituation"></ul>
<p class="oder-text">— oder Texteintrag —</p>
<textarea name="einkommenssituation_text" placeholder="z.B. 'Keine Änderungen seit letzter Meldung' oder Details zu Änderungen">{{ einkommenssituation_text|default:"" }}</textarea>
</div>
<!-- 3. Vermögenssituation -->
<div class="kategorie pflicht">
<h3>Vermögenssituation</h3>
<p class="hinweis">Angaben zu Spar-/Festgeldguthaben, Aktien, Immobilien etc.</p>
<label for="vermogenssituation">Datei hochladen:</label>
<div class="upload-area" data-target="vermogenssituation">
<input type="file" name="vermogenssituation" id="vermogenssituation" accept=".pdf,.jpg,.jpeg,.png,.tiff,.tif">
<div class="icon">&#128196;</div>
<p>Datei hierher ziehen oder klicken</p>
<p class="hint">PDF, JPG, PNG, TIFF &bull; max. {{ max_dateigroesse_mb }} MB</p>
</div>
<ul class="file-list" data-list="vermogenssituation"></ul>
<p class="oder-text">— oder Texteintrag —</p>
<textarea name="vermogenssituation_text" placeholder="z.B. 'Keine Änderungen seit letzter Meldung' oder Details zu Änderungen">{{ vermogenssituation_text|default:"" }}</textarea>
</div>
<!-- 4. Weitere Dokumente (optional) -->
<div class="kategorie">
<h3>Weitere Dokumente (optional)</h3>
<p class="hinweis">Mietvertrag, Unterhaltsbelege, sonstige Nachweise</p>
<label for="weitere_dokumente">Datei hochladen:</label>
<div class="upload-area" data-target="weitere_dokumente">
<input type="file" name="weitere_dokumente" id="weitere_dokumente" accept=".pdf,.jpg,.jpeg,.png,.tiff,.tif">
<div class="icon">&#128196;</div>
<p>Datei hierher ziehen oder klicken</p>
<p class="hint">PDF, JPG, PNG, TIFF &bull; max. {{ max_dateigroesse_mb }} MB</p>
</div>
<ul class="file-list" data-list="weitere_dokumente"></ul>
<p class="oder-text">— oder Texteintrag —</p>
<textarea name="weitere_dokumente_text" placeholder="Optionale Anmerkungen oder Beschreibung">{{ weitere_dokumente_text|default:"" }}</textarea>
</div>
<button type="submit" class="submit-btn">Unterlagen jetzt einreichen</button>
</form>
<p class="deadline">&#9201; Gültig bis: {{ gueltig_bis|date:"d.m.Y" }}</p>
</div>
<div class="footer">
van Hees-Theyssen-Vogel'sche Stiftung &bull; Raesfelder Str. 3 &bull; 46499 Hamminkeln<br>
Fragen? Tel. 02858/836780
</div>
</div>
<script>
document.querySelectorAll('.upload-area').forEach(area => {
const input = area.querySelector('input[type="file"]');
const target = area.dataset.target;
const list = document.querySelector(`[data-list="${target}"]`);
function updateList(files) {
list.innerHTML = '';
Array.from(files).forEach(f => {
const li = document.createElement('li');
li.textContent = `\u2714 ${f.name} (${(f.size/1024/1024).toFixed(2)} MB)`;
list.appendChild(li);
});
}
input.addEventListener('change', () => updateList(input.files));
area.addEventListener('dragover', e => { e.preventDefault(); area.classList.add('dragover'); });
area.addEventListener('dragleave', () => area.classList.remove('dragover'));
area.addEventListener('drop', e => {
e.preventDefault();
area.classList.remove('dragover');
input.files = e.dataTransfer.files;
updateList(e.dataTransfer.files);
});
});
</script>
</body>
</html>