import React, { useState, useEffect, useMemo, useCallback } from 'react'; import api from '../../utils/api'; import Navbar from '../../components/Navbar'; import MemberFooter from '../../components/MemberFooter'; import { Card } from '../../components/ui/card'; import { Input } from '../../components/ui/input'; import { Badge } from '../../components/ui/badge'; import { Button } from '../../components/ui/button'; import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, } from '../../components/ui/dialog'; import { User, Search, Mail, MapPin, Phone, Heart, Facebook, Instagram, Twitter, Linkedin, UserCircle, Calendar } from 'lucide-react'; import { useToast } from '../../hooks/use-toast'; import MemberCard from '../../components/MemberCard'; import MemberBadge from '../../components/MemberBadge'; import useMembers from '../../hooks/use-members'; import useMemberTiers from '../../hooks/use-member-tiers'; const MembersDirectory = () => { const [selectedMember, setSelectedMember] = useState(null); const [profileDialogOpen, setProfileDialogOpen] = useState(false); const { toast } = useToast(); const [currentPage, setCurrentPage] = useState(1); const pageSize = 12; const { tiers } = useMemberTiers(); const allowedRoles = useMemo(() => [], []); const normalizeStatus = useCallback((status) => { if (typeof status === 'string') { return status.toLowerCase(); } return status; }, []); const normalizeMembers = useCallback( (data) => { const list = Array.isArray(data) ? data : data?.members || data?.results || data?.items || data?.data || []; return list.map((member) => ({ ...member, status: normalizeStatus(member.status ?? member.membership_status ?? member.member_status), })); }, [normalizeStatus] ); const searchAccessor = useCallback( (member) => [ `${member.first_name} ${member.last_name}`, member.directory_bio || '' ], [] ); const handleFetchError = useCallback(() => { toast({ title: "Error", description: "Failed to load members directory. Please try again.", variant: "destructive" }); }, [toast]); const { users: members, filteredUsers: filteredMembers, loading, searchQuery, setSearchQuery, filterValue, } = useMembers({ endpoint: '/members/directory', initialFilter: 'all', filterKey: 'status', allowedRoles, searchAccessor, transform: normalizeMembers, fetchErrorMessage: 'Failed to load members directory. Please try again.', onFetchError: handleFetchError }); useEffect(() => { setCurrentPage(1); }, [searchQuery, members]); const totalPages = Math.max(1, Math.ceil(filteredMembers.length / pageSize)); const pageStart = (currentPage - 1) * pageSize; const paginatedMembers = filteredMembers.slice(pageStart, pageStart + pageSize); const totalMembers = useMemo(() => { if (!filterValue || filterValue === 'all') { return members.length; } return members.filter((member) => member.status === filterValue).length; }, [members, filterValue]); const getSocialMediaLink = (url) => { if (!url) return null; // Ensure URL has protocol if (!url.startsWith('http://') && !url.startsWith('https://')) { return `https://${url}`; } return url; }; const handleViewProfile = async (memberId) => { try { const response = await api.get(`/members/directory/${memberId}`); setSelectedMember(response.data); setProfileDialogOpen(true); } catch (error) { toast({ title: "Error", description: "Failed to load member profile. Please try again.", variant: "destructive" }); } }; const formatDate = (dateString) => { if (!dateString) return null; return new Date(dateString).toLocaleDateString('en-US', { month: 'long', day: 'numeric' }); }; const Border = ({ yaxis = false }) => { return ( yaxis ?
: ) } return (Number of current members in the directory: {totalMembers}
Found {filteredMembers.length} {filteredMembers.length === 1 ? 'member' : 'members'}
)}Loading members...
{searchQuery ? 'Try adjusting your search query.' : 'Members who opt in to the directory will appear here.'}
Update your profile settings to show in the directory and add your photo, bio, and contact information.{' '} Edit your profile →
Showing {pageStart + 1}–{Math.min(pageStart + pageSize, filteredMembers.length)} of {filteredMembers.length}