@medialane/ui 0.288.0 → 0.289.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/asset-page.cjs +3 -2
- package/dist/components/asset-page.cjs.map +1 -1
- package/dist/components/asset-page.js +3 -2
- package/dist/components/asset-page.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 +1 -1
- package/dist/components/button.d.ts +1 -1
- package/dist/components/collection-page.cjs +3 -2
- package/dist/components/collection-page.cjs.map +1 -1
- package/dist/components/collection-page.js +3 -2
- package/dist/components/collection-page.js.map +1 -1
- package/dist/components/comments-section.cjs +3 -3
- package/dist/components/comments-section.cjs.map +1 -1
- package/dist/components/comments-section.js +2 -2
- package/dist/components/comments-section.js.map +1 -1
- package/dist/components/creator-page.cjs +6 -5
- package/dist/components/creator-page.cjs.map +1 -1
- package/dist/components/creator-page.js +5 -4
- package/dist/components/creator-page.js.map +1 -1
- package/dist/components/launchpad/edition-mint-schema.d.cts +2 -2
- package/dist/components/launchpad/edition-mint-schema.d.ts +2 -2
- package/dist/components/listing-card-menu.cjs +10 -13
- package/dist/components/listing-card-menu.cjs.map +1 -1
- package/dist/components/listing-card-menu.js +10 -13
- package/dist/components/listing-card-menu.js.map +1 -1
- package/dist/components/medialane-app.cjs.map +1 -1
- package/dist/components/medialane-app.d.cts +2 -8
- package/dist/components/medialane-app.d.ts +2 -8
- package/dist/components/medialane-app.js.map +1 -1
- package/dist/components/portfolio-assets.cjs +4 -5
- package/dist/components/portfolio-assets.cjs.map +1 -1
- package/dist/components/portfolio-assets.js +3 -4
- package/dist/components/portfolio-assets.js.map +1 -1
- package/dist/components/report-dialog.cjs +191 -0
- package/dist/components/report-dialog.cjs.map +1 -0
- package/dist/components/report-dialog.d.cts +17 -0
- package/dist/components/report-dialog.d.ts +17 -0
- package/dist/components/report-dialog.js +167 -0
- package/dist/components/report-dialog.js.map +1 -0
- package/dist/index.cjs +3 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -50,6 +50,7 @@ var import_listing_card_menu = require("./listing-card-menu.js");
|
|
|
50
50
|
var import_activity_timeline_row = require("./activity-timeline-row.js");
|
|
51
51
|
var import_more_menu = require("./more-menu.js");
|
|
52
52
|
var import_medialane_app = require("./medialane-app.js");
|
|
53
|
+
var import_report_dialog = require("./report-dialog.js");
|
|
53
54
|
var import_cn = require("../utils/cn.js");
|
|
54
55
|
var import_explorer_url = require("../utils/explorer-url.js");
|
|
55
56
|
var import_same_address = require("../utils/same-address.js");
|
|
@@ -72,7 +73,7 @@ const TABS = [
|
|
|
72
73
|
const GRID = "grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5 gap-4";
|
|
73
74
|
const isNft = (itemType) => itemType === "ERC721" || itemType === "ERC1155";
|
|
74
75
|
function CreatorPage({ address: addressProp, username, useAssetActions, useMarketActions }) {
|
|
75
|
-
const { walletAddress
|
|
76
|
+
const { walletAddress } = (0, import_medialane_app.useMedialaneApp)();
|
|
76
77
|
const client = (0, import_use_medialane_client.useMedialaneClient)();
|
|
77
78
|
const resolveImage = (0, import_use_image_url.useImageUrl)();
|
|
78
79
|
const prices = (0, import_use_usd_prices.useUsdPrices)();
|
|
@@ -168,7 +169,7 @@ function CreatorPage({ address: addressProp, username, useAssetActions, useMarke
|
|
|
168
169
|
onCancel: isOwner ? actions.cancel : void 0,
|
|
169
170
|
onBuy: !isOwner && listing ? () => market.buy(listing) : void 0,
|
|
170
171
|
onOffer: isOwner ? void 0 : market.offer,
|
|
171
|
-
onReport:
|
|
172
|
+
onReport: setReportToken
|
|
172
173
|
},
|
|
173
174
|
`${t.contractAddress}-${t.tokenId}`
|
|
174
175
|
);
|
|
@@ -179,8 +180,8 @@ function CreatorPage({ address: addressProp, username, useAssetActions, useMarke
|
|
|
179
180
|
] }),
|
|
180
181
|
actions.dialogs,
|
|
181
182
|
market.dialogs,
|
|
182
|
-
|
|
183
|
-
ReportDialog,
|
|
183
|
+
reportToken ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
184
|
+
import_report_dialog.ReportDialog,
|
|
184
185
|
{
|
|
185
186
|
open: !!reportToken,
|
|
186
187
|
onOpenChange: (open) => {
|
|
@@ -189,7 +190,7 @@ function CreatorPage({ address: addressProp, username, useAssetActions, useMarke
|
|
|
189
190
|
target: { type: "TOKEN", contract: reportToken.contractAddress, tokenId: reportToken.tokenId, name: reportToken.metadata?.name ?? void 0 }
|
|
190
191
|
}
|
|
191
192
|
) : null,
|
|
192
|
-
|
|
193
|
+
address ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_report_dialog.ReportDialog, { open: reportOpen, onOpenChange: setReportOpen, target: { type: "CREATOR", address, name: identity.name ?? identity.identity } }) : null
|
|
193
194
|
] });
|
|
194
195
|
}
|
|
195
196
|
// Annotate the CommonJS export names for ESM import in node:
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/creator-page.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState } from \"react\";\nimport useSWR from \"swr\";\nimport { Activity, Image as ImageIcon, LayoutGrid, ShoppingBag } from \"lucide-react\";\nimport type { ApiToken } from \"@medialane/sdk\";\nimport Link from \"./link.js\";\nimport { Button } from \"./button.js\";\nimport { Skeleton } from \"./skeleton.js\";\nimport { AddressDisplay } from \"./address-display.js\";\nimport { CreatorHeader } from \"./creator-header.js\";\nimport { HiddenContentBanner } from \"./hidden-content-banner.js\";\nimport { TabEmptyState } from \"./tab-empty-state.js\";\nimport { TokenCard, TokenCardSkeleton } from \"./token-card.js\";\nimport { CollectionCard, CollectionCardSkeleton } from \"./collection-card.js\";\nimport { ListingCard, ListingCardSkeleton } from \"./listing-card.js\";\nimport { ListingCardMenu } from \"./listing-card-menu.js\";\nimport { ActivityTimelineRow } from \"./activity-timeline-row.js\";\nimport { MoreMenu } from \"./more-menu.js\";\nimport { useMedialaneApp } from \"./medialane-app.js\";\nimport type { UsePortfolioAssetActions } from \"./portfolio-assets.js\";\nimport type { CollectionMarketActions } from \"./collection-page.js\";\nimport { cn } from \"../utils/cn.js\";\nimport { EXPLORER_URL } from \"../utils/explorer-url.js\";\nimport { isSameAddress } from \"../utils/same-address.js\";\nimport { orderUsd } from \"../utils/order-usd.js\";\nimport { profileIdentity } from \"../utils/profile-identity.js\";\nimport { useImageUrl } from \"../utils/use-image-url.js\";\nimport { useMedialaneClient } from \"../utils/use-medialane-client.js\";\nimport { useUsdPrices } from \"../utils/use-usd-prices.js\";\nimport { useTokensByOwner } from \"../utils/use-tokens.js\";\nimport { useCollectionsByOwner } from \"../utils/use-collections.js\";\nimport { useUserOrders } from \"../utils/use-orders.js\";\nimport { useActivitiesByAddress } from \"../utils/use-activities.js\";\nimport { useCreatorByUsername, useCreatorProfile } from \"../utils/use-profiles.js\";\n\nconst TABS = [\n { id: \"assets\", label: \"Assets\", Icon: ImageIcon },\n { id: \"collections\", label: \"Collections\", Icon: LayoutGrid },\n { id: \"listings\", label: \"Listings\", Icon: ShoppingBag },\n { id: \"activity\", label: \"Activity\", Icon: Activity },\n] as const;\n\ntype TabId = (typeof TABS)[number][\"id\"];\n\nconst GRID = \"grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5 gap-4\";\nconst isNft = (itemType: string) => itemType === \"ERC721\" || itemType === \"ERC1155\";\n\nexport interface CreatorPageProps {\n address?: string;\n username?: string;\n useAssetActions: UsePortfolioAssetActions;\n useMarketActions: () => CollectionMarketActions;\n}\n\nexport function CreatorPage({ address: addressProp, username, useAssetActions, useMarketActions }: CreatorPageProps) {\n const { walletAddress, ReportDialog } = useMedialaneApp();\n const client = useMedialaneClient();\n const resolveImage = useImageUrl();\n const prices = useUsdPrices();\n const [activeTab, setActiveTab] = useState<TabId>(\"assets\");\n const [reportOpen, setReportOpen] = useState(false);\n const [reportToken, setReportToken] = useState<ApiToken | null>(null);\n\n const byName = useCreatorByUsername(username);\n const byAddress = useCreatorProfile(username ? undefined : addressProp);\n const creator = username ? byName.creator : byAddress.profile;\n const address = username ? creator?.walletAddress ?? null : addressProp ?? null;\n const isOwner = !!address && !!walletAddress && isSameAddress(address, walletAddress);\n\n const { tokens, meta, isLoading: tokensLoading, mutate: refreshTokens } = useTokensByOwner(address, 1, 20);\n const { collections, isLoading: collectionsLoading } = useCollectionsByOwner(address);\n const { orders, isLoading: ordersLoading } = useUserOrders(activeTab === \"listings\" ? address : null);\n const { activities, isLoading: activitiesLoading } = useActivitiesByAddress(activeTab === \"activity\" ? address : null);\n const { data: hidden } = useSWR(address ? `creator-hidden-${address}` : null, () => client.api.creators.isHidden(address!).catch(() => false));\n const actions = useAssetActions({ refresh: () => void refreshTokens() });\n const market = useMarketActions();\n\n const listings = orders.filter((o) => o.status === \"ACTIVE\" && isNft(o.offer.itemType));\n const identity = profileIdentity({ username: creator?.username, name: creator?.name, walletAddress: address });\n\n if (username && byName.isLoading) {\n return (\n <div className=\"min-h-screen pb-20\">\n <div className=\"px-6 pt-20 pb-6\"><CreatorHeader creator={null} image={null} stats={[]} loading /></div>\n <div className={cn(\"px-6\", GRID)}>{Array.from({ length: 8 }).map((_, i) => <TokenCardSkeleton key={i} />)}</div>\n </div>\n );\n }\n\n if (username && !creator) {\n return (\n <div className=\"mx-auto max-w-lg space-y-4 px-4 py-24 text-center\">\n <h1 className=\"text-2xl font-bold\">Creator not found</h1>\n <p className=\"text-muted-foreground\"><span className=\"tabular-nums\">@{username}</span> isn't a profile yet.</p>\n <Button variant=\"outline\" asChild><Link href=\"/creators\">Browse creators</Link></Button>\n </div>\n );\n }\n\n const counts: Partial<Record<TabId, number>> = {\n assets: meta?.total ?? undefined,\n collections: collectionsLoading ? undefined : collections.length,\n ...(activeTab === \"listings\" && !ordersLoading ? { listings: listings.length } : {}),\n };\n\n return (\n <div className=\"min-h-screen overflow-x-hidden pb-20\">\n {hidden === true ? <HiddenContentBanner /> : null}\n\n <div className=\"px-6 pt-20 pb-6\">\n {creator ? (\n <CreatorHeader\n creator={creator}\n image={resolveImage(creator.avatarImage || tokens[0]?.metadata?.image)}\n stats={[\n { label: \"Assets\", value: meta?.total ?? null },\n { label: \"Collections\", value: collectionsLoading ? null : collections.length },\n ]}\n />\n ) : (\n <div className=\"flex flex-wrap items-center gap-2\">\n <AddressDisplay address={address ?? \"\"} chars={10} className=\"text-base font-semibold tabular-nums\" />\n </div>\n )}\n </div>\n\n <div className=\"sticky top-0 z-20 mt-4 flex items-center gap-2 border-b border-border bg-background/95 px-6 backdrop-blur-sm\">\n <div className=\"-mb-px flex min-w-0 flex-1 items-center gap-0.5 overflow-x-auto scrollbar-none\">\n {TABS.map(({ id, label, Icon }) => {\n const count = counts[id];\n const active = activeTab === id;\n return (\n <button\n key={id}\n onClick={() => setActiveTab(id)}\n className={cn(\n \"relative flex shrink-0 items-center gap-2 whitespace-nowrap px-4 py-3 text-sm font-medium transition-colors duration-200\",\n active ? \"text-foreground\" : \"text-muted-foreground hover:text-foreground\"\n )}\n >\n <Icon className=\"h-3.5 w-3.5\" />\n {label}\n {count ? (\n <span className={cn(\"min-w-[18px] rounded-full px-1.5 py-px text-center text-2xs font-bold tabular-nums\", active ? \"bg-primary/15 text-primary\" : \"bg-muted text-muted-foreground\")}>{count}</span>\n ) : null}\n {active ? <span className=\"absolute inset-x-0 bottom-0 h-0.5 rounded-full bg-primary\" /> : null}\n </button>\n );\n })}\n </div>\n {address ? (\n <MoreMenu explorerHref={`${EXPLORER_URL}/contract/${address}`} shareTitle={identity.name ?? identity.identity} onReport={() => setReportOpen(true)} />\n ) : null}\n </div>\n\n <div className=\"mt-6 px-6\">\n {activeTab === \"assets\" && (\n tokensLoading ? (\n <div className={GRID}>{Array.from({ length: 8 }).map((_, i) => <TokenCardSkeleton key={i} />)}</div>\n ) : tokens.length === 0 ? (\n <TabEmptyState icon={ImageIcon} heading=\"No assets yet\" body=\"Works this creator makes on Medialane appear here.\" />\n ) : (\n <div className={GRID}>\n {tokens.map((t: ApiToken) => {\n const listing = t.activeOrders?.find((o) => isNft(o.offer.itemType));\n return (\n <TokenCard\n key={`${t.contractAddress}-${t.tokenId}`}\n token={t}\n isOwner={isOwner}\n usdValue={orderUsd(listing?.price, prices)}\n onList={isOwner ? actions.list : undefined}\n onTransfer={isOwner ? actions.transfer : undefined}\n onCancel={isOwner ? actions.cancel : undefined}\n onBuy={!isOwner && listing ? () => market.buy(listing) : undefined}\n onOffer={isOwner ? undefined : market.offer}\n onReport={ReportDialog ? setReportToken : undefined}\n />\n );\n })}\n </div>\n )\n )}\n\n {activeTab === \"collections\" && (\n collectionsLoading ? (\n <div className=\"grid grid-cols-2 gap-4 lg:grid-cols-3\">{Array.from({ length: 6 }).map((_, i) => <CollectionCardSkeleton key={i} />)}</div>\n ) : collections.length === 0 ? (\n <TabEmptyState icon={LayoutGrid} heading=\"No collections yet\" body=\"Collections this creator makes appear here.\" />\n ) : (\n <div className=\"grid grid-cols-2 gap-4 lg:grid-cols-3\">{collections.map((c) => <CollectionCard key={c.contractAddress} collection={c} />)}</div>\n )\n )}\n\n {activeTab === \"listings\" && (\n ordersLoading ? (\n <div className={GRID}>{Array.from({ length: 4 }).map((_, i) => <ListingCardSkeleton key={i} />)}</div>\n ) : listings.length === 0 ? (\n <TabEmptyState icon={ShoppingBag} heading=\"No active listings\" body=\"Works this creator lists for sale appear here.\" />\n ) : (\n <div className={GRID}>\n {listings.map((o) => <ListingCard key={o.orderHash} order={o} onBuy={isOwner ? undefined : market.buy} usdValue={orderUsd(o.price, prices)} overflowMenu={<ListingCardMenu order={o} />} />)}\n </div>\n )\n )}\n\n {activeTab === \"activity\" && (\n <div className=\"max-w-2xl\">\n {activitiesLoading ? (\n <div className=\"space-y-5\">{Array.from({ length: 6 }).map((_, i) => <Skeleton key={i} className=\"h-10 w-full rounded-xl\" />)}</div>\n ) : activities.length === 0 ? (\n <TabEmptyState icon={Activity} heading=\"No activity yet\" body=\"This creator's activity appears here as it happens.\" />\n ) : (\n <div>{activities.map((a, i) => <ActivityTimelineRow key={i} event={a} isLast={i === activities.length - 1} />)}</div>\n )}\n </div>\n )}\n </div>\n\n {actions.dialogs}\n {market.dialogs}\n {ReportDialog && reportToken ? (\n <ReportDialog\n open={!!reportToken}\n onOpenChange={(open) => { if (!open) setReportToken(null); }}\n target={{ type: \"TOKEN\", contract: reportToken.contractAddress, tokenId: reportToken.tokenId, name: reportToken.metadata?.name ?? undefined }}\n />\n ) : null}\n {ReportDialog && address ? (\n <ReportDialog open={reportOpen} onOpenChange={setReportOpen} target={{ type: \"CREATOR\", address, name: identity.name ?? identity.identity }} />\n ) : null}\n </div>\n );\n}\n"],"mappings":"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","names":["ImageIcon","useSWR","Link"]}
|
|
1
|
+
{"version":3,"sources":["../../src/components/creator-page.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState } from \"react\";\nimport useSWR from \"swr\";\nimport { Activity, Image as ImageIcon, LayoutGrid, ShoppingBag } from \"lucide-react\";\nimport type { ApiToken } from \"@medialane/sdk\";\nimport Link from \"./link.js\";\nimport { Button } from \"./button.js\";\nimport { Skeleton } from \"./skeleton.js\";\nimport { AddressDisplay } from \"./address-display.js\";\nimport { CreatorHeader } from \"./creator-header.js\";\nimport { HiddenContentBanner } from \"./hidden-content-banner.js\";\nimport { TabEmptyState } from \"./tab-empty-state.js\";\nimport { TokenCard, TokenCardSkeleton } from \"./token-card.js\";\nimport { CollectionCard, CollectionCardSkeleton } from \"./collection-card.js\";\nimport { ListingCard, ListingCardSkeleton } from \"./listing-card.js\";\nimport { ListingCardMenu } from \"./listing-card-menu.js\";\nimport { ActivityTimelineRow } from \"./activity-timeline-row.js\";\nimport { MoreMenu } from \"./more-menu.js\";\nimport { useMedialaneApp } from \"./medialane-app.js\";\nimport { ReportDialog } from \"./report-dialog.js\";\nimport type { UsePortfolioAssetActions } from \"./portfolio-assets.js\";\nimport type { CollectionMarketActions } from \"./collection-page.js\";\nimport { cn } from \"../utils/cn.js\";\nimport { EXPLORER_URL } from \"../utils/explorer-url.js\";\nimport { isSameAddress } from \"../utils/same-address.js\";\nimport { orderUsd } from \"../utils/order-usd.js\";\nimport { profileIdentity } from \"../utils/profile-identity.js\";\nimport { useImageUrl } from \"../utils/use-image-url.js\";\nimport { useMedialaneClient } from \"../utils/use-medialane-client.js\";\nimport { useUsdPrices } from \"../utils/use-usd-prices.js\";\nimport { useTokensByOwner } from \"../utils/use-tokens.js\";\nimport { useCollectionsByOwner } from \"../utils/use-collections.js\";\nimport { useUserOrders } from \"../utils/use-orders.js\";\nimport { useActivitiesByAddress } from \"../utils/use-activities.js\";\nimport { useCreatorByUsername, useCreatorProfile } from \"../utils/use-profiles.js\";\n\nconst TABS = [\n { id: \"assets\", label: \"Assets\", Icon: ImageIcon },\n { id: \"collections\", label: \"Collections\", Icon: LayoutGrid },\n { id: \"listings\", label: \"Listings\", Icon: ShoppingBag },\n { id: \"activity\", label: \"Activity\", Icon: Activity },\n] as const;\n\ntype TabId = (typeof TABS)[number][\"id\"];\n\nconst GRID = \"grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5 gap-4\";\nconst isNft = (itemType: string) => itemType === \"ERC721\" || itemType === \"ERC1155\";\n\nexport interface CreatorPageProps {\n address?: string;\n username?: string;\n useAssetActions: UsePortfolioAssetActions;\n useMarketActions: () => CollectionMarketActions;\n}\n\nexport function CreatorPage({ address: addressProp, username, useAssetActions, useMarketActions }: CreatorPageProps) {\n const { walletAddress } = useMedialaneApp();\n const client = useMedialaneClient();\n const resolveImage = useImageUrl();\n const prices = useUsdPrices();\n const [activeTab, setActiveTab] = useState<TabId>(\"assets\");\n const [reportOpen, setReportOpen] = useState(false);\n const [reportToken, setReportToken] = useState<ApiToken | null>(null);\n\n const byName = useCreatorByUsername(username);\n const byAddress = useCreatorProfile(username ? undefined : addressProp);\n const creator = username ? byName.creator : byAddress.profile;\n const address = username ? creator?.walletAddress ?? null : addressProp ?? null;\n const isOwner = !!address && !!walletAddress && isSameAddress(address, walletAddress);\n\n const { tokens, meta, isLoading: tokensLoading, mutate: refreshTokens } = useTokensByOwner(address, 1, 20);\n const { collections, isLoading: collectionsLoading } = useCollectionsByOwner(address);\n const { orders, isLoading: ordersLoading } = useUserOrders(activeTab === \"listings\" ? address : null);\n const { activities, isLoading: activitiesLoading } = useActivitiesByAddress(activeTab === \"activity\" ? address : null);\n const { data: hidden } = useSWR(address ? `creator-hidden-${address}` : null, () => client.api.creators.isHidden(address!).catch(() => false));\n const actions = useAssetActions({ refresh: () => void refreshTokens() });\n const market = useMarketActions();\n\n const listings = orders.filter((o) => o.status === \"ACTIVE\" && isNft(o.offer.itemType));\n const identity = profileIdentity({ username: creator?.username, name: creator?.name, walletAddress: address });\n\n if (username && byName.isLoading) {\n return (\n <div className=\"min-h-screen pb-20\">\n <div className=\"px-6 pt-20 pb-6\"><CreatorHeader creator={null} image={null} stats={[]} loading /></div>\n <div className={cn(\"px-6\", GRID)}>{Array.from({ length: 8 }).map((_, i) => <TokenCardSkeleton key={i} />)}</div>\n </div>\n );\n }\n\n if (username && !creator) {\n return (\n <div className=\"mx-auto max-w-lg space-y-4 px-4 py-24 text-center\">\n <h1 className=\"text-2xl font-bold\">Creator not found</h1>\n <p className=\"text-muted-foreground\"><span className=\"tabular-nums\">@{username}</span> isn't a profile yet.</p>\n <Button variant=\"outline\" asChild><Link href=\"/creators\">Browse creators</Link></Button>\n </div>\n );\n }\n\n const counts: Partial<Record<TabId, number>> = {\n assets: meta?.total ?? undefined,\n collections: collectionsLoading ? undefined : collections.length,\n ...(activeTab === \"listings\" && !ordersLoading ? { listings: listings.length } : {}),\n };\n\n return (\n <div className=\"min-h-screen overflow-x-hidden pb-20\">\n {hidden === true ? <HiddenContentBanner /> : null}\n\n <div className=\"px-6 pt-20 pb-6\">\n {creator ? (\n <CreatorHeader\n creator={creator}\n image={resolveImage(creator.avatarImage || tokens[0]?.metadata?.image)}\n stats={[\n { label: \"Assets\", value: meta?.total ?? null },\n { label: \"Collections\", value: collectionsLoading ? null : collections.length },\n ]}\n />\n ) : (\n <div className=\"flex flex-wrap items-center gap-2\">\n <AddressDisplay address={address ?? \"\"} chars={10} className=\"text-base font-semibold tabular-nums\" />\n </div>\n )}\n </div>\n\n <div className=\"sticky top-0 z-20 mt-4 flex items-center gap-2 border-b border-border bg-background/95 px-6 backdrop-blur-sm\">\n <div className=\"-mb-px flex min-w-0 flex-1 items-center gap-0.5 overflow-x-auto scrollbar-none\">\n {TABS.map(({ id, label, Icon }) => {\n const count = counts[id];\n const active = activeTab === id;\n return (\n <button\n key={id}\n onClick={() => setActiveTab(id)}\n className={cn(\n \"relative flex shrink-0 items-center gap-2 whitespace-nowrap px-4 py-3 text-sm font-medium transition-colors duration-200\",\n active ? \"text-foreground\" : \"text-muted-foreground hover:text-foreground\"\n )}\n >\n <Icon className=\"h-3.5 w-3.5\" />\n {label}\n {count ? (\n <span className={cn(\"min-w-[18px] rounded-full px-1.5 py-px text-center text-2xs font-bold tabular-nums\", active ? \"bg-primary/15 text-primary\" : \"bg-muted text-muted-foreground\")}>{count}</span>\n ) : null}\n {active ? <span className=\"absolute inset-x-0 bottom-0 h-0.5 rounded-full bg-primary\" /> : null}\n </button>\n );\n })}\n </div>\n {address ? (\n <MoreMenu explorerHref={`${EXPLORER_URL}/contract/${address}`} shareTitle={identity.name ?? identity.identity} onReport={() => setReportOpen(true)} />\n ) : null}\n </div>\n\n <div className=\"mt-6 px-6\">\n {activeTab === \"assets\" && (\n tokensLoading ? (\n <div className={GRID}>{Array.from({ length: 8 }).map((_, i) => <TokenCardSkeleton key={i} />)}</div>\n ) : tokens.length === 0 ? (\n <TabEmptyState icon={ImageIcon} heading=\"No assets yet\" body=\"Works this creator makes on Medialane appear here.\" />\n ) : (\n <div className={GRID}>\n {tokens.map((t: ApiToken) => {\n const listing = t.activeOrders?.find((o) => isNft(o.offer.itemType));\n return (\n <TokenCard\n key={`${t.contractAddress}-${t.tokenId}`}\n token={t}\n isOwner={isOwner}\n usdValue={orderUsd(listing?.price, prices)}\n onList={isOwner ? actions.list : undefined}\n onTransfer={isOwner ? actions.transfer : undefined}\n onCancel={isOwner ? actions.cancel : undefined}\n onBuy={!isOwner && listing ? () => market.buy(listing) : undefined}\n onOffer={isOwner ? undefined : market.offer}\n onReport={setReportToken}\n />\n );\n })}\n </div>\n )\n )}\n\n {activeTab === \"collections\" && (\n collectionsLoading ? (\n <div className=\"grid grid-cols-2 gap-4 lg:grid-cols-3\">{Array.from({ length: 6 }).map((_, i) => <CollectionCardSkeleton key={i} />)}</div>\n ) : collections.length === 0 ? (\n <TabEmptyState icon={LayoutGrid} heading=\"No collections yet\" body=\"Collections this creator makes appear here.\" />\n ) : (\n <div className=\"grid grid-cols-2 gap-4 lg:grid-cols-3\">{collections.map((c) => <CollectionCard key={c.contractAddress} collection={c} />)}</div>\n )\n )}\n\n {activeTab === \"listings\" && (\n ordersLoading ? (\n <div className={GRID}>{Array.from({ length: 4 }).map((_, i) => <ListingCardSkeleton key={i} />)}</div>\n ) : listings.length === 0 ? (\n <TabEmptyState icon={ShoppingBag} heading=\"No active listings\" body=\"Works this creator lists for sale appear here.\" />\n ) : (\n <div className={GRID}>\n {listings.map((o) => <ListingCard key={o.orderHash} order={o} onBuy={isOwner ? undefined : market.buy} usdValue={orderUsd(o.price, prices)} overflowMenu={<ListingCardMenu order={o} />} />)}\n </div>\n )\n )}\n\n {activeTab === \"activity\" && (\n <div className=\"max-w-2xl\">\n {activitiesLoading ? (\n <div className=\"space-y-5\">{Array.from({ length: 6 }).map((_, i) => <Skeleton key={i} className=\"h-10 w-full rounded-xl\" />)}</div>\n ) : activities.length === 0 ? (\n <TabEmptyState icon={Activity} heading=\"No activity yet\" body=\"This creator's activity appears here as it happens.\" />\n ) : (\n <div>{activities.map((a, i) => <ActivityTimelineRow key={i} event={a} isLast={i === activities.length - 1} />)}</div>\n )}\n </div>\n )}\n </div>\n\n {actions.dialogs}\n {market.dialogs}\n {reportToken ? (\n <ReportDialog\n open={!!reportToken}\n onOpenChange={(open) => { if (!open) setReportToken(null); }}\n target={{ type: \"TOKEN\", contract: reportToken.contractAddress, tokenId: reportToken.tokenId, name: reportToken.metadata?.name ?? undefined }}\n />\n ) : null}\n {address ? (\n <ReportDialog open={reportOpen} onOpenChange={setReportOpen} target={{ type: \"CREATOR\", address, name: identity.name ?? identity.identity }} />\n ) : null}\n </div>\n );\n}\n"],"mappings":"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","names":["ImageIcon","useSWR","Link"]}
|
|
@@ -17,6 +17,7 @@ import { ListingCardMenu } from "./listing-card-menu.js";
|
|
|
17
17
|
import { ActivityTimelineRow } from "./activity-timeline-row.js";
|
|
18
18
|
import { MoreMenu } from "./more-menu.js";
|
|
19
19
|
import { useMedialaneApp } from "./medialane-app.js";
|
|
20
|
+
import { ReportDialog } from "./report-dialog.js";
|
|
20
21
|
import { cn } from "../utils/cn.js";
|
|
21
22
|
import { EXPLORER_URL } from "../utils/explorer-url.js";
|
|
22
23
|
import { isSameAddress } from "../utils/same-address.js";
|
|
@@ -39,7 +40,7 @@ const TABS = [
|
|
|
39
40
|
const GRID = "grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5 gap-4";
|
|
40
41
|
const isNft = (itemType) => itemType === "ERC721" || itemType === "ERC1155";
|
|
41
42
|
function CreatorPage({ address: addressProp, username, useAssetActions, useMarketActions }) {
|
|
42
|
-
const { walletAddress
|
|
43
|
+
const { walletAddress } = useMedialaneApp();
|
|
43
44
|
const client = useMedialaneClient();
|
|
44
45
|
const resolveImage = useImageUrl();
|
|
45
46
|
const prices = useUsdPrices();
|
|
@@ -135,7 +136,7 @@ function CreatorPage({ address: addressProp, username, useAssetActions, useMarke
|
|
|
135
136
|
onCancel: isOwner ? actions.cancel : void 0,
|
|
136
137
|
onBuy: !isOwner && listing ? () => market.buy(listing) : void 0,
|
|
137
138
|
onOffer: isOwner ? void 0 : market.offer,
|
|
138
|
-
onReport:
|
|
139
|
+
onReport: setReportToken
|
|
139
140
|
},
|
|
140
141
|
`${t.contractAddress}-${t.tokenId}`
|
|
141
142
|
);
|
|
@@ -146,7 +147,7 @@ function CreatorPage({ address: addressProp, username, useAssetActions, useMarke
|
|
|
146
147
|
] }),
|
|
147
148
|
actions.dialogs,
|
|
148
149
|
market.dialogs,
|
|
149
|
-
|
|
150
|
+
reportToken ? /* @__PURE__ */ jsx(
|
|
150
151
|
ReportDialog,
|
|
151
152
|
{
|
|
152
153
|
open: !!reportToken,
|
|
@@ -156,7 +157,7 @@ function CreatorPage({ address: addressProp, username, useAssetActions, useMarke
|
|
|
156
157
|
target: { type: "TOKEN", contract: reportToken.contractAddress, tokenId: reportToken.tokenId, name: reportToken.metadata?.name ?? void 0 }
|
|
157
158
|
}
|
|
158
159
|
) : null,
|
|
159
|
-
|
|
160
|
+
address ? /* @__PURE__ */ jsx(ReportDialog, { open: reportOpen, onOpenChange: setReportOpen, target: { type: "CREATOR", address, name: identity.name ?? identity.identity } }) : null
|
|
160
161
|
] });
|
|
161
162
|
}
|
|
162
163
|
export {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/creator-page.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState } from \"react\";\nimport useSWR from \"swr\";\nimport { Activity, Image as ImageIcon, LayoutGrid, ShoppingBag } from \"lucide-react\";\nimport type { ApiToken } from \"@medialane/sdk\";\nimport Link from \"./link.js\";\nimport { Button } from \"./button.js\";\nimport { Skeleton } from \"./skeleton.js\";\nimport { AddressDisplay } from \"./address-display.js\";\nimport { CreatorHeader } from \"./creator-header.js\";\nimport { HiddenContentBanner } from \"./hidden-content-banner.js\";\nimport { TabEmptyState } from \"./tab-empty-state.js\";\nimport { TokenCard, TokenCardSkeleton } from \"./token-card.js\";\nimport { CollectionCard, CollectionCardSkeleton } from \"./collection-card.js\";\nimport { ListingCard, ListingCardSkeleton } from \"./listing-card.js\";\nimport { ListingCardMenu } from \"./listing-card-menu.js\";\nimport { ActivityTimelineRow } from \"./activity-timeline-row.js\";\nimport { MoreMenu } from \"./more-menu.js\";\nimport { useMedialaneApp } from \"./medialane-app.js\";\nimport type { UsePortfolioAssetActions } from \"./portfolio-assets.js\";\nimport type { CollectionMarketActions } from \"./collection-page.js\";\nimport { cn } from \"../utils/cn.js\";\nimport { EXPLORER_URL } from \"../utils/explorer-url.js\";\nimport { isSameAddress } from \"../utils/same-address.js\";\nimport { orderUsd } from \"../utils/order-usd.js\";\nimport { profileIdentity } from \"../utils/profile-identity.js\";\nimport { useImageUrl } from \"../utils/use-image-url.js\";\nimport { useMedialaneClient } from \"../utils/use-medialane-client.js\";\nimport { useUsdPrices } from \"../utils/use-usd-prices.js\";\nimport { useTokensByOwner } from \"../utils/use-tokens.js\";\nimport { useCollectionsByOwner } from \"../utils/use-collections.js\";\nimport { useUserOrders } from \"../utils/use-orders.js\";\nimport { useActivitiesByAddress } from \"../utils/use-activities.js\";\nimport { useCreatorByUsername, useCreatorProfile } from \"../utils/use-profiles.js\";\n\nconst TABS = [\n { id: \"assets\", label: \"Assets\", Icon: ImageIcon },\n { id: \"collections\", label: \"Collections\", Icon: LayoutGrid },\n { id: \"listings\", label: \"Listings\", Icon: ShoppingBag },\n { id: \"activity\", label: \"Activity\", Icon: Activity },\n] as const;\n\ntype TabId = (typeof TABS)[number][\"id\"];\n\nconst GRID = \"grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5 gap-4\";\nconst isNft = (itemType: string) => itemType === \"ERC721\" || itemType === \"ERC1155\";\n\nexport interface CreatorPageProps {\n address?: string;\n username?: string;\n useAssetActions: UsePortfolioAssetActions;\n useMarketActions: () => CollectionMarketActions;\n}\n\nexport function CreatorPage({ address: addressProp, username, useAssetActions, useMarketActions }: CreatorPageProps) {\n const { walletAddress, ReportDialog } = useMedialaneApp();\n const client = useMedialaneClient();\n const resolveImage = useImageUrl();\n const prices = useUsdPrices();\n const [activeTab, setActiveTab] = useState<TabId>(\"assets\");\n const [reportOpen, setReportOpen] = useState(false);\n const [reportToken, setReportToken] = useState<ApiToken | null>(null);\n\n const byName = useCreatorByUsername(username);\n const byAddress = useCreatorProfile(username ? undefined : addressProp);\n const creator = username ? byName.creator : byAddress.profile;\n const address = username ? creator?.walletAddress ?? null : addressProp ?? null;\n const isOwner = !!address && !!walletAddress && isSameAddress(address, walletAddress);\n\n const { tokens, meta, isLoading: tokensLoading, mutate: refreshTokens } = useTokensByOwner(address, 1, 20);\n const { collections, isLoading: collectionsLoading } = useCollectionsByOwner(address);\n const { orders, isLoading: ordersLoading } = useUserOrders(activeTab === \"listings\" ? address : null);\n const { activities, isLoading: activitiesLoading } = useActivitiesByAddress(activeTab === \"activity\" ? address : null);\n const { data: hidden } = useSWR(address ? `creator-hidden-${address}` : null, () => client.api.creators.isHidden(address!).catch(() => false));\n const actions = useAssetActions({ refresh: () => void refreshTokens() });\n const market = useMarketActions();\n\n const listings = orders.filter((o) => o.status === \"ACTIVE\" && isNft(o.offer.itemType));\n const identity = profileIdentity({ username: creator?.username, name: creator?.name, walletAddress: address });\n\n if (username && byName.isLoading) {\n return (\n <div className=\"min-h-screen pb-20\">\n <div className=\"px-6 pt-20 pb-6\"><CreatorHeader creator={null} image={null} stats={[]} loading /></div>\n <div className={cn(\"px-6\", GRID)}>{Array.from({ length: 8 }).map((_, i) => <TokenCardSkeleton key={i} />)}</div>\n </div>\n );\n }\n\n if (username && !creator) {\n return (\n <div className=\"mx-auto max-w-lg space-y-4 px-4 py-24 text-center\">\n <h1 className=\"text-2xl font-bold\">Creator not found</h1>\n <p className=\"text-muted-foreground\"><span className=\"tabular-nums\">@{username}</span> isn't a profile yet.</p>\n <Button variant=\"outline\" asChild><Link href=\"/creators\">Browse creators</Link></Button>\n </div>\n );\n }\n\n const counts: Partial<Record<TabId, number>> = {\n assets: meta?.total ?? undefined,\n collections: collectionsLoading ? undefined : collections.length,\n ...(activeTab === \"listings\" && !ordersLoading ? { listings: listings.length } : {}),\n };\n\n return (\n <div className=\"min-h-screen overflow-x-hidden pb-20\">\n {hidden === true ? <HiddenContentBanner /> : null}\n\n <div className=\"px-6 pt-20 pb-6\">\n {creator ? (\n <CreatorHeader\n creator={creator}\n image={resolveImage(creator.avatarImage || tokens[0]?.metadata?.image)}\n stats={[\n { label: \"Assets\", value: meta?.total ?? null },\n { label: \"Collections\", value: collectionsLoading ? null : collections.length },\n ]}\n />\n ) : (\n <div className=\"flex flex-wrap items-center gap-2\">\n <AddressDisplay address={address ?? \"\"} chars={10} className=\"text-base font-semibold tabular-nums\" />\n </div>\n )}\n </div>\n\n <div className=\"sticky top-0 z-20 mt-4 flex items-center gap-2 border-b border-border bg-background/95 px-6 backdrop-blur-sm\">\n <div className=\"-mb-px flex min-w-0 flex-1 items-center gap-0.5 overflow-x-auto scrollbar-none\">\n {TABS.map(({ id, label, Icon }) => {\n const count = counts[id];\n const active = activeTab === id;\n return (\n <button\n key={id}\n onClick={() => setActiveTab(id)}\n className={cn(\n \"relative flex shrink-0 items-center gap-2 whitespace-nowrap px-4 py-3 text-sm font-medium transition-colors duration-200\",\n active ? \"text-foreground\" : \"text-muted-foreground hover:text-foreground\"\n )}\n >\n <Icon className=\"h-3.5 w-3.5\" />\n {label}\n {count ? (\n <span className={cn(\"min-w-[18px] rounded-full px-1.5 py-px text-center text-2xs font-bold tabular-nums\", active ? \"bg-primary/15 text-primary\" : \"bg-muted text-muted-foreground\")}>{count}</span>\n ) : null}\n {active ? <span className=\"absolute inset-x-0 bottom-0 h-0.5 rounded-full bg-primary\" /> : null}\n </button>\n );\n })}\n </div>\n {address ? (\n <MoreMenu explorerHref={`${EXPLORER_URL}/contract/${address}`} shareTitle={identity.name ?? identity.identity} onReport={() => setReportOpen(true)} />\n ) : null}\n </div>\n\n <div className=\"mt-6 px-6\">\n {activeTab === \"assets\" && (\n tokensLoading ? (\n <div className={GRID}>{Array.from({ length: 8 }).map((_, i) => <TokenCardSkeleton key={i} />)}</div>\n ) : tokens.length === 0 ? (\n <TabEmptyState icon={ImageIcon} heading=\"No assets yet\" body=\"Works this creator makes on Medialane appear here.\" />\n ) : (\n <div className={GRID}>\n {tokens.map((t: ApiToken) => {\n const listing = t.activeOrders?.find((o) => isNft(o.offer.itemType));\n return (\n <TokenCard\n key={`${t.contractAddress}-${t.tokenId}`}\n token={t}\n isOwner={isOwner}\n usdValue={orderUsd(listing?.price, prices)}\n onList={isOwner ? actions.list : undefined}\n onTransfer={isOwner ? actions.transfer : undefined}\n onCancel={isOwner ? actions.cancel : undefined}\n onBuy={!isOwner && listing ? () => market.buy(listing) : undefined}\n onOffer={isOwner ? undefined : market.offer}\n onReport={ReportDialog ? setReportToken : undefined}\n />\n );\n })}\n </div>\n )\n )}\n\n {activeTab === \"collections\" && (\n collectionsLoading ? (\n <div className=\"grid grid-cols-2 gap-4 lg:grid-cols-3\">{Array.from({ length: 6 }).map((_, i) => <CollectionCardSkeleton key={i} />)}</div>\n ) : collections.length === 0 ? (\n <TabEmptyState icon={LayoutGrid} heading=\"No collections yet\" body=\"Collections this creator makes appear here.\" />\n ) : (\n <div className=\"grid grid-cols-2 gap-4 lg:grid-cols-3\">{collections.map((c) => <CollectionCard key={c.contractAddress} collection={c} />)}</div>\n )\n )}\n\n {activeTab === \"listings\" && (\n ordersLoading ? (\n <div className={GRID}>{Array.from({ length: 4 }).map((_, i) => <ListingCardSkeleton key={i} />)}</div>\n ) : listings.length === 0 ? (\n <TabEmptyState icon={ShoppingBag} heading=\"No active listings\" body=\"Works this creator lists for sale appear here.\" />\n ) : (\n <div className={GRID}>\n {listings.map((o) => <ListingCard key={o.orderHash} order={o} onBuy={isOwner ? undefined : market.buy} usdValue={orderUsd(o.price, prices)} overflowMenu={<ListingCardMenu order={o} />} />)}\n </div>\n )\n )}\n\n {activeTab === \"activity\" && (\n <div className=\"max-w-2xl\">\n {activitiesLoading ? (\n <div className=\"space-y-5\">{Array.from({ length: 6 }).map((_, i) => <Skeleton key={i} className=\"h-10 w-full rounded-xl\" />)}</div>\n ) : activities.length === 0 ? (\n <TabEmptyState icon={Activity} heading=\"No activity yet\" body=\"This creator's activity appears here as it happens.\" />\n ) : (\n <div>{activities.map((a, i) => <ActivityTimelineRow key={i} event={a} isLast={i === activities.length - 1} />)}</div>\n )}\n </div>\n )}\n </div>\n\n {actions.dialogs}\n {market.dialogs}\n {ReportDialog && reportToken ? (\n <ReportDialog\n open={!!reportToken}\n onOpenChange={(open) => { if (!open) setReportToken(null); }}\n target={{ type: \"TOKEN\", contract: reportToken.contractAddress, tokenId: reportToken.tokenId, name: reportToken.metadata?.name ?? undefined }}\n />\n ) : null}\n {ReportDialog && address ? (\n <ReportDialog open={reportOpen} onOpenChange={setReportOpen} target={{ type: \"CREATOR\", address, name: identity.name ?? identity.identity }} />\n ) : null}\n </div>\n );\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/components/creator-page.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState } from \"react\";\nimport useSWR from \"swr\";\nimport { Activity, Image as ImageIcon, LayoutGrid, ShoppingBag } from \"lucide-react\";\nimport type { ApiToken } from \"@medialane/sdk\";\nimport Link from \"./link.js\";\nimport { Button } from \"./button.js\";\nimport { Skeleton } from \"./skeleton.js\";\nimport { AddressDisplay } from \"./address-display.js\";\nimport { CreatorHeader } from \"./creator-header.js\";\nimport { HiddenContentBanner } from \"./hidden-content-banner.js\";\nimport { TabEmptyState } from \"./tab-empty-state.js\";\nimport { TokenCard, TokenCardSkeleton } from \"./token-card.js\";\nimport { CollectionCard, CollectionCardSkeleton } from \"./collection-card.js\";\nimport { ListingCard, ListingCardSkeleton } from \"./listing-card.js\";\nimport { ListingCardMenu } from \"./listing-card-menu.js\";\nimport { ActivityTimelineRow } from \"./activity-timeline-row.js\";\nimport { MoreMenu } from \"./more-menu.js\";\nimport { useMedialaneApp } from \"./medialane-app.js\";\nimport { ReportDialog } from \"./report-dialog.js\";\nimport type { UsePortfolioAssetActions } from \"./portfolio-assets.js\";\nimport type { CollectionMarketActions } from \"./collection-page.js\";\nimport { cn } from \"../utils/cn.js\";\nimport { EXPLORER_URL } from \"../utils/explorer-url.js\";\nimport { isSameAddress } from \"../utils/same-address.js\";\nimport { orderUsd } from \"../utils/order-usd.js\";\nimport { profileIdentity } from \"../utils/profile-identity.js\";\nimport { useImageUrl } from \"../utils/use-image-url.js\";\nimport { useMedialaneClient } from \"../utils/use-medialane-client.js\";\nimport { useUsdPrices } from \"../utils/use-usd-prices.js\";\nimport { useTokensByOwner } from \"../utils/use-tokens.js\";\nimport { useCollectionsByOwner } from \"../utils/use-collections.js\";\nimport { useUserOrders } from \"../utils/use-orders.js\";\nimport { useActivitiesByAddress } from \"../utils/use-activities.js\";\nimport { useCreatorByUsername, useCreatorProfile } from \"../utils/use-profiles.js\";\n\nconst TABS = [\n { id: \"assets\", label: \"Assets\", Icon: ImageIcon },\n { id: \"collections\", label: \"Collections\", Icon: LayoutGrid },\n { id: \"listings\", label: \"Listings\", Icon: ShoppingBag },\n { id: \"activity\", label: \"Activity\", Icon: Activity },\n] as const;\n\ntype TabId = (typeof TABS)[number][\"id\"];\n\nconst GRID = \"grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5 gap-4\";\nconst isNft = (itemType: string) => itemType === \"ERC721\" || itemType === \"ERC1155\";\n\nexport interface CreatorPageProps {\n address?: string;\n username?: string;\n useAssetActions: UsePortfolioAssetActions;\n useMarketActions: () => CollectionMarketActions;\n}\n\nexport function CreatorPage({ address: addressProp, username, useAssetActions, useMarketActions }: CreatorPageProps) {\n const { walletAddress } = useMedialaneApp();\n const client = useMedialaneClient();\n const resolveImage = useImageUrl();\n const prices = useUsdPrices();\n const [activeTab, setActiveTab] = useState<TabId>(\"assets\");\n const [reportOpen, setReportOpen] = useState(false);\n const [reportToken, setReportToken] = useState<ApiToken | null>(null);\n\n const byName = useCreatorByUsername(username);\n const byAddress = useCreatorProfile(username ? undefined : addressProp);\n const creator = username ? byName.creator : byAddress.profile;\n const address = username ? creator?.walletAddress ?? null : addressProp ?? null;\n const isOwner = !!address && !!walletAddress && isSameAddress(address, walletAddress);\n\n const { tokens, meta, isLoading: tokensLoading, mutate: refreshTokens } = useTokensByOwner(address, 1, 20);\n const { collections, isLoading: collectionsLoading } = useCollectionsByOwner(address);\n const { orders, isLoading: ordersLoading } = useUserOrders(activeTab === \"listings\" ? address : null);\n const { activities, isLoading: activitiesLoading } = useActivitiesByAddress(activeTab === \"activity\" ? address : null);\n const { data: hidden } = useSWR(address ? `creator-hidden-${address}` : null, () => client.api.creators.isHidden(address!).catch(() => false));\n const actions = useAssetActions({ refresh: () => void refreshTokens() });\n const market = useMarketActions();\n\n const listings = orders.filter((o) => o.status === \"ACTIVE\" && isNft(o.offer.itemType));\n const identity = profileIdentity({ username: creator?.username, name: creator?.name, walletAddress: address });\n\n if (username && byName.isLoading) {\n return (\n <div className=\"min-h-screen pb-20\">\n <div className=\"px-6 pt-20 pb-6\"><CreatorHeader creator={null} image={null} stats={[]} loading /></div>\n <div className={cn(\"px-6\", GRID)}>{Array.from({ length: 8 }).map((_, i) => <TokenCardSkeleton key={i} />)}</div>\n </div>\n );\n }\n\n if (username && !creator) {\n return (\n <div className=\"mx-auto max-w-lg space-y-4 px-4 py-24 text-center\">\n <h1 className=\"text-2xl font-bold\">Creator not found</h1>\n <p className=\"text-muted-foreground\"><span className=\"tabular-nums\">@{username}</span> isn't a profile yet.</p>\n <Button variant=\"outline\" asChild><Link href=\"/creators\">Browse creators</Link></Button>\n </div>\n );\n }\n\n const counts: Partial<Record<TabId, number>> = {\n assets: meta?.total ?? undefined,\n collections: collectionsLoading ? undefined : collections.length,\n ...(activeTab === \"listings\" && !ordersLoading ? { listings: listings.length } : {}),\n };\n\n return (\n <div className=\"min-h-screen overflow-x-hidden pb-20\">\n {hidden === true ? <HiddenContentBanner /> : null}\n\n <div className=\"px-6 pt-20 pb-6\">\n {creator ? (\n <CreatorHeader\n creator={creator}\n image={resolveImage(creator.avatarImage || tokens[0]?.metadata?.image)}\n stats={[\n { label: \"Assets\", value: meta?.total ?? null },\n { label: \"Collections\", value: collectionsLoading ? null : collections.length },\n ]}\n />\n ) : (\n <div className=\"flex flex-wrap items-center gap-2\">\n <AddressDisplay address={address ?? \"\"} chars={10} className=\"text-base font-semibold tabular-nums\" />\n </div>\n )}\n </div>\n\n <div className=\"sticky top-0 z-20 mt-4 flex items-center gap-2 border-b border-border bg-background/95 px-6 backdrop-blur-sm\">\n <div className=\"-mb-px flex min-w-0 flex-1 items-center gap-0.5 overflow-x-auto scrollbar-none\">\n {TABS.map(({ id, label, Icon }) => {\n const count = counts[id];\n const active = activeTab === id;\n return (\n <button\n key={id}\n onClick={() => setActiveTab(id)}\n className={cn(\n \"relative flex shrink-0 items-center gap-2 whitespace-nowrap px-4 py-3 text-sm font-medium transition-colors duration-200\",\n active ? \"text-foreground\" : \"text-muted-foreground hover:text-foreground\"\n )}\n >\n <Icon className=\"h-3.5 w-3.5\" />\n {label}\n {count ? (\n <span className={cn(\"min-w-[18px] rounded-full px-1.5 py-px text-center text-2xs font-bold tabular-nums\", active ? \"bg-primary/15 text-primary\" : \"bg-muted text-muted-foreground\")}>{count}</span>\n ) : null}\n {active ? <span className=\"absolute inset-x-0 bottom-0 h-0.5 rounded-full bg-primary\" /> : null}\n </button>\n );\n })}\n </div>\n {address ? (\n <MoreMenu explorerHref={`${EXPLORER_URL}/contract/${address}`} shareTitle={identity.name ?? identity.identity} onReport={() => setReportOpen(true)} />\n ) : null}\n </div>\n\n <div className=\"mt-6 px-6\">\n {activeTab === \"assets\" && (\n tokensLoading ? (\n <div className={GRID}>{Array.from({ length: 8 }).map((_, i) => <TokenCardSkeleton key={i} />)}</div>\n ) : tokens.length === 0 ? (\n <TabEmptyState icon={ImageIcon} heading=\"No assets yet\" body=\"Works this creator makes on Medialane appear here.\" />\n ) : (\n <div className={GRID}>\n {tokens.map((t: ApiToken) => {\n const listing = t.activeOrders?.find((o) => isNft(o.offer.itemType));\n return (\n <TokenCard\n key={`${t.contractAddress}-${t.tokenId}`}\n token={t}\n isOwner={isOwner}\n usdValue={orderUsd(listing?.price, prices)}\n onList={isOwner ? actions.list : undefined}\n onTransfer={isOwner ? actions.transfer : undefined}\n onCancel={isOwner ? actions.cancel : undefined}\n onBuy={!isOwner && listing ? () => market.buy(listing) : undefined}\n onOffer={isOwner ? undefined : market.offer}\n onReport={setReportToken}\n />\n );\n })}\n </div>\n )\n )}\n\n {activeTab === \"collections\" && (\n collectionsLoading ? (\n <div className=\"grid grid-cols-2 gap-4 lg:grid-cols-3\">{Array.from({ length: 6 }).map((_, i) => <CollectionCardSkeleton key={i} />)}</div>\n ) : collections.length === 0 ? (\n <TabEmptyState icon={LayoutGrid} heading=\"No collections yet\" body=\"Collections this creator makes appear here.\" />\n ) : (\n <div className=\"grid grid-cols-2 gap-4 lg:grid-cols-3\">{collections.map((c) => <CollectionCard key={c.contractAddress} collection={c} />)}</div>\n )\n )}\n\n {activeTab === \"listings\" && (\n ordersLoading ? (\n <div className={GRID}>{Array.from({ length: 4 }).map((_, i) => <ListingCardSkeleton key={i} />)}</div>\n ) : listings.length === 0 ? (\n <TabEmptyState icon={ShoppingBag} heading=\"No active listings\" body=\"Works this creator lists for sale appear here.\" />\n ) : (\n <div className={GRID}>\n {listings.map((o) => <ListingCard key={o.orderHash} order={o} onBuy={isOwner ? undefined : market.buy} usdValue={orderUsd(o.price, prices)} overflowMenu={<ListingCardMenu order={o} />} />)}\n </div>\n )\n )}\n\n {activeTab === \"activity\" && (\n <div className=\"max-w-2xl\">\n {activitiesLoading ? (\n <div className=\"space-y-5\">{Array.from({ length: 6 }).map((_, i) => <Skeleton key={i} className=\"h-10 w-full rounded-xl\" />)}</div>\n ) : activities.length === 0 ? (\n <TabEmptyState icon={Activity} heading=\"No activity yet\" body=\"This creator's activity appears here as it happens.\" />\n ) : (\n <div>{activities.map((a, i) => <ActivityTimelineRow key={i} event={a} isLast={i === activities.length - 1} />)}</div>\n )}\n </div>\n )}\n </div>\n\n {actions.dialogs}\n {market.dialogs}\n {reportToken ? (\n <ReportDialog\n open={!!reportToken}\n onOpenChange={(open) => { if (!open) setReportToken(null); }}\n target={{ type: \"TOKEN\", contract: reportToken.contractAddress, tokenId: reportToken.tokenId, name: reportToken.metadata?.name ?? undefined }}\n />\n ) : null}\n {address ? (\n <ReportDialog open={reportOpen} onOpenChange={setReportOpen} target={{ type: \"CREATOR\", address, name: identity.name ?? identity.identity }} />\n ) : null}\n </div>\n );\n}\n"],"mappings":"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","names":[]}
|
|
@@ -16,7 +16,6 @@ declare const editionMintSchema: zod.ZodObject<{
|
|
|
16
16
|
royalty: zod.ZodNumber;
|
|
17
17
|
}, "strip", zod.ZodTypeAny, {
|
|
18
18
|
name: string;
|
|
19
|
-
value: string;
|
|
20
19
|
ipType: "Audio" | "Video" | "Art" | "Photography" | "NFT" | "Software" | "RWA" | "Patents" | "Posts" | "Publications" | "Documents" | "Custom";
|
|
21
20
|
licenseType: string;
|
|
22
21
|
commercialUse: "Yes" | "No";
|
|
@@ -25,12 +24,12 @@ declare const editionMintSchema: zod.ZodObject<{
|
|
|
25
24
|
geographicScope: string;
|
|
26
25
|
aiPolicy: "Allowed" | "Not Allowed" | "Training Only";
|
|
27
26
|
royalty: number;
|
|
27
|
+
value: string;
|
|
28
28
|
recipient: string;
|
|
29
29
|
description?: string | undefined;
|
|
30
30
|
external_url?: string | undefined;
|
|
31
31
|
}, {
|
|
32
32
|
name: string;
|
|
33
|
-
value: string;
|
|
34
33
|
ipType: "Audio" | "Video" | "Art" | "Photography" | "NFT" | "Software" | "RWA" | "Patents" | "Posts" | "Publications" | "Documents" | "Custom";
|
|
35
34
|
licenseType: string;
|
|
36
35
|
commercialUse: "Yes" | "No";
|
|
@@ -39,6 +38,7 @@ declare const editionMintSchema: zod.ZodObject<{
|
|
|
39
38
|
geographicScope: string;
|
|
40
39
|
aiPolicy: "Allowed" | "Not Allowed" | "Training Only";
|
|
41
40
|
royalty: number;
|
|
41
|
+
value: string;
|
|
42
42
|
recipient: string;
|
|
43
43
|
description?: string | undefined;
|
|
44
44
|
external_url?: string | undefined;
|
|
@@ -16,7 +16,6 @@ declare const editionMintSchema: zod.ZodObject<{
|
|
|
16
16
|
royalty: zod.ZodNumber;
|
|
17
17
|
}, "strip", zod.ZodTypeAny, {
|
|
18
18
|
name: string;
|
|
19
|
-
value: string;
|
|
20
19
|
ipType: "Audio" | "Video" | "Art" | "Photography" | "NFT" | "Software" | "RWA" | "Patents" | "Posts" | "Publications" | "Documents" | "Custom";
|
|
21
20
|
licenseType: string;
|
|
22
21
|
commercialUse: "Yes" | "No";
|
|
@@ -25,12 +24,12 @@ declare const editionMintSchema: zod.ZodObject<{
|
|
|
25
24
|
geographicScope: string;
|
|
26
25
|
aiPolicy: "Allowed" | "Not Allowed" | "Training Only";
|
|
27
26
|
royalty: number;
|
|
27
|
+
value: string;
|
|
28
28
|
recipient: string;
|
|
29
29
|
description?: string | undefined;
|
|
30
30
|
external_url?: string | undefined;
|
|
31
31
|
}, {
|
|
32
32
|
name: string;
|
|
33
|
-
value: string;
|
|
34
33
|
ipType: "Audio" | "Video" | "Art" | "Photography" | "NFT" | "Software" | "RWA" | "Patents" | "Posts" | "Publications" | "Documents" | "Custom";
|
|
35
34
|
licenseType: string;
|
|
36
35
|
commercialUse: "Yes" | "No";
|
|
@@ -39,6 +38,7 @@ declare const editionMintSchema: zod.ZodObject<{
|
|
|
39
38
|
geographicScope: string;
|
|
40
39
|
aiPolicy: "Allowed" | "Not Allowed" | "Training Only";
|
|
41
40
|
royalty: number;
|
|
41
|
+
value: string;
|
|
42
42
|
recipient: string;
|
|
43
43
|
description?: string | undefined;
|
|
44
44
|
external_url?: string | undefined;
|
|
@@ -39,9 +39,8 @@ var import_sdk = require("@medialane/sdk");
|
|
|
39
39
|
var import_link = __toESM(require("./link.js"), 1);
|
|
40
40
|
var import_button = require("./button.js");
|
|
41
41
|
var import_dropdown_menu = require("./dropdown-menu.js");
|
|
42
|
-
var
|
|
42
|
+
var import_report_dialog = require("./report-dialog.js");
|
|
43
43
|
function ListingCardMenu({ order }) {
|
|
44
|
-
const { ReportDialog } = (0, import_medialane_app.useMedialaneApp)();
|
|
45
44
|
const [reportOpen, setReportOpen] = (0, import_react.useState)(false);
|
|
46
45
|
const contract = order.nftContract ?? "";
|
|
47
46
|
const tokenId = order.nftTokenId ?? "";
|
|
@@ -57,19 +56,17 @@ function ListingCardMenu({ order }) {
|
|
|
57
56
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.Layers, { className: "h-3.5 w-3.5 text-muted-foreground" }),
|
|
58
57
|
"View collection"
|
|
59
58
|
] }) }),
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
] })
|
|
69
|
-
] }) : null
|
|
59
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dropdown_menu.DropdownMenuSeparator, {}),
|
|
60
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_dropdown_menu.DropdownMenuItem, { className: "flex items-center gap-2 text-destructive focus:text-destructive", onClick: (e) => {
|
|
61
|
+
e.preventDefault();
|
|
62
|
+
setReportOpen(true);
|
|
63
|
+
}, children: [
|
|
64
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.Flag, { className: "h-3.5 w-3.5" }),
|
|
65
|
+
"Report"
|
|
66
|
+
] })
|
|
70
67
|
] })
|
|
71
68
|
] }),
|
|
72
|
-
|
|
69
|
+
reportOpen ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_report_dialog.ReportDialog, { open: reportOpen, onOpenChange: setReportOpen, target: { type: "TOKEN", contract, tokenId, name: order.token?.name ?? void 0 } }) : null
|
|
73
70
|
] });
|
|
74
71
|
}
|
|
75
72
|
// Annotate the CommonJS export names for ESM import in node:
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/listing-card-menu.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState } from \"react\";\nimport { ExternalLink, Flag, Layers, MoreHorizontal } from \"lucide-react\";\nimport { assetHref, collectionHref, type ApiOrder } from \"@medialane/sdk\";\nimport Link from \"./link.js\";\nimport { Button } from \"./button.js\";\nimport { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuTrigger } from \"./dropdown-menu.js\";\nimport {
|
|
1
|
+
{"version":3,"sources":["../../src/components/listing-card-menu.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState } from \"react\";\nimport { ExternalLink, Flag, Layers, MoreHorizontal } from \"lucide-react\";\nimport { assetHref, collectionHref, type ApiOrder } from \"@medialane/sdk\";\nimport Link from \"./link.js\";\nimport { Button } from \"./button.js\";\nimport { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuTrigger } from \"./dropdown-menu.js\";\nimport { ReportDialog } from \"./report-dialog.js\";\n\nexport function ListingCardMenu({ order }: { order: ApiOrder }) {\n const [reportOpen, setReportOpen] = useState(false);\n const contract = order.nftContract ?? \"\";\n const tokenId = order.nftTokenId ?? \"\";\n\n return (\n <>\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button size=\"sm\" variant=\"outline\" className=\"h-9 w-9 p-0 shrink-0 rounded-[9px]\" onClick={(e) => e.preventDefault()} aria-label=\"More actions\">\n <MoreHorizontal className=\"h-3.5 w-3.5\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\" className=\"w-44\">\n <DropdownMenuItem asChild>\n <Link href={assetHref(\"STARKNET\", contract, tokenId)} className=\"flex items-center gap-2\">\n <ExternalLink className=\"h-3.5 w-3.5 text-muted-foreground\" />\n View asset\n </Link>\n </DropdownMenuItem>\n <DropdownMenuItem asChild>\n <Link href={collectionHref(\"STARKNET\", contract)} className=\"flex items-center gap-2\">\n <Layers className=\"h-3.5 w-3.5 text-muted-foreground\" />\n View collection\n </Link>\n </DropdownMenuItem>\n <DropdownMenuSeparator />\n <DropdownMenuItem className=\"flex items-center gap-2 text-destructive focus:text-destructive\" onClick={(e) => { e.preventDefault(); setReportOpen(true); }}>\n <Flag className=\"h-3.5 w-3.5\" />\n Report\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n {reportOpen ? (\n <ReportDialog open={reportOpen} onOpenChange={setReportOpen} target={{ type: \"TOKEN\", contract, tokenId, name: order.token?.name ?? undefined }} />\n ) : null}\n </>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAgBI;AAdJ,mBAAyB;AACzB,0BAA2D;AAC3D,iBAAyD;AACzD,kBAAiB;AACjB,oBAAuB;AACvB,2BAAgH;AAChH,2BAA6B;AAEtB,SAAS,gBAAgB,EAAE,MAAM,GAAwB;AAC9D,QAAM,CAAC,YAAY,aAAa,QAAI,uBAAS,KAAK;AAClD,QAAM,WAAW,MAAM,eAAe;AACtC,QAAM,UAAU,MAAM,cAAc;AAEpC,SACE,4EACE;AAAA,iDAAC,qCACC;AAAA,kDAAC,4CAAoB,SAAO,MAC1B,sDAAC,wBAAO,MAAK,MAAK,SAAQ,WAAU,WAAU,sCAAqC,SAAS,CAAC,MAAM,EAAE,eAAe,GAAG,cAAW,gBAChI,sDAAC,sCAAe,WAAU,eAAc,GAC1C,GACF;AAAA,MACA,6CAAC,4CAAoB,OAAM,OAAM,WAAU,QACzC;AAAA,oDAAC,yCAAiB,SAAO,MACvB,uDAAC,YAAAA,SAAA,EAAK,UAAM,sBAAU,YAAY,UAAU,OAAO,GAAG,WAAU,2BAC9D;AAAA,sDAAC,oCAAa,WAAU,qCAAoC;AAAA,UAAE;AAAA,WAEhE,GACF;AAAA,QACA,4CAAC,yCAAiB,SAAO,MACvB,uDAAC,YAAAA,SAAA,EAAK,UAAM,2BAAe,YAAY,QAAQ,GAAG,WAAU,2BAC1D;AAAA,sDAAC,8BAAO,WAAU,qCAAoC;AAAA,UAAE;AAAA,WAE1D,GACF;AAAA,QACA,4CAAC,8CAAsB;AAAA,QACvB,6CAAC,yCAAiB,WAAU,mEAAkE,SAAS,CAAC,MAAM;AAAE,YAAE,eAAe;AAAG,wBAAc,IAAI;AAAA,QAAG,GACvJ;AAAA,sDAAC,4BAAK,WAAU,eAAc;AAAA,UAAE;AAAA,WAElC;AAAA,SACF;AAAA,OACF;AAAA,IACC,aACC,4CAAC,qCAAa,MAAM,YAAY,cAAc,eAAe,QAAQ,EAAE,MAAM,SAAS,UAAU,SAAS,MAAM,MAAM,OAAO,QAAQ,OAAU,GAAG,IAC/I;AAAA,KACN;AAEJ;","names":["Link"]}
|
|
@@ -6,9 +6,8 @@ import { assetHref, collectionHref } from "@medialane/sdk";
|
|
|
6
6
|
import Link from "./link.js";
|
|
7
7
|
import { Button } from "./button.js";
|
|
8
8
|
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuTrigger } from "./dropdown-menu.js";
|
|
9
|
-
import {
|
|
9
|
+
import { ReportDialog } from "./report-dialog.js";
|
|
10
10
|
function ListingCardMenu({ order }) {
|
|
11
|
-
const { ReportDialog } = useMedialaneApp();
|
|
12
11
|
const [reportOpen, setReportOpen] = useState(false);
|
|
13
12
|
const contract = order.nftContract ?? "";
|
|
14
13
|
const tokenId = order.nftTokenId ?? "";
|
|
@@ -24,19 +23,17 @@ function ListingCardMenu({ order }) {
|
|
|
24
23
|
/* @__PURE__ */ jsx(Layers, { className: "h-3.5 w-3.5 text-muted-foreground" }),
|
|
25
24
|
"View collection"
|
|
26
25
|
] }) }),
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
] })
|
|
36
|
-
] }) : null
|
|
26
|
+
/* @__PURE__ */ jsx(DropdownMenuSeparator, {}),
|
|
27
|
+
/* @__PURE__ */ jsxs(DropdownMenuItem, { className: "flex items-center gap-2 text-destructive focus:text-destructive", onClick: (e) => {
|
|
28
|
+
e.preventDefault();
|
|
29
|
+
setReportOpen(true);
|
|
30
|
+
}, children: [
|
|
31
|
+
/* @__PURE__ */ jsx(Flag, { className: "h-3.5 w-3.5" }),
|
|
32
|
+
"Report"
|
|
33
|
+
] })
|
|
37
34
|
] })
|
|
38
35
|
] }),
|
|
39
|
-
|
|
36
|
+
reportOpen ? /* @__PURE__ */ jsx(ReportDialog, { open: reportOpen, onOpenChange: setReportOpen, target: { type: "TOKEN", contract, tokenId, name: order.token?.name ?? void 0 } }) : null
|
|
40
37
|
] });
|
|
41
38
|
}
|
|
42
39
|
export {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/listing-card-menu.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState } from \"react\";\nimport { ExternalLink, Flag, Layers, MoreHorizontal } from \"lucide-react\";\nimport { assetHref, collectionHref, type ApiOrder } from \"@medialane/sdk\";\nimport Link from \"./link.js\";\nimport { Button } from \"./button.js\";\nimport { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuTrigger } from \"./dropdown-menu.js\";\nimport {
|
|
1
|
+
{"version":3,"sources":["../../src/components/listing-card-menu.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState } from \"react\";\nimport { ExternalLink, Flag, Layers, MoreHorizontal } from \"lucide-react\";\nimport { assetHref, collectionHref, type ApiOrder } from \"@medialane/sdk\";\nimport Link from \"./link.js\";\nimport { Button } from \"./button.js\";\nimport { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuTrigger } from \"./dropdown-menu.js\";\nimport { ReportDialog } from \"./report-dialog.js\";\n\nexport function ListingCardMenu({ order }: { order: ApiOrder }) {\n const [reportOpen, setReportOpen] = useState(false);\n const contract = order.nftContract ?? \"\";\n const tokenId = order.nftTokenId ?? \"\";\n\n return (\n <>\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button size=\"sm\" variant=\"outline\" className=\"h-9 w-9 p-0 shrink-0 rounded-[9px]\" onClick={(e) => e.preventDefault()} aria-label=\"More actions\">\n <MoreHorizontal className=\"h-3.5 w-3.5\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\" className=\"w-44\">\n <DropdownMenuItem asChild>\n <Link href={assetHref(\"STARKNET\", contract, tokenId)} className=\"flex items-center gap-2\">\n <ExternalLink className=\"h-3.5 w-3.5 text-muted-foreground\" />\n View asset\n </Link>\n </DropdownMenuItem>\n <DropdownMenuItem asChild>\n <Link href={collectionHref(\"STARKNET\", contract)} className=\"flex items-center gap-2\">\n <Layers className=\"h-3.5 w-3.5 text-muted-foreground\" />\n View collection\n </Link>\n </DropdownMenuItem>\n <DropdownMenuSeparator />\n <DropdownMenuItem className=\"flex items-center gap-2 text-destructive focus:text-destructive\" onClick={(e) => { e.preventDefault(); setReportOpen(true); }}>\n <Flag className=\"h-3.5 w-3.5\" />\n Report\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n {reportOpen ? (\n <ReportDialog open={reportOpen} onOpenChange={setReportOpen} target={{ type: \"TOKEN\", contract, tokenId, name: order.token?.name ?? undefined }} />\n ) : null}\n </>\n );\n}\n"],"mappings":";AAgBI,mBAIQ,KAKA,YATR;AAdJ,SAAS,gBAAgB;AACzB,SAAS,cAAc,MAAM,QAAQ,sBAAsB;AAC3D,SAAS,WAAW,sBAAqC;AACzD,OAAO,UAAU;AACjB,SAAS,cAAc;AACvB,SAAS,cAAc,qBAAqB,kBAAkB,uBAAuB,2BAA2B;AAChH,SAAS,oBAAoB;AAEtB,SAAS,gBAAgB,EAAE,MAAM,GAAwB;AAC9D,QAAM,CAAC,YAAY,aAAa,IAAI,SAAS,KAAK;AAClD,QAAM,WAAW,MAAM,eAAe;AACtC,QAAM,UAAU,MAAM,cAAc;AAEpC,SACE,iCACE;AAAA,yBAAC,gBACC;AAAA,0BAAC,uBAAoB,SAAO,MAC1B,8BAAC,UAAO,MAAK,MAAK,SAAQ,WAAU,WAAU,sCAAqC,SAAS,CAAC,MAAM,EAAE,eAAe,GAAG,cAAW,gBAChI,8BAAC,kBAAe,WAAU,eAAc,GAC1C,GACF;AAAA,MACA,qBAAC,uBAAoB,OAAM,OAAM,WAAU,QACzC;AAAA,4BAAC,oBAAiB,SAAO,MACvB,+BAAC,QAAK,MAAM,UAAU,YAAY,UAAU,OAAO,GAAG,WAAU,2BAC9D;AAAA,8BAAC,gBAAa,WAAU,qCAAoC;AAAA,UAAE;AAAA,WAEhE,GACF;AAAA,QACA,oBAAC,oBAAiB,SAAO,MACvB,+BAAC,QAAK,MAAM,eAAe,YAAY,QAAQ,GAAG,WAAU,2BAC1D;AAAA,8BAAC,UAAO,WAAU,qCAAoC;AAAA,UAAE;AAAA,WAE1D,GACF;AAAA,QACA,oBAAC,yBAAsB;AAAA,QACvB,qBAAC,oBAAiB,WAAU,mEAAkE,SAAS,CAAC,MAAM;AAAE,YAAE,eAAe;AAAG,wBAAc,IAAI;AAAA,QAAG,GACvJ;AAAA,8BAAC,QAAK,WAAU,eAAc;AAAA,UAAE;AAAA,WAElC;AAAA,SACF;AAAA,OACF;AAAA,IACC,aACC,oBAAC,gBAAa,MAAM,YAAY,cAAc,eAAe,QAAQ,EAAE,MAAM,SAAS,UAAU,SAAS,MAAM,MAAM,OAAO,QAAQ,OAAU,GAAG,IAC/I;AAAA,KACN;AAEJ;","names":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/medialane-app.tsx"],"sourcesContent":["\"use client\";\n\nimport { createContext, useContext, type
|
|
1
|
+
{"version":3,"sources":["../../src/components/medialane-app.tsx"],"sourcesContent":["\"use client\";\n\nimport { createContext, useContext, type ElementType, type ReactNode } from \"react\";\nimport type { MedialaneClient } from \"@medialane/sdk/starknet\";\nimport type { FastMintSigner } from \"./fast-mint/types.js\";\nimport type { ApiToken } from \"@medialane/sdk\";\nimport type { ImageResolver } from \"../utils/ipfs.js\";\n\nexport type AssetRef = Pick<ApiToken, \"chain\" | \"contractAddress\" | \"tokenId\">;\n\nexport interface CompanionApp {\n title: string;\n description: string;\n icon: ElementType;\n origin: string;\n}\n\nexport type ReportTarget =\n | { type: \"TOKEN\"; contract: string; tokenId: string; name?: string }\n | { type: \"COLLECTION\"; contract: string; name?: string }\n | { type: \"CREATOR\"; address: string; name?: string }\n | { type: \"COMMENT\"; commentId: string };\n\nexport interface MedialaneApp {\n getClient: () => MedialaneClient;\n getSigner: () => Promise<FastMintSigner> | FastMintSigner;\n walletAddress: string | null;\n walletLoading?: boolean;\n onRequireWallet: () => void;\n releaseSigner?: () => void;\n ensureSignedIn?: () => Promise<void>;\n connectLabel?: string;\n verifyEmailHref?: string;\n companion?: CompanionApp;\n resolveImage?: ImageResolver;\n}\n\nexport const MedialaneAppContext = createContext<MedialaneApp | null>(null);\n\nexport function MedialaneAppProvider({ value, children }: { value: MedialaneApp; children: ReactNode }) {\n return <MedialaneAppContext.Provider value={value}>{children}</MedialaneAppContext.Provider>;\n}\n\nexport function useMedialaneApp(): MedialaneApp {\n const app = useContext(MedialaneAppContext);\n if (!app) throw new Error(\"MedialaneAppProvider missing\");\n return app;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAwCS;AAtCT,mBAA4E;AAmCrE,MAAM,0BAAsB,4BAAmC,IAAI;AAEnE,SAAS,qBAAqB,EAAE,OAAO,SAAS,GAAiD;AACtG,SAAO,4CAAC,oBAAoB,UAApB,EAA6B,OAAe,UAAS;AAC/D;AAEO,SAAS,kBAAgC;AAC9C,QAAM,UAAM,yBAAW,mBAAmB;AAC1C,MAAI,CAAC,IAAK,OAAM,IAAI,MAAM,8BAA8B;AACxD,SAAO;AACT;","names":[]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
2
|
import * as React from 'react';
|
|
3
|
-
import { ElementType,
|
|
3
|
+
import { ElementType, ReactNode } from 'react';
|
|
4
4
|
import { MedialaneClient } from '@medialane/sdk/starknet';
|
|
5
5
|
import { FastMintSigner } from './fast-mint/types.cjs';
|
|
6
6
|
import { ApiToken } from '@medialane/sdk';
|
|
@@ -31,11 +31,6 @@ type ReportTarget = {
|
|
|
31
31
|
type: "COMMENT";
|
|
32
32
|
commentId: string;
|
|
33
33
|
};
|
|
34
|
-
type ReportDialogSlot = ComponentType<{
|
|
35
|
-
open: boolean;
|
|
36
|
-
onOpenChange: (open: boolean) => void;
|
|
37
|
-
target: ReportTarget;
|
|
38
|
-
}>;
|
|
39
34
|
interface MedialaneApp {
|
|
40
35
|
getClient: () => MedialaneClient;
|
|
41
36
|
getSigner: () => Promise<FastMintSigner> | FastMintSigner;
|
|
@@ -47,7 +42,6 @@ interface MedialaneApp {
|
|
|
47
42
|
connectLabel?: string;
|
|
48
43
|
verifyEmailHref?: string;
|
|
49
44
|
companion?: CompanionApp;
|
|
50
|
-
ReportDialog?: ReportDialogSlot;
|
|
51
45
|
resolveImage?: ImageResolver;
|
|
52
46
|
}
|
|
53
47
|
declare const MedialaneAppContext: React.Context<MedialaneApp | null>;
|
|
@@ -57,4 +51,4 @@ declare function MedialaneAppProvider({ value, children }: {
|
|
|
57
51
|
}): react_jsx_runtime.JSX.Element;
|
|
58
52
|
declare function useMedialaneApp(): MedialaneApp;
|
|
59
53
|
|
|
60
|
-
export { type AssetRef, type CompanionApp, type MedialaneApp, MedialaneAppContext, MedialaneAppProvider, type
|
|
54
|
+
export { type AssetRef, type CompanionApp, type MedialaneApp, MedialaneAppContext, MedialaneAppProvider, type ReportTarget, useMedialaneApp };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
2
|
import * as React from 'react';
|
|
3
|
-
import { ElementType,
|
|
3
|
+
import { ElementType, ReactNode } from 'react';
|
|
4
4
|
import { MedialaneClient } from '@medialane/sdk/starknet';
|
|
5
5
|
import { FastMintSigner } from './fast-mint/types.js';
|
|
6
6
|
import { ApiToken } from '@medialane/sdk';
|
|
@@ -31,11 +31,6 @@ type ReportTarget = {
|
|
|
31
31
|
type: "COMMENT";
|
|
32
32
|
commentId: string;
|
|
33
33
|
};
|
|
34
|
-
type ReportDialogSlot = ComponentType<{
|
|
35
|
-
open: boolean;
|
|
36
|
-
onOpenChange: (open: boolean) => void;
|
|
37
|
-
target: ReportTarget;
|
|
38
|
-
}>;
|
|
39
34
|
interface MedialaneApp {
|
|
40
35
|
getClient: () => MedialaneClient;
|
|
41
36
|
getSigner: () => Promise<FastMintSigner> | FastMintSigner;
|
|
@@ -47,7 +42,6 @@ interface MedialaneApp {
|
|
|
47
42
|
connectLabel?: string;
|
|
48
43
|
verifyEmailHref?: string;
|
|
49
44
|
companion?: CompanionApp;
|
|
50
|
-
ReportDialog?: ReportDialogSlot;
|
|
51
45
|
resolveImage?: ImageResolver;
|
|
52
46
|
}
|
|
53
47
|
declare const MedialaneAppContext: React.Context<MedialaneApp | null>;
|
|
@@ -57,4 +51,4 @@ declare function MedialaneAppProvider({ value, children }: {
|
|
|
57
51
|
}): react_jsx_runtime.JSX.Element;
|
|
58
52
|
declare function useMedialaneApp(): MedialaneApp;
|
|
59
53
|
|
|
60
|
-
export { type AssetRef, type CompanionApp, type MedialaneApp, MedialaneAppContext, MedialaneAppProvider, type
|
|
54
|
+
export { type AssetRef, type CompanionApp, type MedialaneApp, MedialaneAppContext, MedialaneAppProvider, type ReportTarget, useMedialaneApp };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/medialane-app.tsx"],"sourcesContent":["\"use client\";\n\nimport { createContext, useContext, type
|
|
1
|
+
{"version":3,"sources":["../../src/components/medialane-app.tsx"],"sourcesContent":["\"use client\";\n\nimport { createContext, useContext, type ElementType, type ReactNode } from \"react\";\nimport type { MedialaneClient } from \"@medialane/sdk/starknet\";\nimport type { FastMintSigner } from \"./fast-mint/types.js\";\nimport type { ApiToken } from \"@medialane/sdk\";\nimport type { ImageResolver } from \"../utils/ipfs.js\";\n\nexport type AssetRef = Pick<ApiToken, \"chain\" | \"contractAddress\" | \"tokenId\">;\n\nexport interface CompanionApp {\n title: string;\n description: string;\n icon: ElementType;\n origin: string;\n}\n\nexport type ReportTarget =\n | { type: \"TOKEN\"; contract: string; tokenId: string; name?: string }\n | { type: \"COLLECTION\"; contract: string; name?: string }\n | { type: \"CREATOR\"; address: string; name?: string }\n | { type: \"COMMENT\"; commentId: string };\n\nexport interface MedialaneApp {\n getClient: () => MedialaneClient;\n getSigner: () => Promise<FastMintSigner> | FastMintSigner;\n walletAddress: string | null;\n walletLoading?: boolean;\n onRequireWallet: () => void;\n releaseSigner?: () => void;\n ensureSignedIn?: () => Promise<void>;\n connectLabel?: string;\n verifyEmailHref?: string;\n companion?: CompanionApp;\n resolveImage?: ImageResolver;\n}\n\nexport const MedialaneAppContext = createContext<MedialaneApp | null>(null);\n\nexport function MedialaneAppProvider({ value, children }: { value: MedialaneApp; children: ReactNode }) {\n return <MedialaneAppContext.Provider value={value}>{children}</MedialaneAppContext.Provider>;\n}\n\nexport function useMedialaneApp(): MedialaneApp {\n const app = useContext(MedialaneAppContext);\n if (!app) throw new Error(\"MedialaneAppProvider missing\");\n return app;\n}\n"],"mappings":";AAwCS;AAtCT,SAAS,eAAe,kBAAoD;AAmCrE,MAAM,sBAAsB,cAAmC,IAAI;AAEnE,SAAS,qBAAqB,EAAE,OAAO,SAAS,GAAiD;AACtG,SAAO,oBAAC,oBAAoB,UAApB,EAA6B,OAAe,UAAS;AAC/D;AAEO,SAAS,kBAAgC;AAC9C,QAAM,MAAM,WAAW,mBAAmB;AAC1C,MAAI,CAAC,IAAK,OAAM,IAAI,MAAM,8BAA8B;AACxD,SAAO;AACT;","names":[]}
|
|
@@ -28,7 +28,7 @@ var import_lucide_react = require("lucide-react");
|
|
|
28
28
|
var import_empty_or_error = require("./empty-or-error.js");
|
|
29
29
|
var import_load_more_sentinel = require("./load-more-sentinel.js");
|
|
30
30
|
var import_token_card = require("./token-card.js");
|
|
31
|
-
var
|
|
31
|
+
var import_report_dialog = require("./report-dialog.js");
|
|
32
32
|
var import_order_usd = require("../utils/order-usd.js");
|
|
33
33
|
var import_use_usd_prices = require("../utils/use-usd-prices.js");
|
|
34
34
|
var import_use_tokens = require("../utils/use-tokens.js");
|
|
@@ -39,7 +39,6 @@ function usdFor(token, prices) {
|
|
|
39
39
|
return (0, import_order_usd.orderUsd)(order?.price, prices);
|
|
40
40
|
}
|
|
41
41
|
function PortfolioAssets({ address, useActions }) {
|
|
42
|
-
const { ReportDialog } = (0, import_medialane_app.useMedialaneApp)();
|
|
43
42
|
const [page, setPage] = (0, import_react.useState)(1);
|
|
44
43
|
const [all, setAll] = (0, import_react.useState)([]);
|
|
45
44
|
const [reportToken, setReportToken] = (0, import_react.useState)(null);
|
|
@@ -86,7 +85,7 @@ function PortfolioAssets({ address, useActions }) {
|
|
|
86
85
|
onList: actions.list,
|
|
87
86
|
onTransfer: actions.transfer,
|
|
88
87
|
onCancel: actions.cancel,
|
|
89
|
-
onReport:
|
|
88
|
+
onReport: setReportToken
|
|
90
89
|
},
|
|
91
90
|
`${token.contractAddress}-${token.tokenId}`
|
|
92
91
|
)) }),
|
|
@@ -95,8 +94,8 @@ function PortfolioAssets({ address, useActions }) {
|
|
|
95
94
|
}
|
|
96
95
|
),
|
|
97
96
|
actions.dialogs,
|
|
98
|
-
|
|
99
|
-
ReportDialog,
|
|
97
|
+
reportToken && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
98
|
+
import_report_dialog.ReportDialog,
|
|
100
99
|
{
|
|
101
100
|
open: !!reportToken,
|
|
102
101
|
onOpenChange: (open) => {
|