160 lines
6.0 KiB
TypeScript
160 lines
6.0 KiB
TypeScript
// services/eventService.ts
|
|
export interface Event {
|
|
id: number;
|
|
title: string;
|
|
description: string;
|
|
date: string;
|
|
subtitle: string;
|
|
mainImage: string;
|
|
galleryImages: string[];
|
|
price?: number;
|
|
location?: string;
|
|
}
|
|
|
|
export interface ApiEvent {
|
|
id: number;
|
|
title: string;
|
|
description: string;
|
|
date: string;
|
|
subtitle?: string;
|
|
imageUrl?: string;
|
|
galleryImages?: string[];
|
|
price?: number;
|
|
location?: string;
|
|
// Add other fields that your Spring Boot API returns
|
|
}
|
|
|
|
class EventService {
|
|
private apiBaseUrl = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:8080';
|
|
|
|
async getAllEvents(): Promise<Event[]> {
|
|
try {
|
|
const response = await fetch(`${this.apiBaseUrl}/api/events`);
|
|
if (!response.ok) {
|
|
throw new Error(`HTTP error! status: ${response.status}`);
|
|
}
|
|
const apiEvents: ApiEvent[] = await response.json();
|
|
return this.transformApiEventsToEvents(apiEvents);
|
|
} catch (error) {
|
|
console.error('Error fetching events:', error);
|
|
return this.getFallbackEvents(); // Return fallback data if API fails
|
|
}
|
|
}
|
|
|
|
async getEventById(id: number): Promise<Event | null> {
|
|
try {
|
|
const response = await fetch(`${this.apiBaseUrl}/api/events/${id}`);
|
|
if (!response.ok) {
|
|
if (response.status === 404) {
|
|
return null;
|
|
}
|
|
throw new Error(`HTTP error! status: ${response.status}`);
|
|
}
|
|
const apiEvent: ApiEvent = await response.json();
|
|
return this.transformApiEventToEvent(apiEvent);
|
|
} catch (error) {
|
|
console.error(`Error fetching event ${id}:`, error);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
private transformApiEventsToEvents(apiEvents: ApiEvent[]): Event[] {
|
|
return apiEvents.map(apiEvent => this.transformApiEventToEvent(apiEvent));
|
|
}
|
|
|
|
private transformApiEventToEvent(apiEvent: ApiEvent): Event {
|
|
return {
|
|
id: apiEvent.id,
|
|
title: apiEvent.title,
|
|
description: apiEvent.description,
|
|
date: this.formatDate(apiEvent.date),
|
|
subtitle: apiEvent.subtitle || 'More details coming soon',
|
|
mainImage: apiEvent.imageUrl || this.getDefaultMainImage(),
|
|
galleryImages: apiEvent.galleryImages || this.getDefaultGalleryImages(),
|
|
price: apiEvent.price,
|
|
location: apiEvent.location
|
|
};
|
|
}
|
|
|
|
private formatDate(dateString: string): string {
|
|
try {
|
|
const date = new Date(dateString);
|
|
return date.toLocaleDateString('en-GB', {
|
|
day: 'numeric',
|
|
month: 'long',
|
|
year: 'numeric'
|
|
});
|
|
} catch (error) {
|
|
return dateString; // Return original if parsing fails
|
|
}
|
|
}
|
|
|
|
private getDefaultMainImage(): string {
|
|
const defaultImages = [
|
|
'https://images.unsplash.com/photo-1559757148-5c350d0d3c56?w=400&h=200&fit=crop',
|
|
'https://images.unsplash.com/photo-1559757175-0eb30cd8c063?w=400&h=200&fit=crop',
|
|
'https://images.unsplash.com/photo-1573496359142-b8d87734a5a2?w=400&h=200&fit=crop',
|
|
'https://images.unsplash.com/photo-1576091160550-2173dba999ef?w=400&h=200&fit=crop'
|
|
];
|
|
return defaultImages[Math.floor(Math.random() * defaultImages.length)];
|
|
}
|
|
|
|
private getDefaultGalleryImages(): string[] {
|
|
return [
|
|
'https://images.unsplash.com/photo-1551601651-2a8555f1a136?w=200&h=100&fit=crop',
|
|
'https://images.unsplash.com/photo-1582750433449-648ed127bb54?w=200&h=100&fit=crop',
|
|
'https://images.unsplash.com/photo-1638202993928-7267aad84c31?w=200&h=100&fit=crop',
|
|
'https://images.unsplash.com/photo-1576091160550-2173dba999ef?w=200&h=100&fit=crop'
|
|
];
|
|
}
|
|
|
|
private getFallbackEvents(): Event[] {
|
|
// Return the original hardcoded events as fallback
|
|
return [
|
|
{
|
|
id: 1,
|
|
date: '28 September 2025',
|
|
title: 'Advanced Cardiac Surgery Symposium',
|
|
description: 'Cutting-edge techniques in minimally invasive cardiac procedures',
|
|
subtitle: 'Learn from world-renowned cardiac surgeons about the latest innovations',
|
|
mainImage: 'https://images.unsplash.com/photo-1559757148-5c350d0d3c56?w=400&h=200&fit=crop',
|
|
galleryImages: [
|
|
'https://images.unsplash.com/photo-1551601651-2a8555f1a136?w=200&h=100&fit=crop',
|
|
'https://images.unsplash.com/photo-1582750433449-648ed127bb54?w=200&h=100&fit=crop',
|
|
'https://images.unsplash.com/photo-1638202993928-7267aad84c31?w=200&h=100&fit=crop',
|
|
'https://images.unsplash.com/photo-1551601651-2a8555f1a136?w=200&h=100&fit=crop'
|
|
]
|
|
},
|
|
{
|
|
id: 2,
|
|
date: '2 October 2025',
|
|
title: 'Pediatric Immunization Update Conference',
|
|
description: 'Latest developments in childhood vaccination protocols',
|
|
subtitle: 'Comprehensive review of new vaccine guidelines and safety data',
|
|
mainImage: 'https://images.unsplash.com/photo-1559757175-0eb30cd8c063?w=400&h=200&fit=crop',
|
|
galleryImages: [
|
|
'https://images.unsplash.com/photo-1584362917165-526a968579e8?w=200&h=100&fit=crop',
|
|
'https://images.unsplash.com/photo-1612349317150-e413f6a5b16d?w=200&h=100&fit=crop',
|
|
'https://images.unsplash.com/photo-1581056771107-24ca5f033842?w=200&h=100&fit=crop',
|
|
'https://images.unsplash.com/photo-1576091160550-2173dba999ef?w=200&h=100&fit=crop'
|
|
]
|
|
},
|
|
{
|
|
id: 3,
|
|
date: '8 October 2025',
|
|
title: 'Mental Health in Healthcare Workers',
|
|
description: 'Addressing burnout and psychological well-being in medical practice',
|
|
subtitle: 'Strategies for maintaining mental health in high-pressure environments',
|
|
mainImage: 'https://images.unsplash.com/photo-1573496359142-b8d87734a5a2?w=400&h=200&fit=crop',
|
|
galleryImages: [
|
|
'https://images.unsplash.com/photo-1582719508461-905c673771fd?w=200&h=100&fit=crop',
|
|
'https://images.unsplash.com/photo-1559757148-5c350d0d3c56?w=200&h=100&fit=crop',
|
|
'https://images.unsplash.com/photo-1576091160550-2173dba999ef?w=200&h=100&fit=crop',
|
|
'https://images.unsplash.com/photo-1582750433449-648ed127bb54?w=200&h=100&fit=crop'
|
|
]
|
|
}
|
|
];
|
|
}
|
|
}
|
|
|
|
export const eventService = new EventService(); |