| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479 |
- <!DOCTYPE html>
- <html lang="de" xmlns:th="http://www.thymeleaf.org">
- <head>
- <meta charset="UTF-8"/>
- <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
- <title>DIWO Vergleich – Haushaltsmitglieder/Einkommen</title>
- <link rel="stylesheet" href="/styles.css"/>
- </head>
- <body>
- <header class="diwo-header" role="banner">
- <div class="header-row-1">
- <div class="kunde-logo">
- <div th:if="${activeKunde != null and !#strings.isEmpty(activeKunde)}" class="kunde-logo-container">
- <img th:src="@{'/images/' + ${#strings.toLowerCase(activeKunde)} + '.jpg'}"
- th:alt="${activeKunde != null and !#strings.isEmpty(activeKunde) ? activeKunde + ' Logo' : 'Kunden-Logo'}"
- class="kunde-logo-image"
- th:onerror="'this.style.display=\\'none\\''"/>
- </div>
- </div>
- <div class="diwo-title">
- <h1>DIWO</h1>
- <h2>Vergleich</h2>
- </div>
- <div class="page-title" role="heading" aria-level="2">Haushaltsmitglieder/Einkommen</div>
- </div>
-
- <div class="header-row-2">
- <div class="aktenzeichen" th:if="${stammakteRight != null and !#strings.isEmpty(stammakteRight.aktenzeichen)}" role="contentinfo" aria-label="Aktenzeichen">
- <span th:text="${stammakteRight.aktenzeichen}">01/01/119979</span>
- </div>
- <div class="aktenzeichen" th:if="${(stammakteRight == null or #strings.isEmpty(stammakteRight.aktenzeichen)) and stammvorgangRight != null}" role="contentinfo" aria-label="Aktenzeichen">
- <span th:text="${stammvorgangRight.aktenzeichen}">01/01/119979</span>
- </div>
-
- <div class="antragsteller-info" th:if="${stammakteRight != null}" role="contentinfo" aria-label="Antragsteller-Informationen">
- <span th:if="${!#strings.isEmpty(stammakteRight.antragstellername)}" th:text="${stammakteRight.antragstellername}">Müller, Tobias</span>
- <span th:if="${!#strings.isEmpty(stammakteRight.antragstellerGeburtsdatum)}"> - <span th:text="${stammakteRight.antragstellerGeburtsdatum}">01.01.2000</span></span>
- </div>
-
- <div class="location-info" th:if="${stammakteRight != null and !#strings.isEmpty(stammakteRight.anschrift)}" role="contentinfo" aria-label="Anschrift">
- <span th:text="${stammakteRight.anschrift}">Unter den Linden 1, 10117 Berlin</span>
- </div>
- </div>
-
- <div class="header-row-3">
- <div class="vorgang-info" th:if="${stammvorgangRight != null}" role="contentinfo" aria-label="Vorgang in Bearbeitung">
- <span>Vorgang in der Bearbeitung: </span>
- <span th:if="${!#strings.isEmpty(stammvorgangRight.bemerkung)}" th:text="${stammvorgangRight.bemerkung}">Weiterleistungsantrag</span>
- <span th:if="${#strings.isEmpty(stammvorgangRight.bemerkung)}">-</span>
- <span th:if="${!#strings.isEmpty(stammvorgangRight.beginn) and !#strings.isEmpty(stammvorgangRight.ende)}">
- (<span th:text="${stammvorgangRight.beginn}">01.01.2026</span> - <span th:text="${stammvorgangRight.ende}">31.12.2027</span>)
- </span>
- </div>
-
- <div class="zeitraum-controls">
- <form method="post" action="/vergleich" class="zeitraum-form" role="form" aria-label="Zeitraum wechseln">
- <input type="hidden" name="schemaName" th:value="${schemaName}"/>
- <input type="hidden" name="validate" th:value="${validate}"/>
- <input type="hidden" name="leftJson" th:value="${leftJson}"/>
- <input type="hidden" name="rightJson" th:value="${rightJson}"/>
- <input type="hidden" name="leftVorgangId" th:value="${leftVorgangId}"/>
- <input type="hidden" name="leftZeitraumId" th:value="${leftZeitraumId}"/>
- <input type="hidden" name="kunde" th:value="${activeKunde}"/>
-
- <label for="rightZeitraumId">Zeitraum:</label>
- <select name="rightZeitraumId" id="rightZeitraumId" class="zeitraum-select" aria-describedby="zeitraum-hint">
- <option th:each="z : ${zeitraeumeRight}" th:value="${z.id}"
- th:selected="${z.id == rightZeitraumId}"
- th:text="${z.beginn} + ' - ' + ${z.ende}"></option>
- </select>
- <button type="submit" class="wechseln-btn" aria-label="Zeitraum wechseln">▼</button>
- </form>
- </div>
- </div>
- </header>
- <!-- Vergleichslegende -->
- <section class="vergleich-legende" role="complementary" aria-labelledby="legende-title">
- <div class="legende-title" id="legende-title">
- <strong>Legende:</strong>
- </div>
- <div class="legende-item">
- <span class="sym plus" aria-label="Hinzugefügt">+</span>
- <span>hinzugefügt (<span id="addedColorName">grün</span>)</span>
- </div>
- <div class="legende-spacer" aria-hidden="true">|</div>
- <div class="legende-item">
- <span class="sym minus" aria-label="Gelöscht">−</span>
- <span>gelöscht (<span id="removedColorName">rot</span>)</span>
- </div>
- <div class="legende-spacer" aria-hidden="true">|</div>
- <div class="legende-item">
- <span class="sym warn" aria-label="Geändert">!</span>
- <span>geändert (<span id="changedColorName">gelb</span>)</span>
- </div>
- <div class="legende-spacer" aria-hidden="true">|</div>
- <div class="legende-item">
- <span class="selected-indicator-text">ausgewählte Person (blauer Rahmen)</span>
- </div>
-
- <!-- Farbwahl -->
- <div class="color-picker-container">
- <button class="color-picker-toggle" onclick="toggleColorPicker()" aria-label="Farbschema-Einstellungen öffnen" aria-expanded="false" aria-controls="colorPickerPopup">⚙️</button>
- <div class="color-picker-popup hidden" id="colorPickerPopup" role="dialog" aria-labelledby="color-picker-label">
- <label id="color-picker-label" for="colorSchemeSelect">Farbwahl:</label>
- <select id="colorSchemeSelect" class="color-scheme-select" onchange="changeColorScheme(this.value)" aria-describedby="color-scheme-hint">
- <option value="standard">Standard</option>
- <option value="alternative">Pastell</option>
- </select>
- </div>
- </div>
- </section>
- <!-- Haushaltsmitglieder - klickbare Zeilen -->
- <main role="main">
- <div class="section-container">
- <div class="section-header" onclick="toggleSection('haushaltsmitglieder')" role="button" tabindex="0"
- onkeypress="handleKeyPress(event, 'haushaltsmitglieder')" aria-expanded="true" aria-controls="haushaltsmitglieder-content">
- <span class="toggle-icon" id="haushaltsmitglieder-icon" aria-hidden="true">▼</span>
- <h3>Haushaltsmitglieder</h3>
- </div>
- <div class="section-content" id="haushaltsmitglieder-content">
- <table role="table" aria-labelledby="haushaltsmitglieder-caption">
- <thead>
- <tr>
- <th scope="col">Änderung</th>
- <th scope="col">Name</th>
- <th scope="col">Geburtsdatum</th>
- <th scope="col">Familienstand</th>
- <th scope="col">Geschlecht</th>
- <th scope="col">Verwandtschaft</th>
- <th scope="col">Sozialstellung</th>
- <th scope="col">Kind</th>
- </tr>
- </thead>
- <tbody>
- <tr th:each="r : ${mitgliederRows}"
- th:class="'person-row ' + ${r.rowClass} + ((${r.personId} == ${personId}) ? ' person-selected' : '')"
- th:data-person-id="${r.personId}"
- role="button"
- tabindex="0"
- th:aria-label="'Person auswählen: ' + ${r.nameHtml}"
- onkeypress="handleRowKeyPress(event, this)">
- <td class="sym" th:classappend="' ' + ${r.symbolClass}" th:text="${r.symbol}"
- th:aria-label="${r.symbol == '+' ? 'Hinzugefügt' : (r.symbol == '-' ? 'Gelöscht' : (r.symbol == '!' ? 'Geändert' : 'Unverändert'))}"></td>
- <td th:utext="${r.nameHtml}"></td>
- <td th:utext="${r.geburtsdatumHtml}"></td>
- <td th:utext="${r.familienstandHtml}"></td>
- <td th:utext="${r.geschlechtHtml}"></td>
- <td th:utext="${r.verwandtschaftHtml}"></td>
- <td th:utext="${r.sozialstellungHtml}"></td>
- <td th:utext="${r.istKindHtml}"></td>
- </tr>
- </tbody>
- </table>
- </div>
- </div>
- <!-- Hidden form for person selection -->
- <form id="personForm" method="post" action="/vergleich" style="display: none;" aria-hidden="true">
- <input type="hidden" name="leftJson" th:value="${leftJson}"/>
- <input type="hidden" name="rightJson" th:value="${rightJson}"/>
- <input type="hidden" name="validate" th:value="${validate}"/>
- <input type="hidden" name="schemaName" th:value="${schemaName}"/>
- <input type="hidden" name="leftVorgangId" th:value="${leftVorgangId}"/>
- <input type="hidden" name="leftZeitraumId" th:value="${leftZeitraumId}"/>
- <input type="hidden" name="rightZeitraumId" th:value="${rightZeitraumId}"/>
- <input type="hidden" name="kunde" th:value="${activeKunde}"/>
- <input type="hidden" name="personId" id="selectedPersonId"/>
- </form>
- <h2>Details zu <span th:if="${personLabel != null and !#strings.isEmpty(personLabel) and personLabel != '(keine Person)'}"><span th:text="${personLabel}"> - </span></span></h2>
-
- <!-- Einkommen -->
- <div class="section-container">
- <div class="section-header" onclick="toggleSection('einkommen')" role="button" tabindex="0"
- onkeypress="handleKeyPress(event, 'einkommen')" aria-expanded="true" aria-controls="einkommen-content">
- <span class="toggle-icon" id="einkommen-icon" aria-hidden="true">▼</span>
- <h3>Einkommen</h3>
- </div>
- <div class="section-content" id="einkommen-content">
- <table role="table" aria-labelledby="einkommen-caption">
- <thead>
- <tr>
- <th scope="col">Änderung</th>
- <th scope="col">Art</th>
- <th scope="col">Frequenz</th>
- <th scope="col">Betrag</th>
- <th scope="col">Zuschlag</th>
- <th scope="col">Abschlag</th>
- <th scope="col">Werbungskosten</th>
- <th scope="col">Berechnungsart</th>
- </tr>
- </thead>
- <tbody>
- <tr th:each="z : ${einkommenZeilen}" th:class="${z.rowClass}">
- <td class="sym" th:classappend="' ' + ${z.symbolClass}" th:text="${z.symbol}"
- th:aria-label="${z.symbol == '+' ? 'Hinzugefügt' : (z.symbol == '-' ? 'Gelöscht' : (z.symbol == '!' ? 'Geändert' : 'Unverändert'))}"></td>
- <td th:utext="${z.artHtml}"></td>
- <td th:utext="${z.frequenzHtml}"></td>
- <td th:utext="${z.betragHtml}"></td>
- <td th:utext="${z.zuschlagHtml}"></td>
- <td th:utext="${z.abschlagHtml}"></td>
- <td th:utext="${z.werbungskostenHtml}"></td>
- <td th:utext="${z.berechnungsartHtml}"></td>
- </tr>
- </tbody>
- </table>
- </div>
- </div>
- <div class="freibetrag-container">
- <div class="freibetrag-section">
- <div class="section-container">
- <div class="section-header" onclick="toggleSection('pauschale')" role="button" tabindex="0"
- onkeypress="handleKeyPress(event, 'pauschale')" aria-expanded="true" aria-controls="pauschale-content">
- <span class="toggle-icon" id="pauschale-icon" aria-hidden="true">▼</span>
- <h3>Pauschale Abzüge</h3>
- </div>
- <div class="section-content" id="pauschale-content">
- <table role="table" aria-labelledby="pauschale-caption">
- <thead>
- <tr>
- <th scope="col">Änderung</th>
- <th scope="col">Art</th>
- <th scope="col">Frequenz</th>
- <th scope="col">Betrag</th>
- </tr>
- </thead>
- <tbody>
- <tr th:each="z : ${freibetragZeilen}" th:if="${z.typ == 'P'}" th:class="${z.rowClass}">
- <td class="sym" th:classappend="' ' + ${z.symbolClass}" th:text="${z.symbol}"
- th:aria-label="${z.symbol == '+' ? 'Hinzugefügt' : (z.symbol == '-' ? 'Gelöscht' : (z.symbol == '!' ? 'Geändert' : 'Unverändert'))}"></td>
- <td th:utext="${z.artHtml}"></td>
- <td th:utext="${z.frequenzHtml}"></td>
- <td th:utext="${z.betragHtml}"></td>
- </tr>
- </tbody>
- </table>
- </div>
- </div>
- </div>
-
- <div class="freibetrag-section">
- <div class="section-container">
- <div class="section-header" onclick="toggleSection('freibetraege')" role="button" tabindex="0"
- onkeypress="handleKeyPress(event, 'freibetraege')" aria-expanded="true" aria-controls="freibetraege-content">
- <span class="toggle-icon" id="freibetraege-icon" aria-hidden="true">▼</span>
- <h3>Freibeträge</h3>
- </div>
- <div class="section-content" id="freibetraege-content">
- <table role="table" aria-labelledby="freibetraege-caption">
- <thead>
- <tr>
- <th scope="col">Änderung</th>
- <th scope="col">Art</th>
- <th scope="col">Frequenz</th>
- <th scope="col">Betrag</th>
- <th scope="col">Frist</th>
- </tr>
- </thead>
- <tbody>
- <tr th:each="z : ${freibetragZeilen}" th:if="${z.typ == 'F'}" th:class="${z.rowClass}">
- <td class="sym" th:classappend="' ' + ${z.symbolClass}" th:text="${z.symbol}"
- th:aria-label="${z.symbol == '+' ? 'Hinzugefügt' : (z.symbol == '-' ? 'Gelöscht' : (z.symbol == '!' ? 'Geändert' : 'Unverändert'))}"></td>
- <td th:utext="${z.artHtml}"></td>
- <td th:utext="${z.frequenzHtml}"></td>
- <td th:utext="${z.betragHtml}"></td>
- <td th:utext="${z.fristHtml}"></td>
- </tr>
- </tbody>
- </table>
- </div>
- </div>
- </div>
- </div>
- <!-- Kinderbetreuungskosten -->
- <div class="kinderbetreuung-container">
- <div class="section-container">
- <div class="section-header" onclick="toggleSection('kinderbetreuung')" role="button" tabindex="0"
- onkeypress="handleKeyPress(event, 'kinderbetreuung')" aria-expanded="true" aria-controls="kinderbetreuung-content">
- <span class="toggle-icon" id="kinderbetreuung-icon" aria-hidden="true">▼</span>
- <h3>Kinderbetreuungskosten</h3>
- </div>
- <div class="section-content" id="kinderbetreuung-content">
- <table role="table" aria-labelledby="kinderbetreuung-caption">
- <thead>
- <tr>
- <th scope="col">Änderung</th>
- <th scope="col">Kind</th>
- <th scope="col">Betrag</th>
- </tr>
- </thead>
- <tbody>
- <tr th:each="z : ${kitaZeilen}" th:class="${z.rowClass}">
- <td class="sym" th:classappend="' ' + ${z.symbolClass}" th:text="${z.symbol}"
- th:aria-label="${z.symbol == '+' ? 'Hinzugefügt' : (z.symbol == '-' ? 'Gelöscht' : (z.symbol == '!' ? 'Geändert' : 'Unverändert'))}"></td>
- <td th:utext="${z.kindNameHtml}"></td>
- <td th:utext="${z.betragHtml}"></td>
- </tr>
- </tbody>
- </table>
- </div>
- </div>
- </div>
- </main>
- <script>
- // Cookie Verwaltung
- function setCookie(name, value, days) {
- const expires = new Date();
- expires.setTime(expires.getTime() + (days * 24 * 60 * 60 * 1000));
- document.cookie = name + '=' + value + ';expires=' + expires.toUTCString() + ';path=/';
- }
- function getCookie(name) {
- const nameEQ = name + '=';
- const ca = document.cookie.split(';');
- for(let i = 0; i < ca.length; i++) {
- let c = ca[i];
- while (c.charAt(0) === ' ') c = c.substring(1, c.length);
- if (c.indexOf(nameEQ) === 0) return c.substring(nameEQ.length, c.length);
- }
- return null;
- }
- // Keyboard support for toggles
- function handleKeyPress(event, sectionId) {
- if (event.key === 'Enter' || event.key === ' ') {
- event.preventDefault();
- toggleSection(sectionId);
- }
- }
- // Keyboard support for table rows
- function handleRowKeyPress(event, row) {
- if (event.key === 'Enter' || event.key === ' ') {
- event.preventDefault();
- row.click();
- }
- }
- // Farbwahl-Funktionen
- function toggleColorPicker() {
- const popup = document.getElementById('colorPickerPopup');
- const button = document.querySelector('.color-picker-toggle');
- const isHidden = popup.classList.contains('hidden');
-
- popup.classList.toggle('hidden');
- button.setAttribute('aria-expanded', !isHidden);
-
- if (!isHidden) {
- // Focus the select when opening
- document.getElementById('colorSchemeSelect').focus();
- }
- }
- function updateColorNames(scheme) {
- const colorNames = {
- 'standard': { added: 'grün', removed: 'rot', changed: 'gelb' },
- 'alternative': { added: 'blau', removed: 'pink', changed: 'orange' }
- };
-
- const names = colorNames[scheme] || colorNames['standard'];
-
- document.getElementById('addedColorName').textContent = names.added;
- document.getElementById('removedColorName').textContent = names.removed;
- document.getElementById('changedColorName').textContent = names.changed;
- }
- function changeColorScheme(scheme) {
- const html = document.documentElement;
-
- // Entferne alle existierenden Farbschema-Attribute
- html.removeAttribute('data-color-scheme');
-
- // Setze das neue Farbschema (außer für "standard")
- if (scheme !== 'standard') {
- html.setAttribute('data-color-scheme', scheme);
- }
-
- // Aktualisiere die Farbnamen in der Legende
- updateColorNames(scheme);
-
- // Speichere die Auswahl im Cookie (365 Tage gültig)
- setCookie('colorScheme', scheme, 365);
-
- // Schließe das Popup nach der Auswahl
- const popup = document.getElementById('colorPickerPopup');
- const button = document.querySelector('.color-picker-toggle');
- popup.classList.add('hidden');
- button.setAttribute('aria-expanded', 'false');
- }
- function initializeColorScheme() {
- // Lade das gespeicherte Farbschema aus dem Cookie (Standard: "standard" = Ihre ursprünglichen Farben)
- const savedScheme = getCookie('colorScheme') || 'standard';
-
- // Setze das Farbschema
- const html = document.documentElement;
- if (savedScheme !== 'standard') {
- html.setAttribute('data-color-scheme', savedScheme);
- }
-
- // Aktualisiere die Farbnamen
- updateColorNames(savedScheme);
-
- // Setze den Wert in der Dropdown-Box
- const select = document.getElementById('colorSchemeSelect');
- if (select) {
- select.value = savedScheme;
- }
- }
- // Escape key support for popup
- document.addEventListener('keydown', function(event) {
- if (event.key === 'Escape') {
- const popup = document.getElementById('colorPickerPopup');
- const button = document.querySelector('.color-picker-toggle');
- if (!popup.classList.contains('hidden')) {
- popup.classList.add('hidden');
- button.setAttribute('aria-expanded', 'false');
- button.focus();
- }
- }
- });
- // Schließe das Popup wenn außerhalb geklickt wird
- document.addEventListener('click', function(event) {
- const container = document.querySelector('.color-picker-container');
- const popup = document.getElementById('colorPickerPopup');
- const button = document.querySelector('.color-picker-toggle');
-
- if (container && !container.contains(event.target)) {
- popup.classList.add('hidden');
- button.setAttribute('aria-expanded', 'false');
- }
- });
- // Toggle-Funktion für ausklappbare Sektionen
- function toggleSection(sectionId) {
- const content = document.getElementById(sectionId + '-content');
- const icon = document.getElementById(sectionId + '-icon');
- const header = content.parentElement.querySelector('.section-header');
-
- if (content.classList.contains('collapsed')) {
- content.classList.remove('collapsed');
- icon.classList.remove('collapsed');
- icon.textContent = '▼';
- header.setAttribute('aria-expanded', 'true');
- } else {
- content.classList.add('collapsed');
- icon.classList.add('collapsed');
- icon.textContent = '▶';
- header.setAttribute('aria-expanded', 'false');
- }
- }
- document.addEventListener('DOMContentLoaded', function() {
- // Initialisiere das Farbschema
- initializeColorScheme();
-
- // Add click event listeners to all person rows
- const personRows = document.querySelectorAll('.person-row');
- personRows.forEach(function(row) {
- row.addEventListener('click', function() {
- const personId = this.dataset.personId;
- if (personId) {
- document.getElementById('selectedPersonId').value = personId;
- document.getElementById('personForm').submit();
- }
- });
- });
- });
- </script>
- </body>
- </html>
|