diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..4d9c8ae --- /dev/null +++ b/.env.example @@ -0,0 +1,8 @@ +# Local development — Vite proxies /api to VITE_API_PROXY_TARGET +VITE_API_BASE_URL=/api +VITE_API_PROXY_TARGET=http://localhost:3001 +VITE_PUBLIC_WEB_BASE=http://localhost:5175 + +# Production (see .env.production — used automatically by `npm run build`) +# VITE_API_BASE_URL=https://api.eventbuzz.live/api +# VITE_PUBLIC_WEB_BASE=https://web.eventbuzz.live diff --git a/package-lock.json b/package-lock.json index 359e45d..e6d4bea 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,6 +8,7 @@ "name": "eventbuzz-web", "version": "0.0.1", "dependencies": { + "bootstrap-icons": "^1.13.1", "flatpickr": "^4.6.13", "react": "^18.3.1", "react-dom": "^18.3.1", @@ -1275,6 +1276,22 @@ "node": ">=6.0.0" } }, + "node_modules/bootstrap-icons": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/bootstrap-icons/-/bootstrap-icons-1.13.1.tgz", + "integrity": "sha512-ijombt4v6bv5CLeXvRWKy7CuM3TRTuPEuGaGKvTV5cz65rQSY8RQ2JcHt6b90cBBAC7s8fsf2EkQDldzCoXUjw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/twbs" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/bootstrap" + } + ], + "license": "MIT" + }, "node_modules/browserslist": { "version": "4.28.4", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.4.tgz", diff --git a/package.json b/package.json index 6a03224..3536389 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,7 @@ "preview": "vite preview --port 5175" }, "dependencies": { + "bootstrap-icons": "^1.13.1", "flatpickr": "^4.6.13", "react": "^18.3.1", "react-dom": "^18.3.1", diff --git a/src/components/microsite/SectionRenderer.tsx b/src/components/microsite/SectionRenderer.tsx index 79f7b7b..eb46c48 100644 --- a/src/components/microsite/SectionRenderer.tsx +++ b/src/components/microsite/SectionRenderer.tsx @@ -12,6 +12,21 @@ function str(v: unknown, fallback = ''): string { return v != null ? String(v).trim() : fallback; } +function isRegisterLabel(label: string): boolean { + return /\bregister\b/i.test(label); +} + +function looksLikeRegistrationUrl(url: string): boolean { + return /\/register\/?$/i.test(url) || /\/form\/[a-f0-9]{24}\/?$/i.test(url); +} + +function resolveRegistrationCtaUrl(label: string, configuredUrl: unknown, registrationUrl: string): string { + const configured = str(configuredUrl); + const wantsRegistration = isRegisterLabel(label) || looksLikeRegistrationUrl(configured); + if (wantsRegistration) return registrationUrl; + return configured || '#'; +} + function HeaderSection({ section, ctx }: { section: MicrositeSection; ctx: Ctx }) { const c = section.config; const logoText = str(c.logoText, ctx.data.event.name); @@ -40,6 +55,7 @@ function HeaderSection({ section, ctx }: { section: MicrositeSection; ctx: Ctx } const label = str(item.label); const url = str(item.url, '#'); const isReg = label.toLowerCase() === 'register'; + if (isReg && !ctx.registrationUrl) return null; return (
{subtext}
: null} - - {buttonLabel} - + {buttonUrl && buttonUrl !== '#' ? ( + + {buttonLabel} + + ) : null}{str(tier.price)}
{tier.description ?{tier.description}
: null} - - Register - + {ctx.registrationUrl ? ( + + Register + + ) : null}