/* ====================================================================== KOREALM — App shell: top bar, role switcher, sidebar, router Role modules register into window.KOREALM.roles[role] = { nav, Screen } ====================================================================== */ window.KOREALM = window.KOREALM || { roles: {} }; /* Randomized display name for the account menu (regenerated each load) */ const DISPLAY_NAME = (() => { const first = ["Maya", "Leo", "Nadia", "Owen", "Priya", "Theo", "Zara", "Felix", "Imani", "Rohan"]; const last = ["Carter", "Nguyen", "Okafor", "Silva", "Hansen", "Moreau", "Patel", "Kowalski", "Reyes", "Doyle"]; return first[Math.floor(Math.random() * first.length)] + " " + last[Math.floor(Math.random() * last.length)]; })(); /* ---------------- Brand mark ---------------- */ function Logo({ size = 30, variant = "compact", onDark = false }) { const isFull = variant === "full"; const src = isFull ? "logo-full.png" : "logo-compact.png"; const h = isFull ? 130 : 42; const plate = onDark ? { background: "#ffffff", padding: isFull ? "20px 26px" : "12px 16px", borderRadius: 18, boxShadow: "0 16px 40px rgba(8,18,33,0.34)" } : { background: "#ffffff", padding: "7px 13px", borderRadius: 12, border: "1px solid var(--line-2)", boxShadow: "var(--sh-1)" }; return (
Korealm — Property Management
); } /* ---------------- Role switcher ---------------- */ const ROLE_META = { public: { label: "Public", icon: "search", path: "/", desc: "Marketing site & listings" }, tenant: { label: "Tenant", icon: "user", path: "/tenant", desc: "Renter workspace" }, landlord: { label: "Landlord", icon: "building", path: "/landlord", desc: "Owner workspace" }, admin: { label: "Admin", icon: "shield", path: "/admin", desc: "Operations console" }, }; /* ---------------- Route Dashboard (persona router) ---------------- */ function RouteSwitcher() { const app = useApp(); const { session, setRole, db, me } = app; const [open, setOpen] = useState(false); const ref = useRef(); useEffect(() => { const h = (e) => { if (ref.current && !ref.current.contains(e.target)) setOpen(false); }; document.addEventListener("mousedown", h); return () => document.removeEventListener("mousedown", h); }, []); const cur = ROLE_META[session.role]; const subRoutes = (r) => { if (r === "public") return 0; try { const cfg = window.KOREALM.roles[r]; return cfg ? cfg.nav(db, me(r), app).length : 0; } catch (e) { return 0; } }; return (
{open && (
Route Dashboard Switch the active persona route
{Object.keys(ROLE_META).map(r => { const m = ROLE_META[r]; const active = session.role === r; const n = subRoutes(r); return ( ); })}
Each persona is served as an isolated route.
)}
); } /* ---------------- Route counting helper ---------------- */ function countRoutes(r, app) { if (r === "public") return 0; try { const cfg = window.KOREALM.roles[r]; return cfg ? cfg.nav(app.db, app.me(r), app).length : 0; } catch (e) { return 0; } } /* ---------------- Route Map landing (POC launcher) ---------------- */ function RouteLanding() { const app = useApp(); const { setRole } = app; const order = ["public", "tenant", "landlord", "admin"]; const total = order.reduce((s, r) => s + countRoutes(r, app), 0); return (
POC · Route map

Where would you like to start?

Korealm serves each persona as an isolated route off a single origin. Choose a route to enter that workspace — you can switch anytime from the top bar.

korealm.app production origin · {total} routes
online
{order.map(r => { const m = ROLE_META[r]; const n = countRoutes(r, app); return ( ); })}
Sandbox build · payments use a test gateway, no real charges occur.
); } /* ---------------- Account menu ---------------- */ function AccountMenu() { const { session, db, me, actions, go, setRole } = useApp(); const [open, setOpen] = useState(false); const ref = useRef(); useEffect(() => { const h = (e) => { if (ref.current && !ref.current.contains(e.target)) setOpen(false); }; document.addEventListener("mousedown", h); return () => document.removeEventListener("mousedown", h); }, []); const u = session.role === "public" ? null : me(session.role); const displayName = u && u.registered ? u.name : DISPLAY_NAME; return (
{u ? ( ) : (
)} {open && u && (
{displayName} {u.email}
{ setOpen(false); }}>Profile & settings
{ setOpen(false); }}>Notifications
{ setOpen(false); setRole("public"); }}>Sign out
)}
); } /* ---------------- Top bar ---------------- */ function TopBar() { const { session, setRole } = useApp(); const launch = session.role === "launch"; return (
setRole("launch")}>
POC
{!launch && } {!launch && (
{session.role !== "public" && }
)}
); } /* ---------------- Page header ---------------- */ function PageHeader({ title, sub, actions, back, children }) { return (
{back && }

{title}

{sub &&

{sub}

}
{actions &&
{actions}
}
{children}
); } /* ---------------- Sidebar (dashboard roles) ---------------- */ function Sidebar({ role }) { const app = useApp(); const { session, go, db, me } = app; const cfg = window.KOREALM.roles[role]; const items = cfg.nav(db, me(role), app); return ( ); } /* ---------------- App body / router ---------------- */ function AppBody() { const app = useApp(); const { session } = app; const role = session.role; if (role === "launch") { return ; } if (role === "public") { return ; } const cfg = window.KOREALM.roles[role]; const Screen = cfg.Screen; return (
); } function Shell() { return ( ); } Object.assign(window, { Logo, PageHeader, Shell, ROLE_META });