mirror of
https://github.com/shoelace-style/webawesome.git
synced 2026-01-12 04:09:12 +00:00
Gating Launch Sale-Based Banner and Dialog (#1769)
* gating wa-launch banner and dialog based on coupon state * addressing PR feedback * Update packages/webawesome/docs/_includes/_dialog-wa-launch.njk Co-authored-by: Konnor Rogers <konnor5456@gmail.com> --------- Co-authored-by: Konnor Rogers <konnor5456@gmail.com>
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
{% raw %}
|
{% raw %}
|
||||||
{%- if not currentUser.hasPro -%}
|
{%- if req.stripe.discount.active and not currentUser.hasPro -%}
|
||||||
<div slot="banner" class="banner-wa-launch wa-dark">
|
<div slot="banner" class="banner-wa-launch wa-dark">
|
||||||
<div class="banner-content wa-split">
|
<div class="banner-content wa-split">
|
||||||
<div class="wa-cluster wa-gap-s">
|
<div class="wa-cluster wa-gap-s">
|
||||||
|
|||||||
@@ -1,97 +1,95 @@
|
|||||||
<wa-dialog id="dialog-site" light-dismiss without-header>
|
{% raw %}
|
||||||
|
{%- if req.stripe.discount.active and not currentUser.hasPro -%}
|
||||||
|
<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="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;">
|
<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-40); --secondary-opacity: 1.0;"></wa-icon>
|
<wa-icon name="party-horn" family="duotone" variant="solid" style="font-size: var(--wa-font-size-3xl); --secondary-color: var(--wa-color-brand-40); --secondary-opacity: 1.0;"></wa-icon>
|
||||||
<h2 class="wa-heading-2xl brand-font">Get a lifetime discount on Web Awesome Pro!</h2>
|
<h2 class="wa-heading-2xl brand-font">Get a lifetime discount on Web Awesome Pro!</h2>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="wa-stack wa-gap-l">
|
<div class="wa-stack wa-gap-l">
|
||||||
<p>Celebrate our official launch with a 20% discount on a Web Awesome Pro plan…<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>
|
<p>Celebrate our official launch with a 20% discount on a Web Awesome Pro plan…<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">
|
<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 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-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>
|
<wa-icon slot="start" variant="regular" name="rocket-launch"></wa-icon>
|
||||||
Get Pro + Save 20%
|
Get Pro + Save 20%
|
||||||
</wa-button>
|
</wa-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</wa-dialog>
|
</wa-dialog>
|
||||||
|
|
||||||
<script type="module">
|
<script type="module">
|
||||||
(function() {
|
(function() {
|
||||||
const SITE_DIALOG_DISMISSED_KEY = 'dialog-wa-launch-sale-dismissed';
|
const SITE_DIALOG_DISMISSED_KEY = 'dialog-wa-launch-sale-dismissed';
|
||||||
|
|
||||||
// Early exit if user has dismissed the dialog
|
// 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 {
|
try {
|
||||||
localStorage.setItem(SITE_DIALOG_DISMISSED_KEY, 'true');
|
if (localStorage.getItem(SITE_DIALOG_DISMISSED_KEY) === 'true') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// localStorage may be disabled or unavailable
|
// localStorage may be disabled or unavailable
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}, { once: true });
|
|
||||||
|
|
||||||
// Show dialog after a short delay to ensure page is loaded
|
// Wait for DOM and dialog element
|
||||||
setTimeout(() => {
|
const dialog = document.getElementById('dialog-site');
|
||||||
dialog.open = true;
|
if (!dialog) {
|
||||||
}, 500);
|
return;
|
||||||
};
|
}
|
||||||
|
|
||||||
// Initialize when ready
|
// Helper function to safely track Plausible events
|
||||||
if (customElements.get('wa-dialog')) {
|
const trackEvent = (eventName) => {
|
||||||
initDialog();
|
if (typeof plausible !== 'undefined') {
|
||||||
} else {
|
plausible(eventName);
|
||||||
document.addEventListener('wa-discovery-complete', initDialog, { once: true });
|
}
|
||||||
// Fallback timeout in case wa-discovery-complete doesn't fire
|
};
|
||||||
setTimeout(initDialog, 100);
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
</script>
|
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
};
|
||||||
|
|
||||||
|
customElements.whenDefined("wa-dialog").then(() => {
|
||||||
|
initDialog()
|
||||||
|
})
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
|
{%- endif -%}
|
||||||
|
{% endraw %}
|
||||||
|
|||||||
@@ -139,11 +139,7 @@
|
|||||||
|
|
||||||
{#- Site-Wide Dialog -#}
|
{#- Site-Wide Dialog -#}
|
||||||
{% if hasSiteDialog %}
|
{% if hasSiteDialog %}
|
||||||
{% raw %}
|
{% include "_dialog-wa-launch.njk" ignore missing %}
|
||||||
{%- if not currentUser.hasPro -%}
|
|
||||||
{% include "_dialog-wa-launch.njk" ignore missing %}
|
|
||||||
{%- endif -%}
|
|
||||||
{% endraw %}
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{# Footer #}
|
{# Footer #}
|
||||||
|
|||||||
Reference in New Issue
Block a user