import React, { useState, useEffect } 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';
const MembersDirectory = () => {
const [members, setMembers] = useState([]);
const [filteredMembers, setFilteredMembers] = useState([]);
const [searchQuery, setSearchQuery] = useState('');
const [loading, setLoading] = useState(true);
const [selectedMember, setSelectedMember] = useState(null);
const [profileDialogOpen, setProfileDialogOpen] = useState(false);
const { toast } = useToast();
const [currentPage, setCurrentPage] = useState(1);
const pageSize = 12;
useEffect(() => {
fetchMembers();
}, []);
useEffect(() => {
filterMembers();
}, [searchQuery, members]);
useEffect(() => {
setCurrentPage(1);
}, [searchQuery, members]);
const fetchMembers = async () => {
try {
const response = await api.get('/members/directory');
setMembers(response.data);
setFilteredMembers(response.data);
} catch (error) {
console.error('Failed to fetch members:', error);
toast({
title: "Error",
description: "Failed to load members directory. Please try again.",
variant: "destructive"
});
} finally {
setLoading(false);
}
};
const filterMembers = () => {
if (!searchQuery.trim()) {
setFilteredMembers(members);
return;
}
const query = searchQuery.toLowerCase();
const filtered = members.filter(member => {
const fullName = `${member.first_name} ${member.last_name}`.toLowerCase();
const bio = (member.directory_bio || '').toLowerCase();
return fullName.includes(query) || bio.includes(query);
});
setFilteredMembers(filtered);
};
const totalPages = Math.max(1, Math.ceil(filteredMembers.length / pageSize));
const pageStart = (currentPage - 1) * pageSize;
const paginatedMembers = filteredMembers.slice(pageStart, pageStart + pageSize);
const totalMembers = members.length;
const getInitials = (firstName, lastName) => {
return `${firstName.charAt(0)}${lastName.charAt(0)}`.toUpperCase();
};
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 ?
:
)
}
const MemberCard = ({ member }) => {
const joinedDate = member.member_since || member.created_at;
return (
{/* Profile Photo */}
{member.profile_photo_url ? (

) : (
{getInitials(member.first_name, member.last_name)}
)}
{/* Name */}
{member.first_name} {member.last_name}
{/* Partner Name */}
{member.directory_partner_name && (
Partner: {member.directory_partner_name}
)}
{/* Bio */}
{member.directory_bio && (
{member.directory_bio}
)}
{/* Member Since */}
{joinedDate && (
Member since {new Date(joinedDate).toLocaleDateString('en-US', {
month: 'long',
year: 'numeric'
})}
)}
{/* Contact Information */}
{member.directory_email && (
)}
{member.directory_phone && (
)}
{member.directory_address && (
{member.directory_address}
)}
{/* Social Media Links */}
{(member.social_media_facebook || member.social_media_instagram || member.social_media_twitter || member.social_media_linkedin) && (
{member.social_media_facebook && (
)}
{member.social_media_instagram && (
)}
{member.social_media_twitter && (
)}
{member.social_media_linkedin && (
)}
)}
{/* View Profile Button */}
);
};
return (
{/* Header and Search bar */}
{/* Header */}
LOAF Members
Number of current memebers in the directory: {totalMembers}
{/* Search Bar */}
setSearchQuery(e.target.value)}
className="pl-12 pr-4 py-6 text-3xl font-medium bg-background border-foreground rounded-full focus:border-brand-purple focus:ring-brand-purple "
style={{ fontFamily: "'Nunito Sans', sans-serif" }}
/>
{searchQuery && (
Found {filteredMembers.length} {filteredMembers.length === 1 ? 'member' : 'members'}
)}
{/* Border Decoration */}
{/* Members Grid */}
{loading ? (
) : filteredMembers.length > 0 ? (
{paginatedMembers.map((member) => (
))}
) : (
{searchQuery ? 'No Members Found' : 'No Members in Directory'}
{searchQuery
? 'Try adjusting your search query.'
: 'Members who opt in to the directory will appear here.'}
)}
{/* Border Decoration */}
{/* Info Card */}
{!loading && members.length > 0 && (
Want to appear in the directory?
Update your profile settings to show in the directory and add your photo, bio, and contact information.{' '}
Edit your profile →
)}
{/* Profile Detail Dialog */}
{/* Pagination */}
{!loading && filteredMembers.length > 0 && (
Showing {pageStart + 1}–{Math.min(pageStart + pageSize, filteredMembers.length)} of {filteredMembers.length}
{Array.from({ length: totalPages }, (_, index) => {
const pageNumber = index + 1;
const isActive = pageNumber === currentPage;
return (
);
})}
)}
);
};
export default MembersDirectory;