// New Hub workflow — the empty state of a freshly created hub (see NEW-HUB.md).
// One loop: Start a Hub → Upload your content → Work with Claude on a Playbook → Go.
// Stage 1 builds the `template` picker; upload/review/playbook are stubs the later
// stages fill. Rendered by app_evergreen when the active hub is in onboarding.
//
// Proxa-branded surface (the platform doing the creating); the built hub carries the
// Cascade Ridge org identity.
// Templates, files and data products now come from the domain pack (domains.jsx)
// so the same flow serves a company or a lab. NH_GROUPS is the company set,
// kept as the default for callers that don't pass a domain.
const NH_GROUPS_FALLBACK = [
{ label: 'Org templates', items: [
{ id: 'finance', name: 'Finance', live: true,
desc: 'Statements, working capital, budget vs. actual, capacity and forecast — from your financial model.',
icon: '' },
{ id: 'contracts', name: 'Contracts', live: false,
desc: 'Customer agreements, renewals, obligations and pricing — from your MSAs and SOWs.',
icon: '' },
{ id: 'people', name: 'People', live: false,
desc: 'Headcount, org, compensation and safety — from your roster and payroll exports.',
icon: '' },
{ id: 'commercial', name: 'Commercial', live: false,
desc: 'A 360 per customer — contracts, pipeline, volume, revenue and margin, merged.',
icon: '' },
{ id: 'sales', name: 'Sales', live: false,
desc: 'Pipeline, bookings, win-rate and forecast across the commercial organization.',
icon: '' },
{ id: 'marketing', name: 'Marketing', live: false,
desc: 'Campaigns, spend, funnel and attribution across channels.',
icon: '' },
] },
{ label: 'Project templates', items: [
{ id: 'diligence', name: 'Diligence', live: true,
desc: 'Upload a DDQ — Claude turns every request into a tracked data product, answered from the model.',
icon: '' },
{ id: 'audit', name: 'Audit', live: false,
desc: 'A PBC list, encoded — requests, evidence and status against your model.',
icon: '' },
] },
];
// Resolve a domain key to its pack, falling back to the company set above if
// domains.jsx hasn't loaded (script order) or the key is unknown.
function nhPack(domain) {
const pack = window.proxaDomain ? window.proxaDomain(domain) : null;
return pack || { groups: NH_GROUPS_FALLBACK, orgName: 'Cascade Ridge' };
}
function NHTemplateCard({ t, onPick, onPropose }) {
// Live cards open the hub; non-live cards are inert unless onPropose is given
// (then a click asks the assistant to build that hub).
const clickable = t.live || !!onPropose;
return (
);
}
function NHTemplatePicker({ onPick, compact, domain }) {
return (
{!compact && (
New hub · Proxa
What should we build?
Pick a template, or tell Claude what you would like to model. Start with what you
have — a website, spreadsheet, report or docs — and it proposes the data structure
so we can iterate.
)}
{nhPack(domain).groups.map((g) => (
{g.label}
{g.items.map((t) => )}
))}
);
}
// ── The "What should we build?" create-from-scratch entry (the + button) ─────
// Prompt-first page: describe-box + Knowledge Base/Template chips + template
// grid + the Template→Hub→Context→Products→Report stepper. Picking a live
// template routes into the hub, landing on Model → Context (see pickTemplate).
function NHBuildStepper({ active }) {
const steps = ['Template', 'Hub', 'Context', 'Products', 'Report'];
return (
}
);
}
// Generic instructional empty state (dashed card) for the non-Dashboard tabs.
function NHEmptyState({ icon, title, body }) {
return (
{title}
{body}
);
}
// Dashboard empty state — describes what the hub will build, then hosts the upload,
// then the (stubbed) review/playbook steps as the hub fills in.
function NHDashboardOnboard({ flow, onAdvance, domain }) {
const pack = nhPack(domain);
const step = flow.step;
if (step === 'review' || step === 'playbook') {
return (
'
: ''}
title={step === 'review' ? 'Reading your files…' : 'Hub Playbook'}
body={step === 'review'
? 'Claude is reading your model and drafting the hub — the review sequence lands here next.'
: 'Confirm the context and choose which data products to build — the playbook lands here next.'} />
);
}
// 'upload' — the instructional Dashboard empty state
return (
{pack.onboard.title}
{pack.onboard.body}
{pack.products.map(([n, d]) =>
{n}
{d}
)}
);
}
// Onboarding panel content, rendered inside the real hub shell (HubHome) per active tile.
function NHOnboardPanel({ tileTab, flow, onAdvance, domain }) {
if (tileTab === 'dashboard') return ;
const states = {
control: {
icon: '',
title: 'Control',
body: 'Once your hub is built, a data-product agent maintains each product and surfaces source changes here for you to review and accept.',
},
library: {
icon: '',
title: 'Library',
body: 'The files you upload and the reports Proxa generates will be organized here — with lineage back to every data product.',
},
calendar: {
icon: '',
title: 'Calendar',
body: 'Your month-end close checklist and key financial dates will live here once the hub is set up.',
},
};
const s = states[tileTab] || states.control;
return ;
}
// The template picker is the only full-screen step; once a template is chosen the
// new hub renders through the real hub shell (HubHome) in onboarding mode.
function NewHubFlow({ flow, onPickTemplate, domain }) {
return (
);
}
window.NewHubFlow = NewHubFlow;
window.NHOnboardPanel = NHOnboardPanel;
window.NHTemplatePicker = NHTemplatePicker;