/* Host CRM — Lists, Analysis (Medium) · Marketing/Events/Volunteers/Memberships (Stub) · Settings (Stub, with the link into the 95 Forward settings page). */ function HostLists() { const D = window.POC_DATA; const { Icon, HostCard, HostBtn } = window.POC; const [cat, setCat] = React.useState("Constituents"); const CATS = ["Actions", "Constituents", "Gifts", "Opportunities"]; return (
{/* Category rail + filter builder */}
{CATS.map(c => ( ))}
Filter builder
{["Lifetime giving ≥ $50,000", "Status is Prospect", "Region is Riverside"].map((f, i) => (
{i > 0 ?
AND
: null}
{f}
))} Add condition
{/* Built list */}
Major prospects · {cat}
Representative built list Columns
{D.constituents.filter(c => c.prospect).map(c => ( ))}
NameFirst giftGreatest giftLifetimeStatus
{c.name} $5,000 {c.lastGift.split(" · ")[0]} {c.lifetime} {c.status}
); } function HostAnalysis() { const { Icon, HostCard } = window.POC; const reports = [ { name: "Fundraising performance", icon: "bar-chart-3" }, { name: "Donor retention", icon: "repeat" }, { name: "Campaign progress", icon: "target" }, { name: "Appeal analysis", icon: "mail" }, ]; return (
{reports.map((r, i) => ( {r.name} ))}
Fundraising performance · FY24
{[42, 58, 50, 71, 64, 80, 76, 92, 70, 88, 95, 84].map((v, i) => (
))}
{["Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "Jan", "Feb", "Mar", "Apr", "May", "Jun"].map(m => {m})}
{[["Total raised", "$1.28M"], ["vs. goal", "94%"], ["New donors", "312"], ["Avg gift", "$3,118"]].map(([k, v], i) => (
{k} {v}
))}
); } /* ---- Stubs ---- */ function HostStub({ route }) { const { HostCard, StubPage } = window.POC; const CFG = { marketing: { icon: "megaphone", lead: "Email campaigns, appeals, and audience segments — your outbound program lives here.", cols: ["Appeal", "Channel", "Sent", "Open rate", "Gifts"], rows: [["Spring mail 2024", "Direct mail", "8,400", "—", "212"], ["FY24 sustainer", "Email", "12,100", "38%", "96"], ["Year-end push", "Email", "11,800", "41%", "184"], ["Match drive", "Email", "6,200", "44%", "73"]] }, events: { icon: "calendar", lead: "Galas, tours, and cultivation events — registration, attendance, and follow-up.", cols: ["Event", "Date", "Registered", "Attended", "Raised"], rows: [["Youth Center tour", "Jul 18", "24", "—", "—"], ["Annual gala", "Oct 5", "310", "—", "—"], ["Donor breakfast", "May 9", "62", "58", "$48,000"], ["Volunteer thank-you", "Apr 2", "120", "104", "—"]] }, volunteers: { icon: "heart-handshake", lead: "Your volunteer roster — hours, roles, and the donors among them.", cols: ["Name", "Role", "Hours YTD", "Since", "Also a donor"], rows: [["Theodore Brennan", "Mentor", "84", "2021", "Yes"], ["Helen Vasquez", "Event lead", "42", "2022", "Yes"], ["Marcus Webb", "Board liaison", "30", "2019", "—"], ["Sofia Lin", "Tutor", "112", "2020", "Yes"]] }, memberships: { icon: "id-card", lead: "Membership tiers and renewals — the recurring base under the major-gifts program.", cols: ["Tier", "Members", "Annual", "Renewal rate", "Revenue"], rows: [["Friend", "640", "$50", "71%", "$32,000"], ["Advocate", "210", "$150", "78%", "$31,500"], ["Champion", "88", "$500", "84%", "$44,000"], ["Founder's Circle", "24", "$2,500", "92%", "$60,000"]] }, }; const c = CFG[route] || CFG.marketing; return ( {c.cols.map((h, i) => )} {c.rows.map((r, i) => ( {r.map((cell, j) => )} ))}
= 2 ? { textAlign: "right" } : null}>{h}
= 2 ? "ks-num" : ""} style={{ textAlign: j >= 2 ? "right" : "left", fontWeight: j === 0 ? 600 : 400, color: j === 0 ? "var(--host-ink-strong, #2A3640)" : "var(--host-muted, #71808B)" }}>{cell}
); } /* ---- Host Settings (stub) + link into 95 Forward settings ---- */ function HostSettings({ go }) { const { Icon, HostCard } = window.POC; const groups = [ { label: "Users & roles", icon: "users", note: "12 users · 3 roles" }, { label: "Campaigns", icon: "target", note: "FY24 Annual, Capital" }, { label: "Funds", icon: "wallet", note: "8 funds" }, { label: "Appeals", icon: "mail", note: "14 appeals" }, { label: "Integrations", icon: "plug", note: "Email, payments" }, { label: "Data & privacy", icon: "shield", note: "Retention, exports" }, ]; return (
{/* The one settings page that matters — 95 Forward */}
go("settings95")} style={{ display: "flex", alignItems: "center", gap: 16, padding: 20, cursor: "pointer", borderRadius: "var(--radius-lg)", border: "1px solid var(--blue-100)", background: "linear-gradient(160deg, var(--blue-50), var(--white))", }}>
95 Forward settings
Tune the QPI weights and copilot behavior — the score is yours to configure.
Keystone configuration
{groups.map((g, i) => (
{g.label}
{g.note}
))}
); } window.POC = Object.assign(window.POC || {}, { HostLists, HostAnalysis, HostStub, HostSettings });