From 2562c51c2773c6ad3cbc03745119ef3c16baf224 Mon Sep 17 00:00:00 2001 From: John Mizerek Date: Sun, 1 Feb 2026 08:08:03 -0800 Subject: [PATCH] Normalize API response keys to uppercase for consistent access Lucee serializeJSON casing varies by server config (preserveCaseForStructKey). Normalize all biz object keys to uppercase on the JS side so lookups work regardless of server config. Co-Authored-By: Claude Opus 4.5 --- portal/portal.js | 41 +++++++++++++++++------------------------ 1 file changed, 17 insertions(+), 24 deletions(-) diff --git a/portal/portal.js b/portal/portal.js index 22d460a..89236f8 100644 --- a/portal/portal.js +++ b/portal/portal.js @@ -724,50 +724,43 @@ const Portal = { const data = await response.json(); if (data.OK && data.BUSINESS) { - const biz = data.BUSINESS; + // Normalize all keys to uppercase for consistent access + // (Lucee serializeJSON casing varies by server config) + const raw = data.BUSINESS; + const biz = {}; + Object.keys(raw).forEach(k => { biz[k.toUpperCase()] = raw[k]; }); this.currentBusiness = biz; - // Populate form fields (Lucee serializes all keys as uppercase) - document.getElementById('settingBusinessName').value = biz.BUSINESSNAME || biz.Name || ''; - document.getElementById('settingPhone').value = biz.BUSINESSPHONE || biz.Phone || ''; - document.getElementById('settingTaxRate').value = biz.TAXRATEPERCENT || biz.TaxRatePercent || ''; - document.getElementById('settingAddressLine1').value = biz.ADDRESSLINE1 || biz.Line1 || ''; - document.getElementById('settingCity').value = biz.ADDRESSCITY || biz.City || ''; - document.getElementById('settingState').value = biz.ADDRESSSTATE || biz.AddressState || ''; - document.getElementById('settingZip').value = biz.ADDRESSZIP || biz.AddressZip || ''; - - // DEBUG: show what keys the API returned - alert('BIZ KEYS: ' + Object.keys(biz).join(', ')); - alert('BRANDCOLOR=' + biz.BRANDCOLOR + ' | BrandColor=' + biz.BrandColor); - alert('HEADERIMAGEURL=' + biz.HEADERIMAGEURL + ' | HeaderImageURL=' + biz.HeaderImageURL); + // Populate form fields + document.getElementById('settingBusinessName').value = biz.NAME || biz.BUSINESSNAME || ''; + document.getElementById('settingPhone').value = biz.PHONE || biz.BUSINESSPHONE || ''; + document.getElementById('settingTaxRate').value = biz.TAXRATEPERCENT || ''; + document.getElementById('settingAddressLine1').value = biz.LINE1 || biz.ADDRESSLINE1 || ''; + document.getElementById('settingCity').value = biz.CITY || biz.ADDRESSCITY || ''; + document.getElementById('settingState').value = biz.ADDRESSSTATE || ''; + document.getElementById('settingZip').value = biz.ADDRESSZIP || ''; // Load brand color if set - const brandColor = biz.BRANDCOLOR || biz.BrandColor; + const brandColor = biz.BRANDCOLOR || ''; if (brandColor) { this.brandColor = brandColor; const swatch = document.getElementById('brandColorSwatch'); - alert('swatch found: ' + !!swatch + ' | brandColor: ' + brandColor); if (swatch) swatch.style.backgroundColor = brandColor; } // Load header preview const headerPreview = document.getElementById('headerPreview'); const headerWrapper = document.getElementById('headerPreviewWrapper'); - const headerUrl = biz.HEADERIMAGEURL || biz.HeaderImageURL; - alert('headerPreview found: ' + !!headerPreview + ' | headerUrl: ' + headerUrl); + const headerUrl = biz.HEADERIMAGEURL || ''; if (headerPreview && headerUrl) { - headerPreview.onerror = function() { - alert('IMG LOAD ERROR: ' + headerPreview.src); - }; headerPreview.onload = function() { - alert('IMG LOADED OK'); if (headerWrapper) headerWrapper.style.display = 'block'; }; headerPreview.src = `${headerUrl}?t=${Date.now()}`; } // Render hours editor - this.renderHoursEditor(biz.BUSINESSHOURSDETAIL || biz.HoursDetail || []); + this.renderHoursEditor(biz.HOURSDETAIL || biz.BUSINESSHOURSDETAIL || []); } } catch (err) { console.error('[Portal] Error loading business info:', err); @@ -1118,7 +1111,7 @@ const Portal = { openCustomerPreview() { const businessId = this.config.businessId; const businessName = encodeURIComponent( - this.currentBusiness?.BUSINESSNAME || this.currentBusiness?.Name || 'Preview' + this.currentBusiness?.NAME || this.currentBusiness?.BUSINESSNAME || 'Preview' ); const deepLink = `payfrit://open?businessId=${businessId}&businessName=${businessName}`; window.location.href = deepLink;