Files
shopdb-flask/frontend/src/views/settings/BrandingSettings.vue

149 lines
5.8 KiB
Vue

<template>
<div>
<div class="page-header">
<h2>Branding</h2>
</div>
<div class="section-card">
<div class="setting-group">
<p class="setting-description">
Replace the shipped GE logos with your own site branding. Each logo can
be uploaded, or set to a path/URL directly. Leave blank to use the
bundled default.
</p>
<div class="setting-row" v-for="logo in brandingLogos" :key="logo.kind">
<label>
<span>{{ logo.label }}</span>
<input
type="text"
v-model="settings[logo.key]"
:placeholder="logo.placeholder"
@blur="saveSetting(logo.key, settings[logo.key])"
:disabled="saving"
>
<div class="map-upload-row">
<input type="file" :accept="logo.accept" @change="uploadLogo(logo.kind, logo.key, $event)" :disabled="brandingUploading" />
<img v-if="settings[logo.key]" :src="withBase(settings[logo.key])" class="map-thumb" :alt="logo.label" />
</div>
<small class="input-hint">{{ logo.hint }}</small>
</label>
</div>
<div class="setting-row">
<label>
<span>Primary brand color</span>
<div class="color-input-row">
<input
type="color"
:value="settings.brand_primary_color || '#000000'"
@input="settings.brand_primary_color = $event.target.value"
@change="saveSetting('brand_primary_color', settings.brand_primary_color)"
:disabled="saving"
>
<input
type="text"
v-model="settings.brand_primary_color"
placeholder="(blank = built-in)"
@blur="saveSetting('brand_primary_color', settings.brand_primary_color)"
:disabled="saving"
>
</div>
<small class="input-hint">Hex color for the primary accent. Leave blank to use the built-in palette.</small>
</label>
</div>
<div class="setting-row">
<label>
<span>Primary hover color</span>
<div class="color-input-row">
<input
type="color"
:value="settings.brand_primary_dark_color || '#000000'"
@input="settings.brand_primary_dark_color = $event.target.value"
@change="saveSetting('brand_primary_dark_color', settings.brand_primary_dark_color)"
:disabled="saving"
>
<input
type="text"
v-model="settings.brand_primary_dark_color"
placeholder="(blank = derived from primary)"
@blur="saveSetting('brand_primary_dark_color', settings.brand_primary_dark_color)"
:disabled="saving"
>
</div>
<small class="input-hint">Hover/active shade of the primary color. Leave blank to auto-darken the primary color ~15%.</small>
</label>
</div>
<div class="setting-row">
<label>
<span>Accent color</span>
<div class="color-input-row">
<input
type="color"
:value="settings.brand_accent_color || '#000000'"
@input="settings.brand_accent_color = $event.target.value"
@change="saveSetting('brand_accent_color', settings.brand_accent_color)"
:disabled="saving"
>
<input
type="text"
v-model="settings.brand_accent_color"
placeholder="(blank = built-in)"
@blur="saveSetting('brand_accent_color', settings.brand_accent_color)"
:disabled="saving"
>
</div>
<small class="input-hint">Accent for secondary buttons and badges. Leave blank to use the built-in palette.</small>
</label>
</div>
<div class="setting-row">
<label>
<span>Sidebar color</span>
<div class="color-input-row">
<input
type="color"
:value="settings.brand_sidebar_color || '#000000'"
@input="settings.brand_sidebar_color = $event.target.value"
@change="saveSetting('brand_sidebar_color', settings.brand_sidebar_color)"
:disabled="saving"
>
<input
type="text"
v-model="settings.brand_sidebar_color"
placeholder="(blank = built-in)"
@blur="saveSetting('brand_sidebar_color', settings.brand_sidebar_color)"
:disabled="saving"
>
</div>
<small class="input-hint">Sidebar background color. Leave blank to use the built-in palette.</small>
</label>
</div>
</div>
</div>
<div v-if="error" class="error-message">{{ error }}</div>
<div v-if="success" class="settings-success">{{ success }}</div>
</div>
</template>
<script setup>
import { onMounted } from 'vue'
import { useSystemSettings, brandingLogos } from '../../composables/systemSettings'
// The stored value is root-relative ('/ge-aerospace-logo.svg'). This app is
// mounted under a base path at every real deployment (/shopdb, /ops), so a raw
// src resolves against the SERVER root and 404s - which is what "error loading
// image" was. siteSettings.js already wraps every logo this way for the rest of
// the app; this preview was the one place that did not.
import { withBase } from '@/utils/basePath'
const {
settings, saving, brandingUploading, error, success,
loadSettings, saveSetting, uploadLogo,
} = useSystemSettings()
onMounted(loadSettings)
</script>