diff --git a/app/TicketListings/TicketListings.tsx b/app/TicketListings/TicketListings.tsx index 0ae0c67..46efa5f 100644 --- a/app/TicketListings/TicketListings.tsx +++ b/app/TicketListings/TicketListings.tsx @@ -1,5 +1,5 @@ 'use client'; -import React, { useEffect, useState } from 'react'; +import React, { useEffect, useState, useRef } from 'react'; import Header from '../../components/custom/header'; import Footer from '../../components/custom/footer'; @@ -7,13 +7,14 @@ import Footer from '../../components/custom/footer'; interface Event { EventID: number; name: string; - date: string; + date: string; // Should ideally be a Date object for better handling location: string; - ticketPrice: string; + ticketPrice: number; // Changed to number for sorting description: string; capacity: number; ticketsSold: number; imageUrl: string; + host: string; // New field for host } // Dummy function to fetch events @@ -24,50 +25,129 @@ const fetchEvents = (): Event[] => { name: 'Rock Concert', date: '2023-12-01', location: 'New York City', - ticketPrice: '$99', + ticketPrice: 99, description: 'An exhilarating rock concert featuring famous bands.', capacity: 5000, ticketsSold: 4500, imageUrl: 'https://via.placeholder.com/150', + host: 'Music Mania', }, { EventID: 2, name: 'Art Expo', date: '2023-11-15', location: 'San Francisco', - ticketPrice: '$55', + ticketPrice: 55, description: 'A showcase of modern art from around the world.', capacity: 300, ticketsSold: 260, imageUrl: 'https://via.placeholder.com/150', + host: 'Art Lovers', }, { EventID: 3, name: 'Tech Summit 2023', date: '2023-12-10', location: 'Chicago', - ticketPrice: '$250', + ticketPrice: 250, description: 'The leading tech summit with top industry speakers.', capacity: 2000, ticketsSold: 1800, imageUrl: 'https://via.placeholder.com/150', + host: 'Tech Alliance', }, ]; }; const TicketListing: React.FC = () => { const [events, setEvents] = useState([]); + const [filteredEvents, setFilteredEvents] = useState([]); + const [searchQuery, setSearchQuery] = useState(''); const [hoveredEventId, setHoveredEventId] = useState(null); + const [sortOption, setSortOption] = useState(''); // Track sorting option + const [filterOptions, setFilterOptions] = useState([]); // Track applied filters + const [selectedHost, setSelectedHost] = useState(''); // For host filtering + const [showSortMenu, setShowSortMenu] = useState(false); + const [showFilterMenu, setShowFilterMenu] = useState(false); + + const sortRef = useRef(null); + const filterRef = useRef(null); useEffect(() => { const eventsData = fetchEvents(); setEvents(eventsData); + setFilteredEvents(eventsData); + }, []); + + useEffect(() => { + let filtered = events.filter((event) => + ['name', 'date', 'location', 'description', 'host'].some((key) => + event[key as keyof Event] + .toString() + .toLowerCase() + .includes(searchQuery.toLowerCase()) + ) + ); + + if (filterOptions.includes('limited')) { + filtered = filtered.filter( + (event) => event.ticketsSold / event.capacity >= 0.9 + ); + } + + if (filterOptions.includes('future')) { + const now = new Date(); + filtered = filtered.filter((event) => new Date(event.date) > now); + } + + if (filterOptions.includes('past')) { + const now = new Date(); + filtered = filtered.filter((event) => new Date(event.date) < now); + } + + if (selectedHost) { + filtered = filtered.filter((event) => event.host === selectedHost); + } + + if (sortOption === 'price-asc') { + filtered = filtered.sort((a, b) => a.ticketPrice - b.ticketPrice); + } else if (sortOption === 'price-desc') { + filtered = filtered.sort((a, b) => b.ticketPrice - a.ticketPrice); + } else if (sortOption === 'date-asc') { + filtered = filtered.sort( + (a, b) => new Date(a.date).getTime() - new Date(b.date).getTime() + ); + } else if (sortOption === 'date-desc') { + filtered = filtered.sort( + (a, b) => new Date(b.date).getTime() - new Date(a.date).getTime() + ); + } + + setFilteredEvents(filtered); + }, [searchQuery, sortOption, filterOptions, selectedHost, events]); + + const handleClickOutside = (event: MouseEvent) => { + if (sortRef.current && !sortRef.current.contains(event.target as Node)) { + setShowSortMenu(false); + } + if ( + filterRef.current && + !filterRef.current.contains(event.target as Node) + ) { + setShowFilterMenu(false); + } + }; + + useEffect(() => { + document.addEventListener('mousedown', handleClickOutside); + return () => { + document.removeEventListener('mousedown', handleClickOutside); + }; }, []); return (
- {/* Video Background */} - {/* Overlay for Readability */}
- {/* Main Content */}
setSearchQuery(e.target.value)} className="search-bar mt-4 p-2 border border-gray-300 rounded w-full max-w-md" />
- - + {/* Sort Button and Dropdown */} +
+ + {showSortMenu && ( +
+ + + + +
+ )} +
+ + {/* Filter Button and Dropdown */} +
+ + {showFilterMenu && ( +
+ + + + + {/* Filter by Host */} + +
+ )} +
+

Available Events

- {events.map((event) => ( + {filteredEvents.map((event) => (
{

{event.date}

{event.location}

- {event.ticketPrice} + ${event.ticketPrice.toFixed(2)}

+

Host: {event.host}

{event.ticketsSold / event.capacity >= 0.9 && (
Limited Tickets Remaining! diff --git a/package-lock.json b/package-lock.json index 3e66f56..02109a7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -24012,6 +24012,111 @@ "funding": { "url": "https://github.com/sponsors/sindresorhus" } + }, + "node_modules/@next/swc-darwin-arm64": { + "version": "14.2.13", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.2.13.tgz", + "integrity": "sha512-IkAmQEa2Htq+wHACBxOsslt+jMoV3msvxCn0WFSfJSkv/scy+i/EukBKNad36grRxywaXUYJc9mxEGkeIs8Bzg==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-darwin-x64": { + "version": "14.2.13", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.2.13.tgz", + "integrity": "sha512-Dv1RBGs2TTjkwEnFMVL5XIfJEavnLqqwYSD6LXgTPdEy/u6FlSrLBSSfe1pcfqhFEXRAgVL3Wpjibe5wXJzWog==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-gnu": { + "version": "14.2.13", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.2.13.tgz", + "integrity": "sha512-yB1tYEFFqo4ZNWkwrJultbsw7NPAAxlPXURXioRl9SdW6aIefOLS+0TEsKrWBtbJ9moTDgU3HRILL6QBQnMevg==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-musl": { + "version": "14.2.13", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.2.13.tgz", + "integrity": "sha512-v5jZ/FV/eHGoWhMKYrsAweQ7CWb8xsWGM/8m1mwwZQ/sutJjoFaXchwK4pX8NqwImILEvQmZWyb8pPTcP7htWg==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-arm64-msvc": { + "version": "14.2.13", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.13.tgz", + "integrity": "sha512-uP1XkqCqV2NVH9+g2sC7qIw+w2tRbcMiXFEbMihkQ8B1+V6m28sshBwAB0SDmOe0u44ne1vFU66+gx/28RsBVQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-ia32-msvc": { + "version": "14.2.13", + "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.13.tgz", + "integrity": "sha512-V26ezyjPqQpDBV4lcWIh8B/QICQ4v+M5Bo9ykLN+sqeKKBxJVDpEc6biDVyluTXTC40f5IqCU0ttth7Es2ZuMw==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-x64-msvc": { + "version": "14.2.13", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.2.13.tgz", + "integrity": "sha512-WwzOEAFBGhlDHE5Z73mNU8CO8mqMNLqaG+AO9ETmzdCQlJhVtWZnOl2+rqgVQS+YHunjOWptdFmNfbpwcUuEsw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } } } }