Files
ecoconnect/client/src/pages/EventsPage.tsx
2024-08-01 02:08:53 +08:00

156 lines
5.1 KiB
TypeScript

import React, { useState, useEffect } from "react";
import { useNavigate } from "react-router-dom";
import instance from "../security/http";
import config from "../config";
import {
Card,
CardHeader,
CardBody,
CardFooter,
Image,
Button,
} from "@nextui-org/react";
interface Event {
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();
useEffect(() => {
const fetchEvents = async () => {
try {
const res = await instance.get<Event[]>(`${config.serverAddress}/events`);
console.log("Fetched events data:", 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) {
console.error("Failed to fetch events:", error);
}
};
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 (
<div className="w-full h-full">
<div className="p-8">
<div className="mb-6">
<h2 className="text-3xl font-semibold text-primary-600">Events</h2>
</div>
{/* Filter Options */}
<div className="mb-6 flex gap-4">
<select
value={selectedCategory}
onChange={(e) => setSelectedCategory(e.target.value)}
>
<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)}
>
<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)}
>
<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">
{filteredEvents.length === 0 ? (
<p className="text-gray-600">No events available.</p>
) : (
filteredEvents.map((event) => (
<Card
key={event.id}
>
<CardHeader className="pb-0 pt-2 px-4 flex-col items-start">
<h4 className="font-bold text-large">{event.title}</h4>
</CardHeader>
<CardBody className="pb-0 pt-2 px-4 flex-col items-start">
<Image
alt={event.title}
className="object-cover rounded-xl"
src={event.imageUrl}
width="100%"
height={180}
/>
</CardBody>
<CardFooter className="flex flex-col items-start p-4">
<p className="text-gray-600 mb-4">{event.description}</p>
<Button
className="bg-primary-600 text-white rounded px-4 py-2 hover:bg-primary-700"
onClick={() => navigate(`/event/${event.id}`)}
>
View event details
</Button>
</CardFooter>
</Card>
))
)}
</div>
</div>
</div>
);
};
export default EventsPage;