/bewerbung/🆔 zweispaltiges Layout, dezente Eigene Anhänge

- Zweispalter auf >=lg (links: Bewerbungsdaten+Status+Termine,
  rechts: Unterlagen+Korrespondenz), vorher alles untereinander auf
  max-w-3xl. Seite deutlich kürzer, keine Grid-Row-Lücken dank
  unabhängiger Spalten-Container. Unter lg weiter einspaltig.
- Eigene Anhänge: amber durch neutral grau ersetzt, Papierclip durch
  Schloss-Icon ersetzt (signalisiert „nur für dich / nicht im PDF").
- Größte Textareas etwas kürzer (notizen 6->4, Begleit-E-Mail 12->10,
  Versand-Nachricht 10->8).

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2026-07-20 08:23:37 +02:00
co-authored by Claude
parent 7d5dc582e4
commit ada69eb482
+431 -424
View File
@@ -27,7 +27,7 @@
const today = new Date().toISOString().split('T')[0]; const today = new Date().toISOString().split('T')[0];
%> %>
<main class="flex-1 container mx-auto px-4 py-8 max-w-3xl"> <main class="flex-1 container mx-auto px-4 py-8 max-w-7xl">
<!-- Back link --> <!-- Back link -->
<a href="/" class="inline-flex items-center gap-2 text-sm text-blue-600 dark:text-blue-400 hover:underline mb-6"> <a href="/" class="inline-flex items-center gap-2 text-sm text-blue-600 dark:text-blue-400 hover:underline mb-6">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
@@ -47,6 +47,8 @@
<%- include('partials/favorit-button', { j: application, endpoint: '/api/bewerbungen/' + application.id + '/favorit' }) %> <%- include('partials/favorit-button', { j: application, endpoint: '/api/bewerbungen/' + application.id + '/favorit' }) %>
</div> </div>
<div class="grid grid-cols-1 lg:grid-cols-2 gap-8 items-start">
<div class="space-y-8">
<!-- Application data --> <!-- Application data -->
<section class="bg-white dark:bg-gray-800 rounded-lg shadow-md p-6 mb-8"> <section class="bg-white dark:bg-gray-800 rounded-lg shadow-md p-6 mb-8">
<h2 class="text-lg font-semibold text-gray-800 dark:text-white mb-4">Bewerbungsdaten</h2> <h2 class="text-lg font-semibold text-gray-800 dark:text-white mb-4">Bewerbungsdaten</h2>
@@ -83,7 +85,7 @@
</div> </div>
<div> <div>
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">Notizen</label> <label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">Notizen</label>
<textarea name="notizen" rows="6" <textarea name="notizen" rows="4"
class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-700 text-gray-800 dark:text-white leading-relaxed" class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-700 text-gray-800 dark:text-white leading-relaxed"
placeholder="Allgemeine Notizen zur Bewerbung..."><%= application.notizen || '' %></textarea> placeholder="Allgemeine Notizen zur Bewerbung..."><%= application.notizen || '' %></textarea>
</div> </div>
@@ -108,16 +110,16 @@
<!-- Eigene Anhänge: private files for the user only, never exported/sent. <!-- Eigene Anhänge: private files for the user only, never exported/sent.
Kept außerhalb des Bewerbungsdaten-Formulars, damit der Upload Kept außerhalb des Bewerbungsdaten-Formulars, damit der Upload
(multipart) und das Löschen als eigene Formulare funktionieren. --> (multipart) und das Löschen als eigene Formulare funktionieren. -->
<div class="mt-5 rounded-lg border border-amber-200 dark:border-amber-900/50 bg-amber-50/40 dark:bg-amber-900/10 p-4"> <div class="mt-5 rounded-lg border border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-700/30 p-4">
<div class="flex items-center gap-2 mb-3"> <div class="flex items-center gap-2 mb-3">
<span class="inline-flex items-center justify-center w-7 h-7 rounded-full bg-amber-100 dark:bg-amber-900/40 text-amber-600 dark:text-amber-400 shrink-0"> <span class="inline-flex items-center justify-center w-7 h-7 rounded-full bg-gray-100 dark:bg-gray-700 text-gray-500 dark:text-gray-400 shrink-0">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15.172 7l-6.586 6.586a2 2 0 102.828 2.828l6.414-6.586a4 4 0 00-5.656-5.656l-6.415 6.586a6 6 0 108.486 8.486L20.5 13"></path> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z"></path>
</svg> </svg>
</span> </span>
<div class="min-w-0"> <div class="min-w-0">
<h3 class="text-sm font-semibold text-amber-800 dark:text-amber-300 leading-tight">Eigene Anhänge</h3> <h3 class="text-sm font-semibold text-gray-700 dark:text-gray-200 leading-tight">Eigene Anhänge</h3>
<p class="text-xs text-amber-700/80 dark:text-amber-400/70 leading-tight">Nur für dich erscheinen nicht im PDF und werden nicht mitversendet.</p> <p class="text-xs text-gray-500 dark:text-gray-400 leading-tight">Nur für dich erscheinen nicht im PDF und werden nicht mitversendet.</p>
</div> </div>
</div> </div>
@@ -125,10 +127,10 @@
<ul class="space-y-2 mb-3"> <ul class="space-y-2 mb-3">
<% interneAnhaenge.forEach(a => { %> <% interneAnhaenge.forEach(a => { %>
<% const isPdf = (a.mime === 'application/pdf') || /\.pdf$/i.test(a.dateiname || ''); %> <% const isPdf = (a.mime === 'application/pdf') || /\.pdf$/i.test(a.dateiname || ''); %>
<li class="group flex items-center gap-3 rounded-lg border border-amber-200/70 dark:border-amber-800/50 bg-white/70 dark:bg-gray-800/60 px-3 py-2.5 hover:border-amber-300 dark:hover:border-amber-700 transition-colors"> <li class="group flex items-center gap-3 rounded-lg border border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-800 px-3 py-2.5 hover:border-gray-300 dark:hover:border-gray-600 transition-colors">
<a href="/bewerbung/<%= application.id %>/interne-anhaenge/<%= a.id %>/download?inline=1" target="_blank" rel="noopener" <a href="/bewerbung/<%= application.id %>/interne-anhaenge/<%= a.id %>/download?inline=1" target="_blank" rel="noopener"
class="flex items-center gap-3 min-w-0 flex-1" title="<%= isPdf ? 'PDF im neuen Tab öffnen' : 'Im neuen Tab öffnen' %>"> class="flex items-center gap-3 min-w-0 flex-1" title="<%= isPdf ? 'PDF im neuen Tab öffnen' : 'Im neuen Tab öffnen' %>">
<span class="inline-flex items-center justify-center w-9 h-9 rounded-md bg-red-50 dark:bg-red-900/30 text-red-500 dark:text-red-400 shrink-0"> <span class="inline-flex items-center justify-center w-9 h-9 rounded-md bg-gray-100 dark:bg-gray-700 text-gray-500 dark:text-gray-400 shrink-0">
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 21h10a2 2 0 002-2V9.414a1 1 0 00-.293-.707l-5.414-5.414A1 1 0 0012.586 3H7a2 2 0 00-2 2v14a2 2 0 002 2z"></path> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 21h10a2 2 0 002-2V9.414a1 1 0 00-.293-.707l-5.414-5.414A1 1 0 0012.586 3H7a2 2 0 00-2 2v14a2 2 0 002 2z"></path>
</svg> </svg>
@@ -140,7 +142,7 @@
</a> </a>
<div class="flex items-center gap-1 shrink-0"> <div class="flex items-center gap-1 shrink-0">
<a href="/bewerbung/<%= application.id %>/interne-anhaenge/<%= a.id %>/download?inline=1" target="_blank" rel="noopener" <a href="/bewerbung/<%= application.id %>/interne-anhaenge/<%= a.id %>/download?inline=1" target="_blank" rel="noopener"
class="inline-flex items-center justify-center w-8 h-8 rounded-md text-gray-500 dark:text-gray-400 hover:bg-amber-100 dark:hover:bg-amber-900/40 hover:text-amber-700 dark:hover:text-amber-300 transition-colors" class="inline-flex items-center justify-center w-8 h-8 rounded-md text-gray-500 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-700 hover:text-gray-700 dark:hover:text-gray-200 transition-colors"
title="Öffnen" aria-label="Öffnen"> title="Öffnen" aria-label="Öffnen">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"></path> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"></path>
@@ -148,7 +150,7 @@
</svg> </svg>
</a> </a>
<a href="/bewerbung/<%= application.id %>/interne-anhaenge/<%= a.id %>/download" <a href="/bewerbung/<%= application.id %>/interne-anhaenge/<%= a.id %>/download"
class="inline-flex items-center justify-center w-8 h-8 rounded-md text-gray-500 dark:text-gray-400 hover:bg-amber-100 dark:hover:bg-amber-900/40 hover:text-amber-700 dark:hover:text-amber-300 transition-colors" class="inline-flex items-center justify-center w-8 h-8 rounded-md text-gray-500 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-700 hover:text-gray-700 dark:hover:text-gray-200 transition-colors"
title="Herunterladen" aria-label="Herunterladen"> title="Herunterladen" aria-label="Herunterladen">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4"></path> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4"></path>
@@ -169,27 +171,27 @@
<% }); %> <% }); %>
</ul> </ul>
<% } else { %> <% } else { %>
<p class="text-xs text-amber-700/70 dark:text-amber-400/60 mb-3">Noch keine eigenen Anhänge.</p> <p class="text-xs text-gray-500 dark:text-gray-400 mb-3">Noch keine eigenen Anhänge.</p>
<% } %> <% } %>
<form action="/bewerbung/<%= application.id %>/interne-anhaenge" method="POST" enctype="multipart/form-data" class="space-y-3 border-t border-amber-200/70 dark:border-amber-800/50 pt-3"> <form action="/bewerbung/<%= application.id %>/interne-anhaenge" method="POST" enctype="multipart/form-data" class="space-y-3 border-t border-gray-200 dark:border-gray-700 pt-3">
<div class="grid grid-cols-1 sm:grid-cols-[1fr_auto] gap-3 items-start"> <div class="grid grid-cols-1 sm:grid-cols-[1fr_auto] gap-3 items-start">
<div class="space-y-2"> <div class="space-y-2">
<label class="block"> <label class="block">
<span class="sr-only">Datei</span> <span class="sr-only">Datei</span>
<input type="file" name="datei" required <input type="file" name="datei" required
accept="application/pdf,image/*,.doc,.docx,.xls,.xlsx,.txt,.zip" accept="application/pdf,image/*,.doc,.docx,.xls,.xlsx,.txt,.zip"
class="block w-full text-sm text-gray-600 dark:text-gray-300 file:mr-3 file:py-2 file:px-4 file:rounded-md file:border-0 file:font-medium file:bg-amber-600 file:text-white hover:file:bg-amber-700 file:cursor-pointer file:transition-colors"> class="block w-full text-sm text-gray-600 dark:text-gray-300 file:mr-3 file:py-2 file:px-4 file:rounded-md file:border-0 file:font-medium file:bg-gray-600 file:text-white hover:file:bg-gray-700 file:cursor-pointer file:transition-colors">
</label> </label>
<label class="block"> <label class="block">
<span class="sr-only">Bezeichnung (optional)</span> <span class="sr-only">Bezeichnung (optional)</span>
<input type="text" name="name" placeholder="Bezeichnung (optional) z. B. Arbeitszeugnis" <input type="text" name="name" placeholder="Bezeichnung (optional) z. B. Arbeitszeugnis"
class="w-full px-3 py-2 text-sm border border-amber-200 dark:border-amber-800/60 rounded-md bg-white dark:bg-gray-700 text-gray-800 dark:text-white placeholder-gray-400 dark:placeholder-gray-500 focus:outline-none focus:ring-2 focus:ring-amber-400/40 focus:border-amber-400"> class="w-full px-3 py-2 text-sm border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-700 text-gray-800 dark:text-white placeholder-gray-400 dark:placeholder-gray-500 focus:outline-none focus:ring-2 focus:ring-blue-400/40 focus:border-blue-400">
</label> </label>
</div> </div>
<div class="flex sm:items-end"> <div class="flex sm:items-end">
<button type="submit" <button type="submit"
class="w-full sm:w-auto inline-flex items-center justify-center gap-1.5 px-4 py-2 text-sm font-medium bg-amber-600 hover:bg-amber-700 text-white rounded-md transition-colors shadow-sm"> class="w-full sm:w-auto inline-flex items-center justify-center gap-1.5 px-4 py-2 text-sm font-medium bg-gray-600 hover:bg-gray-700 text-white rounded-md transition-colors shadow-sm">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12"></path> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12"></path>
</svg> </svg>
@@ -197,418 +199,11 @@
</button> </button>
</div> </div>
</div> </div>
<p class="text-xs text-amber-700/60 dark:text-amber-400/50">PDFs lassen sich per Klick direkt öffnen. Max. 15 MB.</p> <p class="text-xs text-gray-500 dark:text-gray-400">PDFs lassen sich per Klick direkt öffnen. Max. 15 MB.</p>
</form> </form>
</div> </div>
</section> </section>
<!-- Bewerbungsunterlagen (KI-generiert) -->
<% const genStatus = application.generierung_status; %>
<% if (genStatus || (anhaenge && anhaenge.length) || (application.stellenbeschreibung && application.stellenbeschreibung.trim())) { %>
<section id="unterlagen" class="bg-white dark:bg-gray-800 rounded-lg shadow-md p-6 mb-8"
data-status="<%= genStatus || '' %>">
<div class="flex flex-wrap items-center justify-between gap-3 mb-4">
<h2 class="text-lg font-semibold text-gray-800 dark:text-white">Bewerbungsunterlagen</h2>
</div>
<!-- Generation status banner -->
<div id="genBanner">
<% if (!genStatus || genStatus === 'nicht_gestartet') { %>
<div class="flex items-center gap-3 rounded-lg bg-gray-50 dark:bg-gray-700/40 border border-gray-200 dark:border-gray-700 px-4 py-3 mb-4">
<svg class="w-5 h-5 text-gray-500 dark:text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path>
</svg>
<span class="text-sm text-gray-700 dark:text-gray-300">Noch keine Unterlagen generiert. Ergänze bei Bedarf unten Notizen (z. B. die vollständige Firmenanschrift) und starte die Generierung.</span>
</div>
<% } else if (genStatus === 'ausstehend') { %>
<div class="flex items-center gap-3 rounded-lg bg-blue-50 dark:bg-blue-900/30 border border-blue-200 dark:border-blue-800 px-4 py-3 mb-4">
<svg class="w-5 h-5 text-blue-600 dark:text-blue-400 animate-spin" fill="none" viewBox="0 0 24 24">
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
<path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"></path>
</svg>
<span class="text-sm text-blue-800 dark:text-blue-200">Die KI erstellt gerade individuelle Bewerbungsunterlagen … Diese Seite aktualisiert sich automatisch.</span>
</div>
<% } else if (genStatus === 'fehler') { %>
<div class="rounded-lg bg-red-50 dark:bg-red-900/30 border border-red-200 dark:border-red-800 px-4 py-3 mb-4">
<div class="flex items-center gap-2 mb-1">
<svg class="w-5 h-5 text-red-600 dark:text-red-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"></path>
</svg>
<span class="text-sm font-semibold text-red-800 dark:text-red-200">Generierung fehlgeschlagen</span>
</div>
<p class="text-sm text-red-700 dark:text-red-300 ml-7"><%= application.generierung_fehler || 'Unbekannter Fehler.' %></p>
</div>
<% } else if (genStatus === 'fertig') { %>
<div class="flex items-center gap-2 rounded-lg bg-green-50 dark:bg-green-900/30 border border-green-200 dark:border-green-800 px-4 py-3 mb-4">
<svg class="w-5 h-5 text-green-600 dark:text-green-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"></path>
</svg>
<span class="text-sm text-green-800 dark:text-green-200">Unterlagen wurden erstellt. Bitte vor dem Versand prüfen und ggf. anpassen.</span>
</div>
<% } %>
</div>
<!-- Attachments -->
<div id="anhaengeListe">
<% if (anhaenge && anhaenge.length) { %>
<ul class="space-y-2">
<% anhaenge.forEach(a => { %>
<li class="flex items-center justify-between gap-3 rounded-lg border border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-700/40 px-4 py-3">
<a href="/anhaenge/<%= a.id %>/download?inline=1" target="_blank" rel="noopener"
class="flex items-center gap-3 min-w-0 group" title="Im neuen Tab öffnen">
<svg class="w-6 h-6 text-red-500 shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 21h10a2 2 0 002-2V9.414a1 1 0 00-.293-.707l-5.414-5.414A1 1 0 0012.586 3H7a2 2 0 00-2 2v14a2 2 0 002 2z"></path>
</svg>
<div class="min-w-0">
<p class="text-sm font-medium text-gray-800 dark:text-gray-100 truncate group-hover:text-blue-600 dark:group-hover:text-blue-400 group-hover:underline"><%= a.name || a.dateiname %></p>
<p class="text-xs text-gray-500 dark:text-gray-400 truncate"><%= a.dateiname %></p>
</div>
</a>
<div class="flex items-center gap-3 shrink-0">
<a href="/anhaenge/<%= a.id %>/download"
class="inline-flex items-center gap-1 text-sm text-blue-600 hover:text-blue-800 dark:text-blue-400 dark:hover:text-blue-300 hover:underline">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4"></path>
</svg>
Download
</a>
<form action="/bewerbung/<%= application.id %>/anhaenge/<%= a.id %>/delete" method="POST"
onsubmit="return confirm('Diesen Anhang löschen?');">
<button type="submit" class="text-red-500 hover:text-red-700 dark:text-red-400" aria-label="Anhang löschen">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"></path>
</svg>
</button>
</form>
</div>
</li>
<% }); %>
</ul>
<% } else if (genStatus !== 'ausstehend') { %>
<p class="text-sm text-gray-500 dark:text-gray-400">Noch keine generierten Unterlagen vorhanden.</p>
<% } %>
</div>
<!-- Editable e-mail cover text (Begleit-E-Mail) -->
<% if ((application.email_anschreiben && application.email_anschreiben.trim()) || genStatus === 'fertig') { %>
<div id="email" class="mt-6 border-t border-gray-200 dark:border-gray-700 pt-5">
<div class="flex flex-wrap items-center justify-between gap-2 mb-1">
<h3 class="text-sm font-semibold text-gray-800 dark:text-white">Begleit-E-Mail</h3>
<button type="button" id="emailCopyBtn"
class="inline-flex items-center gap-1 text-xs text-blue-600 hover:text-blue-800 dark:text-blue-400 dark:hover:text-blue-300 hover:underline">
<svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z"></path>
</svg>
<span id="emailCopyLabel">E-Mail-Text kopieren</span>
</button>
</div>
<p class="text-xs text-gray-500 dark:text-gray-400 mb-3">
Kurzer, normgerechter Text zum Versand der Bewerbung per E-Mail (Unterlagen im Anhang).
Du kannst Betreff und Text vor dem Versand frei anpassen und speichern.
</p>
<form action="/bewerbung/<%= application.id %>/email" method="POST">
<label class="block text-xs font-medium text-gray-500 dark:text-gray-400 mb-1">Betreff</label>
<input type="text" name="email_betreff" id="emailBetreff" value="<%= application.email_betreff || '' %>"
class="w-full px-3 py-2 mb-3 border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-700 text-gray-800 dark:text-white"
placeholder="Bewerbung als …">
<label class="block text-xs font-medium text-gray-500 dark:text-gray-400 mb-1">E-Mail-Text</label>
<textarea name="email_anschreiben" id="emailText" rows="12"
class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-700 text-gray-800 dark:text-white leading-relaxed font-sans"
placeholder="Sehr geehrte Damen und Herren,&#10;&#10;…"><%= application.email_anschreiben || '' %></textarea>
<div class="flex justify-end mt-3">
<button type="submit"
class="inline-flex items-center gap-1.5 px-4 py-2 text-sm bg-green-600 hover:bg-green-700 text-white rounded-md transition-colors">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"></path>
</svg>
E-Mail-Text speichern
</button>
</div>
</form>
</div>
<% } %>
<!-- LLM notes + generate/regenerate -->
<form action="/bewerbung/<%= application.id %>/generieren" method="POST"
id="generierenForm"
data-bestaetigen="<%= genStatus === 'fertig' ? '1' : '' %>"
class="mt-6 border-t border-gray-200 dark:border-gray-700 pt-5">
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
Notizen für die KI
</label>
<p class="text-xs text-gray-500 dark:text-gray-400 mb-2">
Zusätzliche Infos für die Generierung z. B. die vollständige Firmenanschrift (Straße, PLZ, Ort),
ein Ansprechpartner oder besondere Hinweise zur Bewerbung. Die KI berücksichtigt diese Angaben.
</p>
<textarea name="llm_notizen" rows="4"
class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-700 text-gray-800 dark:text-white leading-relaxed"
placeholder="z. B.&#10;Musterfirma GmbH&#10;Musterstraße 12&#10;10115 Berlin&#10;Ansprechpartner: Frau Müller"><%= application.llm_notizen || '' %></textarea>
<!-- Which documents to generate (vorbelegt aus den Einstellungen). -->
<div class="mt-4" id="dokumentAuswahl">
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Was soll generiert werden?</label>
<p class="text-xs text-gray-500 dark:text-gray-400 mb-2">
Vorbelegt ist deine Auswahl aus den <a href="/einstellungen" class="text-blue-600 dark:text-blue-400 hover:underline">Einstellungen</a>
(Standard: Anschreiben und Lebenslauf). Wird der Lebenslauf abgewählt,
führt ihn das Anschreiben auch nicht mehr unter „Anlagen“ auf.
</p>
<div class="flex flex-wrap gap-4">
<label class="flex items-center gap-2 text-sm text-gray-700 dark:text-gray-300">
<input type="checkbox" name="dokument" value="anschreiben" data-dokument
<%= dokumentAuswahl.includes('anschreiben') ? 'checked' : '' %>
class="rounded border-gray-300 dark:border-gray-600">
Anschreiben
</label>
<label class="flex items-center gap-2 text-sm text-gray-700 dark:text-gray-300">
<input type="checkbox" name="dokument" value="lebenslauf" data-dokument
<%= dokumentAuswahl.includes('lebenslauf') ? 'checked' : '' %>
class="rounded border-gray-300 dark:border-gray-600">
Lebenslauf
</label>
</div>
<p class="text-xs text-red-600 dark:text-red-400 mt-2 hidden" id="dokumentHinweis">
Bitte mindestens ein Dokument auswählen.
</p>
</div>
<!-- Optional extra attachments to enclose (vorbelegt aus den Einstellungen). -->
<div class="mt-4">
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Zusätzliche Anlagen</label>
<% if (basisAnhaenge && basisAnhaenge.length) { %>
<p class="text-xs text-gray-500 dark:text-gray-400 mb-2">
Wähle aus, welche Anlagen (z. B. Zeugnisse) mitgeschickt werden. Vorbelegt ist deine Auswahl
aus den <a href="/einstellungen" class="text-blue-600 dark:text-blue-400 hover:underline">Einstellungen</a>
(Standard: keine); die Auswahl wird auch im Anschreiben unter „Anlagen“ berücksichtigt.
</p>
<div class="space-y-1.5">
<% basisAnhaenge.forEach(function(ba){ %>
<label class="flex items-center gap-2 text-sm text-gray-700 dark:text-gray-200">
<input type="checkbox" name="anlage" value="<%= ba.id %>"
<%= anlagenAuswahl.includes(ba.id) ? 'checked' : '' %>
class="rounded border-gray-300 dark:border-gray-600 text-blue-600">
<%= ba.name || ba.dateiname %>
<% if (ba.name && ba.dateiname && ba.name !== ba.dateiname) { %>
<span class="text-xs text-gray-400">(<%= ba.dateiname %>)</span>
<% } %>
</label>
<% }); %>
</div>
<% } else { %>
<p class="text-xs text-gray-400 dark:text-gray-500">
Keine zusätzlichen Anlagen hinterlegt. Unter
<a href="/vorlagen" class="text-blue-600 dark:text-blue-400 hover:underline">Vorlagen</a>
kannst du statische Anlagen (z. B. Zeugnisse) hochladen.
</p>
<% } %>
</div>
<div class="flex justify-end mt-4">
<button type="submit" <%= genStatus === 'ausstehend' ? 'disabled' : '' %>
class="inline-flex items-center gap-1.5 px-4 py-2 text-sm bg-blue-600 hover:bg-blue-700 disabled:opacity-50 text-white rounded-md transition-colors">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7l9-11h-7z"></path>
</svg>
<%= genStatus === 'ausstehend' ? 'Wird generiert…' : (genStatus === 'fertig' ? 'Notizen speichern & neu generieren' : 'Unterlagen generieren') %>
</button>
</div>
</form>
<!-- Job description from the import -->
<% if (application.stellenbeschreibung && application.stellenbeschreibung.trim()) { %>
<details class="mt-6 rounded-lg border border-gray-200 dark:border-gray-700">
<summary class="cursor-pointer select-none px-4 py-3 text-sm font-medium text-gray-700 dark:text-gray-300">
Importierte Stellenbeschreibung anzeigen
</summary>
<div class="px-4 pb-4">
<% if (application.quelle_url) { %>
<a href="<%= safeUrl(application.quelle_url) %>" target="_blank" rel="noopener"
class="inline-block mb-3 text-sm text-blue-600 dark:text-blue-400 hover:underline break-all"><%= application.quelle_url %></a>
<% } %>
<p class="whitespace-pre-wrap break-words text-sm leading-relaxed text-gray-700 dark:text-gray-300"><%= application.stellenbeschreibung %></p>
</div>
</details>
<% } %>
</section>
<% } %>
<!-- E-Mail-Korrespondenz -->
<section id="korrespondenz" class="bg-white dark:bg-gray-800 rounded-lg shadow-md p-6 mb-8">
<div class="flex flex-wrap items-center justify-between gap-3 mb-4">
<h2 class="text-lg font-semibold text-gray-800 dark:text-white">E-Mail-Korrespondenz</h2>
<% if (mailConfigured) { %>
<form action="/email/fetch" method="POST" class="shrink-0">
<input type="hidden" name="back" value="/bewerbung/<%= application.id %>#korrespondenz">
<button type="submit" class="inline-flex items-center gap-1.5 px-3 py-1.5 text-sm border border-gray-300 dark:border-gray-600 rounded-md text-gray-700 dark:text-gray-200 hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"></path></svg>
Postfach abrufen
</button>
</form>
<% } %>
</div>
<% if (!mailConfigured) { %>
<div class="flex items-center gap-3 rounded-lg bg-yellow-50 dark:bg-yellow-900/30 border border-yellow-200 dark:border-yellow-800 px-4 py-3">
<svg class="w-5 h-5 text-yellow-600 dark:text-yellow-400" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"></path></svg>
<span class="text-sm text-yellow-800 dark:text-yellow-200">E-Mail ist nicht konfiguriert. Bitte <code>MAIL_HOST</code>, <code>MAIL_USER</code> und <code>MAIL_PASSWORD</code> in der <code>.env</code> setzen.</span>
</div>
<% } else { %>
<% if (mailError) { %>
<div class="rounded-lg bg-red-50 dark:bg-red-900/30 border border-red-200 dark:border-red-800 px-4 py-3 mb-4 text-sm text-red-800 dark:text-red-200"><%= mailError %></div>
<% } %>
<% if (mailOk) { %>
<div class="rounded-lg bg-green-50 dark:bg-green-900/30 border border-green-200 dark:border-green-800 px-4 py-3 mb-4 text-sm text-green-800 dark:text-green-200"><%= mailOk %></div>
<% } %>
<!-- Conversation thread -->
<% if (emails && emails.length) { %>
<ul class="space-y-3 mb-6">
<% emails.forEach(function(e){ var out = e.direction === 'out'; %>
<li class="rounded-lg border <%= out ? 'border-blue-200 dark:border-blue-800 bg-blue-50/60 dark:bg-blue-900/20' : 'border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-700/40' %> px-4 py-3">
<div class="flex flex-wrap items-center justify-between gap-2 mb-1">
<div class="flex items-center gap-2 min-w-0">
<span class="inline-flex items-center px-2 py-0.5 rounded text-xs font-medium <%= out ? 'bg-blue-600 text-white' : 'bg-gray-600 text-white' %>"><%= out ? 'Gesendet' : 'Empfangen' %></span>
<span class="text-sm text-gray-700 dark:text-gray-200 truncate">
<%= out ? ('An: ' + (e.to_addr || '')) : ('Von: ' + (e.from_addr || '')) %>
</span>
</div>
<span class="text-xs text-gray-500 dark:text-gray-400 shrink-0"><%= e.email_date ? new Date(e.email_date).toLocaleString('de-DE', { timeZone: 'Europe/Berlin' }) : '' %></span>
</div>
<p class="text-sm font-medium text-gray-800 dark:text-gray-100 mb-1"><%= e.subject || '(kein Betreff)' %></p>
<% if (e.display_srcdoc) { %>
<iframe class="email-html-frame w-full border border-gray-200 dark:border-gray-600 rounded bg-white" style="height:6rem"
sandbox="allow-same-origin" referrerpolicy="no-referrer"
srcdoc="<%= e.display_srcdoc %>"></iframe>
<% } else { %>
<p class="whitespace-pre-wrap break-words text-sm leading-relaxed text-gray-700 dark:text-gray-300"><%= e.body_text || '' %></p>
<% } %>
<% if (e.anhaenge && e.anhaenge.length) { %>
<div class="mt-2 flex flex-wrap gap-2">
<% e.anhaenge.forEach(function(a){ %>
<a href="/email-anhaenge/<%= a.id %>/download?inline=1" target="_blank" rel="noopener" class="inline-flex items-center gap-1 text-xs px-2 py-1 rounded border border-gray-300 dark:border-gray-600 text-blue-600 dark:text-blue-400 hover:underline">
<svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15.172 7l-6.586 6.586a2 2 0 102.828 2.828l6.414-6.586a4 4 0 00-5.656-5.656l-6.415 6.585a6 6 0 108.486 8.486L20.5 13"></path></svg>
<%= a.name || 'Anhang' %>
</a>
<% }); %>
</div>
<% } %>
<% if (!out) { %>
<div class="mt-2">
<button type="button" class="reply-toggle text-sm text-blue-600 hover:text-blue-800 dark:text-blue-400 hover:underline" data-target="reply-<%= e.id %>">Antworten</button>
</div>
<form action="/bewerbung/<%= application.id %>/email/send" method="POST" id="reply-<%= e.id %>" class="hidden mt-3 border-t border-gray-200 dark:border-gray-600 pt-3">
<input type="hidden" name="reply_to" value="<%= e.id %>">
<label class="block text-xs font-medium text-gray-500 dark:text-gray-400 mb-1">An</label>
<input type="email" name="to" required value="<%= e.from_addr_clean || '' %>"
class="w-full px-3 py-2 mb-2 border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-700 text-gray-800 dark:text-white text-sm">
<label class="block text-xs font-medium text-gray-500 dark:text-gray-400 mb-1">Betreff</label>
<input type="text" name="subject" value="<%= /^\s*(re|aw)\s*:/i.test(e.subject || '') ? (e.subject || '') : ('Re: ' + (e.subject || '')) %>"
class="reply-subject w-full px-3 py-2 mb-2 border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-700 text-gray-800 dark:text-white text-sm">
<!-- KI-Antwort: erst sagen, was drinstehen soll, dann generieren lassen.
Ohne Vorgabe kommt nur eine allgemeine Höflichkeitsantwort heraus. -->
<div class="mb-3 rounded-md border border-purple-200 dark:border-purple-800/60 bg-purple-50/60 dark:bg-purple-900/10 p-3">
<div class="flex flex-wrap items-center justify-between gap-2 mb-1.5">
<label for="ai-prompt-<%= e.id %>" class="flex items-center gap-1.5 text-xs font-medium text-purple-700 dark:text-purple-300">
<svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7l9-11h-7z"></path></svg>
Was soll die KI antworten?
</label>
<select class="ai-reply-typ text-xs px-1.5 py-0.5 border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-700 text-gray-700 dark:text-gray-200">
<option value="antwort">Antwort</option>
<option value="absage">Absage (andere Stelle)</option>
</select>
</div>
<textarea id="ai-prompt-<%= e.id %>" rows="2"
class="ai-reply-prompt w-full px-3 py-2 border border-purple-200 dark:border-purple-800/60 rounded-md bg-white dark:bg-gray-700 text-gray-800 dark:text-white text-sm leading-relaxed"
placeholder="z. B. Termin am Dienstag 14 Uhr zusagen, nach dem Ablauf des Gesprächs fragen oder: kürzer und förmlicher"></textarea>
<div class="flex flex-wrap items-center justify-between gap-2 mt-2">
<p class="ai-reply-status text-xs text-gray-500 dark:text-gray-400">
Ohne Vorgabe antwortet die KI nur allgemein auf die Nachricht.
</p>
<button type="button" class="ai-reply-btn inline-flex items-center gap-1.5 shrink-0 px-3 py-1.5 text-xs font-medium rounded-md bg-purple-600 hover:bg-purple-700 text-white transition-colors disabled:opacity-50 disabled:cursor-not-allowed"
data-email-id="<%= e.id %>" data-app-id="<%= application.id %>" data-target="reply-<%= e.id %>">
<svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7l9-11h-7z"></path></svg>
<span class="ai-reply-label">KI-Antwort generieren</span>
</button>
</div>
</div>
<label class="block text-xs font-medium text-gray-500 dark:text-gray-400 mb-1">Nachricht</label>
<textarea name="body" rows="12" required
class="reply-body w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-700 text-gray-800 dark:text-white text-sm leading-relaxed"><%= e.reply_quote ? '\n\n' + e.reply_quote : '' %></textarea>
<% if (basisAnhaenge && basisAnhaenge.length) { %>
<p class="text-xs font-medium text-gray-500 dark:text-gray-400 mt-2 mb-1">Anlagen</p>
<div class="space-y-1">
<% basisAnhaenge.forEach(function(ba){ %>
<label class="flex items-center gap-2 text-sm text-gray-700 dark:text-gray-200">
<input type="checkbox" name="basis_anlage" value="<%= ba.id %>"
class="rounded border-gray-300 dark:border-gray-600 text-blue-600">
<%= ba.name || ba.dateiname %>
<% if (ba.name && ba.dateiname && ba.name !== ba.dateiname) { %>
<span class="text-xs text-gray-400">(<%= ba.dateiname %>)</span>
<% } %>
</label>
<% }); %>
</div>
<% } %>
<div class="flex justify-end mt-2">
<button type="submit" class="inline-flex items-center gap-1.5 px-4 py-2 text-sm bg-blue-600 hover:bg-blue-700 text-white rounded-md transition-colors">Antwort senden</button>
</div>
</form>
<% } %>
</li>
<% }); %>
</ul>
<% } else { %>
<p class="text-sm text-gray-500 dark:text-gray-400 mb-6">Noch keine E-Mails. Sende die Bewerbung unten oder rufe das Postfach ab.</p>
<% } %>
<!-- Compose / send the application -->
<div class="border-t border-gray-200 dark:border-gray-700 pt-5">
<h3 class="text-sm font-semibold text-gray-800 dark:text-white mb-1">Bewerbung per E-Mail senden</h3>
<p class="text-xs text-gray-500 dark:text-gray-400 mb-3">
Versand über <code><%= mailFrom %></code>. Empfängeradresse eingeben, Betreff und Text prüfen,
Anhänge auswählen und senden.
</p>
<form action="/bewerbung/<%= application.id %>/email/send" method="POST"
onsubmit="return confirm('Bewerbung jetzt verbindlich an ' + (this.to.value.trim() || 'den Empfänger') + ' senden?');">
<label class="block text-xs font-medium text-gray-500 dark:text-gray-400 mb-1">Empfänger (E-Mail)</label>
<input type="email" name="to" required value="<%= application.email_empfaenger || '' %>"
placeholder="personal@unternehmen.de"
class="w-full px-3 py-2 mb-3 border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-700 text-gray-800 dark:text-white">
<label class="block text-xs font-medium text-gray-500 dark:text-gray-400 mb-1">Betreff</label>
<input type="text" name="subject" value="<%= application.email_betreff || ('Bewerbung als ' + (application.stelle || '')) %>"
class="w-full px-3 py-2 mb-3 border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-700 text-gray-800 dark:text-white">
<label class="block text-xs font-medium text-gray-500 dark:text-gray-400 mb-1">Nachricht</label>
<textarea name="body" rows="10"
class="w-full px-3 py-2 mb-3 border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-700 text-gray-800 dark:text-white leading-relaxed"><%= application.email_anschreiben || '' %></textarea>
<% if (anhaenge && anhaenge.length) { %>
<p class="text-xs font-medium text-gray-500 dark:text-gray-400 mb-1">Anhänge</p>
<div class="space-y-1 mb-3">
<% anhaenge.forEach(function(a){ %>
<label class="flex items-center gap-2 text-sm text-gray-700 dark:text-gray-200">
<input type="checkbox" name="anhang" value="<%= a.id %>" checked
class="rounded border-gray-300 dark:border-gray-600 text-blue-600">
<%= a.name || a.dateiname %> <span class="text-xs text-gray-400">(<%= a.dateiname %>)</span>
</label>
<% }); %>
</div>
<% } else { %>
<p class="text-xs text-gray-400 mb-3">Keine generierten Anhänge vorhanden - erst Unterlagen generieren.</p>
<% } %>
<div class="flex justify-end">
<button type="submit" class="inline-flex items-center gap-1.5 px-4 py-2 text-sm bg-green-600 hover:bg-green-700 text-white rounded-md transition-colors">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 19l9 2-9-18-9 18 9-2zm0 0v-8"></path></svg>
Bewerbung senden
</button>
</div>
</form>
</div>
<% } %>
</section>
<!-- Status timeline --> <!-- Status timeline -->
<section class="bg-white dark:bg-gray-800 rounded-lg shadow-md p-6"> <section class="bg-white dark:bg-gray-800 rounded-lg shadow-md p-6">
<h2 class="text-lg font-semibold text-gray-800 dark:text-white mb-1">Status-Verlauf</h2> <h2 class="text-lg font-semibold text-gray-800 dark:text-white mb-1">Status-Verlauf</h2>
@@ -898,6 +493,418 @@
</script> </script>
</section> </section>
<% } %> <% } %>
</div>
<div class="space-y-8">
<!-- Bewerbungsunterlagen (KI-generiert) -->
<% const genStatus = application.generierung_status; %>
<% if (genStatus || (anhaenge && anhaenge.length) || (application.stellenbeschreibung && application.stellenbeschreibung.trim())) { %>
<section id="unterlagen" class="bg-white dark:bg-gray-800 rounded-lg shadow-md p-6 mb-8"
data-status="<%= genStatus || '' %>">
<div class="flex flex-wrap items-center justify-between gap-3 mb-4">
<h2 class="text-lg font-semibold text-gray-800 dark:text-white">Bewerbungsunterlagen</h2>
</div>
<!-- Generation status banner -->
<div id="genBanner">
<% if (!genStatus || genStatus === 'nicht_gestartet') { %>
<div class="flex items-center gap-3 rounded-lg bg-gray-50 dark:bg-gray-700/40 border border-gray-200 dark:border-gray-700 px-4 py-3 mb-4">
<svg class="w-5 h-5 text-gray-500 dark:text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path>
</svg>
<span class="text-sm text-gray-700 dark:text-gray-300">Noch keine Unterlagen generiert. Ergänze bei Bedarf unten Notizen (z. B. die vollständige Firmenanschrift) und starte die Generierung.</span>
</div>
<% } else if (genStatus === 'ausstehend') { %>
<div class="flex items-center gap-3 rounded-lg bg-blue-50 dark:bg-blue-900/30 border border-blue-200 dark:border-blue-800 px-4 py-3 mb-4">
<svg class="w-5 h-5 text-blue-600 dark:text-blue-400 animate-spin" fill="none" viewBox="0 0 24 24">
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
<path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"></path>
</svg>
<span class="text-sm text-blue-800 dark:text-blue-200">Die KI erstellt gerade individuelle Bewerbungsunterlagen … Diese Seite aktualisiert sich automatisch.</span>
</div>
<% } else if (genStatus === 'fehler') { %>
<div class="rounded-lg bg-red-50 dark:bg-red-900/30 border border-red-200 dark:border-red-800 px-4 py-3 mb-4">
<div class="flex items-center gap-2 mb-1">
<svg class="w-5 h-5 text-red-600 dark:text-red-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"></path>
</svg>
<span class="text-sm font-semibold text-red-800 dark:text-red-200">Generierung fehlgeschlagen</span>
</div>
<p class="text-sm text-red-700 dark:text-red-300 ml-7"><%= application.generierung_fehler || 'Unbekannter Fehler.' %></p>
</div>
<% } else if (genStatus === 'fertig') { %>
<div class="flex items-center gap-2 rounded-lg bg-green-50 dark:bg-green-900/30 border border-green-200 dark:border-green-800 px-4 py-3 mb-4">
<svg class="w-5 h-5 text-green-600 dark:text-green-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"></path>
</svg>
<span class="text-sm text-green-800 dark:text-green-200">Unterlagen wurden erstellt. Bitte vor dem Versand prüfen und ggf. anpassen.</span>
</div>
<% } %>
</div>
<!-- Attachments -->
<div id="anhaengeListe">
<% if (anhaenge && anhaenge.length) { %>
<ul class="space-y-2">
<% anhaenge.forEach(a => { %>
<li class="flex items-center justify-between gap-3 rounded-lg border border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-700/40 px-4 py-3">
<a href="/anhaenge/<%= a.id %>/download?inline=1" target="_blank" rel="noopener"
class="flex items-center gap-3 min-w-0 group" title="Im neuen Tab öffnen">
<svg class="w-6 h-6 text-red-500 shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 21h10a2 2 0 002-2V9.414a1 1 0 00-.293-.707l-5.414-5.414A1 1 0 0012.586 3H7a2 2 0 00-2 2v14a2 2 0 002 2z"></path>
</svg>
<div class="min-w-0">
<p class="text-sm font-medium text-gray-800 dark:text-gray-100 truncate group-hover:text-blue-600 dark:group-hover:text-blue-400 group-hover:underline"><%= a.name || a.dateiname %></p>
<p class="text-xs text-gray-500 dark:text-gray-400 truncate"><%= a.dateiname %></p>
</div>
</a>
<div class="flex items-center gap-3 shrink-0">
<a href="/anhaenge/<%= a.id %>/download"
class="inline-flex items-center gap-1 text-sm text-blue-600 hover:text-blue-800 dark:text-blue-400 dark:hover:text-blue-300 hover:underline">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4"></path>
</svg>
Download
</a>
<form action="/bewerbung/<%= application.id %>/anhaenge/<%= a.id %>/delete" method="POST"
onsubmit="return confirm('Diesen Anhang löschen?');">
<button type="submit" class="text-red-500 hover:text-red-700 dark:text-red-400" aria-label="Anhang löschen">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"></path>
</svg>
</button>
</form>
</div>
</li>
<% }); %>
</ul>
<% } else if (genStatus !== 'ausstehend') { %>
<p class="text-sm text-gray-500 dark:text-gray-400">Noch keine generierten Unterlagen vorhanden.</p>
<% } %>
</div>
<!-- Editable e-mail cover text (Begleit-E-Mail) -->
<% if ((application.email_anschreiben && application.email_anschreiben.trim()) || genStatus === 'fertig') { %>
<div id="email" class="mt-6 border-t border-gray-200 dark:border-gray-700 pt-5">
<div class="flex flex-wrap items-center justify-between gap-2 mb-1">
<h3 class="text-sm font-semibold text-gray-800 dark:text-white">Begleit-E-Mail</h3>
<button type="button" id="emailCopyBtn"
class="inline-flex items-center gap-1 text-xs text-blue-600 hover:text-blue-800 dark:text-blue-400 dark:hover:text-blue-300 hover:underline">
<svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z"></path>
</svg>
<span id="emailCopyLabel">E-Mail-Text kopieren</span>
</button>
</div>
<p class="text-xs text-gray-500 dark:text-gray-400 mb-3">
Kurzer, normgerechter Text zum Versand der Bewerbung per E-Mail (Unterlagen im Anhang).
Du kannst Betreff und Text vor dem Versand frei anpassen und speichern.
</p>
<form action="/bewerbung/<%= application.id %>/email" method="POST">
<label class="block text-xs font-medium text-gray-500 dark:text-gray-400 mb-1">Betreff</label>
<input type="text" name="email_betreff" id="emailBetreff" value="<%= application.email_betreff || '' %>"
class="w-full px-3 py-2 mb-3 border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-700 text-gray-800 dark:text-white"
placeholder="Bewerbung als …">
<label class="block text-xs font-medium text-gray-500 dark:text-gray-400 mb-1">E-Mail-Text</label>
<textarea name="email_anschreiben" id="emailText" rows="10"
class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-700 text-gray-800 dark:text-white leading-relaxed font-sans"
placeholder="Sehr geehrte Damen und Herren,&#10;&#10;…"><%= application.email_anschreiben || '' %></textarea>
<div class="flex justify-end mt-3">
<button type="submit"
class="inline-flex items-center gap-1.5 px-4 py-2 text-sm bg-green-600 hover:bg-green-700 text-white rounded-md transition-colors">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"></path>
</svg>
E-Mail-Text speichern
</button>
</div>
</form>
</div>
<% } %>
<!-- LLM notes + generate/regenerate -->
<form action="/bewerbung/<%= application.id %>/generieren" method="POST"
id="generierenForm"
data-bestaetigen="<%= genStatus === 'fertig' ? '1' : '' %>"
class="mt-6 border-t border-gray-200 dark:border-gray-700 pt-5">
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
Notizen für die KI
</label>
<p class="text-xs text-gray-500 dark:text-gray-400 mb-2">
Zusätzliche Infos für die Generierung z. B. die vollständige Firmenanschrift (Straße, PLZ, Ort),
ein Ansprechpartner oder besondere Hinweise zur Bewerbung. Die KI berücksichtigt diese Angaben.
</p>
<textarea name="llm_notizen" rows="4"
class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-700 text-gray-800 dark:text-white leading-relaxed"
placeholder="z. B.&#10;Musterfirma GmbH&#10;Musterstraße 12&#10;10115 Berlin&#10;Ansprechpartner: Frau Müller"><%= application.llm_notizen || '' %></textarea>
<!-- Which documents to generate (vorbelegt aus den Einstellungen). -->
<div class="mt-4" id="dokumentAuswahl">
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Was soll generiert werden?</label>
<p class="text-xs text-gray-500 dark:text-gray-400 mb-2">
Vorbelegt ist deine Auswahl aus den <a href="/einstellungen" class="text-blue-600 dark:text-blue-400 hover:underline">Einstellungen</a>
(Standard: Anschreiben und Lebenslauf). Wird der Lebenslauf abgewählt,
führt ihn das Anschreiben auch nicht mehr unter „Anlagen“ auf.
</p>
<div class="flex flex-wrap gap-4">
<label class="flex items-center gap-2 text-sm text-gray-700 dark:text-gray-300">
<input type="checkbox" name="dokument" value="anschreiben" data-dokument
<%= dokumentAuswahl.includes('anschreiben') ? 'checked' : '' %>
class="rounded border-gray-300 dark:border-gray-600">
Anschreiben
</label>
<label class="flex items-center gap-2 text-sm text-gray-700 dark:text-gray-300">
<input type="checkbox" name="dokument" value="lebenslauf" data-dokument
<%= dokumentAuswahl.includes('lebenslauf') ? 'checked' : '' %>
class="rounded border-gray-300 dark:border-gray-600">
Lebenslauf
</label>
</div>
<p class="text-xs text-red-600 dark:text-red-400 mt-2 hidden" id="dokumentHinweis">
Bitte mindestens ein Dokument auswählen.
</p>
</div>
<!-- Optional extra attachments to enclose (vorbelegt aus den Einstellungen). -->
<div class="mt-4">
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Zusätzliche Anlagen</label>
<% if (basisAnhaenge && basisAnhaenge.length) { %>
<p class="text-xs text-gray-500 dark:text-gray-400 mb-2">
Wähle aus, welche Anlagen (z. B. Zeugnisse) mitgeschickt werden. Vorbelegt ist deine Auswahl
aus den <a href="/einstellungen" class="text-blue-600 dark:text-blue-400 hover:underline">Einstellungen</a>
(Standard: keine); die Auswahl wird auch im Anschreiben unter „Anlagen“ berücksichtigt.
</p>
<div class="space-y-1.5">
<% basisAnhaenge.forEach(function(ba){ %>
<label class="flex items-center gap-2 text-sm text-gray-700 dark:text-gray-200">
<input type="checkbox" name="anlage" value="<%= ba.id %>"
<%= anlagenAuswahl.includes(ba.id) ? 'checked' : '' %>
class="rounded border-gray-300 dark:border-gray-600 text-blue-600">
<%= ba.name || ba.dateiname %>
<% if (ba.name && ba.dateiname && ba.name !== ba.dateiname) { %>
<span class="text-xs text-gray-400">(<%= ba.dateiname %>)</span>
<% } %>
</label>
<% }); %>
</div>
<% } else { %>
<p class="text-xs text-gray-400 dark:text-gray-500">
Keine zusätzlichen Anlagen hinterlegt. Unter
<a href="/vorlagen" class="text-blue-600 dark:text-blue-400 hover:underline">Vorlagen</a>
kannst du statische Anlagen (z. B. Zeugnisse) hochladen.
</p>
<% } %>
</div>
<div class="flex justify-end mt-4">
<button type="submit" <%= genStatus === 'ausstehend' ? 'disabled' : '' %>
class="inline-flex items-center gap-1.5 px-4 py-2 text-sm bg-blue-600 hover:bg-blue-700 disabled:opacity-50 text-white rounded-md transition-colors">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7l9-11h-7z"></path>
</svg>
<%= genStatus === 'ausstehend' ? 'Wird generiert…' : (genStatus === 'fertig' ? 'Notizen speichern & neu generieren' : 'Unterlagen generieren') %>
</button>
</div>
</form>
<!-- Job description from the import -->
<% if (application.stellenbeschreibung && application.stellenbeschreibung.trim()) { %>
<details class="mt-6 rounded-lg border border-gray-200 dark:border-gray-700">
<summary class="cursor-pointer select-none px-4 py-3 text-sm font-medium text-gray-700 dark:text-gray-300">
Importierte Stellenbeschreibung anzeigen
</summary>
<div class="px-4 pb-4">
<% if (application.quelle_url) { %>
<a href="<%= safeUrl(application.quelle_url) %>" target="_blank" rel="noopener"
class="inline-block mb-3 text-sm text-blue-600 dark:text-blue-400 hover:underline break-all"><%= application.quelle_url %></a>
<% } %>
<p class="whitespace-pre-wrap break-words text-sm leading-relaxed text-gray-700 dark:text-gray-300"><%= application.stellenbeschreibung %></p>
</div>
</details>
<% } %>
</section>
<% } %>
<!-- E-Mail-Korrespondenz -->
<section id="korrespondenz" class="bg-white dark:bg-gray-800 rounded-lg shadow-md p-6 mb-8">
<div class="flex flex-wrap items-center justify-between gap-3 mb-4">
<h2 class="text-lg font-semibold text-gray-800 dark:text-white">E-Mail-Korrespondenz</h2>
<% if (mailConfigured) { %>
<form action="/email/fetch" method="POST" class="shrink-0">
<input type="hidden" name="back" value="/bewerbung/<%= application.id %>#korrespondenz">
<button type="submit" class="inline-flex items-center gap-1.5 px-3 py-1.5 text-sm border border-gray-300 dark:border-gray-600 rounded-md text-gray-700 dark:text-gray-200 hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"></path></svg>
Postfach abrufen
</button>
</form>
<% } %>
</div>
<% if (!mailConfigured) { %>
<div class="flex items-center gap-3 rounded-lg bg-yellow-50 dark:bg-yellow-900/30 border border-yellow-200 dark:border-yellow-800 px-4 py-3">
<svg class="w-5 h-5 text-yellow-600 dark:text-yellow-400" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"></path></svg>
<span class="text-sm text-yellow-800 dark:text-yellow-200">E-Mail ist nicht konfiguriert. Bitte <code>MAIL_HOST</code>, <code>MAIL_USER</code> und <code>MAIL_PASSWORD</code> in der <code>.env</code> setzen.</span>
</div>
<% } else { %>
<% if (mailError) { %>
<div class="rounded-lg bg-red-50 dark:bg-red-900/30 border border-red-200 dark:border-red-800 px-4 py-3 mb-4 text-sm text-red-800 dark:text-red-200"><%= mailError %></div>
<% } %>
<% if (mailOk) { %>
<div class="rounded-lg bg-green-50 dark:bg-green-900/30 border border-green-200 dark:border-green-800 px-4 py-3 mb-4 text-sm text-green-800 dark:text-green-200"><%= mailOk %></div>
<% } %>
<!-- Conversation thread -->
<% if (emails && emails.length) { %>
<ul class="space-y-3 mb-6">
<% emails.forEach(function(e){ var out = e.direction === 'out'; %>
<li class="rounded-lg border <%= out ? 'border-blue-200 dark:border-blue-800 bg-blue-50/60 dark:bg-blue-900/20' : 'border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-700/40' %> px-4 py-3">
<div class="flex flex-wrap items-center justify-between gap-2 mb-1">
<div class="flex items-center gap-2 min-w-0">
<span class="inline-flex items-center px-2 py-0.5 rounded text-xs font-medium <%= out ? 'bg-blue-600 text-white' : 'bg-gray-600 text-white' %>"><%= out ? 'Gesendet' : 'Empfangen' %></span>
<span class="text-sm text-gray-700 dark:text-gray-200 truncate">
<%= out ? ('An: ' + (e.to_addr || '')) : ('Von: ' + (e.from_addr || '')) %>
</span>
</div>
<span class="text-xs text-gray-500 dark:text-gray-400 shrink-0"><%= e.email_date ? new Date(e.email_date).toLocaleString('de-DE', { timeZone: 'Europe/Berlin' }) : '' %></span>
</div>
<p class="text-sm font-medium text-gray-800 dark:text-gray-100 mb-1"><%= e.subject || '(kein Betreff)' %></p>
<% if (e.display_srcdoc) { %>
<iframe class="email-html-frame w-full border border-gray-200 dark:border-gray-600 rounded bg-white" style="height:6rem"
sandbox="allow-same-origin" referrerpolicy="no-referrer"
srcdoc="<%= e.display_srcdoc %>"></iframe>
<% } else { %>
<p class="whitespace-pre-wrap break-words text-sm leading-relaxed text-gray-700 dark:text-gray-300"><%= e.body_text || '' %></p>
<% } %>
<% if (e.anhaenge && e.anhaenge.length) { %>
<div class="mt-2 flex flex-wrap gap-2">
<% e.anhaenge.forEach(function(a){ %>
<a href="/email-anhaenge/<%= a.id %>/download?inline=1" target="_blank" rel="noopener" class="inline-flex items-center gap-1 text-xs px-2 py-1 rounded border border-gray-300 dark:border-gray-600 text-blue-600 dark:text-blue-400 hover:underline">
<svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15.172 7l-6.586 6.586a2 2 0 102.828 2.828l6.414-6.586a4 4 0 00-5.656-5.656l-6.415 6.585a6 6 0 108.486 8.486L20.5 13"></path></svg>
<%= a.name || 'Anhang' %>
</a>
<% }); %>
</div>
<% } %>
<% if (!out) { %>
<div class="mt-2">
<button type="button" class="reply-toggle text-sm text-blue-600 hover:text-blue-800 dark:text-blue-400 hover:underline" data-target="reply-<%= e.id %>">Antworten</button>
</div>
<form action="/bewerbung/<%= application.id %>/email/send" method="POST" id="reply-<%= e.id %>" class="hidden mt-3 border-t border-gray-200 dark:border-gray-600 pt-3">
<input type="hidden" name="reply_to" value="<%= e.id %>">
<label class="block text-xs font-medium text-gray-500 dark:text-gray-400 mb-1">An</label>
<input type="email" name="to" required value="<%= e.from_addr_clean || '' %>"
class="w-full px-3 py-2 mb-2 border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-700 text-gray-800 dark:text-white text-sm">
<label class="block text-xs font-medium text-gray-500 dark:text-gray-400 mb-1">Betreff</label>
<input type="text" name="subject" value="<%= /^\s*(re|aw)\s*:/i.test(e.subject || '') ? (e.subject || '') : ('Re: ' + (e.subject || '')) %>"
class="reply-subject w-full px-3 py-2 mb-2 border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-700 text-gray-800 dark:text-white text-sm">
<!-- KI-Antwort: erst sagen, was drinstehen soll, dann generieren lassen.
Ohne Vorgabe kommt nur eine allgemeine Höflichkeitsantwort heraus. -->
<div class="mb-3 rounded-md border border-purple-200 dark:border-purple-800/60 bg-purple-50/60 dark:bg-purple-900/10 p-3">
<div class="flex flex-wrap items-center justify-between gap-2 mb-1.5">
<label for="ai-prompt-<%= e.id %>" class="flex items-center gap-1.5 text-xs font-medium text-purple-700 dark:text-purple-300">
<svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7l9-11h-7z"></path></svg>
Was soll die KI antworten?
</label>
<select class="ai-reply-typ text-xs px-1.5 py-0.5 border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-700 text-gray-700 dark:text-gray-200">
<option value="antwort">Antwort</option>
<option value="absage">Absage (andere Stelle)</option>
</select>
</div>
<textarea id="ai-prompt-<%= e.id %>" rows="2"
class="ai-reply-prompt w-full px-3 py-2 border border-purple-200 dark:border-purple-800/60 rounded-md bg-white dark:bg-gray-700 text-gray-800 dark:text-white text-sm leading-relaxed"
placeholder="z. B. Termin am Dienstag 14 Uhr zusagen, nach dem Ablauf des Gesprächs fragen oder: kürzer und förmlicher"></textarea>
<div class="flex flex-wrap items-center justify-between gap-2 mt-2">
<p class="ai-reply-status text-xs text-gray-500 dark:text-gray-400">
Ohne Vorgabe antwortet die KI nur allgemein auf die Nachricht.
</p>
<button type="button" class="ai-reply-btn inline-flex items-center gap-1.5 shrink-0 px-3 py-1.5 text-xs font-medium rounded-md bg-purple-600 hover:bg-purple-700 text-white transition-colors disabled:opacity-50 disabled:cursor-not-allowed"
data-email-id="<%= e.id %>" data-app-id="<%= application.id %>" data-target="reply-<%= e.id %>">
<svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7l9-11h-7z"></path></svg>
<span class="ai-reply-label">KI-Antwort generieren</span>
</button>
</div>
</div>
<label class="block text-xs font-medium text-gray-500 dark:text-gray-400 mb-1">Nachricht</label>
<textarea name="body" rows="12" required
class="reply-body w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-700 text-gray-800 dark:text-white text-sm leading-relaxed"><%= e.reply_quote ? '\n\n' + e.reply_quote : '' %></textarea>
<% if (basisAnhaenge && basisAnhaenge.length) { %>
<p class="text-xs font-medium text-gray-500 dark:text-gray-400 mt-2 mb-1">Anlagen</p>
<div class="space-y-1">
<% basisAnhaenge.forEach(function(ba){ %>
<label class="flex items-center gap-2 text-sm text-gray-700 dark:text-gray-200">
<input type="checkbox" name="basis_anlage" value="<%= ba.id %>"
class="rounded border-gray-300 dark:border-gray-600 text-blue-600">
<%= ba.name || ba.dateiname %>
<% if (ba.name && ba.dateiname && ba.name !== ba.dateiname) { %>
<span class="text-xs text-gray-400">(<%= ba.dateiname %>)</span>
<% } %>
</label>
<% }); %>
</div>
<% } %>
<div class="flex justify-end mt-2">
<button type="submit" class="inline-flex items-center gap-1.5 px-4 py-2 text-sm bg-blue-600 hover:bg-blue-700 text-white rounded-md transition-colors">Antwort senden</button>
</div>
</form>
<% } %>
</li>
<% }); %>
</ul>
<% } else { %>
<p class="text-sm text-gray-500 dark:text-gray-400 mb-6">Noch keine E-Mails. Sende die Bewerbung unten oder rufe das Postfach ab.</p>
<% } %>
<!-- Compose / send the application -->
<div class="border-t border-gray-200 dark:border-gray-700 pt-5">
<h3 class="text-sm font-semibold text-gray-800 dark:text-white mb-1">Bewerbung per E-Mail senden</h3>
<p class="text-xs text-gray-500 dark:text-gray-400 mb-3">
Versand über <code><%= mailFrom %></code>. Empfängeradresse eingeben, Betreff und Text prüfen,
Anhänge auswählen und senden.
</p>
<form action="/bewerbung/<%= application.id %>/email/send" method="POST"
onsubmit="return confirm('Bewerbung jetzt verbindlich an ' + (this.to.value.trim() || 'den Empfänger') + ' senden?');">
<label class="block text-xs font-medium text-gray-500 dark:text-gray-400 mb-1">Empfänger (E-Mail)</label>
<input type="email" name="to" required value="<%= application.email_empfaenger || '' %>"
placeholder="personal@unternehmen.de"
class="w-full px-3 py-2 mb-3 border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-700 text-gray-800 dark:text-white">
<label class="block text-xs font-medium text-gray-500 dark:text-gray-400 mb-1">Betreff</label>
<input type="text" name="subject" value="<%= application.email_betreff || ('Bewerbung als ' + (application.stelle || '')) %>"
class="w-full px-3 py-2 mb-3 border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-700 text-gray-800 dark:text-white">
<label class="block text-xs font-medium text-gray-500 dark:text-gray-400 mb-1">Nachricht</label>
<textarea name="body" rows="8"
class="w-full px-3 py-2 mb-3 border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-700 text-gray-800 dark:text-white leading-relaxed"><%= application.email_anschreiben || '' %></textarea>
<% if (anhaenge && anhaenge.length) { %>
<p class="text-xs font-medium text-gray-500 dark:text-gray-400 mb-1">Anhänge</p>
<div class="space-y-1 mb-3">
<% anhaenge.forEach(function(a){ %>
<label class="flex items-center gap-2 text-sm text-gray-700 dark:text-gray-200">
<input type="checkbox" name="anhang" value="<%= a.id %>" checked
class="rounded border-gray-300 dark:border-gray-600 text-blue-600">
<%= a.name || a.dateiname %> <span class="text-xs text-gray-400">(<%= a.dateiname %>)</span>
</label>
<% }); %>
</div>
<% } else { %>
<p class="text-xs text-gray-400 mb-3">Keine generierten Anhänge vorhanden - erst Unterlagen generieren.</p>
<% } %>
<div class="flex justify-end">
<button type="submit" class="inline-flex items-center gap-1.5 px-4 py-2 text-sm bg-green-600 hover:bg-green-700 text-white rounded-md transition-colors">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 19l9 2-9-18-9 18 9-2zm0 0v-8"></path></svg>
Bewerbung senden
</button>
</div>
</form>
</div>
<% } %>
</section>
</div>
</div>
</main> </main>
<%- include('partials/footer') %> <%- include('partials/footer') %>