Hadith-interval kan nu via instellingen worden aangepast met de toevoeging van 'hadith_interval_seconds' aan settings.json, settings.html en app.py. De update interval voor hadiths in JavaScript gebruikt deze variabele. Daarnaast is de instellingenpagina herzien en georganiseerd in vier tabbladen: Audio & Volume, Gebedstijden, Functies, Systeem. Nieuwe CSS-styling en JavaScript-functionaliteit zijn toegevoegd om het schakelgedrag van tabbladen te beheren, waarbij de laatst actieve tab in localStorage wordt opgeslagen.
400 lines
15 KiB
HTML
400 lines
15 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="nl">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<title>Instellingen - Gebedstijden Display</title>
|
||
<link rel="stylesheet" href="/static/style.css">
|
||
<link href="https://fonts.googleapis.com/css2?family=Cairo:wght@700&family=Lato:wght@400;700&display=swap" rel="stylesheet">
|
||
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
|
||
</head>
|
||
<body class="settings-page">
|
||
<div class="app">
|
||
<!-- Dark/Light toggle -->
|
||
<button id="themeToggle" title="Schakel modus"><span id="themeIcon" class="material-icons">brightness_6</span></button>
|
||
|
||
<div class="settings-container">
|
||
<div class="settings-header">
|
||
<a href="/" class="back-link" title="Terug naar hoofdpagina">
|
||
<span class="material-icons">arrow_back</span>
|
||
Terug naar hoofdpagina
|
||
</a>
|
||
<h1>Instellingen</h1>
|
||
</div>
|
||
|
||
<form method="POST" class="settings-form">
|
||
<!-- Tab Navigation -->
|
||
<div class="tab-navigation">
|
||
<button type="button" class="tab-btn active" data-tab="audio">
|
||
<span class="material-icons">volume_up</span>
|
||
Audio & Volume
|
||
</button>
|
||
<button type="button" class="tab-btn" data-tab="prayer">
|
||
<span class="material-icons">schedule</span>
|
||
Gebedstijden
|
||
</button>
|
||
<button type="button" class="tab-btn" data-tab="features">
|
||
<span class="material-icons">auto_stories</span>
|
||
Functies
|
||
</button>
|
||
<button type="button" class="tab-btn" data-tab="system">
|
||
<span class="material-icons">settings</span>
|
||
Systeem
|
||
</button>
|
||
</div>
|
||
|
||
<!-- Audio & Volume Tab -->
|
||
<div class="tab-content active" id="audio-tab">
|
||
<div class="settings-section">
|
||
<div class="form-group">
|
||
<label>
|
||
<span class="material-icons">info</span>
|
||
Volume Instellingen:
|
||
</label>
|
||
<p style="color: var(--text-secondary); font-size: 0.9rem; margin: 0.5rem 0;">
|
||
Stel verschillende volumes in voor overdag en 's avonds. Het systeem wisselt automatisch tussen deze volumes op basis van de ingestelde tijden.
|
||
</p>
|
||
</div>
|
||
|
||
<div class="form-row">
|
||
<div class="form-group">
|
||
<label for="volume_day">
|
||
<span class="material-icons">volume_up</span>
|
||
Volume Overdag (0–100):
|
||
</label>
|
||
<input type="number" name="volume_day" value="{{ settings.volume_day or settings.volume }}" min="0" max="100" />
|
||
</div>
|
||
|
||
<div class="form-group">
|
||
<label for="volume_night">
|
||
<span class="material-icons">volume_down</span>
|
||
Volume Avond (0–100):
|
||
</label>
|
||
<input type="number" name="volume_night" value="{{ settings.volume_night or (settings.volume // 2) }}" min="0" max="100" />
|
||
</div>
|
||
</div>
|
||
|
||
<div class="form-row">
|
||
<div class="form-group">
|
||
<label for="day_start">
|
||
<span class="material-icons">wb_sunny</span>
|
||
Dag begint om:
|
||
</label>
|
||
<input type="time" name="day_start" value="{{ settings.day_start or '07:00' }}" />
|
||
</div>
|
||
|
||
<div class="form-group">
|
||
<label for="night_start">
|
||
<span class="material-icons">nightlight</span>
|
||
Avond begint om:
|
||
</label>
|
||
<input type="time" name="night_start" value="{{ settings.night_start or '20:00' }}" />
|
||
</div>
|
||
</div>
|
||
|
||
<div class="form-group">
|
||
<label>
|
||
<span class="material-icons">speaker_group</span>
|
||
Sonos Zones:
|
||
</label>
|
||
<div class="checkboxes">
|
||
{% for zone in alle_zones %}
|
||
<div class="checkbox-item">
|
||
<input type="checkbox" name="zones" value="{{ zone }}" id="zone_{{ loop.index }}"
|
||
{% if zone in settings.zones %}checked{% endif %}>
|
||
<label for="zone_{{ loop.index }}">{{ zone }}</label>
|
||
</div>
|
||
{% endfor %}
|
||
</div>
|
||
</div>
|
||
|
||
<div class="form-row audio-row">
|
||
<div class="form-group audio-section">
|
||
<label for="audio_clip">
|
||
<span class="material-icons">music_note</span>
|
||
Adhaan Audio Bestand:
|
||
</label>
|
||
<select name="audio_clip" id="audioSelect">
|
||
{% for clip in clips %}
|
||
<option value="{{ clip }}" {% if clip == settings.audio_clip %}selected{% endif %}>
|
||
{% if clip == 'adhan1.mp3' %}Klassieke Adhaan
|
||
{% elif 'mekka' in clip %}Mekka Stijl
|
||
{% elif 'medina' in clip %}Medina Stijl
|
||
{% elif 'kort' in clip %}Korte Versie
|
||
{% elif 'traditioneel' in clip %}Traditioneel
|
||
{% else %}{{ clip }}
|
||
{% endif %}
|
||
</option>
|
||
{% endfor %}
|
||
</select>
|
||
</div>
|
||
|
||
<div class="form-group audio-preview-section">
|
||
<label>
|
||
<span class="material-icons">play_circle</span>
|
||
Audio Voorbeeld:
|
||
</label>
|
||
<div class="audio-preview">
|
||
<button type="button" class="preview-btn" onclick="previewAudio()">
|
||
<span class="material-icons">play_arrow</span>
|
||
Voorbeeld afspelen
|
||
</button>
|
||
<audio id="previewAudio" preload="none"></audio>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Prayer Times Tab -->
|
||
<div class="tab-content" id="prayer-tab">
|
||
<div class="settings-section">
|
||
<div class="form-group">
|
||
<label>
|
||
<span class="material-icons">schedule</span>
|
||
Gebedstijd Aanpassingen:
|
||
</label>
|
||
<p style="color: var(--text-secondary); font-size: 0.9rem; margin: 0.5rem 0;">
|
||
Voeg minuten toe (+) of haal af (-) van de VUMG gebedstijden. Bijvoorbeeld: +30 voor 30 minuten later, -15 voor 15 minuten eerder.
|
||
</p>
|
||
</div>
|
||
|
||
<div class="form-row three-columns">
|
||
<div class="form-group">
|
||
<label for="fajr_offset">
|
||
<span class="material-icons">wb_twilight</span>
|
||
Fajr Aanpassing (minuten):
|
||
</label>
|
||
<input type="number" name="fajr_offset" value="{{ settings.fajr_offset or 0 }}" min="-120" max="120" step="5" />
|
||
</div>
|
||
|
||
<div class="form-group">
|
||
<label for="zuhr_offset">
|
||
<span class="material-icons">wb_sunny</span>
|
||
Zuhr Aanpassing (minuten):
|
||
</label>
|
||
<input type="number" name="zuhr_offset" value="{{ settings.zuhr_offset or 0 }}" min="-120" max="120" step="5" />
|
||
</div>
|
||
|
||
<div class="form-group">
|
||
<label for="asr_offset">
|
||
<span class="material-icons">brightness_low</span>
|
||
Asr Aanpassing (minuten):
|
||
</label>
|
||
<input type="number" name="asr_offset" value="{{ settings.asr_offset or 0 }}" min="-120" max="120" step="5" />
|
||
</div>
|
||
</div>
|
||
|
||
<div class="form-row">
|
||
<div class="form-group">
|
||
<label for="maghrib_offset">
|
||
<span class="material-icons">brightness_3</span>
|
||
Maghrib Aanpassing (minuten):
|
||
</label>
|
||
<input type="number" name="maghrib_offset" value="{{ settings.maghrib_offset or 0 }}" min="-120" max="120" step="5" />
|
||
</div>
|
||
|
||
<div class="form-group">
|
||
<label for="isha_offset">
|
||
<span class="material-icons">brightness_2</span>
|
||
Isha Aanpassing (minuten):
|
||
</label>
|
||
<input type="number" name="isha_offset" value="{{ settings.isha_offset or 0 }}" min="-120" max="120" step="5" />
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Features Tab -->
|
||
<div class="tab-content" id="features-tab">
|
||
<div class="settings-section">
|
||
<div class="form-group">
|
||
<label>
|
||
<span class="material-icons">auto_stories</span>
|
||
Adzkaar na Gebed:
|
||
</label>
|
||
<p style="color: var(--text-secondary); font-size: 0.9rem; margin: 0.5rem 0;">
|
||
Toon automatisch een fullscreen Adzkaar scherm na elke gebedstijd voor spirituele versterking en dhikr.
|
||
</p>
|
||
</div>
|
||
|
||
<div class="form-row">
|
||
<div class="form-group">
|
||
<div class="checkbox-item">
|
||
<input type="checkbox" name="adzkaar_enabled" id="adzkaar_enabled"
|
||
{% if settings.adzkaar_enabled != False %}checked{% endif %}>
|
||
<label for="adzkaar_enabled">
|
||
<span class="material-icons">visibility</span>
|
||
Adzkaar scherm inschakelen
|
||
</label>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="form-group">
|
||
<label for="adzkaar_duration">
|
||
<span class="material-icons">timer</span>
|
||
Adzkaar duur (minuten):
|
||
</label>
|
||
<input type="number" name="adzkaar_duration" value="{{ settings.adzkaar_duration or 5 }}" min="1" max="30" step="1" />
|
||
</div>
|
||
</div>
|
||
|
||
<div class="form-group">
|
||
<label>
|
||
<span class="material-icons">format_quote</span>
|
||
Hadith Instellingen:
|
||
</label>
|
||
<p style="color: var(--text-secondary); font-size: 0.9rem; margin: 0.5rem 0;">
|
||
Stel in hoe vaak de hadith tekst op het hoofdscherm wordt bijgewerkt met een nieuwe hadith.
|
||
</p>
|
||
</div>
|
||
|
||
<div class="form-row">
|
||
<div class="form-group">
|
||
<label for="hadith_interval_seconds">
|
||
<span class="material-icons">refresh</span>
|
||
Hadith update interval (seconden):
|
||
</label>
|
||
<input type="number" name="hadith_interval_seconds" value="{{ settings.hadith_interval_seconds or 30 }}" min="5" max="300" step="5" />
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- System Tab -->
|
||
<div class="tab-content" id="system-tab">
|
||
<div class="settings-section">
|
||
<div class="form-group">
|
||
<label>
|
||
<span class="material-icons">info</span>
|
||
Systeem Informatie:
|
||
</label>
|
||
<p style="color: var(--text-secondary); font-size: 0.9rem; margin: 0.5rem 0;">
|
||
Algemene systeem instellingen en test functies.
|
||
</p>
|
||
</div>
|
||
|
||
<div class="button-group">
|
||
<button type="submit" name="test_clip" class="btn-secondary">
|
||
<span class="material-icons">speaker</span>
|
||
Test Adhaan op Sonos
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Save Button (always visible) -->
|
||
<div class="save-section">
|
||
<button type="submit" class="btn-primary btn-save">
|
||
<span class="material-icons">save</span>
|
||
Alle Instellingen Opslaan
|
||
</button>
|
||
</div>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
|
||
<script>
|
||
function previewAudio() {
|
||
const select = document.getElementById('audioSelect');
|
||
const audio = document.getElementById('previewAudio');
|
||
const selectedClip = select.value;
|
||
|
||
audio.src = `/static/clips/${selectedClip}`;
|
||
audio.play().catch(e => {
|
||
console.log('Audio afspelen mislukt:', e);
|
||
alert('Kon audio niet afspelen. Controleer of het bestand bestaat.');
|
||
});
|
||
}
|
||
|
||
// Auto-update preview audio source when selection changes
|
||
document.getElementById('audioSelect').addEventListener('change', function() {
|
||
const audio = document.getElementById('previewAudio');
|
||
audio.src = `/static/clips/${this.value}`;
|
||
});
|
||
|
||
// Set initial audio source
|
||
window.onload = function() {
|
||
const select = document.getElementById('audioSelect');
|
||
const audio = document.getElementById('previewAudio');
|
||
audio.src = `/static/clips/${select.value}`;
|
||
|
||
// Setup theme toggle
|
||
setupThemeToggle();
|
||
updateThemeIcon();
|
||
|
||
// Setup tabs
|
||
setupTabs();
|
||
};
|
||
|
||
// Theme toggle functionaliteit (gekopieerd van index.html)
|
||
function setupThemeToggle() {
|
||
const toggleBtn = document.getElementById("themeToggle");
|
||
if (!toggleBtn) return;
|
||
|
||
const currentTheme = localStorage.getItem("theme") || "dark";
|
||
document.documentElement.className = currentTheme;
|
||
|
||
toggleBtn.addEventListener("click", function () {
|
||
const html = document.documentElement;
|
||
const newTheme = html.className === "light" ? "dark" : "light";
|
||
html.className = newTheme;
|
||
localStorage.setItem("theme", newTheme);
|
||
updateThemeIcon();
|
||
});
|
||
}
|
||
|
||
function updateThemeIcon() {
|
||
const html = document.documentElement;
|
||
const icon = document.getElementById('themeIcon');
|
||
if (icon) {
|
||
if (html.className === 'light') {
|
||
icon.textContent = 'dark_mode';
|
||
} else {
|
||
icon.textContent = 'light_mode';
|
||
}
|
||
}
|
||
}
|
||
|
||
// Tab functionality
|
||
function setupTabs() {
|
||
const tabBtns = document.querySelectorAll('.tab-btn');
|
||
const tabContents = document.querySelectorAll('.tab-content');
|
||
|
||
tabBtns.forEach(btn => {
|
||
btn.addEventListener('click', () => {
|
||
const targetTab = btn.getAttribute('data-tab');
|
||
|
||
// Remove active class from all buttons and contents
|
||
tabBtns.forEach(b => b.classList.remove('active'));
|
||
tabContents.forEach(c => c.classList.remove('active'));
|
||
|
||
// Add active class to clicked button and corresponding content
|
||
btn.classList.add('active');
|
||
document.getElementById(targetTab + '-tab').classList.add('active');
|
||
|
||
// Save active tab to localStorage
|
||
localStorage.setItem('activeSettingsTab', targetTab);
|
||
});
|
||
});
|
||
|
||
// Restore last active tab
|
||
const savedTab = localStorage.getItem('activeSettingsTab');
|
||
if (savedTab) {
|
||
const savedBtn = document.querySelector(`[data-tab="${savedTab}"]`);
|
||
const savedContent = document.getElementById(savedTab + '-tab');
|
||
|
||
if (savedBtn && savedContent) {
|
||
// Remove active from all
|
||
tabBtns.forEach(b => b.classList.remove('active'));
|
||
tabContents.forEach(c => c.classList.remove('active'));
|
||
|
||
// Activate saved tab
|
||
savedBtn.classList.add('active');
|
||
savedContent.classList.add('active');
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
</body>
|
||
</html>
|