// Section 4b — Marketing & Sales (admin sub-page)
function AdminMarketingSales() {
const revenueData = [
{ label: 'Mon', revenue: 28400, bookings: 12 },
{ label: 'Tue', revenue: 34200, bookings: 14 },
{ label: 'Wed', revenue: 41800, bookings: 18 },
{ label: 'Thu', revenue: 38400, bookings: 16 },
{ label: 'Fri', revenue: 52600, bookings: 22 },
{ label: 'Sat', revenue: 64200, bookings: 27 },
{ label: 'Sun', revenue: 71800, bookings: 31 },
{ label: 'Mon', revenue: 48200, bookings: 19 },
{ label: 'Tue', revenue: 56400, bookings: 23 },
{ label: 'Wed', revenue: 62800, bookings: 26 },
{ label: 'Thu', revenue: 58200, bookings: 24 },
{ label: 'Fri', revenue: 74600, bookings: 30 },
{ label: 'Sat', revenue: 84200, bookings: 34 },
{ label: 'Sun', revenue: 79400, bookings: 32 },
];
const channels = [
{ label: 'Direct', value: 38, conv: 4.2, spend: 0 },
{ label: 'Organic search', value: 24, conv: 2.8, spend: 0 },
{ label: 'Instagram', value: 18, conv: 3.4, spend: 12400 },
{ label: 'Editorial', value: 12, conv: 5.1, spend: 8200 },
{ label: 'Referral', value: 8, conv: 6.4, spend: 0 },
];
const campaigns = [
{ name: 'Wellness reset · Q2', channel: 'Instagram', spend: 4200, rev: 38400, roas: 9.1, status: 'live' },
{ name: 'Honeymoon edit · May', channel: 'Editorial', spend: 6800, rev: 71200, roas: 10.5, status: 'live' },
{ name: 'Sidemen rice fields', channel: 'Newsletter', spend: 0, rev: 22800, roas: '—', status: 'live' },
{ name: 'Ubud retreats · revival',channel: 'Instagram', spend: 2400, rev: 8400, roas: 3.5, status: 'paused' },
{ name: 'Family compounds', channel: 'Editorial', spend: 1800, rev: 14200, roas: 7.9, status: 'draft' },
];
return (
{/* KPI strip */}
Gross bookings · 14d
d.revenue)} width={120} height={36} />
+18.2%
Bookings · 14d
328
d.bookings)} width={120} height={36} />
+11.4%
Avg booking value
5.7 nights · ADR $478
Blended ROAS
8.4×
Spend $20.6k · rev $174k
{/* Revenue chart */}
Gross bookings.
Last 14 days · USD · daily
7d14d30d90d
`$${(v/1000).toFixed(0)}k`} highlightIdx={12} />
{/* Channels + campaigns */}
Acquisition channels.
{channels.map((c, i) => (
{c.label}
{c.value}% · conv {c.conv}%
))}
Live campaigns.
{['Campaign', 'Channel', 'Spend', 'Revenue', 'ROAS', ''].map(h => {h})}
{campaigns.map((c, i) => (
{c.name}
{c.status}
{c.channel}
{typeof c.roas === 'number' ? `${c.roas}×` : c.roas}
Open
))}
{/* Funnel + cohorts */}
Sales funnel · 14d.
{[
{ stage: 'Visit', n: 84200, pct: 100 },
{ stage: 'Villa view', n: 28400, pct: 34 },
{ stage: 'Inquiry', n: 4280, pct: 5.1 },
{ stage: 'Quote sent', n: 3120, pct: 3.7 },
{ stage: 'Booking', n: 328, pct: 0.39 },
].map((f, i) => (
{f.stage}
{f.n.toLocaleString()} · {f.pct}%
))}
Top destinations.
{[
{ name: 'Ubud', rev: 248400, share: 28 },
{ name: 'Canggu', rev: 186200, share: 21 },
{ name: 'Tabanan', rev: 142800, share: 16 },
{ name: 'Sidemen', rev: 98400, share: 11 },
{ name: 'Munduk', rev: 64200, share: 7 },
].map((d, i) => (
{String(i+1).padStart(2,'0')}
{d.name}
))}
);
}
// Section 4c — Orchestration (design tokens, social, marketing automation)
function AdminOrchestration() {
const [tab, setTab] = React.useState('design');
const tabs = [
{ key: 'design', label: 'Design system' },
{ key: 'social', label: 'Social' },
{ key: 'automation', label: 'Automation' },
{ key: 'integrations', label: 'Integrations' },
];
return (
{tab === 'design' &&
}
{tab === 'social' &&
}
{tab === 'automation' &&
}
{tab === 'integrations' &&
}
);
}
function OrchDesign() {
return (
Design tokens.
Synced to repo · last push 2h ago
{[
{ token: 'color/ink', value: '#141414', use: 'Body, primary CTA' },
{ token: 'color/border', value: '#e5e5e5', use: 'Hairlines' },
{ token: 'radius/pill', value: '100', use: 'Buttons, chips' },
{ token: 'radius/card', value: '18', use: 'Panels' },
{ token: 'radius/input', value: '12', use: 'Inputs' },
{ token: 'font/display', value: 'Playfair', use: 'H1–H3, italic' },
{ token: 'font/ui', value: 'Plus Jakarta', use: 'UI, body, numerics' },
].map((t, i) => (
{t.token}
{t.token.startsWith('color') && }
{t.value}
{t.use}
Edit
))}
Brand assets.
{['Wordmark', 'Crest', 'Photo set · Ubud', 'Photo set · Canggu', 'Email header', 'IG template'].map((a, i) => (
v{2+i}.0
{a}
))}
BANNED IN PRODUCTION
{['Gold', 'Terracotta', 'Cream', 'Inter', 'Cormorant', 'Times'].map(b => (
{b}
))}
);
}
function OrchSocial() {
const followers = [
{ label: 'W1', ig: 84200, tt: 12400, pin: 8400 },
{ label: 'W2', ig: 86400, tt: 13800, pin: 8600 },
{ label: 'W3', ig: 88200, tt: 15400, pin: 8800 },
{ label: 'W4', ig: 91400, tt: 18200, pin: 9100 },
{ label: 'W5', ig: 94800, tt: 22400, pin: 9400 },
{ label: 'W6', ig: 98200, tt: 28600, pin: 9700 },
{ label: 'W7', ig: 102400, tt: 34800, pin: 10200 },
{ label: 'W8', ig: 108600, tt: 42400, pin: 10800 },
];
const posts = [
{ ts: 'Today · 16:00', plat: 'Instagram', kind: 'Carousel', caption: 'A week in the rice terraces · Sidemen', status: 'scheduled' },
{ ts: 'Today · 19:30', plat: 'TikTok', kind: 'Video', caption: 'Sunrise at Sumeru · 28s', status: 'scheduled' },
{ ts: 'Tomorrow · 09:00', plat: 'Pinterest', kind: 'Idea pin', caption: 'Quiet for two · Munduk', status: 'draft' },
{ ts: 'Fri · 17:00', plat: 'Newsletter', kind: 'Editorial', caption: 'Wellness reset · 6 nights', status: 'in review' },
{ ts: 'Sat · 11:00', plat: 'Instagram', kind: 'Reel', caption: 'Chef Komang · 6-course tasting', status: 'scheduled' },
];
return (
{[
{ label: 'Instagram', value: '108.6k', delta: '+5.7% · 30d' },
{ label: 'TikTok', value: '42.4k', delta: '+89% · 30d' },
{ label: 'Pinterest', value: '10.8k', delta: '+5.8% · 30d' },
{ label: 'Newsletter', value: '24.2k', delta: '+2.1% · 30d' },
].map(s => (
{s.label}
{s.value}
{s.delta}
))}
Audience growth.
Followers · weekly · 8 weeks
{[{ k: 'ig', l: 'Instagram' }, { k: 'tt', l: 'TikTok' }, { k: 'pin', l: 'Pinterest' }].map((s, i) => (
{s.l}
))}
`${(v/1000).toFixed(0)}k`} />
Content calendar.
{posts.map((p, i) => (
{p.ts}
{p.plat}
{p.caption}
{p.kind}
{p.status}
))}
Top posts · 30d.
{[
{ cap: 'Sumeru sunrise · reel', plat: 'IG', reach: 482000, eng: 8.4 },
{ cap: 'Six nights, volcanic Bali', plat: 'IG', reach: 318000, eng: 6.2 },
{ cap: 'Driver, villa, repeat', plat: 'TT', reach: 1240000, eng: 12.8 },
{ cap: 'Honeymoon edit', plat: 'Pin', reach: 84200, eng: 4.1 },
].map((p, i) => (
{p.cap}
{p.plat}
{(p.reach/1000).toFixed(0)}k
{p.eng}%
))}
);
}
function OrchAutomation() {
const flows = [
{ name: 'Welcome series', trigger: 'Sign-up', steps: 4, sent: 1248, open: 64.2, click: 12.4, status: 'on' },
{ name: 'Abandoned inquiry', trigger: 'Inquiry · 24h idle', steps: 3, sent: 412, open: 71.8, click: 18.2, status: 'on' },
{ name: 'Post-stay journal', trigger: 'Check-out + 48h', steps: 2, sent: 318, open: 82.4, click: 28.6, status: 'on' },
{ name: 'Tier upgrade · Obsidian', trigger: 'Nights ≥ 25', steps: 5, sent: 24, open: 91.2, click: 42.8, status: 'on' },
{ name: 'Lapsed guest · 90d', trigger: 'No activity 90d', steps: 4, sent: 612, open: 38.4, click: 4.2, status: 'paused' },
];
return (
Marketing flows.
Email + WhatsApp · triggered automations
{['Flow', 'Trigger', 'Steps', 'Sent', 'Open', 'Click', ''].map(h => {h})}
{flows.map((f, i) => (
{f.name}
{f.status}
{f.trigger}
{f.steps}
{f.sent.toLocaleString()}
{f.open}%
{f.click}%
{}} />
))}
Flow visualizer · Welcome series.
{[
{ kind: 'trigger', label: 'Sign-up', sub: 'Event' },
{ kind: 'wait', label: 'Wait 5 min', sub: 'Delay' },
{ kind: 'send', label: 'Welcome email', sub: '64% open' },
{ kind: 'wait', label: 'Wait 2 days', sub: 'Delay' },
{ kind: 'branch', label: 'Opened?', sub: 'Condition' },
{ kind: 'send', label: 'Curated escapes · WA', sub: '38% click' },
{ kind: 'end', label: 'Goal · inquiry', sub: 'Convert' },
].map((s, i, arr) => (
{s.sub}
{s.label}
{i < arr.length - 1 && }
))}
);
}
function OrchIntegrations() {
const items = [
{ name: 'Stripe', cat: 'Payments', status: 'connected', sub: 'acct_1O… · live key' },
{ name: 'WhatsApp Business', cat: 'Messaging', status: 'connected', sub: 'Cloud API · BSP Twilio' },
{ name: 'Postmark', cat: 'Email', status: 'connected', sub: 'Server · transactional' },
{ name: 'Klaviyo', cat: 'Marketing', status: 'connected', sub: 'List · 24.2k members' },
{ name: 'Meta', cat: 'Social', status: 'connected', sub: 'IG · FB · 4 ad accts' },
{ name: 'TikTok Business', cat: 'Social', status: 'connected', sub: 'Ads · org. posting' },
{ name: 'Pinterest', cat: 'Social', status: 'connected', sub: 'Catalog feed · daily' },
{ name: 'Algolia', cat: 'Search', status: 'connected', sub: 'Index · villas, escapes' },
{ name: 'Cloudflare', cat: 'CDN', status: 'connected', sub: 'R2 · imagery · 99.98%' },
{ name: 'GA4', cat: 'Analytics', status: 'connected', sub: 'Web + app stream' },
{ name: 'Looker Studio', cat: 'BI', status: 'available', sub: 'Connect to mirror data' },
{ name: 'Hubspot', cat: 'CRM', status: 'available', sub: 'Sales pipeline sync' },
];
return (
Integrations.
10 connected · 2 available
{items.map(it => (
{it.cat}
{it.status}
{it.name}
{it.sub}
))}
);
}
Object.assign(window, { AdminMarketingSales, AdminOrchestration });