diff --git a/partials/landing/account/dashboard.php b/partials/landing/account/dashboard.php index e1d50be..242c5f9 100755 --- a/partials/landing/account/dashboard.php +++ b/partials/landing/account/dashboard.php @@ -2,6 +2,7 @@ $app = app(); $vm = \App\AccountPages::dashboard($app); extract($vm, EXTR_OVERWRITE); +$avatarPlaceholder = 'data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 12 12%22%3E%3Crect width=%2212%22 height=%2212%22 fill=%22%23f7efe6%22/%3E%3C/svg%3E'; $editing = isset($editEvent) && $editEvent !== null; $actionEvent = $editing ? 'event_update' : 'event_add'; $startVal = $editEvent ? date('Y-m-d\TH:i', strtotime((string)$editEvent['starts_at'])) : ''; @@ -343,9 +344,10 @@ $sectionLinks = [ > <?= htmlspecialchars((string)$choice['label'], ENT_QUOTES) ?> @@ -593,9 +595,7 @@ $sectionLinks = [ btn.addEventListener('click', () => { const id = btn.getAttribute('data-modal-open'); const modal = document.getElementById(id); - if (modal) { - modal.classList.add('open'); - } + if (modal) modal.classList.add('open'); }); }); document.querySelectorAll('[data-modal-close]').forEach(btn => { diff --git a/public/assets/js/app.js b/public/assets/js/app.js index f12bce3..25418e9 100755 --- a/public/assets/js/app.js +++ b/public/assets/js/app.js @@ -788,17 +788,36 @@ document.addEventListener('DOMContentLoaded', () => { image.src = url; }; - const updateAvatarOptionPreviews = (form) => { - form.querySelectorAll('[data-avatar-option-thumb]').forEach((image) => { + const getActiveAvatarField = (form) => { + const activeTab = form.querySelector('[data-avatar-component-tab].is-active'); + return activeTab?.getAttribute('data-avatar-component-tab') || 'avatar_lorelei_eyes_variant'; + }; + + const updateAvatarOptionPreviews = (form, activeField = null) => { + const selector = activeField + ? `[data-avatar-component-panel="${activeField}"] [data-avatar-option-thumb]` + : '[data-avatar-option-thumb]'; + + form.querySelectorAll(selector).forEach((image) => { const field = image.getAttribute('data-avatar-option-field') || ''; const value = image.getAttribute('data-avatar-option-value') || ''; const params = buildAvatarParams(form, { [field]: value }); if (!params) return; - image.src = `${avatarEndpoint}?${params.toString()}`; + const src = `${avatarEndpoint}?${params.toString()}`; + if (image.dataset.avatarLoadedSrc === src) return; + image.dataset.avatarLoadedSrc = src; + image.src = src; }); }; + const ensureAvatarBuilderLoaded = (form) => { + if (form.dataset.avatarInitialized === 'true') return; + form.dataset.avatarInitialized = 'true'; + updateAvatarPreview(form); + updateAvatarOptionPreviews(form, getActiveAvatarField(form)); + }; + const renderAvatarSeedChoices = (form, seeds) => { const picker = form.querySelector('[data-avatar-seed-picker]'); const grid = form.querySelector('[data-avatar-seed-picker-grid]'); @@ -824,8 +843,9 @@ document.addEventListener('DOMContentLoaded', () => { if (!(seedField instanceof HTMLInputElement)) return; seedField.value = seed; picker.hidden = true; + ensureAvatarBuilderLoaded(form); updateAvatarPreview(form); - updateAvatarOptionPreviews(form); + updateAvatarOptionPreviews(form, getActiveAvatarField(form)); }); grid.appendChild(card); }); @@ -834,16 +854,16 @@ document.addEventListener('DOMContentLoaded', () => { }; document.querySelectorAll('[data-avatar-builder]').forEach((form) => { - updateAvatarPreview(form); - updateAvatarOptionPreviews(form); form.querySelectorAll('[data-avatar-field]').forEach((field) => { field.addEventListener('change', () => { + ensureAvatarBuilderLoaded(form); updateAvatarPreview(form); - updateAvatarOptionPreviews(form); + updateAvatarOptionPreviews(form, getActiveAvatarField(form)); }); field.addEventListener('input', () => { + ensureAvatarBuilderLoaded(form); updateAvatarPreview(form); - updateAvatarOptionPreviews(form); + updateAvatarOptionPreviews(form, getActiveAvatarField(form)); }); }); @@ -856,12 +876,16 @@ document.addEventListener('DOMContentLoaded', () => { form.querySelectorAll('[data-avatar-component-panel]').forEach((panel) => { panel.classList.toggle('is-active', panel.getAttribute('data-avatar-component-panel') === field); }); + updateAvatarOptionPreviews(form, field); }; form.querySelectorAll('[data-avatar-component-tab]').forEach((button) => { button.addEventListener('click', () => { const field = button.getAttribute('data-avatar-component-tab'); - if (field) setActiveComponentPanel(field); + if (field) { + ensureAvatarBuilderLoaded(form); + setActiveComponentPanel(field); + } }); }); @@ -913,6 +937,14 @@ document.addEventListener('DOMContentLoaded', () => { }); }); + document.querySelectorAll('[data-modal-open="modalAvatar"]').forEach((button) => { + button.addEventListener('click', () => { + const form = document.querySelector('#modalAvatar [data-avatar-builder]'); + if (!form) return; + window.setTimeout(() => ensureAvatarBuilderLoaded(form), 20); + }); + }); + document.querySelectorAll('[data-nav-events]').forEach(link => { link.addEventListener('click', async () => { if (window.location.pathname === '/' && window.location.hash === '#events') {