@medialane/ui 0.327.0 → 0.329.0
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.
- package/dist/components/account/input-otp.d.cts +2 -2
- package/dist/components/account/input-otp.d.ts +2 -2
- package/dist/components/asset-card.cjs +4 -4
- package/dist/components/asset-card.cjs.map +1 -1
- package/dist/components/asset-card.js +4 -4
- package/dist/components/asset-card.js.map +1 -1
- package/dist/components/asset-marketplace-panel.cjs +23 -26
- package/dist/components/asset-marketplace-panel.cjs.map +1 -1
- package/dist/components/asset-marketplace-panel.js +23 -26
- package/dist/components/asset-marketplace-panel.js.map +1 -1
- package/dist/components/badge.d.cts +1 -1
- package/dist/components/badge.d.ts +1 -1
- package/dist/components/button.d.cts +2 -2
- package/dist/components/button.d.ts +2 -2
- package/dist/components/coin-row.cjs +3 -3
- package/dist/components/coin-row.cjs.map +1 -1
- package/dist/components/coin-row.js +3 -3
- package/dist/components/coin-row.js.map +1 -1
- package/dist/components/fast-mint/fast-mint.d.cts +2 -2
- package/dist/components/fast-mint/fast-mint.d.ts +2 -2
- package/dist/components/home-page.cjs +4 -8
- package/dist/components/home-page.cjs.map +1 -1
- package/dist/components/home-page.js +4 -8
- package/dist/components/home-page.js.map +1 -1
- package/dist/components/listing-card.cjs +2 -14
- package/dist/components/listing-card.cjs.map +1 -1
- package/dist/components/listing-card.js +2 -14
- package/dist/components/listing-card.js.map +1 -1
- package/dist/components/portfolio-section.cjs +1 -1
- package/dist/components/portfolio-section.cjs.map +1 -1
- package/dist/components/portfolio-section.js +1 -1
- package/dist/components/portfolio-section.js.map +1 -1
- package/dist/components/price-display.cjs +115 -0
- package/dist/components/price-display.cjs.map +1 -0
- package/dist/components/price-display.d.cts +44 -0
- package/dist/components/price-display.d.ts +44 -0
- package/dist/components/price-display.js +91 -0
- package/dist/components/price-display.js.map +1 -0
- package/dist/components/section-heading.cjs +1 -1
- package/dist/components/section-heading.cjs.map +1 -1
- package/dist/components/section-heading.js +1 -1
- package/dist/components/section-heading.js.map +1 -1
- package/dist/components/sheet.d.cts +1 -1
- package/dist/components/sheet.d.ts +1 -1
- package/dist/components/token-card.cjs +4 -4
- package/dist/components/token-card.cjs.map +1 -1
- package/dist/components/token-card.js +4 -4
- package/dist/components/token-card.js.map +1 -1
- package/dist/utils/format.cjs +9 -0
- package/dist/utils/format.cjs.map +1 -1
- package/dist/utils/format.d.cts +2 -1
- package/dist/utils/format.d.ts +2 -1
- package/dist/utils/format.js +8 -0
- package/dist/utils/format.js.map +1 -1
- package/package.json +1 -1
- package/dist/components/dual-price.cjs +0 -164
- package/dist/components/dual-price.cjs.map +0 -1
- package/dist/components/dual-price.d.cts +0 -53
- package/dist/components/dual-price.d.ts +0 -53
- package/dist/components/dual-price.js +0 -138
- package/dist/components/dual-price.js.map +0 -1
|
@@ -39,7 +39,7 @@ var import_jsx_runtime = require("react/jsx-runtime");
|
|
|
39
39
|
var import_link = __toESM(require("./link.js"), 1);
|
|
40
40
|
var import_image = __toESM(require("./image.js"), 1);
|
|
41
41
|
var import_cn = require("../utils/cn.js");
|
|
42
|
-
var
|
|
42
|
+
var import_price_display = require("./price-display.js");
|
|
43
43
|
var import_coins = require("../data/coins.js");
|
|
44
44
|
var import_format = require("../utils/format.js");
|
|
45
45
|
var import_use_image_url = require("../utils/use-image-url.js");
|
|
@@ -80,13 +80,13 @@ function PriceCell({ price, status, isLoading }) {
|
|
|
80
80
|
}
|
|
81
81
|
const usd = price.quoteUsdRate != null ? (0, import_format.formatUsdPrice)(price.quotePerCoin * price.quoteUsdRate) : null;
|
|
82
82
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "flex justify-end", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
83
|
-
|
|
83
|
+
import_price_display.PriceDisplay,
|
|
84
84
|
{
|
|
85
85
|
amountFormatted: String(price.quotePerCoin),
|
|
86
86
|
currency: price.quoteSymbol,
|
|
87
87
|
usdValue: usd,
|
|
88
88
|
scale: "card",
|
|
89
|
-
|
|
89
|
+
pillClassName: "hidden sm:inline-flex"
|
|
90
90
|
}
|
|
91
91
|
) });
|
|
92
92
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/coin-row.tsx"],"sourcesContent":["\"use client\";\n\nimport Link from \"./link.js\";\nimport Image from \"./image.js\";\nimport { cn } from \"../utils/cn.js\";\nimport {
|
|
1
|
+
{"version":3,"sources":["../../src/components/coin-row.tsx"],"sourcesContent":["\"use client\";\n\nimport Link from \"./link.js\";\nimport Image from \"./image.js\";\nimport { cn } from \"../utils/cn.js\";\nimport { PriceDisplay } from \"./price-display.js\";\nimport {\n coinKind, coinKindLabel, coinAccentToken,\n type CoinCollectionLike, type CoinPriceLike,\n} from \"../data/coins.js\";\nimport { formatUsdPrice } from \"../utils/format.js\";\nimport { useImageUrl } from \"../utils/use-image-url.js\";\n\nexport type CoinMarketStatus = \"live\" | \"pre-launch\" | \"unavailable\";\n\nexport type UseCoinPrice = (collection: CoinCollectionLike) => {\n price: CoinPriceLike | null;\n status?: CoinMarketStatus;\n isLoading: boolean;\n};\n\nexport const COIN_GRID = \"grid grid-cols-[minmax(0,1fr)_auto] items-center gap-3 sm:gap-4\";\n\nexport interface CoinRowProps {\n collection: CoinCollectionLike;\n usePrice: UseCoinPrice;\n href: string;\n showKind?: boolean;\n}\n\nexport function CoinAvatar({ collection, size = 36 }: { collection: CoinCollectionLike; size?: number }) {\n const resolveImage = useImageUrl();\n const logoUri = collection.profile?.image ?? collection.image;\n const logo = resolveImage(logoUri);\n const initials = (collection.symbol ?? collection.name ?? \"?\").trim().slice(0, 2).toUpperCase();\n const accent = coinAccentToken(collection.symbol ?? collection.name ?? collection.contractAddress);\n\n return (\n <div\n className={cn(\"relative shrink-0 overflow-hidden rounded-full\", accent)}\n style={{ width: size, height: size }}\n >\n {logo ? (\n <Image src={logo} alt=\"\" fill sizes={`${size}px`} className=\"object-cover\" unoptimized />\n ) : (\n <span\n className=\"flex h-full w-full items-center justify-center font-bold leading-none text-white\"\n style={{ fontSize: size * 0.36 }}\n >\n {initials}\n </span>\n )}\n </div>\n );\n}\n\nfunction PriceCell({ price, status, isLoading }: { price: CoinPriceLike | null; status?: CoinMarketStatus; isLoading: boolean }) {\n if (isLoading) return <span className=\"ml-auto block h-4 w-16 animate-pulse rounded bg-muted-foreground/20\" />;\n if (!price) {\n return status === \"pre-launch\" ? (\n <span className=\"block text-right text-xs text-muted-foreground\">Not trading yet</span>\n ) : (\n <span\n className=\"block text-right text-muted-foreground\"\n title=\"No liquidity route was found for this coin on any Starknet DEX yet.\"\n >\n —\n </span>\n );\n }\n\n const usd = price.quoteUsdRate != null ? formatUsdPrice(price.quotePerCoin * price.quoteUsdRate) : null;\n\n return (\n <span className=\"flex justify-end\">\n <PriceDisplay\n amountFormatted={String(price.quotePerCoin)}\n currency={price.quoteSymbol}\n usdValue={usd}\n scale=\"card\"\n pillClassName=\"hidden sm:inline-flex\"\n />\n </span>\n );\n}\n\nexport function CoinRow({ collection, usePrice, href, showKind = false }: CoinRowProps) {\n const { price, status, isLoading } = usePrice(collection);\n\n return (\n <Link\n href={href}\n className={cn(\n COIN_GRID,\n \"border-b border-border/40 px-2 py-2.5 text-sm transition-colors\",\n \"hover:bg-muted/40 active:bg-muted/60\"\n )}\n >\n <span className=\"flex min-w-0 items-center gap-3\">\n <CoinAvatar collection={collection} />\n <span className=\"min-w-0\">\n <span className=\"block truncate font-semibold leading-tight\">{collection.name ?? \"Untitled coin\"}</span>\n <span className=\"block truncate text-xs text-muted-foreground\">\n {collection.symbol ?? \"—\"}\n {showKind && <span className=\"text-muted-foreground/60\"> · {coinKindLabel(coinKind(collection.service))}</span>}\n </span>\n </span>\n </span>\n\n <PriceCell price={price} status={status} isLoading={isLoading} />\n </Link>\n );\n}\n\nexport function CoinRowSkeleton() {\n return (\n <div className={cn(COIN_GRID, \"border-b border-border/40 px-2 py-2.5\")}>\n <span className=\"flex items-center gap-3\">\n <span className=\"h-9 w-9 shrink-0 animate-pulse rounded-full bg-muted-foreground/20\" />\n <span className=\"space-y-1.5\">\n <span className=\"block h-4 w-28 animate-pulse rounded bg-muted-foreground/20\" />\n <span className=\"block h-3 w-14 animate-pulse rounded bg-muted-foreground/10\" />\n </span>\n </span>\n <span className=\"ml-auto block h-4 w-16 animate-pulse rounded bg-muted-foreground/20\" />\n </div>\n );\n}\n"],"mappings":"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","names":["Image","Link"]}
|
|
@@ -3,7 +3,7 @@ import { jsx, jsxs } from "react/jsx-runtime";
|
|
|
3
3
|
import Link from "./link.js";
|
|
4
4
|
import Image from "./image.js";
|
|
5
5
|
import { cn } from "../utils/cn.js";
|
|
6
|
-
import {
|
|
6
|
+
import { PriceDisplay } from "./price-display.js";
|
|
7
7
|
import {
|
|
8
8
|
coinKind,
|
|
9
9
|
coinKindLabel,
|
|
@@ -48,13 +48,13 @@ function PriceCell({ price, status, isLoading }) {
|
|
|
48
48
|
}
|
|
49
49
|
const usd = price.quoteUsdRate != null ? formatUsdPrice(price.quotePerCoin * price.quoteUsdRate) : null;
|
|
50
50
|
return /* @__PURE__ */ jsx("span", { className: "flex justify-end", children: /* @__PURE__ */ jsx(
|
|
51
|
-
|
|
51
|
+
PriceDisplay,
|
|
52
52
|
{
|
|
53
53
|
amountFormatted: String(price.quotePerCoin),
|
|
54
54
|
currency: price.quoteSymbol,
|
|
55
55
|
usdValue: usd,
|
|
56
56
|
scale: "card",
|
|
57
|
-
|
|
57
|
+
pillClassName: "hidden sm:inline-flex"
|
|
58
58
|
}
|
|
59
59
|
) });
|
|
60
60
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/coin-row.tsx"],"sourcesContent":["\"use client\";\n\nimport Link from \"./link.js\";\nimport Image from \"./image.js\";\nimport { cn } from \"../utils/cn.js\";\nimport {
|
|
1
|
+
{"version":3,"sources":["../../src/components/coin-row.tsx"],"sourcesContent":["\"use client\";\n\nimport Link from \"./link.js\";\nimport Image from \"./image.js\";\nimport { cn } from \"../utils/cn.js\";\nimport { PriceDisplay } from \"./price-display.js\";\nimport {\n coinKind, coinKindLabel, coinAccentToken,\n type CoinCollectionLike, type CoinPriceLike,\n} from \"../data/coins.js\";\nimport { formatUsdPrice } from \"../utils/format.js\";\nimport { useImageUrl } from \"../utils/use-image-url.js\";\n\nexport type CoinMarketStatus = \"live\" | \"pre-launch\" | \"unavailable\";\n\nexport type UseCoinPrice = (collection: CoinCollectionLike) => {\n price: CoinPriceLike | null;\n status?: CoinMarketStatus;\n isLoading: boolean;\n};\n\nexport const COIN_GRID = \"grid grid-cols-[minmax(0,1fr)_auto] items-center gap-3 sm:gap-4\";\n\nexport interface CoinRowProps {\n collection: CoinCollectionLike;\n usePrice: UseCoinPrice;\n href: string;\n showKind?: boolean;\n}\n\nexport function CoinAvatar({ collection, size = 36 }: { collection: CoinCollectionLike; size?: number }) {\n const resolveImage = useImageUrl();\n const logoUri = collection.profile?.image ?? collection.image;\n const logo = resolveImage(logoUri);\n const initials = (collection.symbol ?? collection.name ?? \"?\").trim().slice(0, 2).toUpperCase();\n const accent = coinAccentToken(collection.symbol ?? collection.name ?? collection.contractAddress);\n\n return (\n <div\n className={cn(\"relative shrink-0 overflow-hidden rounded-full\", accent)}\n style={{ width: size, height: size }}\n >\n {logo ? (\n <Image src={logo} alt=\"\" fill sizes={`${size}px`} className=\"object-cover\" unoptimized />\n ) : (\n <span\n className=\"flex h-full w-full items-center justify-center font-bold leading-none text-white\"\n style={{ fontSize: size * 0.36 }}\n >\n {initials}\n </span>\n )}\n </div>\n );\n}\n\nfunction PriceCell({ price, status, isLoading }: { price: CoinPriceLike | null; status?: CoinMarketStatus; isLoading: boolean }) {\n if (isLoading) return <span className=\"ml-auto block h-4 w-16 animate-pulse rounded bg-muted-foreground/20\" />;\n if (!price) {\n return status === \"pre-launch\" ? (\n <span className=\"block text-right text-xs text-muted-foreground\">Not trading yet</span>\n ) : (\n <span\n className=\"block text-right text-muted-foreground\"\n title=\"No liquidity route was found for this coin on any Starknet DEX yet.\"\n >\n —\n </span>\n );\n }\n\n const usd = price.quoteUsdRate != null ? formatUsdPrice(price.quotePerCoin * price.quoteUsdRate) : null;\n\n return (\n <span className=\"flex justify-end\">\n <PriceDisplay\n amountFormatted={String(price.quotePerCoin)}\n currency={price.quoteSymbol}\n usdValue={usd}\n scale=\"card\"\n pillClassName=\"hidden sm:inline-flex\"\n />\n </span>\n );\n}\n\nexport function CoinRow({ collection, usePrice, href, showKind = false }: CoinRowProps) {\n const { price, status, isLoading } = usePrice(collection);\n\n return (\n <Link\n href={href}\n className={cn(\n COIN_GRID,\n \"border-b border-border/40 px-2 py-2.5 text-sm transition-colors\",\n \"hover:bg-muted/40 active:bg-muted/60\"\n )}\n >\n <span className=\"flex min-w-0 items-center gap-3\">\n <CoinAvatar collection={collection} />\n <span className=\"min-w-0\">\n <span className=\"block truncate font-semibold leading-tight\">{collection.name ?? \"Untitled coin\"}</span>\n <span className=\"block truncate text-xs text-muted-foreground\">\n {collection.symbol ?? \"—\"}\n {showKind && <span className=\"text-muted-foreground/60\"> · {coinKindLabel(coinKind(collection.service))}</span>}\n </span>\n </span>\n </span>\n\n <PriceCell price={price} status={status} isLoading={isLoading} />\n </Link>\n );\n}\n\nexport function CoinRowSkeleton() {\n return (\n <div className={cn(COIN_GRID, \"border-b border-border/40 px-2 py-2.5\")}>\n <span className=\"flex items-center gap-3\">\n <span className=\"h-9 w-9 shrink-0 animate-pulse rounded-full bg-muted-foreground/20\" />\n <span className=\"space-y-1.5\">\n <span className=\"block h-4 w-28 animate-pulse rounded bg-muted-foreground/20\" />\n <span className=\"block h-3 w-14 animate-pulse rounded bg-muted-foreground/10\" />\n </span>\n </span>\n <span className=\"ml-auto block h-4 w-16 animate-pulse rounded bg-muted-foreground/20\" />\n </div>\n );\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import * as React from 'react';
|
|
2
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import * as React from 'react';
|
|
3
3
|
import { FastMintProps } from './types.cjs';
|
|
4
4
|
import 'starknet';
|
|
5
5
|
import '@medialane/sdk';
|
|
6
6
|
import '@medialane/sdk/starknet';
|
|
7
7
|
|
|
8
|
-
declare function FastMint(props: FastMintProps): string | number | bigint | boolean |
|
|
8
|
+
declare function FastMint(props: FastMintProps): string | number | bigint | boolean | Iterable<React.ReactNode> | Promise<string | number | bigint | boolean | React.ReactPortal | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | null | undefined> | react_jsx_runtime.JSX.Element | null | undefined;
|
|
9
9
|
|
|
10
10
|
export { FastMint };
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import * as React from 'react';
|
|
2
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import * as React from 'react';
|
|
3
3
|
import { FastMintProps } from './types.js';
|
|
4
4
|
import 'starknet';
|
|
5
5
|
import '@medialane/sdk';
|
|
6
6
|
import '@medialane/sdk/starknet';
|
|
7
7
|
|
|
8
|
-
declare function FastMint(props: FastMintProps): string | number | bigint | boolean |
|
|
8
|
+
declare function FastMint(props: FastMintProps): string | number | bigint | boolean | Iterable<React.ReactNode> | Promise<string | number | bigint | boolean | React.ReactPortal | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | null | undefined> | react_jsx_runtime.JSX.Element | null | undefined;
|
|
9
9
|
|
|
10
10
|
export { FastMint };
|
|
@@ -65,7 +65,6 @@ function ListingsStrip({
|
|
|
65
65
|
title,
|
|
66
66
|
query,
|
|
67
67
|
href,
|
|
68
|
-
linkLabel,
|
|
69
68
|
empty
|
|
70
69
|
}) {
|
|
71
70
|
const { walletAddress } = (0, import_medialane_app.useMedialaneApp)();
|
|
@@ -73,7 +72,7 @@ function ListingsStrip({
|
|
|
73
72
|
const prices = (0, import_use_usd_prices.useUsdPrices)();
|
|
74
73
|
const listings = orders.filter((o) => o.offer.itemType === "ERC721" || o.offer.itemType === "ERC1155").slice(0, 10);
|
|
75
74
|
if (!isLoading && listings.length === 0 && !empty) return null;
|
|
76
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_scroll_section.ScrollSection, { icon, title, href,
|
|
75
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_scroll_section.ScrollSection, { icon, title, href, children: isLoading ? Array.from({ length: 8 }).map((_, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "w-56 shrink-0 snap-start sm:w-64", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_listing_card.ListingCardSkeleton, {}) }, i)) : listings.length === 0 ? empty : listings.map((order) => {
|
|
77
76
|
const own = !!walletAddress && (0, import_same_address.isSameAddress)(order.offerer, walletAddress);
|
|
78
77
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "w-56 shrink-0 snap-start sm:w-64", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
79
78
|
import_listing_card.ListingCard,
|
|
@@ -92,10 +91,9 @@ function NewListings({ market }) {
|
|
|
92
91
|
{
|
|
93
92
|
market,
|
|
94
93
|
icon: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.Tag, {}),
|
|
95
|
-
title: "
|
|
94
|
+
title: "Marketplace",
|
|
96
95
|
query: { status: "ACTIVE", limit: 10, page: 1 },
|
|
97
96
|
href: "/marketplace",
|
|
98
|
-
linkLabel: "Marketplace",
|
|
99
97
|
empty: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "py-4 text-sm text-muted-foreground", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_link.default, { href: "/launchpad/single-editions", className: "text-primary hover:underline", children: "Sell the first asset" }) })
|
|
100
98
|
}
|
|
101
99
|
);
|
|
@@ -106,10 +104,9 @@ function FeaturedListings({ market }) {
|
|
|
106
104
|
{
|
|
107
105
|
market,
|
|
108
106
|
icon: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.Sparkles, {}),
|
|
109
|
-
title: "Featured
|
|
107
|
+
title: "Featured",
|
|
110
108
|
query: { status: "ACTIVE", isFeatured: true, limit: 20, page: 1 },
|
|
111
|
-
href: "/marketplace"
|
|
112
|
-
linkLabel: "Marketplace"
|
|
109
|
+
href: "/marketplace"
|
|
113
110
|
}
|
|
114
111
|
);
|
|
115
112
|
}
|
|
@@ -121,7 +118,6 @@ function CollectionsStrip() {
|
|
|
121
118
|
icon: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.TrendingUp, { className: "h-4 w-4" }),
|
|
122
119
|
title: "Collections",
|
|
123
120
|
href: "/collections",
|
|
124
|
-
linkLabel: "See all",
|
|
125
121
|
children: isLoading ? Array.from({ length: 5 }).map((_, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "w-56 shrink-0 snap-start sm:w-64", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_collection_card.CollectionCardSkeleton, {}) }, i)) : collections.map((col) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "w-56 shrink-0 snap-start sm:w-64", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_collection_card.CollectionCard, { collection: col }) }, col.contractAddress))
|
|
126
122
|
}
|
|
127
123
|
);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/home-page.tsx"],"sourcesContent":["\"use client\";\n\nimport { assetHref, collectionHref, type ApiCollection, type ApiOrdersQuery } from \"@medialane/sdk\";\nimport type { ReactNode } from \"react\";\nimport { Sparkles, Tag, TrendingUp } from \"lucide-react\";\nimport Link from \"./link.js\";\nimport { PageContainer } from \"./page-container.js\";\nimport { HeroSlider } from \"./hero-slider.js\";\nimport { ActivityTicker } from \"./activity-ticker.js\";\nimport { ScrollSection } from \"./scroll-section.js\";\nimport { ListingCard, ListingCardSkeleton } from \"./listing-card.js\";\nimport { ListingCardMenu } from \"./listing-card-menu.js\";\nimport { CollectionCard, CollectionCardSkeleton } from \"./collection-card.js\";\nimport { RewardsSection } from \"./rewards-section.js\";\nimport { LaunchpadStrip } from \"./launchpad-strip.js\";\nimport { useMedialaneApp } from \"./medialane-app.js\";\nimport type { CollectionMarketActions } from \"./collection-page.js\";\nimport { useOrders } from \"../utils/use-orders.js\";\nimport { useCollections } from \"../utils/use-collections.js\";\nimport { useUsdPrices } from \"../utils/use-usd-prices.js\";\nimport { orderUsd } from \"../utils/order-usd.js\";\nimport { isSameAddress } from \"../utils/same-address.js\";\n\nconst LAUNCHPAD_HREFS = {\n nfts: \"/launchpad/single-editions\",\n \"limited-editions\": \"/launchpad/nfteditions\",\n \"collection-drop\": \"/launchpad/drop\",\n \"pop-protocol\": \"/launchpad/pop\",\n \"ip-tickets\": \"/launchpad/tickets\",\n \"creator-coins\": \"/launchpad/coin/create\",\n};\n\nfunction ListingsStrip({\n market, icon, title, query, href,
|
|
1
|
+
{"version":3,"sources":["../../src/components/home-page.tsx"],"sourcesContent":["\"use client\";\n\nimport { assetHref, collectionHref, type ApiCollection, type ApiOrdersQuery } from \"@medialane/sdk\";\nimport type { ReactNode } from \"react\";\nimport { Sparkles, Tag, TrendingUp } from \"lucide-react\";\nimport Link from \"./link.js\";\nimport { PageContainer } from \"./page-container.js\";\nimport { HeroSlider } from \"./hero-slider.js\";\nimport { ActivityTicker } from \"./activity-ticker.js\";\nimport { ScrollSection } from \"./scroll-section.js\";\nimport { ListingCard, ListingCardSkeleton } from \"./listing-card.js\";\nimport { ListingCardMenu } from \"./listing-card-menu.js\";\nimport { CollectionCard, CollectionCardSkeleton } from \"./collection-card.js\";\nimport { RewardsSection } from \"./rewards-section.js\";\nimport { LaunchpadStrip } from \"./launchpad-strip.js\";\nimport { useMedialaneApp } from \"./medialane-app.js\";\nimport type { CollectionMarketActions } from \"./collection-page.js\";\nimport { useOrders } from \"../utils/use-orders.js\";\nimport { useCollections } from \"../utils/use-collections.js\";\nimport { useUsdPrices } from \"../utils/use-usd-prices.js\";\nimport { orderUsd } from \"../utils/order-usd.js\";\nimport { isSameAddress } from \"../utils/same-address.js\";\n\nconst LAUNCHPAD_HREFS = {\n nfts: \"/launchpad/single-editions\",\n \"limited-editions\": \"/launchpad/nfteditions\",\n \"collection-drop\": \"/launchpad/drop\",\n \"pop-protocol\": \"/launchpad/pop\",\n \"ip-tickets\": \"/launchpad/tickets\",\n \"creator-coins\": \"/launchpad/coin/create\",\n};\n\nfunction ListingsStrip({\n market, icon, title, query, href, empty,\n}: {\n market: CollectionMarketActions;\n icon: ReactNode;\n title: string;\n query: ApiOrdersQuery;\n href: string;\n empty?: ReactNode;\n}) {\n const { walletAddress } = useMedialaneApp();\n const { orders, isLoading } = useOrders(query);\n const prices = useUsdPrices();\n const listings = orders.filter((o) => o.offer.itemType === \"ERC721\" || o.offer.itemType === \"ERC1155\").slice(0, 10);\n if (!isLoading && listings.length === 0 && !empty) return null;\n return (\n <ScrollSection icon={icon} title={title} href={href}>\n {isLoading\n ? Array.from({ length: 8 }).map((_, i) => (\n <div key={i} className=\"w-56 shrink-0 snap-start sm:w-64\"><ListingCardSkeleton /></div>\n ))\n : listings.length === 0\n ? empty\n : listings.map((order) => {\n const own = !!walletAddress && isSameAddress(order.offerer, walletAddress);\n return (\n <div key={order.orderHash} className=\"w-56 shrink-0 snap-start sm:w-64\">\n <ListingCard\n order={order}\n onBuy={own ? undefined : () => market.buy(order)}\n overflowMenu={<ListingCardMenu order={order} />}\n usdValue={orderUsd(order.price, prices)}\n />\n </div>\n );\n })}\n </ScrollSection>\n );\n}\n\nfunction NewListings({ market }: { market: CollectionMarketActions }) {\n return (\n <ListingsStrip\n market={market}\n icon={<Tag />}\n title=\"Marketplace\"\n query={{ status: \"ACTIVE\", limit: 10, page: 1 }}\n href=\"/marketplace\"\n empty={\n <p className=\"py-4 text-sm text-muted-foreground\">\n <Link href=\"/launchpad/single-editions\" className=\"text-primary hover:underline\">Sell the first asset</Link>\n </p>\n }\n />\n );\n}\n\nfunction FeaturedListings({ market }: { market: CollectionMarketActions }) {\n return (\n <ListingsStrip\n market={market}\n icon={<Sparkles />}\n title=\"Featured\"\n query={{ status: \"ACTIVE\", isFeatured: true, limit: 20, page: 1 }}\n href=\"/marketplace\"\n />\n );\n}\n\nfunction CollectionsStrip() {\n const { collections, isLoading } = useCollections(1, 10, undefined, \"recent\");\n return (\n <ScrollSection\n icon={<TrendingUp className=\"h-4 w-4\" />}\n title=\"Collections\"\n href=\"/collections\"\n >\n {isLoading\n ? Array.from({ length: 5 }).map((_, i) => (\n <div key={i} className=\"w-56 shrink-0 snap-start sm:w-64\"><CollectionCardSkeleton /></div>\n ))\n : collections.map((col) => (\n <div key={col.contractAddress} className=\"w-56 shrink-0 snap-start sm:w-64\"><CollectionCard collection={col} /></div>\n ))}\n </ScrollSection>\n );\n}\n\nexport interface HomePageProps {\n useMarketActions: () => CollectionMarketActions;\n initialFeatured?: ApiCollection[];\n}\n\nexport function HomePage({ useMarketActions, initialFeatured }: HomePageProps) {\n const market = useMarketActions();\n const { collections: featured, isLoading: featuredLoading } = useCollections(1, 3, true, \"recent\", true, undefined, undefined, initialFeatured);\n const { orders: tickerOrders } = useOrders({ status: \"ACTIVE\", sort: \"recent\", limit: 14 });\n return (\n <div className=\"pb-20\">\n <HeroSlider collections={featured} isLoading={featuredLoading} getHref={(c) => collectionHref(\"STARKNET\", c.contractAddress)} />\n <PageContainer className=\"box-border max-w-full pt-6 pb-0\">\n <ActivityTicker orders={tickerOrders} minItems={3} getHref={(o) => assetHref(\"STARKNET\", o.nftContract, o.nftTokenId)} />\n </PageContainer>\n <PageContainer className=\"mt-16 box-border max-w-full space-y-10 pt-0 pb-0 sm:space-y-16 lg:space-y-20\">\n <NewListings market={market} />\n <FeaturedListings market={market} />\n <CollectionsStrip />\n <RewardsSection rewardsHref=\"/rewards\" />\n <LaunchpadStrip hrefs={LAUNCHPAD_HREFS} marketplaceHref=\"/marketplace\" launchpadHref=\"/launchpad\" />\n </PageContainer>\n {market.dialogs}\n </div>\n );\n}\n"],"mappings":"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","names":["Link"]}
|
|
@@ -32,7 +32,6 @@ function ListingsStrip({
|
|
|
32
32
|
title,
|
|
33
33
|
query,
|
|
34
34
|
href,
|
|
35
|
-
linkLabel,
|
|
36
35
|
empty
|
|
37
36
|
}) {
|
|
38
37
|
const { walletAddress } = useMedialaneApp();
|
|
@@ -40,7 +39,7 @@ function ListingsStrip({
|
|
|
40
39
|
const prices = useUsdPrices();
|
|
41
40
|
const listings = orders.filter((o) => o.offer.itemType === "ERC721" || o.offer.itemType === "ERC1155").slice(0, 10);
|
|
42
41
|
if (!isLoading && listings.length === 0 && !empty) return null;
|
|
43
|
-
return /* @__PURE__ */ jsx(ScrollSection, { icon, title, href,
|
|
42
|
+
return /* @__PURE__ */ jsx(ScrollSection, { icon, title, href, children: isLoading ? Array.from({ length: 8 }).map((_, i) => /* @__PURE__ */ jsx("div", { className: "w-56 shrink-0 snap-start sm:w-64", children: /* @__PURE__ */ jsx(ListingCardSkeleton, {}) }, i)) : listings.length === 0 ? empty : listings.map((order) => {
|
|
44
43
|
const own = !!walletAddress && isSameAddress(order.offerer, walletAddress);
|
|
45
44
|
return /* @__PURE__ */ jsx("div", { className: "w-56 shrink-0 snap-start sm:w-64", children: /* @__PURE__ */ jsx(
|
|
46
45
|
ListingCard,
|
|
@@ -59,10 +58,9 @@ function NewListings({ market }) {
|
|
|
59
58
|
{
|
|
60
59
|
market,
|
|
61
60
|
icon: /* @__PURE__ */ jsx(Tag, {}),
|
|
62
|
-
title: "
|
|
61
|
+
title: "Marketplace",
|
|
63
62
|
query: { status: "ACTIVE", limit: 10, page: 1 },
|
|
64
63
|
href: "/marketplace",
|
|
65
|
-
linkLabel: "Marketplace",
|
|
66
64
|
empty: /* @__PURE__ */ jsx("p", { className: "py-4 text-sm text-muted-foreground", children: /* @__PURE__ */ jsx(Link, { href: "/launchpad/single-editions", className: "text-primary hover:underline", children: "Sell the first asset" }) })
|
|
67
65
|
}
|
|
68
66
|
);
|
|
@@ -73,10 +71,9 @@ function FeaturedListings({ market }) {
|
|
|
73
71
|
{
|
|
74
72
|
market,
|
|
75
73
|
icon: /* @__PURE__ */ jsx(Sparkles, {}),
|
|
76
|
-
title: "Featured
|
|
74
|
+
title: "Featured",
|
|
77
75
|
query: { status: "ACTIVE", isFeatured: true, limit: 20, page: 1 },
|
|
78
|
-
href: "/marketplace"
|
|
79
|
-
linkLabel: "Marketplace"
|
|
76
|
+
href: "/marketplace"
|
|
80
77
|
}
|
|
81
78
|
);
|
|
82
79
|
}
|
|
@@ -88,7 +85,6 @@ function CollectionsStrip() {
|
|
|
88
85
|
icon: /* @__PURE__ */ jsx(TrendingUp, { className: "h-4 w-4" }),
|
|
89
86
|
title: "Collections",
|
|
90
87
|
href: "/collections",
|
|
91
|
-
linkLabel: "See all",
|
|
92
88
|
children: isLoading ? Array.from({ length: 5 }).map((_, i) => /* @__PURE__ */ jsx("div", { className: "w-56 shrink-0 snap-start sm:w-64", children: /* @__PURE__ */ jsx(CollectionCardSkeleton, {}) }, i)) : collections.map((col) => /* @__PURE__ */ jsx("div", { className: "w-56 shrink-0 snap-start sm:w-64", children: /* @__PURE__ */ jsx(CollectionCard, { collection: col }) }, col.contractAddress))
|
|
93
89
|
}
|
|
94
90
|
);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/home-page.tsx"],"sourcesContent":["\"use client\";\n\nimport { assetHref, collectionHref, type ApiCollection, type ApiOrdersQuery } from \"@medialane/sdk\";\nimport type { ReactNode } from \"react\";\nimport { Sparkles, Tag, TrendingUp } from \"lucide-react\";\nimport Link from \"./link.js\";\nimport { PageContainer } from \"./page-container.js\";\nimport { HeroSlider } from \"./hero-slider.js\";\nimport { ActivityTicker } from \"./activity-ticker.js\";\nimport { ScrollSection } from \"./scroll-section.js\";\nimport { ListingCard, ListingCardSkeleton } from \"./listing-card.js\";\nimport { ListingCardMenu } from \"./listing-card-menu.js\";\nimport { CollectionCard, CollectionCardSkeleton } from \"./collection-card.js\";\nimport { RewardsSection } from \"./rewards-section.js\";\nimport { LaunchpadStrip } from \"./launchpad-strip.js\";\nimport { useMedialaneApp } from \"./medialane-app.js\";\nimport type { CollectionMarketActions } from \"./collection-page.js\";\nimport { useOrders } from \"../utils/use-orders.js\";\nimport { useCollections } from \"../utils/use-collections.js\";\nimport { useUsdPrices } from \"../utils/use-usd-prices.js\";\nimport { orderUsd } from \"../utils/order-usd.js\";\nimport { isSameAddress } from \"../utils/same-address.js\";\n\nconst LAUNCHPAD_HREFS = {\n nfts: \"/launchpad/single-editions\",\n \"limited-editions\": \"/launchpad/nfteditions\",\n \"collection-drop\": \"/launchpad/drop\",\n \"pop-protocol\": \"/launchpad/pop\",\n \"ip-tickets\": \"/launchpad/tickets\",\n \"creator-coins\": \"/launchpad/coin/create\",\n};\n\nfunction ListingsStrip({\n market, icon, title, query, href,
|
|
1
|
+
{"version":3,"sources":["../../src/components/home-page.tsx"],"sourcesContent":["\"use client\";\n\nimport { assetHref, collectionHref, type ApiCollection, type ApiOrdersQuery } from \"@medialane/sdk\";\nimport type { ReactNode } from \"react\";\nimport { Sparkles, Tag, TrendingUp } from \"lucide-react\";\nimport Link from \"./link.js\";\nimport { PageContainer } from \"./page-container.js\";\nimport { HeroSlider } from \"./hero-slider.js\";\nimport { ActivityTicker } from \"./activity-ticker.js\";\nimport { ScrollSection } from \"./scroll-section.js\";\nimport { ListingCard, ListingCardSkeleton } from \"./listing-card.js\";\nimport { ListingCardMenu } from \"./listing-card-menu.js\";\nimport { CollectionCard, CollectionCardSkeleton } from \"./collection-card.js\";\nimport { RewardsSection } from \"./rewards-section.js\";\nimport { LaunchpadStrip } from \"./launchpad-strip.js\";\nimport { useMedialaneApp } from \"./medialane-app.js\";\nimport type { CollectionMarketActions } from \"./collection-page.js\";\nimport { useOrders } from \"../utils/use-orders.js\";\nimport { useCollections } from \"../utils/use-collections.js\";\nimport { useUsdPrices } from \"../utils/use-usd-prices.js\";\nimport { orderUsd } from \"../utils/order-usd.js\";\nimport { isSameAddress } from \"../utils/same-address.js\";\n\nconst LAUNCHPAD_HREFS = {\n nfts: \"/launchpad/single-editions\",\n \"limited-editions\": \"/launchpad/nfteditions\",\n \"collection-drop\": \"/launchpad/drop\",\n \"pop-protocol\": \"/launchpad/pop\",\n \"ip-tickets\": \"/launchpad/tickets\",\n \"creator-coins\": \"/launchpad/coin/create\",\n};\n\nfunction ListingsStrip({\n market, icon, title, query, href, empty,\n}: {\n market: CollectionMarketActions;\n icon: ReactNode;\n title: string;\n query: ApiOrdersQuery;\n href: string;\n empty?: ReactNode;\n}) {\n const { walletAddress } = useMedialaneApp();\n const { orders, isLoading } = useOrders(query);\n const prices = useUsdPrices();\n const listings = orders.filter((o) => o.offer.itemType === \"ERC721\" || o.offer.itemType === \"ERC1155\").slice(0, 10);\n if (!isLoading && listings.length === 0 && !empty) return null;\n return (\n <ScrollSection icon={icon} title={title} href={href}>\n {isLoading\n ? Array.from({ length: 8 }).map((_, i) => (\n <div key={i} className=\"w-56 shrink-0 snap-start sm:w-64\"><ListingCardSkeleton /></div>\n ))\n : listings.length === 0\n ? empty\n : listings.map((order) => {\n const own = !!walletAddress && isSameAddress(order.offerer, walletAddress);\n return (\n <div key={order.orderHash} className=\"w-56 shrink-0 snap-start sm:w-64\">\n <ListingCard\n order={order}\n onBuy={own ? undefined : () => market.buy(order)}\n overflowMenu={<ListingCardMenu order={order} />}\n usdValue={orderUsd(order.price, prices)}\n />\n </div>\n );\n })}\n </ScrollSection>\n );\n}\n\nfunction NewListings({ market }: { market: CollectionMarketActions }) {\n return (\n <ListingsStrip\n market={market}\n icon={<Tag />}\n title=\"Marketplace\"\n query={{ status: \"ACTIVE\", limit: 10, page: 1 }}\n href=\"/marketplace\"\n empty={\n <p className=\"py-4 text-sm text-muted-foreground\">\n <Link href=\"/launchpad/single-editions\" className=\"text-primary hover:underline\">Sell the first asset</Link>\n </p>\n }\n />\n );\n}\n\nfunction FeaturedListings({ market }: { market: CollectionMarketActions }) {\n return (\n <ListingsStrip\n market={market}\n icon={<Sparkles />}\n title=\"Featured\"\n query={{ status: \"ACTIVE\", isFeatured: true, limit: 20, page: 1 }}\n href=\"/marketplace\"\n />\n );\n}\n\nfunction CollectionsStrip() {\n const { collections, isLoading } = useCollections(1, 10, undefined, \"recent\");\n return (\n <ScrollSection\n icon={<TrendingUp className=\"h-4 w-4\" />}\n title=\"Collections\"\n href=\"/collections\"\n >\n {isLoading\n ? Array.from({ length: 5 }).map((_, i) => (\n <div key={i} className=\"w-56 shrink-0 snap-start sm:w-64\"><CollectionCardSkeleton /></div>\n ))\n : collections.map((col) => (\n <div key={col.contractAddress} className=\"w-56 shrink-0 snap-start sm:w-64\"><CollectionCard collection={col} /></div>\n ))}\n </ScrollSection>\n );\n}\n\nexport interface HomePageProps {\n useMarketActions: () => CollectionMarketActions;\n initialFeatured?: ApiCollection[];\n}\n\nexport function HomePage({ useMarketActions, initialFeatured }: HomePageProps) {\n const market = useMarketActions();\n const { collections: featured, isLoading: featuredLoading } = useCollections(1, 3, true, \"recent\", true, undefined, undefined, initialFeatured);\n const { orders: tickerOrders } = useOrders({ status: \"ACTIVE\", sort: \"recent\", limit: 14 });\n return (\n <div className=\"pb-20\">\n <HeroSlider collections={featured} isLoading={featuredLoading} getHref={(c) => collectionHref(\"STARKNET\", c.contractAddress)} />\n <PageContainer className=\"box-border max-w-full pt-6 pb-0\">\n <ActivityTicker orders={tickerOrders} minItems={3} getHref={(o) => assetHref(\"STARKNET\", o.nftContract, o.nftTokenId)} />\n </PageContainer>\n <PageContainer className=\"mt-16 box-border max-w-full space-y-10 pt-0 pb-0 sm:space-y-16 lg:space-y-20\">\n <NewListings market={market} />\n <FeaturedListings market={market} />\n <CollectionsStrip />\n <RewardsSection rewardsHref=\"/rewards\" />\n <LaunchpadStrip hrefs={LAUNCHPAD_HREFS} marketplaceHref=\"/marketplace\" launchpadHref=\"/launchpad\" />\n </PageContainer>\n {market.dialogs}\n </div>\n );\n}\n"],"mappings":"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","names":[]}
|
|
@@ -39,9 +39,8 @@ var import_link = __toESM(require("./link.js"), 1);
|
|
|
39
39
|
var import_lucide_react = require("lucide-react");
|
|
40
40
|
var import_motion_primitives = require("./motion-primitives.js");
|
|
41
41
|
var import_animated_token_media = require("./animated-token-media.js");
|
|
42
|
-
var
|
|
42
|
+
var import_price_display = require("./price-display.js");
|
|
43
43
|
var import_cn = require("../utils/cn.js");
|
|
44
|
-
var import_format = require("../utils/format.js");
|
|
45
44
|
var import_time = require("../utils/time.js");
|
|
46
45
|
var import_living_render_collections = require("../data/living-render-collections.js");
|
|
47
46
|
var import_sdk = require("@medialane/sdk");
|
|
@@ -51,18 +50,7 @@ function CardPrice({
|
|
|
51
50
|
currency,
|
|
52
51
|
usdValue
|
|
53
52
|
}) {
|
|
54
|
-
|
|
55
|
-
const amount = (0, import_format.formatDisplayPrice)(amountFormatted);
|
|
56
|
-
const primary = usdValue ?? amount;
|
|
57
|
-
const showAmount = !!usdValue && !(0, import_format.isStableCurrency)(currency);
|
|
58
|
-
const marker = (0, import_currency_icon.hasCurrencyIcon)(currency) ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_currency_icon.CurrencyIcon, { symbol: currency, size: 14 }) : currency;
|
|
59
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { className: "flex items-center gap-1.5 tabular-nums", children: [
|
|
60
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "text-base font-bold tracking-tight", children: primary }),
|
|
61
|
-
marker || showAmount ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "inline-flex items-center gap-1 text-xs text-muted-foreground", children: [
|
|
62
|
-
marker,
|
|
63
|
-
showAmount ? amount : null
|
|
64
|
-
] }) : null
|
|
65
|
-
] });
|
|
53
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_price_display.PriceDisplay, { amountFormatted, currency, usdValue, scale: "card" });
|
|
66
54
|
}
|
|
67
55
|
function ListingCard({ order: rawOrder, inCart = false, onBuy, onCart, overflowMenu, primaryAction, compact = false, imageUrl, usdValue }) {
|
|
68
56
|
const resolveImage = (0, import_use_image_url.useImageUrl)();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/listing-card.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState } from \"react\";\nimport Link from \"./link.js\";\nimport { ShoppingCart, Check, Zap, ArrowUpRight } from \"lucide-react\";\nimport { MotionCard } from \"./motion-primitives.js\";\nimport { AnimatedTokenMedia } from \"./animated-token-media.js\";\nimport { CurrencyIcon, hasCurrencyIcon } from \"./currency-icon.js\";\nimport { cn } from \"../utils/cn.js\";\nimport { formatDisplayPrice, isStableCurrency } from \"../utils/format.js\";\nimport { timeAgo } from \"../utils/time.js\";\nimport { isLivingRenderCollection } from \"../data/living-render-collections.js\";\nimport { assetHref as buildAssetHref, type ApiOrder, type Chain } from \"@medialane/sdk\";\nimport { useImageUrl } from \"../utils/use-image-url.js\";\n\ntype OrderWithAnimation = ApiOrder & { token: (ApiOrder[\"token\"] & { animationUrl?: string | null }) | null };\n\nfunction CardPrice({\n amountFormatted, currency, usdValue,\n}: {\n amountFormatted: string | null | undefined;\n currency: string | null | undefined;\n usdValue?: string | null;\n}) {\n if (!amountFormatted) return null;\n const amount = formatDisplayPrice(amountFormatted);\n const primary = usdValue ?? amount;\n const showAmount = !!usdValue && !isStableCurrency(currency);\n const marker = hasCurrencyIcon(currency) ? <CurrencyIcon symbol={currency} size={14} /> : currency;\n return (\n <p className=\"flex items-center gap-1.5 tabular-nums\">\n <span className=\"text-base font-bold tracking-tight\">{primary}</span>\n {marker || showAmount ? (\n <span className=\"inline-flex items-center gap-1 text-xs text-muted-foreground\">\n {marker}\n {showAmount ? amount : null}\n </span>\n ) : null}\n </p>\n );\n}\n\nexport interface ListingCardProps {\n order: ApiOrder;\n inCart?: boolean;\n onBuy?: (order: ApiOrder) => void;\n onCart?: (order: ApiOrder) => void;\n\n overflowMenu?: React.ReactNode;\n\n primaryAction?: React.ReactNode;\n compact?: boolean;\n\n imageUrl?: string | null;\n\n usdValue?: string | null;\n}\n\nexport function ListingCard({ order: rawOrder, inCart = false, onBuy, onCart, overflowMenu, primaryAction, compact = false, imageUrl, usdValue }: ListingCardProps) {\n const resolveImage = useImageUrl();\n const order = rawOrder as OrderWithAnimation;\n const [imgError, setImgError] = useState(false);\n const isListing = order.offer.itemType === \"ERC721\" || order.offer.itemType === \"ERC1155\";\n const name = order.token?.name ?? `Token #${order.nftTokenId}`;\n const image = imageUrl !== undefined ? imageUrl : (order.token?.image ? resolveImage(order.token.image, { width: 480 }) : null);\n\n const animationUrl = order.token?.animationUrl ?? null;\n const live = !!(order.chain && order.nftContract) && isLivingRenderCollection(order.chain.toUpperCase() as Chain, order.nftContract!);\n const assetHref = buildAssetHref(\"STARKNET\", order.nftContract ?? \"\", order.nftTokenId ?? \"\");\n\n const showActionBar = !!(onBuy || onCart || overflowMenu || primaryAction);\n\n if (compact) {\n return (\n <MotionCard className=\"group overflow-hidden rounded-[calc(var(--radius)*1.25)] bg-card\">\n <Link href={assetHref} className=\"block\">\n <div className=\"relative aspect-square bg-muted overflow-hidden\">\n <AnimatedTokenMedia\n image={image}\n animationUrl={animationUrl}\n live={live}\n alt={name}\n mode=\"fill\"\n sizes=\"(max-width: 640px) 33vw, 20vw\"\n className=\"object-cover\"\n imgError={imgError}\n onImageError={() => setImgError(true)}\n fallback={\n <div className=\"absolute inset-0 bg-gradient-to-br from-brand-purple/15 to-brand-blue/15\" />\n }\n />\n </div>\n <div className=\"p-2.5 space-y-0.5\">\n <p className=\"text-xs font-medium truncate\">{name}</p>\n <CardPrice amountFormatted={order.price?.formatted} currency={order.price?.currency} usdValue={usdValue} />\n <p className=\"text-2xs text-muted-foreground\">{timeAgo(order.createdAt)}</p>\n </div>\n </Link>\n </MotionCard>\n );\n }\n\n return (\n <MotionCard className=\"group overflow-hidden rounded-[calc(var(--radius)*1.25)] bg-card\">\n <Link href={assetHref} className=\"block\">\n <div className=\"relative aspect-square bg-muted overflow-hidden\">\n <AnimatedTokenMedia\n image={image}\n animationUrl={animationUrl}\n live={live}\n alt={name}\n mode=\"fill\"\n sizes=\"(max-width: 640px) 50vw, (max-width: 1024px) 33vw, 25vw\"\n className=\"object-cover\"\n imgError={imgError}\n onImageError={() => setImgError(true)}\n fallback={\n <div className=\"absolute inset-0 bg-gradient-to-br from-brand-purple/15 to-brand-blue/15\" />\n }\n />\n </div>\n\n <div className=\"p-3.5 space-y-2.5\">\n <div className=\"min-w-0 space-y-1\">\n <p className=\"text-sm font-medium truncate\">{name}</p>\n <CardPrice amountFormatted={order.price?.formatted} currency={order.price?.currency} usdValue={usdValue} />\n </div>\n\n {showActionBar && (\n <div className=\"flex items-center gap-1.5\">\n {isListing ? (\n primaryAction ? (\n primaryAction\n ) : onBuy ? (\n <div className=\"btn-border-animated p-[1.5px] rounded-[10px] flex-1 h-9\">\n <button\n className=\"w-full h-full rounded-[9px] bg-background flex items-center justify-center gap-1.5 text-xs font-semibold text-foreground hover:bg-muted/60 transition-all active:scale-[0.98]\"\n onClick={(e) => { e.preventDefault(); onBuy(order); }}\n >\n <Zap className=\"h-3.5 w-3.5 shrink-0\" /> Buy\n </button>\n </div>\n ) : (\n <Link\n href={assetHref}\n className=\"flex-1 h-9 inline-flex items-center justify-center gap-1.5 rounded-[9px] border border-border bg-background text-xs font-semibold text-foreground hover:bg-muted/60 transition-all active:scale-[0.98]\"\n >\n <ArrowUpRight className=\"h-3.5 w-3.5 shrink-0\" /> View\n </Link>\n )\n ) : (\n <Link\n href={assetHref}\n className=\"flex-1 h-9 inline-flex items-center justify-center gap-1.5 rounded-[9px] border border-border bg-background text-xs font-semibold text-foreground hover:bg-muted/60 transition-all active:scale-[0.98]\"\n >\n <ArrowUpRight className=\"h-3.5 w-3.5 shrink-0\" /> View asset\n </Link>\n )}\n {onCart && (\n <button\n className={cn(\n \"min-h-11 min-w-11 shrink-0 rounded-[9px] border flex items-center justify-center transition-colors\",\n inCart\n ? \"border-brand-orange/50 bg-brand-orange/10 text-brand-orange\"\n : \"border-border bg-background hover:bg-muted text-foreground\"\n )}\n onClick={(e) => { e.preventDefault(); if (!inCart) onCart(order); }}\n disabled={inCart}\n aria-label={inCart ? \"Added to cart\" : \"Add to cart\"}\n >\n {inCart ? <Check className=\"h-3.5 w-3.5\" /> : <ShoppingCart className=\"h-3.5 w-3.5\" />}\n </button>\n )}\n {overflowMenu}\n </div>\n )}\n </div>\n </Link>\n </MotionCard>\n );\n}\n\nexport function ListingCardSkeleton() {\n return (\n <div className=\"overflow-hidden rounded-[calc(var(--radius)*1.25)] bg-card\">\n <div className=\"aspect-square w-full bg-muted animate-pulse\" />\n <div className=\"p-3.5 space-y-2.5\">\n <div className=\"space-y-1\">\n <div className=\"h-4 w-3/4 bg-muted animate-pulse rounded\" />\n <div className=\"h-5 w-1/2 bg-muted animate-pulse rounded\" />\n </div>\n <div className=\"h-9 w-full bg-muted animate-pulse rounded-[9px]\" />\n </div>\n </div>\n );\n}\n"],"mappings":"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","names":["buildAssetHref","Link"]}
|
|
1
|
+
{"version":3,"sources":["../../src/components/listing-card.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState } from \"react\";\nimport Link from \"./link.js\";\nimport { ShoppingCart, Check, Zap, ArrowUpRight } from \"lucide-react\";\nimport { MotionCard } from \"./motion-primitives.js\";\nimport { AnimatedTokenMedia } from \"./animated-token-media.js\";\nimport { PriceDisplay } from \"./price-display.js\";\nimport { cn } from \"../utils/cn.js\";\nimport { timeAgo } from \"../utils/time.js\";\nimport { isLivingRenderCollection } from \"../data/living-render-collections.js\";\nimport { assetHref as buildAssetHref, type ApiOrder, type Chain } from \"@medialane/sdk\";\nimport { useImageUrl } from \"../utils/use-image-url.js\";\n\ntype OrderWithAnimation = ApiOrder & { token: (ApiOrder[\"token\"] & { animationUrl?: string | null }) | null };\n\nfunction CardPrice({\n amountFormatted, currency, usdValue,\n}: {\n amountFormatted: string | null | undefined;\n currency: string | null | undefined;\n usdValue?: string | null;\n}) {\n return <PriceDisplay amountFormatted={amountFormatted} currency={currency} usdValue={usdValue} scale=\"card\" />;\n}\n\nexport interface ListingCardProps {\n order: ApiOrder;\n inCart?: boolean;\n onBuy?: (order: ApiOrder) => void;\n onCart?: (order: ApiOrder) => void;\n\n overflowMenu?: React.ReactNode;\n\n primaryAction?: React.ReactNode;\n compact?: boolean;\n\n imageUrl?: string | null;\n\n usdValue?: string | null;\n}\n\nexport function ListingCard({ order: rawOrder, inCart = false, onBuy, onCart, overflowMenu, primaryAction, compact = false, imageUrl, usdValue }: ListingCardProps) {\n const resolveImage = useImageUrl();\n const order = rawOrder as OrderWithAnimation;\n const [imgError, setImgError] = useState(false);\n const isListing = order.offer.itemType === \"ERC721\" || order.offer.itemType === \"ERC1155\";\n const name = order.token?.name ?? `Token #${order.nftTokenId}`;\n const image = imageUrl !== undefined ? imageUrl : (order.token?.image ? resolveImage(order.token.image, { width: 480 }) : null);\n\n const animationUrl = order.token?.animationUrl ?? null;\n const live = !!(order.chain && order.nftContract) && isLivingRenderCollection(order.chain.toUpperCase() as Chain, order.nftContract!);\n const assetHref = buildAssetHref(\"STARKNET\", order.nftContract ?? \"\", order.nftTokenId ?? \"\");\n\n const showActionBar = !!(onBuy || onCart || overflowMenu || primaryAction);\n\n if (compact) {\n return (\n <MotionCard className=\"group overflow-hidden rounded-[calc(var(--radius)*1.25)] bg-card\">\n <Link href={assetHref} className=\"block\">\n <div className=\"relative aspect-square bg-muted overflow-hidden\">\n <AnimatedTokenMedia\n image={image}\n animationUrl={animationUrl}\n live={live}\n alt={name}\n mode=\"fill\"\n sizes=\"(max-width: 640px) 33vw, 20vw\"\n className=\"object-cover\"\n imgError={imgError}\n onImageError={() => setImgError(true)}\n fallback={\n <div className=\"absolute inset-0 bg-gradient-to-br from-brand-purple/15 to-brand-blue/15\" />\n }\n />\n </div>\n <div className=\"p-2.5 space-y-0.5\">\n <p className=\"text-xs font-medium truncate\">{name}</p>\n <CardPrice amountFormatted={order.price?.formatted} currency={order.price?.currency} usdValue={usdValue} />\n <p className=\"text-2xs text-muted-foreground\">{timeAgo(order.createdAt)}</p>\n </div>\n </Link>\n </MotionCard>\n );\n }\n\n return (\n <MotionCard className=\"group overflow-hidden rounded-[calc(var(--radius)*1.25)] bg-card\">\n <Link href={assetHref} className=\"block\">\n <div className=\"relative aspect-square bg-muted overflow-hidden\">\n <AnimatedTokenMedia\n image={image}\n animationUrl={animationUrl}\n live={live}\n alt={name}\n mode=\"fill\"\n sizes=\"(max-width: 640px) 50vw, (max-width: 1024px) 33vw, 25vw\"\n className=\"object-cover\"\n imgError={imgError}\n onImageError={() => setImgError(true)}\n fallback={\n <div className=\"absolute inset-0 bg-gradient-to-br from-brand-purple/15 to-brand-blue/15\" />\n }\n />\n </div>\n\n <div className=\"p-3.5 space-y-2.5\">\n <div className=\"min-w-0 space-y-1\">\n <p className=\"text-sm font-medium truncate\">{name}</p>\n <CardPrice amountFormatted={order.price?.formatted} currency={order.price?.currency} usdValue={usdValue} />\n </div>\n\n {showActionBar && (\n <div className=\"flex items-center gap-1.5\">\n {isListing ? (\n primaryAction ? (\n primaryAction\n ) : onBuy ? (\n <div className=\"btn-border-animated p-[1.5px] rounded-[10px] flex-1 h-9\">\n <button\n className=\"w-full h-full rounded-[9px] bg-background flex items-center justify-center gap-1.5 text-xs font-semibold text-foreground hover:bg-muted/60 transition-all active:scale-[0.98]\"\n onClick={(e) => { e.preventDefault(); onBuy(order); }}\n >\n <Zap className=\"h-3.5 w-3.5 shrink-0\" /> Buy\n </button>\n </div>\n ) : (\n <Link\n href={assetHref}\n className=\"flex-1 h-9 inline-flex items-center justify-center gap-1.5 rounded-[9px] border border-border bg-background text-xs font-semibold text-foreground hover:bg-muted/60 transition-all active:scale-[0.98]\"\n >\n <ArrowUpRight className=\"h-3.5 w-3.5 shrink-0\" /> View\n </Link>\n )\n ) : (\n <Link\n href={assetHref}\n className=\"flex-1 h-9 inline-flex items-center justify-center gap-1.5 rounded-[9px] border border-border bg-background text-xs font-semibold text-foreground hover:bg-muted/60 transition-all active:scale-[0.98]\"\n >\n <ArrowUpRight className=\"h-3.5 w-3.5 shrink-0\" /> View asset\n </Link>\n )}\n {onCart && (\n <button\n className={cn(\n \"min-h-11 min-w-11 shrink-0 rounded-[9px] border flex items-center justify-center transition-colors\",\n inCart\n ? \"border-brand-orange/50 bg-brand-orange/10 text-brand-orange\"\n : \"border-border bg-background hover:bg-muted text-foreground\"\n )}\n onClick={(e) => { e.preventDefault(); if (!inCart) onCart(order); }}\n disabled={inCart}\n aria-label={inCart ? \"Added to cart\" : \"Add to cart\"}\n >\n {inCart ? <Check className=\"h-3.5 w-3.5\" /> : <ShoppingCart className=\"h-3.5 w-3.5\" />}\n </button>\n )}\n {overflowMenu}\n </div>\n )}\n </div>\n </Link>\n </MotionCard>\n );\n}\n\nexport function ListingCardSkeleton() {\n return (\n <div className=\"overflow-hidden rounded-[calc(var(--radius)*1.25)] bg-card\">\n <div className=\"aspect-square w-full bg-muted animate-pulse\" />\n <div className=\"p-3.5 space-y-2.5\">\n <div className=\"space-y-1\">\n <div className=\"h-4 w-3/4 bg-muted animate-pulse rounded\" />\n <div className=\"h-5 w-1/2 bg-muted animate-pulse rounded\" />\n </div>\n <div className=\"h-9 w-full bg-muted animate-pulse rounded-[9px]\" />\n </div>\n </div>\n );\n}\n"],"mappings":"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","names":["buildAssetHref","Link"]}
|
|
@@ -5,9 +5,8 @@ import Link from "./link.js";
|
|
|
5
5
|
import { ShoppingCart, Check, Zap, ArrowUpRight } from "lucide-react";
|
|
6
6
|
import { MotionCard } from "./motion-primitives.js";
|
|
7
7
|
import { AnimatedTokenMedia } from "./animated-token-media.js";
|
|
8
|
-
import {
|
|
8
|
+
import { PriceDisplay } from "./price-display.js";
|
|
9
9
|
import { cn } from "../utils/cn.js";
|
|
10
|
-
import { formatDisplayPrice, isStableCurrency } from "../utils/format.js";
|
|
11
10
|
import { timeAgo } from "../utils/time.js";
|
|
12
11
|
import { isLivingRenderCollection } from "../data/living-render-collections.js";
|
|
13
12
|
import { assetHref as buildAssetHref } from "@medialane/sdk";
|
|
@@ -17,18 +16,7 @@ function CardPrice({
|
|
|
17
16
|
currency,
|
|
18
17
|
usdValue
|
|
19
18
|
}) {
|
|
20
|
-
|
|
21
|
-
const amount = formatDisplayPrice(amountFormatted);
|
|
22
|
-
const primary = usdValue ?? amount;
|
|
23
|
-
const showAmount = !!usdValue && !isStableCurrency(currency);
|
|
24
|
-
const marker = hasCurrencyIcon(currency) ? /* @__PURE__ */ jsx(CurrencyIcon, { symbol: currency, size: 14 }) : currency;
|
|
25
|
-
return /* @__PURE__ */ jsxs("p", { className: "flex items-center gap-1.5 tabular-nums", children: [
|
|
26
|
-
/* @__PURE__ */ jsx("span", { className: "text-base font-bold tracking-tight", children: primary }),
|
|
27
|
-
marker || showAmount ? /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1 text-xs text-muted-foreground", children: [
|
|
28
|
-
marker,
|
|
29
|
-
showAmount ? amount : null
|
|
30
|
-
] }) : null
|
|
31
|
-
] });
|
|
19
|
+
return /* @__PURE__ */ jsx(PriceDisplay, { amountFormatted, currency, usdValue, scale: "card" });
|
|
32
20
|
}
|
|
33
21
|
function ListingCard({ order: rawOrder, inCart = false, onBuy, onCart, overflowMenu, primaryAction, compact = false, imageUrl, usdValue }) {
|
|
34
22
|
const resolveImage = useImageUrl();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/listing-card.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState } from \"react\";\nimport Link from \"./link.js\";\nimport { ShoppingCart, Check, Zap, ArrowUpRight } from \"lucide-react\";\nimport { MotionCard } from \"./motion-primitives.js\";\nimport { AnimatedTokenMedia } from \"./animated-token-media.js\";\nimport { CurrencyIcon, hasCurrencyIcon } from \"./currency-icon.js\";\nimport { cn } from \"../utils/cn.js\";\nimport { formatDisplayPrice, isStableCurrency } from \"../utils/format.js\";\nimport { timeAgo } from \"../utils/time.js\";\nimport { isLivingRenderCollection } from \"../data/living-render-collections.js\";\nimport { assetHref as buildAssetHref, type ApiOrder, type Chain } from \"@medialane/sdk\";\nimport { useImageUrl } from \"../utils/use-image-url.js\";\n\ntype OrderWithAnimation = ApiOrder & { token: (ApiOrder[\"token\"] & { animationUrl?: string | null }) | null };\n\nfunction CardPrice({\n amountFormatted, currency, usdValue,\n}: {\n amountFormatted: string | null | undefined;\n currency: string | null | undefined;\n usdValue?: string | null;\n}) {\n if (!amountFormatted) return null;\n const amount = formatDisplayPrice(amountFormatted);\n const primary = usdValue ?? amount;\n const showAmount = !!usdValue && !isStableCurrency(currency);\n const marker = hasCurrencyIcon(currency) ? <CurrencyIcon symbol={currency} size={14} /> : currency;\n return (\n <p className=\"flex items-center gap-1.5 tabular-nums\">\n <span className=\"text-base font-bold tracking-tight\">{primary}</span>\n {marker || showAmount ? (\n <span className=\"inline-flex items-center gap-1 text-xs text-muted-foreground\">\n {marker}\n {showAmount ? amount : null}\n </span>\n ) : null}\n </p>\n );\n}\n\nexport interface ListingCardProps {\n order: ApiOrder;\n inCart?: boolean;\n onBuy?: (order: ApiOrder) => void;\n onCart?: (order: ApiOrder) => void;\n\n overflowMenu?: React.ReactNode;\n\n primaryAction?: React.ReactNode;\n compact?: boolean;\n\n imageUrl?: string | null;\n\n usdValue?: string | null;\n}\n\nexport function ListingCard({ order: rawOrder, inCart = false, onBuy, onCart, overflowMenu, primaryAction, compact = false, imageUrl, usdValue }: ListingCardProps) {\n const resolveImage = useImageUrl();\n const order = rawOrder as OrderWithAnimation;\n const [imgError, setImgError] = useState(false);\n const isListing = order.offer.itemType === \"ERC721\" || order.offer.itemType === \"ERC1155\";\n const name = order.token?.name ?? `Token #${order.nftTokenId}`;\n const image = imageUrl !== undefined ? imageUrl : (order.token?.image ? resolveImage(order.token.image, { width: 480 }) : null);\n\n const animationUrl = order.token?.animationUrl ?? null;\n const live = !!(order.chain && order.nftContract) && isLivingRenderCollection(order.chain.toUpperCase() as Chain, order.nftContract!);\n const assetHref = buildAssetHref(\"STARKNET\", order.nftContract ?? \"\", order.nftTokenId ?? \"\");\n\n const showActionBar = !!(onBuy || onCart || overflowMenu || primaryAction);\n\n if (compact) {\n return (\n <MotionCard className=\"group overflow-hidden rounded-[calc(var(--radius)*1.25)] bg-card\">\n <Link href={assetHref} className=\"block\">\n <div className=\"relative aspect-square bg-muted overflow-hidden\">\n <AnimatedTokenMedia\n image={image}\n animationUrl={animationUrl}\n live={live}\n alt={name}\n mode=\"fill\"\n sizes=\"(max-width: 640px) 33vw, 20vw\"\n className=\"object-cover\"\n imgError={imgError}\n onImageError={() => setImgError(true)}\n fallback={\n <div className=\"absolute inset-0 bg-gradient-to-br from-brand-purple/15 to-brand-blue/15\" />\n }\n />\n </div>\n <div className=\"p-2.5 space-y-0.5\">\n <p className=\"text-xs font-medium truncate\">{name}</p>\n <CardPrice amountFormatted={order.price?.formatted} currency={order.price?.currency} usdValue={usdValue} />\n <p className=\"text-2xs text-muted-foreground\">{timeAgo(order.createdAt)}</p>\n </div>\n </Link>\n </MotionCard>\n );\n }\n\n return (\n <MotionCard className=\"group overflow-hidden rounded-[calc(var(--radius)*1.25)] bg-card\">\n <Link href={assetHref} className=\"block\">\n <div className=\"relative aspect-square bg-muted overflow-hidden\">\n <AnimatedTokenMedia\n image={image}\n animationUrl={animationUrl}\n live={live}\n alt={name}\n mode=\"fill\"\n sizes=\"(max-width: 640px) 50vw, (max-width: 1024px) 33vw, 25vw\"\n className=\"object-cover\"\n imgError={imgError}\n onImageError={() => setImgError(true)}\n fallback={\n <div className=\"absolute inset-0 bg-gradient-to-br from-brand-purple/15 to-brand-blue/15\" />\n }\n />\n </div>\n\n <div className=\"p-3.5 space-y-2.5\">\n <div className=\"min-w-0 space-y-1\">\n <p className=\"text-sm font-medium truncate\">{name}</p>\n <CardPrice amountFormatted={order.price?.formatted} currency={order.price?.currency} usdValue={usdValue} />\n </div>\n\n {showActionBar && (\n <div className=\"flex items-center gap-1.5\">\n {isListing ? (\n primaryAction ? (\n primaryAction\n ) : onBuy ? (\n <div className=\"btn-border-animated p-[1.5px] rounded-[10px] flex-1 h-9\">\n <button\n className=\"w-full h-full rounded-[9px] bg-background flex items-center justify-center gap-1.5 text-xs font-semibold text-foreground hover:bg-muted/60 transition-all active:scale-[0.98]\"\n onClick={(e) => { e.preventDefault(); onBuy(order); }}\n >\n <Zap className=\"h-3.5 w-3.5 shrink-0\" /> Buy\n </button>\n </div>\n ) : (\n <Link\n href={assetHref}\n className=\"flex-1 h-9 inline-flex items-center justify-center gap-1.5 rounded-[9px] border border-border bg-background text-xs font-semibold text-foreground hover:bg-muted/60 transition-all active:scale-[0.98]\"\n >\n <ArrowUpRight className=\"h-3.5 w-3.5 shrink-0\" /> View\n </Link>\n )\n ) : (\n <Link\n href={assetHref}\n className=\"flex-1 h-9 inline-flex items-center justify-center gap-1.5 rounded-[9px] border border-border bg-background text-xs font-semibold text-foreground hover:bg-muted/60 transition-all active:scale-[0.98]\"\n >\n <ArrowUpRight className=\"h-3.5 w-3.5 shrink-0\" /> View asset\n </Link>\n )}\n {onCart && (\n <button\n className={cn(\n \"min-h-11 min-w-11 shrink-0 rounded-[9px] border flex items-center justify-center transition-colors\",\n inCart\n ? \"border-brand-orange/50 bg-brand-orange/10 text-brand-orange\"\n : \"border-border bg-background hover:bg-muted text-foreground\"\n )}\n onClick={(e) => { e.preventDefault(); if (!inCart) onCart(order); }}\n disabled={inCart}\n aria-label={inCart ? \"Added to cart\" : \"Add to cart\"}\n >\n {inCart ? <Check className=\"h-3.5 w-3.5\" /> : <ShoppingCart className=\"h-3.5 w-3.5\" />}\n </button>\n )}\n {overflowMenu}\n </div>\n )}\n </div>\n </Link>\n </MotionCard>\n );\n}\n\nexport function ListingCardSkeleton() {\n return (\n <div className=\"overflow-hidden rounded-[calc(var(--radius)*1.25)] bg-card\">\n <div className=\"aspect-square w-full bg-muted animate-pulse\" />\n <div className=\"p-3.5 space-y-2.5\">\n <div className=\"space-y-1\">\n <div className=\"h-4 w-3/4 bg-muted animate-pulse rounded\" />\n <div className=\"h-5 w-1/2 bg-muted animate-pulse rounded\" />\n </div>\n <div className=\"h-9 w-full bg-muted animate-pulse rounded-[9px]\" />\n </div>\n </div>\n );\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/components/listing-card.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState } from \"react\";\nimport Link from \"./link.js\";\nimport { ShoppingCart, Check, Zap, ArrowUpRight } from \"lucide-react\";\nimport { MotionCard } from \"./motion-primitives.js\";\nimport { AnimatedTokenMedia } from \"./animated-token-media.js\";\nimport { PriceDisplay } from \"./price-display.js\";\nimport { cn } from \"../utils/cn.js\";\nimport { timeAgo } from \"../utils/time.js\";\nimport { isLivingRenderCollection } from \"../data/living-render-collections.js\";\nimport { assetHref as buildAssetHref, type ApiOrder, type Chain } from \"@medialane/sdk\";\nimport { useImageUrl } from \"../utils/use-image-url.js\";\n\ntype OrderWithAnimation = ApiOrder & { token: (ApiOrder[\"token\"] & { animationUrl?: string | null }) | null };\n\nfunction CardPrice({\n amountFormatted, currency, usdValue,\n}: {\n amountFormatted: string | null | undefined;\n currency: string | null | undefined;\n usdValue?: string | null;\n}) {\n return <PriceDisplay amountFormatted={amountFormatted} currency={currency} usdValue={usdValue} scale=\"card\" />;\n}\n\nexport interface ListingCardProps {\n order: ApiOrder;\n inCart?: boolean;\n onBuy?: (order: ApiOrder) => void;\n onCart?: (order: ApiOrder) => void;\n\n overflowMenu?: React.ReactNode;\n\n primaryAction?: React.ReactNode;\n compact?: boolean;\n\n imageUrl?: string | null;\n\n usdValue?: string | null;\n}\n\nexport function ListingCard({ order: rawOrder, inCart = false, onBuy, onCart, overflowMenu, primaryAction, compact = false, imageUrl, usdValue }: ListingCardProps) {\n const resolveImage = useImageUrl();\n const order = rawOrder as OrderWithAnimation;\n const [imgError, setImgError] = useState(false);\n const isListing = order.offer.itemType === \"ERC721\" || order.offer.itemType === \"ERC1155\";\n const name = order.token?.name ?? `Token #${order.nftTokenId}`;\n const image = imageUrl !== undefined ? imageUrl : (order.token?.image ? resolveImage(order.token.image, { width: 480 }) : null);\n\n const animationUrl = order.token?.animationUrl ?? null;\n const live = !!(order.chain && order.nftContract) && isLivingRenderCollection(order.chain.toUpperCase() as Chain, order.nftContract!);\n const assetHref = buildAssetHref(\"STARKNET\", order.nftContract ?? \"\", order.nftTokenId ?? \"\");\n\n const showActionBar = !!(onBuy || onCart || overflowMenu || primaryAction);\n\n if (compact) {\n return (\n <MotionCard className=\"group overflow-hidden rounded-[calc(var(--radius)*1.25)] bg-card\">\n <Link href={assetHref} className=\"block\">\n <div className=\"relative aspect-square bg-muted overflow-hidden\">\n <AnimatedTokenMedia\n image={image}\n animationUrl={animationUrl}\n live={live}\n alt={name}\n mode=\"fill\"\n sizes=\"(max-width: 640px) 33vw, 20vw\"\n className=\"object-cover\"\n imgError={imgError}\n onImageError={() => setImgError(true)}\n fallback={\n <div className=\"absolute inset-0 bg-gradient-to-br from-brand-purple/15 to-brand-blue/15\" />\n }\n />\n </div>\n <div className=\"p-2.5 space-y-0.5\">\n <p className=\"text-xs font-medium truncate\">{name}</p>\n <CardPrice amountFormatted={order.price?.formatted} currency={order.price?.currency} usdValue={usdValue} />\n <p className=\"text-2xs text-muted-foreground\">{timeAgo(order.createdAt)}</p>\n </div>\n </Link>\n </MotionCard>\n );\n }\n\n return (\n <MotionCard className=\"group overflow-hidden rounded-[calc(var(--radius)*1.25)] bg-card\">\n <Link href={assetHref} className=\"block\">\n <div className=\"relative aspect-square bg-muted overflow-hidden\">\n <AnimatedTokenMedia\n image={image}\n animationUrl={animationUrl}\n live={live}\n alt={name}\n mode=\"fill\"\n sizes=\"(max-width: 640px) 50vw, (max-width: 1024px) 33vw, 25vw\"\n className=\"object-cover\"\n imgError={imgError}\n onImageError={() => setImgError(true)}\n fallback={\n <div className=\"absolute inset-0 bg-gradient-to-br from-brand-purple/15 to-brand-blue/15\" />\n }\n />\n </div>\n\n <div className=\"p-3.5 space-y-2.5\">\n <div className=\"min-w-0 space-y-1\">\n <p className=\"text-sm font-medium truncate\">{name}</p>\n <CardPrice amountFormatted={order.price?.formatted} currency={order.price?.currency} usdValue={usdValue} />\n </div>\n\n {showActionBar && (\n <div className=\"flex items-center gap-1.5\">\n {isListing ? (\n primaryAction ? (\n primaryAction\n ) : onBuy ? (\n <div className=\"btn-border-animated p-[1.5px] rounded-[10px] flex-1 h-9\">\n <button\n className=\"w-full h-full rounded-[9px] bg-background flex items-center justify-center gap-1.5 text-xs font-semibold text-foreground hover:bg-muted/60 transition-all active:scale-[0.98]\"\n onClick={(e) => { e.preventDefault(); onBuy(order); }}\n >\n <Zap className=\"h-3.5 w-3.5 shrink-0\" /> Buy\n </button>\n </div>\n ) : (\n <Link\n href={assetHref}\n className=\"flex-1 h-9 inline-flex items-center justify-center gap-1.5 rounded-[9px] border border-border bg-background text-xs font-semibold text-foreground hover:bg-muted/60 transition-all active:scale-[0.98]\"\n >\n <ArrowUpRight className=\"h-3.5 w-3.5 shrink-0\" /> View\n </Link>\n )\n ) : (\n <Link\n href={assetHref}\n className=\"flex-1 h-9 inline-flex items-center justify-center gap-1.5 rounded-[9px] border border-border bg-background text-xs font-semibold text-foreground hover:bg-muted/60 transition-all active:scale-[0.98]\"\n >\n <ArrowUpRight className=\"h-3.5 w-3.5 shrink-0\" /> View asset\n </Link>\n )}\n {onCart && (\n <button\n className={cn(\n \"min-h-11 min-w-11 shrink-0 rounded-[9px] border flex items-center justify-center transition-colors\",\n inCart\n ? \"border-brand-orange/50 bg-brand-orange/10 text-brand-orange\"\n : \"border-border bg-background hover:bg-muted text-foreground\"\n )}\n onClick={(e) => { e.preventDefault(); if (!inCart) onCart(order); }}\n disabled={inCart}\n aria-label={inCart ? \"Added to cart\" : \"Add to cart\"}\n >\n {inCart ? <Check className=\"h-3.5 w-3.5\" /> : <ShoppingCart className=\"h-3.5 w-3.5\" />}\n </button>\n )}\n {overflowMenu}\n </div>\n )}\n </div>\n </Link>\n </MotionCard>\n );\n}\n\nexport function ListingCardSkeleton() {\n return (\n <div className=\"overflow-hidden rounded-[calc(var(--radius)*1.25)] bg-card\">\n <div className=\"aspect-square w-full bg-muted animate-pulse\" />\n <div className=\"p-3.5 space-y-2.5\">\n <div className=\"space-y-1\">\n <div className=\"h-4 w-3/4 bg-muted animate-pulse rounded\" />\n <div className=\"h-5 w-1/2 bg-muted animate-pulse rounded\" />\n </div>\n <div className=\"h-9 w-full bg-muted animate-pulse rounded-[9px]\" />\n </div>\n </div>\n );\n}\n"],"mappings":"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","names":[]}
|
|
@@ -70,7 +70,7 @@ function PortfolioSection({
|
|
|
70
70
|
href,
|
|
71
71
|
className: "inline-flex items-center gap-1 text-xs font-medium text-muted-foreground hover:text-foreground transition-colors",
|
|
72
72
|
children: [
|
|
73
|
-
"
|
|
73
|
+
"View all",
|
|
74
74
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.ArrowRight, { className: "h-3 w-3" })
|
|
75
75
|
]
|
|
76
76
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/portfolio-section.tsx"],"sourcesContent":["\"use client\";\n\nimport Link from \"./link.js\";\nimport { ArrowRight } from \"lucide-react\";\nimport { cn } from \"../utils/cn.js\";\n\nexport type PortfolioSectionColor =\n | \"blue\"\n | \"purple\"\n | \"rose\"\n | \"orange\"\n | \"maeve\"\n | \"navy\";\n\nconst BORDER_BY_COLOR: Record<PortfolioSectionColor, string> = {\n blue: \"border-brand-blue/40\",\n purple: \"border-brand-purple/40\",\n rose: \"border-brand-rose/40\",\n orange: \"border-brand-orange/40\",\n maeve: \"border-brand-maeve/40\",\n navy: \"border-brand-navy/40\",\n};\n\nexport interface PortfolioSectionProps {\n title: string;\n href: string;\n\n color?: PortfolioSectionColor;\n\n size?: \"default\" | \"wide\";\n children: React.ReactNode;\n className?: string;\n}\n\nexport function PortfolioSection({\n title,\n href,\n color = \"purple\",\n size = \"default\",\n children,\n className,\n}: PortfolioSectionProps) {\n return (\n <section\n className={cn(\n \"rounded-2xl border min-w-0\",\n BORDER_BY_COLOR[color],\n size === \"wide\" && \"sm:col-span-2 lg:col-span-3\",\n className,\n )}\n >\n <div className=\"flex items-center justify-between gap-3 px-5 pt-5 pb-3\">\n <h2 className=\"text-sm font-black text-foreground tracking-tight\">\n {title}\n </h2>\n <Link\n href={href}\n className=\"inline-flex items-center gap-1 text-xs font-medium text-muted-foreground hover:text-foreground transition-colors\"\n >\n
|
|
1
|
+
{"version":3,"sources":["../../src/components/portfolio-section.tsx"],"sourcesContent":["\"use client\";\n\nimport Link from \"./link.js\";\nimport { ArrowRight } from \"lucide-react\";\nimport { cn } from \"../utils/cn.js\";\n\nexport type PortfolioSectionColor =\n | \"blue\"\n | \"purple\"\n | \"rose\"\n | \"orange\"\n | \"maeve\"\n | \"navy\";\n\nconst BORDER_BY_COLOR: Record<PortfolioSectionColor, string> = {\n blue: \"border-brand-blue/40\",\n purple: \"border-brand-purple/40\",\n rose: \"border-brand-rose/40\",\n orange: \"border-brand-orange/40\",\n maeve: \"border-brand-maeve/40\",\n navy: \"border-brand-navy/40\",\n};\n\nexport interface PortfolioSectionProps {\n title: string;\n href: string;\n\n color?: PortfolioSectionColor;\n\n size?: \"default\" | \"wide\";\n children: React.ReactNode;\n className?: string;\n}\n\nexport function PortfolioSection({\n title,\n href,\n color = \"purple\",\n size = \"default\",\n children,\n className,\n}: PortfolioSectionProps) {\n return (\n <section\n className={cn(\n \"rounded-2xl border min-w-0\",\n BORDER_BY_COLOR[color],\n size === \"wide\" && \"sm:col-span-2 lg:col-span-3\",\n className,\n )}\n >\n <div className=\"flex items-center justify-between gap-3 px-5 pt-5 pb-3\">\n <h2 className=\"text-sm font-black text-foreground tracking-tight\">\n {title}\n </h2>\n <Link\n href={href}\n className=\"inline-flex items-center gap-1 text-xs font-medium text-muted-foreground hover:text-foreground transition-colors\"\n >\n View all\n <ArrowRight className=\"h-3 w-3\" />\n </Link>\n </div>\n <div className=\"px-5 pb-5\">{children}</div>\n </section>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAoDQ;AAlDR,kBAAiB;AACjB,0BAA2B;AAC3B,gBAAmB;AAUnB,MAAM,kBAAyD;AAAA,EAC7D,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,MAAM;AACR;AAaO,SAAS,iBAAiB;AAAA,EAC/B;AAAA,EACA;AAAA,EACA,QAAQ;AAAA,EACR,OAAO;AAAA,EACP;AAAA,EACA;AACF,GAA0B;AACxB,SACE;AAAA,IAAC;AAAA;AAAA,MACC,eAAW;AAAA,QACT;AAAA,QACA,gBAAgB,KAAK;AAAA,QACrB,SAAS,UAAU;AAAA,QACnB;AAAA,MACF;AAAA,MAEA;AAAA,qDAAC,SAAI,WAAU,0DACb;AAAA,sDAAC,QAAG,WAAU,qDACX,iBACH;AAAA,UACA;AAAA,YAAC,YAAAA;AAAA,YAAA;AAAA,cACC;AAAA,cACA,WAAU;AAAA,cACX;AAAA;AAAA,gBAEC,4CAAC,kCAAW,WAAU,WAAU;AAAA;AAAA;AAAA,UAClC;AAAA,WACF;AAAA,QACA,4CAAC,SAAI,WAAU,aAAa,UAAS;AAAA;AAAA;AAAA,EACvC;AAEJ;","names":["Link"]}
|
|
@@ -37,7 +37,7 @@ function PortfolioSection({
|
|
|
37
37
|
href,
|
|
38
38
|
className: "inline-flex items-center gap-1 text-xs font-medium text-muted-foreground hover:text-foreground transition-colors",
|
|
39
39
|
children: [
|
|
40
|
-
"
|
|
40
|
+
"View all",
|
|
41
41
|
/* @__PURE__ */ jsx(ArrowRight, { className: "h-3 w-3" })
|
|
42
42
|
]
|
|
43
43
|
}
|