diff --git a/.github/workflows/ci-pr.yml b/.github/workflows/ci-pr.yml index 677a5d2..5f8ced1 100644 --- a/.github/workflows/ci-pr.yml +++ b/.github/workflows/ci-pr.yml @@ -62,7 +62,7 @@ jobs: - run: npx prettier --check . env: - NODE_OPTIONS: "--max_old_space_size=4096" + NODE_OPTIONS: "--max_old_space_size=8192" lint: runs-on: self-hosted @@ -89,7 +89,7 @@ jobs: - run: npx nx run ${{ matrix.tasks }}:lint env: - NODE_OPTIONS: "--max_old_space_size=4096" + NODE_OPTIONS: "--max_old_space_size=8192" test: @@ -117,7 +117,7 @@ jobs: - run: npx nx run ${{ matrix.tasks }}:test env: - NODE_OPTIONS: "--max_old_space_size=4096" + NODE_OPTIONS: "--max_old_space_size=8192" build: runs-on: self-hosted @@ -144,4 +144,4 @@ jobs: - run: npx nx run ${{ matrix.tasks }}:build env: - NODE_OPTIONS: "--max_old_space_size=4096" \ No newline at end of file + NODE_OPTIONS: "--max_old_space_size=8192" \ No newline at end of file diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9c1d90e..ab81242 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -65,7 +65,7 @@ jobs: - run: npx prettier --check . env: - NODE_OPTIONS: "--max_old_space_size=4096" + NODE_OPTIONS: "--max_old_space_size=8192" lint: runs-on: self-hosted @@ -92,7 +92,7 @@ jobs: - run: npx nx run ${{ matrix.tasks }}:lint env: - NODE_OPTIONS: "--max_old_space_size=4096" + NODE_OPTIONS: "--max_old_space_size=8192" test: @@ -120,7 +120,7 @@ jobs: - run: npx nx run ${{ matrix.tasks }}:test env: - NODE_OPTIONS: "--max_old_space_size=4096" + NODE_OPTIONS: "--max_old_space_size=8192" build: runs-on: self-hosted @@ -147,7 +147,7 @@ jobs: - run: npx nx run ${{ matrix.tasks }}:build env: - NODE_OPTIONS: "--max_old_space_size=4096" + NODE_OPTIONS: "--max_old_space_size=8192" deploy: @@ -172,7 +172,7 @@ jobs: - name: Build run: NX_PUBLIC_APP_BUILD=$(node scripts/CreateBuildIdent.js) npx nx run-many -t build --no-cloud env: - NODE_OPTIONS: "--max_old_space_size=4096" + NODE_OPTIONS: "--max_old_space_size=8192" - run: npm ci --legacy-peer-deps working-directory: ./infra diff --git a/apps/userweb/src/components/TicketCard.tsx b/apps/userweb/src/components/TicketCard.tsx index 51fe6de..e30a1dc 100644 --- a/apps/userweb/src/components/TicketCard.tsx +++ b/apps/userweb/src/components/TicketCard.tsx @@ -11,12 +11,14 @@ export interface TicketCardProps { event: UserEventDetailsResponse; ticket: string; transferEnabled: boolean; + onWaiting: (showBlockInclusion: boolean) => void; } export function TicketCard({ event, ticket, - transferEnabled + transferEnabled, + onWaiting }: TicketCardProps) { const { primaryWallet } = useDynamicContext(); const titleRef = useRef(null); @@ -66,6 +68,10 @@ export function TicketCard({ onClose={async (showLoading: boolean) => { setShouldShowTransferModal(false); setShouldShowLoadingModal(showLoading); + onWaiting(false); + }} + onWaiting={async () => { + onWaiting(true); }} TicketID={BigInt(ticket)} /> diff --git a/apps/userweb/src/components/TransferTicketsModal.tsx b/apps/userweb/src/components/TransferTicketsModal.tsx index 48d29f2..a08e873 100644 --- a/apps/userweb/src/components/TransferTicketsModal.tsx +++ b/apps/userweb/src/components/TransferTicketsModal.tsx @@ -3,31 +3,58 @@ import { useDynamicContext } from '@dynamic-labs/sdk-react-core'; import { ContractAddress, ContractABI } from '@platform/blockchain'; import { CrossCircledIcon } from '@radix-ui/react-icons'; import { Button, Callout, Dialog, Flex, Text } from '@radix-ui/themes'; -import { useState } from 'react'; +import { useEffect, useState } from 'react'; import { useNavigate } from 'react-router-dom'; -type ReturnedMetadata = { - min: bigint; - max: bigint; - exists: boolean; -}; - export interface TransferTicketsModalProps { onClose: (showLoading: boolean) => void; + onWaiting: () => void; TicketID: bigint; } export default function TransferTicketsModal({ onClose, + onWaiting, TicketID }: TransferTicketsModalProps) { - const navigate = useNavigate(); const [showError, setShowError] = useState(false); const [errorMessage, setErrorMessage] = useState(''); const [isSubmitting, setIsSubmitting] = useState(false); + const [ticketTransferable, setTicketTransferable] = + useState(false); const { primaryWallet } = useDynamicContext(); - const onSubmit = async () => { + // query the contract (not on network) for the event name for an id + async function checkIfTicketIsTransferable(id: bigint) { + // get the events description from the id + if (primaryWallet && isEthereumWallet(primaryWallet)) { + const p = await primaryWallet.getPublicClient(); + if (p) { + const data = (await p.readContract({ + abi: ContractABI, + address: ContractAddress, + functionName: 'check_ticket_transferable', + args: [id] + })) as boolean; + + return data; + } else { + throw new Error('Failed to create public client.'); + } + } else { + throw new Error('Failed to confirm ethereum wallet.'); + } + } + + async function start() { + setTicketTransferable(await checkIfTicketIsTransferable(TicketID)); + } + + useEffect(() => { + start(); + }); + + const onSubmit = async (allow: boolean) => { setIsSubmitting(true); if (primaryWallet && isEthereumWallet(primaryWallet)) { @@ -39,7 +66,9 @@ export default function TransferTicketsModal({ const { request } = await p.simulateContract({ abi: ContractABI, address: ContractAddress, - functionName: 'allow_ticket_to_be_transfered', + functionName: allow + ? 'allow_ticket_to_be_transfered' + : 'disallow_ticket_to_be_transfered', account: w.account, args: [TicketID] }); @@ -47,13 +76,17 @@ export default function TransferTicketsModal({ console.log(hash); // wait for the call to be included in a block + onWaiting(); await p.waitForTransactionReceipt({ hash: hash }); setIsSubmitting(false); - onClose(true); - // navigate(0); + if (allow) { + onClose(true); + } else { + onClose(false); + } } else { console.error('Wallet client or public client not set up'); setErrorMessage( @@ -103,9 +136,21 @@ export default function TransferTicketsModal({ - + {ticketTransferable ? ( + + ) : ( + + )} diff --git a/apps/userweb/src/views/Profile.tsx b/apps/userweb/src/views/Profile.tsx index 8503066..3bf5e8e 100644 --- a/apps/userweb/src/views/Profile.tsx +++ b/apps/userweb/src/views/Profile.tsx @@ -30,6 +30,7 @@ import { import { useTheme } from 'next-themes'; import React, { ReactElement, useEffect, useState } from 'react'; import styled from 'styled-components'; +import { FullscreenLoadingMessage } from '@platform/ui'; import { TicketCard } from '../components/TicketCard'; //70/30 left right column split @@ -106,6 +107,8 @@ export default function Profile() { setTicketTransferStateChangeRequested ] = useState(false); const { theme, setTheme } = useTheme(); + const [showBlockInclusionModal, setShowBlockInclusionModal] = + useState(false); const getUserBalance = async () => { const bal = await primaryWallet?.getBalance(); @@ -140,6 +143,7 @@ export default function Profile() { async function getNFTsInWallet() { const token = getAuthToken(); const url = `${process.env.NX_PUBLIC_API_BASEURL}/oklink?wallet=${primaryWallet?.address}&tokenContractAddress=${ContractAddress}&chainShortName=amoy_testnet`; + console.log(url); const resp = await fetch(url, { method: 'GET', headers: { Authorization: `Bearer ${token}` } @@ -148,8 +152,16 @@ export default function Profile() { if (!resp.ok) return Error('There was an error fetching data from oklink.'); + const tmp = (await resp.json())['data']; + console.log(tmp); + + // stop app from blowing up if the user owns no tickets + if (tmp.length === 0) { + return 0; + } + // this is nasty but it gives us what we want - return (await resp.json())['data'][0]['tokenList']; + return tmp[0]['tokenList']; } // Return an array of owned ticket ids @@ -322,9 +334,11 @@ export default function Profile() { }); const hash = await w.writeContract(request); console.log(`enable ticket transfer hash ${hash}`); + setShowBlockInclusionModal(true); await p.waitForTransactionReceipt({ hash: hash }); + setShowBlockInclusionModal(false); setTicketTransferStateChangeRequested(true); } else { console.error('Wallet client or public client not set up'); @@ -351,9 +365,11 @@ export default function Profile() { }); const hash = await w.writeContract(request); console.log(`disable ticket transfer hash ${hash}`); + setShowBlockInclusionModal(true); await p.waitForTransactionReceipt({ hash: hash }); + setShowBlockInclusionModal(false); setTicketTransferStateChangeRequested(true); } else { console.error('Wallet client or public client not set up'); @@ -380,6 +396,9 @@ export default function Profile() { return ( <> + {showBlockInclusionModal && ( + + )} Profile @@ -911,6 +930,13 @@ export default function Profile() { return ( { + setShowBlockInclusionModal( + showBlockInclusion + ); + }} key={`${idx}`} event={data.data} ticket={ diff --git a/apps/vendorweb/src/views/Profile.tsx b/apps/vendorweb/src/views/Profile.tsx index 3733afb..bb9dd3d 100644 --- a/apps/vendorweb/src/views/Profile.tsx +++ b/apps/vendorweb/src/views/Profile.tsx @@ -25,6 +25,7 @@ import { import { useTheme } from 'next-themes'; import React, { useEffect, useState } from 'react'; import styled from 'styled-components'; +import { FullscreenLoadingMessage } from '@platform/ui'; //70/30 left right column split const LeftColumn = styled.div`