diff --git a/app.js b/app.js index 920967b..2336156 100644 --- a/app.js +++ b/app.js @@ -221,6 +221,7 @@ class TeeTracker { this.entries = []; this.currentTeaId = null; this.charts = {}; + this.currentBgImage = null; // Initialize this.initStorage(); @@ -664,6 +665,9 @@ class TeeTracker { }); } + // Background image settings + this.setupBackgroundListeners(); + // Nextcloud settings this.setupNextcloudListeners(); } @@ -756,6 +760,111 @@ class TeeTracker { } } + setupBackgroundListeners() { + // Background image upload + const bgUpload = document.getElementById('bg-image-upload'); + if (bgUpload) { + bgUpload.addEventListener('change', (e) => this.handleBackgroundUpload(e)); + } + + // Background enable toggle + const bgEnabled = document.getElementById('bg-enabled'); + if (bgEnabled) { + bgEnabled.addEventListener('change', () => this.toggleBackground()); + } + + // Save background button + const saveBgBtn = document.getElementById('save-bg'); + if (saveBgBtn) { + saveBgBtn.addEventListener('click', () => this.saveBackgroundSettings()); + } + + // Remove background button + const removeBgBtn = document.getElementById('remove-bg'); + if (removeBgBtn) { + removeBgBtn.addEventListener('click', () => this.removeBackground()); + } + + // Load saved background settings + this.loadBackgroundSettings(); + } + + handleBackgroundUpload(e) { + const file = e.target.files[0]; + if (!file) return; + + const preview = document.getElementById('bg-preview-img'); + const previewContainer = document.getElementById('bg-image-preview'); + const removeBtn = document.getElementById('remove-bg'); + + if (file.type.startsWith('image/')) { + const reader = new FileReader(); + reader.onload = (event) => { + preview.src = event.target.result; + previewContainer.style.display = 'block'; + removeBtn.style.display = 'inline-flex'; + this.currentBgImage = event.target.result; + }; + reader.readAsDataURL(file); + } + } + + toggleBackground() { + const enabled = document.getElementById('bg-enabled').checked; + if (enabled && this.currentBgImage) { + document.documentElement.style.setProperty('--bg-image', `url("${this.currentBgImage}")`); + } else { + document.documentElement.style.setProperty('--bg-image', 'none'); + } + } + + saveBackgroundSettings() { + const enabled = document.getElementById('bg-enabled').checked; + const bgImage = this.currentBgImage; + + if (enabled && bgImage) { + localStorage.setItem('teatracker_bg_enabled', 'true'); + localStorage.setItem('teatracker_bg_image', bgImage); + this.showToast('Hintergrundbild gespeichert!', 'success'); + } else { + localStorage.removeItem('teatracker_bg_enabled'); + localStorage.removeItem('teatracker_bg_image'); + this.showToast('Hintergrundbild deaktiviert!', 'success'); + } + this.toggleBackground(); + } + + removeBackground() { + this.currentBgImage = null; + document.getElementById('bg-preview-img').src = ''; + document.getElementById('bg-image-preview').style.display = 'none'; + document.getElementById('remove-bg').style.display = 'none'; + document.getElementById('bg-enabled').checked = false; + this.toggleBackground(); + } + + loadBackgroundSettings() { + this.currentBgImage = localStorage.getItem('teatracker_bg_image'); + const enabled = localStorage.getItem('teatracker_bg_enabled') === 'true'; + + if (this.currentBgImage) { + document.getElementById('bg-enabled').checked = enabled; + if (enabled) { + document.documentElement.style.setProperty('--bg-image', `url("${this.currentBgImage}")`); + } + + // Show preview + const preview = document.getElementById('bg-preview-img'); + const previewContainer = document.getElementById('bg-image-preview'); + const removeBtn = document.getElementById('remove-bg'); + if (preview && previewContainer && removeBtn) { + preview.src = this.currentBgImage; + previewContainer.style.display = 'block'; + removeBtn.style.display = 'inline-flex'; + } + } + } + // ============================================ // Nextcloud Functions // ============================================ diff --git a/styles.css b/styles.css index d4560e4..4ad19ee 100644 --- a/styles.css +++ b/styles.css @@ -936,3 +936,38 @@ header p { outline: none; border-color: var(--primary-color); } + +/* Background Image Settings */ +.bg-preview { + margin-top: 10px; +} + +.bg-preview img { + max-width: 200px; + max-height: 150px; + border-radius: var(--border-radius); + box-shadow: var(--box-shadow); + object-fit: cover; +} + +/* Background Image for App */ +.app-container { + background-image: var(--bg-image, none); + background-size: cover; + background-position: center; + background-attachment: fixed; + background-repeat: no-repeat; +} + +/* Overlay for better text readability */ +.app-container::before { + content: ''; + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: rgba(255, 255, 255, 0.85); + z-index: -1; + pointer-events: none; +}