Remove CTA button from mobile

This commit is contained in:
2026-05-07 07:57:52 +12:00
parent ad9df7578a
commit 32ccd49d78
8 changed files with 74 additions and 19 deletions
+6
View File
@@ -75,6 +75,7 @@ It is created from [deploy.env.template](deploy.env.template). Current template
```env ```env
APP_VERSION=4.2.3 APP_VERSION=4.2.3
ENABLE_GENERAL_ENQUIRIES=false ENABLE_GENERAL_ENQUIRIES=false
PUBLIC_ENABLE_MOBILE_CTA_BUTTON=false
TZ=Pacific/Auckland TZ=Pacific/Auckland
POSTGRES_DB=goodwalk POSTGRES_DB=goodwalk
@@ -100,6 +101,11 @@ After the first deploy, edit `/docker/goodwalk-svelte/.env` on the server and re
- `RESEND_API_KEY=replace-me` - `RESEND_API_KEY=replace-me`
- `OWNER_EMAIL=replace-me` - `OWNER_EMAIL=replace-me`
Frontend flags:
- `PUBLIC_ENABLE_MOBILE_CTA_BUTTON=false` keeps the sticky mobile booking CTA hidden.
- Set `PUBLIC_ENABLE_MOBILE_CTA_BUTTON=true` to show it again.
4. Confirm the shared Docker network already exists: 4. Confirm the shared Docker network already exists:
```bash ```bash
+1
View File
@@ -13,6 +13,7 @@ CLIENT_BCC=mattcohen0@gmail.com
FROM_EMAIL=GoodWalk <info@goodwalk.co.nz> FROM_EMAIL=GoodWalk <info@goodwalk.co.nz>
REPLY_TO=info@goodwalk.co.nz REPLY_TO=info@goodwalk.co.nz
ENABLE_GENERAL_ENQUIRIES=false ENABLE_GENERAL_ENQUIRIES=false
PUBLIC_ENABLE_MOBILE_CTA_BUTTON=false
FORM_MIN_SECONDS=4 FORM_MIN_SECONDS=4
FORM_MAX_SECONDS=7200 FORM_MAX_SECONDS=7200
+1
View File
@@ -11,6 +11,7 @@ services:
NODE_ENV: production NODE_ENV: production
PORT: 3000 PORT: 3000
ENABLE_GENERAL_ENQUIRIES: ${ENABLE_GENERAL_ENQUIRIES:-false} ENABLE_GENERAL_ENQUIRIES: ${ENABLE_GENERAL_ENQUIRIES:-false}
PUBLIC_ENABLE_MOBILE_CTA_BUTTON: ${PUBLIC_ENABLE_MOBILE_CTA_BUTTON:-false}
TZ: ${TZ:-Pacific/Auckland} TZ: ${TZ:-Pacific/Auckland}
depends_on: depends_on:
- db - db
+1
View File
@@ -10,6 +10,7 @@ services:
NODE_ENV: production NODE_ENV: production
PORT: ${APP_PORT:-3000} PORT: ${APP_PORT:-3000}
ENABLE_GENERAL_ENQUIRIES: ${ENABLE_GENERAL_ENQUIRIES:-false} ENABLE_GENERAL_ENQUIRIES: ${ENABLE_GENERAL_ENQUIRIES:-false}
PUBLIC_ENABLE_MOBILE_CTA_BUTTON: ${PUBLIC_ENABLE_MOBILE_CTA_BUTTON:-false}
TZ: ${TZ:-Pacific/Auckland} TZ: ${TZ:-Pacific/Auckland}
depends_on: depends_on:
- db - db
+13 -2
View File
@@ -3,6 +3,7 @@
import { afterNavigate } from '$app/navigation'; import { afterNavigate } from '$app/navigation';
import { page } from '$app/stores'; import { page } from '$app/stores';
import Icon from '$lib/components/Icon.svelte'; import Icon from '$lib/components/Icon.svelte';
import { isMobileCtaButtonEnabled } from '$lib/feature-flags';
/* /*
* Sticky bottom CTA shown on mobile only. * Sticky bottom CTA shown on mobile only.
@@ -20,6 +21,8 @@
* to book while they're already on the form). * to book while they're already on the form).
*/ */
const mobileCtaButtonEnabled = isMobileCtaButtonEnabled();
$: pathname = $page.url.pathname; $: pathname = $page.url.pathname;
$: hidden = pathname === '/contact-us' || pathname === '/booking'; $: hidden = pathname === '/contact-us' || pathname === '/booking';
@@ -41,7 +44,7 @@
} }
async function setupObservers() { async function setupObservers() {
if (typeof window === 'undefined') { if (!mobileCtaButtonEnabled || typeof window === 'undefined') {
return; return;
} }
@@ -84,6 +87,10 @@
} }
afterNavigate(() => { afterNavigate(() => {
if (!mobileCtaButtonEnabled) {
return;
}
visible = false; visible = false;
triggerPassed = false; triggerPassed = false;
bookingInView = false; bookingInView = false;
@@ -91,6 +98,10 @@
}); });
onMount(() => { onMount(() => {
if (!mobileCtaButtonEnabled) {
return;
}
void setupObservers(); void setupObservers();
return () => { return () => {
@@ -99,7 +110,7 @@
}); });
</script> </script>
{#if !hidden} {#if mobileCtaButtonEnabled && !hidden}
<div <div
class="mobile-book-bar" class="mobile-book-bar"
class:mobile-book-bar-visible={visible} class:mobile-book-bar-visible={visible}
+30
View File
@@ -0,0 +1,30 @@
import { afterEach, describe, expect, it, vi } from 'vitest';
describe('feature flags', () => {
afterEach(() => {
vi.unstubAllEnvs();
vi.resetModules();
});
it('defaults the mobile CTA button to disabled', async () => {
const { isMobileCtaButtonEnabled } = await import('./feature-flags');
expect(isMobileCtaButtonEnabled()).toBe(false);
});
it('enables the mobile CTA button when the public env flag is truthy', async () => {
vi.stubEnv('PUBLIC_ENABLE_MOBILE_CTA_BUTTON', 'enabled');
const { isMobileCtaButtonEnabled } = await import('./feature-flags');
expect(isMobileCtaButtonEnabled()).toBe(true);
});
it('treats explicit false values as disabled', async () => {
vi.stubEnv('PUBLIC_ENABLE_MOBILE_CTA_BUTTON', 'off');
const { isMobileCtaButtonEnabled } = await import('./feature-flags');
expect(isMobileCtaButtonEnabled()).toBe(false);
});
});
+21
View File
@@ -0,0 +1,21 @@
export function parseBooleanFlag(value: string | undefined, defaultValue = false) {
if (value == null) {
return defaultValue;
}
const normalized = value.trim().toLowerCase();
if (['1', 'true', 'yes', 'on', 'enabled'].includes(normalized)) {
return true;
}
if (['0', 'false', 'no', 'off', 'disabled'].includes(normalized)) {
return false;
}
return defaultValue;
}
export function isMobileCtaButtonEnabled() {
return parseBooleanFlag(import.meta.env.PUBLIC_ENABLE_MOBILE_CTA_BUTTON, false);
}
+1 -17
View File
@@ -1,20 +1,4 @@
function parseBooleanFlag(value: string | undefined, defaultValue = false) { import { parseBooleanFlag } from '$lib/feature-flags';
if (value == null) {
return defaultValue;
}
const normalized = value.trim().toLowerCase();
if (['1', 'true', 'yes', 'on', 'enabled'].includes(normalized)) {
return true;
}
if (['0', 'false', 'no', 'off', 'disabled'].includes(normalized)) {
return false;
}
return defaultValue;
}
export function isGeneralEnquiryEnabled() { export function isGeneralEnquiryEnabled() {
return parseBooleanFlag(process.env.ENABLE_GENERAL_ENQUIRIES, false); return parseBooleanFlag(process.env.ENABLE_GENERAL_ENQUIRIES, false);