diff --git a/packages/app/src/app/tickets/components/tickets-page.tsx b/packages/app/src/app/tickets/components/tickets-page.tsx index f7023bb..ae6bebe 100644 --- a/packages/app/src/app/tickets/components/tickets-page.tsx +++ b/packages/app/src/app/tickets/components/tickets-page.tsx @@ -137,7 +137,7 @@ function TicketsContent({ useEffect(() => { if (isSuccess) { - setRefreshKey((k) => k + 1) + setRefreshKey((prevKey) => prevKey + 1) } }, [isSuccess]) diff --git a/packages/app/src/app/tickets/create/page.tsx b/packages/app/src/app/tickets/create/page.tsx index 46cfa1f..9b8ce47 100644 --- a/packages/app/src/app/tickets/create/page.tsx +++ b/packages/app/src/app/tickets/create/page.tsx @@ -8,14 +8,14 @@ import { useTransactionNotifications } from '@/hooks/web3/useTransactionNotifica import { InlineSpinner } from '@/components/loading-spinner' export default function CreateTicket() { - const [name, setName] = useState('') - const [price, setPrice] = useState('0.01') - const [amount, setAmount] = useState('100') + const [ticketName, setTicketName] = useState('') + const [ticketPrice, setTicketPrice] = useState('0.01') + const [ticketSupply, setTicketSupply] = useState('100') const [maxSellPerPerson, setMaxSellPerPerson] = useState('5') const [infoUrl, setInfoUrl] = useState('') const { address, chain } = useAccount() - const { Add } = useNotifications() + const { addNotification } = useNotifications() const { address: contractAddress, abi } = useContractConfig(chain) @@ -38,7 +38,7 @@ export default function CreateTicket() { const handleCreateTicket = () => { if (!address) { - Add('Please connect your wallet first', { type: 'warning' }) + addNotification('Please connect your wallet first', { type: 'warning' }) return } @@ -48,7 +48,7 @@ export default function CreateTicket() { address: contractAddress, abi, functionName: 'create', - args: [name, parseEther(price), BigInt(amount), BigInt(maxSellPerPerson), infoUrl, emptyBytes as `0x${string}`], + args: [ticketName, parseEther(ticketPrice), BigInt(ticketSupply), BigInt(maxSellPerPerson), infoUrl, emptyBytes as `0x${string}`], }) } @@ -64,8 +64,8 @@ export default function CreateTicket() { Event Name setName(e.target.value)} + value={ticketName} + onChange={(e) => setTicketName(e.target.value)} placeholder='Enter event name' className='input-field' /> @@ -76,8 +76,8 @@ export default function CreateTicket() { Ticket Price (ETH) setPrice(e.target.value)} + value={ticketPrice} + onChange={(e) => setTicketPrice(e.target.value)} placeholder='0.01' className='input-field' step='0.01' @@ -89,8 +89,8 @@ export default function CreateTicket() { Total Supply setAmount(e.target.value)} + value={ticketSupply} + onChange={(e) => setTicketSupply(e.target.value)} placeholder='100' className='input-field' min='1' @@ -126,7 +126,7 @@ export default function CreateTicket() { + disabled={isLoading || !ticketName || !address}> {isLoading ? ( diff --git a/packages/app/src/components/network-guard.tsx b/packages/app/src/components/network-guard.tsx index 4a23cc1..03100e9 100644 --- a/packages/app/src/components/network-guard.tsx +++ b/packages/app/src/components/network-guard.tsx @@ -6,19 +6,19 @@ import React, { useEffect, useRef } from 'react' export function NetworkGuard({ children }: { children: React.ReactNode }) { const { chain } = useAccount() const { switchChain, isPending, error } = useSwitchChain() - const { Add } = useNotifications() + const { addNotification } = useNotifications() const notifiedRef = useRef(null) useEffect(() => { if (chain && chain.id !== sepolia.id) { if (notifiedRef.current !== chain.id) { - Add('You are connected to the wrong network. Please switch to Sepolia.', { type: 'warning' }) + addNotification('You are connected to the wrong network. Please switch to Sepolia.', { type: 'warning' }) notifiedRef.current = chain.id } } else { notifiedRef.current = null // Reset if on correct network } - }, [chain, Add]) + }, [chain, addNotification]) if (chain && chain.id !== sepolia.id) { return ( diff --git a/packages/app/src/context/notifications.tsx b/packages/app/src/context/notifications.tsx index 6fc2e91..cd79f5e 100644 --- a/packages/app/src/context/notifications.tsx +++ b/packages/app/src/context/notifications.tsx @@ -12,14 +12,14 @@ import { StatusIcon } from '@/components/alert' type NotificationOptions = Partial> interface NotificationContext { - Add: (message: string, options?: NotificationOptions) => void - Clear: () => void + addNotification: (message: string, options?: NotificationOptions) => void + clearNotifications: () => void notifications: Notification[] } const defaultNotificationContext: NotificationContext = { - Add: () => {}, - Clear: () => {}, + addNotification: () => {}, + clearNotifications: () => {}, notifications: [], } @@ -45,7 +45,7 @@ export function NotificationProvider(props: PropsWithChildren) { } }, []) - function Add(message: string, options?: NotificationOptions) { + function addNotification(message: string, options?: NotificationOptions) { const notification: Notification = { message, type: options?.type || 'info', @@ -58,13 +58,13 @@ export function NotificationProvider(props: PropsWithChildren) { toast(message, { type: notification.type, icon: }) } - function Clear() { + function clearNotifications() { localStorage.removeItem('notifications') setNotifications([]) } return ( - + {props.children} ( { @@ -59,7 +59,7 @@ export function useAvailableTickets( chain ) if (details) { - results.push({ + fetchedTickets.push({ id, name: details[1] || 'Unknown Ticket', price: details[2] || BigInt(0), @@ -69,7 +69,7 @@ export function useAvailableTickets( }) } } - setTickets(results) + setTickets(fetchedTickets) } catch (_err) { setError('Failed to load tickets') } finally { diff --git a/packages/app/src/hooks/tickets/useBuyTicket.ts b/packages/app/src/hooks/tickets/useBuyTicket.ts index 16cc5fb..10c5876 100644 --- a/packages/app/src/hooks/tickets/useBuyTicket.ts +++ b/packages/app/src/hooks/tickets/useBuyTicket.ts @@ -33,11 +33,11 @@ import { useTransactionNotifications } from '@/hooks/web3/useTransactionNotifica * ``` */ export function useBuyTicket(contractAddress: `0x${string}`) { - const { data: buyTxData, writeContract } = useWriteContract() - const { isLoading, error, isSuccess } = useWaitForTransactionReceipt({ hash: buyTxData }) + const { data: buyTransactionHash, writeContract } = useWriteContract() + const { isLoading, error, isSuccess } = useWaitForTransactionReceipt({ hash: buyTransactionHash }) // Use centralized notification handling - useTransactionNotifications(buyTxData, isSuccess, error, { + useTransactionNotifications(buyTransactionHash, isSuccess, error, { successMessage: 'Successfully purchased ticket!', errorMessagePrefix: 'Failed to purchase ticket', includeExplorerLink: true, diff --git a/packages/app/src/hooks/tickets/useOwnedTickets.ts b/packages/app/src/hooks/tickets/useOwnedTickets.ts index c793431..abd2d9f 100644 --- a/packages/app/src/hooks/tickets/useOwnedTickets.ts +++ b/packages/app/src/hooks/tickets/useOwnedTickets.ts @@ -45,13 +45,13 @@ export function useOwnedTickets( const [loading, setLoading] = useState(false) const [error, setError] = useState(null) - const fetchOwned = useCallback(async () => { + const fetchOwnedTickets = useCallback(async () => { if (!address || !chain) return setLoading(true) setError(null) try { - const owned: OwnedTicket[] = [] + const ownedTicketsList: OwnedTicket[] = [] for (const id of ticketIds) { try { @@ -81,7 +81,7 @@ export function useOwnedTickets( // The second element (index 1) is the name const name = ticketDetails[1] - owned.push({ + ownedTicketsList.push({ id, name: name || `Ticket #${id.toString()}`, quantity: balance, @@ -94,7 +94,7 @@ export function useOwnedTickets( } } - setOwnedTickets(owned) + setOwnedTickets(ownedTicketsList) } catch (err) { if (process.env.NODE_ENV === 'development') { console.error('Error fetching owned tickets:', err) @@ -106,15 +106,15 @@ export function useOwnedTickets( }, [contractAddress, address, ticketIds, chain]) useEffect(() => { - if (contractAddress && address && ticketIds.length > 0 && chain) fetchOwned() - }, [contractAddress, address, ticketIds, chain, fetchOwned, refreshKey]) + if (contractAddress && address && ticketIds.length > 0 && chain) fetchOwnedTickets() + }, [contractAddress, address, ticketIds, chain, fetchOwnedTickets, refreshKey]) const refetch = useCallback(() => { if (contractAddress && address && ticketIds.length > 0 && chain) { - return fetchOwned() + return fetchOwnedTickets() } return Promise.resolve() - }, [contractAddress, address, ticketIds, chain, fetchOwned]) + }, [contractAddress, address, ticketIds, chain, fetchOwnedTickets]) return { ownedTickets, diff --git a/packages/app/src/hooks/tickets/useTicketIds.ts b/packages/app/src/hooks/tickets/useTicketIds.ts index 432dcf3..9e194b0 100644 --- a/packages/app/src/hooks/tickets/useTicketIds.ts +++ b/packages/app/src/hooks/tickets/useTicketIds.ts @@ -58,7 +58,7 @@ export function useTicketIds( setLoading(true) setError(null) try { - const ids: bigint[] = [] + const fetchedTicketIds: bigint[] = [] const safeLength = Math.min(Number(ticketIdsLength), 100) for (let i = 0; i < safeLength; i++) { try { @@ -71,12 +71,12 @@ export function useTicketIds( }, chain ) - if (id) ids.push(id) + if (id) fetchedTicketIds.push(id) } catch (_) { // Continue to next ID } } - setTicketIds(ids) + setTicketIds(fetchedTicketIds) } catch (_err) { setError('Failed to load ticket IDs') } finally { diff --git a/packages/app/src/hooks/web3/useTransactionNotifications.ts b/packages/app/src/hooks/web3/useTransactionNotifications.ts index 5c8d50e..10d15fb 100644 --- a/packages/app/src/hooks/web3/useTransactionNotifications.ts +++ b/packages/app/src/hooks/web3/useTransactionNotifications.ts @@ -40,7 +40,7 @@ export function useTransactionNotifications( error: Error | null, options: TransactionNotificationOptions ) { - const { Add } = useNotifications() + const { addNotification } = useNotifications() const { chain } = useAccount() // Track which transaction hash we've notified about @@ -61,7 +61,7 @@ export function useTransactionNotifications( const explorerUrl = chain?.blockExplorers?.default.url const shouldIncludeLink = options.includeExplorerLink && explorerUrl - Add(options.successMessage, { + addNotification(options.successMessage, { type: 'success', href: shouldIncludeLink ? `${explorerUrl}/tx/${txHash}` : undefined, }) @@ -69,7 +69,7 @@ export function useTransactionNotifications( notifiedTxHashRef.current = txHash notifiedErrorRef.current = false } - }, [isSuccess, txHash, Add, options.successMessage, options.includeExplorerLink, chain]) + }, [isSuccess, txHash, addNotification, options.successMessage, options.includeExplorerLink, chain]) // Handle error notification useEffect(() => { @@ -77,11 +77,11 @@ export function useTransactionNotifications( const errorPrefix = options.errorMessagePrefix || 'Transaction failed' const errorMessage = error.message || 'Unknown error' - Add(`${errorPrefix}: ${errorMessage}`, { + addNotification(`${errorPrefix}: ${errorMessage}`, { type: 'error', }) notifiedErrorRef.current = true } - }, [error, Add, options.errorMessagePrefix]) + }, [error, addNotification, options.errorMessagePrefix]) } diff --git a/packages/app/src/hooks/web3/useTransactionState.ts b/packages/app/src/hooks/web3/useTransactionState.ts index dc67425..ae78ec3 100644 --- a/packages/app/src/hooks/web3/useTransactionState.ts +++ b/packages/app/src/hooks/web3/useTransactionState.ts @@ -49,7 +49,7 @@ export function useTransactionState( const [isTransactionSuccess, setIsTransactionSuccess] = useState(false) const [transactionError, setTransactionError] = useState(null) const [transactionHash, setTransactionHash] = useState<`0x${string}` | undefined>() - const { Add } = useNotifications() + const { addNotification } = useNotifications() const { isLoading: txLoading, error: txError, isSuccess: txSuccess } = useWaitForTransactionReceipt({ hash: txData }) @@ -58,17 +58,17 @@ export function useTransactionState( if (txSuccess) { setIsTransactionSuccess(true) setTransactionHash(txData) - Add(`Transaction successful`, { + addNotification(`Transaction successful`, { type: 'success', href: chain?.blockExplorers?.default.url ? `${chain.blockExplorers.default.url}/tx/${txData}` : undefined, }) } else if (txError) { setTransactionError(txError) - Add(`Transaction failed: ${txError.cause}`, { + addNotification(`Transaction failed: ${txError.cause}`, { type: 'error', }) } - }, [txSuccess, txError, txLoading, txData, Add, chain]) + }, [txSuccess, txError, txLoading, txData, addNotification, chain]) const resetTransactionState = () => { setIsTransactionLoading(false) diff --git a/packages/app/src/services/contract/contractService.ts b/packages/app/src/services/contract/contractService.ts index 4f3f887..ee5c193 100644 --- a/packages/app/src/services/contract/contractService.ts +++ b/packages/app/src/services/contract/contractService.ts @@ -52,8 +52,8 @@ export async function readContract( // If we have retries left, wait and try again if (retries > 0) { // Exponential backoff: wait longer on each retry - const delay = (4 - retries) * 1000 // 1s, 2s, 3s - await new Promise((resolve) => setTimeout(resolve, delay)) + const retryDelayMs = (4 - retries) * 1000 // 1s, 2s, 3s + await new Promise((resolve) => setTimeout(resolve, retryDelayMs)) if (process.env.NODE_ENV === 'development') { console.warn(`Contract read failed, retrying... (${retries} attempts remaining)`) diff --git a/packages/hardhat/test/TicketContract.test.ts b/packages/hardhat/test/TicketContract.test.ts index 2d29b4b..df91b68 100644 --- a/packages/hardhat/test/TicketContract.test.ts +++ b/packages/hardhat/test/TicketContract.test.ts @@ -3,7 +3,7 @@ import { expect } from 'chai' import hre from 'hardhat' describe('TicketContract', function () { - async function deployMessageFixture() { + async function deployTicketContractFixture() { const ethers = hre.ethers const [contractOwner, alice, bob] = await ethers.getSigners() @@ -15,7 +15,7 @@ describe('TicketContract', function () { describe('Deployment', function () { it('Should have correct default owner', async function () { - const { ticketContract, contractOwner } = await loadFixture(deployMessageFixture) + const { ticketContract, contractOwner } = await loadFixture(deployTicketContractFixture) const owner = await ticketContract.owner() expect(owner).to.equal(contractOwner.address)