From 771f70f2f358f4bd1dfcfddf2e92a1a4fbe8221a Mon Sep 17 00:00:00 2001 From: John Mizerek Date: Thu, 5 Mar 2026 15:09:30 -0800 Subject: [PATCH] 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 --- portal/index.html | 11 +++++--- portal/portal.js | 66 ++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 64 insertions(+), 13 deletions(-) diff --git a/portal/index.html b/portal/index.html index 3fd2346..303b984 100644 --- a/portal/index.html +++ b/portal/index.html @@ -650,12 +650,15 @@
- -

Used for accents and fallback backgrounds

+ +

Dark for accents/gradients, Light for card tinting

- +
+ + +
diff --git a/portal/portal.js b/portal/portal.js index ca27356..c90220c 100644 --- a/portal/portal.js +++ b/portal/portal.js @@ -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 = `
-

This color is used for accents and fallback backgrounds in your menu.

+ +

Used for accents and gradients in the customer app.

@@ -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;">
-
+
+
+ +

Subtle tint for menu builder cards. Leave empty for white.

+
+ + +
+ +
+
- +
`; 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'); }