replace client-side tab toggling with server-side tab routing

Each settings tab is now a separate page load via ?tab= query param.
Flask renders only the active panel - no CSS or JS visibility logic needed.
Tab bar uses <a> links instead of buttons. Eliminates the display:none
cascade issue that was preventing Import and Maintenance tabs from showing.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-20 17:06:11 -04:00
parent e37ce27256
commit 52d783546e
3 changed files with 18 additions and 34 deletions
+5 -1
View File
@@ -594,7 +594,11 @@ def artist_gallery(artist_name):
@main.route('/settings')
def settings():
return render_template('settings.html')
valid_tabs = {'overview', 'import', 'maintenance'}
tab = request.args.get('tab', 'overview')
if tab not in valid_tabs:
tab = 'overview'
return render_template('settings.html', active_tab=tab)
# ----------------------------
+3 -5
View File
@@ -1233,6 +1233,8 @@ header {
}
.settings-tab-btn {
display: inline-block;
text-decoration: none;
padding: 0.4rem 1.1rem;
border-radius: 999px;
border: 1px solid var(--filter-border);
@@ -1253,12 +1255,8 @@ header {
color: var(--filter-active-fg);
}
/* Settings tab panels */
/* Settings tab panels — always visible, server renders only the active one */
.settings-tab-panel {
display: none;
}
.settings-tab-panel.is-active {
display: block;
}
+10 -28
View File
@@ -6,13 +6,14 @@
<!-- Tab bar -->
<div class="settings-tab-bar" role="tablist">
<button class="settings-tab-btn is-active" data-tab="overview" role="tab">Overview</button>
<button class="settings-tab-btn" data-tab="import" role="tab">Import</button>
<button class="settings-tab-btn" data-tab="maintenance" role="tab">Maintenance</button>
<a class="settings-tab-btn{% if active_tab == 'overview' %} is-active{% endif %}" href="{{ url_for('main.settings', tab='overview') }}">Overview</a>
<a class="settings-tab-btn{% if active_tab == 'import' %} is-active{% endif %}" href="{{ url_for('main.settings', tab='import') }}">Import</a>
<a class="settings-tab-btn{% if active_tab == 'maintenance' %} is-active{% endif %}" href="{{ url_for('main.settings', tab='maintenance') }}">Maintenance</a>
</div>
<!-- ===== OVERVIEW TAB ===== -->
<div class="settings-tab-panel is-active" data-tab="overview">
{% if active_tab == 'overview' %}
<div class="settings-tab-panel" data-tab="overview">
<!-- System Stats (Full Width at Top) -->
<div class="settings-grid-full">
@@ -212,8 +213,10 @@
</div>
</div><!-- end overview tab panel -->
{% endif %}
<!-- ===== IMPORT TAB ===== -->
{% if active_tab == 'import' %}
<div class="settings-tab-panel" data-tab="import">
<div class="settings-grid-full">
<div class="settings-two-col">
@@ -409,8 +412,10 @@
</div><!-- end settings-two-col -->
</div><!-- end settings-grid-full -->
</div><!-- end import tab panel -->
{% endif %}
<!-- ===== MAINTENANCE TAB ===== -->
{% if active_tab == 'maintenance' %}
<div class="settings-tab-panel" data-tab="maintenance">
<div class="settings-grid-full">
<div class="settings-container">
@@ -434,6 +439,7 @@
</div>
</div>
</div><!-- end maintenance tab panel -->
{% endif %}
<style>
.clickable-stat {
@@ -1847,28 +1853,4 @@ document.addEventListener('DOMContentLoaded', () => {
});
</script>
<script>
(function() {
const tabBtns = document.querySelectorAll('.settings-tab-btn');
const tabPanels = document.querySelectorAll('.settings-tab-panel');
const validTabs = ['overview', 'import', 'maintenance'];
function activateTab(tabName) {
tabBtns.forEach(function(btn) {
btn.classList.toggle('is-active', btn.dataset.tab === tabName);
});
tabPanels.forEach(function(panel) {
panel.style.display = panel.dataset.tab === tabName ? 'block' : 'none';
});
history.replaceState(null, '', '#' + tabName);
}
tabBtns.forEach(function(btn) {
btn.addEventListener('click', function() { activateTab(btn.dataset.tab); });
});
const hash = window.location.hash.replace('#', '');
activateTab(validTabs.includes(hash) ? hash : 'overview');
})();
</script>
{% endblock %}