* apply: Recorder.step_snap(page, name) captures both a JPEG screenshot and the page HTML for every major moment; every provider now calls step_snap at each logical step so failure reports contain the exact DOM and rendered state at every stage of the flow * ZIP report: each snapshot becomes snapshots/NN_<label>.jpg + snapshots/NN_<label>.html for AI-assisted debugging * web: Wohnungsliste zeigt nur noch Flats, die die eigenen Filter treffen; Match-Chip entfernt (Liste ist jetzt implizit matchend) * UI komplett auf Deutsch: Protokoll statt Logs, Administrator statt admin, Trockenmodus statt dry-run, Automatik pausiert statt circuit open, Alarm statt Alert, Abmelden statt Logout * Wohnungen-Header: Zeile 1 Info (Alarm + Filter), Zeile 2 Schalter mit echten Radio-Paaren (An/Aus) für Automatisch bewerben und Trockenmodus; hx-confirm auf den kritischen Radios; per-form CSS für sichtbaren Check-State * Protokoll: von/bis-Datumsfilter (Berliner Zeit) + CSV-Download (/logs/export.csv) mit UTC + lokaler Zeit Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
111 lines
4.9 KiB
HTML
111 lines
4.9 KiB
HTML
<h2 class="font-semibold mb-4">Bewerbungsdaten</h2>
|
|
|
|
<form method="post" action="/actions/profile" class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
<input type="hidden" name="csrf" value="{{ csrf }}">
|
|
|
|
<div>
|
|
<label class="block text-xs uppercase text-slate-500 mb-1">Anrede</label>
|
|
<select class="input" name="salutation">
|
|
{% for s in ['Herr', 'Frau', 'Divers'] %}
|
|
<option value="{{ s }}" {% if profile.salutation == s %}selected{% endif %}>{{ s }}</option>
|
|
{% endfor %}
|
|
</select>
|
|
</div>
|
|
<div></div>
|
|
|
|
<div>
|
|
<label class="block text-xs uppercase text-slate-500 mb-1">Vorname</label>
|
|
<input class="input" name="firstname" value="{{ profile.firstname }}">
|
|
</div>
|
|
<div>
|
|
<label class="block text-xs uppercase text-slate-500 mb-1">Nachname</label>
|
|
<input class="input" name="lastname" value="{{ profile.lastname }}">
|
|
</div>
|
|
|
|
<div>
|
|
<label class="block text-xs uppercase text-slate-500 mb-1">E-Mail</label>
|
|
<input class="input" type="email" name="email" value="{{ profile.email }}">
|
|
</div>
|
|
<div>
|
|
<label class="block text-xs uppercase text-slate-500 mb-1">Telefon</label>
|
|
<input class="input" name="telephone" value="{{ profile.telephone }}">
|
|
</div>
|
|
|
|
<div>
|
|
<label class="block text-xs uppercase text-slate-500 mb-1">Straße</label>
|
|
<input class="input" name="street" value="{{ profile.street }}">
|
|
</div>
|
|
<div>
|
|
<label class="block text-xs uppercase text-slate-500 mb-1">Hausnummer</label>
|
|
<input class="input" name="house_number" value="{{ profile.house_number }}">
|
|
</div>
|
|
|
|
<div>
|
|
<label class="block text-xs uppercase text-slate-500 mb-1">PLZ</label>
|
|
<input class="input" name="postcode" value="{{ profile.postcode }}">
|
|
</div>
|
|
<div>
|
|
<label class="block text-xs uppercase text-slate-500 mb-1">Stadt</label>
|
|
<input class="input" name="city" value="{{ profile.city }}">
|
|
</div>
|
|
|
|
<div class="col-span-1 md:col-span-2 mt-4 border-t border-soft pt-4">
|
|
<h3 class="font-semibold mb-2">WBS</h3>
|
|
</div>
|
|
<label class="col-span-1 md:col-span-2 inline-flex items-center gap-2">
|
|
<input type="checkbox" name="is_possessing_wbs" {% if profile.is_possessing_wbs %}checked{% endif %}>
|
|
<span class="text-sm">WBS vorhanden</span>
|
|
</label>
|
|
<div>
|
|
<label class="block text-xs uppercase text-slate-500 mb-1">WBS-Typ</label>
|
|
<input class="input" name="wbs_type" value="{{ profile.wbs_type }}" placeholder="z.B. 180">
|
|
</div>
|
|
<div>
|
|
<label class="block text-xs uppercase text-slate-500 mb-1">gültig bis</label>
|
|
<input class="input" type="date" name="wbs_valid_till" value="{{ profile.wbs_valid_till }}">
|
|
</div>
|
|
<div>
|
|
<label class="block text-xs uppercase text-slate-500 mb-1">Räume</label>
|
|
<input class="input" type="number" name="wbs_rooms" value="{{ profile.wbs_rooms }}" min="0">
|
|
</div>
|
|
<div>
|
|
<label class="block text-xs uppercase text-slate-500 mb-1">Erwachsene</label>
|
|
<input class="input" type="number" name="wbs_adults" value="{{ profile.wbs_adults }}" min="0">
|
|
</div>
|
|
<div>
|
|
<label class="block text-xs uppercase text-slate-500 mb-1">Kinder</label>
|
|
<input class="input" type="number" name="wbs_children" value="{{ profile.wbs_children }}" min="0">
|
|
</div>
|
|
<label class="inline-flex items-center gap-2 mt-6">
|
|
<input type="checkbox" name="is_prio_wbs" {% if profile.is_prio_wbs %}checked{% endif %}>
|
|
<span class="text-sm">Prio-WBS (besonderer Wohnbedarf)</span>
|
|
</label>
|
|
|
|
<div class="col-span-1 md:col-span-2 mt-4 border-t border-soft pt-4">
|
|
<h3 class="font-semibold mb-2">Immomio-Login (optional)</h3>
|
|
<p class="text-xs text-slate-500 mb-2">
|
|
Wird von Anbietern benötigt, die über immomio/tenant vermitteln (z.B. gesobau.de).
|
|
</p>
|
|
</div>
|
|
<div>
|
|
<label class="block text-xs uppercase text-slate-500 mb-1">Immomio-Email</label>
|
|
<input class="input" type="email" name="immomio_email" value="{{ profile.immomio_email }}">
|
|
</div>
|
|
<div>
|
|
<label class="block text-xs uppercase text-slate-500 mb-1">Immomio-Passwort</label>
|
|
<input class="input" type="password" name="immomio_password" value="{{ profile.immomio_password }}" placeholder="(unverändert lassen = leer)">
|
|
</div>
|
|
|
|
<div class="col-span-1 md:col-span-2">
|
|
<button class="btn btn-primary" type="submit">Speichern</button>
|
|
</div>
|
|
</form>
|
|
|
|
<hr class="my-6 border-soft">
|
|
<h3 class="font-semibold mb-2">Trockenmodus</h3>
|
|
<p class="text-sm text-slate-600 mb-3">
|
|
<span class="chip chip-warn">experimentell</span>
|
|
Im Trockenmodus wird das Formular ausgefüllt, aber nicht abgesendet. Erst deaktivieren,
|
|
wenn du jeden Anbieter einmal im Trockenmodus erfolgreich getestet hast — den Schalter
|
|
findest du auch oben auf der Wohnungen-Seite.
|
|
</p>
|