import { useState, useEffect, useCallback } from 'react'; import axios from 'axios'; // Define Event interface export interface Event { _id: string; title: string; description: string; date: string; time: string; location: string; category: 'social' | 'athletic' | 'board' | 'general' | 'educational'; status: 'published' | 'draft' | 'archived'; registrationRequired: boolean; registeredCount: number; maxAttendees?: number; recurring?: boolean; recurrencePattern?: string; tags?: string[]; createdAt: string; updatedAt: string; } // Define filter interface export interface EventFilter { status?: string; category?: string; search?: string; startDate?: string; endDate?: string; page?: number; limit?: number; } // Define pagination interface export interface Pagination { total: number; page: number; limit: number; pages: number; } // Define hook return interface export interface UseEventsReturn { events: Event[]; loading: boolean; error: Error | null; pagination: Pagination | null; fetchEvents: (filters?: EventFilter) => Promise; getEventById: (id: string) => Promise; createEvent: (eventData: Omit) => Promise; updateEvent: (id: string, eventData: Partial) => Promise; deleteEvent: (id: string) => Promise; registerForEvent: (id: string) => Promise; cancelRegistration: (id: string) => Promise; } // API base URL const API_URL = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:4000/api'; /** * Hook for managing events data */ export function useEvents(): UseEventsReturn { const [events, setEvents] = useState([]); const [loading, setLoading] = useState(false); const [error, setError] = useState(null); const [pagination, setPagination] = useState(null); /** * Fetch events with optional filtering */ const fetchEvents = useCallback(async (filters?: EventFilter) => { 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}/events?${queryParams.toString()}`); setEvents(response.data.events); setPagination(response.data.pagination); } catch (err) { console.error('Error fetching events:', err); setError(err instanceof Error ? err : new Error('Failed to fetch events')); } finally { setLoading(false); } }, []); /** * Get a single event by ID */ const getEventById = useCallback(async (id: string): Promise => { try { const response = await axios.get(`${API_URL}/events/${id}`); return response.data.event; } catch (err) { console.error(`Error fetching event with ID ${id}:`, err); return null; } }, []); /** * Create a new event */ const createEvent = useCallback(async (eventData: Omit): Promise => { try { const response = await axios.post(`${API_URL}/events`, eventData, { headers: { 'Content-Type': 'application/json', // Add authorization header if needed // 'Authorization': `Bearer ${token}` } }); // Refresh events list after creating fetchEvents(); return response.data.event; } catch (err) { console.error('Error creating event:', err); return null; } }, [fetchEvents]); /** * Update an existing event */ const updateEvent = useCallback(async (id: string, eventData: Partial): Promise => { try { const response = await axios.put(`${API_URL}/events/${id}`, eventData, { headers: { 'Content-Type': 'application/json', // Add authorization header if needed // 'Authorization': `Bearer ${token}` } }); // Update local state setEvents(prevEvents => prevEvents.map(event => event._id === id ? { ...event, ...response.data.event } : event ) ); return response.data.event; } catch (err) { console.error(`Error updating event with ID ${id}:`, err); return null; } }, []); /** * Delete an event */ const deleteEvent = useCallback(async (id: string): Promise => { try { await axios.delete(`${API_URL}/events/${id}`, { headers: { // Add authorization header if needed // 'Authorization': `Bearer ${token}` } }); // Update local state setEvents(prevEvents => prevEvents.filter(event => event._id !== id)); return true; } catch (err) { console.error(`Error deleting event with ID ${id}:`, err); return false; } }, []); /** * Register for an event */ const registerForEvent = useCallback(async (id: string): Promise => { try { const response = await axios.post(`${API_URL}/events/${id}/register`, {}, { headers: { 'Content-Type': 'application/json', // Add authorization header if needed // 'Authorization': `Bearer ${token}` } }); // Update local state setEvents(prevEvents => prevEvents.map(event => event._id === id ? { ...event, ...response.data.event } : event ) ); return response.data.event; } catch (err) { console.error(`Error registering for event with ID ${id}:`, err); return null; } }, []); /** * Cancel registration for an event */ const cancelRegistration = useCallback(async (id: string): Promise => { try { const response = await axios.post(`${API_URL}/events/${id}/cancel-registration`, {}, { headers: { 'Content-Type': 'application/json', // Add authorization header if needed // 'Authorization': `Bearer ${token}` } }); // Update local state setEvents(prevEvents => prevEvents.map(event => event._id === id ? { ...event, ...response.data.event } : event ) ); return response.data.event; } catch (err) { console.error(`Error cancelling registration for event with ID ${id}:`, err); return null; } }, []); // Load events on initial render useEffect(() => { fetchEvents(); }, [fetchEvents]); return { events, loading, error, pagination, fetchEvents, getEventById, createEvent, updateEvent, deleteEvent, registerForEvent, cancelRegistration }; }