feat: show tenancy scope (Org → Chapter) in chapter & member portals

Surface where the logged-in user sits in the hierarchy via a ScopeCard
in the sidebar, below the brand mark.

API:
- Enrich chapter login/me responses with tenantName + organization
  (LoginResponse.admin, AdminProfile types updated)
- Add GET /my/scope returning member's chapter + organization

Web:
- ScopeCard component (Organisation row + Chapter row, themed icons)
- Chapter portal: scope from auth context, blue accent
- Member portal: scope fetched server-side in layout, emerald accent
- PortalShell gains a `scope` slot rendered under the brand

Org and admin portals intentionally omit it — org IS the scope, admin is
platform-wide.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-20 18:27:23 +05:30
parent 205418fc4e
commit a3798b3059
10 changed files with 131 additions and 8 deletions
+6 -1
View File
@@ -34,6 +34,8 @@ interface PortalShellProps {
theme: PortalTheme;
navItems: PortalNavItem[];
user?: PortalUser;
/** Optional scope indicator (e.g. <ScopeCard/>) rendered below the brand */
scope?: React.ReactNode;
loading: boolean;
authed: boolean;
onLogout: () => void;
@@ -41,7 +43,7 @@ interface PortalShellProps {
}
export function PortalShell({
portalName, theme, navItems, user, loading, authed, onLogout, children,
portalName, theme, navItems, user, scope, loading, authed, onLogout, children,
}: PortalShellProps) {
const pathname = usePathname();
const t = PORTAL_THEMES[theme];
@@ -61,6 +63,9 @@ export function PortalShell({
</div>
</div>
{/* Scope */}
{!loading && authed && scope}
{/* Nav */}
<nav className="flex-1 overflow-y-auto p-3 space-y-1">
{loading ? (