83 lines
3.9 KiB
JavaScript
83 lines
3.9 KiB
JavaScript
import React, { useState, useEffect } from 'react';
|
|
|
|
export default function EventFilterSearch({ events }) {
|
|
const [searchTerm, setSearchTerm] = useState('');
|
|
const [selectedCategory, setSelectedCategory] = useState('All');
|
|
const [filteredEvents, setFilteredEvents] = useState(events);
|
|
|
|
const categories = ['All', ...new Set(events.map(event => event.frontmatter.category))];
|
|
|
|
useEffect(() => {
|
|
let tempEvents = events;
|
|
|
|
// Filter by category
|
|
if (selectedCategory !== 'All') {
|
|
tempEvents = tempEvents.filter(event => event.frontmatter.category === selectedCategory);
|
|
}
|
|
|
|
// Filter by search term
|
|
if (searchTerm) {
|
|
tempEvents = tempEvents.filter(event =>
|
|
event.frontmatter.title.toLowerCase().includes(searchTerm.toLowerCase()) ||
|
|
event.frontmatter.description.toLowerCase().includes(searchTerm.toLowerCase())
|
|
);
|
|
}
|
|
|
|
setFilteredEvents(tempEvents);
|
|
}, [searchTerm, selectedCategory, events]);
|
|
|
|
return (
|
|
<div className="container mx-auto px-4 py-8">
|
|
<div className="flex flex-col md:flex-row gap-4 mb-8">
|
|
{/* Search Input */}
|
|
<input
|
|
type="text"
|
|
placeholder="Search events..."
|
|
className="flex-grow p-3 border border-gray-300 rounded-lg shadow-sm focus:outline-none focus:ring-2 focus:ring-nigerian-green-500"
|
|
value={searchTerm}
|
|
onChange={(e) => setSearchTerm(e.target.value)}
|
|
/>
|
|
|
|
{/* Category Filter */}
|
|
<select
|
|
className="p-3 border border-gray-300 rounded-lg shadow-sm focus:outline-none focus:ring-2 focus:ring-nigerian-green-500"
|
|
value={selectedCategory}
|
|
onChange={(e) => setSelectedCategory(e.target.value)}
|
|
>
|
|
{categories.map(category => (
|
|
<option key={category} value={category}>{category}</option>
|
|
))}
|
|
</select>
|
|
</div>
|
|
|
|
{/* Event List */}
|
|
<section className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
|
|
{filteredEvents.length > 0 ? (
|
|
filteredEvents.map(event => (
|
|
<article key={event.url} className="card bg-base-100 shadow-lg rounded-xl overflow-hidden transform transition-transform duration-300 hover:scale-105 hover:shadow-xl">
|
|
<figure className="relative h-48 w-full overflow-hidden">
|
|
<img src={event.frontmatter.image} alt={event.frontmatter.title} className="w-full h-full object-cover" />
|
|
<div className="absolute inset-0 bg-gradient-to-t from-black/60 to-transparent"></div>
|
|
<span className="absolute bottom-3 left-3 badge badge-secondary bg-kente-gold-500 text-white px-3 py-1 rounded-full text-sm font-semibold">{event.frontmatter.category}</span>
|
|
</figure>
|
|
<div className="card-body p-6">
|
|
<h2 className="card-title text-xl font-bold text-nigerian-green-700 mb-2">{event.frontmatter.title}</h2>
|
|
<p className="text-sm text-gray-600 mb-3">{new Date(event.frontmatter.date).toLocaleDateString('en-US', { year: 'numeric', month: 'long', day: 'numeric' })}</p>
|
|
<p className="text-gray-700 leading-relaxed text-sm mb-4">{event.frontmatter.description}</p>
|
|
<a href={event.url} className="inline-flex items-center text-nigerian-green-600 hover:text-nigerian-green-800 font-semibold transition-colors duration-200">
|
|
Read More
|
|
<svg xmlns="http://www.w3.org/2000/svg" className="h-4 w-4 ml-1" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M9 5l7 7-7 7" />
|
|
</svg>
|
|
</a>
|
|
</div>
|
|
</article>
|
|
))
|
|
) : (
|
|
<p className="text-center text-gray-500 text-lg col-span-full">No events found matching your criteria.</p>
|
|
)}
|
|
</section>
|
|
</div>
|
|
);
|
|
}
|