import React from 'react'; import { View, Text, Pressable } from 'react-native'; import { Image } from 'expo-image'; import Svg, { Path } from 'react-native-svg'; import type { TradeOffer as TradeOfferType, ASA, AlgorandAccount, ComponentSize } from '../types/algorand'; import { formatAddress, formatRelativeTime } from '../utils/format'; import { CopyButton } from '../ui/CopyButton'; import { SizeContainer } from '../ui/SizeContainer'; import { StatusBadge } from '../ui/StatusBadge'; function ArrowRightLeftIcon({ size = 20, color = '#a1a1aa' }: { size?: number; color?: string }) { return ( ); } function SwapIcon({ size = 20, color = '#a1a1aa' }: { size?: number; color?: string }) { return ( ); } function CheckIcon({ size = 16, color = '#fff' }: { size?: number; color?: string }) { return ( ); } function XIcon({ size = 16, color = '#fff' }: { size?: number; color?: string }) { return ( ); } function ClockIcon({ size = 16, color = '#a1a1aa' }: { size?: number; color?: string }) { return ( ); } function MessageIcon({ size = 16, color = '#a1a1aa' }: { size?: number; color?: string }) { return ( ); } // Helper to determine if something is an ASA function isASA(item: ASA | AlgorandAccount): item is ASA { return 'unitName' in item; } function AssetItem({ asset, imageUrl }: { asset: ASA | AlgorandAccount; imageUrl?: string }) { if (isASA(asset)) { const isNFT = asset.total === 1 && asset.decimals === 0; return ( {imageUrl && ( )} {asset.name} {asset.unitName} - #{asset.id} {asset.price !== undefined && ( ${asset.price} )} ); } // AlgorandAccount return ( ACC {formatAddress(asset.address)} ALGO Account ); } function AssetGroup({ title, assets }: { title: string; assets: (ASA | AlgorandAccount)[] }) { if (assets.length === 0) { return ( No assets ); } return ( {title} {assets.map((asset, index) => ( ))} ); } interface TradeOfferProps { data: TradeOfferType; showActions?: boolean; size?: ComponentSize; className?: string; currentUserAddress?: string; onAccept?: (offer: TradeOfferType) => void; onReject?: (offer: TradeOfferType) => void; } export function TradeOfferComponent({ data: offer, showActions = true, size = 'full', className, currentUserAddress, onAccept, onReject, }: TradeOfferProps) { const isExpired = new Date() > offer.expiresAt; const isRecipient = currentUserAddress ? offer.recipients.includes(currentUserAddress) : false; const canRespond = isRecipient && offer.status === 'pending' && !isExpired; const statusVariant = offer.status === 'pending' ? 'info' : offer.status === 'accepted' ? 'success' : offer.status === 'rejected' ? 'error' : 'neutral'; const isFullscreen = size === 'fullscreen'; return ( {/* Header */} {isRecipient ? 'Incoming Trade' : 'Trade Offer'} {isExpired && } {formatRelativeTime(offer.expiresAt)} From {formatAddress(offer.creator)} {/* Trade Content */} {/* Offering */} {/* Swap Icon */} {/* Requesting */} {/* Message */} {offer.message && ( {offer.message} )} {/* Action Buttons */} {showActions && canRespond && ( onReject?.(offer)} className="flex-1 flex-row items-center justify-center gap-2 py-2.5 px-4 rounded-xl bg-red-500/20" > Reject onAccept?.(offer)} className="flex-1 flex-row items-center justify-center gap-2 py-2.5 px-4 rounded-xl bg-green-600" > Accept )} ); }