@medialane/ui 0.258.0 → 0.259.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/comments-section.cjs +5 -4
- package/dist/components/comments-section.cjs.map +1 -1
- package/dist/components/comments-section.js +5 -4
- package/dist/components/comments-section.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 +0 -30
- 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 +1 -30
- package/dist/components/marketplace-dialog-primitives.js.map +1 -1
- package/dist/components/pop-claim-button.cjs +5 -4
- package/dist/components/pop-claim-button.cjs.map +1 -1
- package/dist/components/pop-claim-button.js +5 -4
- package/dist/components/pop-claim-button.js.map +1 -1
- package/dist/components/pop-manage-page.cjs +2 -2
- package/dist/components/pop-manage-page.cjs.map +1 -1
- package/dist/components/pop-manage-page.js +2 -2
- package/dist/components/pop-manage-page.js.map +1 -1
- package/dist/components/portfolio-sponsorships.cjs +2 -2
- package/dist/components/portfolio-sponsorships.cjs.map +1 -1
- package/dist/components/portfolio-sponsorships.js +2 -2
- package/dist/components/portfolio-sponsorships.js.map +1 -1
- package/dist/components/sponsorship-offer-page.cjs +5 -4
- package/dist/components/sponsorship-offer-page.cjs.map +1 -1
- package/dist/components/sponsorship-offer-page.js +5 -4
- package/dist/components/sponsorship-offer-page.js.map +1 -1
- package/dist/components/{creation-success.cjs → transaction-success.cjs} +14 -15
- 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/{creation-success.js → transaction-success.js} +10 -11
- package/dist/components/transaction-success.js.map +1 -0
- package/dist/components/transfer-collection-ownership.cjs +5 -4
- package/dist/components/transfer-collection-ownership.cjs.map +1 -1
- package/dist/components/transfer-collection-ownership.js +5 -4
- package/dist/components/transfer-collection-ownership.js.map +1 -1
- package/dist/index.cjs +6 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +4 -6
- package/dist/index.js.map +1 -1
- package/dist/utils/success-messages.cjs +54 -0
- package/dist/utils/success-messages.cjs.map +1 -0
- package/dist/utils/success-messages.d.cts +31 -0
- package/dist/utils/success-messages.d.ts +31 -0
- package/dist/utils/success-messages.js +30 -0
- package/dist/utils/success-messages.js.map +1 -0
- package/package.json +3 -3
- 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.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
|
@@ -11,7 +11,7 @@ import { FadeIn } from "./motion-primitives.js";
|
|
|
11
11
|
import { Skeleton } from "./skeleton.js";
|
|
12
12
|
import { Textarea } from "./textarea.js";
|
|
13
13
|
import { TransactionDialog } from "./transaction-dialog.js";
|
|
14
|
-
import {
|
|
14
|
+
import { TransactionSuccess } from "./transaction-success.js";
|
|
15
15
|
import { WalletRequired } from "./wallet-required.js";
|
|
16
16
|
import { runIntentCalls } from "../utils/run-intent-calls.js";
|
|
17
17
|
import { useCollection } from "../utils/use-collections.js";
|
|
@@ -159,7 +159,7 @@ function PopManagePage({ contract }) {
|
|
|
159
159
|
/* @__PURE__ */ jsx("p", { className: "text-muted-foreground", children: "You are not the organizer of this event." }),
|
|
160
160
|
/* @__PURE__ */ jsx(Button, { asChild: true, variant: "outline", size: "sm", children: /* @__PURE__ */ jsx(Link, { href: "/launchpad/pop", children: "\u2190 Back to events" }) })
|
|
161
161
|
] }) : /* @__PURE__ */ jsxs("div", { className: "max-w-xl mx-auto px-4 pt-10 pb-16 space-y-6", children: [
|
|
162
|
-
/* @__PURE__ */ jsx(TransactionDialog, { tx, title: "Manage event", workingLabel: "Updating your event\u2026", firstStepLabel: "Prepare", children: /* @__PURE__ */ jsx(
|
|
162
|
+
/* @__PURE__ */ jsx(TransactionDialog, { tx, title: "Manage event", workingLabel: "Updating your event\u2026", firstStepLabel: "Prepare", children: /* @__PURE__ */ jsx(TransactionSuccess, { name: collection.name ?? "Event", title: done.title, description: done.description, txHash: tx.txHash, actions: [{ label: "Done", onClick: tx.reset }] }) }),
|
|
163
163
|
/* @__PURE__ */ jsx(FadeIn, { children: /* @__PURE__ */ jsx(Button, { asChild: true, variant: "ghost", size: "sm", className: "-ml-2", children: /* @__PURE__ */ jsxs(Link, { href: "/launchpad/pop", children: [
|
|
164
164
|
/* @__PURE__ */ jsx(ArrowLeft, { className: "h-3.5 w-3.5 mr-1.5" }),
|
|
165
165
|
"All events"
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/pop-manage-page.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState } from \"react\";\nimport { normalizeAddress } from \"@medialane/sdk\";\nimport { buildPopAllowlist, popClaimLinks, popClaimLinksCsv, type PopClaimLink } from \"@medialane/sdk/starknet\";\nimport { ArrowLeft, Award, AlertCircle, CheckCircle2, Download, Loader2, Send, Users } from \"lucide-react\";\nimport { Button } from \"./button.js\";\nimport Link from \"./link.js\";\nimport { useMedialaneApp } from \"./medialane-app.js\";\nimport { FadeIn } from \"./motion-primitives.js\";\nimport { Skeleton } from \"./skeleton.js\";\nimport { Textarea } from \"./textarea.js\";\nimport { TransactionDialog } from \"./transaction-dialog.js\";\nimport { TransactionDone } from \"./transaction-done.js\";\nimport { WalletRequired } from \"./wallet-required.js\";\nimport { runIntentCalls } from \"../utils/run-intent-calls.js\";\nimport { useCollection } from \"../utils/use-collections.js\";\nimport { useTransaction } from \"../utils/use-transaction.js\";\n\nfunction parseAddresses(raw: string): string[] {\n return raw\n .split(/[\\n,\\s]+/)\n .map((a) => a.trim())\n .filter((a) => /^0x[0-9a-fA-F]+$/.test(a));\n}\n\nfunction downloadCsv(links: PopClaimLink[]) {\n const href = URL.createObjectURL(new Blob([popClaimLinksCsv(links)], { type: \"text/csv\" }));\n const anchor = Object.assign(document.createElement(\"a\"), { href, download: \"claim-links.csv\" });\n anchor.click();\n URL.revokeObjectURL(href);\n}\n\nfunction IssueSection({\n onIssue,\n isSubmitting,\n}: {\n onIssue: (address: string) => void;\n isSubmitting: boolean;\n}) {\n const [raw, setRaw] = useState(\"\");\n const address = raw.trim();\n const valid = /^0x[0-9a-fA-F]{1,64}$/.test(address);\n\n return (\n <div className=\"bento-cell p-5 space-y-3\">\n <div className=\"flex items-center gap-2\">\n <Award className=\"h-4 w-4 text-green-500\" />\n <span className=\"font-semibold text-sm\">Issue directly</span>\n </div>\n <p className=\"text-xs text-muted-foreground\">\n Send the credential straight to one wallet — for a late participant, without republishing the list or\n changing anyone's claim link.\n </p>\n <input\n type=\"text\"\n placeholder=\"0x...\"\n value={raw}\n onChange={(e) => setRaw(e.target.value)}\n className=\"w-full rounded-lg border border-border bg-background px-3 py-2 text-sm tabular-nums placeholder:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-ring\"\n />\n <Button\n size=\"sm\"\n variant=\"outline\"\n className=\"w-full\"\n disabled={!valid || isSubmitting}\n onClick={() => {\n onIssue(address);\n setRaw(\"\");\n }}\n >\n <Send className=\"h-3.5 w-3.5 mr-1.5\" />\n Issue credential\n </Button>\n </div>\n );\n}\n\nfunction AllowlistSection({\n onPublish,\n isSubmitting,\n links,\n}: {\n onPublish: (addresses: string[]) => void;\n isSubmitting: boolean;\n links: PopClaimLink[] | null;\n}) {\n const [raw, setRaw] = useState(\"\");\n const parsed = parseAddresses(raw);\n\n return (\n <div className=\"bento-cell p-5 space-y-3\">\n <div className=\"flex items-center gap-2\">\n <Users className=\"h-4 w-4 text-green-500\" />\n <span className=\"font-semibold text-sm\">Participants</span>\n {parsed.length > 0 && (\n <span className=\"ml-auto text-xs text-muted-foreground\">\n {parsed.length} address{parsed.length !== 1 ? \"es\" : \"\"}\n </span>\n )}\n </div>\n <p className=\"text-xs text-muted-foreground\">\n Paste every participant's wallet address. Publishing replaces the previous list and every link\n sent before it — send the new links to everyone who hasn't claimed yet. The list stays in this\n browser: download the claim links and send each participant theirs.\n </p>\n <Textarea\n placeholder={\"Paste Starknet addresses, one per line:\\n0x04a...\\n0x06b...\"}\n rows={8}\n value={raw}\n onChange={(e) => setRaw(e.target.value)}\n className=\"tabular-nums text-xs resize-none\"\n />\n <Button\n size=\"sm\"\n className=\"w-full bg-green-600 hover:bg-green-700 text-white\"\n disabled={parsed.length === 0 || isSubmitting}\n onClick={() => onPublish(parsed)}\n >\n {isSubmitting ? (\n <>\n <Loader2 className=\"h-3.5 w-3.5 animate-spin mr-1.5\" />\n Publishing…\n </>\n ) : (\n <>\n <CheckCircle2 className=\"h-3.5 w-3.5 mr-1.5\" />\n Publish {parsed.length > 0 ? `${parsed.length} participant${parsed.length !== 1 ? \"s\" : \"\"}` : \"participants\"}\n </>\n )}\n </Button>\n {links && (\n <div className=\"space-y-2 pt-2\">\n <Button variant=\"outline\" size=\"sm\" className=\"w-full\" onClick={() => downloadCsv(links)}>\n <Download className=\"h-3.5 w-3.5 mr-1.5\" />\n Download claim links (CSV)\n </Button>\n <ul className=\"max-h-48 overflow-auto text-xs tabular-nums space-y-1 text-muted-foreground\">\n {links.map((link) => (\n <li key={link.address} className=\"truncate\">{link.address}</li>\n ))}\n </ul>\n </div>\n )}\n </div>\n );\n}\n\nexport function PopManagePage({ contract }: { contract: string }) {\n const app = useMedialaneApp();\n const walletAddress = app.walletAddress;\n const { collection, isLoading } = useCollection(contract);\n const tx = useTransaction();\n const [done, setDone] = useState({ title: \"\", description: \"\" });\n const [links, setLinks] = useState<PopClaimLink[] | null>(null);\n const isSubmitting = tx.phase === \"preparing\" || tx.phase === \"submitting\" || tx.phase === \"confirming\";\n\n const isOwner =\n walletAddress &&\n collection?.owner &&\n normalizeAddress(\"STARKNET\", walletAddress) === normalizeAddress(\"STARKNET\", collection.owner);\n\n const issue = (recipient: string) => {\n setDone({ title: \"Credential issued\", description: \"The credential is now in their wallet.\" });\n void tx.run(async (signer) => {\n await runIntentCalls(signer, () => app.getClient().api.intents.create(\"pop-manage\", { owner: signer.address, collection: contract, action: \"issue\", recipient }));\n });\n };\n\n const publish = (addresses: string[]) => {\n const list = buildPopAllowlist(addresses);\n const count = Object.keys(list.proofs).length;\n setDone({ title: \"Participants published\", description: `Published ${count} participant${count !== 1 ? \"s\" : \"\"}.` });\n void tx\n .run(async (signer) => {\n await runIntentCalls(signer, () => app.getClient().api.intents.create(\"pop-manage\", { owner: signer.address, collection: contract, action: \"set_allowlist_root\", root: list.root }));\n })\n .then((ok) => {\n if (ok) setLinks(popClaimLinks(window.location.origin, contract, list));\n });\n };\n\n return (\n <WalletRequired icon={Award} title=\"Connect your wallet\" description=\"Connect to manage your event.\">\n {isLoading ? (\n <div className=\"max-w-xl mx-auto px-4 pt-10 pb-16 space-y-4\">\n <Skeleton className=\"h-6 w-24\" />\n <Skeleton className=\"h-32 w-full rounded-2xl\" />\n <Skeleton className=\"h-64 w-full rounded-2xl\" />\n </div>\n ) : !collection ? (\n <div className=\"max-w-xl mx-auto px-4 pt-24 pb-8 text-center space-y-4\">\n <AlertCircle className=\"h-10 w-10 text-muted-foreground/20 mx-auto\" />\n <p className=\"text-muted-foreground\">Collection not found.</p>\n <Button asChild variant=\"outline\" size=\"sm\">\n <Link href=\"/launchpad/pop\">← Back</Link>\n </Button>\n </div>\n ) : !isOwner ? (\n <div className=\"max-w-xl mx-auto px-4 pt-24 pb-8 text-center space-y-4\">\n <Award className=\"h-10 w-10 text-muted-foreground/20 mx-auto\" />\n <p className=\"text-muted-foreground\">You are not the organizer of this event.</p>\n <Button asChild variant=\"outline\" size=\"sm\">\n <Link href=\"/launchpad/pop\">← Back to events</Link>\n </Button>\n </div>\n ) : (\n <div className=\"max-w-xl mx-auto px-4 pt-10 pb-16 space-y-6\">\n <TransactionDialog tx={tx} title=\"Manage event\" workingLabel=\"Updating your event…\" firstStepLabel=\"Prepare\">\n <TransactionDone tx={tx} name={collection.name ?? \"Event\"} title={done.title} description={done.description} />\n </TransactionDialog>\n\n <FadeIn>\n <Button asChild variant=\"ghost\" size=\"sm\" className=\"-ml-2\">\n <Link href=\"/launchpad/pop\">\n <ArrowLeft className=\"h-3.5 w-3.5 mr-1.5\" />\n All events\n </Link>\n </Button>\n </FadeIn>\n\n <FadeIn delay={0.04}>\n <div>\n <span className=\"pill-badge inline-flex gap-1.5 mb-2\">\n <Award className=\"h-3 w-3\" />\n Organizer\n </span>\n <h1 className=\"text-2xl font-bold mt-1\">Manage Event</h1>\n <p className=\"text-sm text-muted-foreground\">{collection.name ?? contract}</p>\n </div>\n </FadeIn>\n\n <FadeIn delay={0.08}>\n <div className=\"bento-cell p-4 flex items-center gap-3\">\n <Award className=\"h-4 w-4 text-green-500 shrink-0\" />\n <p className=\"text-xs text-muted-foreground\">\n Only participants on your <strong className=\"text-foreground\">published list</strong> can claim,\n with the link you send them.\n </p>\n </div>\n </FadeIn>\n\n <FadeIn delay={0.12}>\n <AllowlistSection onPublish={publish} isSubmitting={isSubmitting} links={links} />\n </FadeIn>\n\n <FadeIn delay={0.16}>\n <IssueSection onIssue={issue} isSubmitting={isSubmitting} />\n </FadeIn>\n </div>\n )}\n </WalletRequired>\n );\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/components/pop-manage-page.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState } from \"react\";\nimport { normalizeAddress } from \"@medialane/sdk\";\nimport { buildPopAllowlist, popClaimLinks, popClaimLinksCsv, type PopClaimLink } from \"@medialane/sdk/starknet\";\nimport { ArrowLeft, Award, AlertCircle, CheckCircle2, Download, Loader2, Send, Users } from \"lucide-react\";\nimport { Button } from \"./button.js\";\nimport Link from \"./link.js\";\nimport { useMedialaneApp } from \"./medialane-app.js\";\nimport { FadeIn } from \"./motion-primitives.js\";\nimport { Skeleton } from \"./skeleton.js\";\nimport { Textarea } from \"./textarea.js\";\nimport { TransactionDialog } from \"./transaction-dialog.js\";\nimport { TransactionSuccess } from \"./transaction-success.js\";\nimport { WalletRequired } from \"./wallet-required.js\";\nimport { runIntentCalls } from \"../utils/run-intent-calls.js\";\nimport { useCollection } from \"../utils/use-collections.js\";\nimport { useTransaction } from \"../utils/use-transaction.js\";\n\nfunction parseAddresses(raw: string): string[] {\n return raw\n .split(/[\\n,\\s]+/)\n .map((a) => a.trim())\n .filter((a) => /^0x[0-9a-fA-F]+$/.test(a));\n}\n\nfunction downloadCsv(links: PopClaimLink[]) {\n const href = URL.createObjectURL(new Blob([popClaimLinksCsv(links)], { type: \"text/csv\" }));\n const anchor = Object.assign(document.createElement(\"a\"), { href, download: \"claim-links.csv\" });\n anchor.click();\n URL.revokeObjectURL(href);\n}\n\nfunction IssueSection({\n onIssue,\n isSubmitting,\n}: {\n onIssue: (address: string) => void;\n isSubmitting: boolean;\n}) {\n const [raw, setRaw] = useState(\"\");\n const address = raw.trim();\n const valid = /^0x[0-9a-fA-F]{1,64}$/.test(address);\n\n return (\n <div className=\"bento-cell p-5 space-y-3\">\n <div className=\"flex items-center gap-2\">\n <Award className=\"h-4 w-4 text-green-500\" />\n <span className=\"font-semibold text-sm\">Issue directly</span>\n </div>\n <p className=\"text-xs text-muted-foreground\">\n Send the credential straight to one wallet — for a late participant, without republishing the list or\n changing anyone's claim link.\n </p>\n <input\n type=\"text\"\n placeholder=\"0x...\"\n value={raw}\n onChange={(e) => setRaw(e.target.value)}\n className=\"w-full rounded-lg border border-border bg-background px-3 py-2 text-sm tabular-nums placeholder:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-ring\"\n />\n <Button\n size=\"sm\"\n variant=\"outline\"\n className=\"w-full\"\n disabled={!valid || isSubmitting}\n onClick={() => {\n onIssue(address);\n setRaw(\"\");\n }}\n >\n <Send className=\"h-3.5 w-3.5 mr-1.5\" />\n Issue credential\n </Button>\n </div>\n );\n}\n\nfunction AllowlistSection({\n onPublish,\n isSubmitting,\n links,\n}: {\n onPublish: (addresses: string[]) => void;\n isSubmitting: boolean;\n links: PopClaimLink[] | null;\n}) {\n const [raw, setRaw] = useState(\"\");\n const parsed = parseAddresses(raw);\n\n return (\n <div className=\"bento-cell p-5 space-y-3\">\n <div className=\"flex items-center gap-2\">\n <Users className=\"h-4 w-4 text-green-500\" />\n <span className=\"font-semibold text-sm\">Participants</span>\n {parsed.length > 0 && (\n <span className=\"ml-auto text-xs text-muted-foreground\">\n {parsed.length} address{parsed.length !== 1 ? \"es\" : \"\"}\n </span>\n )}\n </div>\n <p className=\"text-xs text-muted-foreground\">\n Paste every participant's wallet address. Publishing replaces the previous list and every link\n sent before it — send the new links to everyone who hasn't claimed yet. The list stays in this\n browser: download the claim links and send each participant theirs.\n </p>\n <Textarea\n placeholder={\"Paste Starknet addresses, one per line:\\n0x04a...\\n0x06b...\"}\n rows={8}\n value={raw}\n onChange={(e) => setRaw(e.target.value)}\n className=\"tabular-nums text-xs resize-none\"\n />\n <Button\n size=\"sm\"\n className=\"w-full bg-green-600 hover:bg-green-700 text-white\"\n disabled={parsed.length === 0 || isSubmitting}\n onClick={() => onPublish(parsed)}\n >\n {isSubmitting ? (\n <>\n <Loader2 className=\"h-3.5 w-3.5 animate-spin mr-1.5\" />\n Publishing…\n </>\n ) : (\n <>\n <CheckCircle2 className=\"h-3.5 w-3.5 mr-1.5\" />\n Publish {parsed.length > 0 ? `${parsed.length} participant${parsed.length !== 1 ? \"s\" : \"\"}` : \"participants\"}\n </>\n )}\n </Button>\n {links && (\n <div className=\"space-y-2 pt-2\">\n <Button variant=\"outline\" size=\"sm\" className=\"w-full\" onClick={() => downloadCsv(links)}>\n <Download className=\"h-3.5 w-3.5 mr-1.5\" />\n Download claim links (CSV)\n </Button>\n <ul className=\"max-h-48 overflow-auto text-xs tabular-nums space-y-1 text-muted-foreground\">\n {links.map((link) => (\n <li key={link.address} className=\"truncate\">{link.address}</li>\n ))}\n </ul>\n </div>\n )}\n </div>\n );\n}\n\nexport function PopManagePage({ contract }: { contract: string }) {\n const app = useMedialaneApp();\n const walletAddress = app.walletAddress;\n const { collection, isLoading } = useCollection(contract);\n const tx = useTransaction();\n const [done, setDone] = useState({ title: \"\", description: \"\" });\n const [links, setLinks] = useState<PopClaimLink[] | null>(null);\n const isSubmitting = tx.phase === \"preparing\" || tx.phase === \"submitting\" || tx.phase === \"confirming\";\n\n const isOwner =\n walletAddress &&\n collection?.owner &&\n normalizeAddress(\"STARKNET\", walletAddress) === normalizeAddress(\"STARKNET\", collection.owner);\n\n const issue = (recipient: string) => {\n setDone({ title: \"Credential issued\", description: \"The credential is now in their wallet.\" });\n void tx.run(async (signer) => {\n await runIntentCalls(signer, () => app.getClient().api.intents.create(\"pop-manage\", { owner: signer.address, collection: contract, action: \"issue\", recipient }));\n });\n };\n\n const publish = (addresses: string[]) => {\n const list = buildPopAllowlist(addresses);\n const count = Object.keys(list.proofs).length;\n setDone({ title: \"Participants published\", description: `Published ${count} participant${count !== 1 ? \"s\" : \"\"}.` });\n void tx\n .run(async (signer) => {\n await runIntentCalls(signer, () => app.getClient().api.intents.create(\"pop-manage\", { owner: signer.address, collection: contract, action: \"set_allowlist_root\", root: list.root }));\n })\n .then((ok) => {\n if (ok) setLinks(popClaimLinks(window.location.origin, contract, list));\n });\n };\n\n return (\n <WalletRequired icon={Award} title=\"Connect your wallet\" description=\"Connect to manage your event.\">\n {isLoading ? (\n <div className=\"max-w-xl mx-auto px-4 pt-10 pb-16 space-y-4\">\n <Skeleton className=\"h-6 w-24\" />\n <Skeleton className=\"h-32 w-full rounded-2xl\" />\n <Skeleton className=\"h-64 w-full rounded-2xl\" />\n </div>\n ) : !collection ? (\n <div className=\"max-w-xl mx-auto px-4 pt-24 pb-8 text-center space-y-4\">\n <AlertCircle className=\"h-10 w-10 text-muted-foreground/20 mx-auto\" />\n <p className=\"text-muted-foreground\">Collection not found.</p>\n <Button asChild variant=\"outline\" size=\"sm\">\n <Link href=\"/launchpad/pop\">← Back</Link>\n </Button>\n </div>\n ) : !isOwner ? (\n <div className=\"max-w-xl mx-auto px-4 pt-24 pb-8 text-center space-y-4\">\n <Award className=\"h-10 w-10 text-muted-foreground/20 mx-auto\" />\n <p className=\"text-muted-foreground\">You are not the organizer of this event.</p>\n <Button asChild variant=\"outline\" size=\"sm\">\n <Link href=\"/launchpad/pop\">← Back to events</Link>\n </Button>\n </div>\n ) : (\n <div className=\"max-w-xl mx-auto px-4 pt-10 pb-16 space-y-6\">\n <TransactionDialog tx={tx} title=\"Manage event\" workingLabel=\"Updating your event…\" firstStepLabel=\"Prepare\">\n <TransactionSuccess name={collection.name ?? \"Event\"} title={done.title} description={done.description} txHash={tx.txHash} actions={[{ label: \"Done\", onClick: tx.reset }]} />\n </TransactionDialog>\n\n <FadeIn>\n <Button asChild variant=\"ghost\" size=\"sm\" className=\"-ml-2\">\n <Link href=\"/launchpad/pop\">\n <ArrowLeft className=\"h-3.5 w-3.5 mr-1.5\" />\n All events\n </Link>\n </Button>\n </FadeIn>\n\n <FadeIn delay={0.04}>\n <div>\n <span className=\"pill-badge inline-flex gap-1.5 mb-2\">\n <Award className=\"h-3 w-3\" />\n Organizer\n </span>\n <h1 className=\"text-2xl font-bold mt-1\">Manage Event</h1>\n <p className=\"text-sm text-muted-foreground\">{collection.name ?? contract}</p>\n </div>\n </FadeIn>\n\n <FadeIn delay={0.08}>\n <div className=\"bento-cell p-4 flex items-center gap-3\">\n <Award className=\"h-4 w-4 text-green-500 shrink-0\" />\n <p className=\"text-xs text-muted-foreground\">\n Only participants on your <strong className=\"text-foreground\">published list</strong> can claim,\n with the link you send them.\n </p>\n </div>\n </FadeIn>\n\n <FadeIn delay={0.12}>\n <AllowlistSection onPublish={publish} isSubmitting={isSubmitting} links={links} />\n </FadeIn>\n\n <FadeIn delay={0.16}>\n <IssueSection onIssue={issue} isSubmitting={isSubmitting} />\n </FadeIn>\n </div>\n )}\n </WalletRequired>\n );\n}\n"],"mappings":"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","names":[]}
|
|
@@ -42,7 +42,7 @@ var import_link = __toESM(require("./link.js"), 1);
|
|
|
42
42
|
var import_medialane_app = require("./medialane-app.js");
|
|
43
43
|
var import_skeleton = require("./skeleton.js");
|
|
44
44
|
var import_transaction_dialog = require("./transaction-dialog.js");
|
|
45
|
-
var
|
|
45
|
+
var import_transaction_success = require("./transaction-success.js");
|
|
46
46
|
var import_run_intent_calls = require("../utils/run-intent-calls.js");
|
|
47
47
|
var import_use_sponsorship = require("../utils/use-sponsorship.js");
|
|
48
48
|
var import_use_transaction = require("../utils/use-transaction.js");
|
|
@@ -57,7 +57,7 @@ function useRowAction(copy) {
|
|
|
57
57
|
await (0, import_run_intent_calls.runIntentCalls)(signer, () => create(app.getClient().api));
|
|
58
58
|
}).then((ok) => ok ? then() : void 0).finally(() => setActiveId(null));
|
|
59
59
|
};
|
|
60
|
-
const dialog = /* @__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)(
|
|
60
|
+
const dialog = /* @__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)(import_transaction_success.TransactionSuccess, { name: copy.title, title: copy.done, description: copy.description, txHash: tx.txHash, actions: [{ label: "Done", onClick: tx.reset }] }) });
|
|
61
61
|
return { run, dialog, busy, activeId };
|
|
62
62
|
}
|
|
63
63
|
function Spinner({ active, idle, className }) {
|
|
@@ -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":["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 { 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 <TransactionSuccess name={copy.title} title={copy.done} description={copy.description} 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…\", 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":["Link"]}
|
|
@@ -9,7 +9,7 @@ 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
15
|
import { useTransaction } from "../utils/use-transaction.js";
|
|
@@ -24,7 +24,7 @@ function useRowAction(copy) {
|
|
|
24
24
|
await runIntentCalls(signer, () => create(app.getClient().api));
|
|
25
25
|
}).then((ok) => ok ? then() : void 0).finally(() => setActiveId(null));
|
|
26
26
|
};
|
|
27
|
-
const dialog = /* @__PURE__ */ jsx(TransactionDialog, { tx, title: copy.title, workingLabel: copy.working, firstStepLabel: "Prepare", children: /* @__PURE__ */ jsx(
|
|
27
|
+
const dialog = /* @__PURE__ */ jsx(TransactionDialog, { tx, title: copy.title, workingLabel: copy.working, firstStepLabel: "Prepare", children: /* @__PURE__ */ jsx(TransactionSuccess, { name: copy.title, title: copy.done, description: copy.description, txHash: tx.txHash, actions: [{ label: "Done", onClick: tx.reset }] }) });
|
|
28
28
|
return { run, dialog, busy, activeId };
|
|
29
29
|
}
|
|
30
30
|
function Spinner({ active, idle, className }) {
|
|
@@ -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 { 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 <TransactionSuccess name={copy.title} title={copy.done} description={copy.description} 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…\", 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":[]}
|
|
@@ -45,7 +45,7 @@ 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");
|
|
@@ -110,13 +110,14 @@ function SponsorshipOfferPage({ offerId }) {
|
|
|
110
110
|
const copy = COPY[action];
|
|
111
111
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "pb-16", children: [
|
|
112
112
|
/* @__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
|
-
|
|
113
|
+
import_transaction_success.TransactionSuccess,
|
|
114
114
|
{
|
|
115
|
-
tx,
|
|
116
115
|
name,
|
|
117
116
|
title: copy.done,
|
|
118
117
|
description: copy.description,
|
|
119
|
-
|
|
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\";\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 <TransactionSuccess\n name={name}\n title={copy.done}\n description={copy.description}\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"]}
|
|
@@ -12,7 +12,7 @@ import { FadeIn } from "./motion-primitives.js";
|
|
|
12
12
|
import { RewardEarned } from "./rewards/reward-earned.js";
|
|
13
13
|
import { ServiceHeader } from "./service-header.js";
|
|
14
14
|
import { TransactionDialog } from "./transaction-dialog.js";
|
|
15
|
-
import {
|
|
15
|
+
import { TransactionSuccess } from "./transaction-success.js";
|
|
16
16
|
import { shortenAddress } from "../utils/address.js";
|
|
17
17
|
import { runIntentCalls } from "../utils/run-intent-calls.js";
|
|
18
18
|
import { useImageUrl } from "../utils/use-image-url.js";
|
|
@@ -77,13 +77,14 @@ function SponsorshipOfferPage({ offerId }) {
|
|
|
77
77
|
const copy = COPY[action];
|
|
78
78
|
return /* @__PURE__ */ jsxs("div", { className: "pb-16", children: [
|
|
79
79
|
/* @__PURE__ */ jsx(TransactionDialog, { tx, title: copy.title, workingLabel: copy.working, firstStepLabel: "Prepare", children: /* @__PURE__ */ jsx(
|
|
80
|
-
|
|
80
|
+
TransactionSuccess,
|
|
81
81
|
{
|
|
82
|
-
tx,
|
|
83
82
|
name,
|
|
84
83
|
title: copy.done,
|
|
85
84
|
description: copy.description,
|
|
86
|
-
|
|
85
|
+
txHash: tx.txHash,
|
|
86
|
+
actions: [{ label: "Done", onClick: tx.reset }],
|
|
87
|
+
children: action === "bid" && /* @__PURE__ */ jsx(RewardEarned, { actionType: "place_sponsorship_bid" })
|
|
87
88
|
}
|
|
88
89
|
) }),
|
|
89
90
|
/* @__PURE__ */ 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":[]}
|
|
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\";\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 <TransactionSuccess\n name={name}\n title={copy.done}\n description={copy.description}\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":[]}
|