Files
jason b5318abe0a
Build and Push Docker Image / build (push) Successful in 12s
mobile friendly
2026-04-22 16:22:09 -05:00

125 lines
6.3 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<%- include('../partials/head', { title: 'Settings' }) %>
<%- include('../partials/adminNav', { currentPath: '/admin/settings' }) %>
<%- include('../partials/adminTopBar') %>
<div class="lg:pl-56 pt-14 lg:pt-0 min-h-screen">
<%- include('../partials/adminBanner') %>
<div class="max-w-2xl mx-auto px-4 sm:px-8 py-6 sm:py-8">
<div class="mb-8">
<h1 class="text-xl font-semibold text-white">Settings</h1>
<p class="text-sm text-gray-500 mt-0.5">Branding, appearance, and app configuration</p>
</div>
<% if (saved) { %>
<div class="mb-6 flex items-start gap-3 bg-green-500/10 border border-green-500/30 rounded-lg px-4 py-3">
<svg class="w-4 h-4 text-green-400 mt-0.5 shrink-0" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
<path stroke-linecap="round" stroke-linejoin="round" d="M9 12.75L11.25 15 15 9.75M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
<p class="text-sm text-green-400">Settings saved.</p>
</div>
<% } %>
<!-- Branding -->
<form method="POST" action="/admin/settings" class="bg-surface-900 border border-gray-800 rounded-2xl p-6 mb-6 space-y-5">
<h2 class="text-sm font-semibold text-white">Branding</h2>
<div>
<label class="block text-xs font-medium text-gray-400 mb-1.5">App Name</label>
<input name="brand_name" type="text" value="<%= settings.brand_name %>"
class="w-full bg-surface-800 border border-gray-700 rounded-lg px-3.5 py-2.5 text-sm text-white focus:outline-none focus:border-accent transition-colors"
placeholder="StepView" />
<p class="text-xs text-gray-600 mt-1.5">Shown in the browser tab, viewer overlay, and admin sidebar.</p>
</div>
<div>
<label class="block text-xs font-medium text-gray-400 mb-1.5">Tagline</label>
<input name="brand_tagline" type="text" value="<%= settings.brand_tagline %>"
class="w-full bg-surface-800 border border-gray-700 rounded-lg px-3.5 py-2.5 text-sm text-white focus:outline-none focus:border-accent transition-colors"
placeholder="3D Model Viewer" />
</div>
<div>
<label class="block text-xs font-medium text-gray-400 mb-1.5">Accent Color</label>
<div class="flex items-center gap-3">
<input type="color" name="brand_accent" value="<%= settings.brand_accent %>"
class="h-10 w-16 rounded-lg border border-gray-700 bg-surface-800 cursor-pointer p-1" />
<input type="text" id="accent-hex" value="<%= settings.brand_accent %>"
class="bg-surface-800 border border-gray-700 rounded-lg px-3.5 py-2.5 text-sm text-white font-mono w-32 focus:outline-none focus:border-accent transition-colors"
placeholder="#3b82f6" />
</div>
<p class="text-xs text-gray-600 mt-1.5">Used for buttons, highlights, and active nav items.</p>
</div>
<div class="pt-2">
<button type="submit" class="btn-accent text-white rounded-lg px-5 py-2 text-sm font-medium transition-all">
Save Branding
</button>
</div>
</form>
<!-- Logo -->
<div class="bg-surface-900 border border-gray-800 rounded-2xl p-6 mb-6">
<h2 class="text-sm font-semibold text-white mb-4">Logo</h2>
<% if (settings.brand_logo_path) { %>
<div class="flex items-center gap-4 mb-5 p-4 bg-surface-800 rounded-xl border border-gray-700">
<img src="/brand/logo" alt="Current logo" class="h-10 w-auto object-contain" />
<div class="flex-1">
<p class="text-sm text-gray-300">Logo uploaded</p>
<p class="text-xs text-gray-500 mt-0.5">PNG, SVG, or JPEG recommended</p>
</div>
<form method="POST" action="/admin/settings/logo/delete">
<button type="submit" class="text-xs text-gray-500 hover:text-red-400 transition-colors">Remove</button>
</form>
</div>
<% } else { %>
<p class="text-sm text-gray-500 mb-4">No logo uploaded. A default icon is shown.</p>
<% } %>
<form method="POST" action="/admin/settings/logo" enctype="multipart/form-data" class="flex items-end gap-3">
<div class="flex-1">
<label class="block text-xs font-medium text-gray-400 mb-1.5">Upload Logo</label>
<input type="file" name="logo" accept=".png,.jpg,.jpeg,.svg,.webp" required
class="w-full text-sm text-gray-400 file:mr-3 file:py-1.5 file:px-3 file:rounded-lg file:border-0 file:text-xs file:font-medium file:bg-surface-700 file:text-gray-300 hover:file:bg-surface-600 transition-colors" />
<p class="text-xs text-gray-600 mt-1">Max 2 MB. PNG or SVG recommended for best quality.</p>
</div>
<button type="submit" class="bg-surface-700 hover:bg-surface-600 border border-gray-700 text-sm text-gray-300 rounded-lg px-4 py-2 transition-colors shrink-0">
Upload
</button>
</form>
</div>
<!-- Favicon -->
<div class="bg-surface-900 border border-gray-800 rounded-2xl p-6">
<h2 class="text-sm font-semibold text-white mb-4">Favicon</h2>
<form method="POST" action="/admin/settings/favicon" enctype="multipart/form-data" class="flex items-end gap-3">
<div class="flex-1">
<label class="block text-xs font-medium text-gray-400 mb-1.5">Upload Favicon</label>
<input type="file" name="favicon" accept=".ico,.png,.svg" required
class="w-full text-sm text-gray-400 file:mr-3 file:py-1.5 file:px-3 file:rounded-lg file:border-0 file:text-xs file:font-medium file:bg-surface-700 file:text-gray-300 hover:file:bg-surface-600 transition-colors" />
<p class="text-xs text-gray-600 mt-1">ICO or PNG, max 512 KB. Ideal size: 32×32 px.</p>
</div>
<button type="submit" class="bg-surface-700 hover:bg-surface-600 border border-gray-700 text-sm text-gray-300 rounded-lg px-4 py-2 transition-colors shrink-0">
Upload
</button>
</form>
</div>
</div>
</div>
<script>
// Keep color picker and hex input in sync
const colorInput = document.querySelector('input[type="color"]')
const hexInput = document.getElementById('accent-hex')
if (colorInput && hexInput) {
colorInput.addEventListener('input', () => { hexInput.value = colorInput.value })
hexInput.addEventListener('input', () => {
if (/^#[0-9a-fA-F]{6}$/.test(hexInput.value)) colorInput.value = hexInput.value
})
}
</script>
<script src="/admin.js"></script>
</body>
</html>