Add Launch Sale Dialog (#1739)

* adding site-wide dialog to base.njk

* adding logic to control dialog rendering

* adding sale-based site-wide dialog

* overriding docs brand props for `#dialog-site`

* adding plausible event tracking to sale-based site-wide dialog
This commit is contained in:
Brian Talbot
2025-11-12 14:46:04 -05:00
committed by GitHub
parent 9d6ded49b9
commit dfaa959951
3 changed files with 125 additions and 0 deletions

View File

@@ -0,0 +1,97 @@
<wa-dialog id="dialog-site" light-dismiss without-header>
<div class="background-wa-pattern" style="justify-content: center; margin-inline: calc(var(--spacing) * -1); margin-block-start: calc(var(--spacing) * -1); margin-block-end: var(--spacing); background: linear-gradient(to bottom, var(--wa-color-brand), var(--wa-color-brand-50)); color: var(--wa-color-brand-on-loud); padding: var(--wa-space-3xl) var(--spacing); --background-pattern-opacity: 0.2; --background-pattern-image: url('/assets/images/bg-wa-pattern.svg');">
<div class="wa-stack wa-align-items-center" style="text-align: center;">
<wa-icon name="party-horn" family="duotone" variant="solid" style="font-size: var(--wa-font-size-3xl); --secondary-color: var(--wa-color-brand-on-quiet); --secondary-opacity: 1.0;"></wa-icon>
<h2 class="wa-heading-2xl brand-font">Get a lifetime discount on Web Awesome Pro!</h2>
</div>
</div>
<div class="wa-stack wa-gap-l">
<p>Celebrate our official launch with a 20% discount on a Web Awesome Pro plan&hellip;<span class="appearance-underlined variant-drawn" style="--underline-color: var(--wa-color-brand);">for life</span>! But hurry, this lifetime discount is only available for a limited time.</p>
<div class="wa-split">
<wa-button type="button" appearance="plain" data-dialog="close" class="plausible-event-name=launch_dialog:close_button_click">Maybe Later</wa-button>
<wa-button variant="neutral" appearance="accent" href="/purchase" class="brand-font plausible-event-name=launch_dialog:pro_purchase_button_click">
<wa-icon slot="start" variant="regular" name="rocket-launch"></wa-icon>
Get Pro + Save 20%
</wa-button>
</div>
</div>
</wa-dialog>
<script type="module">
(function() {
const SITE_DIALOG_DISMISSED_KEY = 'dialog-wa-launch-sale-dismissed';
// Early exit if user has dismissed the dialog
try {
if (localStorage.getItem(SITE_DIALOG_DISMISSED_KEY) === 'true') {
return;
}
} catch (e) {
// localStorage may be disabled or unavailable
return;
}
// Wait for DOM and dialog element
const dialog = document.getElementById('dialog-site');
if (!dialog) {
return;
}
// Helper function to safely track Plausible events
const trackEvent = (eventName) => {
if (typeof plausible !== 'undefined') {
plausible(eventName);
}
};
// Initialize dialog functionality
let initCalled = false;
const initDialog = () => {
// Prevent double initialization
if (initCalled) {
return;
}
initCalled = true;
// Track when dialog is shown
dialog.addEventListener('wa-show', () => {
trackEvent('launch_dialog:view');
}, { once: true });
// Track when dialog is dismissed
dialog.addEventListener('wa-hide', (event) => {
// Track overlay click or Escape key dismissal
// Button clicks are tracked via CSS classes, so we only track non-button dismissals
if (event.detail?.source === dialog) {
trackEvent('launch_dialog:overlay_click');
}
// Save dismissal state to localStorage
try {
localStorage.setItem(SITE_DIALOG_DISMISSED_KEY, 'true');
} catch (e) {
// localStorage may be disabled or unavailable
}
}, { once: true });
// Show dialog after a short delay to ensure page is loaded
setTimeout(() => {
dialog.open = true;
}, 500);
};
// Initialize when ready
if (customElements.get('wa-dialog')) {
initDialog();
} else {
document.addEventListener('wa-discovery-complete', initDialog, { once: true });
// Fallback timeout in case wa-discovery-complete doesn't fire
setTimeout(initDialog, 100);
}
})();
</script>

View File

@@ -1,6 +1,7 @@
<!DOCTYPE html>
{% if hasAnchors == undefined %}{% set hasAnchors = true %}{% endif %}
{% if hasBanner == undefined %}{% set hasBanner = true %}{% endif %}
{% if hasSiteDialog == undefined %}{% set hasSiteDialog = true %}{% endif %}
{% if hasGeneratedTitle == undefined %}{% set hasGeneratedTitle = true %}{% endif %}
<html lang="en" data-fa-kit-code="38c11e3f20" data-version="{{ package.version }}" class="wa-cloak"{% if hasAnchors == false %} data-no-anchor{% endif %}>
<head>
@@ -136,6 +137,15 @@
{% include 'search.njk' %}
{#- Site-Wide Dialog -#}
{% if hasSiteDialog %}
{% raw %}
{%- if not currentUser.hasPro -%}
{% include "_dialog-wa-launch.njk" ignore missing %}
{%- endif -%}
{% endraw %}
{% endif %}
{# Footer #}
{% block pageFooter %}{% endblock %}
</wa-page>

View File

@@ -64,6 +64,24 @@ wa-page > [slot='banner'] {
}
}
/* Site-Wide Dialog */
#dialog-site {
/* custom brand colors carrried over from theme-site for the banner */
--wa-color-brand-95: #fef0ec;
--wa-color-brand-90: #fce0d8;
--wa-color-brand-80: #f8bcac;
--wa-color-brand-70: #fa9378;
--wa-color-brand-60: #f46a45;
--wa-color-brand-50: #cb4b27;
--wa-color-brand-40: #9d371a;
--wa-color-brand-30: #7c2a13;
--wa-color-brand-20: #5d1d0b;
--wa-color-brand-10: #3b0f05;
--wa-color-brand-05: #270802;
--wa-color-brand: var(--wa-color-brand-60);
--wa-color-brand-on: var(--wa-color-brand-10);
}
/* Header */
wa-page::part(header) {
background-color: var(--wa-color-surface-default);