169 lines
7.3 KiB
TypeScript
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>
|
|
);
|
|
}
|