MotorSignal-App/website/components/founder-portal/founder-top-bar.tsx

173 lines
7.3 KiB
TypeScript

'use client';
import React from 'react';
import Link from 'next/link';
import { Club, UserPortalPermissions, ClubRole } from './types';
interface FounderTopBarProps {
club: Club;
permissions: UserPortalPermissions;
activeNav?: string;
onToggleMobileSidebar?: () => void;
onPlanRide?: () => void;
onPostAnnouncement?: () => void;
onSwitchRole?: (role: ClubRole) => void;
onSwitchClub?: () => void;
}
export function FounderTopBar({
club,
permissions,
activeNav,
onToggleMobileSidebar,
onPlanRide,
onPostAnnouncement,
onSwitchRole,
onSwitchClub,
}: FounderTopBarProps) {
return (
<header className="fixed top-0 left-0 lg:left-72 right-0 h-16 bg-surface-container-lowest/95 backdrop-blur-md border-b border-outline-variant z-40 px-4 sm:px-6 flex items-center justify-between gap-4">
{/* Left: Mobile hamburger + Breadcrumbs + Switch Club */}
<div className="flex items-center gap-3 sm:gap-4 min-w-0">
{/* Mobile Hamburger Toggle */}
<button
onClick={onToggleMobileSidebar}
className="lg:hidden text-outline hover:text-on-surface p-1 rounded hover:bg-surface-container transition-colors"
aria-label="Open sidebar"
>
<span className="material-symbols-outlined text-[22px]">menu</span>
</button>
<div className="flex items-center gap-2 font-mono text-xs text-outline shrink-0">
<Link href="/clubs" className="hover:text-on-surface transition-colors">
CLUBS
</Link>
<span>/</span>
<Link
href={`/clubs/${club.slug || club.id}/manage`}
className="text-on-surface font-semibold truncate max-w-[120px] sm:max-w-[200px] md:max-w-none uppercase hover:text-primary transition-colors"
>
{club.name}
</Link>
{activeNav === 'profile' && (
<>
<span className="text-outline-variant">/</span>
<span className="text-secondary font-semibold uppercase">CLUB PROFILE</span>
</>
)}
{activeNav === 'settings' && (
<>
<span className="text-outline-variant">/</span>
<span className="text-secondary font-semibold uppercase">SETTINGS</span>
</>
)}
</div>
<div className="relative flex items-center shrink-0">
<button
onClick={onSwitchClub}
className="flex items-center gap-1.5 px-2.5 py-1 rounded bg-surface-container border border-outline-variant text-on-surface font-body text-xs hover:bg-surface-container-high transition-colors"
>
<span className="material-symbols-outlined text-[15px] text-secondary">swap_horiz</span>
<span className="hidden sm:inline">Switch Club</span>
<span className="material-symbols-outlined text-[15px] text-outline">expand_more</span>
</button>
</div>
</div>
{/* Middle: Search Input (desktop/tablet only) */}
<div className="flex-1 max-w-md mx-4 hidden md:block">
<div className="relative">
<span className="material-symbols-outlined absolute left-3 top-1/2 -translate-y-1/2 text-outline text-[17px]">
search
</span>
<input
className="w-full h-8 pl-9 pr-3 rounded bg-surface-container-low border border-outline-variant text-on-surface placeholder:text-outline/70 font-body text-xs focus:outline-none focus:border-primary transition-colors"
placeholder="Search members, rides, routes..."
type="text"
aria-label="Search members, rides, routes"
/>
</div>
</div>
{/* Right: Actions + Role Switcher preview pill + Notifications + Profile */}
<div className="flex items-center gap-2 sm:gap-2.5 shrink-0">
{/* Authoritative Role Badge (Production) vs Interactive Role Switcher (Development Only) */}
{process.env.NODE_ENV === 'development' ? (
<div
className="hidden xl:flex items-center gap-1 px-2 py-0.5 rounded bg-surface-container-high border border-outline-variant text-[11px] font-mono text-outline"
title="Interactive role preview for testing software permissions (Development Only)"
>
<span className="text-outline-variant">DEV PREVIEW:</span>
{(['owner', 'admin', 'member'] as const).map((r) => (
<button
key={r}
onClick={() => onSwitchRole?.(r)}
className={`px-1.5 py-0.5 rounded uppercase font-semibold transition-colors ${
permissions.role === r
? 'bg-primary text-white'
: 'hover:text-on-surface'
}`}
>
{r}
</button>
))}
</div>
) : (
<div
className="hidden sm:flex items-center gap-1.5 px-2.5 py-1 rounded bg-surface-container border border-outline-variant text-[11px] font-mono text-outline uppercase font-medium"
title="Authoritative software role"
>
<span className="w-1.5 h-1.5 rounded-full bg-secondary" />
<span className="text-on-surface font-semibold">{permissions.role}</span>
</div>
)}
{/* Post Announcement (Owner / Admin only) */}
{permissions.canManageSettings && (
<button
onClick={onPostAnnouncement}
className="hidden sm:flex items-center gap-1.5 px-3 py-1.5 rounded bg-surface-container border border-outline-variant text-on-surface font-body text-xs font-medium hover:bg-surface-container-high transition-colors"
>
<span className="material-symbols-outlined text-[15px] text-secondary">campaign</span>
<span>Post Announcement</span>
</button>
)}
{/* Plan Club Ride (Owner / Admin only) */}
{permissions.canPlanRides && (
<button
onClick={onPlanRide}
className="flex items-center gap-1.5 px-3 py-1.5 rounded bg-primary text-white font-body text-xs font-semibold hover:bg-primary-container transition-colors shadow-sm"
>
<span className="material-symbols-outlined text-[15px]">add_road</span>
<span className="hidden sm:inline">Plan Club Ride</span>
</button>
)}
{/* Notifications */}
<div className="relative ml-1">
<button
className="w-8 h-8 rounded bg-surface-container border border-outline-variant flex items-center justify-center text-outline hover:text-on-surface transition-colors"
title="Notifications"
aria-label="Notifications"
>
<span className="material-symbols-outlined text-[18px]">notifications</span>
</button>
<span className="absolute top-1 right-1 w-2 h-2 rounded-full bg-error" />
</div>
{/* Account Avatar */}
<Link
href="/account"
className="w-7 h-7 rounded bg-primary flex items-center justify-center ml-0.5 hover:ring-2 hover:ring-primary-container transition-all"
title="Account profile"
aria-label="Account profile"
>
<span className="material-symbols-outlined text-white text-[16px]">person</span>
</Link>
</div>
</header>
);
}