@medialane/ui 0.258.0 → 0.260.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/activities-feed.cjs +5 -1
- package/dist/components/activities-feed.cjs.map +1 -1
- package/dist/components/activities-feed.js +5 -1
- package/dist/components/activities-feed.js.map +1 -1
- package/dist/components/activity-feed-shell.cjs +3 -1
- package/dist/components/activity-feed-shell.cjs.map +1 -1
- package/dist/components/activity-feed-shell.js +3 -1
- package/dist/components/activity-feed-shell.js.map +1 -1
- package/dist/components/button.d.cts +1 -1
- package/dist/components/button.d.ts +1 -1
- package/dist/components/coins-explorer.cjs +5 -1
- package/dist/components/coins-explorer.cjs.map +1 -1
- package/dist/components/coins-explorer.js +6 -2
- package/dist/components/coins-explorer.js.map +1 -1
- package/dist/components/comments-section.cjs +7 -6
- package/dist/components/comments-section.cjs.map +1 -1
- package/dist/components/comments-section.js +7 -6
- package/dist/components/comments-section.js.map +1 -1
- package/dist/components/discover-community-section.cjs +5 -1
- package/dist/components/discover-community-section.cjs.map +1 -1
- package/dist/components/discover-community-section.js +5 -1
- package/dist/components/discover-community-section.js.map +1 -1
- package/dist/components/discover-feed-section.cjs +5 -1
- package/dist/components/discover-feed-section.cjs.map +1 -1
- package/dist/components/discover-feed-section.js +5 -1
- package/dist/components/discover-feed-section.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/fast-mint/success-view.cjs +2 -2
- package/dist/components/fast-mint/success-view.cjs.map +1 -1
- package/dist/components/fast-mint/success-view.js +2 -2
- package/dist/components/fast-mint/success-view.js.map +1 -1
- package/dist/components/ip-type-page.cjs +3 -2
- package/dist/components/ip-type-page.cjs.map +1 -1
- package/dist/components/ip-type-page.js +3 -2
- package/dist/components/ip-type-page.js.map +1 -1
- package/dist/components/launchpad/coin-create.cjs +9 -7
- package/dist/components/launchpad/coin-create.cjs.map +1 -1
- package/dist/components/launchpad/coin-create.js +9 -7
- package/dist/components/launchpad/coin-create.js.map +1 -1
- package/dist/components/launchpad/collection-create-form.cjs +11 -14
- package/dist/components/launchpad/collection-create-form.cjs.map +1 -1
- package/dist/components/launchpad/collection-create-form.js +12 -15
- package/dist/components/launchpad/collection-create-form.js.map +1 -1
- package/dist/components/launchpad/collection-create-presets.cjs +8 -8
- package/dist/components/launchpad/collection-create-presets.cjs.map +1 -1
- package/dist/components/launchpad/collection-create-presets.d.cts +2 -1
- package/dist/components/launchpad/collection-create-presets.d.ts +2 -1
- package/dist/components/launchpad/collection-create-presets.js +8 -8
- package/dist/components/launchpad/collection-create-presets.js.map +1 -1
- package/dist/components/launchpad/edition-mint.cjs +9 -7
- package/dist/components/launchpad/edition-mint.cjs.map +1 -1
- package/dist/components/launchpad/edition-mint.js +9 -7
- package/dist/components/launchpad/edition-mint.js.map +1 -1
- package/dist/components/launchpad/pop-create.cjs +5 -6
- package/dist/components/launchpad/pop-create.cjs.map +1 -1
- package/dist/components/launchpad/pop-create.js +5 -6
- package/dist/components/launchpad/pop-create.js.map +1 -1
- package/dist/components/launchpad/remix-mint.cjs +9 -7
- package/dist/components/launchpad/remix-mint.cjs.map +1 -1
- package/dist/components/launchpad/remix-mint.js +9 -7
- package/dist/components/launchpad/remix-mint.js.map +1 -1
- package/dist/components/launchpad/single-edition-mint.cjs +9 -7
- package/dist/components/launchpad/single-edition-mint.cjs.map +1 -1
- package/dist/components/launchpad/single-edition-mint.js +9 -7
- package/dist/components/launchpad/single-edition-mint.js.map +1 -1
- package/dist/components/launchpad/sponsorship-create.cjs +5 -6
- package/dist/components/launchpad/sponsorship-create.cjs.map +1 -1
- package/dist/components/launchpad/sponsorship-create.js +5 -6
- package/dist/components/launchpad/sponsorship-create.js.map +1 -1
- package/dist/components/launchpad/tier-mint-form.cjs +5 -6
- package/dist/components/launchpad/tier-mint-form.cjs.map +1 -1
- package/dist/components/launchpad/tier-mint-form.js +5 -6
- package/dist/components/launchpad/tier-mint-form.js.map +1 -1
- package/dist/components/launchpad/tier-mint-presets.cjs +2 -2
- package/dist/components/launchpad/tier-mint-presets.cjs.map +1 -1
- package/dist/components/launchpad/tier-mint-presets.d.cts +2 -1
- package/dist/components/launchpad/tier-mint-presets.d.ts +2 -1
- package/dist/components/launchpad/tier-mint-presets.js +2 -2
- package/dist/components/launchpad/tier-mint-presets.js.map +1 -1
- package/dist/components/marketplace-dialog-primitives.cjs +1 -31
- package/dist/components/marketplace-dialog-primitives.cjs.map +1 -1
- package/dist/components/marketplace-dialog-primitives.d.cts +1 -12
- package/dist/components/marketplace-dialog-primitives.d.ts +1 -12
- package/dist/components/marketplace-dialog-primitives.js +2 -31
- package/dist/components/marketplace-dialog-primitives.js.map +1 -1
- package/dist/components/media-wallet/media-wallet-activity.cjs +5 -1
- package/dist/components/media-wallet/media-wallet-activity.cjs.map +1 -1
- package/dist/components/media-wallet/media-wallet-activity.js +5 -1
- package/dist/components/media-wallet/media-wallet-activity.js.map +1 -1
- package/dist/components/media-wallet/media-wallet-home.cjs +3 -2
- package/dist/components/media-wallet/media-wallet-home.cjs.map +1 -1
- package/dist/components/media-wallet/media-wallet-home.js +3 -2
- package/dist/components/media-wallet/media-wallet-home.js.map +1 -1
- package/dist/components/media-wallet/media-wallet-send.cjs +5 -2
- package/dist/components/media-wallet/media-wallet-send.cjs.map +1 -1
- package/dist/components/media-wallet/media-wallet-send.js +5 -2
- package/dist/components/media-wallet/media-wallet-send.js.map +1 -1
- package/dist/components/media-wallet/success-dialog.cjs +5 -11
- package/dist/components/media-wallet/success-dialog.cjs.map +1 -1
- package/dist/components/media-wallet/success-dialog.js +5 -11
- package/dist/components/media-wallet/success-dialog.js.map +1 -1
- package/dist/components/pop-claim-button.cjs +7 -6
- package/dist/components/pop-claim-button.cjs.map +1 -1
- package/dist/components/pop-claim-button.js +7 -6
- package/dist/components/pop-claim-button.js.map +1 -1
- package/dist/components/pop-manage-page.cjs +5 -4
- package/dist/components/pop-manage-page.cjs.map +1 -1
- package/dist/components/pop-manage-page.js +5 -4
- package/dist/components/pop-manage-page.js.map +1 -1
- package/dist/components/portfolio-sponsorships.cjs +15 -8
- package/dist/components/portfolio-sponsorships.cjs.map +1 -1
- package/dist/components/portfolio-sponsorships.js +15 -8
- package/dist/components/portfolio-sponsorships.js.map +1 -1
- package/dist/components/service-collections-page.cjs +2 -2
- package/dist/components/service-collections-page.cjs.map +1 -1
- package/dist/components/service-collections-page.d.cts +2 -2
- package/dist/components/service-collections-page.d.ts +2 -2
- package/dist/components/service-collections-page.js +2 -2
- package/dist/components/service-collections-page.js.map +1 -1
- package/dist/components/sheet.d.cts +1 -1
- package/dist/components/sheet.d.ts +1 -1
- package/dist/components/sponsorship-offer-page.cjs +9 -8
- package/dist/components/sponsorship-offer-page.cjs.map +1 -1
- package/dist/components/sponsorship-offer-page.js +9 -8
- package/dist/components/sponsorship-offer-page.js.map +1 -1
- package/dist/components/transaction-success.cjs +60 -0
- package/dist/components/transaction-success.cjs.map +1 -0
- package/dist/components/transaction-success.d.cts +20 -0
- package/dist/components/transaction-success.d.ts +20 -0
- package/dist/components/transaction-success.js +26 -0
- package/dist/components/transaction-success.js.map +1 -0
- package/dist/components/transfer-collection-ownership.cjs +6 -8
- package/dist/components/transfer-collection-ownership.cjs.map +1 -1
- package/dist/components/transfer-collection-ownership.js +6 -8
- package/dist/components/transfer-collection-ownership.js.map +1 -1
- package/dist/index.cjs +9 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -3
- package/dist/index.d.ts +4 -3
- package/dist/index.js +6 -6
- package/dist/index.js.map +1 -1
- package/dist/utils/empty-messages.cjs +62 -0
- package/dist/utils/empty-messages.cjs.map +1 -0
- package/dist/utils/empty-messages.d.cts +40 -0
- package/dist/utils/empty-messages.d.ts +40 -0
- package/dist/utils/empty-messages.js +38 -0
- package/dist/utils/empty-messages.js.map +1 -0
- package/dist/utils/success-messages.cjs +106 -0
- package/dist/utils/success-messages.cjs.map +1 -0
- package/dist/utils/success-messages.d.cts +58 -0
- package/dist/utils/success-messages.d.ts +58 -0
- package/dist/utils/success-messages.js +82 -0
- package/dist/utils/success-messages.js.map +1 -0
- package/package.json +3 -3
- package/dist/components/creation-success.cjs +0 -64
- package/dist/components/creation-success.cjs.map +0 -1
- package/dist/components/creation-success.d.cts +0 -20
- package/dist/components/creation-success.d.ts +0 -20
- package/dist/components/creation-success.js +0 -30
- package/dist/components/creation-success.js.map +0 -1
- package/dist/components/transaction-done.cjs +0 -46
- package/dist/components/transaction-done.cjs.map +0 -1
- package/dist/components/transaction-done.d.cts +0 -18
- package/dist/components/transaction-done.d.ts +0 -18
- package/dist/components/transaction-done.js +0 -22
- package/dist/components/transaction-done.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/portfolio-sponsorships.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState } from \"react\";\nimport { CheckCircle2, Handshake, Loader2, X } from \"lucide-react\";\nimport { assetHref, type ApiSponsorshipOffer } from \"@medialane/sdk\";\nimport { AddressDisplay } from \"./address-display.js\";\nimport { Button } from \"./button.js\";\nimport Link from \"./link.js\";\nimport { useMedialaneApp } from \"./medialane-app.js\";\nimport { Skeleton } from \"./skeleton.js\";\nimport { TransactionDialog } from \"./transaction-dialog.js\";\nimport { TransactionDone } from \"./transaction-done.js\";\nimport { runIntentCalls } from \"../utils/run-intent-calls.js\";\nimport { useSponsorshipBids, useSponsorshipLicenses, useSponsorshipOffers, useSponsorshipProposals } from \"../utils/use-sponsorship.js\";\nimport { useTransaction } from \"../utils/use-transaction.js\";\n\ntype Api = ReturnType<ReturnType<typeof useMedialaneApp>[\"getClient\"]>[\"api\"];\n\nfunction useRowAction(copy: { title: string; working: string; done: string; description: string }) {\n const app = useMedialaneApp();\n const tx = useTransaction();\n const [activeId, setActiveId] = useState<string | null>(null);\n const busy = tx.phase === \"preparing\" || tx.phase === \"submitting\" || tx.phase === \"confirming\";\n\n const run = (id: string, create: (api: Api) => ReturnType<Parameters<typeof runIntentCalls>[1]>, then: () => Promise<unknown>) => {\n setActiveId(id);\n void tx\n .run(async (signer) => {\n await runIntentCalls(signer, () => create(app.getClient().api));\n })\n .then((ok) => (ok ? then() : undefined))\n .finally(() => setActiveId(null));\n };\n\n const dialog = (\n <TransactionDialog tx={tx} title={copy.title} workingLabel={copy.working} firstStepLabel=\"Prepare\">\n <TransactionDone tx={tx} name={copy.title} title={copy.done} description={copy.description} />\n </TransactionDialog>\n );\n\n return { run, dialog, busy, activeId };\n}\n\nfunction Spinner({ active, idle, className }: { active: boolean; idle: React.ReactNode; className?: string }) {\n return active ? <Loader2 className={`h-3 w-3 animate-spin ${className ?? \"\"}`} /> : <>{idle}</>;\n}\n\nfunction OfferBidsRow({ offer }: { offer: ApiSponsorshipOffer }) {\n const { walletAddress } = useMedialaneApp();\n const { bids, isLoading, mutate } = useSponsorshipBids(offer.offerId);\n const action = useRowAction({ title: \"Accept bid\", working: \"Accepting the bid…\", done: \"Bid accepted!\", description: \"The license is minted to the sponsor.\" });\n\n if (isLoading || bids.length === 0) return null;\n\n return (\n <div className=\"space-y-1.5 rounded-lg bg-muted/30 p-3\">\n {action.dialog}\n <p className=\"text-xs font-semibold text-muted-foreground\">\n Bids on <Link href={assetHref(\"STARKNET\", offer.nftContract, offer.tokenId)} className=\"underline underline-offset-2\">View asset</Link>\n </p>\n {bids.map((bid) => (\n <div key={bid.id} className=\"flex items-center justify-between gap-2 text-xs\">\n <AddressDisplay address={bid.sponsor} chars={4} showCopy={false} className=\"text-muted-foreground\" />\n <Button\n size=\"sm\"\n className=\"bg-brand-rose hover:brightness-110 text-white h-7 px-2.5\"\n aria-label=\"Accept bid\"\n disabled={action.busy || !walletAddress}\n onClick={() =>\n action.run(\n bid.id,\n (api) => api.intents.create(\"sponsorship-bid-accept\", { author: walletAddress!, offerId: offer.offerId, sponsor: bid.sponsor }),\n () => mutate(),\n )\n }\n >\n <Spinner active={action.busy && action.activeId === bid.id} idle={<CheckCircle2 className=\"h-3 w-3\" />} />\n </Button>\n </div>\n ))}\n </div>\n );\n}\n\nfunction ReceivedProposals({ walletAddress }: { walletAddress: string }) {\n const { proposals, isLoading, mutate } = useSponsorshipProposals({ owner: walletAddress, open: true });\n const action = useRowAction({ title: \"Respond to proposal\", working: \"Sending your response…\", done: \"Response sent!\", description: \"Your response is now on-chain.\" });\n\n if (isLoading) return <Skeleton className=\"h-20 w-full rounded-xl\" />;\n if (proposals.length === 0) return <p className=\"text-sm text-muted-foreground\">No proposals awaiting your decision.</p>;\n\n const respond = (proposalId: string, decision: \"accept\" | \"reject\") =>\n action.run(\n proposalId,\n (api) =>\n decision === \"accept\"\n ? api.intents.create(\"sponsorship-proposal-accept\", { owner: walletAddress, proposalId })\n : api.intents.create(\"sponsorship-proposal-reject\", { owner: walletAddress, proposalId }),\n () => mutate(),\n );\n\n return (\n <div className=\"space-y-2\">\n {action.dialog}\n {proposals.map((p) => (\n <div key={p.id} className=\"bento-cell p-4 flex items-center justify-between gap-3\">\n <div className=\"min-w-0\">\n <p className=\"text-sm font-semibold\">\n <Link href={assetHref(\"STARKNET\", p.nftContract, p.tokenId)} className=\"hover:underline\">View asset</Link>\n </p>\n <p className=\"text-xs text-muted-foreground\">\n <AddressDisplay address={p.proposer} chars={4} showCopy={false} /> proposed {p.amount}\n </p>\n </div>\n <div className=\"flex gap-1.5 shrink-0\">\n <Button size=\"sm\" variant=\"outline\" aria-label=\"Decline proposal\" disabled={action.busy} onClick={() => respond(p.proposalId, \"reject\")}>\n <Spinner active={action.busy && action.activeId === p.proposalId} idle={<X className=\"h-3 w-3\" />} />\n </Button>\n <Button size=\"sm\" className=\"bg-brand-rose hover:brightness-110 text-white\" aria-label=\"Accept proposal\" disabled={action.busy} onClick={() => respond(p.proposalId, \"accept\")}>\n <Spinner active={action.busy && action.activeId === p.proposalId} idle={<CheckCircle2 className=\"h-3 w-3\" />} />\n </Button>\n </div>\n </div>\n ))}\n </div>\n );\n}\n\nfunction SentProposals({ walletAddress }: { walletAddress: string }) {\n const { proposals, isLoading, mutate } = useSponsorshipProposals({ proposer: walletAddress, open: true });\n const action = useRowAction({ title: \"Withdraw proposal\", working: \"Withdrawing your proposal…\", done: \"Proposal withdrawn!\", description: \"Your proposal is no longer open.\" });\n\n if (isLoading) return <Skeleton className=\"h-20 w-full rounded-xl\" />;\n if (proposals.length === 0) return <p className=\"text-sm text-muted-foreground\">No pending proposals sent.</p>;\n\n return (\n <div className=\"space-y-2\">\n {action.dialog}\n {proposals.map((p) => (\n <div key={p.id} className=\"bento-cell p-4 flex items-center justify-between gap-3\">\n <div className=\"min-w-0\">\n <p className=\"text-sm font-semibold\">\n <Link href={assetHref(\"STARKNET\", p.nftContract, p.tokenId)} className=\"hover:underline\">View asset</Link>\n </p>\n <p className=\"text-xs text-muted-foreground\">You proposed {p.amount}</p>\n </div>\n <Button\n size=\"sm\"\n variant=\"outline\"\n disabled={action.busy}\n onClick={() =>\n action.run(p.proposalId, (api) => api.intents.create(\"sponsorship-proposal-withdraw\", { proposer: walletAddress, proposalId: p.proposalId }), () => mutate())\n }\n >\n <Spinner active={action.busy && action.activeId === p.proposalId} idle={null} className=\"mr-1.5\" />\n Withdraw\n </Button>\n </div>\n ))}\n </div>\n );\n}\n\nfunction LicenseList({ loading, empty, children }: { loading: boolean; empty: string; children: React.ReactNode[] }) {\n if (loading) return <Skeleton className=\"h-16 w-full rounded-xl\" />;\n if (children.length === 0) return <p className=\"text-sm text-muted-foreground\">{empty}</p>;\n return <div className=\"space-y-2\">{children}</div>;\n}\n\nexport function PortfolioSponsorships() {\n const { walletAddress } = useMedialaneApp();\n const { offers } = useSponsorshipOffers(walletAddress ? { author: walletAddress, open: true } : undefined);\n const { licenses: held, isLoading: heldLoading } = useSponsorshipLicenses(walletAddress ? { holder: walletAddress } : undefined);\n const { licenses: issued, isLoading: issuedLoading } = useSponsorshipLicenses(walletAddress ? { author: walletAddress } : undefined);\n\n if (!walletAddress) return null;\n\n return (\n <div className=\"space-y-8\">\n <section className=\"space-y-3\">\n <h2 className=\"text-sm font-bold flex items-center gap-2\"><Handshake className=\"h-4 w-4 text-brand-rose\" />Proposals awaiting your decision</h2>\n <ReceivedProposals walletAddress={walletAddress} />\n </section>\n\n {offers.length > 0 && (\n <section className=\"space-y-3\">\n <h2 className=\"text-sm font-bold\">Bids on your offers</h2>\n <div className=\"space-y-2\">\n {offers.map((o) => <OfferBidsRow key={o.id} offer={o} />)}\n </div>\n </section>\n )}\n\n <section className=\"space-y-3\">\n <h2 className=\"text-sm font-bold\">Proposals you've sent</h2>\n <SentProposals walletAddress={walletAddress} />\n </section>\n\n <section className=\"space-y-3\">\n <h2 className=\"text-sm font-bold\">Licenses you hold</h2>\n <LicenseList loading={heldLoading} empty=\"No sponsorship licenses yet.\">\n {held.map((l) => (\n <div key={l.id} className=\"bento-cell p-4\">\n <p className=\"text-sm font-semibold\">\n <Link href={assetHref(\"STARKNET\", l.assetContract, l.assetTokenId)} className=\"hover:underline\">License on this asset</Link>\n </p>\n <p className=\"text-xs text-muted-foreground\">from <AddressDisplay address={l.author} chars={4} showCopy={false} /></p>\n </div>\n ))}\n </LicenseList>\n </section>\n\n <section className=\"space-y-3\">\n <h2 className=\"text-sm font-bold\">Licenses issued on your work</h2>\n <LicenseList loading={issuedLoading} empty=\"No licenses issued yet.\">\n {issued.map((l) => (\n <div key={l.id} className=\"bento-cell p-4\">\n <p className=\"text-sm font-semibold\">\n <Link href={assetHref(\"STARKNET\", l.assetContract, l.assetTokenId)} className=\"hover:underline\">License on this asset</Link>\n </p>\n <p className=\"text-xs text-muted-foreground\">held by <AddressDisplay address={l.currentHolder ?? l.recipient} chars={4} showCopy={false} /></p>\n </div>\n ))}\n </LicenseList>\n </section>\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAoCM;AAlCN,mBAAyB;AACzB,0BAAoD;AACpD,iBAAoD;AACpD,6BAA+B;AAC/B,oBAAuB;AACvB,kBAAiB;AACjB,2BAAgC;AAChC,sBAAyB;AACzB,gCAAkC;AAClC,8BAAgC;AAChC,8BAA+B;AAC/B,6BAA0G;AAC1G,6BAA+B;AAI/B,SAAS,aAAa,MAA6E;AACjG,QAAM,UAAM,sCAAgB;AAC5B,QAAM,SAAK,uCAAe;AAC1B,QAAM,CAAC,UAAU,WAAW,QAAI,uBAAwB,IAAI;AAC5D,QAAM,OAAO,GAAG,UAAU,eAAe,GAAG,UAAU,gBAAgB,GAAG,UAAU;AAEnF,QAAM,MAAM,CAAC,IAAY,QAAwE,SAAiC;AAChI,gBAAY,EAAE;AACd,SAAK,GACF,IAAI,OAAO,WAAW;AACrB,gBAAM,wCAAe,QAAQ,MAAM,OAAO,IAAI,UAAU,EAAE,GAAG,CAAC;AAAA,IAChE,CAAC,EACA,KAAK,CAAC,OAAQ,KAAK,KAAK,IAAI,MAAU,EACtC,QAAQ,MAAM,YAAY,IAAI,CAAC;AAAA,EACpC;AAEA,QAAM,SACJ,4CAAC,+CAAkB,IAAQ,OAAO,KAAK,OAAO,cAAc,KAAK,SAAS,gBAAe,WACvF,sDAAC,2CAAgB,IAAQ,MAAM,KAAK,OAAO,OAAO,KAAK,MAAM,aAAa,KAAK,aAAa,GAC9F;AAGF,SAAO,EAAE,KAAK,QAAQ,MAAM,SAAS;AACvC;AAEA,SAAS,QAAQ,EAAE,QAAQ,MAAM,UAAU,GAAmE;AAC5G,SAAO,SAAS,4CAAC,+BAAQ,WAAW,wBAAwB,aAAa,EAAE,IAAI,IAAK,2EAAG,gBAAK;AAC9F;AAEA,SAAS,aAAa,EAAE,MAAM,GAAmC;AAC/D,QAAM,EAAE,cAAc,QAAI,sCAAgB;AAC1C,QAAM,EAAE,MAAM,WAAW,OAAO,QAAI,2CAAmB,MAAM,OAAO;AACpE,QAAM,SAAS,aAAa,EAAE,OAAO,cAAc,SAAS,2BAAsB,MAAM,iBAAiB,aAAa,wCAAwC,CAAC;AAE/J,MAAI,aAAa,KAAK,WAAW,EAAG,QAAO;AAE3C,SACE,6CAAC,SAAI,WAAU,0CACZ;AAAA,WAAO;AAAA,IACR,6CAAC,OAAE,WAAU,+CAA8C;AAAA;AAAA,MACjD,4CAAC,YAAAA,SAAA,EAAK,UAAM,sBAAU,YAAY,MAAM,aAAa,MAAM,OAAO,GAAG,WAAU,gCAA+B,wBAAU;AAAA,OAClI;AAAA,IACC,KAAK,IAAI,CAAC,QACT,6CAAC,SAAiB,WAAU,mDAC1B;AAAA,kDAAC,yCAAe,SAAS,IAAI,SAAS,OAAO,GAAG,UAAU,OAAO,WAAU,yBAAwB;AAAA,MACnG;AAAA,QAAC;AAAA;AAAA,UACC,MAAK;AAAA,UACL,WAAU;AAAA,UACV,cAAW;AAAA,UACX,UAAU,OAAO,QAAQ,CAAC;AAAA,UAC1B,SAAS,MACP,OAAO;AAAA,YACL,IAAI;AAAA,YACJ,CAAC,QAAQ,IAAI,QAAQ,OAAO,0BAA0B,EAAE,QAAQ,eAAgB,SAAS,MAAM,SAAS,SAAS,IAAI,QAAQ,CAAC;AAAA,YAC9H,MAAM,OAAO;AAAA,UACf;AAAA,UAGF,sDAAC,WAAQ,QAAQ,OAAO,QAAQ,OAAO,aAAa,IAAI,IAAI,MAAM,4CAAC,oCAAa,WAAU,WAAU,GAAI;AAAA;AAAA,MAC1G;AAAA,SAhBQ,IAAI,EAiBd,CACD;AAAA,KACH;AAEJ;AAEA,SAAS,kBAAkB,EAAE,cAAc,GAA8B;AACvE,QAAM,EAAE,WAAW,WAAW,OAAO,QAAI,gDAAwB,EAAE,OAAO,eAAe,MAAM,KAAK,CAAC;AACrG,QAAM,SAAS,aAAa,EAAE,OAAO,uBAAuB,SAAS,+BAA0B,MAAM,kBAAkB,aAAa,iCAAiC,CAAC;AAEtK,MAAI,UAAW,QAAO,4CAAC,4BAAS,WAAU,0BAAyB;AACnE,MAAI,UAAU,WAAW,EAAG,QAAO,4CAAC,OAAE,WAAU,iCAAgC,kDAAoC;AAEpH,QAAM,UAAU,CAAC,YAAoB,aACnC,OAAO;AAAA,IACL;AAAA,IACA,CAAC,QACC,aAAa,WACT,IAAI,QAAQ,OAAO,+BAA+B,EAAE,OAAO,eAAe,WAAW,CAAC,IACtF,IAAI,QAAQ,OAAO,+BAA+B,EAAE,OAAO,eAAe,WAAW,CAAC;AAAA,IAC5F,MAAM,OAAO;AAAA,EACf;AAEF,SACE,6CAAC,SAAI,WAAU,aACZ;AAAA,WAAO;AAAA,IACP,UAAU,IAAI,CAAC,MACd,6CAAC,SAAe,WAAU,0DACxB;AAAA,mDAAC,SAAI,WAAU,WACb;AAAA,oDAAC,OAAE,WAAU,yBACX,sDAAC,YAAAA,SAAA,EAAK,UAAM,sBAAU,YAAY,EAAE,aAAa,EAAE,OAAO,GAAG,WAAU,mBAAkB,wBAAU,GACrG;AAAA,QACA,6CAAC,OAAE,WAAU,iCACX;AAAA,sDAAC,yCAAe,SAAS,EAAE,UAAU,OAAO,GAAG,UAAU,OAAO;AAAA,UAAE;AAAA,UAAW,EAAE;AAAA,WACjF;AAAA,SACF;AAAA,MACA,6CAAC,SAAI,WAAU,yBACb;AAAA,oDAAC,wBAAO,MAAK,MAAK,SAAQ,WAAU,cAAW,oBAAmB,UAAU,OAAO,MAAM,SAAS,MAAM,QAAQ,EAAE,YAAY,QAAQ,GACpI,sDAAC,WAAQ,QAAQ,OAAO,QAAQ,OAAO,aAAa,EAAE,YAAY,MAAM,4CAAC,yBAAE,WAAU,WAAU,GAAI,GACrG;AAAA,QACA,4CAAC,wBAAO,MAAK,MAAK,WAAU,iDAAgD,cAAW,mBAAkB,UAAU,OAAO,MAAM,SAAS,MAAM,QAAQ,EAAE,YAAY,QAAQ,GAC3K,sDAAC,WAAQ,QAAQ,OAAO,QAAQ,OAAO,aAAa,EAAE,YAAY,MAAM,4CAAC,oCAAa,WAAU,WAAU,GAAI,GAChH;AAAA,SACF;AAAA,SAhBQ,EAAE,EAiBZ,CACD;AAAA,KACH;AAEJ;AAEA,SAAS,cAAc,EAAE,cAAc,GAA8B;AACnE,QAAM,EAAE,WAAW,WAAW,OAAO,QAAI,gDAAwB,EAAE,UAAU,eAAe,MAAM,KAAK,CAAC;AACxG,QAAM,SAAS,aAAa,EAAE,OAAO,qBAAqB,SAAS,mCAA8B,MAAM,uBAAuB,aAAa,mCAAmC,CAAC;AAE/K,MAAI,UAAW,QAAO,4CAAC,4BAAS,WAAU,0BAAyB;AACnE,MAAI,UAAU,WAAW,EAAG,QAAO,4CAAC,OAAE,WAAU,iCAAgC,wCAA0B;AAE1G,SACE,6CAAC,SAAI,WAAU,aACZ;AAAA,WAAO;AAAA,IACP,UAAU,IAAI,CAAC,MACd,6CAAC,SAAe,WAAU,0DACxB;AAAA,mDAAC,SAAI,WAAU,WACb;AAAA,oDAAC,OAAE,WAAU,yBACX,sDAAC,YAAAA,SAAA,EAAK,UAAM,sBAAU,YAAY,EAAE,aAAa,EAAE,OAAO,GAAG,WAAU,mBAAkB,wBAAU,GACrG;AAAA,QACA,6CAAC,OAAE,WAAU,iCAAgC;AAAA;AAAA,UAAc,EAAE;AAAA,WAAO;AAAA,SACtE;AAAA,MACA;AAAA,QAAC;AAAA;AAAA,UACC,MAAK;AAAA,UACL,SAAQ;AAAA,UACR,UAAU,OAAO;AAAA,UACjB,SAAS,MACP,OAAO,IAAI,EAAE,YAAY,CAAC,QAAQ,IAAI,QAAQ,OAAO,iCAAiC,EAAE,UAAU,eAAe,YAAY,EAAE,WAAW,CAAC,GAAG,MAAM,OAAO,CAAC;AAAA,UAG9J;AAAA,wDAAC,WAAQ,QAAQ,OAAO,QAAQ,OAAO,aAAa,EAAE,YAAY,MAAM,MAAM,WAAU,UAAS;AAAA,YAAE;AAAA;AAAA;AAAA,MAErG;AAAA,SAjBQ,EAAE,EAkBZ,CACD;AAAA,KACH;AAEJ;AAEA,SAAS,YAAY,EAAE,SAAS,OAAO,SAAS,GAAqE;AACnH,MAAI,QAAS,QAAO,4CAAC,4BAAS,WAAU,0BAAyB;AACjE,MAAI,SAAS,WAAW,EAAG,QAAO,4CAAC,OAAE,WAAU,iCAAiC,iBAAM;AACtF,SAAO,4CAAC,SAAI,WAAU,aAAa,UAAS;AAC9C;AAEO,SAAS,wBAAwB;AACtC,QAAM,EAAE,cAAc,QAAI,sCAAgB;AAC1C,QAAM,EAAE,OAAO,QAAI,6CAAqB,gBAAgB,EAAE,QAAQ,eAAe,MAAM,KAAK,IAAI,MAAS;AACzG,QAAM,EAAE,UAAU,MAAM,WAAW,YAAY,QAAI,+CAAuB,gBAAgB,EAAE,QAAQ,cAAc,IAAI,MAAS;AAC/H,QAAM,EAAE,UAAU,QAAQ,WAAW,cAAc,QAAI,+CAAuB,gBAAgB,EAAE,QAAQ,cAAc,IAAI,MAAS;AAEnI,MAAI,CAAC,cAAe,QAAO;AAE3B,SACE,6CAAC,SAAI,WAAU,aACb;AAAA,iDAAC,aAAQ,WAAU,aACjB;AAAA,mDAAC,QAAG,WAAU,6CAA4C;AAAA,oDAAC,iCAAU,WAAU,2BAA0B;AAAA,QAAE;AAAA,SAAgC;AAAA,MAC3I,4CAAC,qBAAkB,eAA8B;AAAA,OACnD;AAAA,IAEC,OAAO,SAAS,KACf,6CAAC,aAAQ,WAAU,aACjB;AAAA,kDAAC,QAAG,WAAU,qBAAoB,iCAAmB;AAAA,MACrD,4CAAC,SAAI,WAAU,aACZ,iBAAO,IAAI,CAAC,MAAM,4CAAC,gBAAwB,OAAO,KAAb,EAAE,EAAc,CAAE,GAC1D;AAAA,OACF;AAAA,IAGF,6CAAC,aAAQ,WAAU,aACjB;AAAA,kDAAC,QAAG,WAAU,qBAAoB,mCAA0B;AAAA,MAC5D,4CAAC,iBAAc,eAA8B;AAAA,OAC/C;AAAA,IAEA,6CAAC,aAAQ,WAAU,aACjB;AAAA,kDAAC,QAAG,WAAU,qBAAoB,+BAAiB;AAAA,MACnD,4CAAC,eAAY,SAAS,aAAa,OAAM,gCACtC,eAAK,IAAI,CAAC,MACT,6CAAC,SAAe,WAAU,kBACxB;AAAA,oDAAC,OAAE,WAAU,yBACX,sDAAC,YAAAA,SAAA,EAAK,UAAM,sBAAU,YAAY,EAAE,eAAe,EAAE,YAAY,GAAG,WAAU,mBAAkB,mCAAqB,GACvH;AAAA,QACA,6CAAC,OAAE,WAAU,iCAAgC;AAAA;AAAA,UAAK,4CAAC,yCAAe,SAAS,EAAE,QAAQ,OAAO,GAAG,UAAU,OAAO;AAAA,WAAE;AAAA,WAJ1G,EAAE,EAKZ,CACD,GACH;AAAA,OACF;AAAA,IAEA,6CAAC,aAAQ,WAAU,aACjB;AAAA,kDAAC,QAAG,WAAU,qBAAoB,0CAA4B;AAAA,MAC9D,4CAAC,eAAY,SAAS,eAAe,OAAM,2BACxC,iBAAO,IAAI,CAAC,MACX,6CAAC,SAAe,WAAU,kBACxB;AAAA,oDAAC,OAAE,WAAU,yBACX,sDAAC,YAAAA,SAAA,EAAK,UAAM,sBAAU,YAAY,EAAE,eAAe,EAAE,YAAY,GAAG,WAAU,mBAAkB,mCAAqB,GACvH;AAAA,QACA,6CAAC,OAAE,WAAU,iCAAgC;AAAA;AAAA,UAAQ,4CAAC,yCAAe,SAAS,EAAE,iBAAiB,EAAE,WAAW,OAAO,GAAG,UAAU,OAAO;AAAA,WAAE;AAAA,WAJnI,EAAE,EAKZ,CACD,GACH;AAAA,OACF;AAAA,KACF;AAEJ;","names":["Link"]}
|
|
1
|
+
{"version":3,"sources":["../../src/components/portfolio-sponsorships.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState } from \"react\";\nimport { CheckCircle2, Handshake, Loader2, X } from \"lucide-react\";\nimport { assetHref, type ApiSponsorshipOffer } from \"@medialane/sdk\";\nimport { AddressDisplay } from \"./address-display.js\";\nimport { Button } from \"./button.js\";\nimport Link from \"./link.js\";\nimport { useMedialaneApp } from \"./medialane-app.js\";\nimport { Skeleton } from \"./skeleton.js\";\nimport { TransactionDialog } from \"./transaction-dialog.js\";\nimport { TransactionSuccess } from \"./transaction-success.js\";\nimport { runIntentCalls } from \"../utils/run-intent-calls.js\";\nimport { useSponsorshipBids, useSponsorshipLicenses, useSponsorshipOffers, useSponsorshipProposals } from \"../utils/use-sponsorship.js\";\nimport { emptyMessages, type EmptyMessage } from \"../utils/empty-messages.js\";\nimport { successMessages, type SuccessMessage } from \"../utils/success-messages.js\";\nimport { useTransaction } from \"../utils/use-transaction.js\";\n\ntype Api = ReturnType<ReturnType<typeof useMedialaneApp>[\"getClient\"]>[\"api\"];\n\nfunction useRowAction(copy: { title: string; working: string; message: SuccessMessage }) {\n const app = useMedialaneApp();\n const tx = useTransaction();\n const [activeId, setActiveId] = useState<string | null>(null);\n const busy = tx.phase === \"preparing\" || tx.phase === \"submitting\" || tx.phase === \"confirming\";\n\n const run = (id: string, create: (api: Api) => ReturnType<Parameters<typeof runIntentCalls>[1]>, then: () => Promise<unknown>) => {\n setActiveId(id);\n void tx\n .run(async (signer) => {\n await runIntentCalls(signer, () => create(app.getClient().api));\n })\n .then((ok) => (ok ? then() : undefined))\n .finally(() => setActiveId(null));\n };\n\n const dialog = (\n <TransactionDialog tx={tx} title={copy.title} workingLabel={copy.working} firstStepLabel=\"Prepare\">\n <TransactionSuccess name={copy.title} {...copy.message} txHash={tx.txHash} actions={[{ label: \"Done\", onClick: tx.reset }]} />\n </TransactionDialog>\n );\n\n return { run, dialog, busy, activeId };\n}\n\nfunction Spinner({ active, idle, className }: { active: boolean; idle: React.ReactNode; className?: string }) {\n return active ? <Loader2 className={`h-3 w-3 animate-spin ${className ?? \"\"}`} /> : <>{idle}</>;\n}\n\nfunction OfferBidsRow({ offer }: { offer: ApiSponsorshipOffer }) {\n const { walletAddress } = useMedialaneApp();\n const { bids, isLoading, mutate } = useSponsorshipBids(offer.offerId);\n const action = useRowAction({ title: \"Accept bid\", working: \"Accepting the bid…\", message: successMessages.bidAccepted() });\n\n if (isLoading || bids.length === 0) return null;\n\n return (\n <div className=\"space-y-1.5 rounded-lg bg-muted/30 p-3\">\n {action.dialog}\n <p className=\"text-xs font-semibold text-muted-foreground\">\n Bids on <Link href={assetHref(\"STARKNET\", offer.nftContract, offer.tokenId)} className=\"underline underline-offset-2\">View asset</Link>\n </p>\n {bids.map((bid) => (\n <div key={bid.id} className=\"flex items-center justify-between gap-2 text-xs\">\n <AddressDisplay address={bid.sponsor} chars={4} showCopy={false} className=\"text-muted-foreground\" />\n <Button\n size=\"sm\"\n className=\"bg-brand-rose hover:brightness-110 text-white h-7 px-2.5\"\n aria-label=\"Accept bid\"\n disabled={action.busy || !walletAddress}\n onClick={() =>\n action.run(\n bid.id,\n (api) => api.intents.create(\"sponsorship-bid-accept\", { author: walletAddress!, offerId: offer.offerId, sponsor: bid.sponsor }),\n () => mutate(),\n )\n }\n >\n <Spinner active={action.busy && action.activeId === bid.id} idle={<CheckCircle2 className=\"h-3 w-3\" />} />\n </Button>\n </div>\n ))}\n </div>\n );\n}\n\nfunction ReceivedProposals({ walletAddress }: { walletAddress: string }) {\n const { proposals, isLoading, mutate } = useSponsorshipProposals({ owner: walletAddress, open: true });\n const action = useRowAction({ title: \"Respond to proposal\", working: \"Sending your response…\", message: successMessages.responseSent() });\n\n if (isLoading) return <Skeleton className=\"h-20 w-full rounded-xl\" />;\n if (proposals.length === 0) return <p className=\"text-sm text-muted-foreground\">No proposals awaiting your decision.</p>;\n\n const respond = (proposalId: string, decision: \"accept\" | \"reject\") =>\n action.run(\n proposalId,\n (api) =>\n decision === \"accept\"\n ? api.intents.create(\"sponsorship-proposal-accept\", { owner: walletAddress, proposalId })\n : api.intents.create(\"sponsorship-proposal-reject\", { owner: walletAddress, proposalId }),\n () => mutate(),\n );\n\n return (\n <div className=\"space-y-2\">\n {action.dialog}\n {proposals.map((p) => (\n <div key={p.id} className=\"bento-cell p-4 flex items-center justify-between gap-3\">\n <div className=\"min-w-0\">\n <p className=\"text-sm font-semibold\">\n <Link href={assetHref(\"STARKNET\", p.nftContract, p.tokenId)} className=\"hover:underline\">View asset</Link>\n </p>\n <p className=\"text-xs text-muted-foreground\">\n <AddressDisplay address={p.proposer} chars={4} showCopy={false} /> proposed {p.amount}\n </p>\n </div>\n <div className=\"flex gap-1.5 shrink-0\">\n <Button size=\"sm\" variant=\"outline\" aria-label=\"Decline proposal\" disabled={action.busy} onClick={() => respond(p.proposalId, \"reject\")}>\n <Spinner active={action.busy && action.activeId === p.proposalId} idle={<X className=\"h-3 w-3\" />} />\n </Button>\n <Button size=\"sm\" className=\"bg-brand-rose hover:brightness-110 text-white\" aria-label=\"Accept proposal\" disabled={action.busy} onClick={() => respond(p.proposalId, \"accept\")}>\n <Spinner active={action.busy && action.activeId === p.proposalId} idle={<CheckCircle2 className=\"h-3 w-3\" />} />\n </Button>\n </div>\n </div>\n ))}\n </div>\n );\n}\n\nfunction SentProposals({ walletAddress }: { walletAddress: string }) {\n const { proposals, isLoading, mutate } = useSponsorshipProposals({ proposer: walletAddress, open: true });\n const action = useRowAction({ title: \"Withdraw proposal\", working: \"Withdrawing your proposal…\", message: successMessages.proposalWithdrawn() });\n\n if (isLoading) return <Skeleton className=\"h-20 w-full rounded-xl\" />;\n if (proposals.length === 0) return <p className=\"text-sm text-muted-foreground\">No pending proposals sent.</p>;\n\n return (\n <div className=\"space-y-2\">\n {action.dialog}\n {proposals.map((p) => (\n <div key={p.id} className=\"bento-cell p-4 flex items-center justify-between gap-3\">\n <div className=\"min-w-0\">\n <p className=\"text-sm font-semibold\">\n <Link href={assetHref(\"STARKNET\", p.nftContract, p.tokenId)} className=\"hover:underline\">View asset</Link>\n </p>\n <p className=\"text-xs text-muted-foreground\">You proposed {p.amount}</p>\n </div>\n <Button\n size=\"sm\"\n variant=\"outline\"\n disabled={action.busy}\n onClick={() =>\n action.run(p.proposalId, (api) => api.intents.create(\"sponsorship-proposal-withdraw\", { proposer: walletAddress, proposalId: p.proposalId }), () => mutate())\n }\n >\n <Spinner active={action.busy && action.activeId === p.proposalId} idle={null} className=\"mr-1.5\" />\n Withdraw\n </Button>\n </div>\n ))}\n </div>\n );\n}\n\nfunction LicenseList({ loading, empty, children }: { loading: boolean; empty: EmptyMessage; children: React.ReactNode[] }) {\n if (loading) return <Skeleton className=\"h-16 w-full rounded-xl\" />;\n if (children.length === 0) {\n return (\n <div>\n <p className=\"text-sm font-medium\">{empty.title}</p>\n <p className=\"text-sm text-muted-foreground\">{empty.description}</p>\n </div>\n );\n }\n return <div className=\"space-y-2\">{children}</div>;\n}\n\nexport function PortfolioSponsorships() {\n const { walletAddress } = useMedialaneApp();\n const { offers } = useSponsorshipOffers(walletAddress ? { author: walletAddress, open: true } : undefined);\n const { licenses: held, isLoading: heldLoading } = useSponsorshipLicenses(walletAddress ? { holder: walletAddress } : undefined);\n const { licenses: issued, isLoading: issuedLoading } = useSponsorshipLicenses(walletAddress ? { author: walletAddress } : undefined);\n\n if (!walletAddress) return null;\n\n return (\n <div className=\"space-y-8\">\n <section className=\"space-y-3\">\n <h2 className=\"text-sm font-bold flex items-center gap-2\"><Handshake className=\"h-4 w-4 text-brand-rose\" />Proposals awaiting your decision</h2>\n <ReceivedProposals walletAddress={walletAddress} />\n </section>\n\n {offers.length > 0 && (\n <section className=\"space-y-3\">\n <h2 className=\"text-sm font-bold\">Bids on your offers</h2>\n <div className=\"space-y-2\">\n {offers.map((o) => <OfferBidsRow key={o.id} offer={o} />)}\n </div>\n </section>\n )}\n\n <section className=\"space-y-3\">\n <h2 className=\"text-sm font-bold\">Proposals you've sent</h2>\n <SentProposals walletAddress={walletAddress} />\n </section>\n\n <section className=\"space-y-3\">\n <h2 className=\"text-sm font-bold\">Licenses you hold</h2>\n <LicenseList loading={heldLoading} empty={emptyMessages.heldLicenses}>\n {held.map((l) => (\n <div key={l.id} className=\"bento-cell p-4\">\n <p className=\"text-sm font-semibold\">\n <Link href={assetHref(\"STARKNET\", l.assetContract, l.assetTokenId)} className=\"hover:underline\">License on this asset</Link>\n </p>\n <p className=\"text-xs text-muted-foreground\">from <AddressDisplay address={l.author} chars={4} showCopy={false} /></p>\n </div>\n ))}\n </LicenseList>\n </section>\n\n <section className=\"space-y-3\">\n <h2 className=\"text-sm font-bold\">Licenses issued on your work</h2>\n <LicenseList loading={issuedLoading} empty={emptyMessages.issuedLicenses}>\n {issued.map((l) => (\n <div key={l.id} className=\"bento-cell p-4\">\n <p className=\"text-sm font-semibold\">\n <Link href={assetHref(\"STARKNET\", l.assetContract, l.assetTokenId)} className=\"hover:underline\">License on this asset</Link>\n </p>\n <p className=\"text-xs text-muted-foreground\">held by <AddressDisplay address={l.currentHolder ?? l.recipient} chars={4} showCopy={false} /></p>\n </div>\n ))}\n </LicenseList>\n </section>\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAsCM;AApCN,mBAAyB;AACzB,0BAAoD;AACpD,iBAAoD;AACpD,6BAA+B;AAC/B,oBAAuB;AACvB,kBAAiB;AACjB,2BAAgC;AAChC,sBAAyB;AACzB,gCAAkC;AAClC,iCAAmC;AACnC,8BAA+B;AAC/B,6BAA0G;AAC1G,4BAAiD;AACjD,8BAAqD;AACrD,6BAA+B;AAI/B,SAAS,aAAa,MAAmE;AACvF,QAAM,UAAM,sCAAgB;AAC5B,QAAM,SAAK,uCAAe;AAC1B,QAAM,CAAC,UAAU,WAAW,QAAI,uBAAwB,IAAI;AAC5D,QAAM,OAAO,GAAG,UAAU,eAAe,GAAG,UAAU,gBAAgB,GAAG,UAAU;AAEnF,QAAM,MAAM,CAAC,IAAY,QAAwE,SAAiC;AAChI,gBAAY,EAAE;AACd,SAAK,GACF,IAAI,OAAO,WAAW;AACrB,gBAAM,wCAAe,QAAQ,MAAM,OAAO,IAAI,UAAU,EAAE,GAAG,CAAC;AAAA,IAChE,CAAC,EACA,KAAK,CAAC,OAAQ,KAAK,KAAK,IAAI,MAAU,EACtC,QAAQ,MAAM,YAAY,IAAI,CAAC;AAAA,EACpC;AAEA,QAAM,SACJ,4CAAC,+CAAkB,IAAQ,OAAO,KAAK,OAAO,cAAc,KAAK,SAAS,gBAAe,WACvF,sDAAC,iDAAmB,MAAM,KAAK,OAAQ,GAAG,KAAK,SAAS,QAAQ,GAAG,QAAQ,SAAS,CAAC,EAAE,OAAO,QAAQ,SAAS,GAAG,MAAM,CAAC,GAAG,GAC9H;AAGF,SAAO,EAAE,KAAK,QAAQ,MAAM,SAAS;AACvC;AAEA,SAAS,QAAQ,EAAE,QAAQ,MAAM,UAAU,GAAmE;AAC5G,SAAO,SAAS,4CAAC,+BAAQ,WAAW,wBAAwB,aAAa,EAAE,IAAI,IAAK,2EAAG,gBAAK;AAC9F;AAEA,SAAS,aAAa,EAAE,MAAM,GAAmC;AAC/D,QAAM,EAAE,cAAc,QAAI,sCAAgB;AAC1C,QAAM,EAAE,MAAM,WAAW,OAAO,QAAI,2CAAmB,MAAM,OAAO;AACpE,QAAM,SAAS,aAAa,EAAE,OAAO,cAAc,SAAS,2BAAsB,SAAS,wCAAgB,YAAY,EAAE,CAAC;AAE1H,MAAI,aAAa,KAAK,WAAW,EAAG,QAAO;AAE3C,SACE,6CAAC,SAAI,WAAU,0CACZ;AAAA,WAAO;AAAA,IACR,6CAAC,OAAE,WAAU,+CAA8C;AAAA;AAAA,MACjD,4CAAC,YAAAA,SAAA,EAAK,UAAM,sBAAU,YAAY,MAAM,aAAa,MAAM,OAAO,GAAG,WAAU,gCAA+B,wBAAU;AAAA,OAClI;AAAA,IACC,KAAK,IAAI,CAAC,QACT,6CAAC,SAAiB,WAAU,mDAC1B;AAAA,kDAAC,yCAAe,SAAS,IAAI,SAAS,OAAO,GAAG,UAAU,OAAO,WAAU,yBAAwB;AAAA,MACnG;AAAA,QAAC;AAAA;AAAA,UACC,MAAK;AAAA,UACL,WAAU;AAAA,UACV,cAAW;AAAA,UACX,UAAU,OAAO,QAAQ,CAAC;AAAA,UAC1B,SAAS,MACP,OAAO;AAAA,YACL,IAAI;AAAA,YACJ,CAAC,QAAQ,IAAI,QAAQ,OAAO,0BAA0B,EAAE,QAAQ,eAAgB,SAAS,MAAM,SAAS,SAAS,IAAI,QAAQ,CAAC;AAAA,YAC9H,MAAM,OAAO;AAAA,UACf;AAAA,UAGF,sDAAC,WAAQ,QAAQ,OAAO,QAAQ,OAAO,aAAa,IAAI,IAAI,MAAM,4CAAC,oCAAa,WAAU,WAAU,GAAI;AAAA;AAAA,MAC1G;AAAA,SAhBQ,IAAI,EAiBd,CACD;AAAA,KACH;AAEJ;AAEA,SAAS,kBAAkB,EAAE,cAAc,GAA8B;AACvE,QAAM,EAAE,WAAW,WAAW,OAAO,QAAI,gDAAwB,EAAE,OAAO,eAAe,MAAM,KAAK,CAAC;AACrG,QAAM,SAAS,aAAa,EAAE,OAAO,uBAAuB,SAAS,+BAA0B,SAAS,wCAAgB,aAAa,EAAE,CAAC;AAExI,MAAI,UAAW,QAAO,4CAAC,4BAAS,WAAU,0BAAyB;AACnE,MAAI,UAAU,WAAW,EAAG,QAAO,4CAAC,OAAE,WAAU,iCAAgC,kDAAoC;AAEpH,QAAM,UAAU,CAAC,YAAoB,aACnC,OAAO;AAAA,IACL;AAAA,IACA,CAAC,QACC,aAAa,WACT,IAAI,QAAQ,OAAO,+BAA+B,EAAE,OAAO,eAAe,WAAW,CAAC,IACtF,IAAI,QAAQ,OAAO,+BAA+B,EAAE,OAAO,eAAe,WAAW,CAAC;AAAA,IAC5F,MAAM,OAAO;AAAA,EACf;AAEF,SACE,6CAAC,SAAI,WAAU,aACZ;AAAA,WAAO;AAAA,IACP,UAAU,IAAI,CAAC,MACd,6CAAC,SAAe,WAAU,0DACxB;AAAA,mDAAC,SAAI,WAAU,WACb;AAAA,oDAAC,OAAE,WAAU,yBACX,sDAAC,YAAAA,SAAA,EAAK,UAAM,sBAAU,YAAY,EAAE,aAAa,EAAE,OAAO,GAAG,WAAU,mBAAkB,wBAAU,GACrG;AAAA,QACA,6CAAC,OAAE,WAAU,iCACX;AAAA,sDAAC,yCAAe,SAAS,EAAE,UAAU,OAAO,GAAG,UAAU,OAAO;AAAA,UAAE;AAAA,UAAW,EAAE;AAAA,WACjF;AAAA,SACF;AAAA,MACA,6CAAC,SAAI,WAAU,yBACb;AAAA,oDAAC,wBAAO,MAAK,MAAK,SAAQ,WAAU,cAAW,oBAAmB,UAAU,OAAO,MAAM,SAAS,MAAM,QAAQ,EAAE,YAAY,QAAQ,GACpI,sDAAC,WAAQ,QAAQ,OAAO,QAAQ,OAAO,aAAa,EAAE,YAAY,MAAM,4CAAC,yBAAE,WAAU,WAAU,GAAI,GACrG;AAAA,QACA,4CAAC,wBAAO,MAAK,MAAK,WAAU,iDAAgD,cAAW,mBAAkB,UAAU,OAAO,MAAM,SAAS,MAAM,QAAQ,EAAE,YAAY,QAAQ,GAC3K,sDAAC,WAAQ,QAAQ,OAAO,QAAQ,OAAO,aAAa,EAAE,YAAY,MAAM,4CAAC,oCAAa,WAAU,WAAU,GAAI,GAChH;AAAA,SACF;AAAA,SAhBQ,EAAE,EAiBZ,CACD;AAAA,KACH;AAEJ;AAEA,SAAS,cAAc,EAAE,cAAc,GAA8B;AACnE,QAAM,EAAE,WAAW,WAAW,OAAO,QAAI,gDAAwB,EAAE,UAAU,eAAe,MAAM,KAAK,CAAC;AACxG,QAAM,SAAS,aAAa,EAAE,OAAO,qBAAqB,SAAS,mCAA8B,SAAS,wCAAgB,kBAAkB,EAAE,CAAC;AAE/I,MAAI,UAAW,QAAO,4CAAC,4BAAS,WAAU,0BAAyB;AACnE,MAAI,UAAU,WAAW,EAAG,QAAO,4CAAC,OAAE,WAAU,iCAAgC,wCAA0B;AAE1G,SACE,6CAAC,SAAI,WAAU,aACZ;AAAA,WAAO;AAAA,IACP,UAAU,IAAI,CAAC,MACd,6CAAC,SAAe,WAAU,0DACxB;AAAA,mDAAC,SAAI,WAAU,WACb;AAAA,oDAAC,OAAE,WAAU,yBACX,sDAAC,YAAAA,SAAA,EAAK,UAAM,sBAAU,YAAY,EAAE,aAAa,EAAE,OAAO,GAAG,WAAU,mBAAkB,wBAAU,GACrG;AAAA,QACA,6CAAC,OAAE,WAAU,iCAAgC;AAAA;AAAA,UAAc,EAAE;AAAA,WAAO;AAAA,SACtE;AAAA,MACA;AAAA,QAAC;AAAA;AAAA,UACC,MAAK;AAAA,UACL,SAAQ;AAAA,UACR,UAAU,OAAO;AAAA,UACjB,SAAS,MACP,OAAO,IAAI,EAAE,YAAY,CAAC,QAAQ,IAAI,QAAQ,OAAO,iCAAiC,EAAE,UAAU,eAAe,YAAY,EAAE,WAAW,CAAC,GAAG,MAAM,OAAO,CAAC;AAAA,UAG9J;AAAA,wDAAC,WAAQ,QAAQ,OAAO,QAAQ,OAAO,aAAa,EAAE,YAAY,MAAM,MAAM,WAAU,UAAS;AAAA,YAAE;AAAA;AAAA;AAAA,MAErG;AAAA,SAjBQ,EAAE,EAkBZ,CACD;AAAA,KACH;AAEJ;AAEA,SAAS,YAAY,EAAE,SAAS,OAAO,SAAS,GAA2E;AACzH,MAAI,QAAS,QAAO,4CAAC,4BAAS,WAAU,0BAAyB;AACjE,MAAI,SAAS,WAAW,GAAG;AACzB,WACE,6CAAC,SACC;AAAA,kDAAC,OAAE,WAAU,uBAAuB,gBAAM,OAAM;AAAA,MAChD,4CAAC,OAAE,WAAU,iCAAiC,gBAAM,aAAY;AAAA,OAClE;AAAA,EAEJ;AACA,SAAO,4CAAC,SAAI,WAAU,aAAa,UAAS;AAC9C;AAEO,SAAS,wBAAwB;AACtC,QAAM,EAAE,cAAc,QAAI,sCAAgB;AAC1C,QAAM,EAAE,OAAO,QAAI,6CAAqB,gBAAgB,EAAE,QAAQ,eAAe,MAAM,KAAK,IAAI,MAAS;AACzG,QAAM,EAAE,UAAU,MAAM,WAAW,YAAY,QAAI,+CAAuB,gBAAgB,EAAE,QAAQ,cAAc,IAAI,MAAS;AAC/H,QAAM,EAAE,UAAU,QAAQ,WAAW,cAAc,QAAI,+CAAuB,gBAAgB,EAAE,QAAQ,cAAc,IAAI,MAAS;AAEnI,MAAI,CAAC,cAAe,QAAO;AAE3B,SACE,6CAAC,SAAI,WAAU,aACb;AAAA,iDAAC,aAAQ,WAAU,aACjB;AAAA,mDAAC,QAAG,WAAU,6CAA4C;AAAA,oDAAC,iCAAU,WAAU,2BAA0B;AAAA,QAAE;AAAA,SAAgC;AAAA,MAC3I,4CAAC,qBAAkB,eAA8B;AAAA,OACnD;AAAA,IAEC,OAAO,SAAS,KACf,6CAAC,aAAQ,WAAU,aACjB;AAAA,kDAAC,QAAG,WAAU,qBAAoB,iCAAmB;AAAA,MACrD,4CAAC,SAAI,WAAU,aACZ,iBAAO,IAAI,CAAC,MAAM,4CAAC,gBAAwB,OAAO,KAAb,EAAE,EAAc,CAAE,GAC1D;AAAA,OACF;AAAA,IAGF,6CAAC,aAAQ,WAAU,aACjB;AAAA,kDAAC,QAAG,WAAU,qBAAoB,mCAA0B;AAAA,MAC5D,4CAAC,iBAAc,eAA8B;AAAA,OAC/C;AAAA,IAEA,6CAAC,aAAQ,WAAU,aACjB;AAAA,kDAAC,QAAG,WAAU,qBAAoB,+BAAiB;AAAA,MACnD,4CAAC,eAAY,SAAS,aAAa,OAAO,oCAAc,cACrD,eAAK,IAAI,CAAC,MACT,6CAAC,SAAe,WAAU,kBACxB;AAAA,oDAAC,OAAE,WAAU,yBACX,sDAAC,YAAAA,SAAA,EAAK,UAAM,sBAAU,YAAY,EAAE,eAAe,EAAE,YAAY,GAAG,WAAU,mBAAkB,mCAAqB,GACvH;AAAA,QACA,6CAAC,OAAE,WAAU,iCAAgC;AAAA;AAAA,UAAK,4CAAC,yCAAe,SAAS,EAAE,QAAQ,OAAO,GAAG,UAAU,OAAO;AAAA,WAAE;AAAA,WAJ1G,EAAE,EAKZ,CACD,GACH;AAAA,OACF;AAAA,IAEA,6CAAC,aAAQ,WAAU,aACjB;AAAA,kDAAC,QAAG,WAAU,qBAAoB,0CAA4B;AAAA,MAC9D,4CAAC,eAAY,SAAS,eAAe,OAAO,oCAAc,gBACvD,iBAAO,IAAI,CAAC,MACX,6CAAC,SAAe,WAAU,kBACxB;AAAA,oDAAC,OAAE,WAAU,yBACX,sDAAC,YAAAA,SAAA,EAAK,UAAM,sBAAU,YAAY,EAAE,eAAe,EAAE,YAAY,GAAG,WAAU,mBAAkB,mCAAqB,GACvH;AAAA,QACA,6CAAC,OAAE,WAAU,iCAAgC;AAAA;AAAA,UAAQ,4CAAC,yCAAe,SAAS,EAAE,iBAAiB,EAAE,WAAW,OAAO,GAAG,UAAU,OAAO;AAAA,WAAE;AAAA,WAJnI,EAAE,EAKZ,CACD,GACH;AAAA,OACF;AAAA,KACF;AAEJ;","names":["Link"]}
|
|
@@ -9,9 +9,11 @@ import Link from "./link.js";
|
|
|
9
9
|
import { useMedialaneApp } from "./medialane-app.js";
|
|
10
10
|
import { Skeleton } from "./skeleton.js";
|
|
11
11
|
import { TransactionDialog } from "./transaction-dialog.js";
|
|
12
|
-
import {
|
|
12
|
+
import { TransactionSuccess } from "./transaction-success.js";
|
|
13
13
|
import { runIntentCalls } from "../utils/run-intent-calls.js";
|
|
14
14
|
import { useSponsorshipBids, useSponsorshipLicenses, useSponsorshipOffers, useSponsorshipProposals } from "../utils/use-sponsorship.js";
|
|
15
|
+
import { emptyMessages } from "../utils/empty-messages.js";
|
|
16
|
+
import { successMessages } from "../utils/success-messages.js";
|
|
15
17
|
import { useTransaction } from "../utils/use-transaction.js";
|
|
16
18
|
function useRowAction(copy) {
|
|
17
19
|
const app = useMedialaneApp();
|
|
@@ -24,7 +26,7 @@ function useRowAction(copy) {
|
|
|
24
26
|
await runIntentCalls(signer, () => create(app.getClient().api));
|
|
25
27
|
}).then((ok) => ok ? then() : void 0).finally(() => setActiveId(null));
|
|
26
28
|
};
|
|
27
|
-
const dialog = /* @__PURE__ */ jsx(TransactionDialog, { tx, title: copy.title, workingLabel: copy.working, firstStepLabel: "Prepare", children: /* @__PURE__ */ jsx(
|
|
29
|
+
const dialog = /* @__PURE__ */ jsx(TransactionDialog, { tx, title: copy.title, workingLabel: copy.working, firstStepLabel: "Prepare", children: /* @__PURE__ */ jsx(TransactionSuccess, { name: copy.title, ...copy.message, txHash: tx.txHash, actions: [{ label: "Done", onClick: tx.reset }] }) });
|
|
28
30
|
return { run, dialog, busy, activeId };
|
|
29
31
|
}
|
|
30
32
|
function Spinner({ active, idle, className }) {
|
|
@@ -33,7 +35,7 @@ function Spinner({ active, idle, className }) {
|
|
|
33
35
|
function OfferBidsRow({ offer }) {
|
|
34
36
|
const { walletAddress } = useMedialaneApp();
|
|
35
37
|
const { bids, isLoading, mutate } = useSponsorshipBids(offer.offerId);
|
|
36
|
-
const action = useRowAction({ title: "Accept bid", working: "Accepting the bid\u2026",
|
|
38
|
+
const action = useRowAction({ title: "Accept bid", working: "Accepting the bid\u2026", message: successMessages.bidAccepted() });
|
|
37
39
|
if (isLoading || bids.length === 0) return null;
|
|
38
40
|
return /* @__PURE__ */ jsxs("div", { className: "space-y-1.5 rounded-lg bg-muted/30 p-3", children: [
|
|
39
41
|
action.dialog,
|
|
@@ -63,7 +65,7 @@ function OfferBidsRow({ offer }) {
|
|
|
63
65
|
}
|
|
64
66
|
function ReceivedProposals({ walletAddress }) {
|
|
65
67
|
const { proposals, isLoading, mutate } = useSponsorshipProposals({ owner: walletAddress, open: true });
|
|
66
|
-
const action = useRowAction({ title: "Respond to proposal", working: "Sending your response\u2026",
|
|
68
|
+
const action = useRowAction({ title: "Respond to proposal", working: "Sending your response\u2026", message: successMessages.responseSent() });
|
|
67
69
|
if (isLoading) return /* @__PURE__ */ jsx(Skeleton, { className: "h-20 w-full rounded-xl" });
|
|
68
70
|
if (proposals.length === 0) return /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: "No proposals awaiting your decision." });
|
|
69
71
|
const respond = (proposalId, decision) => action.run(
|
|
@@ -91,7 +93,7 @@ function ReceivedProposals({ walletAddress }) {
|
|
|
91
93
|
}
|
|
92
94
|
function SentProposals({ walletAddress }) {
|
|
93
95
|
const { proposals, isLoading, mutate } = useSponsorshipProposals({ proposer: walletAddress, open: true });
|
|
94
|
-
const action = useRowAction({ title: "Withdraw proposal", working: "Withdrawing your proposal\u2026",
|
|
96
|
+
const action = useRowAction({ title: "Withdraw proposal", working: "Withdrawing your proposal\u2026", message: successMessages.proposalWithdrawn() });
|
|
95
97
|
if (isLoading) return /* @__PURE__ */ jsx(Skeleton, { className: "h-20 w-full rounded-xl" });
|
|
96
98
|
if (proposals.length === 0) return /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: "No pending proposals sent." });
|
|
97
99
|
return /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
@@ -122,7 +124,12 @@ function SentProposals({ walletAddress }) {
|
|
|
122
124
|
}
|
|
123
125
|
function LicenseList({ loading, empty, children }) {
|
|
124
126
|
if (loading) return /* @__PURE__ */ jsx(Skeleton, { className: "h-16 w-full rounded-xl" });
|
|
125
|
-
if (children.length === 0)
|
|
127
|
+
if (children.length === 0) {
|
|
128
|
+
return /* @__PURE__ */ jsxs("div", { children: [
|
|
129
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm font-medium", children: empty.title }),
|
|
130
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: empty.description })
|
|
131
|
+
] });
|
|
132
|
+
}
|
|
126
133
|
return /* @__PURE__ */ jsx("div", { className: "space-y-2", children });
|
|
127
134
|
}
|
|
128
135
|
function PortfolioSponsorships() {
|
|
@@ -149,7 +156,7 @@ function PortfolioSponsorships() {
|
|
|
149
156
|
] }),
|
|
150
157
|
/* @__PURE__ */ jsxs("section", { className: "space-y-3", children: [
|
|
151
158
|
/* @__PURE__ */ jsx("h2", { className: "text-sm font-bold", children: "Licenses you hold" }),
|
|
152
|
-
/* @__PURE__ */ jsx(LicenseList, { loading: heldLoading, empty:
|
|
159
|
+
/* @__PURE__ */ jsx(LicenseList, { loading: heldLoading, empty: emptyMessages.heldLicenses, children: held.map((l) => /* @__PURE__ */ jsxs("div", { className: "bento-cell p-4", children: [
|
|
153
160
|
/* @__PURE__ */ jsx("p", { className: "text-sm font-semibold", children: /* @__PURE__ */ jsx(Link, { href: assetHref("STARKNET", l.assetContract, l.assetTokenId), className: "hover:underline", children: "License on this asset" }) }),
|
|
154
161
|
/* @__PURE__ */ jsxs("p", { className: "text-xs text-muted-foreground", children: [
|
|
155
162
|
"from ",
|
|
@@ -159,7 +166,7 @@ function PortfolioSponsorships() {
|
|
|
159
166
|
] }),
|
|
160
167
|
/* @__PURE__ */ jsxs("section", { className: "space-y-3", children: [
|
|
161
168
|
/* @__PURE__ */ jsx("h2", { className: "text-sm font-bold", children: "Licenses issued on your work" }),
|
|
162
|
-
/* @__PURE__ */ jsx(LicenseList, { loading: issuedLoading, empty:
|
|
169
|
+
/* @__PURE__ */ jsx(LicenseList, { loading: issuedLoading, empty: emptyMessages.issuedLicenses, children: issued.map((l) => /* @__PURE__ */ jsxs("div", { className: "bento-cell p-4", children: [
|
|
163
170
|
/* @__PURE__ */ jsx("p", { className: "text-sm font-semibold", children: /* @__PURE__ */ jsx(Link, { href: assetHref("STARKNET", l.assetContract, l.assetTokenId), className: "hover:underline", children: "License on this asset" }) }),
|
|
164
171
|
/* @__PURE__ */ jsxs("p", { className: "text-xs text-muted-foreground", children: [
|
|
165
172
|
"held by ",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/portfolio-sponsorships.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState } from \"react\";\nimport { CheckCircle2, Handshake, Loader2, X } from \"lucide-react\";\nimport { assetHref, type ApiSponsorshipOffer } from \"@medialane/sdk\";\nimport { AddressDisplay } from \"./address-display.js\";\nimport { Button } from \"./button.js\";\nimport Link from \"./link.js\";\nimport { useMedialaneApp } from \"./medialane-app.js\";\nimport { Skeleton } from \"./skeleton.js\";\nimport { TransactionDialog } from \"./transaction-dialog.js\";\nimport { TransactionDone } from \"./transaction-done.js\";\nimport { runIntentCalls } from \"../utils/run-intent-calls.js\";\nimport { useSponsorshipBids, useSponsorshipLicenses, useSponsorshipOffers, useSponsorshipProposals } from \"../utils/use-sponsorship.js\";\nimport { useTransaction } from \"../utils/use-transaction.js\";\n\ntype Api = ReturnType<ReturnType<typeof useMedialaneApp>[\"getClient\"]>[\"api\"];\n\nfunction useRowAction(copy: { title: string; working: string; done: string; description: string }) {\n const app = useMedialaneApp();\n const tx = useTransaction();\n const [activeId, setActiveId] = useState<string | null>(null);\n const busy = tx.phase === \"preparing\" || tx.phase === \"submitting\" || tx.phase === \"confirming\";\n\n const run = (id: string, create: (api: Api) => ReturnType<Parameters<typeof runIntentCalls>[1]>, then: () => Promise<unknown>) => {\n setActiveId(id);\n void tx\n .run(async (signer) => {\n await runIntentCalls(signer, () => create(app.getClient().api));\n })\n .then((ok) => (ok ? then() : undefined))\n .finally(() => setActiveId(null));\n };\n\n const dialog = (\n <TransactionDialog tx={tx} title={copy.title} workingLabel={copy.working} firstStepLabel=\"Prepare\">\n <TransactionDone tx={tx} name={copy.title} title={copy.done} description={copy.description} />\n </TransactionDialog>\n );\n\n return { run, dialog, busy, activeId };\n}\n\nfunction Spinner({ active, idle, className }: { active: boolean; idle: React.ReactNode; className?: string }) {\n return active ? <Loader2 className={`h-3 w-3 animate-spin ${className ?? \"\"}`} /> : <>{idle}</>;\n}\n\nfunction OfferBidsRow({ offer }: { offer: ApiSponsorshipOffer }) {\n const { walletAddress } = useMedialaneApp();\n const { bids, isLoading, mutate } = useSponsorshipBids(offer.offerId);\n const action = useRowAction({ title: \"Accept bid\", working: \"Accepting the bid…\", done: \"Bid accepted!\", description: \"The license is minted to the sponsor.\" });\n\n if (isLoading || bids.length === 0) return null;\n\n return (\n <div className=\"space-y-1.5 rounded-lg bg-muted/30 p-3\">\n {action.dialog}\n <p className=\"text-xs font-semibold text-muted-foreground\">\n Bids on <Link href={assetHref(\"STARKNET\", offer.nftContract, offer.tokenId)} className=\"underline underline-offset-2\">View asset</Link>\n </p>\n {bids.map((bid) => (\n <div key={bid.id} className=\"flex items-center justify-between gap-2 text-xs\">\n <AddressDisplay address={bid.sponsor} chars={4} showCopy={false} className=\"text-muted-foreground\" />\n <Button\n size=\"sm\"\n className=\"bg-brand-rose hover:brightness-110 text-white h-7 px-2.5\"\n aria-label=\"Accept bid\"\n disabled={action.busy || !walletAddress}\n onClick={() =>\n action.run(\n bid.id,\n (api) => api.intents.create(\"sponsorship-bid-accept\", { author: walletAddress!, offerId: offer.offerId, sponsor: bid.sponsor }),\n () => mutate(),\n )\n }\n >\n <Spinner active={action.busy && action.activeId === bid.id} idle={<CheckCircle2 className=\"h-3 w-3\" />} />\n </Button>\n </div>\n ))}\n </div>\n );\n}\n\nfunction ReceivedProposals({ walletAddress }: { walletAddress: string }) {\n const { proposals, isLoading, mutate } = useSponsorshipProposals({ owner: walletAddress, open: true });\n const action = useRowAction({ title: \"Respond to proposal\", working: \"Sending your response…\", done: \"Response sent!\", description: \"Your response is now on-chain.\" });\n\n if (isLoading) return <Skeleton className=\"h-20 w-full rounded-xl\" />;\n if (proposals.length === 0) return <p className=\"text-sm text-muted-foreground\">No proposals awaiting your decision.</p>;\n\n const respond = (proposalId: string, decision: \"accept\" | \"reject\") =>\n action.run(\n proposalId,\n (api) =>\n decision === \"accept\"\n ? api.intents.create(\"sponsorship-proposal-accept\", { owner: walletAddress, proposalId })\n : api.intents.create(\"sponsorship-proposal-reject\", { owner: walletAddress, proposalId }),\n () => mutate(),\n );\n\n return (\n <div className=\"space-y-2\">\n {action.dialog}\n {proposals.map((p) => (\n <div key={p.id} className=\"bento-cell p-4 flex items-center justify-between gap-3\">\n <div className=\"min-w-0\">\n <p className=\"text-sm font-semibold\">\n <Link href={assetHref(\"STARKNET\", p.nftContract, p.tokenId)} className=\"hover:underline\">View asset</Link>\n </p>\n <p className=\"text-xs text-muted-foreground\">\n <AddressDisplay address={p.proposer} chars={4} showCopy={false} /> proposed {p.amount}\n </p>\n </div>\n <div className=\"flex gap-1.5 shrink-0\">\n <Button size=\"sm\" variant=\"outline\" aria-label=\"Decline proposal\" disabled={action.busy} onClick={() => respond(p.proposalId, \"reject\")}>\n <Spinner active={action.busy && action.activeId === p.proposalId} idle={<X className=\"h-3 w-3\" />} />\n </Button>\n <Button size=\"sm\" className=\"bg-brand-rose hover:brightness-110 text-white\" aria-label=\"Accept proposal\" disabled={action.busy} onClick={() => respond(p.proposalId, \"accept\")}>\n <Spinner active={action.busy && action.activeId === p.proposalId} idle={<CheckCircle2 className=\"h-3 w-3\" />} />\n </Button>\n </div>\n </div>\n ))}\n </div>\n );\n}\n\nfunction SentProposals({ walletAddress }: { walletAddress: string }) {\n const { proposals, isLoading, mutate } = useSponsorshipProposals({ proposer: walletAddress, open: true });\n const action = useRowAction({ title: \"Withdraw proposal\", working: \"Withdrawing your proposal…\", done: \"Proposal withdrawn!\", description: \"Your proposal is no longer open.\" });\n\n if (isLoading) return <Skeleton className=\"h-20 w-full rounded-xl\" />;\n if (proposals.length === 0) return <p className=\"text-sm text-muted-foreground\">No pending proposals sent.</p>;\n\n return (\n <div className=\"space-y-2\">\n {action.dialog}\n {proposals.map((p) => (\n <div key={p.id} className=\"bento-cell p-4 flex items-center justify-between gap-3\">\n <div className=\"min-w-0\">\n <p className=\"text-sm font-semibold\">\n <Link href={assetHref(\"STARKNET\", p.nftContract, p.tokenId)} className=\"hover:underline\">View asset</Link>\n </p>\n <p className=\"text-xs text-muted-foreground\">You proposed {p.amount}</p>\n </div>\n <Button\n size=\"sm\"\n variant=\"outline\"\n disabled={action.busy}\n onClick={() =>\n action.run(p.proposalId, (api) => api.intents.create(\"sponsorship-proposal-withdraw\", { proposer: walletAddress, proposalId: p.proposalId }), () => mutate())\n }\n >\n <Spinner active={action.busy && action.activeId === p.proposalId} idle={null} className=\"mr-1.5\" />\n Withdraw\n </Button>\n </div>\n ))}\n </div>\n );\n}\n\nfunction LicenseList({ loading, empty, children }: { loading: boolean; empty: string; children: React.ReactNode[] }) {\n if (loading) return <Skeleton className=\"h-16 w-full rounded-xl\" />;\n if (children.length === 0) return <p className=\"text-sm text-muted-foreground\">{empty}</p>;\n return <div className=\"space-y-2\">{children}</div>;\n}\n\nexport function PortfolioSponsorships() {\n const { walletAddress } = useMedialaneApp();\n const { offers } = useSponsorshipOffers(walletAddress ? { author: walletAddress, open: true } : undefined);\n const { licenses: held, isLoading: heldLoading } = useSponsorshipLicenses(walletAddress ? { holder: walletAddress } : undefined);\n const { licenses: issued, isLoading: issuedLoading } = useSponsorshipLicenses(walletAddress ? { author: walletAddress } : undefined);\n\n if (!walletAddress) return null;\n\n return (\n <div className=\"space-y-8\">\n <section className=\"space-y-3\">\n <h2 className=\"text-sm font-bold flex items-center gap-2\"><Handshake className=\"h-4 w-4 text-brand-rose\" />Proposals awaiting your decision</h2>\n <ReceivedProposals walletAddress={walletAddress} />\n </section>\n\n {offers.length > 0 && (\n <section className=\"space-y-3\">\n <h2 className=\"text-sm font-bold\">Bids on your offers</h2>\n <div className=\"space-y-2\">\n {offers.map((o) => <OfferBidsRow key={o.id} offer={o} />)}\n </div>\n </section>\n )}\n\n <section className=\"space-y-3\">\n <h2 className=\"text-sm font-bold\">Proposals you've sent</h2>\n <SentProposals walletAddress={walletAddress} />\n </section>\n\n <section className=\"space-y-3\">\n <h2 className=\"text-sm font-bold\">Licenses you hold</h2>\n <LicenseList loading={heldLoading} empty=\"No sponsorship licenses yet.\">\n {held.map((l) => (\n <div key={l.id} className=\"bento-cell p-4\">\n <p className=\"text-sm font-semibold\">\n <Link href={assetHref(\"STARKNET\", l.assetContract, l.assetTokenId)} className=\"hover:underline\">License on this asset</Link>\n </p>\n <p className=\"text-xs text-muted-foreground\">from <AddressDisplay address={l.author} chars={4} showCopy={false} /></p>\n </div>\n ))}\n </LicenseList>\n </section>\n\n <section className=\"space-y-3\">\n <h2 className=\"text-sm font-bold\">Licenses issued on your work</h2>\n <LicenseList loading={issuedLoading} empty=\"No licenses issued yet.\">\n {issued.map((l) => (\n <div key={l.id} className=\"bento-cell p-4\">\n <p className=\"text-sm font-semibold\">\n <Link href={assetHref(\"STARKNET\", l.assetContract, l.assetTokenId)} className=\"hover:underline\">License on this asset</Link>\n </p>\n <p className=\"text-xs text-muted-foreground\">held by <AddressDisplay address={l.currentHolder ?? l.recipient} chars={4} showCopy={false} /></p>\n </div>\n ))}\n </LicenseList>\n </section>\n </div>\n );\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/components/portfolio-sponsorships.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState } from \"react\";\nimport { CheckCircle2, Handshake, Loader2, X } from \"lucide-react\";\nimport { assetHref, type ApiSponsorshipOffer } from \"@medialane/sdk\";\nimport { AddressDisplay } from \"./address-display.js\";\nimport { Button } from \"./button.js\";\nimport Link from \"./link.js\";\nimport { useMedialaneApp } from \"./medialane-app.js\";\nimport { Skeleton } from \"./skeleton.js\";\nimport { TransactionDialog } from \"./transaction-dialog.js\";\nimport { TransactionSuccess } from \"./transaction-success.js\";\nimport { runIntentCalls } from \"../utils/run-intent-calls.js\";\nimport { useSponsorshipBids, useSponsorshipLicenses, useSponsorshipOffers, useSponsorshipProposals } from \"../utils/use-sponsorship.js\";\nimport { emptyMessages, type EmptyMessage } from \"../utils/empty-messages.js\";\nimport { successMessages, type SuccessMessage } from \"../utils/success-messages.js\";\nimport { useTransaction } from \"../utils/use-transaction.js\";\n\ntype Api = ReturnType<ReturnType<typeof useMedialaneApp>[\"getClient\"]>[\"api\"];\n\nfunction useRowAction(copy: { title: string; working: string; message: SuccessMessage }) {\n const app = useMedialaneApp();\n const tx = useTransaction();\n const [activeId, setActiveId] = useState<string | null>(null);\n const busy = tx.phase === \"preparing\" || tx.phase === \"submitting\" || tx.phase === \"confirming\";\n\n const run = (id: string, create: (api: Api) => ReturnType<Parameters<typeof runIntentCalls>[1]>, then: () => Promise<unknown>) => {\n setActiveId(id);\n void tx\n .run(async (signer) => {\n await runIntentCalls(signer, () => create(app.getClient().api));\n })\n .then((ok) => (ok ? then() : undefined))\n .finally(() => setActiveId(null));\n };\n\n const dialog = (\n <TransactionDialog tx={tx} title={copy.title} workingLabel={copy.working} firstStepLabel=\"Prepare\">\n <TransactionSuccess name={copy.title} {...copy.message} txHash={tx.txHash} actions={[{ label: \"Done\", onClick: tx.reset }]} />\n </TransactionDialog>\n );\n\n return { run, dialog, busy, activeId };\n}\n\nfunction Spinner({ active, idle, className }: { active: boolean; idle: React.ReactNode; className?: string }) {\n return active ? <Loader2 className={`h-3 w-3 animate-spin ${className ?? \"\"}`} /> : <>{idle}</>;\n}\n\nfunction OfferBidsRow({ offer }: { offer: ApiSponsorshipOffer }) {\n const { walletAddress } = useMedialaneApp();\n const { bids, isLoading, mutate } = useSponsorshipBids(offer.offerId);\n const action = useRowAction({ title: \"Accept bid\", working: \"Accepting the bid…\", message: successMessages.bidAccepted() });\n\n if (isLoading || bids.length === 0) return null;\n\n return (\n <div className=\"space-y-1.5 rounded-lg bg-muted/30 p-3\">\n {action.dialog}\n <p className=\"text-xs font-semibold text-muted-foreground\">\n Bids on <Link href={assetHref(\"STARKNET\", offer.nftContract, offer.tokenId)} className=\"underline underline-offset-2\">View asset</Link>\n </p>\n {bids.map((bid) => (\n <div key={bid.id} className=\"flex items-center justify-between gap-2 text-xs\">\n <AddressDisplay address={bid.sponsor} chars={4} showCopy={false} className=\"text-muted-foreground\" />\n <Button\n size=\"sm\"\n className=\"bg-brand-rose hover:brightness-110 text-white h-7 px-2.5\"\n aria-label=\"Accept bid\"\n disabled={action.busy || !walletAddress}\n onClick={() =>\n action.run(\n bid.id,\n (api) => api.intents.create(\"sponsorship-bid-accept\", { author: walletAddress!, offerId: offer.offerId, sponsor: bid.sponsor }),\n () => mutate(),\n )\n }\n >\n <Spinner active={action.busy && action.activeId === bid.id} idle={<CheckCircle2 className=\"h-3 w-3\" />} />\n </Button>\n </div>\n ))}\n </div>\n );\n}\n\nfunction ReceivedProposals({ walletAddress }: { walletAddress: string }) {\n const { proposals, isLoading, mutate } = useSponsorshipProposals({ owner: walletAddress, open: true });\n const action = useRowAction({ title: \"Respond to proposal\", working: \"Sending your response…\", message: successMessages.responseSent() });\n\n if (isLoading) return <Skeleton className=\"h-20 w-full rounded-xl\" />;\n if (proposals.length === 0) return <p className=\"text-sm text-muted-foreground\">No proposals awaiting your decision.</p>;\n\n const respond = (proposalId: string, decision: \"accept\" | \"reject\") =>\n action.run(\n proposalId,\n (api) =>\n decision === \"accept\"\n ? api.intents.create(\"sponsorship-proposal-accept\", { owner: walletAddress, proposalId })\n : api.intents.create(\"sponsorship-proposal-reject\", { owner: walletAddress, proposalId }),\n () => mutate(),\n );\n\n return (\n <div className=\"space-y-2\">\n {action.dialog}\n {proposals.map((p) => (\n <div key={p.id} className=\"bento-cell p-4 flex items-center justify-between gap-3\">\n <div className=\"min-w-0\">\n <p className=\"text-sm font-semibold\">\n <Link href={assetHref(\"STARKNET\", p.nftContract, p.tokenId)} className=\"hover:underline\">View asset</Link>\n </p>\n <p className=\"text-xs text-muted-foreground\">\n <AddressDisplay address={p.proposer} chars={4} showCopy={false} /> proposed {p.amount}\n </p>\n </div>\n <div className=\"flex gap-1.5 shrink-0\">\n <Button size=\"sm\" variant=\"outline\" aria-label=\"Decline proposal\" disabled={action.busy} onClick={() => respond(p.proposalId, \"reject\")}>\n <Spinner active={action.busy && action.activeId === p.proposalId} idle={<X className=\"h-3 w-3\" />} />\n </Button>\n <Button size=\"sm\" className=\"bg-brand-rose hover:brightness-110 text-white\" aria-label=\"Accept proposal\" disabled={action.busy} onClick={() => respond(p.proposalId, \"accept\")}>\n <Spinner active={action.busy && action.activeId === p.proposalId} idle={<CheckCircle2 className=\"h-3 w-3\" />} />\n </Button>\n </div>\n </div>\n ))}\n </div>\n );\n}\n\nfunction SentProposals({ walletAddress }: { walletAddress: string }) {\n const { proposals, isLoading, mutate } = useSponsorshipProposals({ proposer: walletAddress, open: true });\n const action = useRowAction({ title: \"Withdraw proposal\", working: \"Withdrawing your proposal…\", message: successMessages.proposalWithdrawn() });\n\n if (isLoading) return <Skeleton className=\"h-20 w-full rounded-xl\" />;\n if (proposals.length === 0) return <p className=\"text-sm text-muted-foreground\">No pending proposals sent.</p>;\n\n return (\n <div className=\"space-y-2\">\n {action.dialog}\n {proposals.map((p) => (\n <div key={p.id} className=\"bento-cell p-4 flex items-center justify-between gap-3\">\n <div className=\"min-w-0\">\n <p className=\"text-sm font-semibold\">\n <Link href={assetHref(\"STARKNET\", p.nftContract, p.tokenId)} className=\"hover:underline\">View asset</Link>\n </p>\n <p className=\"text-xs text-muted-foreground\">You proposed {p.amount}</p>\n </div>\n <Button\n size=\"sm\"\n variant=\"outline\"\n disabled={action.busy}\n onClick={() =>\n action.run(p.proposalId, (api) => api.intents.create(\"sponsorship-proposal-withdraw\", { proposer: walletAddress, proposalId: p.proposalId }), () => mutate())\n }\n >\n <Spinner active={action.busy && action.activeId === p.proposalId} idle={null} className=\"mr-1.5\" />\n Withdraw\n </Button>\n </div>\n ))}\n </div>\n );\n}\n\nfunction LicenseList({ loading, empty, children }: { loading: boolean; empty: EmptyMessage; children: React.ReactNode[] }) {\n if (loading) return <Skeleton className=\"h-16 w-full rounded-xl\" />;\n if (children.length === 0) {\n return (\n <div>\n <p className=\"text-sm font-medium\">{empty.title}</p>\n <p className=\"text-sm text-muted-foreground\">{empty.description}</p>\n </div>\n );\n }\n return <div className=\"space-y-2\">{children}</div>;\n}\n\nexport function PortfolioSponsorships() {\n const { walletAddress } = useMedialaneApp();\n const { offers } = useSponsorshipOffers(walletAddress ? { author: walletAddress, open: true } : undefined);\n const { licenses: held, isLoading: heldLoading } = useSponsorshipLicenses(walletAddress ? { holder: walletAddress } : undefined);\n const { licenses: issued, isLoading: issuedLoading } = useSponsorshipLicenses(walletAddress ? { author: walletAddress } : undefined);\n\n if (!walletAddress) return null;\n\n return (\n <div className=\"space-y-8\">\n <section className=\"space-y-3\">\n <h2 className=\"text-sm font-bold flex items-center gap-2\"><Handshake className=\"h-4 w-4 text-brand-rose\" />Proposals awaiting your decision</h2>\n <ReceivedProposals walletAddress={walletAddress} />\n </section>\n\n {offers.length > 0 && (\n <section className=\"space-y-3\">\n <h2 className=\"text-sm font-bold\">Bids on your offers</h2>\n <div className=\"space-y-2\">\n {offers.map((o) => <OfferBidsRow key={o.id} offer={o} />)}\n </div>\n </section>\n )}\n\n <section className=\"space-y-3\">\n <h2 className=\"text-sm font-bold\">Proposals you've sent</h2>\n <SentProposals walletAddress={walletAddress} />\n </section>\n\n <section className=\"space-y-3\">\n <h2 className=\"text-sm font-bold\">Licenses you hold</h2>\n <LicenseList loading={heldLoading} empty={emptyMessages.heldLicenses}>\n {held.map((l) => (\n <div key={l.id} className=\"bento-cell p-4\">\n <p className=\"text-sm font-semibold\">\n <Link href={assetHref(\"STARKNET\", l.assetContract, l.assetTokenId)} className=\"hover:underline\">License on this asset</Link>\n </p>\n <p className=\"text-xs text-muted-foreground\">from <AddressDisplay address={l.author} chars={4} showCopy={false} /></p>\n </div>\n ))}\n </LicenseList>\n </section>\n\n <section className=\"space-y-3\">\n <h2 className=\"text-sm font-bold\">Licenses issued on your work</h2>\n <LicenseList loading={issuedLoading} empty={emptyMessages.issuedLicenses}>\n {issued.map((l) => (\n <div key={l.id} className=\"bento-cell p-4\">\n <p className=\"text-sm font-semibold\">\n <Link href={assetHref(\"STARKNET\", l.assetContract, l.assetTokenId)} className=\"hover:underline\">License on this asset</Link>\n </p>\n <p className=\"text-xs text-muted-foreground\">held by <AddressDisplay address={l.currentHolder ?? l.recipient} chars={4} showCopy={false} /></p>\n </div>\n ))}\n </LicenseList>\n </section>\n </div>\n );\n}\n"],"mappings":"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","names":[]}
|
|
@@ -54,7 +54,7 @@ const KINDS = {
|
|
|
54
54
|
createLabel: "Create collection",
|
|
55
55
|
sectionLabel: "Your collections",
|
|
56
56
|
sectionTitle: "Ticket collections",
|
|
57
|
-
empty: "
|
|
57
|
+
empty: "Your ticket collections appear here",
|
|
58
58
|
emptyText: "Create your first tickets collection.",
|
|
59
59
|
accent: "bg-brand-blue",
|
|
60
60
|
tint: "bg-brand-blue/10 text-brand-blue/40"
|
|
@@ -67,7 +67,7 @@ const KINDS = {
|
|
|
67
67
|
createLabel: "Create club",
|
|
68
68
|
sectionLabel: "Your clubs",
|
|
69
69
|
sectionTitle: "Club collections",
|
|
70
|
-
empty: "
|
|
70
|
+
empty: "Your clubs appear here",
|
|
71
71
|
emptyText: "Create your first club.",
|
|
72
72
|
accent: "bg-brand-purple",
|
|
73
73
|
tint: "bg-brand-purple/10 text-brand-purple/40"
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/service-collections-page.tsx"],"sourcesContent":["\"use client\";\n\nimport { Plus, Ticket, Users } from \"lucide-react\";\nimport { collectionHref } from \"@medialane/sdk\";\nimport Link from \"./link.js\";\nimport { Button } from \"./button.js\";\nimport { Skeleton } from \"./skeleton.js\";\nimport { FadeIn, Stagger, StaggerItem } from \"./motion-primitives.js\";\nimport { BackButton } from \"./back-button.js\";\nimport { ServiceHeader } from \"./service-header.js\";\nimport { CollectionCard } from \"./collection-card.js\";\nimport { SignInPrompt } from \"./sign-in-prompt.js\";\nimport { useMedialaneApp } from \"./medialane-app.js\";\nimport { useMyClubCollections, useMyTicketCollections } from \"../utils/use-tiers.js\";\n\nconst KINDS = {\n tickets: {\n icon: Ticket,\n title: \"IP Tickets\",\n subtitle: \"Create a tickets collection, then mint tickets from its collection page.\",\n createHref: \"/launchpad/tickets/create\",\n createLabel: \"Create collection\",\n sectionLabel: \"Your collections\",\n sectionTitle: \"Ticket collections\",\n empty: \"
|
|
1
|
+
{"version":3,"sources":["../../src/components/service-collections-page.tsx"],"sourcesContent":["\"use client\";\n\nimport { Plus, Ticket, Users } from \"lucide-react\";\nimport { collectionHref } from \"@medialane/sdk\";\nimport Link from \"./link.js\";\nimport { Button } from \"./button.js\";\nimport { Skeleton } from \"./skeleton.js\";\nimport { FadeIn, Stagger, StaggerItem } from \"./motion-primitives.js\";\nimport { BackButton } from \"./back-button.js\";\nimport { ServiceHeader } from \"./service-header.js\";\nimport { CollectionCard } from \"./collection-card.js\";\nimport { SignInPrompt } from \"./sign-in-prompt.js\";\nimport { useMedialaneApp } from \"./medialane-app.js\";\nimport { useMyClubCollections, useMyTicketCollections } from \"../utils/use-tiers.js\";\n\nconst KINDS = {\n tickets: {\n icon: Ticket,\n title: \"IP Tickets\",\n subtitle: \"Create a tickets collection, then mint tickets from its collection page.\",\n createHref: \"/launchpad/tickets/create\",\n createLabel: \"Create collection\",\n sectionLabel: \"Your collections\",\n sectionTitle: \"Ticket collections\",\n empty: \"Your ticket collections appear here\",\n emptyText: \"Create your first tickets collection.\",\n accent: \"bg-brand-blue\",\n tint: \"bg-brand-blue/10 text-brand-blue/40\",\n },\n club: {\n icon: Users,\n title: \"IP Club\",\n subtitle: \"Create a club, then create membership tiers from its collection page.\",\n createHref: \"/launchpad/club/create\",\n createLabel: \"Create club\",\n sectionLabel: \"Your clubs\",\n sectionTitle: \"Club collections\",\n empty: \"Your clubs appear here\",\n emptyText: \"Create your first club.\",\n accent: \"bg-brand-purple\",\n tint: \"bg-brand-purple/10 text-brand-purple/40\",\n },\n} as const;\n\nexport function ServiceCollectionsPage({ kind }: { kind: keyof typeof KINDS }) {\n const config = KINDS[kind];\n const Icon = config.icon;\n const { walletAddress, walletLoading } = useMedialaneApp();\n const tickets = useMyTicketCollections(kind === \"tickets\" ? walletAddress : null);\n const clubs = useMyClubCollections(kind === \"club\" ? walletAddress : null);\n const { collections, isLoading } = kind === \"tickets\" ? tickets : clubs;\n\n const createButton = (\n <Button asChild size=\"sm\" className={`${config.accent} gap-1.5 text-white hover:brightness-110`}>\n <Link href={config.createHref}>\n <Plus className=\"h-3.5 w-3.5\" />\n {config.createLabel}\n </Link>\n </Button>\n );\n const iconTile = (\n <div className={`flex h-16 w-16 items-center justify-center rounded-2xl ${config.tint}`}>\n <Icon className=\"h-8 w-8\" />\n </div>\n );\n\n return (\n <div className=\"mx-auto max-w-5xl space-y-10 pb-16\">\n <section className=\"px-4 pt-10\">\n <BackButton />\n <FadeIn>\n <div className=\"mt-6\">\n <ServiceHeader plain icon={<Icon className=\"h-4 w-4 text-white\" />} title={config.title} subtitle={config.subtitle} headerAccessory={createButton} />\n </div>\n </FadeIn>\n </section>\n\n <section className=\"space-y-4 px-4\">\n <div>\n <p className=\"section-label\">{config.sectionLabel}</p>\n <h2 className=\"mt-0.5 text-xl font-bold\">{config.sectionTitle}</h2>\n </div>\n\n {!walletAddress && !walletLoading ? (\n <SignInPrompt icon={iconTile} title=\"Sign in to see your collections\" />\n ) : isLoading || walletLoading ? (\n <div className=\"grid grid-cols-2 gap-4 sm:grid-cols-3 lg:grid-cols-4\">\n {Array.from({ length: 4 }).map((_, i) => <Skeleton key={i} className=\"aspect-square rounded-2xl\" />)}\n </div>\n ) : collections.length === 0 ? (\n <div className=\"bento-cell space-y-4 border-dashed p-12 text-center\">\n <div className=\"flex justify-center\">{iconTile}</div>\n <div className=\"space-y-1\">\n <p className=\"text-sm font-semibold\">{config.empty}</p>\n <p className=\"text-xs text-muted-foreground\">{config.emptyText}</p>\n </div>\n {createButton}\n </div>\n ) : (\n <Stagger className=\"grid grid-cols-2 gap-4 sm:grid-cols-3 lg:grid-cols-4\">\n {collections.map((col) => (\n <StaggerItem key={col.contractAddress}>\n <CollectionCard collection={col} href={collectionHref(\"STARKNET\", col.contractAddress)} />\n </StaggerItem>\n ))}\n </Stagger>\n )}\n </section>\n </div>\n );\n}\n"],"mappings":"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","names":["Link"]}
|
|
@@ -11,7 +11,7 @@ declare const KINDS: {
|
|
|
11
11
|
readonly createLabel: "Create collection";
|
|
12
12
|
readonly sectionLabel: "Your collections";
|
|
13
13
|
readonly sectionTitle: "Ticket collections";
|
|
14
|
-
readonly empty: "
|
|
14
|
+
readonly empty: "Your ticket collections appear here";
|
|
15
15
|
readonly emptyText: "Create your first tickets collection.";
|
|
16
16
|
readonly accent: "bg-brand-blue";
|
|
17
17
|
readonly tint: "bg-brand-blue/10 text-brand-blue/40";
|
|
@@ -24,7 +24,7 @@ declare const KINDS: {
|
|
|
24
24
|
readonly createLabel: "Create club";
|
|
25
25
|
readonly sectionLabel: "Your clubs";
|
|
26
26
|
readonly sectionTitle: "Club collections";
|
|
27
|
-
readonly empty: "
|
|
27
|
+
readonly empty: "Your clubs appear here";
|
|
28
28
|
readonly emptyText: "Create your first club.";
|
|
29
29
|
readonly accent: "bg-brand-purple";
|
|
30
30
|
readonly tint: "bg-brand-purple/10 text-brand-purple/40";
|
|
@@ -11,7 +11,7 @@ declare const KINDS: {
|
|
|
11
11
|
readonly createLabel: "Create collection";
|
|
12
12
|
readonly sectionLabel: "Your collections";
|
|
13
13
|
readonly sectionTitle: "Ticket collections";
|
|
14
|
-
readonly empty: "
|
|
14
|
+
readonly empty: "Your ticket collections appear here";
|
|
15
15
|
readonly emptyText: "Create your first tickets collection.";
|
|
16
16
|
readonly accent: "bg-brand-blue";
|
|
17
17
|
readonly tint: "bg-brand-blue/10 text-brand-blue/40";
|
|
@@ -24,7 +24,7 @@ declare const KINDS: {
|
|
|
24
24
|
readonly createLabel: "Create club";
|
|
25
25
|
readonly sectionLabel: "Your clubs";
|
|
26
26
|
readonly sectionTitle: "Club collections";
|
|
27
|
-
readonly empty: "
|
|
27
|
+
readonly empty: "Your clubs appear here";
|
|
28
28
|
readonly emptyText: "Create your first club.";
|
|
29
29
|
readonly accent: "bg-brand-purple";
|
|
30
30
|
readonly tint: "bg-brand-purple/10 text-brand-purple/40";
|
|
@@ -21,7 +21,7 @@ const KINDS = {
|
|
|
21
21
|
createLabel: "Create collection",
|
|
22
22
|
sectionLabel: "Your collections",
|
|
23
23
|
sectionTitle: "Ticket collections",
|
|
24
|
-
empty: "
|
|
24
|
+
empty: "Your ticket collections appear here",
|
|
25
25
|
emptyText: "Create your first tickets collection.",
|
|
26
26
|
accent: "bg-brand-blue",
|
|
27
27
|
tint: "bg-brand-blue/10 text-brand-blue/40"
|
|
@@ -34,7 +34,7 @@ const KINDS = {
|
|
|
34
34
|
createLabel: "Create club",
|
|
35
35
|
sectionLabel: "Your clubs",
|
|
36
36
|
sectionTitle: "Club collections",
|
|
37
|
-
empty: "
|
|
37
|
+
empty: "Your clubs appear here",
|
|
38
38
|
emptyText: "Create your first club.",
|
|
39
39
|
accent: "bg-brand-purple",
|
|
40
40
|
tint: "bg-brand-purple/10 text-brand-purple/40"
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/service-collections-page.tsx"],"sourcesContent":["\"use client\";\n\nimport { Plus, Ticket, Users } from \"lucide-react\";\nimport { collectionHref } from \"@medialane/sdk\";\nimport Link from \"./link.js\";\nimport { Button } from \"./button.js\";\nimport { Skeleton } from \"./skeleton.js\";\nimport { FadeIn, Stagger, StaggerItem } from \"./motion-primitives.js\";\nimport { BackButton } from \"./back-button.js\";\nimport { ServiceHeader } from \"./service-header.js\";\nimport { CollectionCard } from \"./collection-card.js\";\nimport { SignInPrompt } from \"./sign-in-prompt.js\";\nimport { useMedialaneApp } from \"./medialane-app.js\";\nimport { useMyClubCollections, useMyTicketCollections } from \"../utils/use-tiers.js\";\n\nconst KINDS = {\n tickets: {\n icon: Ticket,\n title: \"IP Tickets\",\n subtitle: \"Create a tickets collection, then mint tickets from its collection page.\",\n createHref: \"/launchpad/tickets/create\",\n createLabel: \"Create collection\",\n sectionLabel: \"Your collections\",\n sectionTitle: \"Ticket collections\",\n empty: \"
|
|
1
|
+
{"version":3,"sources":["../../src/components/service-collections-page.tsx"],"sourcesContent":["\"use client\";\n\nimport { Plus, Ticket, Users } from \"lucide-react\";\nimport { collectionHref } from \"@medialane/sdk\";\nimport Link from \"./link.js\";\nimport { Button } from \"./button.js\";\nimport { Skeleton } from \"./skeleton.js\";\nimport { FadeIn, Stagger, StaggerItem } from \"./motion-primitives.js\";\nimport { BackButton } from \"./back-button.js\";\nimport { ServiceHeader } from \"./service-header.js\";\nimport { CollectionCard } from \"./collection-card.js\";\nimport { SignInPrompt } from \"./sign-in-prompt.js\";\nimport { useMedialaneApp } from \"./medialane-app.js\";\nimport { useMyClubCollections, useMyTicketCollections } from \"../utils/use-tiers.js\";\n\nconst KINDS = {\n tickets: {\n icon: Ticket,\n title: \"IP Tickets\",\n subtitle: \"Create a tickets collection, then mint tickets from its collection page.\",\n createHref: \"/launchpad/tickets/create\",\n createLabel: \"Create collection\",\n sectionLabel: \"Your collections\",\n sectionTitle: \"Ticket collections\",\n empty: \"Your ticket collections appear here\",\n emptyText: \"Create your first tickets collection.\",\n accent: \"bg-brand-blue\",\n tint: \"bg-brand-blue/10 text-brand-blue/40\",\n },\n club: {\n icon: Users,\n title: \"IP Club\",\n subtitle: \"Create a club, then create membership tiers from its collection page.\",\n createHref: \"/launchpad/club/create\",\n createLabel: \"Create club\",\n sectionLabel: \"Your clubs\",\n sectionTitle: \"Club collections\",\n empty: \"Your clubs appear here\",\n emptyText: \"Create your first club.\",\n accent: \"bg-brand-purple\",\n tint: \"bg-brand-purple/10 text-brand-purple/40\",\n },\n} as const;\n\nexport function ServiceCollectionsPage({ kind }: { kind: keyof typeof KINDS }) {\n const config = KINDS[kind];\n const Icon = config.icon;\n const { walletAddress, walletLoading } = useMedialaneApp();\n const tickets = useMyTicketCollections(kind === \"tickets\" ? walletAddress : null);\n const clubs = useMyClubCollections(kind === \"club\" ? walletAddress : null);\n const { collections, isLoading } = kind === \"tickets\" ? tickets : clubs;\n\n const createButton = (\n <Button asChild size=\"sm\" className={`${config.accent} gap-1.5 text-white hover:brightness-110`}>\n <Link href={config.createHref}>\n <Plus className=\"h-3.5 w-3.5\" />\n {config.createLabel}\n </Link>\n </Button>\n );\n const iconTile = (\n <div className={`flex h-16 w-16 items-center justify-center rounded-2xl ${config.tint}`}>\n <Icon className=\"h-8 w-8\" />\n </div>\n );\n\n return (\n <div className=\"mx-auto max-w-5xl space-y-10 pb-16\">\n <section className=\"px-4 pt-10\">\n <BackButton />\n <FadeIn>\n <div className=\"mt-6\">\n <ServiceHeader plain icon={<Icon className=\"h-4 w-4 text-white\" />} title={config.title} subtitle={config.subtitle} headerAccessory={createButton} />\n </div>\n </FadeIn>\n </section>\n\n <section className=\"space-y-4 px-4\">\n <div>\n <p className=\"section-label\">{config.sectionLabel}</p>\n <h2 className=\"mt-0.5 text-xl font-bold\">{config.sectionTitle}</h2>\n </div>\n\n {!walletAddress && !walletLoading ? (\n <SignInPrompt icon={iconTile} title=\"Sign in to see your collections\" />\n ) : isLoading || walletLoading ? (\n <div className=\"grid grid-cols-2 gap-4 sm:grid-cols-3 lg:grid-cols-4\">\n {Array.from({ length: 4 }).map((_, i) => <Skeleton key={i} className=\"aspect-square rounded-2xl\" />)}\n </div>\n ) : collections.length === 0 ? (\n <div className=\"bento-cell space-y-4 border-dashed p-12 text-center\">\n <div className=\"flex justify-center\">{iconTile}</div>\n <div className=\"space-y-1\">\n <p className=\"text-sm font-semibold\">{config.empty}</p>\n <p className=\"text-xs text-muted-foreground\">{config.emptyText}</p>\n </div>\n {createButton}\n </div>\n ) : (\n <Stagger className=\"grid grid-cols-2 gap-4 sm:grid-cols-3 lg:grid-cols-4\">\n {collections.map((col) => (\n <StaggerItem key={col.contractAddress}>\n <CollectionCard collection={col} href={collectionHref(\"STARKNET\", col.contractAddress)} />\n </StaggerItem>\n ))}\n </Stagger>\n )}\n </section>\n </div>\n );\n}\n"],"mappings":"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","names":[]}
|
|
@@ -10,7 +10,7 @@ declare const SheetClose: React.ForwardRefExoticComponent<SheetPrimitive.DialogC
|
|
|
10
10
|
declare const SheetPortal: React.FC<SheetPrimitive.DialogPortalProps>;
|
|
11
11
|
declare const SheetOverlay: React.ForwardRefExoticComponent<Omit<SheetPrimitive.DialogOverlayProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
12
12
|
declare const sheetVariants: (props?: ({
|
|
13
|
-
side?: "
|
|
13
|
+
side?: "left" | "right" | "bottom" | "top" | null | undefined;
|
|
14
14
|
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
15
15
|
interface SheetContentProps extends React.ComponentPropsWithoutRef<typeof SheetPrimitive.Content>, VariantProps<typeof sheetVariants> {
|
|
16
16
|
overlayClassName?: string;
|
|
@@ -10,7 +10,7 @@ declare const SheetClose: React.ForwardRefExoticComponent<SheetPrimitive.DialogC
|
|
|
10
10
|
declare const SheetPortal: React.FC<SheetPrimitive.DialogPortalProps>;
|
|
11
11
|
declare const SheetOverlay: React.ForwardRefExoticComponent<Omit<SheetPrimitive.DialogOverlayProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
12
12
|
declare const sheetVariants: (props?: ({
|
|
13
|
-
side?: "
|
|
13
|
+
side?: "left" | "right" | "bottom" | "top" | null | undefined;
|
|
14
14
|
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
15
15
|
interface SheetContentProps extends React.ComponentPropsWithoutRef<typeof SheetPrimitive.Content>, VariantProps<typeof sheetVariants> {
|
|
16
16
|
overlayClassName?: string;
|
|
@@ -45,16 +45,17 @@ var import_motion_primitives = require("./motion-primitives.js");
|
|
|
45
45
|
var import_reward_earned = require("./rewards/reward-earned.js");
|
|
46
46
|
var import_service_header = require("./service-header.js");
|
|
47
47
|
var import_transaction_dialog = require("./transaction-dialog.js");
|
|
48
|
-
var
|
|
48
|
+
var import_transaction_success = require("./transaction-success.js");
|
|
49
49
|
var import_address = require("../utils/address.js");
|
|
50
50
|
var import_run_intent_calls = require("../utils/run-intent-calls.js");
|
|
51
51
|
var import_use_image_url = require("../utils/use-image-url.js");
|
|
52
52
|
var import_use_sponsorship = require("../utils/use-sponsorship.js");
|
|
53
53
|
var import_use_tokens = require("../utils/use-tokens.js");
|
|
54
54
|
var import_use_transaction = require("../utils/use-transaction.js");
|
|
55
|
+
var import_success_messages = require("../utils/success-messages.js");
|
|
55
56
|
const COPY = {
|
|
56
|
-
bid: { title: "Place bid", working: "Placing your bid\u2026",
|
|
57
|
-
accept: { title: "Accept bid", working: "Accepting the bid\u2026",
|
|
57
|
+
bid: { title: "Place bid", working: "Placing your bid\u2026", message: import_success_messages.successMessages.bidPlaced() },
|
|
58
|
+
accept: { title: "Accept bid", working: "Accepting the bid\u2026", message: import_success_messages.successMessages.bidAccepted() }
|
|
58
59
|
};
|
|
59
60
|
function SponsorshipOfferPage({ offerId }) {
|
|
60
61
|
const app = (0, import_medialane_app.useMedialaneApp)();
|
|
@@ -110,13 +111,13 @@ function SponsorshipOfferPage({ offerId }) {
|
|
|
110
111
|
const copy = COPY[action];
|
|
111
112
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "pb-16", children: [
|
|
112
113
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_transaction_dialog.TransactionDialog, { tx, title: copy.title, workingLabel: copy.working, firstStepLabel: "Prepare", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
113
|
-
|
|
114
|
+
import_transaction_success.TransactionSuccess,
|
|
114
115
|
{
|
|
115
|
-
tx,
|
|
116
116
|
name,
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
117
|
+
...copy.message,
|
|
118
|
+
txHash: tx.txHash,
|
|
119
|
+
actions: [{ label: "Done", onClick: tx.reset }],
|
|
120
|
+
children: action === "bid" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_reward_earned.RewardEarned, { actionType: "place_sponsorship_bid" })
|
|
120
121
|
}
|
|
121
122
|
) }),
|
|
122
123
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", { className: "px-4 pt-10 max-w-3xl mx-auto space-y-6", children: [
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/sponsorship-offer-page.tsx"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useState } from \"react\";\nimport { Handshake, ImageIcon, Loader2 } from \"lucide-react\";\nimport { formatAmount, getTokenByAddress, normalizeAddress } from \"@medialane/sdk\";\nimport { BackButton } from \"./back-button.js\";\nimport { Button } from \"./button.js\";\nimport Image from \"./image.js\";\nimport { Input } from \"./input.js\";\nimport { useMedialaneApp } from \"./medialane-app.js\";\nimport { FadeIn } from \"./motion-primitives.js\";\nimport { RewardEarned } from \"./rewards/reward-earned.js\";\nimport { ServiceHeader } from \"./service-header.js\";\nimport { TransactionDialog } from \"./transaction-dialog.js\";\nimport { TransactionDone } from \"./transaction-done.js\";\nimport { shortenAddress } from \"../utils/address.js\";\nimport { runIntentCalls } from \"../utils/run-intent-calls.js\";\nimport { useImageUrl } from \"../utils/use-image-url.js\";\nimport { useSponsorshipBids, useSponsorshipOffer } from \"../utils/use-sponsorship.js\";\nimport { useToken } from \"../utils/use-tokens.js\";\nimport { useTransaction } from \"../utils/use-transaction.js\";\n\ntype Action = \"bid\" | \"accept\";\n\nconst COPY = {\n bid: { title: \"Place bid\", working: \"Placing your bid…\", done: \"Bid placed!\", description: \"Your bid is now on-chain.\" },\n accept: { title: \"Accept bid\", working: \"Accepting the bid…\", done: \"Bid accepted!\", description: \"The license is minted to the sponsor.\" },\n} as const;\n\nexport function SponsorshipOfferPage({ offerId }: { offerId: string }) {\n const app = useMedialaneApp();\n const walletAddress = app.walletAddress;\n const resolveImage = useImageUrl();\n const { offer, isLoading, mutate: mutateOffer } = useSponsorshipOffer(offerId);\n const { bids, isLoading: bidsLoading, mutate: mutateBids } = useSponsorshipBids(offerId);\n const { token } = useToken(offer?.nftContract ?? \"\", offer?.tokenId ?? \"\");\n const tx = useTransaction();\n const [action, setAction] = useState<Action>(\"bid\");\n const [amount, setAmount] = useState(\"\");\n const [activeSponsor, setActiveSponsor] = useState<string | null>(null);\n\n useEffect(() => {\n if (tx.phase !== \"success\") return;\n setAmount(\"\");\n void Promise.all([mutateOffer(), mutateBids()]);\n }, [tx.phase, mutateOffer, mutateBids]);\n\n if (isLoading) {\n return <div className=\"max-w-3xl mx-auto px-4 pt-24 pb-8 text-center text-sm text-muted-foreground\">Loading offer…</div>;\n }\n if (!offer) {\n return <div className=\"max-w-3xl mx-auto px-4 pt-24 pb-8 text-center text-sm text-muted-foreground\">Offer not found.</div>;\n }\n\n const isOwner = !!walletAddress && normalizeAddress(\"STARKNET\", walletAddress) === normalizeAddress(\"STARKNET\", offer.author);\n const paymentToken = getTokenByAddress(offer.paymentToken);\n const busy = tx.phase === \"preparing\" || tx.phase === \"submitting\" || tx.phase === \"confirming\";\n const name = token?.metadata?.name ?? `Token #${offer.tokenId}`;\n const imageUrl = resolveImage(token?.metadata?.image);\n const minDisplay = paymentToken ? `${formatAmount(offer.minAmount, paymentToken.decimals)} ${paymentToken.symbol}` : offer.minAmount;\n const format = (value: string) => (paymentToken ? `${formatAmount(value, paymentToken.decimals)} ${paymentToken.symbol}` : value);\n\n const placeBid = () => {\n if (!walletAddress || !paymentToken) return;\n setAction(\"bid\");\n void tx.run(async (signer) => {\n const value = BigInt(Math.round(Number(amount) * 10 ** paymentToken.decimals));\n await runIntentCalls(signer, () =>\n app.getClient().api.intents.create(\"sponsorship-bid\", { sponsor: walletAddress, offerId: offer.offerId, amount: value.toString(), paymentToken: offer.paymentToken }),\n );\n });\n };\n\n const acceptBid = (sponsor: string) => {\n if (!walletAddress) return;\n setAction(\"accept\");\n setActiveSponsor(sponsor);\n void tx\n .run(async (signer) => {\n await runIntentCalls(signer, () =>\n app.getClient().api.intents.create(\"sponsorship-bid-accept\", { author: walletAddress, offerId: offer.offerId, sponsor }),\n );\n })\n .finally(() => setActiveSponsor(null));\n };\n\n const copy = COPY[action];\n\n return (\n <div className=\"pb-16\">\n <TransactionDialog tx={tx} title={copy.title} workingLabel={copy.working} firstStepLabel=\"Prepare\">\n <TransactionDone\n tx={tx}\n name={name}\n title={copy.done}\n description={copy.description}\n footer={action === \"bid\" ? <RewardEarned actionType=\"place_sponsorship_bid\" /> : undefined}\n />\n </TransactionDialog>\n\n <section className=\"px-4 pt-10 max-w-3xl mx-auto space-y-6\">\n <BackButton fallbackHref=\"/launchpad/sponsorship\" />\n <FadeIn>\n <ServiceHeader plain icon={<Handshake className=\"h-4 w-4 text-white\" />} title={name} subtitle={offer.open ? \"Open for bids\" : \"Closed\"} />\n </FadeIn>\n\n <FadeIn>\n <div className=\"rounded-2xl border border-border/40 overflow-hidden\">\n <div className=\"relative aspect-square bg-muted/40\">\n {imageUrl ? (\n <Image src={imageUrl} alt={name} fill sizes=\"(min-width: 768px) 768px, 100vw\" className=\"object-cover\" unoptimized />\n ) : (\n <div className=\"h-full w-full flex items-center justify-center\">\n <ImageIcon className=\"h-8 w-8 text-muted-foreground/40\" />\n </div>\n )}\n </div>\n <div className=\"p-5 grid grid-cols-2 sm:grid-cols-4 gap-4 text-sm\">\n <div>\n <p className=\"text-xs text-muted-foreground\">Minimum bid</p>\n <p className=\"font-semibold\">{minDisplay}</p>\n </div>\n <div>\n <p className=\"text-xs text-muted-foreground\">License length</p>\n <p className=\"font-semibold\">{Math.round(Number(offer.duration) / 86400)} days</p>\n </div>\n <div>\n <p className=\"text-xs text-muted-foreground\">Resale royalty</p>\n <p className=\"font-semibold\">{(offer.royaltyBps / 100).toFixed(1)}%</p>\n </div>\n <div>\n <p className=\"text-xs text-muted-foreground\">Owner</p>\n <p className=\"font-semibold\">{shortenAddress(offer.author)}</p>\n </div>\n </div>\n </div>\n </FadeIn>\n\n {!offer.open ? (\n <FadeIn>\n <p className=\"text-sm text-muted-foreground text-center py-6\">This offer is no longer open.</p>\n </FadeIn>\n ) : isOwner ? (\n <FadeIn>\n <div className=\"space-y-3\">\n <p className=\"text-sm font-semibold\">Bids</p>\n {bidsLoading ? (\n <p className=\"text-xs text-muted-foreground\">Loading bids…</p>\n ) : bids.length === 0 ? (\n <p className=\"text-xs text-muted-foreground\">No bids yet.</p>\n ) : (\n <div className=\"space-y-2\">\n {bids.map((bid) => (\n <div key={bid.id} className=\"flex items-center justify-between gap-3 rounded-xl border border-border/30 p-3\">\n <div>\n <p className=\"text-sm font-medium\">{shortenAddress(bid.sponsor)}</p>\n <p className=\"text-xs text-muted-foreground\">{format(bid.amount)}</p>\n </div>\n <Button size=\"sm\" className=\"bg-brand-rose hover:brightness-110 text-white\" disabled={busy} onClick={() => acceptBid(bid.sponsor)}>\n {busy && activeSponsor === bid.sponsor ? <Loader2 className=\"h-3.5 w-3.5 animate-spin\" /> : \"Accept\"}\n </Button>\n </div>\n ))}\n </div>\n )}\n </div>\n </FadeIn>\n ) : (\n <FadeIn>\n <div className=\"space-y-2\">\n <p className=\"text-sm font-semibold\">Place a bid</p>\n <div className=\"flex gap-2\">\n <Input type=\"number\" min={0} step=\"0.01\" placeholder=\"Your bid\" value={amount} onChange={(e) => setAmount(e.target.value)} disabled={busy} />\n <Button className=\"bg-brand-rose hover:brightness-110 text-white shrink-0\" disabled={busy || !walletAddress || !paymentToken || !amount || Number(amount) <= 0} onClick={placeBid}>\n {busy ? <Loader2 className=\"h-4 w-4 animate-spin\" /> : \"Place bid\"}\n </Button>\n </div>\n {!walletAddress && (\n <button type=\"button\" className=\"text-xs text-muted-foreground underline\" onClick={app.onRequireWallet}>\n {app.connectLabel ?? \"Connect\"} to place a bid\n </button>\n )}\n {!paymentToken && <p className=\"text-xs text-destructive\">This offer uses a currency the app does not support yet.</p>}\n <p className=\"text-xs text-muted-foreground\">\n Placing a bid approves the offer's payment token — no funds move until the owner accepts.\n </p>\n </div>\n </FadeIn>\n )}\n </section>\n </div>\n );\n}\n"],"mappings":"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","names":["Image"]}
|
|
1
|
+
{"version":3,"sources":["../../src/components/sponsorship-offer-page.tsx"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useState } from \"react\";\nimport { Handshake, ImageIcon, Loader2 } from \"lucide-react\";\nimport { formatAmount, getTokenByAddress, normalizeAddress } from \"@medialane/sdk\";\nimport { BackButton } from \"./back-button.js\";\nimport { Button } from \"./button.js\";\nimport Image from \"./image.js\";\nimport { Input } from \"./input.js\";\nimport { useMedialaneApp } from \"./medialane-app.js\";\nimport { FadeIn } from \"./motion-primitives.js\";\nimport { RewardEarned } from \"./rewards/reward-earned.js\";\nimport { ServiceHeader } from \"./service-header.js\";\nimport { TransactionDialog } from \"./transaction-dialog.js\";\nimport { TransactionSuccess } from \"./transaction-success.js\";\nimport { shortenAddress } from \"../utils/address.js\";\nimport { runIntentCalls } from \"../utils/run-intent-calls.js\";\nimport { useImageUrl } from \"../utils/use-image-url.js\";\nimport { useSponsorshipBids, useSponsorshipOffer } from \"../utils/use-sponsorship.js\";\nimport { useToken } from \"../utils/use-tokens.js\";\nimport { useTransaction } from \"../utils/use-transaction.js\";\nimport { successMessages } from \"../utils/success-messages.js\";\n\ntype Action = \"bid\" | \"accept\";\n\nconst COPY = {\n bid: { title: \"Place bid\", working: \"Placing your bid…\", message: successMessages.bidPlaced() },\n accept: { title: \"Accept bid\", working: \"Accepting the bid…\", message: successMessages.bidAccepted() },\n} as const;\n\nexport function SponsorshipOfferPage({ offerId }: { offerId: string }) {\n const app = useMedialaneApp();\n const walletAddress = app.walletAddress;\n const resolveImage = useImageUrl();\n const { offer, isLoading, mutate: mutateOffer } = useSponsorshipOffer(offerId);\n const { bids, isLoading: bidsLoading, mutate: mutateBids } = useSponsorshipBids(offerId);\n const { token } = useToken(offer?.nftContract ?? \"\", offer?.tokenId ?? \"\");\n const tx = useTransaction();\n const [action, setAction] = useState<Action>(\"bid\");\n const [amount, setAmount] = useState(\"\");\n const [activeSponsor, setActiveSponsor] = useState<string | null>(null);\n\n useEffect(() => {\n if (tx.phase !== \"success\") return;\n setAmount(\"\");\n void Promise.all([mutateOffer(), mutateBids()]);\n }, [tx.phase, mutateOffer, mutateBids]);\n\n if (isLoading) {\n return <div className=\"max-w-3xl mx-auto px-4 pt-24 pb-8 text-center text-sm text-muted-foreground\">Loading offer…</div>;\n }\n if (!offer) {\n return <div className=\"max-w-3xl mx-auto px-4 pt-24 pb-8 text-center text-sm text-muted-foreground\">Offer not found.</div>;\n }\n\n const isOwner = !!walletAddress && normalizeAddress(\"STARKNET\", walletAddress) === normalizeAddress(\"STARKNET\", offer.author);\n const paymentToken = getTokenByAddress(offer.paymentToken);\n const busy = tx.phase === \"preparing\" || tx.phase === \"submitting\" || tx.phase === \"confirming\";\n const name = token?.metadata?.name ?? `Token #${offer.tokenId}`;\n const imageUrl = resolveImage(token?.metadata?.image);\n const minDisplay = paymentToken ? `${formatAmount(offer.minAmount, paymentToken.decimals)} ${paymentToken.symbol}` : offer.minAmount;\n const format = (value: string) => (paymentToken ? `${formatAmount(value, paymentToken.decimals)} ${paymentToken.symbol}` : value);\n\n const placeBid = () => {\n if (!walletAddress || !paymentToken) return;\n setAction(\"bid\");\n void tx.run(async (signer) => {\n const value = BigInt(Math.round(Number(amount) * 10 ** paymentToken.decimals));\n await runIntentCalls(signer, () =>\n app.getClient().api.intents.create(\"sponsorship-bid\", { sponsor: walletAddress, offerId: offer.offerId, amount: value.toString(), paymentToken: offer.paymentToken }),\n );\n });\n };\n\n const acceptBid = (sponsor: string) => {\n if (!walletAddress) return;\n setAction(\"accept\");\n setActiveSponsor(sponsor);\n void tx\n .run(async (signer) => {\n await runIntentCalls(signer, () =>\n app.getClient().api.intents.create(\"sponsorship-bid-accept\", { author: walletAddress, offerId: offer.offerId, sponsor }),\n );\n })\n .finally(() => setActiveSponsor(null));\n };\n\n const copy = COPY[action];\n\n return (\n <div className=\"pb-16\">\n <TransactionDialog tx={tx} title={copy.title} workingLabel={copy.working} firstStepLabel=\"Prepare\">\n <TransactionSuccess\n name={name}\n {...copy.message}\n txHash={tx.txHash}\n actions={[{ label: \"Done\", onClick: tx.reset }]}\n >\n {action === \"bid\" && <RewardEarned actionType=\"place_sponsorship_bid\" />}\n </TransactionSuccess>\n </TransactionDialog>\n\n <section className=\"px-4 pt-10 max-w-3xl mx-auto space-y-6\">\n <BackButton fallbackHref=\"/launchpad/sponsorship\" />\n <FadeIn>\n <ServiceHeader plain icon={<Handshake className=\"h-4 w-4 text-white\" />} title={name} subtitle={offer.open ? \"Open for bids\" : \"Closed\"} />\n </FadeIn>\n\n <FadeIn>\n <div className=\"rounded-2xl border border-border/40 overflow-hidden\">\n <div className=\"relative aspect-square bg-muted/40\">\n {imageUrl ? (\n <Image src={imageUrl} alt={name} fill sizes=\"(min-width: 768px) 768px, 100vw\" className=\"object-cover\" unoptimized />\n ) : (\n <div className=\"h-full w-full flex items-center justify-center\">\n <ImageIcon className=\"h-8 w-8 text-muted-foreground/40\" />\n </div>\n )}\n </div>\n <div className=\"p-5 grid grid-cols-2 sm:grid-cols-4 gap-4 text-sm\">\n <div>\n <p className=\"text-xs text-muted-foreground\">Minimum bid</p>\n <p className=\"font-semibold\">{minDisplay}</p>\n </div>\n <div>\n <p className=\"text-xs text-muted-foreground\">License length</p>\n <p className=\"font-semibold\">{Math.round(Number(offer.duration) / 86400)} days</p>\n </div>\n <div>\n <p className=\"text-xs text-muted-foreground\">Resale royalty</p>\n <p className=\"font-semibold\">{(offer.royaltyBps / 100).toFixed(1)}%</p>\n </div>\n <div>\n <p className=\"text-xs text-muted-foreground\">Owner</p>\n <p className=\"font-semibold\">{shortenAddress(offer.author)}</p>\n </div>\n </div>\n </div>\n </FadeIn>\n\n {!offer.open ? (\n <FadeIn>\n <p className=\"text-sm text-muted-foreground text-center py-6\">This offer is no longer open.</p>\n </FadeIn>\n ) : isOwner ? (\n <FadeIn>\n <div className=\"space-y-3\">\n <p className=\"text-sm font-semibold\">Bids</p>\n {bidsLoading ? (\n <p className=\"text-xs text-muted-foreground\">Loading bids…</p>\n ) : bids.length === 0 ? (\n <p className=\"text-xs text-muted-foreground\">No bids yet.</p>\n ) : (\n <div className=\"space-y-2\">\n {bids.map((bid) => (\n <div key={bid.id} className=\"flex items-center justify-between gap-3 rounded-xl border border-border/30 p-3\">\n <div>\n <p className=\"text-sm font-medium\">{shortenAddress(bid.sponsor)}</p>\n <p className=\"text-xs text-muted-foreground\">{format(bid.amount)}</p>\n </div>\n <Button size=\"sm\" className=\"bg-brand-rose hover:brightness-110 text-white\" disabled={busy} onClick={() => acceptBid(bid.sponsor)}>\n {busy && activeSponsor === bid.sponsor ? <Loader2 className=\"h-3.5 w-3.5 animate-spin\" /> : \"Accept\"}\n </Button>\n </div>\n ))}\n </div>\n )}\n </div>\n </FadeIn>\n ) : (\n <FadeIn>\n <div className=\"space-y-2\">\n <p className=\"text-sm font-semibold\">Place a bid</p>\n <div className=\"flex gap-2\">\n <Input type=\"number\" min={0} step=\"0.01\" placeholder=\"Your bid\" value={amount} onChange={(e) => setAmount(e.target.value)} disabled={busy} />\n <Button className=\"bg-brand-rose hover:brightness-110 text-white shrink-0\" disabled={busy || !walletAddress || !paymentToken || !amount || Number(amount) <= 0} onClick={placeBid}>\n {busy ? <Loader2 className=\"h-4 w-4 animate-spin\" /> : \"Place bid\"}\n </Button>\n </div>\n {!walletAddress && (\n <button type=\"button\" className=\"text-xs text-muted-foreground underline\" onClick={app.onRequireWallet}>\n {app.connectLabel ?? \"Connect\"} to place a bid\n </button>\n )}\n {!paymentToken && <p className=\"text-xs text-destructive\">This offer uses a currency the app does not support yet.</p>}\n <p className=\"text-xs text-muted-foreground\">\n Placing a bid approves the offer's payment token — no funds move until the owner accepts.\n </p>\n </div>\n </FadeIn>\n )}\n </section>\n </div>\n );\n}\n"],"mappings":"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","names":["Image"]}
|