Refactor project structure: update Astro configuration, integrate Tailwind CSS, enhance ContactForm with validation, and improve layout for various pages. Add new Donate and Orphanage pages, and implement responsive design adjustments across components.
This commit is contained in:
82
src/components/EventFilterSearch.jsx
Normal file
82
src/components/EventFilterSearch.jsx
Normal file
@@ -0,0 +1,82 @@
|
||||
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>
|
||||
);
|
||||
}
|
Reference in New Issue
Block a user