Wire demo for production deploy + add server config

Fixes images 404'ing under /arrangement/ — Vite's publicDir copies assets
to the build root, but the base prefix is only applied to bundled assets
(JS/CSS), not to runtime URL strings. assetUrl() helper resolves paths
against import.meta.env.BASE_URL so '/images/foo.png' becomes
'/arrangement/images/foo.png' in production while staying '/images/foo.png'
in dev.

- src/demo/shared/assets.ts — assetUrl() helper
- providers.ts + DemoNav.tsx — wrap all public asset paths
- nginx/parsons-demos.conf — swag site-conf for parsons.tensordesign.com.au
  (asset cache regex above SPA fallback regex per nginx first-match rule)
- docs/reference/client-demo-deploy.md — server runbook (DNS, swag
  SUBDOMAINS, mount, htpasswd, deploy loop)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-20 17:22:40 +10:00
parent 45d73759c1
commit cd7f99f59d
5 changed files with 289 additions and 12 deletions

View File

@@ -1,17 +1,18 @@
import Box from '@mui/material/Box';
import { Navigation } from '../../../components/organisms/Navigation';
import { assetUrl } from '../../shared/assets';
const FALogo = () => (
<Box sx={{ display: 'flex', alignItems: 'center' }}>
<Box
component="img"
src="/brandlogo/logo-full.svg"
src={assetUrl('/brandlogo/logo-full.svg')}
alt="Funeral Arranger"
sx={{ height: 28, display: { xs: 'none', md: 'block' } }}
/>
<Box
component="img"
src="/brandlogo/logo-short.svg"
src={assetUrl('/brandlogo/logo-short.svg')}
alt="Funeral Arranger"
sx={{ height: 28, display: { xs: 'block', md: 'none' } }}
/>

17
src/demo/shared/assets.ts Normal file
View File

@@ -0,0 +1,17 @@
/**
* Resolve a public-asset path against Vite's base URL.
*
* In dev `import.meta.env.BASE_URL === '/'`, so `assetUrl('/images/foo.png')`
* returns `/images/foo.png` unchanged. In production the build sets base to
* `/arrangement/` (or whatever `--mode <slice>` was passed), and the same
* call returns `/arrangement/images/foo.png` so the bundled assets resolve
* correctly under the slice subpath.
*
* Always pass leading-slash paths — they're relative to the publicDir root.
*/
export const assetUrl = (path: string): string => {
const base = import.meta.env.BASE_URL;
const cleanBase = base.endsWith('/') ? base.slice(0, -1) : base;
const cleanPath = path.startsWith('/') ? path : `/${path}`;
return `${cleanBase}${cleanPath}`;
};

View File

@@ -1,5 +1,6 @@
import type { ProviderData } from '../../../components/pages/ProvidersStep';
import type { PackagesStepProvider, ProviderTier } from '../../../components/pages/PackagesStep';
import { assetUrl } from '../assets';
export interface DemoProvider extends ProviderData {
id: string;
@@ -13,8 +14,8 @@ export const providers: DemoProvider[] = [
location: 'Wentworth, NSW',
verified: true,
tier: 'verified',
imageUrl: '/images/venues/hparsons-funeral-home-wollongong/01.jpg',
logoUrl: '/images/providers/hparsons-funeral-directors/logo.png',
imageUrl: assetUrl('/images/venues/hparsons-funeral-home-wollongong/01.jpg'),
logoUrl: assetUrl('/images/providers/hparsons-funeral-directors/logo.png'),
rating: 4.6,
reviewCount: 7,
startingPrice: 1800,
@@ -28,8 +29,8 @@ export const providers: DemoProvider[] = [
location: 'Wollongong, NSW',
verified: true,
tier: 'verified',
imageUrl: '/images/venues/rankins-funeral-home-warrawong/01.jpg',
logoUrl: '/images/providers/rankins-funerals/logo.png',
imageUrl: assetUrl('/images/venues/rankins-funeral-home-warrawong/01.jpg'),
logoUrl: assetUrl('/images/providers/rankins-funerals/logo.png'),
rating: 4.8,
reviewCount: 23,
startingPrice: 2450,
@@ -52,8 +53,8 @@ export const providers: DemoProvider[] = [
location: 'Kingaroy, QLD',
verified: true,
tier: 'verified',
imageUrl: '/images/venues/killick-family-funerals-chapel-kingaroy/01.jpg',
logoUrl: '/images/providers/killick-family-funerals/logo.png',
imageUrl: assetUrl('/images/venues/killick-family-funerals-chapel-kingaroy/01.jpg'),
logoUrl: assetUrl('/images/providers/killick-family-funerals/logo.png'),
rating: 4.9,
reviewCount: 15,
startingPrice: 3100,
@@ -65,8 +66,8 @@ export const providers: DemoProvider[] = [
location: 'Ourimbah, NSW',
verified: true,
tier: 'verified',
imageUrl: '/images/venues/mackay-family-garden-estate/01.jpg',
logoUrl: '/images/providers/mackay-family-funerals/logo.webp',
imageUrl: assetUrl('/images/venues/mackay-family-garden-estate/01.jpg'),
logoUrl: assetUrl('/images/providers/mackay-family-funerals/logo.webp'),
rating: 4.6,
reviewCount: 87,
startingPrice: 2800,
@@ -78,8 +79,8 @@ export const providers: DemoProvider[] = [
location: 'Bega, NSW',
verified: true,
tier: 'verified',
imageUrl: '/images/venues/mannings-chapel/01.jpg',
logoUrl: '/images/providers/mannings-funerals/logo.png',
imageUrl: assetUrl('/images/venues/mannings-chapel/01.jpg'),
logoUrl: assetUrl('/images/providers/mannings-funerals/logo.png'),
rating: 4.7,
reviewCount: 31,
startingPrice: 2600,