Add BrandColorLight to portal settings page
Updated the portal settings brand color picker to show both dark and light colors. Light swatch shown alongside dark swatch. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
3bd7585383
commit
771f70f2f3
2 changed files with 64 additions and 13 deletions
|
|
@ -650,12 +650,15 @@
|
|||
</button>
|
||||
</div>
|
||||
<div>
|
||||
<label style="display: block; margin-bottom: 8px; font-weight: 500;">Brand Color</label>
|
||||
<p style="color: #666; font-size: 13px; margin-bottom: 8px;">Used for accents and fallback backgrounds</p>
|
||||
<label style="display: block; margin-bottom: 8px; font-weight: 500;">Brand Colors</label>
|
||||
<p style="color: #666; font-size: 13px; margin-bottom: 8px;">Dark for accents/gradients, Light for card tinting</p>
|
||||
<div style="display: flex; gap: 12px; align-items: center;">
|
||||
<span id="brandColorSwatch" style="width: 40px; height: 40px; border-radius: 8px; background: #1B4D3E; border: 2px solid rgba(255,255,255,0.2); cursor: pointer;" onclick="Portal.showBrandColorPicker()"></span>
|
||||
<div style="display: flex; gap: 6px; align-items: center;">
|
||||
<span id="brandColorSwatch" style="width: 40px; height: 40px; border-radius: 8px; background: #1B4D3E; border: 2px solid rgba(255,255,255,0.2); cursor: pointer;" onclick="Portal.showBrandColorPicker()" title="Dark"></span>
|
||||
<span id="brandColorLightSwatch" style="width: 40px; height: 40px; border-radius: 8px; background: #fff; border: 2px solid rgba(255,255,255,0.2); cursor: pointer;" onclick="Portal.showBrandColorPicker()" title="Light"></span>
|
||||
</div>
|
||||
<button class="btn btn-secondary" onclick="Portal.showBrandColorPicker()" style="flex: 1;">
|
||||
Change Color
|
||||
Change Colors
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -817,13 +817,19 @@ const Portal = {
|
|||
document.getElementById('settingState').value = biz.ADDRESSSTATE || biz.AddressState || '';
|
||||
document.getElementById('settingZip').value = biz.ADDRESSZIP || biz.AddressZip || '';
|
||||
|
||||
// Load brand color if set
|
||||
// Load brand colors
|
||||
const brandColor = biz.BRANDCOLOR || biz.BrandColor;
|
||||
if (brandColor) {
|
||||
this.brandColor = brandColor;
|
||||
const swatch = document.getElementById('brandColorSwatch');
|
||||
if (swatch) swatch.style.background = brandColor;
|
||||
}
|
||||
const brandColorLight = biz.BRANDCOLORLIGHT || biz.BrandColorLight || '';
|
||||
if (brandColorLight) {
|
||||
this.brandColorLight = brandColorLight;
|
||||
const lSwatch = document.getElementById('brandColorLightSwatch');
|
||||
if (lSwatch) lSwatch.style.background = brandColorLight;
|
||||
}
|
||||
|
||||
// Load header preview
|
||||
const headerPreview = document.getElementById('headerPreview');
|
||||
|
|
@ -1316,10 +1322,12 @@ const Portal = {
|
|||
// Show brand color picker
|
||||
showBrandColorPicker() {
|
||||
const currentColor = this.brandColor || '#1B4D3E';
|
||||
document.getElementById('modalTitle').textContent = 'Brand Color';
|
||||
const currentLight = this.brandColorLight || '';
|
||||
document.getElementById('modalTitle').textContent = 'Brand Colors';
|
||||
document.getElementById('modalBody').innerHTML = `
|
||||
<div style="padding: 8px;">
|
||||
<p style="color: #999; margin-bottom: 16px;">This color is used for accents and fallback backgrounds in your menu.</p>
|
||||
<label style="display: block; font-weight: 600; margin-bottom: 6px;">Brand Color (Dark)</label>
|
||||
<p style="color: #999; margin-bottom: 12px; font-size: 12px;">Used for accents and gradients in the customer app.</p>
|
||||
<div style="display: flex; gap: 16px; align-items: flex-start;">
|
||||
<input type="color" id="brandColorInput" value="${currentColor}"
|
||||
style="width: 80px; height: 80px; border: none; cursor: pointer; border-radius: 8px;">
|
||||
|
|
@ -1329,16 +1337,29 @@ const Portal = {
|
|||
style="width: 100%; padding: 8px; border: 1px solid #444; border-radius: 4px; background: #222; color: #fff; font-family: monospace;">
|
||||
</div>
|
||||
</div>
|
||||
<div id="brandColorPreview" style="margin-top: 16px; height: 60px; border-radius: 8px; background: linear-gradient(to bottom, ${currentColor}44, ${currentColor}00, ${currentColor}66);"></div>
|
||||
<div id="brandColorPreview" style="margin-top: 12px; height: 40px; border-radius: 8px; background: linear-gradient(to bottom, ${currentColor}44, ${currentColor}00, ${currentColor}66);"></div>
|
||||
<div style="border-top: 1px solid #333; margin-top: 20px; padding-top: 16px;">
|
||||
<label style="display: block; font-weight: 600; margin-bottom: 6px;">Brand Color (Light)</label>
|
||||
<p style="color: #999; margin-bottom: 12px; font-size: 12px;">Subtle tint for menu builder cards. Leave empty for white.</p>
|
||||
<div style="display: flex; gap: 16px; align-items: center;">
|
||||
<input type="color" id="brandColorLightInput" value="${currentLight || '#F5F5F5'}"
|
||||
style="width: 60px; height: 40px; border: none; cursor: pointer; border-radius: 4px;">
|
||||
<input type="text" id="brandColorLightHex" value="${currentLight}"
|
||||
style="width: 120px; padding: 8px; border: 1px solid #444; border-radius: 4px; background: #222; color: #fff; font-family: monospace;"
|
||||
placeholder="#F5F5F5" maxlength="7">
|
||||
<div id="brandColorLightPreview" style="flex: 1; height: 40px; border-radius: 4px; border: 1px solid #333; background: ${currentLight || '#1a1a1a'};"></div>
|
||||
<button type="button" class="btn btn-secondary" style="font-size: 12px; padding: 6px 10px;" onclick="document.getElementById('brandColorLightHex').value='';document.getElementById('brandColorLightPreview').style.background='#1a1a1a';">Clear</button>
|
||||
</div>
|
||||
</div>
|
||||
<div style="margin-top: 20px; display: flex; gap: 12px; justify-content: flex-end;">
|
||||
<button type="button" class="btn btn-secondary" onclick="Portal.closeModal()">Cancel</button>
|
||||
<button type="button" class="btn btn-primary" onclick="Portal.saveBrandColor()">Save Color</button>
|
||||
<button type="button" class="btn btn-primary" onclick="Portal.saveBrandColor()">Save Colors</button>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
this.showModal();
|
||||
|
||||
// Sync inputs
|
||||
// Sync dark inputs
|
||||
const colorInput = document.getElementById('brandColorInput');
|
||||
const hexInput = document.getElementById('brandColorHex');
|
||||
const preview = document.getElementById('brandColorPreview');
|
||||
|
|
@ -1357,30 +1378,57 @@ const Portal = {
|
|||
preview.style.background = `linear-gradient(to bottom, ${color}44, ${color}00, ${color}66)`;
|
||||
}
|
||||
});
|
||||
|
||||
// Sync light inputs
|
||||
const lightInput = document.getElementById('brandColorLightInput');
|
||||
const lightHex = document.getElementById('brandColorLightHex');
|
||||
const lightPreview = document.getElementById('brandColorLightPreview');
|
||||
|
||||
lightInput.addEventListener('input', () => {
|
||||
lightHex.value = lightInput.value.toUpperCase();
|
||||
lightPreview.style.background = lightInput.value;
|
||||
});
|
||||
|
||||
lightHex.addEventListener('input', () => {
|
||||
let val = lightHex.value;
|
||||
if (/^[0-9A-Fa-f]{6}$/.test(val)) val = '#' + val;
|
||||
if (/^#[0-9A-Fa-f]{6}$/.test(val)) {
|
||||
lightInput.value = val;
|
||||
lightPreview.style.background = val;
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
// Save brand color
|
||||
// Save brand colors
|
||||
async saveBrandColor() {
|
||||
const color = document.getElementById('brandColorHex').value.toUpperCase();
|
||||
if (!/^#?[0-9A-Fa-f]{6}$/.test(color)) {
|
||||
this.toast('Please enter a valid hex color (e.g., #1B4D3E or 1B4D3E)', 'error');
|
||||
return;
|
||||
}
|
||||
const lightColor = (document.getElementById('brandColorLightHex')?.value || '').toUpperCase();
|
||||
if (lightColor && !/^#?[0-9A-Fa-f]{6}$/.test(lightColor)) {
|
||||
this.toast('Invalid light color format. Use #RRGGBB or leave empty', 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await fetch(`${this.config.apiBaseUrl}/businesses/saveBrandColor.cfm`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ BusinessID: this.config.businessId, BrandColor: color })
|
||||
body: JSON.stringify({ BusinessID: this.config.businessId, BrandColor: color, BrandColorLight: lightColor })
|
||||
});
|
||||
const data = await response.json();
|
||||
|
||||
if (data.OK) {
|
||||
this.brandColor = color;
|
||||
this.brandColorLight = lightColor;
|
||||
const swatch = document.getElementById('brandColorSwatch');
|
||||
if (swatch) swatch.style.background = color;
|
||||
const lSwatch = document.getElementById('brandColorLightSwatch');
|
||||
if (lSwatch) lSwatch.style.background = lightColor || '#1a1a1a';
|
||||
this.closeModal();
|
||||
this.toast('Brand color saved!', 'success');
|
||||
this.toast('Brand colors saved!', 'success');
|
||||
} else {
|
||||
this.toast(data.MESSAGE || 'Failed to save color', 'error');
|
||||
}
|
||||
|
|
|
|||
Reference in a new issue