Extract CSS/JS to static files, wrap header pills, add version footer
All checks were successful
Deploy / deploy (push) Successful in 23s
All checks were successful
Deploy / deploy (push) Successful in 23s
The palette lived in a :root block duplicated across all three templates, so every reshade meant three edits — and drifted twice in practice (the favicon hardcoded its own hex; stale danger-border rgba literals survived two palette changes). Move tokens to a single static/css/base.css, derive every dim/border tint from the four source hues with color-mix, and point the favicon at one static/favicon.svg. Also splits the 1558-line dashboard.html into template + static assets: 662 lines of CSS and 396 of JS were re-sent uninlined on every load with no browser caching, which costs real time on the remote/cellular access this app is built for. Templates drop to 501/42/107 lines. Server-rendered config (timezone, script_root) now arrives via <body data-*>; wiring URL_BASE to request.script_root also fixes /api/* fetches for a future subpath mount, which the hardcoded "" would break. Header service pills now wrap instead of scrolling — they were clipped at narrow widths, and a hidden pill is a service whose status you cannot see. Verified 0 clipped and no page overflow at 320/375/700/1280. Footer gains a version and date so the running build is identifiable without trusting the Unraid Docker tab's cached container IDs. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
faf25a811a
commit
18c7719cd7
12 changed files with 1396 additions and 1413 deletions
61
static/js/settings.js
Normal file
61
static/js/settings.js
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
/* Reverse-proxy prefix, so /api/* still resolves on a subpath mount. */
|
||||
const URL_BASE = document.body.dataset.urlBase || "";
|
||||
|
||||
function showToast(msg, isError) {
|
||||
const t = document.getElementById('toast');
|
||||
t.textContent = msg;
|
||||
t.classList.toggle('error', !!isError);
|
||||
t.classList.add('show');
|
||||
setTimeout(() => t.classList.remove('show'), 2800);
|
||||
}
|
||||
|
||||
async function post(url, payload) {
|
||||
return fetch(url, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
credentials: 'include',
|
||||
body: JSON.stringify(payload)
|
||||
});
|
||||
}
|
||||
|
||||
async function saveGeneral() {
|
||||
try {
|
||||
const resp = await post(URL_BASE + '/api/settings', {
|
||||
timezone: document.getElementById('timezone').value,
|
||||
arr_host: document.getElementById('arr_host').value.trim()
|
||||
});
|
||||
showToast(resp.ok ? 'General settings saved — reload the dashboard to apply.'
|
||||
: 'Save failed.', !resp.ok);
|
||||
} catch (e) { showToast('Network error — not saved.', true); }
|
||||
}
|
||||
|
||||
async function saveService(name) {
|
||||
try {
|
||||
const key = document.getElementById(name + '_api_key').value.trim();
|
||||
const resp = await post(URL_BASE + '/api/settings', { [name + '_api_key']: key });
|
||||
const label = name.charAt(0).toUpperCase() + name.slice(1);
|
||||
showToast(resp.ok ? label + ' key saved — restart the container to apply.'
|
||||
: 'Save failed.', !resp.ok);
|
||||
} catch (e) { showToast('Network error — not saved.', true); }
|
||||
}
|
||||
|
||||
async function changePassword() {
|
||||
const errEl = document.getElementById('pw-error');
|
||||
errEl.style.display = 'none';
|
||||
try {
|
||||
const resp = await post(URL_BASE + '/api/change-password', {
|
||||
current: document.getElementById('pw_current').value,
|
||||
new: document.getElementById('pw_new').value,
|
||||
confirm: document.getElementById('pw_confirm').value
|
||||
});
|
||||
const data = await resp.json();
|
||||
if (resp.ok) {
|
||||
['pw_current', 'pw_new', 'pw_confirm'].forEach(id => document.getElementById(id).value = '');
|
||||
showToast('Password updated.');
|
||||
} else {
|
||||
errEl.textContent = data.error || 'Failed to update password.';
|
||||
errEl.style.display = 'block';
|
||||
showToast(data.error || 'Failed to update password.', true);
|
||||
}
|
||||
} catch (e) { showToast('Network error — password not changed.', true); }
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue