@medialane/ui 0.251.0 → 0.253.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-page.cjs +11 -4
- package/dist/components/asset-page.cjs.map +1 -1
- package/dist/components/asset-page.js +11 -4
- package/dist/components/asset-page.js.map +1 -1
- package/dist/components/asset-publication.cjs +5 -13
- package/dist/components/asset-publication.cjs.map +1 -1
- package/dist/components/asset-publication.d.cts +2 -2
- package/dist/components/asset-publication.d.ts +2 -2
- package/dist/components/asset-publication.js +5 -13
- package/dist/components/asset-publication.js.map +1 -1
- package/dist/components/asset-top-sections.cjs +9 -1
- package/dist/components/asset-top-sections.cjs.map +1 -1
- package/dist/components/asset-top-sections.d.cts +2 -1
- package/dist/components/asset-top-sections.d.ts +2 -1
- package/dist/components/asset-top-sections.js +9 -1
- package/dist/components/asset-top-sections.js.map +1 -1
- package/dist/components/button.d.cts +2 -2
- package/dist/components/button.d.ts +2 -2
- package/dist/components/collection-card.cjs +11 -19
- package/dist/components/collection-card.cjs.map +1 -1
- package/dist/components/collection-card.js +11 -19
- package/dist/components/collection-card.js.map +1 -1
- package/dist/components/collections-page.cjs +190 -139
- package/dist/components/collections-page.cjs.map +1 -1
- package/dist/components/collections-page.js +181 -140
- package/dist/components/collections-page.js.map +1 -1
- package/dist/components/creator-page.cjs +1 -1
- package/dist/components/creator-page.cjs.map +1 -1
- package/dist/components/creator-page.js +1 -1
- package/dist/components/creator-page.js.map +1 -1
- package/dist/components/drop/create/drop-create.cjs +1 -1
- package/dist/components/drop/create/drop-create.cjs.map +1 -1
- package/dist/components/drop/create/drop-create.js +1 -1
- package/dist/components/drop/create/drop-create.js.map +1 -1
- package/dist/components/drop/create/launch-dialog.cjs +1 -1
- package/dist/components/drop/create/launch-dialog.cjs.map +1 -1
- package/dist/components/drop/create/launch-dialog.js +1 -1
- package/dist/components/drop/create/launch-dialog.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/hero-slider.cjs +2 -1
- package/dist/components/hero-slider.cjs.map +1 -1
- package/dist/components/hero-slider.js +2 -1
- package/dist/components/hero-slider.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/scroll-section.cjs +1 -1
- package/dist/components/scroll-section.cjs.map +1 -1
- package/dist/components/scroll-section.d.cts +1 -1
- package/dist/components/scroll-section.d.ts +1 -1
- package/dist/components/scroll-section.js +1 -1
- package/dist/components/scroll-section.js.map +1 -1
- package/dist/components/sheet.d.cts +1 -1
- package/dist/components/sheet.d.ts +1 -1
- package/dist/utils/external-link.cjs +44 -0
- package/dist/utils/external-link.cjs.map +1 -0
- package/dist/utils/external-link.d.cts +4 -0
- package/dist/utils/external-link.d.ts +4 -0
- package/dist/utils/external-link.js +19 -0
- package/dist/utils/external-link.js.map +1 -0
- package/dist/utils/use-collections.cjs +1 -2
- package/dist/utils/use-collections.cjs.map +1 -1
- package/dist/utils/use-collections.d.cts +3 -0
- package/dist/utils/use-collections.d.ts +3 -0
- package/dist/utils/use-collections.js +1 -2
- package/dist/utils/use-collections.js.map +1 -1
- package/dist/utils/use-tokens-by-ip-type.d.cts +2 -0
- package/dist/utils/use-tokens-by-ip-type.d.ts +2 -0
- package/dist/utils/use-tokens.d.cts +4 -0
- package/dist/utils/use-tokens.d.ts +4 -0
- package/package.json +3 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/creator-page.tsx"],"sourcesContent":["\"use client\";\n\nimport { lazy, Suspense, useState } from \"react\";\nimport useSWR from \"swr\";\nimport { Activity, BarChart2, 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 CreatorAnalytics = lazy(() => import(\"./creator-analytics.js\").then((m) => ({ default: m.CreatorAnalytics })));\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: \"analytics\", label: \"Analytics\", Icon: BarChart2 },\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\" || activeTab === \"analytics\" ? 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-1 gap-4 sm:grid-cols-2 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-1 gap-4 sm:grid-cols-2 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 === \"analytics\" && (\n <div className=\"max-w-2xl\">\n <Suspense fallback={<div className=\"h-64 w-full animate-pulse rounded-xl bg-muted/40\" />}>\n <CreatorAnalytics activities={activities} isLoading={activitiesLoading} />\n </Suspense>\n </div>\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 { lazy, Suspense, useState } from \"react\";\nimport useSWR from \"swr\";\nimport { Activity, BarChart2, 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 CreatorAnalytics = lazy(() => import(\"./creator-analytics.js\").then((m) => ({ default: m.CreatorAnalytics })));\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: \"analytics\", label: \"Analytics\", Icon: BarChart2 },\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\" || activeTab === \"analytics\" ? 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 === \"analytics\" && (\n <div className=\"max-w-2xl\">\n <Suspense fallback={<div className=\"h-64 w-full animate-pulse rounded-xl bg-muted/40\" />}>\n <CreatorAnalytics activities={activities} isLoading={activitiesLoading} />\n </Suspense>\n </div>\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"]}
|
|
@@ -142,7 +142,7 @@ function CreatorPage({ address: addressProp, username, useAssetActions, useMarke
|
|
|
142
142
|
`${t.contractAddress}-${t.tokenId}`
|
|
143
143
|
);
|
|
144
144
|
}) })),
|
|
145
|
-
activeTab === "collections" && (collectionsLoading ? /* @__PURE__ */ jsx("div", { className: "grid grid-cols-
|
|
145
|
+
activeTab === "collections" && (collectionsLoading ? /* @__PURE__ */ jsx("div", { className: "grid grid-cols-2 gap-4 lg:grid-cols-3", children: Array.from({ length: 6 }).map((_, i) => /* @__PURE__ */ jsx(CollectionCardSkeleton, {}, i)) }) : collections.length === 0 ? /* @__PURE__ */ jsx(TabEmptyState, { icon: LayoutGrid, heading: "No collections yet", body: "Collections this creator makes appear here." }) : /* @__PURE__ */ jsx("div", { className: "grid grid-cols-2 gap-4 lg:grid-cols-3", children: collections.map((c) => /* @__PURE__ */ jsx(CollectionCard, { collection: c }, c.contractAddress)) })),
|
|
146
146
|
activeTab === "listings" && (ordersLoading ? /* @__PURE__ */ jsx("div", { className: GRID, children: Array.from({ length: 4 }).map((_, i) => /* @__PURE__ */ jsx(ListingCardSkeleton, {}, i)) }) : listings.length === 0 ? /* @__PURE__ */ jsx(TabEmptyState, { icon: ShoppingBag, heading: "No active listings", body: "Works this creator lists for sale appear here." }) : /* @__PURE__ */ jsx("div", { className: GRID, children: listings.map((o) => /* @__PURE__ */ jsx(ListingCard, { order: o, onBuy: isOwner ? void 0 : market.buy, usdValue: orderUsd(o.price, prices), overflowMenu: /* @__PURE__ */ jsx(ListingCardMenu, { order: o }) }, o.orderHash)) })),
|
|
147
147
|
activeTab === "analytics" && /* @__PURE__ */ jsx("div", { className: "max-w-2xl", children: /* @__PURE__ */ jsx(Suspense, { fallback: /* @__PURE__ */ jsx("div", { className: "h-64 w-full animate-pulse rounded-xl bg-muted/40" }), children: /* @__PURE__ */ jsx(CreatorAnalytics, { activities, isLoading: activitiesLoading }) }) }),
|
|
148
148
|
activeTab === "activity" && /* @__PURE__ */ jsx("div", { className: "max-w-2xl", children: activitiesLoading ? /* @__PURE__ */ jsx("div", { className: "space-y-5", children: Array.from({ length: 6 }).map((_, i) => /* @__PURE__ */ jsx(Skeleton, { className: "h-10 w-full rounded-xl" }, i)) }) : activities.length === 0 ? /* @__PURE__ */ jsx(TabEmptyState, { icon: Activity, heading: "No activity yet", body: "This creator's activity appears here as it happens." }) : /* @__PURE__ */ jsx("div", { children: activities.map((a, i) => /* @__PURE__ */ jsx(ActivityTimelineRow, { event: a, isLast: i === activities.length - 1 }, i)) }) })
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/creator-page.tsx"],"sourcesContent":["\"use client\";\n\nimport { lazy, Suspense, useState } from \"react\";\nimport useSWR from \"swr\";\nimport { Activity, BarChart2, 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 CreatorAnalytics = lazy(() => import(\"./creator-analytics.js\").then((m) => ({ default: m.CreatorAnalytics })));\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: \"analytics\", label: \"Analytics\", Icon: BarChart2 },\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\" || activeTab === \"analytics\" ? 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-1 gap-4 sm:grid-cols-2 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-1 gap-4 sm:grid-cols-2 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 === \"analytics\" && (\n <div className=\"max-w-2xl\">\n <Suspense fallback={<div className=\"h-64 w-full animate-pulse rounded-xl bg-muted/40\" />}>\n <CreatorAnalytics activities={activities} isLoading={activitiesLoading} />\n </Suspense>\n </div>\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 { lazy, Suspense, useState } from \"react\";\nimport useSWR from \"swr\";\nimport { Activity, BarChart2, 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 CreatorAnalytics = lazy(() => import(\"./creator-analytics.js\").then((m) => ({ default: m.CreatorAnalytics })));\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: \"analytics\", label: \"Analytics\", Icon: BarChart2 },\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\" || activeTab === \"analytics\" ? 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 === \"analytics\" && (\n <div className=\"max-w-2xl\">\n <Suspense fallback={<div className=\"h-64 w-full animate-pulse rounded-xl bg-muted/40\" />}>\n <CreatorAnalytics activities={activities} isLoading={activitiesLoading} />\n </Suspense>\n </div>\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":[]}
|
|
@@ -101,7 +101,7 @@ function DraftSummary({ draft, feeBps }) {
|
|
|
101
101
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "truncate font-semibold", children: draft.name || "Untitled drop" }),
|
|
102
102
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-xs text-muted-foreground", children: draft.sale.paid ? feeBps === null ? "\u2026" : (0, import_sale.collectorPriceLine)(draft.sale, feeBps) ?? "Set a price" : "Free" }),
|
|
103
103
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { className: "text-xs text-muted-foreground", children: [
|
|
104
|
-
Number.isFinite(supply) && supply > 0 ? `${supply.toLocaleString("en-US")} ${draft.kind === "edition" ? "copies" : "items"}` : "Supply not set",
|
|
104
|
+
Number.isFinite(supply) && supply > 0 ? `${supply.toLocaleString("en-US")} ${draft.kind === "edition" ? supply === 1 ? "copy" : "copies" : supply === 1 ? "item" : "items"}` : "Supply not set",
|
|
105
105
|
" \xB7 ",
|
|
106
106
|
draft.listOnly ? "List only" : "Open to everyone"
|
|
107
107
|
] })
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/components/drop/create/drop-create.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState } from \"react\";\nimport { Lock } from \"lucide-react\";\nimport Image from \"../../image.js\";\nimport { GradientButton } from \"../../gradient-button.js\";\nimport { CollapsibleSection } from \"../../collapsible-section.js\";\nimport { ArtworkSection } from \"./artwork-section.js\";\nimport { DetailsSection } from \"./details-section.js\";\nimport { SaleSection } from \"./sale-section.js\";\nimport { ListSection } from \"./list-section.js\";\nimport { ExclusiveFields } from \"./exclusive-fields.js\";\nimport { LaunchDialog } from \"./launch-dialog.js\";\nimport { FieldError } from \"./artwork-section.js\";\nimport { EMPTY_DRAFT, draftSupply, validateDropDraft, type DropDraft } from \"../../../utils/drop/draft.js\";\nimport { collectorPriceLine } from \"../../../utils/drop/sale.js\";\nimport { previewUrl } from \"../../../utils/drop/preview.js\";\nimport { useMedialaneApp } from \"../../medialane-app.js\";\nimport { useDropFee } from \"../../../utils/use-drops.js\";\n\nexport function DropCreate() {\n const app = useMedialaneApp();\n const feeBps = useDropFee();\n const [draft, setDraftState] = useState<DropDraft>(EMPTY_DRAFT);\n const [tried, setTried] = useState(false);\n const [launching, setLaunching] = useState(false);\n const setDraft = (patch: Partial<DropDraft>) => setDraftState((d) => ({ ...d, ...patch }));\n const errors = tried ? validateDropDraft(draft, Math.floor(Date.now() / 1000)) : {};\n\n const launch = () => {\n if (!app.walletAddress) return app.onRequireWallet();\n setTried(true);\n if (Object.keys(validateDropDraft(draft, Math.floor(Date.now() / 1000))).length === 0) setLaunching(true);\n };\n\n return (\n <div className=\"grid gap-6 lg:grid-cols-[minmax(0,1fr)_320px]\">\n <div className=\"space-y-5 lg:order-1 order-2\">\n <ArtworkSection draft={draft} setDraft={setDraft} errors={errors} />\n <DetailsSection draft={draft} setDraft={setDraft} errors={errors} />\n <SaleSection draft={draft} setDraft={setDraft} errors={errors} feeBps={feeBps} />\n <ListSection draft={draft} setDraft={setDraft} errors={errors} />\n <CollapsibleSection\n open={draft.gated.enabled}\n onOpenChange={(enabled) => setDraft({ gated: { ...draft.gated, enabled } })}\n icon={<Lock className=\"h-4 w-4 text-primary\" />}\n label=\"Exclusive content\"\n hint=\"Optional · a private link only holders can open\"\n >\n <ExclusiveFields value={draft.gated} onChange={(v) => setDraft({ gated: { ...draft.gated, ...v } })} />\n <FieldError message={errors.gated} />\n </CollapsibleSection>\n {tried && Object.keys(errors).length > 0 && <p className=\"text-sm font-medium text-destructive\">Check the highlighted fields.</p>}\n <GradientButton big onClick={launch}>\n {app.walletAddress ? \"Review and launch\" : app.connectLabel ?? \"Sign in to launch\"}\n </GradientButton>\n {launching && <LaunchDialog open onClose={() => setLaunching(false)} draft={draft} />}\n </div>\n <div className=\"order-1 lg:order-2\">\n <div className=\"lg:sticky lg:top-24\"><DraftSummary draft={draft} feeBps={feeBps} /></div>\n </div>\n </div>\n );\n}\n\n/** The drop as collectors will see it, updated as the form changes. */\nexport function DraftSummary({ draft, feeBps }: { draft: DropDraft; feeBps: number | null }) {\n const art = draft.cover ?? (draft.kind === \"edition\" ? draft.edition : draft.items[0]?.file ?? null);\n const preview = art ? previewUrl(art) : null;\n const supply = draftSupply(draft);\n return (\n <div className=\"overflow-hidden rounded-2xl border border-border bg-card\">\n <div className=\"relative aspect-square bg-muted\">\n {preview && <Image src={preview} alt={draft.name || \"Drop\"} fill unoptimized className=\"object-cover\" />}\n </div>\n <div className=\"space-y-1 p-4\">\n <p className=\"truncate font-semibold\">{draft.name || \"Untitled drop\"}</p>\n <p className=\"text-xs text-muted-foreground\">\n {draft.sale.paid ? (feeBps === null ? \"…\" : collectorPriceLine(draft.sale, feeBps) ?? \"Set a price\") : \"Free\"}\n </p>\n <p className=\"text-xs text-muted-foreground\">\n {Number.isFinite(supply) && supply > 0 ? `${supply.toLocaleString(\"en-US\")} ${draft.kind === \"edition\" ? \"copies\" : \"items\"}` : \"Supply not set\"}\n {\" · \"}{draft.listOnly ? \"List only\" : \"Open to everyone\"}\n </p>\n </div>\n </div>\n );\n}\n"],"mappings":"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
|
|
1
|
+
{"version":3,"sources":["../../../../src/components/drop/create/drop-create.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState } from \"react\";\nimport { Lock } from \"lucide-react\";\nimport Image from \"../../image.js\";\nimport { GradientButton } from \"../../gradient-button.js\";\nimport { CollapsibleSection } from \"../../collapsible-section.js\";\nimport { ArtworkSection } from \"./artwork-section.js\";\nimport { DetailsSection } from \"./details-section.js\";\nimport { SaleSection } from \"./sale-section.js\";\nimport { ListSection } from \"./list-section.js\";\nimport { ExclusiveFields } from \"./exclusive-fields.js\";\nimport { LaunchDialog } from \"./launch-dialog.js\";\nimport { FieldError } from \"./artwork-section.js\";\nimport { EMPTY_DRAFT, draftSupply, validateDropDraft, type DropDraft } from \"../../../utils/drop/draft.js\";\nimport { collectorPriceLine } from \"../../../utils/drop/sale.js\";\nimport { previewUrl } from \"../../../utils/drop/preview.js\";\nimport { useMedialaneApp } from \"../../medialane-app.js\";\nimport { useDropFee } from \"../../../utils/use-drops.js\";\n\nexport function DropCreate() {\n const app = useMedialaneApp();\n const feeBps = useDropFee();\n const [draft, setDraftState] = useState<DropDraft>(EMPTY_DRAFT);\n const [tried, setTried] = useState(false);\n const [launching, setLaunching] = useState(false);\n const setDraft = (patch: Partial<DropDraft>) => setDraftState((d) => ({ ...d, ...patch }));\n const errors = tried ? validateDropDraft(draft, Math.floor(Date.now() / 1000)) : {};\n\n const launch = () => {\n if (!app.walletAddress) return app.onRequireWallet();\n setTried(true);\n if (Object.keys(validateDropDraft(draft, Math.floor(Date.now() / 1000))).length === 0) setLaunching(true);\n };\n\n return (\n <div className=\"grid gap-6 lg:grid-cols-[minmax(0,1fr)_320px]\">\n <div className=\"space-y-5 lg:order-1 order-2\">\n <ArtworkSection draft={draft} setDraft={setDraft} errors={errors} />\n <DetailsSection draft={draft} setDraft={setDraft} errors={errors} />\n <SaleSection draft={draft} setDraft={setDraft} errors={errors} feeBps={feeBps} />\n <ListSection draft={draft} setDraft={setDraft} errors={errors} />\n <CollapsibleSection\n open={draft.gated.enabled}\n onOpenChange={(enabled) => setDraft({ gated: { ...draft.gated, enabled } })}\n icon={<Lock className=\"h-4 w-4 text-primary\" />}\n label=\"Exclusive content\"\n hint=\"Optional · a private link only holders can open\"\n >\n <ExclusiveFields value={draft.gated} onChange={(v) => setDraft({ gated: { ...draft.gated, ...v } })} />\n <FieldError message={errors.gated} />\n </CollapsibleSection>\n {tried && Object.keys(errors).length > 0 && <p className=\"text-sm font-medium text-destructive\">Check the highlighted fields.</p>}\n <GradientButton big onClick={launch}>\n {app.walletAddress ? \"Review and launch\" : app.connectLabel ?? \"Sign in to launch\"}\n </GradientButton>\n {launching && <LaunchDialog open onClose={() => setLaunching(false)} draft={draft} />}\n </div>\n <div className=\"order-1 lg:order-2\">\n <div className=\"lg:sticky lg:top-24\"><DraftSummary draft={draft} feeBps={feeBps} /></div>\n </div>\n </div>\n );\n}\n\n/** The drop as collectors will see it, updated as the form changes. */\nexport function DraftSummary({ draft, feeBps }: { draft: DropDraft; feeBps: number | null }) {\n const art = draft.cover ?? (draft.kind === \"edition\" ? draft.edition : draft.items[0]?.file ?? null);\n const preview = art ? previewUrl(art) : null;\n const supply = draftSupply(draft);\n return (\n <div className=\"overflow-hidden rounded-2xl border border-border bg-card\">\n <div className=\"relative aspect-square bg-muted\">\n {preview && <Image src={preview} alt={draft.name || \"Drop\"} fill unoptimized className=\"object-cover\" />}\n </div>\n <div className=\"space-y-1 p-4\">\n <p className=\"truncate font-semibold\">{draft.name || \"Untitled drop\"}</p>\n <p className=\"text-xs text-muted-foreground\">\n {draft.sale.paid ? (feeBps === null ? \"…\" : collectorPriceLine(draft.sale, feeBps) ?? \"Set a price\") : \"Free\"}\n </p>\n <p className=\"text-xs text-muted-foreground\">\n {Number.isFinite(supply) && supply > 0 ? `${supply.toLocaleString(\"en-US\")} ${draft.kind === \"edition\" ? (supply === 1 ? \"copy\" : \"copies\") : supply === 1 ? \"item\" : \"items\"}` : \"Supply not set\"}\n {\" · \"}{draft.listOnly ? \"List only\" : \"Open to everyone\"}\n </p>\n </div>\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAsCM;AApCN,mBAAyB;AACzB,0BAAqB;AACrB,mBAAkB;AAClB,6BAA+B;AAC/B,iCAAmC;AACnC,6BAA+B;AAC/B,6BAA+B;AAC/B,0BAA4B;AAC5B,0BAA4B;AAC5B,8BAAgC;AAChC,2BAA6B;AAC7B,IAAAA,0BAA2B;AAC3B,mBAA4E;AAC5E,kBAAmC;AACnC,qBAA2B;AAC3B,2BAAgC;AAChC,uBAA2B;AAEpB,SAAS,aAAa;AAC3B,QAAM,UAAM,sCAAgB;AAC5B,QAAM,aAAS,6BAAW;AAC1B,QAAM,CAAC,OAAO,aAAa,QAAI,uBAAoB,wBAAW;AAC9D,QAAM,CAAC,OAAO,QAAQ,QAAI,uBAAS,KAAK;AACxC,QAAM,CAAC,WAAW,YAAY,QAAI,uBAAS,KAAK;AAChD,QAAM,WAAW,CAAC,UAA8B,cAAc,CAAC,OAAO,EAAE,GAAG,GAAG,GAAG,MAAM,EAAE;AACzF,QAAM,SAAS,YAAQ,gCAAkB,OAAO,KAAK,MAAM,KAAK,IAAI,IAAI,GAAI,CAAC,IAAI,CAAC;AAElF,QAAM,SAAS,MAAM;AACnB,QAAI,CAAC,IAAI,cAAe,QAAO,IAAI,gBAAgB;AACnD,aAAS,IAAI;AACb,QAAI,OAAO,SAAK,gCAAkB,OAAO,KAAK,MAAM,KAAK,IAAI,IAAI,GAAI,CAAC,CAAC,EAAE,WAAW,EAAG,cAAa,IAAI;AAAA,EAC1G;AAEA,SACE,6CAAC,SAAI,WAAU,iDACf;AAAA,iDAAC,SAAI,WAAU,gCACb;AAAA,kDAAC,yCAAe,OAAc,UAAoB,QAAgB;AAAA,MAClE,4CAAC,yCAAe,OAAc,UAAoB,QAAgB;AAAA,MAClE,4CAAC,mCAAY,OAAc,UAAoB,QAAgB,QAAgB;AAAA,MAC/E,4CAAC,mCAAY,OAAc,UAAoB,QAAgB;AAAA,MAC/D;AAAA,QAAC;AAAA;AAAA,UACC,MAAM,MAAM,MAAM;AAAA,UAClB,cAAc,CAAC,YAAY,SAAS,EAAE,OAAO,EAAE,GAAG,MAAM,OAAO,QAAQ,EAAE,CAAC;AAAA,UAC1E,MAAM,4CAAC,4BAAK,WAAU,wBAAuB;AAAA,UAC7C,OAAM;AAAA,UACN,MAAK;AAAA,UAEL;AAAA,wDAAC,2CAAgB,OAAO,MAAM,OAAO,UAAU,CAAC,MAAM,SAAS,EAAE,OAAO,EAAE,GAAG,MAAM,OAAO,GAAG,EAAE,EAAE,CAAC,GAAG;AAAA,YACrG,4CAAC,sCAAW,SAAS,OAAO,OAAO;AAAA;AAAA;AAAA,MACrC;AAAA,MACC,SAAS,OAAO,KAAK,MAAM,EAAE,SAAS,KAAK,4CAAC,OAAE,WAAU,wCAAuC,2CAA6B;AAAA,MAC7H,4CAAC,yCAAe,KAAG,MAAC,SAAS,QAC1B,cAAI,gBAAgB,sBAAsB,IAAI,gBAAgB,qBACjE;AAAA,MACC,aAAa,4CAAC,qCAAa,MAAI,MAAC,SAAS,MAAM,aAAa,KAAK,GAAG,OAAc;AAAA,OACrF;AAAA,IACA,4CAAC,SAAI,WAAU,sBACb,sDAAC,SAAI,WAAU,uBAAsB,sDAAC,gBAAa,OAAc,QAAgB,GAAE,GACrF;AAAA,KACA;AAEJ;AAGO,SAAS,aAAa,EAAE,OAAO,OAAO,GAAgD;AAC3F,QAAM,MAAM,MAAM,UAAU,MAAM,SAAS,YAAY,MAAM,UAAU,MAAM,MAAM,CAAC,GAAG,QAAQ;AAC/F,QAAM,UAAU,UAAM,2BAAW,GAAG,IAAI;AACxC,QAAM,aAAS,0BAAY,KAAK;AAChC,SACE,6CAAC,SAAI,WAAU,4DACb;AAAA,gDAAC,SAAI,WAAU,mCACZ,qBAAW,4CAAC,aAAAC,SAAA,EAAM,KAAK,SAAS,KAAK,MAAM,QAAQ,QAAQ,MAAI,MAAC,aAAW,MAAC,WAAU,gBAAe,GACxG;AAAA,IACA,6CAAC,SAAI,WAAU,iBACb;AAAA,kDAAC,OAAE,WAAU,0BAA0B,gBAAM,QAAQ,iBAAgB;AAAA,MACrE,4CAAC,OAAE,WAAU,iCACV,gBAAM,KAAK,OAAQ,WAAW,OAAO,eAAM,gCAAmB,MAAM,MAAM,MAAM,KAAK,gBAAiB,QACzG;AAAA,MACA,6CAAC,OAAE,WAAU,iCACV;AAAA,eAAO,SAAS,MAAM,KAAK,SAAS,IAAI,GAAG,OAAO,eAAe,OAAO,CAAC,IAAI,MAAM,SAAS,YAAa,WAAW,IAAI,SAAS,WAAY,WAAW,IAAI,SAAS,OAAO,KAAK;AAAA,QACjL;AAAA,QAAO,MAAM,WAAW,cAAc;AAAA,SACzC;AAAA,OACF;AAAA,KACF;AAEJ;","names":["import_artwork_section","Image"]}
|
|
@@ -67,7 +67,7 @@ function DraftSummary({ draft, feeBps }) {
|
|
|
67
67
|
/* @__PURE__ */ jsx("p", { className: "truncate font-semibold", children: draft.name || "Untitled drop" }),
|
|
68
68
|
/* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: draft.sale.paid ? feeBps === null ? "\u2026" : collectorPriceLine(draft.sale, feeBps) ?? "Set a price" : "Free" }),
|
|
69
69
|
/* @__PURE__ */ jsxs("p", { className: "text-xs text-muted-foreground", children: [
|
|
70
|
-
Number.isFinite(supply) && supply > 0 ? `${supply.toLocaleString("en-US")} ${draft.kind === "edition" ? "copies" : "items"}` : "Supply not set",
|
|
70
|
+
Number.isFinite(supply) && supply > 0 ? `${supply.toLocaleString("en-US")} ${draft.kind === "edition" ? supply === 1 ? "copy" : "copies" : supply === 1 ? "item" : "items"}` : "Supply not set",
|
|
71
71
|
" \xB7 ",
|
|
72
72
|
draft.listOnly ? "List only" : "Open to everyone"
|
|
73
73
|
] })
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/components/drop/create/drop-create.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState } from \"react\";\nimport { Lock } from \"lucide-react\";\nimport Image from \"../../image.js\";\nimport { GradientButton } from \"../../gradient-button.js\";\nimport { CollapsibleSection } from \"../../collapsible-section.js\";\nimport { ArtworkSection } from \"./artwork-section.js\";\nimport { DetailsSection } from \"./details-section.js\";\nimport { SaleSection } from \"./sale-section.js\";\nimport { ListSection } from \"./list-section.js\";\nimport { ExclusiveFields } from \"./exclusive-fields.js\";\nimport { LaunchDialog } from \"./launch-dialog.js\";\nimport { FieldError } from \"./artwork-section.js\";\nimport { EMPTY_DRAFT, draftSupply, validateDropDraft, type DropDraft } from \"../../../utils/drop/draft.js\";\nimport { collectorPriceLine } from \"../../../utils/drop/sale.js\";\nimport { previewUrl } from \"../../../utils/drop/preview.js\";\nimport { useMedialaneApp } from \"../../medialane-app.js\";\nimport { useDropFee } from \"../../../utils/use-drops.js\";\n\nexport function DropCreate() {\n const app = useMedialaneApp();\n const feeBps = useDropFee();\n const [draft, setDraftState] = useState<DropDraft>(EMPTY_DRAFT);\n const [tried, setTried] = useState(false);\n const [launching, setLaunching] = useState(false);\n const setDraft = (patch: Partial<DropDraft>) => setDraftState((d) => ({ ...d, ...patch }));\n const errors = tried ? validateDropDraft(draft, Math.floor(Date.now() / 1000)) : {};\n\n const launch = () => {\n if (!app.walletAddress) return app.onRequireWallet();\n setTried(true);\n if (Object.keys(validateDropDraft(draft, Math.floor(Date.now() / 1000))).length === 0) setLaunching(true);\n };\n\n return (\n <div className=\"grid gap-6 lg:grid-cols-[minmax(0,1fr)_320px]\">\n <div className=\"space-y-5 lg:order-1 order-2\">\n <ArtworkSection draft={draft} setDraft={setDraft} errors={errors} />\n <DetailsSection draft={draft} setDraft={setDraft} errors={errors} />\n <SaleSection draft={draft} setDraft={setDraft} errors={errors} feeBps={feeBps} />\n <ListSection draft={draft} setDraft={setDraft} errors={errors} />\n <CollapsibleSection\n open={draft.gated.enabled}\n onOpenChange={(enabled) => setDraft({ gated: { ...draft.gated, enabled } })}\n icon={<Lock className=\"h-4 w-4 text-primary\" />}\n label=\"Exclusive content\"\n hint=\"Optional · a private link only holders can open\"\n >\n <ExclusiveFields value={draft.gated} onChange={(v) => setDraft({ gated: { ...draft.gated, ...v } })} />\n <FieldError message={errors.gated} />\n </CollapsibleSection>\n {tried && Object.keys(errors).length > 0 && <p className=\"text-sm font-medium text-destructive\">Check the highlighted fields.</p>}\n <GradientButton big onClick={launch}>\n {app.walletAddress ? \"Review and launch\" : app.connectLabel ?? \"Sign in to launch\"}\n </GradientButton>\n {launching && <LaunchDialog open onClose={() => setLaunching(false)} draft={draft} />}\n </div>\n <div className=\"order-1 lg:order-2\">\n <div className=\"lg:sticky lg:top-24\"><DraftSummary draft={draft} feeBps={feeBps} /></div>\n </div>\n </div>\n );\n}\n\n/** The drop as collectors will see it, updated as the form changes. */\nexport function DraftSummary({ draft, feeBps }: { draft: DropDraft; feeBps: number | null }) {\n const art = draft.cover ?? (draft.kind === \"edition\" ? draft.edition : draft.items[0]?.file ?? null);\n const preview = art ? previewUrl(art) : null;\n const supply = draftSupply(draft);\n return (\n <div className=\"overflow-hidden rounded-2xl border border-border bg-card\">\n <div className=\"relative aspect-square bg-muted\">\n {preview && <Image src={preview} alt={draft.name || \"Drop\"} fill unoptimized className=\"object-cover\" />}\n </div>\n <div className=\"space-y-1 p-4\">\n <p className=\"truncate font-semibold\">{draft.name || \"Untitled drop\"}</p>\n <p className=\"text-xs text-muted-foreground\">\n {draft.sale.paid ? (feeBps === null ? \"…\" : collectorPriceLine(draft.sale, feeBps) ?? \"Set a price\") : \"Free\"}\n </p>\n <p className=\"text-xs text-muted-foreground\">\n {Number.isFinite(supply) && supply > 0 ? `${supply.toLocaleString(\"en-US\")} ${draft.kind === \"edition\" ? \"copies\" : \"items\"}` : \"Supply not set\"}\n {\" · \"}{draft.listOnly ? \"List only\" : \"Open to everyone\"}\n </p>\n </div>\n </div>\n );\n}\n"],"mappings":"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
|
|
1
|
+
{"version":3,"sources":["../../../../src/components/drop/create/drop-create.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState } from \"react\";\nimport { Lock } from \"lucide-react\";\nimport Image from \"../../image.js\";\nimport { GradientButton } from \"../../gradient-button.js\";\nimport { CollapsibleSection } from \"../../collapsible-section.js\";\nimport { ArtworkSection } from \"./artwork-section.js\";\nimport { DetailsSection } from \"./details-section.js\";\nimport { SaleSection } from \"./sale-section.js\";\nimport { ListSection } from \"./list-section.js\";\nimport { ExclusiveFields } from \"./exclusive-fields.js\";\nimport { LaunchDialog } from \"./launch-dialog.js\";\nimport { FieldError } from \"./artwork-section.js\";\nimport { EMPTY_DRAFT, draftSupply, validateDropDraft, type DropDraft } from \"../../../utils/drop/draft.js\";\nimport { collectorPriceLine } from \"../../../utils/drop/sale.js\";\nimport { previewUrl } from \"../../../utils/drop/preview.js\";\nimport { useMedialaneApp } from \"../../medialane-app.js\";\nimport { useDropFee } from \"../../../utils/use-drops.js\";\n\nexport function DropCreate() {\n const app = useMedialaneApp();\n const feeBps = useDropFee();\n const [draft, setDraftState] = useState<DropDraft>(EMPTY_DRAFT);\n const [tried, setTried] = useState(false);\n const [launching, setLaunching] = useState(false);\n const setDraft = (patch: Partial<DropDraft>) => setDraftState((d) => ({ ...d, ...patch }));\n const errors = tried ? validateDropDraft(draft, Math.floor(Date.now() / 1000)) : {};\n\n const launch = () => {\n if (!app.walletAddress) return app.onRequireWallet();\n setTried(true);\n if (Object.keys(validateDropDraft(draft, Math.floor(Date.now() / 1000))).length === 0) setLaunching(true);\n };\n\n return (\n <div className=\"grid gap-6 lg:grid-cols-[minmax(0,1fr)_320px]\">\n <div className=\"space-y-5 lg:order-1 order-2\">\n <ArtworkSection draft={draft} setDraft={setDraft} errors={errors} />\n <DetailsSection draft={draft} setDraft={setDraft} errors={errors} />\n <SaleSection draft={draft} setDraft={setDraft} errors={errors} feeBps={feeBps} />\n <ListSection draft={draft} setDraft={setDraft} errors={errors} />\n <CollapsibleSection\n open={draft.gated.enabled}\n onOpenChange={(enabled) => setDraft({ gated: { ...draft.gated, enabled } })}\n icon={<Lock className=\"h-4 w-4 text-primary\" />}\n label=\"Exclusive content\"\n hint=\"Optional · a private link only holders can open\"\n >\n <ExclusiveFields value={draft.gated} onChange={(v) => setDraft({ gated: { ...draft.gated, ...v } })} />\n <FieldError message={errors.gated} />\n </CollapsibleSection>\n {tried && Object.keys(errors).length > 0 && <p className=\"text-sm font-medium text-destructive\">Check the highlighted fields.</p>}\n <GradientButton big onClick={launch}>\n {app.walletAddress ? \"Review and launch\" : app.connectLabel ?? \"Sign in to launch\"}\n </GradientButton>\n {launching && <LaunchDialog open onClose={() => setLaunching(false)} draft={draft} />}\n </div>\n <div className=\"order-1 lg:order-2\">\n <div className=\"lg:sticky lg:top-24\"><DraftSummary draft={draft} feeBps={feeBps} /></div>\n </div>\n </div>\n );\n}\n\n/** The drop as collectors will see it, updated as the form changes. */\nexport function DraftSummary({ draft, feeBps }: { draft: DropDraft; feeBps: number | null }) {\n const art = draft.cover ?? (draft.kind === \"edition\" ? draft.edition : draft.items[0]?.file ?? null);\n const preview = art ? previewUrl(art) : null;\n const supply = draftSupply(draft);\n return (\n <div className=\"overflow-hidden rounded-2xl border border-border bg-card\">\n <div className=\"relative aspect-square bg-muted\">\n {preview && <Image src={preview} alt={draft.name || \"Drop\"} fill unoptimized className=\"object-cover\" />}\n </div>\n <div className=\"space-y-1 p-4\">\n <p className=\"truncate font-semibold\">{draft.name || \"Untitled drop\"}</p>\n <p className=\"text-xs text-muted-foreground\">\n {draft.sale.paid ? (feeBps === null ? \"…\" : collectorPriceLine(draft.sale, feeBps) ?? \"Set a price\") : \"Free\"}\n </p>\n <p className=\"text-xs text-muted-foreground\">\n {Number.isFinite(supply) && supply > 0 ? `${supply.toLocaleString(\"en-US\")} ${draft.kind === \"edition\" ? (supply === 1 ? \"copy\" : \"copies\") : supply === 1 ? \"item\" : \"items\"}` : \"Supply not set\"}\n {\" · \"}{draft.listOnly ? \"List only\" : \"Open to everyone\"}\n </p>\n </div>\n </div>\n );\n}\n"],"mappings":"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","names":[]}
|
|
@@ -122,7 +122,7 @@ function LaunchDialog({ open, onClose, draft }) {
|
|
|
122
122
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "font-semibold", children: draft.name }),
|
|
123
123
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-xs font-semibold uppercase tracking-widest text-muted-foreground", children: "Fixed after launch" }),
|
|
124
124
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Row, { label: "Price", value: (0, import_sale.priceLabel)(terms.price, terms.paymentToken) }),
|
|
125
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Row, { label: "Supply", value: `${(0, import_draft.draftSupply)(draft).toLocaleString("en-US")} ${draft.kind === "edition" ? "copies" : "items"}` }),
|
|
125
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Row, { label: "Supply", value: `${(0, import_draft.draftSupply)(draft).toLocaleString("en-US")} ${draft.kind === "edition" ? (0, import_draft.draftSupply)(draft) === 1 ? "copy" : "copies" : (0, import_draft.draftSupply)(draft) === 1 ? "item" : "items"}` }),
|
|
126
126
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Row, { label: "Starts", value: terms.startTime === 0 ? "At launch" : new Date(terms.startTime * 1e3).toLocaleString() }),
|
|
127
127
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Row, { label: "Ends", value: terms.endTime === 0 ? "No end date" : new Date(terms.endTime * 1e3).toLocaleString() }),
|
|
128
128
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Row, { label: "Per wallet", value: terms.maxPerWallet === "0" ? "No limit" : terms.maxPerWallet }),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/components/drop/create/launch-dialog.tsx"],"sourcesContent":["\"use client\";\n\nimport { useMemo, useState } from \"react\";\nimport { CheckCircle2, Loader2, RotateCcw, XCircle } from \"lucide-react\";\nimport { dropHref } from \"@medialane/sdk\";\nimport { buildPopAllowlist, dropClaimLinks, popClaimLinksCsv, type PopClaimLink } from \"@medialane/sdk/starknet\";\nimport { ActionDialog } from \"../../action-dialog.js\";\nimport { GradientButton } from \"../../gradient-button.js\";\nimport { Button } from \"../../button.js\";\nimport { ShareButton } from \"../../share-button.js\";\nimport { describeError } from \"../../../utils/describe-error.js\";\nimport { uploadDirectoryToIpfs, uploadFileToIpfs } from \"../../../utils/ipfs-upload.js\";\nimport { parseAllowlist } from \"../../../utils/drop/allowlist.js\";\nimport { buildDropMetadataFiles, metadataBytes, MAX_DROP_METADATA_BYTES } from \"../../../utils/drop/metadata.js\";\nimport { toDropTerms, priceLabel } from \"../../../utils/drop/sale.js\";\nimport { draftSupply, type DropDraft } from \"../../../utils/drop/draft.js\";\nimport { uploadAll, type UploadTask } from \"../../../utils/drop/upload.js\";\nimport { launchDrop, saveExclusiveContent } from \"../../../utils/drop/actions.js\";\nimport { useMedialaneApp } from \"../../medialane-app.js\";\n\ntype Step =\n | { kind: \"review\" }\n | { kind: \"uploading\" }\n | { kind: \"launching\" }\n | { kind: \"done\"; collection: string; links: PopClaimLink[]; warning: string | null }\n | { kind: \"error\"; message: string };\n\nexport function LaunchDialog({ open, onClose, draft }: { open: boolean; onClose: () => void; draft: DropDraft }) {\n const app = useMedialaneApp();\n const [step, setStep] = useState<Step>({ kind: \"review\" });\n const [tasks, setTasks] = useState<UploadTask[]>([]);\n const [baseUri, setBaseUri] = useState<string | null>(null);\n const client = app.getClient();\n const files = draft.kind === \"edition\" ? (draft.edition ? [draft.edition] : []) : draft.items.map((i) => i.file);\n const terms = toDropTerms(draft.sale);\n const list = useMemo(\n () => (draft.listOnly ? buildPopAllowlist(parseAllowlist(draft.allowlist).addresses) : null),\n [draft.listOnly, draft.allowlist],\n );\n\n const run = async () => {\n try {\n let uri = baseUri;\n if (!uri) {\n setStep({ kind: \"uploading\" });\n const initial = tasks.length > 0 ? tasks : [\n ...files.map((file, i) => ({ id: `art-${i}`, file, status: \"pending\" as const, uri: null, error: null })),\n ...(draft.cover ? [{ id: \"cover\", file: draft.cover, status: \"pending\" as const, uri: null, error: null }] : []),\n ];\n const done = await uploadAll(initial, async (f) => (await uploadFileToIpfs(client.api, f, \"image\")).uri, setTasks);\n setTasks(done);\n if (done.some((t) => t.status !== \"done\")) {\n setStep({ kind: \"error\", message: \"Some files didn't upload. Retry to send only those.\" });\n return;\n }\n const art = done.filter((t) => t.id.startsWith(\"art-\"));\n const metadata = buildDropMetadataFiles({\n kind: draft.kind,\n name: draft.name.trim(),\n description: draft.description.trim(),\n creator: app.walletAddress!,\n coverUri: done.find((t) => t.id === \"cover\")?.uri ?? null,\n license: draft.license,\n items: draft.kind === \"edition\"\n ? [{ name: \"\", description: \"\", imageUri: art[0]!.uri! }]\n : draft.items.map((it, i) => ({ name: it.name, description: it.description, imageUri: art[i]!.uri! })),\n supply: draftSupply(draft),\n });\n if (metadataBytes(metadata) > MAX_DROP_METADATA_BYTES) {\n setStep({ kind: \"error\", message: \"The descriptions are too long for this many tokens. Shorten them and try again.\" });\n return;\n }\n uri = (await uploadDirectoryToIpfs(client.api, metadata)).baseUri;\n setBaseUri(uri);\n }\n setStep({ kind: \"launching\" });\n const signer = await app.getSigner();\n const { collection } = await launchDrop({ client, signer }, {\n owner: app.walletAddress!,\n name: draft.name.trim(),\n symbol: draft.symbol,\n baseUri: uri!,\n maxSupply: draftSupply(draft),\n terms,\n allowlistRoot: list?.root,\n description: draft.description.trim() || undefined,\n });\n let warning: string | null = null;\n if (draft.gated.enabled) {\n try {\n await saveExclusiveContent(client, collection, draft.gated);\n } catch {\n warning = \"Your drop launched, but the exclusive content wasn't saved. You can add it from Manage.\";\n }\n }\n setStep({ kind: \"done\", collection, links: list ? dropClaimLinks(window.location.origin, collection, list) : [], warning });\n } catch (err) {\n setStep({ kind: \"error\", message: describeError(err, \"We couldn't launch your drop. Please try again.\").message });\n }\n };\n\n const close = () => {\n if (step.kind === \"uploading\" || step.kind === \"launching\") return;\n onClose();\n };\n\n return (\n <ActionDialog open={open} onClose={close}>\n <div className=\"space-y-5 p-6\">\n {step.kind === \"review\" && (\n <>\n <h2 className=\"text-lg font-semibold\">Review and launch</h2>\n <div className=\"space-y-2 rounded-xl border border-border p-4 text-sm\">\n <p className=\"font-semibold\">{draft.name}</p>\n <p className=\"text-xs font-semibold uppercase tracking-widest text-muted-foreground\">Fixed after launch</p>\n <Row label=\"Price\" value={priceLabel(terms.price, terms.paymentToken)} />\n <Row label=\"Supply\" value={`${draftSupply(draft).toLocaleString(\"en-US\")} ${draft.kind === \"edition\" ? \"copies\" : \"items\"}`} />\n <Row label=\"Starts\" value={terms.startTime === 0 ? \"At launch\" : new Date(terms.startTime * 1000).toLocaleString()} />\n <Row label=\"Ends\" value={terms.endTime === 0 ? \"No end date\" : new Date(terms.endTime * 1000).toLocaleString()} />\n <Row label=\"Per wallet\" value={terms.maxPerWallet === \"0\" ? \"No limit\" : terms.maxPerWallet} />\n <Row label=\"Who can mint\" value={list ? `${Object.keys(list.proofs).length} wallets on a list` : \"Everyone\"} />\n <p className=\"pt-1 text-xs text-muted-foreground\">The artwork and these terms can't be changed after launch. You can change the list later.</p>\n </div>\n <GradientButton big onClick={() => void run()}>Launch drop</GradientButton>\n </>\n )}\n {step.kind === \"uploading\" && (\n <>\n <h2 className=\"flex items-center gap-2 text-lg font-semibold\"><Loader2 className=\"h-4 w-4 animate-spin\" />Uploading</h2>\n <p className=\"text-sm text-muted-foreground\">{tasks.filter((t) => t.status === \"done\").length} of {tasks.length} files</p>\n </>\n )}\n {step.kind === \"launching\" && (\n <h2 className=\"flex items-center gap-2 text-lg font-semibold\"><Loader2 className=\"h-4 w-4 animate-spin\" />Launching your drop…</h2>\n )}\n {step.kind === \"error\" && (\n <>\n <h2 className=\"flex items-center gap-2 text-lg font-semibold\"><XCircle className=\"h-4 w-4 text-destructive\" />Not launched</h2>\n <p className=\"text-sm text-muted-foreground\">{step.message}</p>\n {tasks.some((t) => t.status === \"failed\") && (\n <ul className=\"space-y-1 text-xs text-muted-foreground\">\n {tasks.filter((t) => t.status === \"failed\").map((t) => <li key={t.id}>{t.file.name}: {t.error}</li>)}\n </ul>\n )}\n <Button onClick={() => void run()} className=\"gap-1.5\"><RotateCcw className=\"h-3.5 w-3.5\" />Try again</Button>\n </>\n )}\n {step.kind === \"done\" && (\n <>\n <h2 className=\"flex items-center gap-2 text-lg font-semibold\"><CheckCircle2 className=\"h-5 w-5 text-green-500\" />Your drop is live</h2>\n {step.warning && <p className=\"text-sm text-brand-orange\">{step.warning}</p>}\n <div className=\"flex flex-wrap gap-2\">\n <ShareButton title={draft.name} url={`${window.location.origin}${dropHref(step.collection)}`} variant=\"outline\" />\n <Button asChild variant=\"outline\"><a href={dropHref(step.collection)}>View drop</a></Button>\n {step.links.length > 0 && (\n <Button variant=\"outline\" onClick={() => downloadCsv(popClaimLinksCsv(step.links), \"claim-links.csv\")}>Download claim links</Button>\n )}\n </div>\n {step.links.length > 0 && <p className=\"text-xs text-muted-foreground\">Send each wallet its link — the link is what lets it mint.</p>}\n </>\n )}\n </div>\n </ActionDialog>\n );\n}\n\nfunction Row({ label, value }: { label: string; value: string }) {\n return <div className=\"flex justify-between gap-3\"><span className=\"text-muted-foreground\">{label}</span><span className=\"text-right font-medium\">{value}</span></div>;\n}\n\nexport function downloadCsv(csv: string, name: string) {\n const href = URL.createObjectURL(new Blob([csv], { type: \"text/csv\" }));\n Object.assign(document.createElement(\"a\"), { href, download: name }).click();\n URL.revokeObjectURL(href);\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../../src/components/drop/create/launch-dialog.tsx"],"sourcesContent":["\"use client\";\n\nimport { useMemo, useState } from \"react\";\nimport { CheckCircle2, Loader2, RotateCcw, XCircle } from \"lucide-react\";\nimport { dropHref } from \"@medialane/sdk\";\nimport { buildPopAllowlist, dropClaimLinks, popClaimLinksCsv, type PopClaimLink } from \"@medialane/sdk/starknet\";\nimport { ActionDialog } from \"../../action-dialog.js\";\nimport { GradientButton } from \"../../gradient-button.js\";\nimport { Button } from \"../../button.js\";\nimport { ShareButton } from \"../../share-button.js\";\nimport { describeError } from \"../../../utils/describe-error.js\";\nimport { uploadDirectoryToIpfs, uploadFileToIpfs } from \"../../../utils/ipfs-upload.js\";\nimport { parseAllowlist } from \"../../../utils/drop/allowlist.js\";\nimport { buildDropMetadataFiles, metadataBytes, MAX_DROP_METADATA_BYTES } from \"../../../utils/drop/metadata.js\";\nimport { toDropTerms, priceLabel } from \"../../../utils/drop/sale.js\";\nimport { draftSupply, type DropDraft } from \"../../../utils/drop/draft.js\";\nimport { uploadAll, type UploadTask } from \"../../../utils/drop/upload.js\";\nimport { launchDrop, saveExclusiveContent } from \"../../../utils/drop/actions.js\";\nimport { useMedialaneApp } from \"../../medialane-app.js\";\n\ntype Step =\n | { kind: \"review\" }\n | { kind: \"uploading\" }\n | { kind: \"launching\" }\n | { kind: \"done\"; collection: string; links: PopClaimLink[]; warning: string | null }\n | { kind: \"error\"; message: string };\n\nexport function LaunchDialog({ open, onClose, draft }: { open: boolean; onClose: () => void; draft: DropDraft }) {\n const app = useMedialaneApp();\n const [step, setStep] = useState<Step>({ kind: \"review\" });\n const [tasks, setTasks] = useState<UploadTask[]>([]);\n const [baseUri, setBaseUri] = useState<string | null>(null);\n const client = app.getClient();\n const files = draft.kind === \"edition\" ? (draft.edition ? [draft.edition] : []) : draft.items.map((i) => i.file);\n const terms = toDropTerms(draft.sale);\n const list = useMemo(\n () => (draft.listOnly ? buildPopAllowlist(parseAllowlist(draft.allowlist).addresses) : null),\n [draft.listOnly, draft.allowlist],\n );\n\n const run = async () => {\n try {\n let uri = baseUri;\n if (!uri) {\n setStep({ kind: \"uploading\" });\n const initial = tasks.length > 0 ? tasks : [\n ...files.map((file, i) => ({ id: `art-${i}`, file, status: \"pending\" as const, uri: null, error: null })),\n ...(draft.cover ? [{ id: \"cover\", file: draft.cover, status: \"pending\" as const, uri: null, error: null }] : []),\n ];\n const done = await uploadAll(initial, async (f) => (await uploadFileToIpfs(client.api, f, \"image\")).uri, setTasks);\n setTasks(done);\n if (done.some((t) => t.status !== \"done\")) {\n setStep({ kind: \"error\", message: \"Some files didn't upload. Retry to send only those.\" });\n return;\n }\n const art = done.filter((t) => t.id.startsWith(\"art-\"));\n const metadata = buildDropMetadataFiles({\n kind: draft.kind,\n name: draft.name.trim(),\n description: draft.description.trim(),\n creator: app.walletAddress!,\n coverUri: done.find((t) => t.id === \"cover\")?.uri ?? null,\n license: draft.license,\n items: draft.kind === \"edition\"\n ? [{ name: \"\", description: \"\", imageUri: art[0]!.uri! }]\n : draft.items.map((it, i) => ({ name: it.name, description: it.description, imageUri: art[i]!.uri! })),\n supply: draftSupply(draft),\n });\n if (metadataBytes(metadata) > MAX_DROP_METADATA_BYTES) {\n setStep({ kind: \"error\", message: \"The descriptions are too long for this many tokens. Shorten them and try again.\" });\n return;\n }\n uri = (await uploadDirectoryToIpfs(client.api, metadata)).baseUri;\n setBaseUri(uri);\n }\n setStep({ kind: \"launching\" });\n const signer = await app.getSigner();\n const { collection } = await launchDrop({ client, signer }, {\n owner: app.walletAddress!,\n name: draft.name.trim(),\n symbol: draft.symbol,\n baseUri: uri!,\n maxSupply: draftSupply(draft),\n terms,\n allowlistRoot: list?.root,\n description: draft.description.trim() || undefined,\n });\n let warning: string | null = null;\n if (draft.gated.enabled) {\n try {\n await saveExclusiveContent(client, collection, draft.gated);\n } catch {\n warning = \"Your drop launched, but the exclusive content wasn't saved. You can add it from Manage.\";\n }\n }\n setStep({ kind: \"done\", collection, links: list ? dropClaimLinks(window.location.origin, collection, list) : [], warning });\n } catch (err) {\n setStep({ kind: \"error\", message: describeError(err, \"We couldn't launch your drop. Please try again.\").message });\n }\n };\n\n const close = () => {\n if (step.kind === \"uploading\" || step.kind === \"launching\") return;\n onClose();\n };\n\n return (\n <ActionDialog open={open} onClose={close}>\n <div className=\"space-y-5 p-6\">\n {step.kind === \"review\" && (\n <>\n <h2 className=\"text-lg font-semibold\">Review and launch</h2>\n <div className=\"space-y-2 rounded-xl border border-border p-4 text-sm\">\n <p className=\"font-semibold\">{draft.name}</p>\n <p className=\"text-xs font-semibold uppercase tracking-widest text-muted-foreground\">Fixed after launch</p>\n <Row label=\"Price\" value={priceLabel(terms.price, terms.paymentToken)} />\n <Row label=\"Supply\" value={`${draftSupply(draft).toLocaleString(\"en-US\")} ${draft.kind === \"edition\" ? (draftSupply(draft) === 1 ? \"copy\" : \"copies\") : draftSupply(draft) === 1 ? \"item\" : \"items\"}`} />\n <Row label=\"Starts\" value={terms.startTime === 0 ? \"At launch\" : new Date(terms.startTime * 1000).toLocaleString()} />\n <Row label=\"Ends\" value={terms.endTime === 0 ? \"No end date\" : new Date(terms.endTime * 1000).toLocaleString()} />\n <Row label=\"Per wallet\" value={terms.maxPerWallet === \"0\" ? \"No limit\" : terms.maxPerWallet} />\n <Row label=\"Who can mint\" value={list ? `${Object.keys(list.proofs).length} wallets on a list` : \"Everyone\"} />\n <p className=\"pt-1 text-xs text-muted-foreground\">The artwork and these terms can't be changed after launch. You can change the list later.</p>\n </div>\n <GradientButton big onClick={() => void run()}>Launch drop</GradientButton>\n </>\n )}\n {step.kind === \"uploading\" && (\n <>\n <h2 className=\"flex items-center gap-2 text-lg font-semibold\"><Loader2 className=\"h-4 w-4 animate-spin\" />Uploading</h2>\n <p className=\"text-sm text-muted-foreground\">{tasks.filter((t) => t.status === \"done\").length} of {tasks.length} files</p>\n </>\n )}\n {step.kind === \"launching\" && (\n <h2 className=\"flex items-center gap-2 text-lg font-semibold\"><Loader2 className=\"h-4 w-4 animate-spin\" />Launching your drop…</h2>\n )}\n {step.kind === \"error\" && (\n <>\n <h2 className=\"flex items-center gap-2 text-lg font-semibold\"><XCircle className=\"h-4 w-4 text-destructive\" />Not launched</h2>\n <p className=\"text-sm text-muted-foreground\">{step.message}</p>\n {tasks.some((t) => t.status === \"failed\") && (\n <ul className=\"space-y-1 text-xs text-muted-foreground\">\n {tasks.filter((t) => t.status === \"failed\").map((t) => <li key={t.id}>{t.file.name}: {t.error}</li>)}\n </ul>\n )}\n <Button onClick={() => void run()} className=\"gap-1.5\"><RotateCcw className=\"h-3.5 w-3.5\" />Try again</Button>\n </>\n )}\n {step.kind === \"done\" && (\n <>\n <h2 className=\"flex items-center gap-2 text-lg font-semibold\"><CheckCircle2 className=\"h-5 w-5 text-green-500\" />Your drop is live</h2>\n {step.warning && <p className=\"text-sm text-brand-orange\">{step.warning}</p>}\n <div className=\"flex flex-wrap gap-2\">\n <ShareButton title={draft.name} url={`${window.location.origin}${dropHref(step.collection)}`} variant=\"outline\" />\n <Button asChild variant=\"outline\"><a href={dropHref(step.collection)}>View drop</a></Button>\n {step.links.length > 0 && (\n <Button variant=\"outline\" onClick={() => downloadCsv(popClaimLinksCsv(step.links), \"claim-links.csv\")}>Download claim links</Button>\n )}\n </div>\n {step.links.length > 0 && <p className=\"text-xs text-muted-foreground\">Send each wallet its link — the link is what lets it mint.</p>}\n </>\n )}\n </div>\n </ActionDialog>\n );\n}\n\nfunction Row({ label, value }: { label: string; value: string }) {\n return <div className=\"flex justify-between gap-3\"><span className=\"text-muted-foreground\">{label}</span><span className=\"text-right font-medium\">{value}</span></div>;\n}\n\nexport function downloadCsv(csv: string, name: string) {\n const href = URL.createObjectURL(new Blob([csv], { type: \"text/csv\" }));\n Object.assign(document.createElement(\"a\"), { href, download: name }).click();\n URL.revokeObjectURL(href);\n}\n"],"mappings":"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","names":[]}
|
|
@@ -98,7 +98,7 @@ function LaunchDialog({ open, onClose, draft }) {
|
|
|
98
98
|
/* @__PURE__ */ jsx("p", { className: "font-semibold", children: draft.name }),
|
|
99
99
|
/* @__PURE__ */ jsx("p", { className: "text-xs font-semibold uppercase tracking-widest text-muted-foreground", children: "Fixed after launch" }),
|
|
100
100
|
/* @__PURE__ */ jsx(Row, { label: "Price", value: priceLabel(terms.price, terms.paymentToken) }),
|
|
101
|
-
/* @__PURE__ */ jsx(Row, { label: "Supply", value: `${draftSupply(draft).toLocaleString("en-US")} ${draft.kind === "edition" ? "copies" : "items"}` }),
|
|
101
|
+
/* @__PURE__ */ jsx(Row, { label: "Supply", value: `${draftSupply(draft).toLocaleString("en-US")} ${draft.kind === "edition" ? draftSupply(draft) === 1 ? "copy" : "copies" : draftSupply(draft) === 1 ? "item" : "items"}` }),
|
|
102
102
|
/* @__PURE__ */ jsx(Row, { label: "Starts", value: terms.startTime === 0 ? "At launch" : new Date(terms.startTime * 1e3).toLocaleString() }),
|
|
103
103
|
/* @__PURE__ */ jsx(Row, { label: "Ends", value: terms.endTime === 0 ? "No end date" : new Date(terms.endTime * 1e3).toLocaleString() }),
|
|
104
104
|
/* @__PURE__ */ jsx(Row, { label: "Per wallet", value: terms.maxPerWallet === "0" ? "No limit" : terms.maxPerWallet }),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/components/drop/create/launch-dialog.tsx"],"sourcesContent":["\"use client\";\n\nimport { useMemo, useState } from \"react\";\nimport { CheckCircle2, Loader2, RotateCcw, XCircle } from \"lucide-react\";\nimport { dropHref } from \"@medialane/sdk\";\nimport { buildPopAllowlist, dropClaimLinks, popClaimLinksCsv, type PopClaimLink } from \"@medialane/sdk/starknet\";\nimport { ActionDialog } from \"../../action-dialog.js\";\nimport { GradientButton } from \"../../gradient-button.js\";\nimport { Button } from \"../../button.js\";\nimport { ShareButton } from \"../../share-button.js\";\nimport { describeError } from \"../../../utils/describe-error.js\";\nimport { uploadDirectoryToIpfs, uploadFileToIpfs } from \"../../../utils/ipfs-upload.js\";\nimport { parseAllowlist } from \"../../../utils/drop/allowlist.js\";\nimport { buildDropMetadataFiles, metadataBytes, MAX_DROP_METADATA_BYTES } from \"../../../utils/drop/metadata.js\";\nimport { toDropTerms, priceLabel } from \"../../../utils/drop/sale.js\";\nimport { draftSupply, type DropDraft } from \"../../../utils/drop/draft.js\";\nimport { uploadAll, type UploadTask } from \"../../../utils/drop/upload.js\";\nimport { launchDrop, saveExclusiveContent } from \"../../../utils/drop/actions.js\";\nimport { useMedialaneApp } from \"../../medialane-app.js\";\n\ntype Step =\n | { kind: \"review\" }\n | { kind: \"uploading\" }\n | { kind: \"launching\" }\n | { kind: \"done\"; collection: string; links: PopClaimLink[]; warning: string | null }\n | { kind: \"error\"; message: string };\n\nexport function LaunchDialog({ open, onClose, draft }: { open: boolean; onClose: () => void; draft: DropDraft }) {\n const app = useMedialaneApp();\n const [step, setStep] = useState<Step>({ kind: \"review\" });\n const [tasks, setTasks] = useState<UploadTask[]>([]);\n const [baseUri, setBaseUri] = useState<string | null>(null);\n const client = app.getClient();\n const files = draft.kind === \"edition\" ? (draft.edition ? [draft.edition] : []) : draft.items.map((i) => i.file);\n const terms = toDropTerms(draft.sale);\n const list = useMemo(\n () => (draft.listOnly ? buildPopAllowlist(parseAllowlist(draft.allowlist).addresses) : null),\n [draft.listOnly, draft.allowlist],\n );\n\n const run = async () => {\n try {\n let uri = baseUri;\n if (!uri) {\n setStep({ kind: \"uploading\" });\n const initial = tasks.length > 0 ? tasks : [\n ...files.map((file, i) => ({ id: `art-${i}`, file, status: \"pending\" as const, uri: null, error: null })),\n ...(draft.cover ? [{ id: \"cover\", file: draft.cover, status: \"pending\" as const, uri: null, error: null }] : []),\n ];\n const done = await uploadAll(initial, async (f) => (await uploadFileToIpfs(client.api, f, \"image\")).uri, setTasks);\n setTasks(done);\n if (done.some((t) => t.status !== \"done\")) {\n setStep({ kind: \"error\", message: \"Some files didn't upload. Retry to send only those.\" });\n return;\n }\n const art = done.filter((t) => t.id.startsWith(\"art-\"));\n const metadata = buildDropMetadataFiles({\n kind: draft.kind,\n name: draft.name.trim(),\n description: draft.description.trim(),\n creator: app.walletAddress!,\n coverUri: done.find((t) => t.id === \"cover\")?.uri ?? null,\n license: draft.license,\n items: draft.kind === \"edition\"\n ? [{ name: \"\", description: \"\", imageUri: art[0]!.uri! }]\n : draft.items.map((it, i) => ({ name: it.name, description: it.description, imageUri: art[i]!.uri! })),\n supply: draftSupply(draft),\n });\n if (metadataBytes(metadata) > MAX_DROP_METADATA_BYTES) {\n setStep({ kind: \"error\", message: \"The descriptions are too long for this many tokens. Shorten them and try again.\" });\n return;\n }\n uri = (await uploadDirectoryToIpfs(client.api, metadata)).baseUri;\n setBaseUri(uri);\n }\n setStep({ kind: \"launching\" });\n const signer = await app.getSigner();\n const { collection } = await launchDrop({ client, signer }, {\n owner: app.walletAddress!,\n name: draft.name.trim(),\n symbol: draft.symbol,\n baseUri: uri!,\n maxSupply: draftSupply(draft),\n terms,\n allowlistRoot: list?.root,\n description: draft.description.trim() || undefined,\n });\n let warning: string | null = null;\n if (draft.gated.enabled) {\n try {\n await saveExclusiveContent(client, collection, draft.gated);\n } catch {\n warning = \"Your drop launched, but the exclusive content wasn't saved. You can add it from Manage.\";\n }\n }\n setStep({ kind: \"done\", collection, links: list ? dropClaimLinks(window.location.origin, collection, list) : [], warning });\n } catch (err) {\n setStep({ kind: \"error\", message: describeError(err, \"We couldn't launch your drop. Please try again.\").message });\n }\n };\n\n const close = () => {\n if (step.kind === \"uploading\" || step.kind === \"launching\") return;\n onClose();\n };\n\n return (\n <ActionDialog open={open} onClose={close}>\n <div className=\"space-y-5 p-6\">\n {step.kind === \"review\" && (\n <>\n <h2 className=\"text-lg font-semibold\">Review and launch</h2>\n <div className=\"space-y-2 rounded-xl border border-border p-4 text-sm\">\n <p className=\"font-semibold\">{draft.name}</p>\n <p className=\"text-xs font-semibold uppercase tracking-widest text-muted-foreground\">Fixed after launch</p>\n <Row label=\"Price\" value={priceLabel(terms.price, terms.paymentToken)} />\n <Row label=\"Supply\" value={`${draftSupply(draft).toLocaleString(\"en-US\")} ${draft.kind === \"edition\" ? \"copies\" : \"items\"}`} />\n <Row label=\"Starts\" value={terms.startTime === 0 ? \"At launch\" : new Date(terms.startTime * 1000).toLocaleString()} />\n <Row label=\"Ends\" value={terms.endTime === 0 ? \"No end date\" : new Date(terms.endTime * 1000).toLocaleString()} />\n <Row label=\"Per wallet\" value={terms.maxPerWallet === \"0\" ? \"No limit\" : terms.maxPerWallet} />\n <Row label=\"Who can mint\" value={list ? `${Object.keys(list.proofs).length} wallets on a list` : \"Everyone\"} />\n <p className=\"pt-1 text-xs text-muted-foreground\">The artwork and these terms can't be changed after launch. You can change the list later.</p>\n </div>\n <GradientButton big onClick={() => void run()}>Launch drop</GradientButton>\n </>\n )}\n {step.kind === \"uploading\" && (\n <>\n <h2 className=\"flex items-center gap-2 text-lg font-semibold\"><Loader2 className=\"h-4 w-4 animate-spin\" />Uploading</h2>\n <p className=\"text-sm text-muted-foreground\">{tasks.filter((t) => t.status === \"done\").length} of {tasks.length} files</p>\n </>\n )}\n {step.kind === \"launching\" && (\n <h2 className=\"flex items-center gap-2 text-lg font-semibold\"><Loader2 className=\"h-4 w-4 animate-spin\" />Launching your drop…</h2>\n )}\n {step.kind === \"error\" && (\n <>\n <h2 className=\"flex items-center gap-2 text-lg font-semibold\"><XCircle className=\"h-4 w-4 text-destructive\" />Not launched</h2>\n <p className=\"text-sm text-muted-foreground\">{step.message}</p>\n {tasks.some((t) => t.status === \"failed\") && (\n <ul className=\"space-y-1 text-xs text-muted-foreground\">\n {tasks.filter((t) => t.status === \"failed\").map((t) => <li key={t.id}>{t.file.name}: {t.error}</li>)}\n </ul>\n )}\n <Button onClick={() => void run()} className=\"gap-1.5\"><RotateCcw className=\"h-3.5 w-3.5\" />Try again</Button>\n </>\n )}\n {step.kind === \"done\" && (\n <>\n <h2 className=\"flex items-center gap-2 text-lg font-semibold\"><CheckCircle2 className=\"h-5 w-5 text-green-500\" />Your drop is live</h2>\n {step.warning && <p className=\"text-sm text-brand-orange\">{step.warning}</p>}\n <div className=\"flex flex-wrap gap-2\">\n <ShareButton title={draft.name} url={`${window.location.origin}${dropHref(step.collection)}`} variant=\"outline\" />\n <Button asChild variant=\"outline\"><a href={dropHref(step.collection)}>View drop</a></Button>\n {step.links.length > 0 && (\n <Button variant=\"outline\" onClick={() => downloadCsv(popClaimLinksCsv(step.links), \"claim-links.csv\")}>Download claim links</Button>\n )}\n </div>\n {step.links.length > 0 && <p className=\"text-xs text-muted-foreground\">Send each wallet its link — the link is what lets it mint.</p>}\n </>\n )}\n </div>\n </ActionDialog>\n );\n}\n\nfunction Row({ label, value }: { label: string; value: string }) {\n return <div className=\"flex justify-between gap-3\"><span className=\"text-muted-foreground\">{label}</span><span className=\"text-right font-medium\">{value}</span></div>;\n}\n\nexport function downloadCsv(csv: string, name: string) {\n const href = URL.createObjectURL(new Blob([csv], { type: \"text/csv\" }));\n Object.assign(document.createElement(\"a\"), { href, download: name }).click();\n URL.revokeObjectURL(href);\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../../src/components/drop/create/launch-dialog.tsx"],"sourcesContent":["\"use client\";\n\nimport { useMemo, useState } from \"react\";\nimport { CheckCircle2, Loader2, RotateCcw, XCircle } from \"lucide-react\";\nimport { dropHref } from \"@medialane/sdk\";\nimport { buildPopAllowlist, dropClaimLinks, popClaimLinksCsv, type PopClaimLink } from \"@medialane/sdk/starknet\";\nimport { ActionDialog } from \"../../action-dialog.js\";\nimport { GradientButton } from \"../../gradient-button.js\";\nimport { Button } from \"../../button.js\";\nimport { ShareButton } from \"../../share-button.js\";\nimport { describeError } from \"../../../utils/describe-error.js\";\nimport { uploadDirectoryToIpfs, uploadFileToIpfs } from \"../../../utils/ipfs-upload.js\";\nimport { parseAllowlist } from \"../../../utils/drop/allowlist.js\";\nimport { buildDropMetadataFiles, metadataBytes, MAX_DROP_METADATA_BYTES } from \"../../../utils/drop/metadata.js\";\nimport { toDropTerms, priceLabel } from \"../../../utils/drop/sale.js\";\nimport { draftSupply, type DropDraft } from \"../../../utils/drop/draft.js\";\nimport { uploadAll, type UploadTask } from \"../../../utils/drop/upload.js\";\nimport { launchDrop, saveExclusiveContent } from \"../../../utils/drop/actions.js\";\nimport { useMedialaneApp } from \"../../medialane-app.js\";\n\ntype Step =\n | { kind: \"review\" }\n | { kind: \"uploading\" }\n | { kind: \"launching\" }\n | { kind: \"done\"; collection: string; links: PopClaimLink[]; warning: string | null }\n | { kind: \"error\"; message: string };\n\nexport function LaunchDialog({ open, onClose, draft }: { open: boolean; onClose: () => void; draft: DropDraft }) {\n const app = useMedialaneApp();\n const [step, setStep] = useState<Step>({ kind: \"review\" });\n const [tasks, setTasks] = useState<UploadTask[]>([]);\n const [baseUri, setBaseUri] = useState<string | null>(null);\n const client = app.getClient();\n const files = draft.kind === \"edition\" ? (draft.edition ? [draft.edition] : []) : draft.items.map((i) => i.file);\n const terms = toDropTerms(draft.sale);\n const list = useMemo(\n () => (draft.listOnly ? buildPopAllowlist(parseAllowlist(draft.allowlist).addresses) : null),\n [draft.listOnly, draft.allowlist],\n );\n\n const run = async () => {\n try {\n let uri = baseUri;\n if (!uri) {\n setStep({ kind: \"uploading\" });\n const initial = tasks.length > 0 ? tasks : [\n ...files.map((file, i) => ({ id: `art-${i}`, file, status: \"pending\" as const, uri: null, error: null })),\n ...(draft.cover ? [{ id: \"cover\", file: draft.cover, status: \"pending\" as const, uri: null, error: null }] : []),\n ];\n const done = await uploadAll(initial, async (f) => (await uploadFileToIpfs(client.api, f, \"image\")).uri, setTasks);\n setTasks(done);\n if (done.some((t) => t.status !== \"done\")) {\n setStep({ kind: \"error\", message: \"Some files didn't upload. Retry to send only those.\" });\n return;\n }\n const art = done.filter((t) => t.id.startsWith(\"art-\"));\n const metadata = buildDropMetadataFiles({\n kind: draft.kind,\n name: draft.name.trim(),\n description: draft.description.trim(),\n creator: app.walletAddress!,\n coverUri: done.find((t) => t.id === \"cover\")?.uri ?? null,\n license: draft.license,\n items: draft.kind === \"edition\"\n ? [{ name: \"\", description: \"\", imageUri: art[0]!.uri! }]\n : draft.items.map((it, i) => ({ name: it.name, description: it.description, imageUri: art[i]!.uri! })),\n supply: draftSupply(draft),\n });\n if (metadataBytes(metadata) > MAX_DROP_METADATA_BYTES) {\n setStep({ kind: \"error\", message: \"The descriptions are too long for this many tokens. Shorten them and try again.\" });\n return;\n }\n uri = (await uploadDirectoryToIpfs(client.api, metadata)).baseUri;\n setBaseUri(uri);\n }\n setStep({ kind: \"launching\" });\n const signer = await app.getSigner();\n const { collection } = await launchDrop({ client, signer }, {\n owner: app.walletAddress!,\n name: draft.name.trim(),\n symbol: draft.symbol,\n baseUri: uri!,\n maxSupply: draftSupply(draft),\n terms,\n allowlistRoot: list?.root,\n description: draft.description.trim() || undefined,\n });\n let warning: string | null = null;\n if (draft.gated.enabled) {\n try {\n await saveExclusiveContent(client, collection, draft.gated);\n } catch {\n warning = \"Your drop launched, but the exclusive content wasn't saved. You can add it from Manage.\";\n }\n }\n setStep({ kind: \"done\", collection, links: list ? dropClaimLinks(window.location.origin, collection, list) : [], warning });\n } catch (err) {\n setStep({ kind: \"error\", message: describeError(err, \"We couldn't launch your drop. Please try again.\").message });\n }\n };\n\n const close = () => {\n if (step.kind === \"uploading\" || step.kind === \"launching\") return;\n onClose();\n };\n\n return (\n <ActionDialog open={open} onClose={close}>\n <div className=\"space-y-5 p-6\">\n {step.kind === \"review\" && (\n <>\n <h2 className=\"text-lg font-semibold\">Review and launch</h2>\n <div className=\"space-y-2 rounded-xl border border-border p-4 text-sm\">\n <p className=\"font-semibold\">{draft.name}</p>\n <p className=\"text-xs font-semibold uppercase tracking-widest text-muted-foreground\">Fixed after launch</p>\n <Row label=\"Price\" value={priceLabel(terms.price, terms.paymentToken)} />\n <Row label=\"Supply\" value={`${draftSupply(draft).toLocaleString(\"en-US\")} ${draft.kind === \"edition\" ? (draftSupply(draft) === 1 ? \"copy\" : \"copies\") : draftSupply(draft) === 1 ? \"item\" : \"items\"}`} />\n <Row label=\"Starts\" value={terms.startTime === 0 ? \"At launch\" : new Date(terms.startTime * 1000).toLocaleString()} />\n <Row label=\"Ends\" value={terms.endTime === 0 ? \"No end date\" : new Date(terms.endTime * 1000).toLocaleString()} />\n <Row label=\"Per wallet\" value={terms.maxPerWallet === \"0\" ? \"No limit\" : terms.maxPerWallet} />\n <Row label=\"Who can mint\" value={list ? `${Object.keys(list.proofs).length} wallets on a list` : \"Everyone\"} />\n <p className=\"pt-1 text-xs text-muted-foreground\">The artwork and these terms can't be changed after launch. You can change the list later.</p>\n </div>\n <GradientButton big onClick={() => void run()}>Launch drop</GradientButton>\n </>\n )}\n {step.kind === \"uploading\" && (\n <>\n <h2 className=\"flex items-center gap-2 text-lg font-semibold\"><Loader2 className=\"h-4 w-4 animate-spin\" />Uploading</h2>\n <p className=\"text-sm text-muted-foreground\">{tasks.filter((t) => t.status === \"done\").length} of {tasks.length} files</p>\n </>\n )}\n {step.kind === \"launching\" && (\n <h2 className=\"flex items-center gap-2 text-lg font-semibold\"><Loader2 className=\"h-4 w-4 animate-spin\" />Launching your drop…</h2>\n )}\n {step.kind === \"error\" && (\n <>\n <h2 className=\"flex items-center gap-2 text-lg font-semibold\"><XCircle className=\"h-4 w-4 text-destructive\" />Not launched</h2>\n <p className=\"text-sm text-muted-foreground\">{step.message}</p>\n {tasks.some((t) => t.status === \"failed\") && (\n <ul className=\"space-y-1 text-xs text-muted-foreground\">\n {tasks.filter((t) => t.status === \"failed\").map((t) => <li key={t.id}>{t.file.name}: {t.error}</li>)}\n </ul>\n )}\n <Button onClick={() => void run()} className=\"gap-1.5\"><RotateCcw className=\"h-3.5 w-3.5\" />Try again</Button>\n </>\n )}\n {step.kind === \"done\" && (\n <>\n <h2 className=\"flex items-center gap-2 text-lg font-semibold\"><CheckCircle2 className=\"h-5 w-5 text-green-500\" />Your drop is live</h2>\n {step.warning && <p className=\"text-sm text-brand-orange\">{step.warning}</p>}\n <div className=\"flex flex-wrap gap-2\">\n <ShareButton title={draft.name} url={`${window.location.origin}${dropHref(step.collection)}`} variant=\"outline\" />\n <Button asChild variant=\"outline\"><a href={dropHref(step.collection)}>View drop</a></Button>\n {step.links.length > 0 && (\n <Button variant=\"outline\" onClick={() => downloadCsv(popClaimLinksCsv(step.links), \"claim-links.csv\")}>Download claim links</Button>\n )}\n </div>\n {step.links.length > 0 && <p className=\"text-xs text-muted-foreground\">Send each wallet its link — the link is what lets it mint.</p>}\n </>\n )}\n </div>\n </ActionDialog>\n );\n}\n\nfunction Row({ label, value }: { label: string; value: string }) {\n return <div className=\"flex justify-between gap-3\"><span className=\"text-muted-foreground\">{label}</span><span className=\"text-right font-medium\">{value}</span></div>;\n}\n\nexport function downloadCsv(csv: string, name: string) {\n const href = URL.createObjectURL(new Blob([csv], { type: \"text/csv\" }));\n Object.assign(document.createElement(\"a\"), { href, download: name }).click();\n URL.revokeObjectURL(href);\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 };
|
|
@@ -61,7 +61,8 @@ function HeroSlide({ collection, active, getHref }) {
|
|
|
61
61
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_link.default, { href: getHref(collection), className: "hover:opacity-90 transition-opacity", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h2", { className: "text-4xl lg:text-5xl font-semibold text-white leading-tight", children: name }) }),
|
|
62
62
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "flex items-center gap-4 text-sm text-white/70", children: supply != null && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { children: [
|
|
63
63
|
supply.toLocaleString(),
|
|
64
|
-
"
|
|
64
|
+
" ",
|
|
65
|
+
supply === 1 ? "item" : "items"
|
|
65
66
|
] }) })
|
|
66
67
|
] })
|
|
67
68
|
] });
|