/* Willow Creek Portal — Admin & House Manager: approvals, houses, residents, payments, forms CMS, rates & site content. role="admin" (full) or "manager" (house manager — minimum admin access: no forms builder, no rates/site content). */ const { PIcon: AIcon, PSection: ASection, KindBadge: AKindBadge, makeReceiptNo: aMakeReceiptNo, ReceiptModal: AReceiptModal } = window.WCPortal; const { useState: adUseState } = React; function AdminPortal({ store, setStore, onLogout, role = "admin" }) { const [tab, setTab] = adUseState("approvals"); const isAdmin = role === "admin"; const navItems = [ ["approvals", "inbox", "Approvals"], ["houses", "home", "Houses & beds"], ["residents", "users", "Residents"], ["payments", "receipt-text", "Payments"], ...(isAdmin ? [ ["forms", "file-stack", "Forms builder"], ["cms", "panel-top", "Rates & site content"], ] : []), ]; const pending = store.applications.filter((a) => a.status === "pending").length; return (
{tab === "approvals" && } {tab === "houses" && } {tab === "residents" && } {tab === "payments" && } {tab === "forms" && isAdmin && } {tab === "cms" && isAdmin && }
); } /* ---------- Approvals ---------- */ function ApprovalsTab({ store, setStore }) { const { Card, Button, Badge } = window.WillowCreekDesignSystem_90378c; const published = store.forms.filter((f) => f.status === "published"); const act = (id, status) => setStore((s) => { const app = s.applications.find((a) => a.id === id); let residents = s.residents; if (status === "approved" && app && !s.residents.some((r) => r.name === app.name)) { residents = [...s.residents, { id: "r" + Date.now(), name: app.name, phone: app.phone || "—", house: "Awaiting bed", phase: 1, status: "Onboarding", balance: s.cms.weeklyRate }]; } return { ...s, residents, applications: s.applications.map((a) => a.id === id ? { ...a, status } : a) }; }); return ( <>

Applications & approvals

New intake applications from the website land here. Approving adds the person to Residents automatically.

{store.applications.map((a) => { const signedCount = (store.signedForms[a.name] || []).length; const allSigned = published.length > 0 && signedCount >= published.length; return ( {a.name.split(" ").map((w) => w[0]).join("")}
{a.name}
{a.situation} · Submitted {a.submitted}
{a.status === "approved" && ( {allSigned ? "All forms signed" : `${signedCount}/${published.length} forms signed`} )} {a.status === "pending" ? (
) : ( {a.status === "approved" ? "Approved · in Residents" : "Declined"} )}
);})}
); } /* ---------- Houses & beds ---------- */ function HousesTab({ store, setStore }) { const { Card, Button, Badge, Select, Input } = window.WillowCreekDesignSystem_90378c; const [assigning, setAssigning] = adUseState(null); // bed id const unhoused = store.residents.filter((r) => !store.houses.some((h) => h.beds.some((b) => b.resident === r.name))); const setManager = (houseId, manager) => setStore((s) => ({ ...s, houses: s.houses.map((h) => h.id === houseId ? { ...h, manager } : h) })); const addBed = (houseId) => setStore((s) => ({ ...s, houses: s.houses.map((h) => h.id === houseId ? { ...h, beds: [...h.beds, { id: "b" + Date.now(), label: `Bed ${h.beds.length + 1} (new)`, resident: null }] } : h) })); const assign = (bedId, name) => { setStore((s) => ({ ...s, houses: s.houses.map((h) => ({ ...h, beds: h.beds.map((b) => b.id === bedId ? { ...b, resident: name || null } : (name && b.resident === name ? { ...b, resident: null } : b)) })) })); setAssigning(null); }; return ( <>

Houses & bed allocation

Assign house managers, add beds, and allocate residents.

{store.houses.map((h) => { const open = h.beds.filter((b) => !b.resident).length; return (

{h.name}

{h.address}
0 ? "success" : "neutral"} dot>{open > 0 ? `${open} open` : "Full"}
assign(b.id, e.target.value)} defaultValue="" style={{ fontFamily: "var(--font-sans)", fontSize: 13, padding: "5px 8px", borderRadius: 6, border: "1px solid var(--border-default)" }}> {store.residents.map((r) => )} ) : b.resident ? ( ) : ( )}
))}
); })} {unhoused.length > 0 && (

Awaiting a bed: {unhoused.map((r) => r.name).join(", ")}

)} ); } /* ---------- Residents ---------- */ function ResidentsTab({ store, setStore }) { const { Card, Button, Badge, Input, Select } = window.WillowCreekDesignSystem_90378c; const [adding, setAdding] = adUseState(false); const [draft, setDraft] = adUseState({ name: "", phone: "", house: "Creekside House" }); const published = store.forms.filter((f) => f.status === "published"); const addResident = () => { if (!draft.name.trim()) return; setStore((s) => ({ ...s, residents: [...s.residents, { id: "r" + Date.now(), name: draft.name.trim(), phone: draft.phone, house: draft.house, phase: 1, status: "Active", balance: s.cms.weeklyRate }] })); setDraft({ name: "", phone: "", house: "Creekside House" }); setAdding(false); }; return ( <>

Residents

Phase, paperwork, and balance at a glance.

{adding && (
setDraft((d) => ({ ...d, name: e.target.value }))} placeholder="Jordan Rivera" /> setDraft((d) => ({ ...d, phone: e.target.value }))} placeholder="(940) 555-0100" /> setDraft((d) => ({ ...d, title: e.target.value }))} placeholder="e.g. Overnight Pass Request" />
setDraft((d) => ({ ...d, required: e.target.value === "req" }))} options={[{ value: "req", label: "Required for all residents" }, { value: "opt", label: "Optional" }]} />