112 lines
4.0 KiB
TypeScript
112 lines
4.0 KiB
TypeScript
// Hubs index — operational landing for each department.
|
|
// Each hub is a curated lens onto the same EA2 scenarios with a chat shortcut.
|
|
|
|
import { useApp } from "../state/store";
|
|
import { Bot, Arrow, Layers, User, Cog, Inbox } from "../components/icons";
|
|
|
|
interface Hub {
|
|
id: "hr" | "it" | "finance" | "procurement";
|
|
label: string;
|
|
blurb: string;
|
|
scenarioPrefixes: string[];
|
|
highlights: string[];
|
|
}
|
|
|
|
const HUBS: Hub[] = [
|
|
{
|
|
id: "hr",
|
|
label: "People (HR)",
|
|
blurb: "Hiring, onboarding, leave, performance, attendance.",
|
|
scenarioPrefixes: ["hcm"],
|
|
highlights: ["New-hire onboarding", "Leave request approval", "Geo-attendance check-in"],
|
|
},
|
|
{
|
|
id: "finance",
|
|
label: "Finance",
|
|
blurb: "AR, AP, period close, refunds, supplier queries.",
|
|
scenarioPrefixes: ["ar", "gl"],
|
|
highlights: ["Customer refund approval", "Period-end close", "AP invoice triage"],
|
|
},
|
|
{
|
|
id: "procurement",
|
|
label: "Procurement",
|
|
blurb: "Purchase requisitions, vendor approval, three-way match.",
|
|
scenarioPrefixes: ["procurement", "extra"],
|
|
highlights: ["PR → PO approval", "Vendor onboarding", "Match invoice to PO"],
|
|
},
|
|
{
|
|
id: "it",
|
|
label: "IT",
|
|
blurb: "Asset procurement, access requests, incidents, service ops.",
|
|
scenarioPrefixes: ["service", "procurement"],
|
|
highlights: ["Laptop procurement (employee → manager → IT)", "Access request", "Customer incident triage"],
|
|
},
|
|
];
|
|
|
|
export default function Hubs() {
|
|
const setScene = useApp((s) => s.setScene);
|
|
const setScenarioId = useApp((s) => s.setScenarioId);
|
|
const scenarios = useApp((s) => s.scenarios);
|
|
const setHub = useApp((s) => s.setHub);
|
|
|
|
return (
|
|
<div className="hubs-page">
|
|
<header className="hubs-head">
|
|
<div>
|
|
<div className="mc-hero-eyebrow"><Layers size={12} /> Hubs</div>
|
|
<h2 className="mc-hero-title">Pick your hub</h2>
|
|
<p className="hubs-sub">Hubs are department-shaped lenses on the same EA2 process catalog. Pick a hub to focus the queue, agents, and processes for that team.</p>
|
|
</div>
|
|
<button className="btn btn-ghost" onClick={() => setScene("agent")}>
|
|
<Bot size={13} /> Ask the agent
|
|
</button>
|
|
</header>
|
|
|
|
<div className="hubs-grid">
|
|
{HUBS.map((h) => {
|
|
const matches = scenarios.filter((s) => h.scenarioPrefixes.some((p) => s.id.startsWith(p)));
|
|
return (
|
|
<article key={h.id} className="hub-card">
|
|
<header className="hub-card-h">
|
|
<div className={`hub-card-mark hub-${h.id}`} />
|
|
<div>
|
|
<h3 className="hub-card-title">{h.label}</h3>
|
|
<p className="hub-card-blurb">{h.blurb}</p>
|
|
</div>
|
|
</header>
|
|
<ul className="hub-card-list">
|
|
{h.highlights.map((hi) => (
|
|
<li key={hi}>{hi}</li>
|
|
))}
|
|
</ul>
|
|
<footer className="hub-card-foot">
|
|
<span className="hub-card-meta">
|
|
<Inbox size={11} /> {matches.length} process{matches.length === 1 ? "" : "es"}
|
|
</span>
|
|
<button
|
|
className="btn btn-primary btn-sm"
|
|
onClick={() => {
|
|
setHub(h.id);
|
|
if (matches[0]) setScenarioId(matches[0].id);
|
|
setScene("mission");
|
|
}}
|
|
>
|
|
Enter <Arrow size={11} />
|
|
</button>
|
|
</footer>
|
|
</article>
|
|
);
|
|
})}
|
|
</div>
|
|
|
|
<section className="hubs-pers">
|
|
<h3 className="panel-h"><User size={12} /> View-as personas</h3>
|
|
<p className="hubs-sub">Switch persona from the Agent panel to see Mission Control from a department head's seat.</p>
|
|
<button className="btn btn-ghost" onClick={() => setScene("agent")}>
|
|
<Cog size={12} /> Open agent + persona switcher
|
|
</button>
|
|
</section>
|
|
</div>
|
|
);
|
|
}
|