Image error resolve

This commit is contained in:
2025-10-10 20:42:13 +05:30
parent d375cad253
commit 84c674cefd

View File

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