Image error resolve
This commit is contained in:
@ -1,6 +1,6 @@
|
||||
// components/BlogListing.tsx
|
||||
'use client';
|
||||
import { useState, useEffect, useCallback } from 'react';
|
||||
import { useState, useEffect, useCallback } from 'react';
|
||||
import Image from 'next/image';
|
||||
import Link from 'next/link';
|
||||
import { ChevronRight } from 'lucide-react';
|
||||
@ -26,31 +26,31 @@ const BlogListing: React.FC = () => {
|
||||
|
||||
// Filter blogs based on category and search query
|
||||
const filterBlogs = useCallback(() => {
|
||||
let filtered = blogs;
|
||||
let filtered = blogs;
|
||||
|
||||
if (selectedCategory !== 'All Categories') {
|
||||
filtered = filtered.filter(blog =>
|
||||
blog.tags.some(tag =>
|
||||
tag.toLowerCase().includes(selectedCategory.toLowerCase())
|
||||
)
|
||||
);
|
||||
}
|
||||
if (selectedCategory !== 'All Categories') {
|
||||
filtered = filtered.filter(blog =>
|
||||
blog.tags.some(tag =>
|
||||
tag.toLowerCase().includes(selectedCategory.toLowerCase())
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if (searchQuery.trim()) {
|
||||
const query = searchQuery.toLowerCase().trim();
|
||||
filtered = filtered.filter(blog =>
|
||||
blog.title.toLowerCase().includes(query) ||
|
||||
blog.excerpt.toLowerCase().includes(query) ||
|
||||
blog.tags.some(tag => tag.toLowerCase().includes(query)) ||
|
||||
(blog.professors && blog.professors.some(prof =>
|
||||
prof.firstName?.toLowerCase().includes(query) ||
|
||||
prof.name?.toLowerCase().includes(query)
|
||||
))
|
||||
);
|
||||
}
|
||||
if (searchQuery.trim()) {
|
||||
const query = searchQuery.toLowerCase().trim();
|
||||
filtered = filtered.filter(blog =>
|
||||
blog.title.toLowerCase().includes(query) ||
|
||||
blog.excerpt.toLowerCase().includes(query) ||
|
||||
blog.tags.some(tag => tag.toLowerCase().includes(query)) ||
|
||||
(blog.professors && blog.professors.some(prof =>
|
||||
prof.firstName?.toLowerCase().includes(query) ||
|
||||
prof.name?.toLowerCase().includes(query)
|
||||
))
|
||||
);
|
||||
}
|
||||
|
||||
setFilteredBlogs(filtered);
|
||||
}, [blogs, selectedCategory, searchQuery]);
|
||||
setFilteredBlogs(filtered);
|
||||
}, [blogs, selectedCategory, searchQuery]);
|
||||
|
||||
// Load blogs from API
|
||||
useEffect(() => {
|
||||
@ -58,13 +58,13 @@ const BlogListing: React.FC = () => {
|
||||
try {
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
|
||||
|
||||
// Load both posted blogs and tag counts
|
||||
const [fetchedBlogs, fetchedTagCounts] = await Promise.all([
|
||||
blogService.getPostedBlogs(),
|
||||
blogService.getTagsWithCount()
|
||||
]);
|
||||
|
||||
|
||||
setBlogs(fetchedBlogs);
|
||||
setFilteredBlogs(fetchedBlogs);
|
||||
setTagCounts(fetchedTagCounts);
|
||||
@ -83,10 +83,10 @@ const BlogListing: React.FC = () => {
|
||||
|
||||
// Filter blogs when category or search changes
|
||||
useEffect(() => {
|
||||
if (mounted && blogs.length > 0) {
|
||||
filterBlogs();
|
||||
}
|
||||
}, [mounted, filterBlogs]);
|
||||
if (mounted && blogs.length > 0) {
|
||||
filterBlogs();
|
||||
}
|
||||
}, [mounted, filterBlogs]);
|
||||
|
||||
|
||||
// Handle mount
|
||||
@ -134,8 +134,8 @@ const BlogListing: React.FC = () => {
|
||||
<div className="min-h-screen flex items-center justify-center">
|
||||
<div className="text-center text-red-600">
|
||||
<p className="text-xl mb-4">⚠️ {error}</p>
|
||||
<button
|
||||
onClick={() => window.location.reload()}
|
||||
<button
|
||||
onClick={() => window.location.reload()}
|
||||
className="px-4 py-2 bg-blue-900 text-white rounded hover:bg-blue-800"
|
||||
>
|
||||
Retry
|
||||
@ -183,12 +183,13 @@ const BlogListing: React.FC = () => {
|
||||
</section>
|
||||
|
||||
{/* Filters Section */}
|
||||
<div className="flex justify-end items-center gap-4 max-w-7xl mx-auto px-4 py-8" style={{ backgroundColor: '#fff' }}>
|
||||
<div className="relative">
|
||||
<div className="flex flex-col sm:flex-row sm:justify-end items-start sm:items-center gap-4 max-w-7xl mx-auto px-4 py-8 bg-white">
|
||||
{/* Category Select */}
|
||||
<div className="relative w-full sm:w-auto">
|
||||
<select
|
||||
value={selectedCategory}
|
||||
onChange={handleCategoryChange}
|
||||
className="appearance-none bg-gray-100 text-sm border border-blue-900 rounded-lg px-4 py-2 pr-8 focus:outline-none focus:border-blue-900"
|
||||
className="w-full sm:w-auto appearance-none bg-gray-100 text-sm border border-blue-900 rounded-lg px-4 py-2 pr-8 focus:outline-none focus:border-blue-900"
|
||||
style={{ color: '#333' }}
|
||||
>
|
||||
{categories.map((category, index) => (
|
||||
@ -204,13 +205,15 @@ const BlogListing: React.FC = () => {
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
<div className="relative">
|
||||
|
||||
{/* Search Input */}
|
||||
<div className="relative w-full sm:w-64">
|
||||
<input
|
||||
type="text"
|
||||
value={searchQuery}
|
||||
onChange={handleSearchChange}
|
||||
placeholder="Search blogs..."
|
||||
className="border border-blue-900 rounded-lg px-4 py-2 pl-4 pr-10 text-sm focus:outline-none focus:border-blue-900 w-64 text-gray-700"
|
||||
className="w-full sm:w-64 border border-blue-900 rounded-lg px-4 py-2 pl-4 pr-10 text-sm focus:outline-none focus:border-blue-900 text-gray-700"
|
||||
/>
|
||||
<button className="absolute inset-y-0 right-0 flex items-center px-3 bg-blue-900 rounded-r-lg">
|
||||
<svg className="w-4 h-4 text-gray-100" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
@ -220,12 +223,13 @@ const BlogListing: React.FC = () => {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
{/* Results Info */}
|
||||
{(selectedCategory !== 'All Categories' || searchQuery.trim()) && (
|
||||
<div className="max-w-7xl mx-auto px-4 pb-4">
|
||||
<p className="text-sm text-gray-600">
|
||||
{filteredBlogs.length === 0
|
||||
? 'No blogs found matching your criteria.'
|
||||
{filteredBlogs.length === 0
|
||||
? 'No blogs found matching your criteria.'
|
||||
: `Showing ${blogsToShow.length} of ${filteredBlogs.length} blog${filteredBlogs.length !== 1 ? 's' : ''}`
|
||||
}
|
||||
</p>
|
||||
@ -238,8 +242,8 @@ const BlogListing: React.FC = () => {
|
||||
{blogsToShow.length === 0 ? (
|
||||
<div className="text-center py-12">
|
||||
<p className="text-gray-500 text-lg mb-4">
|
||||
{searchQuery.trim() || selectedCategory !== 'All Categories'
|
||||
? 'No blogs match your search criteria.'
|
||||
{searchQuery.trim() || selectedCategory !== 'All Categories'
|
||||
? 'No blogs match your search criteria.'
|
||||
: 'No blogs available at the moment.'
|
||||
}
|
||||
</p>
|
||||
@ -272,11 +276,11 @@ const BlogListing: React.FC = () => {
|
||||
{/* Blog Image */}
|
||||
<div className="relative h-48 w-full overflow-hidden">
|
||||
<img
|
||||
src={blog.image}
|
||||
alt={blog.title}
|
||||
className="w-full h-full object-cover transition-transform duration-300 group-hover:scale-105"
|
||||
onError={handleImageError}
|
||||
/>
|
||||
src={blog.image}
|
||||
alt={blog.title}
|
||||
className="w-full h-full object-cover transition-transform duration-300 group-hover:scale-105"
|
||||
onError={handleImageError}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Blog Content */}
|
||||
|
||||
Reference in New Issue
Block a user