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:
@@ -4,12 +4,19 @@ import Link from 'next/link';
|
||||
import { usePathname } from 'next/navigation';
|
||||
import { cn } from '../_lib/utils';
|
||||
import { Button } from '../_components/ui/button';
|
||||
import { ScopeCard } from '../_components/scope-card';
|
||||
import { PORTAL_THEMES } from '../_components/portal-theme';
|
||||
import {
|
||||
LayoutDashboard, Newspaper, Calendar, HeartHandshake, Users2,
|
||||
BookOpen, Sparkles, Images, Contact, Settings, LogOut,
|
||||
} from 'lucide-react';
|
||||
|
||||
interface MemberScope {
|
||||
member: { displayName: string | null };
|
||||
chapter: { id: string; slug: string; name: string };
|
||||
organization: { id: string; slug: string; name: string } | null;
|
||||
}
|
||||
|
||||
const NAV = [
|
||||
{ href: '/my', label: 'Dashboard', icon: <LayoutDashboard /> },
|
||||
{ href: '/my/digest', label: 'Digest', icon: <Newspaper /> },
|
||||
@@ -24,7 +31,7 @@ const NAV = [
|
||||
{ href: '/my/settings', label: 'Settings', icon: <Settings /> },
|
||||
];
|
||||
|
||||
export function MemberNav() {
|
||||
export function MemberNav({ scope }: { scope?: MemberScope | null }) {
|
||||
const pathname = usePathname();
|
||||
const t = PORTAL_THEMES.emerald;
|
||||
|
||||
@@ -45,6 +52,10 @@ export function MemberNav() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{scope && (
|
||||
<ScopeCard accent="text-emerald-600" organization={scope.organization} chapter={scope.chapter} />
|
||||
)}
|
||||
|
||||
<nav className="flex-1 overflow-y-auto p-3 space-y-1">
|
||||
{NAV.map((item) => {
|
||||
const isActive = item.href === '/my' ? pathname === '/my' : pathname.startsWith(item.href);
|
||||
|
||||
Reference in New Issue
Block a user