import { useState, useEffect, useCallback } from 'react'; import axios from 'axios'; // Define Member interface export interface Member { _id: string; firstName: string; lastName: string; email: string; phone?: string; address?: { street?: string; city?: string; state?: string; zip?: string; }; membershipType: 'regular' | 'lifetime' | 'honorary'; joinDate: string; expirationDate?: string; status: 'active' | 'expired' | 'pending'; notificationPreference?: 'email' | 'sms' | 'both'; lastRenewalDate?: string; boardMember: boolean; boardPosition?: string; emergencyContact?: { name: string; relationship: string; phone: string; }; createdAt: string; updatedAt: string; } // Define filter interface export interface MemberFilter { status?: string; type?: string; search?: string; boardMember?: boolean; page?: number; limit?: number; } // Define pagination interface export interface Pagination { total: number; page: number; limit: number; pages: number; } // Define analytics interface export interface MemberAnalytics { statusCounts: Record; typeCounts: Record; boardMemberCount: number; expiringCount: number; recentJoinsCount: number; totalMembers: number; } // Define bulk action interface export interface BulkActionResult { message: string; affected: number; } // Define hook return interface export interface UseMembersReturn { members: Member[]; loading: boolean; error: Error | null; pagination: Pagination | null; analytics: MemberAnalytics | null; fetchMembers: (filters?: MemberFilter) => Promise; getMemberById: (id: string) => Promise; createMember: (memberData: Omit) => Promise; updateMember: (id: string, memberData: Partial) => Promise; deleteMember: (id: string) => Promise; bulkAction: (action: string, memberIds: string[]) => Promise; fetchAnalytics: () => Promise; } // API base URL const API_URL = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:4000/api'; /** * Hook for managing members data */ export function useMembers(): UseMembersReturn { const [members, setMembers] = useState([]); const [loading, setLoading] = useState(false); const [error, setError] = useState(null); const [pagination, setPagination] = useState(null); const [analytics, setAnalytics] = useState(null); /** * Fetch members with optional filtering */ const fetchMembers = useCallback(async (filters?: MemberFilter) => { setLoading(true); setError(null); try { // Build query string from filters const queryParams = new URLSearchParams(); if (filters) { Object.entries(filters).forEach(([key, value]) => { if (value !== undefined && value !== null && value !== '') { queryParams.append(key, String(value)); } }); } const response = await axios.get(`${API_URL}/members?${queryParams.toString()}`); setMembers(response.data.members); setPagination(response.data.pagination); } catch (err) { console.error('Error fetching members:', err); setError(err instanceof Error ? err : new Error('Failed to fetch members')); } finally { setLoading(false); } }, []); /** * Get a single member by ID */ const getMemberById = useCallback(async (id: string): Promise => { try { const response = await axios.get(`${API_URL}/members/${id}`); return response.data.member; } catch (err) { console.error(`Error fetching member with ID ${id}:`, err); return null; } }, []); /** * Create a new member */ const createMember = useCallback(async (memberData: Omit): Promise => { try { const response = await axios.post(`${API_URL}/members`, memberData, { headers: { 'Content-Type': 'application/json', // Add authorization header if needed // 'Authorization': `Bearer ${token}` } }); // Refresh members list after creating fetchMembers(); return response.data.member; } catch (err) { console.error('Error creating member:', err); // Rethrow the error so it can be caught and handled by the component throw err; } }, [fetchMembers]); /** * Update an existing member */ const updateMember = useCallback(async (id: string, memberData: Partial): Promise => { try { const response = await axios.put(`${API_URL}/members/${id}`, memberData, { headers: { 'Content-Type': 'application/json', // Add authorization header if needed // 'Authorization': `Bearer ${token}` } }); // Update local state setMembers(prevMembers => prevMembers.map(member => member._id === id ? { ...member, ...response.data.member } : member ) ); return response.data.member; } catch (err) { console.error(`Error updating member with ID ${id}:`, err); // Rethrow the error so it can be caught and handled by the component throw err; } }, []); /** * Delete a member */ const deleteMember = useCallback(async (id: string): Promise => { try { await axios.delete(`${API_URL}/members/${id}`, { headers: { // Add authorization header if needed // 'Authorization': `Bearer ${token}` } }); // Update local state setMembers(prevMembers => prevMembers.filter(member => member._id !== id)); return true; } catch (err) { console.error(`Error deleting member with ID ${id}:`, err); return false; } }, []); /** * Perform bulk actions on members */ const bulkAction = useCallback(async (action: string, memberIds: string[]): Promise => { try { const response = await axios.post(`${API_URL}/members/bulk-action`, { action, memberIds }, { headers: { 'Content-Type': 'application/json', // Add authorization header if needed // 'Authorization': `Bearer ${token}` } } ); // Refresh members list after bulk action fetchMembers(); return { message: response.data.message, affected: response.data.affected }; } catch (err) { console.error(`Error performing bulk action ${action}:`, err); return null; } }, [fetchMembers]); /** * Fetch member analytics */ const fetchAnalytics = useCallback(async (): Promise => { try { const response = await axios.get(`${API_URL}/members/analytics/stats`, { headers: { // Add authorization header if needed // 'Authorization': `Bearer ${token}` } }); const analyticsData = response.data.analytics; setAnalytics(analyticsData); return analyticsData; } catch (err) { console.error('Error fetching member analytics:', err); return null; } }, []); // Load members on initial render useEffect(() => { fetchMembers(); }, [fetchMembers]); return { members, loading, error, pagination, analytics, fetchMembers, getMemberById, createMember, updateMember, deleteMember, bulkAction, fetchAnalytics }; }