@medialane/ui 0.29.0 → 0.29.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/asset-marketplace-panel.tsx"],"sourcesContent":["\"use client\";\n\nimport type { ReactNode } from \"react\";\nimport {\n ArrowRightLeft, CheckCircle, Clock, GitBranch, HandCoins, Loader2,\n ShoppingCart, Tag, X,\n} from \"lucide-react\";\nimport { CurrencyIcon, CurrencyAmount } from \"./currency-icon.js\";\nimport { AddressDisplay } from \"./address-display.js\";\nimport { formatDisplayPrice, parsePriceDisplay } from \"../utils/format.js\";\nimport { timeUntil } from \"../utils/time.js\";\n\n/** Structural subset of `ApiOrder` (both apps' `@medialane/sdk` types satisfy this). */\nexport interface ApiOrderLike {\n orderHash: string;\n offerer: string;\n endTime: string;\n price: { formatted: string; currency: string | null };\n}\n\ninterface ActionButtonProps {\n label: string;\n icon: ReactNode;\n onClick: () => void;\n tone: \"blue\" | \"orange\" | \"purple\" | \"destructive\" | \"transparent\";\n disabled?: boolean;\n helpContent?: string;\n renderHelp: (content: string) => ReactNode;\n}\n\nconst actionToneClass: Record<ActionButtonProps[\"tone\"], string> = {\n blue: \"bg-brand-blue\",\n orange: \"bg-brand-orange\",\n purple: \"bg-brand-purple\",\n destructive: \"bg-destructive\",\n transparent: \"bg-transparent\",\n};\n\nfunction ActionButton({ label, icon, onClick, tone, disabled = false, helpContent, renderHelp }: ActionButtonProps) {\n return (\n <div className={`btn-border-animated p-[1px] rounded-2xl ${disabled ? \"opacity-40 pointer-events-none\" : \"\"}`}>\n <button\n className={`w-full h-10 rounded-[15px] flex items-center justify-center gap-2 px-3 text-sm font-semibold text-white transition-all hover:brightness-110 active:scale-[0.98] disabled:opacity-50 ${actionToneClass[tone]}`}\n disabled={disabled}\n onClick={onClick}\n >\n {icon}\n {label}\n {helpContent ? renderHelp(helpContent) : null}\n </button>\n </div>\n );\n}\n\nexport interface AssetMarketplacePanelProps {\n cheapest?: ApiOrderLike;\n isOwner: boolean;\n isSignedIn: boolean;\n isProcessing: boolean;\n isERC1155: boolean;\n isMarketLoading?: boolean;\n myListing: ApiOrderLike | null;\n activeBids: ApiOrderLike[];\n walletAddress?: string | null;\n remixEnabled?: boolean;\n showDealOption?: boolean;\n /** Raw \"0.07 STRK\"-style strings — already resolved by the caller. `null`/undefined renders \"—\". */\n floorPriceRaw?: string | null;\n lastSaleRaw?: string | null;\n /** Renders the sign-in/connect-wallet CTA for the given label (e.g. \"Sign in to trade\"). */\n renderAuthAction: (label: string) => ReactNode;\n /** Renders an inline help/info affordance for the given tooltip text. */\n renderHelp: (content: string) => ReactNode;\n onCancelClick: (order: ApiOrderLike) => void;\n onAcceptBid: (order: ApiOrderLike) => void;\n onOpenListing: () => void;\n onOpenTransfer: () => void;\n onOpenPurchase: (order: ApiOrderLike) => void;\n onOpenOffer: () => void;\n onOpenRemix?: () => void;\n onProposeDeal?: () => void;\n}\n\nfunction StatRow({ floorPriceRaw, lastSaleRaw }: { floorPriceRaw?: string | null; lastSaleRaw?: string | null }) {\n if (!floorPriceRaw && !lastSaleRaw) return null;\n const floor = floorPriceRaw ? parsePriceDisplay(floorPriceRaw) : null;\n const lastSale = lastSaleRaw ? parsePriceDisplay(lastSaleRaw) : null;\n return (\n <div className=\"flex items-center gap-4 text-xs text-muted-foreground\">\n <span className=\"flex items-center gap-1.5\">\n <span className=\"uppercase tracking-wider font-semibold\">Floor</span>\n {floor && floor.symbol ? (\n <CurrencyAmount amount={floor.numStr} symbol={floor.symbol} iconSize={12} amountClassName=\"text-foreground font-semibold\" />\n ) : (\n <span className=\"text-foreground font-semibold\">—</span>\n )}\n </span>\n <span className=\"flex items-center gap-1.5\">\n <span className=\"uppercase tracking-wider font-semibold\">Last sale</span>\n {lastSale && lastSale.symbol ? (\n <CurrencyAmount amount={lastSale.numStr} symbol={lastSale.symbol} iconSize={12} amountClassName=\"text-foreground font-semibold\" />\n ) : (\n <span className=\"text-foreground font-semibold\">—</span>\n )}\n </span>\n </div>\n );\n}\n\nexport function AssetMarketplacePanel({\n cheapest,\n isOwner,\n isSignedIn,\n isProcessing,\n isERC1155,\n isMarketLoading = false,\n myListing,\n activeBids,\n walletAddress,\n remixEnabled = false,\n showDealOption = false,\n floorPriceRaw,\n lastSaleRaw,\n renderAuthAction,\n renderHelp,\n onCancelClick,\n onAcceptBid,\n onOpenListing,\n onOpenTransfer,\n onOpenPurchase,\n onOpenOffer,\n onOpenRemix,\n onProposeDeal,\n}: AssetMarketplacePanelProps) {\n const myBid = !isOwner && walletAddress\n ? activeBids.find((bid) => bid.offerer.toLowerCase() === walletAddress.toLowerCase()) ?? null\n : null;\n\n const canBuyMore =\n isERC1155 && isOwner && !!cheapest && !!walletAddress &&\n cheapest.offerer.toLowerCase() !== walletAddress.toLowerCase();\n\n if (isMarketLoading && !cheapest) {\n return (\n <div className=\"space-y-4\">\n <div className=\"h-9 w-32 rounded-md bg-muted animate-pulse\" />\n <div className=\"h-12 w-full rounded-2xl bg-muted animate-pulse\" />\n </div>\n );\n }\n\n return (\n <div className=\"relative\">\n {/* soft brand light-leak behind the trade zone — no hard border, per §III */}\n <div\n aria-hidden\n className=\"aurora-purple pointer-events-none\"\n style={{ position: \"absolute\", width: 280, height: 280, top: -60, left: \"20%\" }}\n />\n <div className=\"relative space-y-4\">\n {cheapest ? (\n <div className=\"space-y-4\">\n <div className=\"flex items-baseline gap-2\">\n <CurrencyIcon symbol={cheapest.price.currency ?? \"\"} size={26} />\n <span className=\"text-4xl font-bold tracking-tight\">\n {formatDisplayPrice(cheapest.price.formatted)}\n </span>\n {renderHelp(\n `${isOwner && !canBuyMore ? \"Your listing\" : \"Current price\"} · Expires ${timeUntil(cheapest.endTime)}`\n )}\n </div>\n\n <StatRow floorPriceRaw={floorPriceRaw} lastSaleRaw={lastSaleRaw} />\n\n {isOwner ? (\n <div className=\"space-y-2\">\n <div className=\"grid grid-cols-2 gap-2\">\n {myListing ? (\n <ActionButton\n label=\"Cancel\"\n icon={isProcessing ? <Loader2 className=\"h-4 w-4 animate-spin\" /> : <X className=\"h-4 w-4\" />}\n onClick={() => onCancelClick(myListing)}\n disabled={isProcessing}\n tone=\"destructive\"\n renderHelp={renderHelp}\n />\n ) : null}\n <ActionButton label=\"List\" icon={<Tag className=\"h-4 w-4\" />} onClick={onOpenListing} tone=\"blue\" renderHelp={renderHelp} />\n <ActionButton label=\"Transfer\" icon={<ArrowRightLeft className=\"h-4 w-4\" />} onClick={onOpenTransfer} tone=\"orange\" renderHelp={renderHelp} />\n {remixEnabled && onOpenRemix ? (\n <ActionButton\n label=\"Remix\"\n icon={<GitBranch className=\"h-4 w-4\" />}\n onClick={onOpenRemix}\n helpContent=\"Build a licensed derivative of this digital asset — your remix is minted as a new onchain NFT linked to the original\"\n tone=\"purple\"\n renderHelp={renderHelp}\n />\n ) : null}\n </div>\n\n {canBuyMore && (\n <>\n <div className=\"border-t border-border/40 pt-2 mt-1\" />\n <div className=\"grid grid-cols-2 gap-2\">\n <ActionButton label=\"Buy\" icon={<ShoppingCart className=\"h-4 w-4\" />} onClick={() => onOpenPurchase(cheapest!)} tone=\"transparent\" renderHelp={renderHelp} />\n <ActionButton label=\"Make offer\" icon={<HandCoins className=\"h-4 w-4\" />} onClick={onOpenOffer} tone=\"orange\" renderHelp={renderHelp} />\n </div>\n </>\n )}\n </div>\n ) : isSignedIn ? (\n <>\n <div className=\"grid grid-cols-2 gap-2\">\n <ActionButton label=\"Buy\" icon={<ShoppingCart className=\"h-4 w-4\" />} onClick={() => onOpenPurchase(cheapest)} tone=\"transparent\" renderHelp={renderHelp} />\n <ActionButton label=\"Make offer\" icon={<HandCoins className=\"h-4 w-4\" />} onClick={onOpenOffer} tone=\"orange\" renderHelp={renderHelp} />\n {remixEnabled && onOpenRemix ? (\n <ActionButton\n label=\"Remix\"\n icon={<GitBranch className=\"h-4 w-4\" />}\n onClick={onOpenRemix}\n helpContent=\"Create your own attributed derivative of this work.\"\n tone=\"purple\"\n renderHelp={renderHelp}\n />\n ) : null}\n {showDealOption && onProposeDeal ? (\n <ActionButton\n label=\"License\"\n icon={<HandCoins className=\"h-4 w-4\" />}\n onClick={onProposeDeal}\n helpContent=\"Propose a license deal to the creator to use this work.\"\n tone=\"blue\"\n renderHelp={renderHelp}\n />\n ) : null}\n </div>\n {!remixEnabled && !showDealOption ? (\n <p className=\"text-xs text-muted-foreground mt-2 leading-relaxed\">\n The creator marked this asset as no-derivatives.\n </p>\n ) : null}\n </>\n ) : (\n renderAuthAction(\"Sign in to trade\")\n )}\n </div>\n ) : (\n <div className=\"space-y-3\">\n <StatRow floorPriceRaw={floorPriceRaw} lastSaleRaw={lastSaleRaw} />\n {isOwner ? (\n <div className=\"grid grid-cols-2 gap-2\">\n <ActionButton label=\"List\" icon={<Tag className=\"h-4 w-4\" />} onClick={onOpenListing} tone=\"transparent\" renderHelp={renderHelp} />\n <ActionButton label=\"Transfer\" icon={<ArrowRightLeft className=\"h-4 w-4\" />} onClick={onOpenTransfer} tone=\"orange\" renderHelp={renderHelp} />\n {remixEnabled && onOpenRemix ? (\n <ActionButton\n label=\"Remix\"\n icon={<GitBranch className=\"h-4 w-4\" />}\n onClick={onOpenRemix}\n helpContent=\"Build a licensed derivative of this digital asset — your remix is minted as a new onchain NFT linked to the original\"\n tone=\"purple\"\n renderHelp={renderHelp}\n />\n ) : null}\n </div>\n ) : isSignedIn ? (\n <div className=\"grid grid-cols-2 gap-2\">\n <ActionButton label=\"Make offer\" icon={<HandCoins className=\"h-4 w-4\" />} onClick={onOpenOffer} tone=\"orange\" renderHelp={renderHelp} />\n {remixEnabled && onOpenRemix ? (\n <ActionButton\n label=\"Remix\"\n icon={<GitBranch className=\"h-4 w-4\" />}\n onClick={onOpenRemix}\n helpContent=\"Build a licensed derivative of this digital asset — your remix is minted as a new onchain NFT linked to the original\"\n tone=\"purple\"\n renderHelp={renderHelp}\n />\n ) : null}\n </div>\n ) : (\n renderAuthAction(\"Sign in to make an offer\")\n )}\n </div>\n )}\n\n {myBid ? (\n <div className=\"rounded-xl bg-amber-500/8 px-4 py-3 flex items-center justify-between gap-3\">\n <div className=\"min-w-0 flex items-center gap-2.5\">\n <HandCoins className=\"h-4 w-4 text-amber-500 shrink-0\" />\n <div className=\"min-w-0\">\n <p className=\"text-xs font-semibold text-amber-500\">Your active offer</p>\n <p className=\"text-xs text-muted-foreground flex items-center gap-1.5 mt-0.5\">\n <span className=\"font-bold text-foreground inline-flex items-center gap-1\">\n {formatDisplayPrice(myBid.price.formatted)}\n <CurrencyIcon symbol={myBid.price.currency ?? \"\"} size={12} />\n </span>\n <span>·</span>\n <Clock className=\"h-3 w-3\" />\n {timeUntil(myBid.endTime)}\n </p>\n </div>\n </div>\n <button\n className=\"shrink-0 text-xs font-semibold text-red-400 hover:text-red-300 transition-colors flex items-center gap-1\"\n onClick={() => onCancelClick(myBid)}\n >\n <X className=\"h-3.5 w-3.5\" />\n Cancel\n </button>\n </div>\n ) : null}\n\n {isOwner && activeBids.length > 0 ? (\n <div className=\"rounded-xl bg-card/40 p-5 space-y-3\">\n <p className=\"text-xs font-semibold uppercase tracking-wider text-muted-foreground\">\n Incoming offers ({activeBids.length})\n </p>\n <div className=\"space-y-2\">\n {activeBids.map((bid) => (\n <div key={bid.orderHash} className=\"flex items-center justify-between gap-3 rounded-lg bg-muted/30 px-3 py-2\">\n <div className=\"min-w-0\">\n <p className=\"text-sm font-bold\">\n <span className=\"inline-flex items-center gap-1.5\">\n {formatDisplayPrice(bid.price.formatted)}\n <CurrencyIcon symbol={bid.price.currency ?? \"\"} size={14} />\n </span>\n </p>\n <div className=\"flex items-center gap-2 mt-0.5\">\n <AddressDisplay address={bid.offerer} chars={4} showCopy={false} className=\"text-xs text-muted-foreground\" />\n <span className=\"text-xs text-muted-foreground\">·</span>\n <div className=\"flex items-center gap-1 text-xs text-muted-foreground\">\n <Clock className=\"h-3 w-3\" />\n {timeUntil(bid.endTime)}\n </div>\n </div>\n </div>\n <button\n disabled={isProcessing}\n onClick={() => onAcceptBid(bid)}\n className=\"inline-flex items-center gap-1.5 rounded-lg bg-primary px-3 py-1.5 text-xs font-semibold text-primary-foreground disabled:opacity-50\"\n >\n <CheckCircle className=\"h-3.5 w-3.5\" />\n Accept\n </button>\n </div>\n ))}\n </div>\n </div>\n ) : null}\n </div>\n </div>\n );\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/components/asset-marketplace-panel.tsx"],"sourcesContent":["\"use client\";\n\nimport type { ReactNode } from \"react\";\nimport {\n ArrowRightLeft, CheckCircle, Clock, GitBranch, HandCoins, Loader2,\n ShoppingCart, Tag, X,\n} from \"lucide-react\";\nimport { CurrencyIcon, CurrencyAmount } from \"./currency-icon.js\";\nimport { AddressDisplay } from \"./address-display.js\";\nimport { formatDisplayPrice, parsePriceDisplay } from \"../utils/format.js\";\nimport { timeUntil } from \"../utils/time.js\";\n\n/** Structural subset of `ApiOrder` (both apps' `@medialane/sdk` types satisfy this). */\nexport interface ApiOrderLike {\n orderHash: string;\n offerer: string;\n endTime: string;\n price: { formatted: string | null; currency: string | null };\n}\n\ninterface ActionButtonProps {\n label: string;\n icon: ReactNode;\n onClick: () => void;\n tone: \"blue\" | \"orange\" | \"purple\" | \"destructive\" | \"transparent\";\n disabled?: boolean;\n helpContent?: string;\n renderHelp: (content: string) => ReactNode;\n}\n\nconst actionToneClass: Record<ActionButtonProps[\"tone\"], string> = {\n blue: \"bg-brand-blue\",\n orange: \"bg-brand-orange\",\n purple: \"bg-brand-purple\",\n destructive: \"bg-destructive\",\n transparent: \"bg-transparent\",\n};\n\nfunction ActionButton({ label, icon, onClick, tone, disabled = false, helpContent, renderHelp }: ActionButtonProps) {\n return (\n <div className={`btn-border-animated p-[1px] rounded-2xl ${disabled ? \"opacity-40 pointer-events-none\" : \"\"}`}>\n <button\n className={`w-full h-10 rounded-[15px] flex items-center justify-center gap-2 px-3 text-sm font-semibold text-white transition-all hover:brightness-110 active:scale-[0.98] disabled:opacity-50 ${actionToneClass[tone]}`}\n disabled={disabled}\n onClick={onClick}\n >\n {icon}\n {label}\n {helpContent ? renderHelp(helpContent) : null}\n </button>\n </div>\n );\n}\n\nexport interface AssetMarketplacePanelProps {\n cheapest?: ApiOrderLike;\n isOwner: boolean;\n isSignedIn: boolean;\n isProcessing: boolean;\n isERC1155: boolean;\n isMarketLoading?: boolean;\n myListing: ApiOrderLike | null;\n activeBids: ApiOrderLike[];\n walletAddress?: string | null;\n remixEnabled?: boolean;\n showDealOption?: boolean;\n /** Raw \"0.07 STRK\"-style strings — already resolved by the caller. `null`/undefined renders \"—\". */\n floorPriceRaw?: string | null;\n lastSaleRaw?: string | null;\n /** Renders the sign-in/connect-wallet CTA for the given label (e.g. \"Sign in to trade\"). */\n renderAuthAction: (label: string) => ReactNode;\n /** Renders an inline help/info affordance for the given tooltip text. */\n renderHelp: (content: string) => ReactNode;\n onCancelClick: (order: ApiOrderLike) => void;\n onAcceptBid: (order: ApiOrderLike) => void;\n onOpenListing: () => void;\n onOpenTransfer: () => void;\n onOpenPurchase: (order: ApiOrderLike) => void;\n onOpenOffer: () => void;\n onOpenRemix?: () => void;\n onProposeDeal?: () => void;\n}\n\nfunction StatRow({ floorPriceRaw, lastSaleRaw }: { floorPriceRaw?: string | null; lastSaleRaw?: string | null }) {\n if (!floorPriceRaw && !lastSaleRaw) return null;\n const floor = floorPriceRaw ? parsePriceDisplay(floorPriceRaw) : null;\n const lastSale = lastSaleRaw ? parsePriceDisplay(lastSaleRaw) : null;\n return (\n <div className=\"flex items-center gap-4 text-xs text-muted-foreground\">\n <span className=\"flex items-center gap-1.5\">\n <span className=\"uppercase tracking-wider font-semibold\">Floor</span>\n {floor && floor.symbol ? (\n <CurrencyAmount amount={floor.numStr} symbol={floor.symbol} iconSize={12} amountClassName=\"text-foreground font-semibold\" />\n ) : (\n <span className=\"text-foreground font-semibold\">—</span>\n )}\n </span>\n <span className=\"flex items-center gap-1.5\">\n <span className=\"uppercase tracking-wider font-semibold\">Last sale</span>\n {lastSale && lastSale.symbol ? (\n <CurrencyAmount amount={lastSale.numStr} symbol={lastSale.symbol} iconSize={12} amountClassName=\"text-foreground font-semibold\" />\n ) : (\n <span className=\"text-foreground font-semibold\">—</span>\n )}\n </span>\n </div>\n );\n}\n\nexport function AssetMarketplacePanel({\n cheapest,\n isOwner,\n isSignedIn,\n isProcessing,\n isERC1155,\n isMarketLoading = false,\n myListing,\n activeBids,\n walletAddress,\n remixEnabled = false,\n showDealOption = false,\n floorPriceRaw,\n lastSaleRaw,\n renderAuthAction,\n renderHelp,\n onCancelClick,\n onAcceptBid,\n onOpenListing,\n onOpenTransfer,\n onOpenPurchase,\n onOpenOffer,\n onOpenRemix,\n onProposeDeal,\n}: AssetMarketplacePanelProps) {\n const myBid = !isOwner && walletAddress\n ? activeBids.find((bid) => bid.offerer.toLowerCase() === walletAddress.toLowerCase()) ?? null\n : null;\n\n const canBuyMore =\n isERC1155 && isOwner && !!cheapest && !!walletAddress &&\n cheapest.offerer.toLowerCase() !== walletAddress.toLowerCase();\n\n if (isMarketLoading && !cheapest) {\n return (\n <div className=\"space-y-4\">\n <div className=\"h-9 w-32 rounded-md bg-muted animate-pulse\" />\n <div className=\"h-12 w-full rounded-2xl bg-muted animate-pulse\" />\n </div>\n );\n }\n\n return (\n <div className=\"relative\">\n {/* soft brand light-leak behind the trade zone — no hard border, per §III */}\n <div\n aria-hidden\n className=\"aurora-purple pointer-events-none\"\n style={{ position: \"absolute\", width: 280, height: 280, top: -60, left: \"20%\" }}\n />\n <div className=\"relative space-y-4\">\n {cheapest ? (\n <div className=\"space-y-4\">\n <div className=\"flex items-baseline gap-2\">\n <CurrencyIcon symbol={cheapest.price.currency ?? \"\"} size={26} />\n <span className=\"text-4xl font-bold tracking-tight\">\n {formatDisplayPrice(cheapest.price.formatted)}\n </span>\n {renderHelp(\n `${isOwner && !canBuyMore ? \"Your listing\" : \"Current price\"} · Expires ${timeUntil(cheapest.endTime)}`\n )}\n </div>\n\n <StatRow floorPriceRaw={floorPriceRaw} lastSaleRaw={lastSaleRaw} />\n\n {isOwner ? (\n <div className=\"space-y-2\">\n <div className=\"grid grid-cols-2 gap-2\">\n {myListing ? (\n <ActionButton\n label=\"Cancel\"\n icon={isProcessing ? <Loader2 className=\"h-4 w-4 animate-spin\" /> : <X className=\"h-4 w-4\" />}\n onClick={() => onCancelClick(myListing)}\n disabled={isProcessing}\n tone=\"destructive\"\n renderHelp={renderHelp}\n />\n ) : null}\n <ActionButton label=\"List\" icon={<Tag className=\"h-4 w-4\" />} onClick={onOpenListing} tone=\"blue\" renderHelp={renderHelp} />\n <ActionButton label=\"Transfer\" icon={<ArrowRightLeft className=\"h-4 w-4\" />} onClick={onOpenTransfer} tone=\"orange\" renderHelp={renderHelp} />\n {remixEnabled && onOpenRemix ? (\n <ActionButton\n label=\"Remix\"\n icon={<GitBranch className=\"h-4 w-4\" />}\n onClick={onOpenRemix}\n helpContent=\"Build a licensed derivative of this digital asset — your remix is minted as a new onchain NFT linked to the original\"\n tone=\"purple\"\n renderHelp={renderHelp}\n />\n ) : null}\n </div>\n\n {canBuyMore && (\n <>\n <div className=\"border-t border-border/40 pt-2 mt-1\" />\n <div className=\"grid grid-cols-2 gap-2\">\n <ActionButton label=\"Buy\" icon={<ShoppingCart className=\"h-4 w-4\" />} onClick={() => onOpenPurchase(cheapest!)} tone=\"transparent\" renderHelp={renderHelp} />\n <ActionButton label=\"Make offer\" icon={<HandCoins className=\"h-4 w-4\" />} onClick={onOpenOffer} tone=\"orange\" renderHelp={renderHelp} />\n </div>\n </>\n )}\n </div>\n ) : isSignedIn ? (\n <>\n <div className=\"grid grid-cols-2 gap-2\">\n <ActionButton label=\"Buy\" icon={<ShoppingCart className=\"h-4 w-4\" />} onClick={() => onOpenPurchase(cheapest)} tone=\"transparent\" renderHelp={renderHelp} />\n <ActionButton label=\"Make offer\" icon={<HandCoins className=\"h-4 w-4\" />} onClick={onOpenOffer} tone=\"orange\" renderHelp={renderHelp} />\n {remixEnabled && onOpenRemix ? (\n <ActionButton\n label=\"Remix\"\n icon={<GitBranch className=\"h-4 w-4\" />}\n onClick={onOpenRemix}\n helpContent=\"Create your own attributed derivative of this work.\"\n tone=\"purple\"\n renderHelp={renderHelp}\n />\n ) : null}\n {showDealOption && onProposeDeal ? (\n <ActionButton\n label=\"License\"\n icon={<HandCoins className=\"h-4 w-4\" />}\n onClick={onProposeDeal}\n helpContent=\"Propose a license deal to the creator to use this work.\"\n tone=\"blue\"\n renderHelp={renderHelp}\n />\n ) : null}\n </div>\n {!remixEnabled && !showDealOption ? (\n <p className=\"text-xs text-muted-foreground mt-2 leading-relaxed\">\n The creator marked this asset as no-derivatives.\n </p>\n ) : null}\n </>\n ) : (\n renderAuthAction(\"Sign in to trade\")\n )}\n </div>\n ) : (\n <div className=\"space-y-3\">\n <StatRow floorPriceRaw={floorPriceRaw} lastSaleRaw={lastSaleRaw} />\n {isOwner ? (\n <div className=\"grid grid-cols-2 gap-2\">\n <ActionButton label=\"List\" icon={<Tag className=\"h-4 w-4\" />} onClick={onOpenListing} tone=\"transparent\" renderHelp={renderHelp} />\n <ActionButton label=\"Transfer\" icon={<ArrowRightLeft className=\"h-4 w-4\" />} onClick={onOpenTransfer} tone=\"orange\" renderHelp={renderHelp} />\n {remixEnabled && onOpenRemix ? (\n <ActionButton\n label=\"Remix\"\n icon={<GitBranch className=\"h-4 w-4\" />}\n onClick={onOpenRemix}\n helpContent=\"Build a licensed derivative of this digital asset — your remix is minted as a new onchain NFT linked to the original\"\n tone=\"purple\"\n renderHelp={renderHelp}\n />\n ) : null}\n </div>\n ) : isSignedIn ? (\n <div className=\"grid grid-cols-2 gap-2\">\n <ActionButton label=\"Make offer\" icon={<HandCoins className=\"h-4 w-4\" />} onClick={onOpenOffer} tone=\"orange\" renderHelp={renderHelp} />\n {remixEnabled && onOpenRemix ? (\n <ActionButton\n label=\"Remix\"\n icon={<GitBranch className=\"h-4 w-4\" />}\n onClick={onOpenRemix}\n helpContent=\"Build a licensed derivative of this digital asset — your remix is minted as a new onchain NFT linked to the original\"\n tone=\"purple\"\n renderHelp={renderHelp}\n />\n ) : null}\n </div>\n ) : (\n renderAuthAction(\"Sign in to make an offer\")\n )}\n </div>\n )}\n\n {myBid ? (\n <div className=\"rounded-xl bg-amber-500/8 px-4 py-3 flex items-center justify-between gap-3\">\n <div className=\"min-w-0 flex items-center gap-2.5\">\n <HandCoins className=\"h-4 w-4 text-amber-500 shrink-0\" />\n <div className=\"min-w-0\">\n <p className=\"text-xs font-semibold text-amber-500\">Your active offer</p>\n <p className=\"text-xs text-muted-foreground flex items-center gap-1.5 mt-0.5\">\n <span className=\"font-bold text-foreground inline-flex items-center gap-1\">\n {formatDisplayPrice(myBid.price.formatted)}\n <CurrencyIcon symbol={myBid.price.currency ?? \"\"} size={12} />\n </span>\n <span>·</span>\n <Clock className=\"h-3 w-3\" />\n {timeUntil(myBid.endTime)}\n </p>\n </div>\n </div>\n <button\n className=\"shrink-0 text-xs font-semibold text-red-400 hover:text-red-300 transition-colors flex items-center gap-1\"\n onClick={() => onCancelClick(myBid)}\n >\n <X className=\"h-3.5 w-3.5\" />\n Cancel\n </button>\n </div>\n ) : null}\n\n {isOwner && activeBids.length > 0 ? (\n <div className=\"rounded-xl bg-card/40 p-5 space-y-3\">\n <p className=\"text-xs font-semibold uppercase tracking-wider text-muted-foreground\">\n Incoming offers ({activeBids.length})\n </p>\n <div className=\"space-y-2\">\n {activeBids.map((bid) => (\n <div key={bid.orderHash} className=\"flex items-center justify-between gap-3 rounded-lg bg-muted/30 px-3 py-2\">\n <div className=\"min-w-0\">\n <p className=\"text-sm font-bold\">\n <span className=\"inline-flex items-center gap-1.5\">\n {formatDisplayPrice(bid.price.formatted)}\n <CurrencyIcon symbol={bid.price.currency ?? \"\"} size={14} />\n </span>\n </p>\n <div className=\"flex items-center gap-2 mt-0.5\">\n <AddressDisplay address={bid.offerer} chars={4} showCopy={false} className=\"text-xs text-muted-foreground\" />\n <span className=\"text-xs text-muted-foreground\">·</span>\n <div className=\"flex items-center gap-1 text-xs text-muted-foreground\">\n <Clock className=\"h-3 w-3\" />\n {timeUntil(bid.endTime)}\n </div>\n </div>\n </div>\n <button\n disabled={isProcessing}\n onClick={() => onAcceptBid(bid)}\n className=\"inline-flex items-center gap-1.5 rounded-lg bg-primary px-3 py-1.5 text-xs font-semibold text-primary-foreground disabled:opacity-50\"\n >\n <CheckCircle className=\"h-3.5 w-3.5\" />\n Accept\n </button>\n </div>\n ))}\n </div>\n </div>\n ) : null}\n </div>\n </div>\n );\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/asset-marketplace-panel.tsx"],"sourcesContent":["\"use client\";\n\nimport type { ReactNode } from \"react\";\nimport {\n ArrowRightLeft, CheckCircle, Clock, GitBranch, HandCoins, Loader2,\n ShoppingCart, Tag, X,\n} from \"lucide-react\";\nimport { CurrencyIcon, CurrencyAmount } from \"./currency-icon.js\";\nimport { AddressDisplay } from \"./address-display.js\";\nimport { formatDisplayPrice, parsePriceDisplay } from \"../utils/format.js\";\nimport { timeUntil } from \"../utils/time.js\";\n\n/** Structural subset of `ApiOrder` (both apps' `@medialane/sdk` types satisfy this). */\nexport interface ApiOrderLike {\n orderHash: string;\n offerer: string;\n endTime: string;\n price: { formatted: string; currency: string | null };\n}\n\ninterface ActionButtonProps {\n label: string;\n icon: ReactNode;\n onClick: () => void;\n tone: \"blue\" | \"orange\" | \"purple\" | \"destructive\" | \"transparent\";\n disabled?: boolean;\n helpContent?: string;\n renderHelp: (content: string) => ReactNode;\n}\n\nconst actionToneClass: Record<ActionButtonProps[\"tone\"], string> = {\n blue: \"bg-brand-blue\",\n orange: \"bg-brand-orange\",\n purple: \"bg-brand-purple\",\n destructive: \"bg-destructive\",\n transparent: \"bg-transparent\",\n};\n\nfunction ActionButton({ label, icon, onClick, tone, disabled = false, helpContent, renderHelp }: ActionButtonProps) {\n return (\n <div className={`btn-border-animated p-[1px] rounded-2xl ${disabled ? \"opacity-40 pointer-events-none\" : \"\"}`}>\n <button\n className={`w-full h-10 rounded-[15px] flex items-center justify-center gap-2 px-3 text-sm font-semibold text-white transition-all hover:brightness-110 active:scale-[0.98] disabled:opacity-50 ${actionToneClass[tone]}`}\n disabled={disabled}\n onClick={onClick}\n >\n {icon}\n {label}\n {helpContent ? renderHelp(helpContent) : null}\n </button>\n </div>\n );\n}\n\nexport interface AssetMarketplacePanelProps {\n cheapest?: ApiOrderLike;\n isOwner: boolean;\n isSignedIn: boolean;\n isProcessing: boolean;\n isERC1155: boolean;\n isMarketLoading?: boolean;\n myListing: ApiOrderLike | null;\n activeBids: ApiOrderLike[];\n walletAddress?: string | null;\n remixEnabled?: boolean;\n showDealOption?: boolean;\n /** Raw \"0.07 STRK\"-style strings — already resolved by the caller. `null`/undefined renders \"—\". */\n floorPriceRaw?: string | null;\n lastSaleRaw?: string | null;\n /** Renders the sign-in/connect-wallet CTA for the given label (e.g. \"Sign in to trade\"). */\n renderAuthAction: (label: string) => ReactNode;\n /** Renders an inline help/info affordance for the given tooltip text. */\n renderHelp: (content: string) => ReactNode;\n onCancelClick: (order: ApiOrderLike) => void;\n onAcceptBid: (order: ApiOrderLike) => void;\n onOpenListing: () => void;\n onOpenTransfer: () => void;\n onOpenPurchase: (order: ApiOrderLike) => void;\n onOpenOffer: () => void;\n onOpenRemix?: () => void;\n onProposeDeal?: () => void;\n}\n\nfunction StatRow({ floorPriceRaw, lastSaleRaw }: { floorPriceRaw?: string | null; lastSaleRaw?: string | null }) {\n if (!floorPriceRaw && !lastSaleRaw) return null;\n const floor = floorPriceRaw ? parsePriceDisplay(floorPriceRaw) : null;\n const lastSale = lastSaleRaw ? parsePriceDisplay(lastSaleRaw) : null;\n return (\n <div className=\"flex items-center gap-4 text-xs text-muted-foreground\">\n <span className=\"flex items-center gap-1.5\">\n <span className=\"uppercase tracking-wider font-semibold\">Floor</span>\n {floor && floor.symbol ? (\n <CurrencyAmount amount={floor.numStr} symbol={floor.symbol} iconSize={12} amountClassName=\"text-foreground font-semibold\" />\n ) : (\n <span className=\"text-foreground font-semibold\">—</span>\n )}\n </span>\n <span className=\"flex items-center gap-1.5\">\n <span className=\"uppercase tracking-wider font-semibold\">Last sale</span>\n {lastSale && lastSale.symbol ? (\n <CurrencyAmount amount={lastSale.numStr} symbol={lastSale.symbol} iconSize={12} amountClassName=\"text-foreground font-semibold\" />\n ) : (\n <span className=\"text-foreground font-semibold\">—</span>\n )}\n </span>\n </div>\n );\n}\n\nexport function AssetMarketplacePanel({\n cheapest,\n isOwner,\n isSignedIn,\n isProcessing,\n isERC1155,\n isMarketLoading = false,\n myListing,\n activeBids,\n walletAddress,\n remixEnabled = false,\n showDealOption = false,\n floorPriceRaw,\n lastSaleRaw,\n renderAuthAction,\n renderHelp,\n onCancelClick,\n onAcceptBid,\n onOpenListing,\n onOpenTransfer,\n onOpenPurchase,\n onOpenOffer,\n onOpenRemix,\n onProposeDeal,\n}: AssetMarketplacePanelProps) {\n const myBid = !isOwner && walletAddress\n ? activeBids.find((bid) => bid.offerer.toLowerCase() === walletAddress.toLowerCase()) ?? null\n : null;\n\n const canBuyMore =\n isERC1155 && isOwner && !!cheapest && !!walletAddress &&\n cheapest.offerer.toLowerCase() !== walletAddress.toLowerCase();\n\n if (isMarketLoading && !cheapest) {\n return (\n <div className=\"space-y-4\">\n <div className=\"h-9 w-32 rounded-md bg-muted animate-pulse\" />\n <div className=\"h-12 w-full rounded-2xl bg-muted animate-pulse\" />\n </div>\n );\n }\n\n return (\n <div className=\"relative\">\n {/* soft brand light-leak behind the trade zone — no hard border, per §III */}\n <div\n aria-hidden\n className=\"aurora-purple pointer-events-none\"\n style={{ position: \"absolute\", width: 280, height: 280, top: -60, left: \"20%\" }}\n />\n <div className=\"relative space-y-4\">\n {cheapest ? (\n <div className=\"space-y-4\">\n <div className=\"flex items-baseline gap-2\">\n <CurrencyIcon symbol={cheapest.price.currency ?? \"\"} size={26} />\n <span className=\"text-4xl font-bold tracking-tight\">\n {formatDisplayPrice(cheapest.price.formatted)}\n </span>\n {renderHelp(\n `${isOwner && !canBuyMore ? \"Your listing\" : \"Current price\"} · Expires ${timeUntil(cheapest.endTime)}`\n )}\n </div>\n\n <StatRow floorPriceRaw={floorPriceRaw} lastSaleRaw={lastSaleRaw} />\n\n {isOwner ? (\n <div className=\"space-y-2\">\n <div className=\"grid grid-cols-2 gap-2\">\n {myListing ? (\n <ActionButton\n label=\"Cancel\"\n icon={isProcessing ? <Loader2 className=\"h-4 w-4 animate-spin\" /> : <X className=\"h-4 w-4\" />}\n onClick={() => onCancelClick(myListing)}\n disabled={isProcessing}\n tone=\"destructive\"\n renderHelp={renderHelp}\n />\n ) : null}\n <ActionButton label=\"List\" icon={<Tag className=\"h-4 w-4\" />} onClick={onOpenListing} tone=\"blue\" renderHelp={renderHelp} />\n <ActionButton label=\"Transfer\" icon={<ArrowRightLeft className=\"h-4 w-4\" />} onClick={onOpenTransfer} tone=\"orange\" renderHelp={renderHelp} />\n {remixEnabled && onOpenRemix ? (\n <ActionButton\n label=\"Remix\"\n icon={<GitBranch className=\"h-4 w-4\" />}\n onClick={onOpenRemix}\n helpContent=\"Build a licensed derivative of this digital asset — your remix is minted as a new onchain NFT linked to the original\"\n tone=\"purple\"\n renderHelp={renderHelp}\n />\n ) : null}\n </div>\n\n {canBuyMore && (\n <>\n <div className=\"border-t border-border/40 pt-2 mt-1\" />\n <div className=\"grid grid-cols-2 gap-2\">\n <ActionButton label=\"Buy\" icon={<ShoppingCart className=\"h-4 w-4\" />} onClick={() => onOpenPurchase(cheapest!)} tone=\"transparent\" renderHelp={renderHelp} />\n <ActionButton label=\"Make offer\" icon={<HandCoins className=\"h-4 w-4\" />} onClick={onOpenOffer} tone=\"orange\" renderHelp={renderHelp} />\n </div>\n </>\n )}\n </div>\n ) : isSignedIn ? (\n <>\n <div className=\"grid grid-cols-2 gap-2\">\n <ActionButton label=\"Buy\" icon={<ShoppingCart className=\"h-4 w-4\" />} onClick={() => onOpenPurchase(cheapest)} tone=\"transparent\" renderHelp={renderHelp} />\n <ActionButton label=\"Make offer\" icon={<HandCoins className=\"h-4 w-4\" />} onClick={onOpenOffer} tone=\"orange\" renderHelp={renderHelp} />\n {remixEnabled && onOpenRemix ? (\n <ActionButton\n label=\"Remix\"\n icon={<GitBranch className=\"h-4 w-4\" />}\n onClick={onOpenRemix}\n helpContent=\"Create your own attributed derivative of this work.\"\n tone=\"purple\"\n renderHelp={renderHelp}\n />\n ) : null}\n {showDealOption && onProposeDeal ? (\n <ActionButton\n label=\"License\"\n icon={<HandCoins className=\"h-4 w-4\" />}\n onClick={onProposeDeal}\n helpContent=\"Propose a license deal to the creator to use this work.\"\n tone=\"blue\"\n renderHelp={renderHelp}\n />\n ) : null}\n </div>\n {!remixEnabled && !showDealOption ? (\n <p className=\"text-xs text-muted-foreground mt-2 leading-relaxed\">\n The creator marked this asset as no-derivatives.\n </p>\n ) : null}\n </>\n ) : (\n renderAuthAction(\"Sign in to trade\")\n )}\n </div>\n ) : (\n <div className=\"space-y-3\">\n <StatRow floorPriceRaw={floorPriceRaw} lastSaleRaw={lastSaleRaw} />\n {isOwner ? (\n <div className=\"grid grid-cols-2 gap-2\">\n <ActionButton label=\"List\" icon={<Tag className=\"h-4 w-4\" />} onClick={onOpenListing} tone=\"transparent\" renderHelp={renderHelp} />\n <ActionButton label=\"Transfer\" icon={<ArrowRightLeft className=\"h-4 w-4\" />} onClick={onOpenTransfer} tone=\"orange\" renderHelp={renderHelp} />\n {remixEnabled && onOpenRemix ? (\n <ActionButton\n label=\"Remix\"\n icon={<GitBranch className=\"h-4 w-4\" />}\n onClick={onOpenRemix}\n helpContent=\"Build a licensed derivative of this digital asset — your remix is minted as a new onchain NFT linked to the original\"\n tone=\"purple\"\n renderHelp={renderHelp}\n />\n ) : null}\n </div>\n ) : isSignedIn ? (\n <div className=\"grid grid-cols-2 gap-2\">\n <ActionButton label=\"Make offer\" icon={<HandCoins className=\"h-4 w-4\" />} onClick={onOpenOffer} tone=\"orange\" renderHelp={renderHelp} />\n {remixEnabled && onOpenRemix ? (\n <ActionButton\n label=\"Remix\"\n icon={<GitBranch className=\"h-4 w-4\" />}\n onClick={onOpenRemix}\n helpContent=\"Build a licensed derivative of this digital asset — your remix is minted as a new onchain NFT linked to the original\"\n tone=\"purple\"\n renderHelp={renderHelp}\n />\n ) : null}\n </div>\n ) : (\n renderAuthAction(\"Sign in to make an offer\")\n )}\n </div>\n )}\n\n {myBid ? (\n <div className=\"rounded-xl bg-amber-500/8 px-4 py-3 flex items-center justify-between gap-3\">\n <div className=\"min-w-0 flex items-center gap-2.5\">\n <HandCoins className=\"h-4 w-4 text-amber-500 shrink-0\" />\n <div className=\"min-w-0\">\n <p className=\"text-xs font-semibold text-amber-500\">Your active offer</p>\n <p className=\"text-xs text-muted-foreground flex items-center gap-1.5 mt-0.5\">\n <span className=\"font-bold text-foreground inline-flex items-center gap-1\">\n {formatDisplayPrice(myBid.price.formatted)}\n <CurrencyIcon symbol={myBid.price.currency ?? \"\"} size={12} />\n </span>\n <span>·</span>\n <Clock className=\"h-3 w-3\" />\n {timeUntil(myBid.endTime)}\n </p>\n </div>\n </div>\n <button\n className=\"shrink-0 text-xs font-semibold text-red-400 hover:text-red-300 transition-colors flex items-center gap-1\"\n onClick={() => onCancelClick(myBid)}\n >\n <X className=\"h-3.5 w-3.5\" />\n Cancel\n </button>\n </div>\n ) : null}\n\n {isOwner && activeBids.length > 0 ? (\n <div className=\"rounded-xl bg-card/40 p-5 space-y-3\">\n <p className=\"text-xs font-semibold uppercase tracking-wider text-muted-foreground\">\n Incoming offers ({activeBids.length})\n </p>\n <div className=\"space-y-2\">\n {activeBids.map((bid) => (\n <div key={bid.orderHash} className=\"flex items-center justify-between gap-3 rounded-lg bg-muted/30 px-3 py-2\">\n <div className=\"min-w-0\">\n <p className=\"text-sm font-bold\">\n <span className=\"inline-flex items-center gap-1.5\">\n {formatDisplayPrice(bid.price.formatted)}\n <CurrencyIcon symbol={bid.price.currency ?? \"\"} size={14} />\n </span>\n </p>\n <div className=\"flex items-center gap-2 mt-0.5\">\n <AddressDisplay address={bid.offerer} chars={4} showCopy={false} className=\"text-xs text-muted-foreground\" />\n <span className=\"text-xs text-muted-foreground\">·</span>\n <div className=\"flex items-center gap-1 text-xs text-muted-foreground\">\n <Clock className=\"h-3 w-3\" />\n {timeUntil(bid.endTime)}\n </div>\n </div>\n </div>\n <button\n disabled={isProcessing}\n onClick={() => onAcceptBid(bid)}\n className=\"inline-flex items-center gap-1.5 rounded-lg bg-primary px-3 py-1.5 text-xs font-semibold text-primary-foreground disabled:opacity-50\"\n >\n <CheckCircle className=\"h-3.5 w-3.5\" />\n Accept\n </button>\n </div>\n ))}\n </div>\n </div>\n ) : null}\n </div>\n </div>\n );\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/components/asset-marketplace-panel.tsx"],"sourcesContent":["\"use client\";\n\nimport type { ReactNode } from \"react\";\nimport {\n ArrowRightLeft, CheckCircle, Clock, GitBranch, HandCoins, Loader2,\n ShoppingCart, Tag, X,\n} from \"lucide-react\";\nimport { CurrencyIcon, CurrencyAmount } from \"./currency-icon.js\";\nimport { AddressDisplay } from \"./address-display.js\";\nimport { formatDisplayPrice, parsePriceDisplay } from \"../utils/format.js\";\nimport { timeUntil } from \"../utils/time.js\";\n\n/** Structural subset of `ApiOrder` (both apps' `@medialane/sdk` types satisfy this). */\nexport interface ApiOrderLike {\n orderHash: string;\n offerer: string;\n endTime: string;\n price: { formatted: string | null; currency: string | null };\n}\n\ninterface ActionButtonProps {\n label: string;\n icon: ReactNode;\n onClick: () => void;\n tone: \"blue\" | \"orange\" | \"purple\" | \"destructive\" | \"transparent\";\n disabled?: boolean;\n helpContent?: string;\n renderHelp: (content: string) => ReactNode;\n}\n\nconst actionToneClass: Record<ActionButtonProps[\"tone\"], string> = {\n blue: \"bg-brand-blue\",\n orange: \"bg-brand-orange\",\n purple: \"bg-brand-purple\",\n destructive: \"bg-destructive\",\n transparent: \"bg-transparent\",\n};\n\nfunction ActionButton({ label, icon, onClick, tone, disabled = false, helpContent, renderHelp }: ActionButtonProps) {\n return (\n <div className={`btn-border-animated p-[1px] rounded-2xl ${disabled ? \"opacity-40 pointer-events-none\" : \"\"}`}>\n <button\n className={`w-full h-10 rounded-[15px] flex items-center justify-center gap-2 px-3 text-sm font-semibold text-white transition-all hover:brightness-110 active:scale-[0.98] disabled:opacity-50 ${actionToneClass[tone]}`}\n disabled={disabled}\n onClick={onClick}\n >\n {icon}\n {label}\n {helpContent ? renderHelp(helpContent) : null}\n </button>\n </div>\n );\n}\n\nexport interface AssetMarketplacePanelProps {\n cheapest?: ApiOrderLike;\n isOwner: boolean;\n isSignedIn: boolean;\n isProcessing: boolean;\n isERC1155: boolean;\n isMarketLoading?: boolean;\n myListing: ApiOrderLike | null;\n activeBids: ApiOrderLike[];\n walletAddress?: string | null;\n remixEnabled?: boolean;\n showDealOption?: boolean;\n /** Raw \"0.07 STRK\"-style strings — already resolved by the caller. `null`/undefined renders \"—\". */\n floorPriceRaw?: string | null;\n lastSaleRaw?: string | null;\n /** Renders the sign-in/connect-wallet CTA for the given label (e.g. \"Sign in to trade\"). */\n renderAuthAction: (label: string) => ReactNode;\n /** Renders an inline help/info affordance for the given tooltip text. */\n renderHelp: (content: string) => ReactNode;\n onCancelClick: (order: ApiOrderLike) => void;\n onAcceptBid: (order: ApiOrderLike) => void;\n onOpenListing: () => void;\n onOpenTransfer: () => void;\n onOpenPurchase: (order: ApiOrderLike) => void;\n onOpenOffer: () => void;\n onOpenRemix?: () => void;\n onProposeDeal?: () => void;\n}\n\nfunction StatRow({ floorPriceRaw, lastSaleRaw }: { floorPriceRaw?: string | null; lastSaleRaw?: string | null }) {\n if (!floorPriceRaw && !lastSaleRaw) return null;\n const floor = floorPriceRaw ? parsePriceDisplay(floorPriceRaw) : null;\n const lastSale = lastSaleRaw ? parsePriceDisplay(lastSaleRaw) : null;\n return (\n <div className=\"flex items-center gap-4 text-xs text-muted-foreground\">\n <span className=\"flex items-center gap-1.5\">\n <span className=\"uppercase tracking-wider font-semibold\">Floor</span>\n {floor && floor.symbol ? (\n <CurrencyAmount amount={floor.numStr} symbol={floor.symbol} iconSize={12} amountClassName=\"text-foreground font-semibold\" />\n ) : (\n <span className=\"text-foreground font-semibold\">—</span>\n )}\n </span>\n <span className=\"flex items-center gap-1.5\">\n <span className=\"uppercase tracking-wider font-semibold\">Last sale</span>\n {lastSale && lastSale.symbol ? (\n <CurrencyAmount amount={lastSale.numStr} symbol={lastSale.symbol} iconSize={12} amountClassName=\"text-foreground font-semibold\" />\n ) : (\n <span className=\"text-foreground font-semibold\">—</span>\n )}\n </span>\n </div>\n );\n}\n\nexport function AssetMarketplacePanel({\n cheapest,\n isOwner,\n isSignedIn,\n isProcessing,\n isERC1155,\n isMarketLoading = false,\n myListing,\n activeBids,\n walletAddress,\n remixEnabled = false,\n showDealOption = false,\n floorPriceRaw,\n lastSaleRaw,\n renderAuthAction,\n renderHelp,\n onCancelClick,\n onAcceptBid,\n onOpenListing,\n onOpenTransfer,\n onOpenPurchase,\n onOpenOffer,\n onOpenRemix,\n onProposeDeal,\n}: AssetMarketplacePanelProps) {\n const myBid = !isOwner && walletAddress\n ? activeBids.find((bid) => bid.offerer.toLowerCase() === walletAddress.toLowerCase()) ?? null\n : null;\n\n const canBuyMore =\n isERC1155 && isOwner && !!cheapest && !!walletAddress &&\n cheapest.offerer.toLowerCase() !== walletAddress.toLowerCase();\n\n if (isMarketLoading && !cheapest) {\n return (\n <div className=\"space-y-4\">\n <div className=\"h-9 w-32 rounded-md bg-muted animate-pulse\" />\n <div className=\"h-12 w-full rounded-2xl bg-muted animate-pulse\" />\n </div>\n );\n }\n\n return (\n <div className=\"relative\">\n {/* soft brand light-leak behind the trade zone — no hard border, per §III */}\n <div\n aria-hidden\n className=\"aurora-purple pointer-events-none\"\n style={{ position: \"absolute\", width: 280, height: 280, top: -60, left: \"20%\" }}\n />\n <div className=\"relative space-y-4\">\n {cheapest ? (\n <div className=\"space-y-4\">\n <div className=\"flex items-baseline gap-2\">\n <CurrencyIcon symbol={cheapest.price.currency ?? \"\"} size={26} />\n <span className=\"text-4xl font-bold tracking-tight\">\n {formatDisplayPrice(cheapest.price.formatted)}\n </span>\n {renderHelp(\n `${isOwner && !canBuyMore ? \"Your listing\" : \"Current price\"} · Expires ${timeUntil(cheapest.endTime)}`\n )}\n </div>\n\n <StatRow floorPriceRaw={floorPriceRaw} lastSaleRaw={lastSaleRaw} />\n\n {isOwner ? (\n <div className=\"space-y-2\">\n <div className=\"grid grid-cols-2 gap-2\">\n {myListing ? (\n <ActionButton\n label=\"Cancel\"\n icon={isProcessing ? <Loader2 className=\"h-4 w-4 animate-spin\" /> : <X className=\"h-4 w-4\" />}\n onClick={() => onCancelClick(myListing)}\n disabled={isProcessing}\n tone=\"destructive\"\n renderHelp={renderHelp}\n />\n ) : null}\n <ActionButton label=\"List\" icon={<Tag className=\"h-4 w-4\" />} onClick={onOpenListing} tone=\"blue\" renderHelp={renderHelp} />\n <ActionButton label=\"Transfer\" icon={<ArrowRightLeft className=\"h-4 w-4\" />} onClick={onOpenTransfer} tone=\"orange\" renderHelp={renderHelp} />\n {remixEnabled && onOpenRemix ? (\n <ActionButton\n label=\"Remix\"\n icon={<GitBranch className=\"h-4 w-4\" />}\n onClick={onOpenRemix}\n helpContent=\"Build a licensed derivative of this digital asset — your remix is minted as a new onchain NFT linked to the original\"\n tone=\"purple\"\n renderHelp={renderHelp}\n />\n ) : null}\n </div>\n\n {canBuyMore && (\n <>\n <div className=\"border-t border-border/40 pt-2 mt-1\" />\n <div className=\"grid grid-cols-2 gap-2\">\n <ActionButton label=\"Buy\" icon={<ShoppingCart className=\"h-4 w-4\" />} onClick={() => onOpenPurchase(cheapest!)} tone=\"transparent\" renderHelp={renderHelp} />\n <ActionButton label=\"Make offer\" icon={<HandCoins className=\"h-4 w-4\" />} onClick={onOpenOffer} tone=\"orange\" renderHelp={renderHelp} />\n </div>\n </>\n )}\n </div>\n ) : isSignedIn ? (\n <>\n <div className=\"grid grid-cols-2 gap-2\">\n <ActionButton label=\"Buy\" icon={<ShoppingCart className=\"h-4 w-4\" />} onClick={() => onOpenPurchase(cheapest)} tone=\"transparent\" renderHelp={renderHelp} />\n <ActionButton label=\"Make offer\" icon={<HandCoins className=\"h-4 w-4\" />} onClick={onOpenOffer} tone=\"orange\" renderHelp={renderHelp} />\n {remixEnabled && onOpenRemix ? (\n <ActionButton\n label=\"Remix\"\n icon={<GitBranch className=\"h-4 w-4\" />}\n onClick={onOpenRemix}\n helpContent=\"Create your own attributed derivative of this work.\"\n tone=\"purple\"\n renderHelp={renderHelp}\n />\n ) : null}\n {showDealOption && onProposeDeal ? (\n <ActionButton\n label=\"License\"\n icon={<HandCoins className=\"h-4 w-4\" />}\n onClick={onProposeDeal}\n helpContent=\"Propose a license deal to the creator to use this work.\"\n tone=\"blue\"\n renderHelp={renderHelp}\n />\n ) : null}\n </div>\n {!remixEnabled && !showDealOption ? (\n <p className=\"text-xs text-muted-foreground mt-2 leading-relaxed\">\n The creator marked this asset as no-derivatives.\n </p>\n ) : null}\n </>\n ) : (\n renderAuthAction(\"Sign in to trade\")\n )}\n </div>\n ) : (\n <div className=\"space-y-3\">\n <StatRow floorPriceRaw={floorPriceRaw} lastSaleRaw={lastSaleRaw} />\n {isOwner ? (\n <div className=\"grid grid-cols-2 gap-2\">\n <ActionButton label=\"List\" icon={<Tag className=\"h-4 w-4\" />} onClick={onOpenListing} tone=\"transparent\" renderHelp={renderHelp} />\n <ActionButton label=\"Transfer\" icon={<ArrowRightLeft className=\"h-4 w-4\" />} onClick={onOpenTransfer} tone=\"orange\" renderHelp={renderHelp} />\n {remixEnabled && onOpenRemix ? (\n <ActionButton\n label=\"Remix\"\n icon={<GitBranch className=\"h-4 w-4\" />}\n onClick={onOpenRemix}\n helpContent=\"Build a licensed derivative of this digital asset — your remix is minted as a new onchain NFT linked to the original\"\n tone=\"purple\"\n renderHelp={renderHelp}\n />\n ) : null}\n </div>\n ) : isSignedIn ? (\n <div className=\"grid grid-cols-2 gap-2\">\n <ActionButton label=\"Make offer\" icon={<HandCoins className=\"h-4 w-4\" />} onClick={onOpenOffer} tone=\"orange\" renderHelp={renderHelp} />\n {remixEnabled && onOpenRemix ? (\n <ActionButton\n label=\"Remix\"\n icon={<GitBranch className=\"h-4 w-4\" />}\n onClick={onOpenRemix}\n helpContent=\"Build a licensed derivative of this digital asset — your remix is minted as a new onchain NFT linked to the original\"\n tone=\"purple\"\n renderHelp={renderHelp}\n />\n ) : null}\n </div>\n ) : (\n renderAuthAction(\"Sign in to make an offer\")\n )}\n </div>\n )}\n\n {myBid ? (\n <div className=\"rounded-xl bg-amber-500/8 px-4 py-3 flex items-center justify-between gap-3\">\n <div className=\"min-w-0 flex items-center gap-2.5\">\n <HandCoins className=\"h-4 w-4 text-amber-500 shrink-0\" />\n <div className=\"min-w-0\">\n <p className=\"text-xs font-semibold text-amber-500\">Your active offer</p>\n <p className=\"text-xs text-muted-foreground flex items-center gap-1.5 mt-0.5\">\n <span className=\"font-bold text-foreground inline-flex items-center gap-1\">\n {formatDisplayPrice(myBid.price.formatted)}\n <CurrencyIcon symbol={myBid.price.currency ?? \"\"} size={12} />\n </span>\n <span>·</span>\n <Clock className=\"h-3 w-3\" />\n {timeUntil(myBid.endTime)}\n </p>\n </div>\n </div>\n <button\n className=\"shrink-0 text-xs font-semibold text-red-400 hover:text-red-300 transition-colors flex items-center gap-1\"\n onClick={() => onCancelClick(myBid)}\n >\n <X className=\"h-3.5 w-3.5\" />\n Cancel\n </button>\n </div>\n ) : null}\n\n {isOwner && activeBids.length > 0 ? (\n <div className=\"rounded-xl bg-card/40 p-5 space-y-3\">\n <p className=\"text-xs font-semibold uppercase tracking-wider text-muted-foreground\">\n Incoming offers ({activeBids.length})\n </p>\n <div className=\"space-y-2\">\n {activeBids.map((bid) => (\n <div key={bid.orderHash} className=\"flex items-center justify-between gap-3 rounded-lg bg-muted/30 px-3 py-2\">\n <div className=\"min-w-0\">\n <p className=\"text-sm font-bold\">\n <span className=\"inline-flex items-center gap-1.5\">\n {formatDisplayPrice(bid.price.formatted)}\n <CurrencyIcon symbol={bid.price.currency ?? \"\"} size={14} />\n </span>\n </p>\n <div className=\"flex items-center gap-2 mt-0.5\">\n <AddressDisplay address={bid.offerer} chars={4} showCopy={false} className=\"text-xs text-muted-foreground\" />\n <span className=\"text-xs text-muted-foreground\">·</span>\n <div className=\"flex items-center gap-1 text-xs text-muted-foreground\">\n <Clock className=\"h-3 w-3\" />\n {timeUntil(bid.endTime)}\n </div>\n </div>\n </div>\n <button\n disabled={isProcessing}\n onClick={() => onAcceptBid(bid)}\n className=\"inline-flex items-center gap-1.5 rounded-lg bg-primary px-3 py-1.5 text-xs font-semibold text-primary-foreground disabled:opacity-50\"\n >\n <CheckCircle className=\"h-3.5 w-3.5\" />\n Accept\n </button>\n </div>\n ))}\n </div>\n </div>\n ) : null}\n </div>\n </div>\n );\n}\n"],"mappings":"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","names":[]}
|