past image resolved
This commit is contained in:
@ -1,6 +1,5 @@
|
|||||||
'use client';
|
'use client';
|
||||||
import { useState, useEffect } from 'react';
|
import { useState, useEffect } from 'react';
|
||||||
import Image from 'next/image';
|
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
import {
|
import {
|
||||||
ChevronRight,
|
ChevronRight,
|
||||||
@ -401,14 +400,19 @@ const AcademicResearch: React.FC = () => {
|
|||||||
href={`/education-training/course-detail?id=${course.id}`}
|
href={`/education-training/course-detail?id=${course.id}`}
|
||||||
className="group bg-white rounded-lg overflow-hidden border border-gray-300 hover:shadow-xl transition-all duration-300 flex flex-col h-full cursor-pointer"
|
className="group bg-white rounded-lg overflow-hidden border border-gray-300 hover:shadow-xl transition-all duration-300 flex flex-col h-full cursor-pointer"
|
||||||
>
|
>
|
||||||
{/* Image - FIXED */}
|
{/* Image - no fallback */}
|
||||||
<div className="relative h-48 w-full overflow-hidden flex-shrink-0">
|
<div className="relative h-48 w-full overflow-hidden flex-shrink-0">
|
||||||
<Image
|
{course.image && course.image.trim() !== '' ? (
|
||||||
|
<img
|
||||||
src={course.image}
|
src={course.image}
|
||||||
alt={course.title}
|
alt={course.title}
|
||||||
fill
|
className="w-full h-full object-cover transition-transform duration-300 group-hover:scale-105"
|
||||||
className="object-cover transition-transform duration-300 group-hover:scale-105"
|
|
||||||
/>
|
/>
|
||||||
|
) : (
|
||||||
|
<div className="w-full h-full bg-gray-200 flex items-center justify-center">
|
||||||
|
<span className="text-gray-400">No image available</span>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Content */}
|
{/* Content */}
|
||||||
|
|||||||
@ -165,30 +165,18 @@ const EventDetail = () => {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const getSafeImageUrl = (imageUrl: string | undefined, fallback: string) => {
|
// Get safe image URL - no fallback
|
||||||
return imageUrl && imageUrl.trim() !== '' ? imageUrl : fallback;
|
const getSafeImageUrl = (imageUrl: string | undefined): string => {
|
||||||
|
return imageUrl && imageUrl.trim() !== '' ? imageUrl : '';
|
||||||
};
|
};
|
||||||
|
|
||||||
const getGalleryImages = (galleryImages: string[] | undefined) => {
|
const getGalleryImages = (galleryImages: string[] | undefined): string[] => {
|
||||||
const fallbackImages = [
|
|
||||||
'https://images.unsplash.com/photo-1576091160550-2173dba999ef?w=400&h=200&fit=crop',
|
|
||||||
'https://images.unsplash.com/photo-1582750433449-648ed127bb54?w=400&h=200&fit=crop'
|
|
||||||
];
|
|
||||||
|
|
||||||
if (!galleryImages || galleryImages.length === 0) {
|
if (!galleryImages || galleryImages.length === 0) {
|
||||||
return fallbackImages;
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
const validImages = galleryImages.filter(img => img && img.trim() !== '');
|
// Only return valid images, no fallbacks
|
||||||
if (validImages.length === 0) {
|
return galleryImages.filter(img => img && img.trim() !== '');
|
||||||
return fallbackImages;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (validImages.length < 2) {
|
|
||||||
validImages.push(fallbackImages[validImages.length % fallbackImages.length]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return validImages.slice(0, 2);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const getFormattedDescription = (event: Event) => {
|
const getFormattedDescription = (event: Event) => {
|
||||||
@ -298,7 +286,7 @@ const EventDetail = () => {
|
|||||||
const venue = getPrimaryVenue(eventData);
|
const venue = getPrimaryVenue(eventData);
|
||||||
const description = getFormattedDescription(eventData);
|
const description = getFormattedDescription(eventData);
|
||||||
const galleryImages = getGalleryImages(eventData.galleryImages);
|
const galleryImages = getGalleryImages(eventData.galleryImages);
|
||||||
const mainImage = getSafeImageUrl(eventData.mainImage, 'https://images.unsplash.com/photo-1559757148-5c350d0d3c56?w=800&h=400&fit=crop');
|
const mainImage = getSafeImageUrl(eventData.mainImage);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="min-h-screen" style={{ backgroundColor: '#f4f4f4' }}>
|
<div className="min-h-screen" style={{ backgroundColor: '#f4f4f4' }}>
|
||||||
@ -335,17 +323,24 @@ const EventDetail = () => {
|
|||||||
|
|
||||||
<div className="py-6">
|
<div className="py-6">
|
||||||
<div className="max-w-7xl mx-auto px-4">
|
<div className="max-w-7xl mx-auto px-4">
|
||||||
{/* Image Section - FIXED */}
|
{/* Image Section - No fallbacks */}
|
||||||
<div className="bg-white shadow-lg rounded-lg overflow-hidden mb-6">
|
<div className="bg-white shadow-lg rounded-lg overflow-hidden mb-6">
|
||||||
<div className="relative">
|
<div className="relative">
|
||||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-1">
|
<div className="grid grid-cols-1 md:grid-cols-3 gap-1">
|
||||||
<div className="md:col-span-2 relative overflow-hidden h-64 md:h-96">
|
<div className="md:col-span-2 relative overflow-hidden h-64 md:h-96">
|
||||||
|
{mainImage ? (
|
||||||
<img
|
<img
|
||||||
src={mainImage}
|
src={mainImage}
|
||||||
alt={eventData.title}
|
alt={eventData.title}
|
||||||
className="w-full h-full object-cover hover:scale-105 transition-transform duration-300"
|
className="w-full h-full object-cover hover:scale-105 transition-transform duration-300"
|
||||||
/>
|
/>
|
||||||
|
) : (
|
||||||
|
<div className="w-full h-full bg-gray-200 flex items-center justify-center">
|
||||||
|
<span className="text-gray-400">No image available</span>
|
||||||
</div>
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
{galleryImages.length > 0 && (
|
||||||
<div className="hidden md:flex md:flex-col gap-1">
|
<div className="hidden md:flex md:flex-col gap-1">
|
||||||
{galleryImages.map((image, index) => (
|
{galleryImages.map((image, index) => (
|
||||||
<div key={index} className="relative overflow-hidden flex-1 min-h-0">
|
<div key={index} className="relative overflow-hidden flex-1 min-h-0">
|
||||||
@ -357,6 +352,7 @@ const EventDetail = () => {
|
|||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -129,38 +129,28 @@ const MedicalEventsComponent = () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Get safe image URL with fallback
|
// Get safe image URL - no fallback, return empty string if no image
|
||||||
const getSafeImageUrl = (imageUrl: string | undefined, fallback: string) => {
|
const getSafeImageUrl = (imageUrl: string | undefined): string => {
|
||||||
return imageUrl && imageUrl.trim() !== '' ? imageUrl : fallback;
|
if (!imageUrl || imageUrl.trim() === '') {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
return imageUrl;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Get gallery images with fallbacks - only for events, not training programs
|
// Get gallery images - no fallbacks, only return valid images
|
||||||
const getGalleryImages = (item: DisplayItem) => {
|
const getGalleryImages = (item: DisplayItem): string[] => {
|
||||||
const fallbackImages = [
|
|
||||||
'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'
|
|
||||||
];
|
|
||||||
|
|
||||||
if (item.type === 'training') {
|
if (item.type === 'training') {
|
||||||
// Training programs don't have gallery images
|
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
const galleryImages = item.galleryImages;
|
const galleryImages = item.galleryImages;
|
||||||
|
|
||||||
if (!galleryImages || galleryImages.length === 0) {
|
if (!galleryImages || galleryImages.length === 0) {
|
||||||
return fallbackImages;
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fill missing images with fallbacks
|
// Only return valid images, no fallbacks
|
||||||
const validImages = galleryImages.filter(img => img && img.trim() !== '');
|
return galleryImages.filter(img => img && img.trim() !== '');
|
||||||
while (validImages.length < 4 && validImages.length < fallbackImages.length) {
|
|
||||||
validImages.push(fallbackImages[validImages.length]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return validImages.slice(0, 4);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if (loading) {
|
if (loading) {
|
||||||
@ -264,11 +254,17 @@ const MedicalEventsComponent = () => {
|
|||||||
onClick={() => navigateToDetail(nextItem)}
|
onClick={() => navigateToDetail(nextItem)}
|
||||||
>
|
>
|
||||||
<div className="relative h-48 md:h-64">
|
<div className="relative h-48 md:h-64">
|
||||||
|
{getSafeImageUrl(nextItem.mainImage) ? (
|
||||||
<img
|
<img
|
||||||
src={getSafeImageUrl(nextItem.mainImage, "https://images.unsplash.com/photo-1576091160550-2173dba999ef?w=800&h=300&fit=crop")}
|
src={getSafeImageUrl(nextItem.mainImage)}
|
||||||
alt={nextItem.title}
|
alt={nextItem.title}
|
||||||
className="w-full h-full object-cover"
|
className="w-full h-full object-cover"
|
||||||
/>
|
/>
|
||||||
|
) : (
|
||||||
|
<div className="w-full h-full bg-gray-200 flex items-center justify-center">
|
||||||
|
<span className="text-gray-400 text-sm">No image available</span>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
{/* Type Badge */}
|
{/* Type Badge */}
|
||||||
<div className="absolute top-4 right-4">
|
<div className="absolute top-4 right-4">
|
||||||
<span
|
<span
|
||||||
@ -402,11 +398,17 @@ const MedicalEventsComponent = () => {
|
|||||||
<div className="flex flex-col sm:flex-row gap-1 w-full md:w-auto">
|
<div className="flex flex-col sm:flex-row gap-1 w-full md:w-auto">
|
||||||
{/* Main image - FIXED HEIGHT */}
|
{/* Main image - FIXED HEIGHT */}
|
||||||
<div className="w-full sm:w-48 h-32 md:h-32 flex-shrink-0 rounded-sm overflow-hidden relative">
|
<div className="w-full sm:w-48 h-32 md:h-32 flex-shrink-0 rounded-sm overflow-hidden relative">
|
||||||
|
{getSafeImageUrl(item.mainImage) ? (
|
||||||
<img
|
<img
|
||||||
src={getSafeImageUrl(item.mainImage, "https://images.unsplash.com/photo-1559757148-5c350d0d3c56?w=400&h=200&fit=crop")}
|
src={getSafeImageUrl(item.mainImage)}
|
||||||
alt={item.title}
|
alt={item.title}
|
||||||
className="w-full h-full object-cover"
|
className="w-full h-full object-cover"
|
||||||
/>
|
/>
|
||||||
|
) : (
|
||||||
|
<div className="w-full h-full bg-gray-200 flex items-center justify-center">
|
||||||
|
<span className="text-gray-400 text-xs">No image</span>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
{/* Type Badge */}
|
{/* Type Badge */}
|
||||||
<div className="absolute top-2 right-2">
|
<div className="absolute top-2 right-2">
|
||||||
<span
|
<span
|
||||||
@ -421,8 +423,8 @@ const MedicalEventsComponent = () => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Gallery grid - only for events - FIXED HEIGHT */}
|
{/* Gallery grid - only for events, only if images exist */}
|
||||||
{showGallery && (
|
{showGallery && galleryImages.length > 0 && (
|
||||||
<div className="grid grid-cols-2 gap-1 w-full sm:w-60 h-32 md:h-32">
|
<div className="grid grid-cols-2 gap-1 w-full sm:w-60 h-32 md:h-32">
|
||||||
{galleryImages.map((img, index) => (
|
{galleryImages.map((img, index) => (
|
||||||
<div key={index} className="rounded-sm overflow-hidden">
|
<div key={index} className="rounded-sm overflow-hidden">
|
||||||
@ -491,11 +493,17 @@ const MedicalEventsComponent = () => {
|
|||||||
onClick={() => router.push(`/event-detail/${event.id}`)}
|
onClick={() => router.push(`/event-detail/${event.id}`)}
|
||||||
>
|
>
|
||||||
<div className="w-full h-32 lg:h-28 mb-3 overflow-hidden rounded-sm">
|
<div className="w-full h-32 lg:h-28 mb-3 overflow-hidden rounded-sm">
|
||||||
|
{getSafeImageUrl(event.mainImage) ? (
|
||||||
<img
|
<img
|
||||||
src={getSafeImageUrl(event.mainImage, "https://images.unsplash.com/photo-1551601651-2a8555f1a136?w=300&h=200&fit=crop")}
|
src={getSafeImageUrl(event.mainImage)}
|
||||||
alt={event.title}
|
alt={event.title}
|
||||||
className="w-full h-full object-cover"
|
className="w-full h-full object-cover"
|
||||||
/>
|
/>
|
||||||
|
) : (
|
||||||
|
<div className="w-full h-full bg-gray-200 flex items-center justify-center">
|
||||||
|
<span className="text-gray-400 text-xs">No image</span>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className="text-sm">
|
<div className="text-sm">
|
||||||
<div className="mb-1 font-medium text-xs" style={{ color: '#e64838' }}>
|
<div className="mb-1 font-medium text-xs" style={{ color: '#e64838' }}>
|
||||||
|
|||||||
@ -60,6 +60,14 @@ const EventsSection = () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Get safe image URL - no fallback
|
||||||
|
const getSafeImageUrl = (item: EventOrCourse): string => {
|
||||||
|
if (!item.mainImage || item.mainImage.trim() === '') {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
return item.mainImage;
|
||||||
|
};
|
||||||
|
|
||||||
// Navigation functions
|
// Navigation functions
|
||||||
const navigateToDetail = (item: EventOrCourse) => {
|
const navigateToDetail = (item: EventOrCourse) => {
|
||||||
if (item.type === 'event') {
|
if (item.type === 'event') {
|
||||||
@ -144,11 +152,17 @@ const EventsSection = () => {
|
|||||||
} ${index === 3 ? 'md:col-span-2 lg:col-span-1' : ''}`}
|
} ${index === 3 ? 'md:col-span-2 lg:col-span-1' : ''}`}
|
||||||
onClick={() => navigateToDetail(item)}
|
onClick={() => navigateToDetail(item)}
|
||||||
>
|
>
|
||||||
|
{getSafeImageUrl(item) ? (
|
||||||
<img
|
<img
|
||||||
src={item.mainImage}
|
src={getSafeImageUrl(item)}
|
||||||
alt={getTitle(item)}
|
alt={getTitle(item)}
|
||||||
className="w-full h-full object-cover"
|
className="w-full h-full object-cover"
|
||||||
/>
|
/>
|
||||||
|
) : (
|
||||||
|
<div className="w-full h-full bg-gray-200 flex items-center justify-center">
|
||||||
|
<span className="text-gray-400 text-sm">No image</span>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
{/* Gradient overlay for better text readability */}
|
{/* Gradient overlay for better text readability */}
|
||||||
<div className="absolute inset-0 bg-gradient-to-t from-black/70 via-black/20 to-transparent"></div>
|
<div className="absolute inset-0 bg-gradient-to-t from-black/70 via-black/20 to-transparent"></div>
|
||||||
|
|
||||||
@ -199,11 +213,17 @@ const EventsSection = () => {
|
|||||||
onClick={() => navigateToDetail(featuredItem)}
|
onClick={() => navigateToDetail(featuredItem)}
|
||||||
>
|
>
|
||||||
<div className="relative h-48 md:h-64">
|
<div className="relative h-48 md:h-64">
|
||||||
|
{getSafeImageUrl(featuredItem) ? (
|
||||||
<img
|
<img
|
||||||
src={featuredItem.mainImage}
|
src={getSafeImageUrl(featuredItem)}
|
||||||
alt={getTitle(featuredItem)}
|
alt={getTitle(featuredItem)}
|
||||||
className="w-full h-full object-cover"
|
className="w-full h-full object-cover"
|
||||||
/>
|
/>
|
||||||
|
) : (
|
||||||
|
<div className="w-full h-full bg-gray-200 flex items-center justify-center">
|
||||||
|
<span className="text-gray-400">No image available</span>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
{/* Item type badge */}
|
{/* Item type badge */}
|
||||||
<div className="absolute top-4 right-4">
|
<div className="absolute top-4 right-4">
|
||||||
<span
|
<span
|
||||||
@ -314,13 +334,19 @@ const EventsSection = () => {
|
|||||||
className="bg-white border border-gray-100 rounded-lg overflow-hidden cursor-pointer hover:shadow-lg transition-shadow flex-shrink-0"
|
className="bg-white border border-gray-100 rounded-lg overflow-hidden cursor-pointer hover:shadow-lg transition-shadow flex-shrink-0"
|
||||||
onClick={() => router.push(`/event-detail/${event.id}`)}
|
onClick={() => router.push(`/event-detail/${event.id}`)}
|
||||||
>
|
>
|
||||||
{/* FIXED: Added explicit height */}
|
{/* FIXED: Added explicit height - no fallback */}
|
||||||
<div className="h-24 w-full overflow-hidden">
|
<div className="h-24 w-full overflow-hidden">
|
||||||
|
{event.mainImage && event.mainImage.trim() !== '' ? (
|
||||||
<img
|
<img
|
||||||
src={event.mainImage}
|
src={event.mainImage}
|
||||||
alt={event.title}
|
alt={event.title}
|
||||||
className="w-full h-full object-cover"
|
className="w-full h-full object-cover"
|
||||||
/>
|
/>
|
||||||
|
) : (
|
||||||
|
<div className="w-full h-full bg-gray-200 flex items-center justify-center">
|
||||||
|
<span className="text-gray-400 text-xs">No image</span>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className="p-4">
|
<div className="p-4">
|
||||||
<div className="text-xs font-medium mb-1" style={{ color: '#e64838' }}>
|
<div className="text-xs font-medium mb-1" style={{ color: '#e64838' }}>
|
||||||
|
|||||||
Reference in New Issue
Block a user