/** * Self-fetching wrappers for algomd-rn display components. * * Each wrapper adds an optional self-fetch prop (appId, address, txId, etc.) * alongside the existing `data` prop. If `data` is provided, it renders * immediately. Otherwise, it fetches from algod via the hooks. */ import React from 'react' import type { ReactNode } from 'react' import type { ComponentSize } from '../types/algorand' import { LoadingSkeleton, ErrorState } from '../ui/DataStates' // Display components (internal names) import { Account as AccountDisplay } from './Account' import { ASAComponent } from './ASA' import { NFTListingComponent } from './NFTListing' import { NFDProfileComponent } from './NFDProfile' import { TransactionDetailsComponent } from './TransactionDetails' import { PollComponent } from './Poll' import { RaffleListingComponent } from './RaffleListing' import { AuctionListingComponent } from './AuctionListing' import { TradeOfferComponent } from './TradeOffer' // Hooks import { useAccountData, useASAData, useTransactionData, useNFDProfileData, usePollData, useRaffleData, useAuctionData, useNFTListingData, useTradeOfferData, } from '../hooks/useAlgomdData' // Types import type { AlgorandAccount, ASA as ASAType, NFTListing as NFTListingType, NFDProfile as NFDProfileType, TransactionDetails as TransactionDetailsType, Poll as PollType, RaffleListing as RaffleListingType, AuctionListing as AuctionListingType, TradeOffer as TradeOfferType, } from '../types/algorand' // --------------------------------------------------------------------------- // Shared fetcher wrapper // --------------------------------------------------------------------------- function FetcherWrapper({ name, isLoading, error, data, loadingFallback, errorFallback, children, }: { name: string isLoading: boolean error: Error | null data: unknown loadingFallback?: ReactNode errorFallback?: ReactNode children: ReactNode }) { if (isLoading) return <>{loadingFallback ?? } if (error || !data) return <>{errorFallback ?? } return <>{children} } // --------------------------------------------------------------------------- // Poll // --------------------------------------------------------------------------- type PollSelfFetchProps = { data?: PollType appId?: number showVoteButton?: boolean compact?: boolean size?: ComponentSize className?: string onVote?: (pollId: string, optionId: string) => void loadingFallback?: ReactNode errorFallback?: ReactNode } function PollFetcher({ appId, ...rest }: Omit & { appId: number }) { const { data, isLoading, error } = usePollData(appId) return ( {data && } ) } export function Poll(props: PollSelfFetchProps) { if (props.data) return if (props.appId != null) return return } // --------------------------------------------------------------------------- // RaffleListing // --------------------------------------------------------------------------- type RaffleListingSelfFetchProps = { data?: RaffleListingType appId?: number showEntryButton?: boolean size?: ComponentSize className?: string imageUrl?: string onEnter?: (raffle: RaffleListingType) => void loadingFallback?: ReactNode errorFallback?: ReactNode } function RaffleListingFetcher({ appId, ...rest }: Omit & { appId: number }) { const { data, isLoading, error } = useRaffleData(appId) return ( {data && } ) } export function RaffleListing(props: RaffleListingSelfFetchProps) { if (props.data) return if (props.appId != null) return return } // --------------------------------------------------------------------------- // AuctionListing // --------------------------------------------------------------------------- type AuctionListingSelfFetchProps = { data?: AuctionListingType appId?: number showBidButton?: boolean size?: ComponentSize className?: string imageUrl?: string onBid?: (auction: AuctionListingType) => void loadingFallback?: ReactNode errorFallback?: ReactNode } function AuctionListingFetcher({ appId, ...rest }: Omit & { appId: number }) { const { data, isLoading, error } = useAuctionData(appId) return ( {data && } ) } export function AuctionListing(props: AuctionListingSelfFetchProps) { if (props.data) return if (props.appId != null) return return } // --------------------------------------------------------------------------- // NFTListing // --------------------------------------------------------------------------- type NFTListingSelfFetchProps = { data?: NFTListingType appId?: number showPurchaseButton?: boolean size?: ComponentSize className?: string imageUrl?: string onPurchase?: (listing: NFTListingType) => void onFavorite?: (listing: NFTListingType) => void loadingFallback?: ReactNode errorFallback?: ReactNode } function NFTListingFetcher({ appId, ...rest }: Omit & { appId: number }) { const { data, isLoading, error } = useNFTListingData(appId) return ( {data && } ) } export function NFTListing(props: NFTListingSelfFetchProps) { if (props.data) return if (props.appId != null) return return } // --------------------------------------------------------------------------- // TradeOffer // --------------------------------------------------------------------------- type TradeOfferSelfFetchProps = { data?: TradeOfferType appId?: number offerId?: number showActions?: boolean size?: ComponentSize className?: string currentUserAddress?: string onAccept?: (offer: TradeOfferType) => void onReject?: (offer: TradeOfferType) => void loadingFallback?: ReactNode errorFallback?: ReactNode } function TradeOfferFetcher({ appId, offerId, ...rest }: Omit & { appId: number; offerId: number }) { const { data, isLoading, error } = useTradeOfferData(appId, offerId) return ( {data && } ) } export function TradeOffer(props: TradeOfferSelfFetchProps) { if (props.data) return if (props.appId != null && props.offerId != null) return return } // --------------------------------------------------------------------------- // Account // --------------------------------------------------------------------------- type AccountSelfFetchProps = { data?: AlgorandAccount address?: string showAssets?: boolean showApps?: boolean compact?: boolean size?: ComponentSize className?: string onExternalLink?: (address: string) => void loadingFallback?: ReactNode errorFallback?: ReactNode } function AccountFetcher({ address, ...rest }: Omit & { address: string }) { const { data, isLoading, error } = useAccountData(address) return ( {data && } ) } export function Account(props: AccountSelfFetchProps) { if (props.data) return if (props.address) return return } // --------------------------------------------------------------------------- // ASA // --------------------------------------------------------------------------- type ASASelfFetchProps = { data?: ASAType assetId?: number showDetails?: boolean compact?: boolean size?: ComponentSize className?: string imageUrl?: string loadingFallback?: ReactNode errorFallback?: ReactNode } function ASAFetcher({ assetId, ...rest }: Omit & { assetId: number }) { const { data, isLoading, error } = useASAData(assetId) return ( {data && } ) } export function ASA(props: ASASelfFetchProps) { if (props.data) return if (props.assetId != null) return return } // --------------------------------------------------------------------------- // TransactionDetails // --------------------------------------------------------------------------- type TransactionDetailsSelfFetchProps = { data?: TransactionDetailsType txId?: string showContext?: boolean showFee?: boolean compact?: boolean size?: ComponentSize className?: string loadingFallback?: ReactNode errorFallback?: ReactNode } function TransactionDetailsFetcher({ txId, ...rest }: Omit & { txId: string }) { const { data, isLoading, error } = useTransactionData(txId) return ( {data && } ) } export function TransactionDetails(props: TransactionDetailsSelfFetchProps) { if (props.data) return if (props.txId) return return } // --------------------------------------------------------------------------- // NFDProfile // --------------------------------------------------------------------------- type NFDProfileSelfFetchProps = { data?: NFDProfileType name?: string showBio?: boolean showProperties?: boolean compact?: boolean size?: ComponentSize className?: string loadingFallback?: ReactNode errorFallback?: ReactNode } function NFDProfileFetcher({ name, ...rest }: Omit & { name: string }) { const { data, isLoading, error } = useNFDProfileData(name) return ( {data && } ) } export function NFDProfile(props: NFDProfileSelfFetchProps) { if (props.data) return if (props.name) return return }