'use client'; import React, { useState } from 'react'; import { ClubMember, ClubRankDefinition } from './types'; interface ClubHierarchyBuilderProps { clubId: string; ranks: ClubRankDefinition[]; members: ClubMember[]; selectedRankId: string | null; onSelectRank: (rankId: string) => void; onUpdateMemberRank: (memberUid: string, newRank: string) => Promise; canManageRanks: boolean; } export function ClubHierarchyBuilder({ ranks, members, selectedRankId, onSelectRank, onUpdateMemberRank, canManageRanks, }: ClubHierarchyBuilderProps) { const [assignModalRank, setAssignModalRank] = useState(null); const [selectedMemberUid, setSelectedMemberUid] = useState(''); const [isSubmitting, setIsSubmitting] = useState(false); const [actionMessage, setActionMessage] = useState<{ text: string; type: 'success' | 'error' } | null>(null); // Group ranks into organizational tiers const tier1 = ranks.filter((r) => r.level === 1); const tier2 = ranks.filter((r) => r.level === 2); const tier3 = ranks.filter((r) => r.level === 3 || r.level === 4); const tier4 = ranks.filter((r) => r.level >= 5); const getRidersForRank = (rankTitle: string) => { return members.filter((m) => { const currentRank = m.displayRank?.toLowerCase().trim(); const targetRank = rankTitle.toLowerCase().trim(); if (targetRank === 'president' && (m.role === 'owner' || currentRank === 'president' || currentRank === 'founder')) { return true; } return currentRank === targetRank; }); }; async function handleAssignMember() { if (!assignModalRank || !selectedMemberUid) return; setIsSubmitting(true); setActionMessage(null); try { await onUpdateMemberRank(selectedMemberUid, assignModalRank.title); setActionMessage({ text: `Assigned ${assignModalRank.title} rank successfully.`, type: 'success' }); setSelectedMemberUid(''); setTimeout(() => { setAssignModalRank(null); setActionMessage(null); }, 1200); } catch { setActionMessage({ text: 'Failed to update member rank. Try again.', type: 'error' }); } finally { setIsSubmitting(false); } } const renderRankNode = (rank: ClubRankDefinition) => { const isSelected = selectedRankId === rank.id; const assignedRiders = getRidersForRank(rank.title); return (
onSelectRank(rank.id)} className={`group relative cursor-pointer rounded-xl p-4 transition-all duration-200 border ${ isSelected ? 'bg-surface-container-high/90 border-brand-cyan shadow-[0_0_15px_rgba(0,242,254,0.2)] ring-1 ring-brand-cyan/50' : 'bg-surface-container/70 border-brand-border/60 hover:border-brand-border hover:bg-surface-container-high/60' }`} > {/* Header */}
{rank.icon}
{rank.title} Level {rank.level}
{rank.category} • Default: {rank.defaultRole}
{assignedRiders.length} {assignedRiders.length === 1 ? 'rider' : 'riders'}
{/* Description */}

{rank.description}

{/* Assigned Riders Preview */} {assignedRiders.length > 0 ? (
{assignedRiders.slice(0, 3).map((rider) => ( {rider.displayName || rider.handle || rider.uid.slice(0, 6)} ))} {assignedRiders.length > 3 && ( +{assignedRiders.length - 3} more )}
) : (
No active riders currently assigned
)} {/* Quick Assign Button */} {canManageRanks && (
)}
); }; return (
account_tree

Club Hierarchy Builder

Visual organizational structure. Select any squad rank to view operational privileges or reassign riders.

{ranks.length} RANKS {members.length} MEMBERS
{/* Visual Hierarchy Tree Canvas */}
{/* Tier 1: Executive Command */}
Tier 1 • Executive Command
{tier1.map(renderRankNode)}
{/* Tier 2: Field Leadership & Governance */}
Tier 2 • Leadership & Administration
{tier2.map(renderRankNode)}
{/* Tier 3: Tactical Operations */}
Tier 3 • Tactical Operations & Pack Safety
{tier3.map(renderRankNode)}
{/* Tier 4: Squad Formation */}
Tier 4 • Squad Formation & Prospects
{tier4.map(renderRankNode)}
{/* Assign Member Modal */} {assignModalRank && (

Assign to {assignModalRank.title}

Select an active member to grant this honorary squad rank.

Rank Notice: Setting this rank updates the member's title displayed on the mobile app, Club Wall, and group rides.
{actionMessage && (
{actionMessage.text}
)}
)}
); }