From 100e8a9468414e8bd82197d1a306fd4ead944be8 Mon Sep 17 00:00:00 2001 From: Shay Patel Date: Sun, 27 Oct 2024 06:23:55 +0000 Subject: [PATCH 1/3] Abstract out fetchEvents.ts from events page --- app/events/page.tsx | 34 +- contracts/EventManager.sol | 8 +- contracts/EventManagerABI.json | 1046 ++++++++++++++++---------------- lib/fetchEvents.ts | 53 ++ 4 files changed, 586 insertions(+), 555 deletions(-) create mode 100644 lib/fetchEvents.ts diff --git a/app/events/page.tsx b/app/events/page.tsx index ea1643c..429bdc7 100644 --- a/app/events/page.tsx +++ b/app/events/page.tsx @@ -6,6 +6,7 @@ import Header from '../../components/custom/header'; import Footer from '../../components/custom/footer'; import { ethers } from 'ethers'; import { getContract } from '@/lib/ethers'; +import { fetchEvents } from '@/lib/fetchEvents'; export const dynamic = 'force-dynamic'; @@ -40,32 +41,9 @@ const EventsPage: React.FC = () => { const [showFilterMenu, setShowFilterMenu] = useState(false); useEffect(() => { - const fetchEvents = async () => { + const getEvents = async () => { try { - const provider = new ethers.providers.Web3Provider(window.ethereum!); - const contract = getContract().connect(provider); - const eventCount = await contract.eventCounter(); - const eventsData: Event[] = []; - - for (let i = 0; i < eventCount; i++) { - const event = await contract.events(i); - const images = await contract.getEventImages(i); - eventsData.push({ - eventId: i, - name: event.name, - description: event.description, - location: event.location, - capacity: event.capacity.toNumber(), - ticketsSold: event.ticketsSold.toNumber(), - ticketPrice: parseFloat( - ethers.utils.formatEther(event.ticketPrice) - ), - eventStartDate: event.eventStartDate.toNumber(), - eventEndDate: event.eventEndDate.toNumber(), - images: images, - eventHost: event.eventHost, - }); - } + const eventsData: Event[] = (await fetchEvents())!; setEvents(eventsData); setFilteredEvents(eventsData); @@ -87,7 +65,7 @@ const EventsPage: React.FC = () => { } }; - fetchEvents(); + getEvents(); }, [initialQuery]); useEffect(() => { @@ -172,7 +150,7 @@ const EventsPage: React.FC = () => {
- Loading...

}> + Loading...
}> {

{event.location}

- ${event.ticketPrice} FLR + ${event.ticketPrice}

Host: {event.eventHost}

diff --git a/contracts/EventManager.sol b/contracts/EventManager.sol index 7c0894e..b19b5ba 100644 --- a/contracts/EventManager.sol +++ b/contracts/EventManager.sol @@ -24,9 +24,9 @@ contract EventManager { string name; string description; string location; - uint256 capacity; - uint256 ticketsSold; - uint256 ticketPrice; // in USD cents + uint64 capacity; + uint64 ticketsSold; + uint64 ticketPrice; // in USD cents uint256 eventStartDate; uint256 eventEndDate; string[] images; // array of image URLs @@ -92,7 +92,7 @@ contract EventManager { return centsToFlare(events[_eventId].ticketPrice); } - function createEvent(string memory _name, string memory _description, string memory _location, uint256 _capacity, uint256 _ticketPrice, uint256 _eventStartDate, uint256 _eventEndDate, string[] memory _images) public returns (uint256 _eventId) { + function createEvent(string memory _name, string memory _description, string memory _location, uint64 _capacity, uint64 _ticketPrice, uint256 _eventStartDate, uint256 _eventEndDate, string[] memory _images) public returns (uint256 _eventId) { events[eventCounter] = Event(_name, _description, _location, _capacity, 0, _ticketPrice, _eventStartDate, _eventEndDate, _images, new uint256[](0), payable(msg.sender)); eventCounter++; emit EventCreated(eventCounter - 1, _name, _eventStartDate); diff --git a/contracts/EventManagerABI.json b/contracts/EventManagerABI.json index 73e85db..d22a78d 100644 --- a/contracts/EventManagerABI.json +++ b/contracts/EventManagerABI.json @@ -1,524 +1,524 @@ [ - { - "inputs": [ - { - "internalType": "uint256", - "name": "_ticketId", - "type": "uint256" - }, - { - "internalType": "address", - "name": "_to", - "type": "address" - }, - { - "internalType": "bool", - "name": "_allowed", - "type": "bool" - } - ], - "name": "approveTicket", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "_eventId", - "type": "uint256" - } - ], - "name": "buyTicket", - "outputs": [ - { - "internalType": "uint256", - "name": "_ticketId", - "type": "uint256" - } - ], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "string", - "name": "_name", - "type": "string" - }, - { - "internalType": "string", - "name": "_description", - "type": "string" - }, - { - "internalType": "string", - "name": "_location", - "type": "string" - }, - { - "internalType": "uint256", - "name": "_capacity", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "_ticketPrice", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "_eventStartDate", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "_eventEndDate", - "type": "uint256" - }, - { - "internalType": "string[]", - "name": "_images", - "type": "string[]" - } - ], - "name": "createEvent", - "outputs": [ - { - "internalType": "uint256", - "name": "_eventId", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint256", - "name": "eventId", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "string", - "name": "name", - "type": "string" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "eventStartDate", - "type": "uint256" - } - ], - "name": "EventCreated", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint256", - "name": "ticketId", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "eventId", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "address", - "name": "buyer", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "price", - "type": "uint256" - } - ], - "name": "TicketPurchased", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint256", - "name": "ticketId", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "trustee", - "type": "address" - } - ], - "name": "TicketTransferApproved", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint256", - "name": "ticketId", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "to", - "type": "address" - } - ], - "name": "TicketTransferred", - "type": "event" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "_ticketId", - "type": "uint256" - }, - { - "internalType": "address", - "name": "_to", - "type": "address" - } - ], - "name": "transferTicket", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "_ticketId", - "type": "uint256" - }, - { - "internalType": "address", - "name": "_to", - "type": "address" - } - ], - "name": "transferTicketFrom", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "_cents", - "type": "uint256" - } - ], - "name": "centsToFlare", - "outputs": [ - { - "internalType": "uint256", - "name": "_flr", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "eventCounter", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "name": "events", - "outputs": [ - { - "internalType": "string", - "name": "name", - "type": "string" - }, - { - "internalType": "string", - "name": "description", - "type": "string" - }, - { - "internalType": "string", - "name": "location", - "type": "string" - }, - { - "internalType": "uint256", - "name": "capacity", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "ticketsSold", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "ticketPrice", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "eventStartDate", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "eventEndDate", - "type": "uint256" - }, - { - "internalType": "address payable", - "name": "eventHost", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "name": "feedIds", - "outputs": [ - { - "internalType": "bytes21", - "name": "", - "type": "bytes21" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "_eventId", - "type": "uint256" - } - ], - "name": "getEventImages", - "outputs": [ - { - "internalType": "string[]", - "name": "", - "type": "string[]" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "_eventId", - "type": "uint256" - } - ], - "name": "getEventPriceFlare", - "outputs": [ - { - "internalType": "uint256", - "name": "_flr", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "_eventId", - "type": "uint256" - } - ], - "name": "getEventTickets", - "outputs": [ - { - "internalType": "uint256[]", - "name": "", - "type": "uint256[]" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getFlareFeed", - "outputs": [ - { - "internalType": "uint256", - "name": "_feedValue", - "type": "uint256" - }, - { - "internalType": "int8", - "name": "_decimals", - "type": "int8" - }, - { - "internalType": "uint64", - "name": "_timestamp", - "type": "uint64" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "getFtsoV2CurrentFeedValues", - "outputs": [ - { - "internalType": "uint256[]", - "name": "_feedValues", - "type": "uint256[]" - }, - { - "internalType": "int8[]", - "name": "_decimals", - "type": "int8[]" - }, - { - "internalType": "uint64", - "name": "_timestamp", - "type": "uint64" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "ticketCounter", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "name": "tickets", - "outputs": [ - { - "internalType": "address", - "name": "holder", - "type": "address" - }, - { - "internalType": "uint256", - "name": "boughtTime", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "eventId", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - }, - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "name": "userTickets", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - } -] + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "eventId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "string", + "name": "name", + "type": "string" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "eventStartDate", + "type": "uint256" + } + ], + "name": "EventCreated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "ticketId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "eventId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "buyer", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "price", + "type": "uint256" + } + ], + "name": "TicketPurchased", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "ticketId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "trustee", + "type": "address" + } + ], + "name": "TicketTransferApproved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "ticketId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "to", + "type": "address" + } + ], + "name": "TicketTransferred", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_ticketId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_to", + "type": "address" + }, + { + "internalType": "bool", + "name": "_allowed", + "type": "bool" + } + ], + "name": "approveTicket", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_eventId", + "type": "uint256" + } + ], + "name": "buyTicket", + "outputs": [ + { + "internalType": "uint256", + "name": "_ticketId", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_cents", + "type": "uint256" + } + ], + "name": "centsToFlare", + "outputs": [ + { + "internalType": "uint256", + "name": "_flr", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "_name", + "type": "string" + }, + { + "internalType": "string", + "name": "_description", + "type": "string" + }, + { + "internalType": "string", + "name": "_location", + "type": "string" + }, + { + "internalType": "uint64", + "name": "_capacity", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "_ticketPrice", + "type": "uint64" + }, + { + "internalType": "uint256", + "name": "_eventStartDate", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_eventEndDate", + "type": "uint256" + }, + { + "internalType": "string[]", + "name": "_images", + "type": "string[]" + } + ], + "name": "createEvent", + "outputs": [ + { + "internalType": "uint256", + "name": "_eventId", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "eventCounter", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "events", + "outputs": [ + { + "internalType": "string", + "name": "name", + "type": "string" + }, + { + "internalType": "string", + "name": "description", + "type": "string" + }, + { + "internalType": "string", + "name": "location", + "type": "string" + }, + { + "internalType": "uint64", + "name": "capacity", + "type": "uint64" + }, + { + "internalType": "uint256", + "name": "ticketsSold", + "type": "uint256" + }, + { + "internalType": "uint64", + "name": "ticketPrice", + "type": "uint64" + }, + { + "internalType": "uint256", + "name": "eventStartDate", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "eventEndDate", + "type": "uint256" + }, + { + "internalType": "address payable", + "name": "eventHost", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "feedIds", + "outputs": [ + { + "internalType": "bytes21", + "name": "", + "type": "bytes21" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_eventId", + "type": "uint256" + } + ], + "name": "getEventImages", + "outputs": [ + { + "internalType": "string[]", + "name": "", + "type": "string[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_eventId", + "type": "uint256" + } + ], + "name": "getEventPriceFlare", + "outputs": [ + { + "internalType": "uint256", + "name": "_flr", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_eventId", + "type": "uint256" + } + ], + "name": "getEventTickets", + "outputs": [ + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getFlareFeed", + "outputs": [ + { + "internalType": "uint256", + "name": "_feedValue", + "type": "uint256" + }, + { + "internalType": "int8", + "name": "_decimals", + "type": "int8" + }, + { + "internalType": "uint64", + "name": "_timestamp", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getFtsoV2CurrentFeedValues", + "outputs": [ + { + "internalType": "uint256[]", + "name": "_feedValues", + "type": "uint256[]" + }, + { + "internalType": "int8[]", + "name": "_decimals", + "type": "int8[]" + }, + { + "internalType": "uint64", + "name": "_timestamp", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "ticketCounter", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "tickets", + "outputs": [ + { + "internalType": "address", + "name": "holder", + "type": "address" + }, + { + "internalType": "uint256", + "name": "boughtTime", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "eventId", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_ticketId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_to", + "type": "address" + } + ], + "name": "transferTicket", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_ticketId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_to", + "type": "address" + } + ], + "name": "transferTicketFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "userTickets", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } +] \ No newline at end of file diff --git a/lib/fetchEvents.ts b/lib/fetchEvents.ts new file mode 100644 index 0000000..bc9e03f --- /dev/null +++ b/lib/fetchEvents.ts @@ -0,0 +1,53 @@ +import { ethers } from "ethers"; +import { getContract } from "./ethers"; + +interface Event { + eventId: number; + name: string; + description: string; + location: string; + capacity: number; + ticketsSold: number; + ticketPrice: number; + eventStartDate: number; + eventEndDate: number; + images: string[]; + eventHost: string; +} + +export const fetchEvents: () => Promise = async () => { + try { + console.log('Starting events call'); + if (typeof window.ethereum === 'undefined') { + console.error('Ethereum provider not found'); + return; + } + + console.log('Connecting to contract'); + const contract = getContract(); + const eventCount = await contract.eventCounter(); + const eventsData: Event[] = []; + + for (let i = 0; i < eventCount; i++) { + const event = await contract.events(i); + const images = await contract.getEventImages(i); + eventsData.push({ + eventId: i, + name: event.name, + description: event.description, + location: event.location, + capacity: event.capacity.toNumber(), + ticketsSold: event.ticketsSold.toNumber(), + ticketPrice: event.ticketPrice.toNumber() / 100, + eventStartDate: event.eventStartDate.toNumber(), + eventEndDate: event.eventEndDate.toNumber(), + images: images, + eventHost: event.eventHost, + }); + } + + return eventsData; + } catch (error) { + console.error('Failed to fetch events:', error); + } +} \ No newline at end of file From 935f0578a38b19a5b38cc63728059f1192c29621 Mon Sep 17 00:00:00 2001 From: Shay Patel Date: Sun, 27 Oct 2024 06:24:28 +0000 Subject: [PATCH 2/3] Fetch events on homepage --- app/page.tsx | 70 ++++++++++++++++++++++------------------------------ 1 file changed, 30 insertions(+), 40 deletions(-) diff --git a/app/page.tsx b/app/page.tsx index 4d3e9ab..282cd8e 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -7,6 +7,7 @@ import { Input } from '@/components/ui/input'; import FeaturedEvent from '@/components/custom/FeaturedEvent'; import { Button } from '@/components/ui/button'; import { FlipWords } from '@/components/ui/flip-words'; +import { fetchEvents } from '@/lib/fetchEvents'; // profile // profile props @@ -15,12 +16,22 @@ import { FlipWords } from '@/components/ui/flip-words'; export default function Home() { const router = useRouter(); const [isClient, setIsClient] = useState(false); + const [events, setEvents] = useState([]); const inputRef = useRef(null); useEffect(() => { setIsClient(true); + fetchEvents().then(eventsData => { + eventsData = eventsData?.sort((a, b) => (a.ticketsSold - b.ticketsSold)); + setEvents(eventsData || []); + }) }, []); + useEffect(() => { + console.log("events updated"); + console.log(events); + }, [events]) + function searchForEvents() { if (inputRef.current?.value === '') { alert('Please enter a search term.'); @@ -54,6 +65,10 @@ export default function Home() { 'gathering', ]; + const handleEventClick = (eventId: number) => { + router.push(`/events/${eventId}`); + }; + return ( <>
@@ -102,46 +117,21 @@ export default function Home() {
- - - - - + { events.map((ev: any, index: number) => { + return <> + { handleEventClick(ev.eventId) }}> + + + + }) }