diff --git a/app/static/app/js/UpdateInfoControl.js b/app/static/app/js/UpdateInfoControl.js index f9ff6f5..9d3adf8 100644 --- a/app/static/app/js/UpdateInfoControl.js +++ b/app/static/app/js/UpdateInfoControl.js @@ -4,6 +4,7 @@ function setUpdateOk() { document.getElementById('update_content').style.display = 'none'; document.getElementById('dashboard').classList.remove('d-none'); document.getElementById('refresh_icon').classList.remove('d-none') + document.getElementById('share_icon').classList.remove('d-none') document.getElementById('settings_icon').classList.remove('d-none') } diff --git a/app/static/app/js/home01.js b/app/static/app/js/home01.js index c492c1e..f4cf753 100644 --- a/app/static/app/js/home01.js +++ b/app/static/app/js/home01.js @@ -18,6 +18,10 @@ const sortFieldMenu = document.getElementById('sortFieldMenu') const sortFieldOptions = document.querySelectorAll('.sortFieldOption') const sortDirectionToggle = document.getElementById('sortDirectionToggle') const sortDirectionIcon = document.getElementById('sortDirectionIcon') +const shareIcon = document.getElementById('share_icon') +const shareReportModalEl = document.getElementById('shareReportModal') +const shareReportStatus = document.getElementById('shareReportStatus') +const shareReportPreview = document.getElementById('shareReportPreview') var allowToSend = false; const monate = ["Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember"]; const currentDate = new Date(); @@ -39,6 +43,9 @@ var isFilterVisible = true; // Ob die Aktivitäten-Tabelle gerade maximiert ist (Timer-Karte ist dann ausgeblendet). var isTableMaximized = false; +// Einträge des gerade angezeigten Monats, für den WhatsApp-Bericht (share_icon) wiederverwendet. +var currentMonthEntries = []; + // // Trigger @@ -71,6 +78,18 @@ document.addEventListener('DOMContentLoaded', (event) => { }); }); +// Behebt die Bootstrap-Konsolenwarnung "Blocked aria-hidden on an element because its +// descendant retained focus": beim Schließen eines Modals (z.B. per "X"-Button) setzt +// Bootstrap aria-hidden="true", obwohl der geklickte Button noch fokussiert ist. Fix: Fokus +// vor dem Ausblenden gezielt vom Modal wegnehmen. Gilt für alle Modals der Seite. +document.querySelectorAll('.modal').forEach(modalEl => { + modalEl.addEventListener('hide.bs.modal', () => { + if (document.activeElement && modalEl.contains(document.activeElement)) { + document.activeElement.blur() + } + }) +}) + // Lädt die 55h-Regel Einstellung (SettingsID 3) aus der DB, setzt rule55Active // und synchronisiert die Checkbox sowie den Badge in der Jahres-Card. async function loadRule55Setting() { @@ -399,6 +418,77 @@ SETLdcNameSaveButton.addEventListener('click', () => { SETLdcNameSaveButton.classList.add('d-none') }) +// +// BERICHT FÜR WHATSAPP TEILEN +// + +// Baut den vorformatierten Bericht für den gerade angezeigten Monat (WhatsApp-Formatierung: *fett*) +function buildMonthReportText() { + const monthLabel = `${monate[cursorMonth]} ${cursorYear}` + const dienstHours = document.getElementById('monthHourService').innerText + const bibelstudien = document.getElementById('studysinput').value + const ldcHours = document.getElementById('monthHourLDC').innerText + + // Sonstige Einträge nach ihrem individuellen Bemerkungstext gruppieren und Stunden je Gruppe summieren + const sonstigeGroups = {} + currentMonthEntries + .filter(entry => entry.type === 3) + .forEach(entry => { + const label = entry.sondertext || 'Sonstiges' + sonstigeGroups[label] = (sonstigeGroups[label] || 0) + entry.duration + }) + + var message = `Bericht: *${monthLabel}*\n` + message += `Dienst: ${dienstHours}h\n` + message += `Bibelstudien: ${bibelstudien}\n` + message += `Bemerkungen:\n` + message += `• ${ldcLabel}: ${ldcHours}h` + + Object.keys(sonstigeGroups).forEach(label => { + message += `\n• ${label}: ${formatDuration(sonstigeGroups[label], true)}h` + }) + + return message +} + +// Kopiert Text in die Zwischenablage - mit Fallback für Umgebungen ohne Clipboard-API +async function copyTextToClipboard(text) { + if (navigator.clipboard && navigator.clipboard.writeText) { + await navigator.clipboard.writeText(text) + return + } + const textarea = document.createElement('textarea') + textarea.value = text + textarea.style.position = 'fixed' + textarea.style.opacity = '0' + document.body.appendChild(textarea) + textarea.select() + document.execCommand('copy') + document.body.removeChild(textarea) +} + +// Bestätigung als Vorschau-Modal statt kurzem Icon-Blitz: so sieht man den Bericht direkt +// (auch praktisch, wenn man ihn gar nicht kopieren, sondern nur ansehen möchte) und kann +// in Ruhe wieder schließen. +shareIcon.addEventListener('click', () => { + const message = buildMonthReportText() + shareReportPreview.innerText = message + + copyTextToClipboard(message) + .then(() => { + shareReportStatus.innerText = '✓ In die Zwischenablage kopiert' + shareReportStatus.style.color = 'rgb(120,170,86)' + }) + .catch((error) => { + console.error('Bericht konnte nicht in die Zwischenablage kopiert werden:', error) + shareReportStatus.innerText = 'Kopieren nicht möglich - Text unten manuell markieren' + shareReportStatus.style.color = '#dc3545' + }) + .finally(() => { + new bootstrap.Modal(shareReportModalEl).show() + }) +}) + async function getActualDataAndFillView(monat = currentDate.getMonth(), jahr = currentDate.getFullYear()) { try { @@ -423,6 +513,7 @@ async function getActualDataAndFillView(monat = currentDate.getMonth(), jahr = c // Filter funktion aufrufen und entsprechend mit dem aktuellen Datum füllen const filteredEntries = await filterEntriesByMonthYear(monat === 12 ? 1 : monat + 1, jahr); + currentMonthEntries = filteredEntries console.log("update-complete") console.log(jahr) diff --git a/app/static/app/js/welcomeControl.js b/app/static/app/js/welcomeControl.js index 24831ce..75a1b58 100644 --- a/app/static/app/js/welcomeControl.js +++ b/app/static/app/js/welcomeControl.js @@ -5,6 +5,7 @@ function setAllOk() { if (localStorage.getItem('UpdateInfoRead') === document.getElementById('versionnumber').value) { document.getElementById('dashboard').classList.remove('d-none'); document.getElementById('refresh_icon').classList.remove('d-none') + document.getElementById('share_icon').classList.remove('d-none') document.getElementById('settings_icon').classList.remove('d-none') } } diff --git a/app/templates/app/base.html b/app/templates/app/base.html index 7a39092..47dea47 100644 --- a/app/templates/app/base.html +++ b/app/templates/app/base.html @@ -20,14 +20,23 @@
-
- Settings - - - - - Settings - SettingsClose + +
+ Settings + + + +
+ + Teilen + + Settings + SettingsClose +
diff --git a/app/templates/app/home.html b/app/templates/app/home.html index d374f38..f2781d9 100644 --- a/app/templates/app/home.html +++ b/app/templates/app/home.html @@ -287,6 +287,22 @@
+ + +