Design der Unterlagen unter Vorlagen einstellbar

Akzentfarbe, Sidebar-Hintergrund, Foto (an/aus, eckig/rund) und Schriftgroesse
lagen als Konstanten im Renderer. Sie kommen jetzt aus lib/design.js und sind
unter Vorlagen waehlbar, inklusive Vorschau-PDF mit Musterinhalten - die zeigt
das Ergebnis, ohne dass die KI laufen muss.

Bewusst geschlossen gehalten: die Palette ist eine kurze Liste gedeckter Toene
(kein freier Color-Picker), Grauwerte und Grundlayout bleiben fest. Die
Schriftgroesse ist nur der Startwert der Seitenskalierung - der Lebenslauf passt
weiterhin garantiert auf eine Seite.

Das Theme wird durch die Render-Funktionen gereicht statt als Modulzustand
gesetzt, damit spaeter mehrere Bewerber parallel generieren koennen, ohne sich
gegenseitig das Design umzustellen.

Rundes Foto: das Bild fuellt den Kreis formatfuellend und zentriert (Clip statt
Skalieren), sonst wuerde ein Hochformat-Foto im Quadrat gestaucht.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-13 00:51:36 +02:00
co-authored by Claude Opus 4.8
parent 65a5943993
commit 9f7349af4e
4 changed files with 546 additions and 128 deletions
+82
View File
@@ -252,6 +252,72 @@
</form>
</section>
<!-- Design of the generated PDFs -->
<h2 id="design" class="text-xl font-bold text-gray-800 dark:text-white mt-10 mb-2 scroll-mt-4">Design der Unterlagen</h2>
<p class="text-sm text-gray-500 dark:text-gray-400 mb-6">
Aussehen von Anschreiben und Lebenslauf. Das Grundlayout (Aufbau, Seitenränder, DIN-gerechter Brief)
bleibt fest der Lebenslauf passt immer auf eine Seite. Die Vorschau zeigt Musterinhalte mit deinem
Namen, Foto und deiner Unterschrift, ohne dass die KI läuft.
</p>
<section class="bg-white dark:bg-gray-800 rounded-lg shadow-md p-6 mb-8">
<form action="/vorlagen/design" method="POST" class="space-y-4" id="designForm">
<div class="grid gap-4 sm:grid-cols-2">
<% designFelder.forEach(f => { %>
<div>
<label class="block text-xs font-medium text-gray-500 dark:text-gray-400 mb-1"><%= f.label %></label>
<select name="<%= f.key %>" <%= f.optionen.length < 2 ? 'disabled' : '' %>
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-900 dark:text-white disabled:opacity-60">
<% f.optionen.forEach(o => { %>
<option value="<%= o.key %>" <%= o.gewaehlt ? 'selected' : '' %>><%= o.label %></option>
<% }) %>
</select>
<% if (f.optionen.length < 2) { %>
<input type="hidden" name="<%= f.key %>" value="<%= f.aktuell %>">
<p class="text-xs text-gray-400 dark:text-gray-500 mt-1">Weitere Layouts folgen.</p>
<% } %>
</div>
<% }) %>
</div>
<!-- The hidden field must come first: when the box is checked both
values are submitted and the *last* one wins. -->
<input type="hidden" name="foto_anzeigen" value="0">
<label class="flex items-center gap-2 text-sm text-gray-700 dark:text-gray-300">
<input type="checkbox" name="foto_anzeigen" value="1" <%= designFotoAn ? 'checked' : '' %>
class="rounded border-gray-300 dark:border-gray-600">
Bewerberfoto im Lebenslauf anzeigen
<% if (!hasFoto) { %>
<span class="text-xs text-gray-400 dark:text-gray-500">(noch kein Foto hinterlegt)</span>
<% } %>
</label>
<div class="flex flex-wrap items-center gap-3 border-t border-gray-200 dark:border-gray-700 pt-4">
<button type="submit" class="px-4 py-2 bg-green-600 hover:bg-green-700 text-white rounded-md transition-colors">
Speichern
</button>
<button type="button" id="vorschauAnschreiben"
class="px-4 py-2 border border-gray-300 dark:border-gray-600 text-gray-700 dark:text-gray-200 rounded-md hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors">
Vorschau Anschreiben
</button>
<button type="button" id="vorschauLebenslauf"
class="px-4 py-2 border border-gray-300 dark:border-gray-600 text-gray-700 dark:text-gray-200 rounded-md hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors">
Vorschau Lebenslauf
</button>
<% if (designAngepasst) { %>
<button type="submit" formaction="/vorlagen/design/reset" formnovalidate
onclick="return confirm('Design auf die Standardwerte zurücksetzen?');"
class="text-sm text-gray-600 dark:text-gray-400 hover:underline">
Auf Standard zurücksetzen
</button>
<% } %>
</div>
<p class="text-xs text-gray-400 dark:text-gray-500">
Die Vorschau zeigt die aktuell <em>ausgewählten</em> Werte auch ungespeicherte.
</p>
</form>
</section>
<!-- Editable KI prompts -->
<h2 id="prompts" class="text-xl font-bold text-gray-800 dark:text-white mt-10 mb-2 scroll-mt-4">KI-Prompts</h2>
<p class="text-sm text-gray-500 dark:text-gray-400 mb-6">
@@ -336,6 +402,22 @@
const cy = document.getElementById('currentYear');
if (cy) cy.textContent = new Date().getFullYear();
})();
// Design preview: open the sample PDF with the values currently selected
// in the form (not just the saved ones), so a choice can be judged before
// it is committed.
(function () {
const form = document.getElementById('designForm');
if (!form) return;
function oeffne(welches) {
const q = new URLSearchParams(new FormData(form)).toString();
window.open('/vorlagen/design/vorschau/' + welches + '.pdf?' + q, '_blank');
}
const a = document.getElementById('vorschauAnschreiben');
const l = document.getElementById('vorschauLebenslauf');
if (a) a.addEventListener('click', () => oeffne('anschreiben'));
if (l) l.addEventListener('click', () => oeffne('lebenslauf'));
})();
</script>
</body>
</html>