Replace ~268 hardcoded text-stone-* classes with theme-aware token utilities (text-text, text-text-secondary, text-text-muted) across all templates and JS components. Adjust dark mode token values to meet WCAG AA contrast ratios on dark surfaces.
65 lines
2 KiB
HTML
65 lines
2 KiB
HTML
{% extends "base.html" %} {% import "partials/icons.html" as icons %} {% block title %}Brewlog · Data{% endblock %}
|
|
{% block content %}
|
|
<header class="flex flex-wrap items-start justify-between gap-4">
|
|
<div class="flex flex-col gap-2">
|
|
<h1 class="text-3xl font-semibold">Data</h1>
|
|
<p class="max-w-2xl text-sm text-text-secondary">Browse all your coffee data.</p>
|
|
</div>
|
|
{% if is_authenticated %}
|
|
<a
|
|
href="/add?type={{ active_type }}"
|
|
class="inline-flex items-center gap-2 rounded-md bg-accent px-4 py-2.5 text-sm font-semibold text-accent-text transition hover:bg-accent-hover"
|
|
>
|
|
{% call icons::plus_circle("h-4 w-4") %}
|
|
Add
|
|
</a>
|
|
{% endif %}
|
|
</header>
|
|
|
|
<div class="rounded-lg border bg-surface">
|
|
{% include "partials/tab_bar.html" %}
|
|
<!-- Search -->
|
|
<div class="border-t px-3 py-2">
|
|
<input
|
|
type="search"
|
|
id="data-search"
|
|
placeholder="Search..."
|
|
value="{{ search_value }}"
|
|
class="input-field w-full text-sm"
|
|
{% if !search_value.is_empty() %}data-init="el.focus(); el.selectionStart = el.value.length"{% endif %}
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="data-content" class="data-page-content">
|
|
{{ content|safe }}
|
|
</div>
|
|
|
|
<div id="detail-panel"></div>
|
|
|
|
<script>
|
|
(() => {
|
|
const searchInput = document.getElementById('data-search');
|
|
if (!searchInput) return;
|
|
|
|
let debounceTimer;
|
|
searchInput.addEventListener('input', () => {
|
|
clearTimeout(debounceTimer);
|
|
debounceTimer = setTimeout(() => {
|
|
const params = new URLSearchParams(window.location.search);
|
|
const activeTab = params.get('type') || 'brews';
|
|
const query = searchInput.value;
|
|
const url = `/data?type=${activeTab}&q=${encodeURIComponent(query)}`;
|
|
|
|
history.pushState(null, '', url);
|
|
|
|
fetch(url, { headers: { 'datastar-request': 'true' } })
|
|
.then((res) => res.text())
|
|
.then((html) => {
|
|
document.getElementById('data-content').innerHTML = html;
|
|
});
|
|
}, 300);
|
|
});
|
|
})();
|
|
</script>
|
|
{% endblock %}
|