MotorSignal-App/website/components/founder-portal/club-masthead.tsx

169 lines
7.3 KiB
TypeScript

'use client';
import React from 'react';
import { Club, UserPortalPermissions } from './types';
interface ClubMastheadProps {
club: Club;
permissions: UserPortalPermissions;
onPlanRide?: () => void;
onInviteMember?: () => void;
onOpenSettings?: () => void;
}
export function ClubMasthead({
club,
permissions,
onPlanRide,
onInviteMember,
onOpenSettings,
}: ClubMastheadProps) {
// Deterministic 2-4 character monogram
const monogram = club.name
.split(/\s+/)
.filter(Boolean)
.map((w) => w[0].toUpperCase())
.slice(0, 3)
.join('') || 'MS';
const visibilityLabel = club.visibility === 'public' ? 'Public' : 'Private';
const admissionLabel =
club.admissionPolicy === 'inviteOnly'
? 'Invite Only'
: club.admissionPolicy === 'open'
? 'Open to Join'
: 'Request to Join';
return (
<section className="relative rounded-2xl glass-card border border-brand-border/60 p-6 sm:p-7 shadow-xl overflow-hidden">
<div className="absolute top-0 left-0 right-0 h-1 bg-gradient-to-r from-brand-cyan/80 via-blue-500/40 to-transparent"></div>
<div className="flex flex-col lg:flex-row lg:items-center lg:justify-between gap-6">
{/* Left: Identity & Monogram */}
<div className="flex flex-col sm:flex-row sm:items-center gap-5 min-w-0">
{/* Precision Hex Monogram Emblem */}
<div className="relative w-16 h-16 sm:w-20 sm:h-20 shrink-0 flex items-center justify-center rounded-2xl bg-gradient-to-br from-brand-borderLight to-slate-900 border border-brand-cyan/40 shadow-[0_0_20px_rgba(0,242,254,0.25)]">
<svg
className="w-12 h-12 sm:w-14 sm:h-14 text-brand-cyan"
fill="none"
stroke="currentColor"
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2"
viewBox="0 0 48 48"
>
<polygon
points="24 4, 43 14, 43 34, 24 44, 5 34, 5 14"
stroke="currentColor"
strokeWidth="1.8"
/>
</svg>
<span className="absolute font-headline font-extrabold text-xs sm:text-sm tracking-wider text-white">
{monogram}
</span>
</div>
{/* Titles and Club Attributes */}
<div className="flex flex-col min-w-0">
<div className="flex flex-wrap items-center gap-2 mb-1">
<h1 className="font-headline text-2xl sm:text-3xl font-extrabold text-white tracking-tight truncate">
{club.name}
</h1>
<span className="px-2.5 py-0.5 rounded-full bg-surface-container border border-brand-border/60 text-slate-300 font-mono text-[11px] font-medium tracking-wider">
{visibilityLabel}
</span>
<span className="px-2.5 py-0.5 rounded-full bg-brand-cyan/10 border border-brand-cyan/30 text-brand-cyan font-mono text-[11px] font-semibold tracking-wider">
{admissionLabel}
</span>
</div>
<div className="flex flex-wrap items-center gap-x-2.5 gap-y-1 font-mono text-xs text-slate-400">
<span className="text-white font-medium">@{club.slug}</span>
{club.homeRegion && (
<>
<span className="text-outline-variant">•</span>
<span>{club.homeRegion}</span>
</>
)}
{club.foundedYear && (
<>
<span className="text-outline-variant">•</span>
<span>Founded {club.foundedYear}</span>
</>
)}
{club.motorcycleFocus && (
<>
<span className="text-outline-variant">•</span>
<span>{club.motorcycleFocus}</span>
</>
)}
</div>
{/* Founder Attribution Sub-strip */}
<div className="mt-2.5 flex flex-wrap items-center gap-x-3 gap-y-1 text-xs text-slate-400 font-body">
<div className="flex items-center gap-1.5">
<span className="text-slate-500">Founder:</span>
<span className="text-slate-200 font-medium">
{club.founderName ?? 'Club Founder'}
</span>
{club.founderHandle && (
<span className="font-mono text-[11px] text-brand-cyan">
({club.founderHandle})
</span>
)}
</div>
<span className="text-outline-variant">•</span>
<div className="flex items-center gap-1.5">
<span className="text-slate-500">Club Rank:</span>
<span className="px-2 py-0.5 rounded-full bg-surface-container-high text-slate-200 font-mono text-[11px] font-medium border border-outline-variant/60">
{club.founderRank ?? 'President'}
</span>
</div>
<span className="text-outline-variant">•</span>
<div className="flex items-center gap-1.5">
<span className="text-slate-500">Administrative Role:</span>
<span className="px-2 py-0.5 rounded-full bg-primary-container/15 text-primary-container font-mono text-[11px] font-semibold border border-primary-container/30">
{permissions.role.charAt(0).toUpperCase() + permissions.role.slice(1)}
</span>
</div>
</div>
</div>
</div>
{/* Right: Founder Actions (Role-gated) */}
<div className="flex flex-wrap sm:flex-nowrap items-center gap-2.5 shrink-0">
{permissions.canPlanRides && (
<button
onClick={onPlanRide}
className="h-10 px-4 rounded-xl bg-primary-container text-on-primary-container font-body text-xs sm:text-sm font-bold hover:brightness-110 shadow-[0_0_16px_rgba(0,242,254,0.3)] transition-all flex items-center gap-2 cursor-pointer"
>
<span className="material-symbols-outlined text-[18px]">add_road</span>
<span>Plan Club Ride</span>
</button>
)}
{permissions.canInviteMembers && (
<button
onClick={onInviteMember}
className="h-10 px-4 rounded-xl bg-surface-container border border-outline-variant/60 text-slate-200 hover:text-white hover:bg-surface-container-high hover:border-brand-cyan/40 transition-all font-body text-xs sm:text-sm font-medium flex items-center gap-2 cursor-pointer"
>
<span className="material-symbols-outlined text-[18px]">person_add</span>
<span>Invite Member</span>
</button>
)}
{permissions.canManageSettings && (
<button
onClick={onOpenSettings}
aria-label="Club Settings"
title="Club Settings"
className="h-10 w-10 rounded-xl bg-surface-container border border-outline-variant/60 text-slate-400 hover:text-white hover:bg-surface-container-high hover:border-brand-cyan/40 transition-all flex items-center justify-center cursor-pointer"
>
<span className="material-symbols-outlined text-[20px]">tune</span>
</button>
)}
</div>
</div>
</section>
);
}