lad-website/frontend/src/hooks/useEvents.ts
TheMaddax 8e986796e0 feat(admin): Implement comprehensive admin dashboard system
Create central dashboard with statistics and quick actions
Build events management with filtering and CRUD UI
Implement members management with bulk actions
Develop video management with accessibility indicators
Add document repository with visibility controls
Create content management with WYSIWYG editor
Add settings interface for site configuration
Additional improvements:

Implement full Events Management System with CRUD
Enhance frontend architecture with TypeScript
Improve accessibility in navigation menu
Add comprehensive test suite for Events API
2025-03-26 10:13:53 -05:00

256 lines
6.9 KiB
TypeScript

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<void>;
getEventById: (id: string) => Promise<Event | null>;
createEvent: (eventData: Omit<Event, '_id' | 'createdAt' | 'updatedAt'>) => Promise<Event | null>;
updateEvent: (id: string, eventData: Partial<Event>) => Promise<Event | null>;
deleteEvent: (id: string) => Promise<boolean>;
registerForEvent: (id: string) => Promise<Event | null>;
cancelRegistration: (id: string) => Promise<Event | null>;
}
// 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<Event[]>([]);
const [loading, setLoading] = useState<boolean>(false);
const [error, setError] = useState<Error | null>(null);
const [pagination, setPagination] = useState<Pagination | null>(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<Event | null> => {
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<Event, '_id' | 'createdAt' | 'updatedAt'>): Promise<Event | null> => {
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<Event>): Promise<Event | null> => {
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<boolean> => {
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<Event | null> => {
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<Event | null> => {
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
};
}