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>
107 lines
4.5 KiB
HTML
107 lines
4.5 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Settings — Media Centre</title>
|
|
<link rel="icon" href="{{ url_for('static', filename='favicon.svg') }}">
|
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
|
|
<link rel="stylesheet" href="{{ url_for('static', filename='css/base.css') }}">
|
|
<link rel="stylesheet" href="{{ url_for('static', filename='css/settings.css') }}">
|
|
</head>
|
|
<body data-url-base="{{ request.script_root }}">
|
|
|
|
<header>
|
|
<svg width="30" height="30" viewBox="0 0 100 100" aria-hidden="true">
|
|
<rect width="100" height="100" rx="22" fill="var(--accent)"/>
|
|
<path d="M40 32 L72 50 L40 68 Z" fill="var(--bg)"/>
|
|
</svg>
|
|
<h1>Settings</h1>
|
|
<a href="{{ url_for('dashboard') }}" class="back-btn">← Dashboard</a>
|
|
</header>
|
|
|
|
<main>
|
|
<div class="grid">
|
|
|
|
<!-- General -->
|
|
<div class="card full">
|
|
<div class="card-header"><h2>General</h2></div>
|
|
<div class="card-body">
|
|
<div class="field">
|
|
<label for="timezone">Timezone</label>
|
|
<select id="timezone">
|
|
{% set tzs = [
|
|
'America/New_York','America/Chicago','America/Denver','America/Los_Angeles',
|
|
'America/Toronto','America/Vancouver','America/Phoenix','America/Halifax',
|
|
'Europe/London','Europe/Paris','Europe/Berlin','Europe/Amsterdam',
|
|
'Europe/Stockholm','Europe/Rome','Europe/Madrid','Europe/Zurich',
|
|
'Australia/Sydney','Australia/Melbourne','Australia/Brisbane','Australia/Perth',
|
|
'Pacific/Auckland','Asia/Tokyo','Asia/Singapore','Asia/Dubai','Asia/Kolkata'
|
|
] %}
|
|
{% for tz in tzs %}
|
|
<option value="{{ tz }}" {% if tz == timezone %}selected{% endif %}>{{ tz }}</option>
|
|
{% endfor %}
|
|
</select>
|
|
</div>
|
|
<div class="field">
|
|
<label for="arr_host">Host IP (ARR_HOST)</label>
|
|
<input type="text" id="arr_host" value="{{ arr_host }}" placeholder="e.g. 192.168.86.33">
|
|
<p class="hint">LAN address of the machine running Sonarr, Radarr, and the rest.</p>
|
|
</div>
|
|
<button class="save" onclick="saveGeneral()">Save general</button>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Change password -->
|
|
<div class="card full">
|
|
<div class="card-header"><h2>Change password</h2></div>
|
|
<div class="card-body">
|
|
<div class="field">
|
|
<label for="pw_current">Current password</label>
|
|
<input type="password" id="pw_current" autocomplete="current-password">
|
|
</div>
|
|
<div class="field">
|
|
<label for="pw_new">New password</label>
|
|
<input type="password" id="pw_new" placeholder="At least 6 characters" autocomplete="new-password">
|
|
</div>
|
|
<div class="field">
|
|
<label for="pw_confirm">Confirm new password</label>
|
|
<input type="password" id="pw_confirm" autocomplete="new-password">
|
|
<div class="error-inline" id="pw-error" role="alert"></div>
|
|
</div>
|
|
<button class="save" onclick="changePassword()">Update password</button>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Service API keys -->
|
|
{% for svc, label in [
|
|
('sonarr','Sonarr'), ('radarr','Radarr'), ('sabnzbd','SABnzbd'),
|
|
('tautulli','Tautulli'), ('prowlarr','Prowlarr'), ('ombi','Ombi')
|
|
] %}
|
|
<div class="card">
|
|
<div class="card-header"><h2>{{ label }}</h2></div>
|
|
<div class="card-body">
|
|
<div class="field">
|
|
<label for="{{ svc }}_api_key">API key</label>
|
|
<input type="password" id="{{ svc }}_api_key"
|
|
value="{{ {'sonarr': sonarr_api_key, 'radarr': radarr_api_key,
|
|
'sabnzbd': sabnzbd_api_key, 'tautulli': tautulli_api_key,
|
|
'prowlarr': prowlarr_api_key, 'ombi': ombi_api_key}[svc] }}"
|
|
autocomplete="off">
|
|
</div>
|
|
<button class="save" onclick="saveService('{{ svc }}')">Save</button>
|
|
</div>
|
|
</div>
|
|
{% endfor %}
|
|
|
|
</div>
|
|
</main>
|
|
|
|
<div class="toast" id="toast" role="status" aria-live="polite"></div>
|
|
|
|
<script src="{{ url_for('static', filename='js/settings.js') }}"></script>
|
|
|
|
</body>
|
|
</html>
|