basic event filtering
This commit is contained in:
@@ -11,16 +11,44 @@ import {
|
|||||||
Button,
|
Button,
|
||||||
} from "@nextui-org/react";
|
} from "@nextui-org/react";
|
||||||
|
|
||||||
const EventsPage = () => {
|
interface Event {
|
||||||
const [events, setEvents] = useState<any[]>([]);
|
id: number;
|
||||||
|
title: string;
|
||||||
|
category: string;
|
||||||
|
location: string;
|
||||||
|
time: string; // Assuming time is a string, adjust if necessary
|
||||||
|
description: string;
|
||||||
|
imageUrl: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const EventsPage: React.FC = () => {
|
||||||
|
const [events, setEvents] = useState<Event[]>([]);
|
||||||
|
const [filteredEvents, setFilteredEvents] = useState<Event[]>([]);
|
||||||
|
const [categories, setCategories] = useState<string[]>([]);
|
||||||
|
const [locations, setLocations] = useState<string[]>([]);
|
||||||
|
const [selectedCategory, setSelectedCategory] = useState<string>("");
|
||||||
|
const [selectedLocation, setSelectedLocation] = useState<string>("");
|
||||||
|
const [selectedTime, setSelectedTime] = useState<string>("");
|
||||||
|
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const fetchEvents = async () => {
|
const fetchEvents = async () => {
|
||||||
try {
|
try {
|
||||||
const res = await instance.get(config.serverAddress + "/events");
|
const res = await instance.get<Event[]>(`${config.serverAddress}/events`);
|
||||||
console.log("Fetched events data:", res.data); // Log the fetched data
|
console.log("Fetched events data:", res.data);
|
||||||
setEvents(res.data);
|
setEvents(res.data);
|
||||||
|
setFilteredEvents(res.data);
|
||||||
|
|
||||||
|
// Extract unique categories and locations from events
|
||||||
|
const uniqueCategories = Array.from(
|
||||||
|
new Set(res.data.map((event) => event.category).filter(Boolean))
|
||||||
|
);
|
||||||
|
const uniqueLocations = Array.from(
|
||||||
|
new Set(res.data.map((event) => event.location).filter(Boolean))
|
||||||
|
);
|
||||||
|
setCategories(uniqueCategories);
|
||||||
|
setLocations(uniqueLocations);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Failed to fetch events:", error);
|
console.error("Failed to fetch events:", error);
|
||||||
}
|
}
|
||||||
@@ -29,17 +57,71 @@ const EventsPage = () => {
|
|||||||
fetchEvents();
|
fetchEvents();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
// Filter events based on selected criteria
|
||||||
|
const filtered = events.filter((event) => {
|
||||||
|
const matchCategory = selectedCategory ? event.category === selectedCategory : true;
|
||||||
|
const matchLocation = selectedLocation ? event.location === selectedLocation : true;
|
||||||
|
const matchTime = selectedTime ? event.time === selectedTime : true;
|
||||||
|
|
||||||
|
return matchCategory && matchLocation && matchTime;
|
||||||
|
});
|
||||||
|
|
||||||
|
setFilteredEvents(filtered);
|
||||||
|
}, [selectedCategory, selectedLocation, selectedTime, events]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="w-full h-full">
|
<div className="w-full h-full">
|
||||||
<div className="p-8">
|
<div className="p-8">
|
||||||
<div className="mb-6">
|
<div className="mb-6">
|
||||||
<h2 className="text-3xl font-semibold text-primary-600">Events</h2>
|
<h2 className="text-3xl font-semibold text-primary-600">Events</h2>
|
||||||
</div>
|
</div>
|
||||||
|
{/* Filter Options */}
|
||||||
|
<div className="mb-6 flex gap-4">
|
||||||
|
<select
|
||||||
|
value={selectedCategory}
|
||||||
|
onChange={(e) => setSelectedCategory(e.target.value)}
|
||||||
|
className="bg-white border border-gray-300 rounded px-3 py-2"
|
||||||
|
>
|
||||||
|
<option value="">All Categories</option>
|
||||||
|
{categories.map((category, index) => (
|
||||||
|
<option key={index} value={category}>
|
||||||
|
{category}
|
||||||
|
</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select
|
||||||
|
value={selectedLocation}
|
||||||
|
onChange={(e) => setSelectedLocation(e.target.value)}
|
||||||
|
className="bg-white border border-gray-300 rounded px-3 py-2"
|
||||||
|
>
|
||||||
|
<option value="">All Locations</option>
|
||||||
|
{locations.map((location, index) => (
|
||||||
|
<option key={index} value={location}>
|
||||||
|
{location}
|
||||||
|
</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select
|
||||||
|
value={selectedTime}
|
||||||
|
onChange={(e) => setSelectedTime(e.target.value)}
|
||||||
|
className="bg-white border border-gray-300 rounded px-3 py-2"
|
||||||
|
>
|
||||||
|
<option value="">All Times</option>
|
||||||
|
<option value="morning">Morning</option>
|
||||||
|
<option value="afternoon">Afternoon</option>
|
||||||
|
<option value="evening">Evening</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Event List */}
|
||||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
|
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
|
||||||
{events.length === 0 ? (
|
{filteredEvents.length === 0 ? (
|
||||||
<p className="text-gray-600">No events available.</p>
|
<p className="text-gray-600">No events available.</p>
|
||||||
) : (
|
) : (
|
||||||
events.map((event) => (
|
filteredEvents.map((event) => (
|
||||||
<Card
|
<Card
|
||||||
key={event.id}
|
key={event.id}
|
||||||
className="bg-white rounded-lg overflow-hidden border"
|
className="bg-white rounded-lg overflow-hidden border"
|
||||||
@@ -54,7 +136,6 @@ const EventsPage = () => {
|
|||||||
src={event.imageUrl}
|
src={event.imageUrl}
|
||||||
width="100%"
|
width="100%"
|
||||||
height={180}
|
height={180}
|
||||||
data-disableanimation={true} // Use custom data attribute
|
|
||||||
/>
|
/>
|
||||||
</CardBody>
|
</CardBody>
|
||||||
<CardFooter className="flex flex-col items-start p-4">
|
<CardFooter className="flex flex-col items-start p-4">
|
||||||
|
|||||||
Reference in New Issue
Block a user