@medialane/ui 0.259.0 → 0.261.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.
Files changed (139) hide show
  1. package/dist/components/action-button.cjs +7 -2
  2. package/dist/components/action-button.cjs.map +1 -1
  3. package/dist/components/action-button.d.cts +2 -1
  4. package/dist/components/action-button.d.ts +2 -1
  5. package/dist/components/action-button.js +7 -2
  6. package/dist/components/action-button.js.map +1 -1
  7. package/dist/components/activities-feed.cjs +5 -1
  8. package/dist/components/activities-feed.cjs.map +1 -1
  9. package/dist/components/activities-feed.js +5 -1
  10. package/dist/components/activities-feed.js.map +1 -1
  11. package/dist/components/activity-feed-shell.cjs +3 -1
  12. package/dist/components/activity-feed-shell.cjs.map +1 -1
  13. package/dist/components/activity-feed-shell.js +3 -1
  14. package/dist/components/activity-feed-shell.js.map +1 -1
  15. package/dist/components/asset-access-cards.cjs +21 -33
  16. package/dist/components/asset-access-cards.cjs.map +1 -1
  17. package/dist/components/asset-access-cards.d.cts +3 -3
  18. package/dist/components/asset-access-cards.d.ts +3 -3
  19. package/dist/components/asset-access-cards.js +20 -32
  20. package/dist/components/asset-access-cards.js.map +1 -1
  21. package/dist/components/asset-marketplace-panel.cjs +44 -41
  22. package/dist/components/asset-marketplace-panel.cjs.map +1 -1
  23. package/dist/components/asset-marketplace-panel.js +45 -42
  24. package/dist/components/asset-marketplace-panel.js.map +1 -1
  25. package/dist/components/asset-overview-content.cjs +12 -1
  26. package/dist/components/asset-overview-content.cjs.map +1 -1
  27. package/dist/components/asset-overview-content.d.cts +3 -1
  28. package/dist/components/asset-overview-content.d.ts +3 -1
  29. package/dist/components/asset-overview-content.js +13 -2
  30. package/dist/components/asset-overview-content.js.map +1 -1
  31. package/dist/components/asset-page.cjs +8 -6
  32. package/dist/components/asset-page.cjs.map +1 -1
  33. package/dist/components/asset-page.js +8 -6
  34. package/dist/components/asset-page.js.map +1 -1
  35. package/dist/components/asset-top-sections.cjs +1 -9
  36. package/dist/components/asset-top-sections.cjs.map +1 -1
  37. package/dist/components/asset-top-sections.d.cts +1 -2
  38. package/dist/components/asset-top-sections.d.ts +1 -2
  39. package/dist/components/asset-top-sections.js +1 -9
  40. package/dist/components/asset-top-sections.js.map +1 -1
  41. package/dist/components/coins-explorer.cjs +5 -1
  42. package/dist/components/coins-explorer.cjs.map +1 -1
  43. package/dist/components/coins-explorer.js +6 -2
  44. package/dist/components/coins-explorer.js.map +1 -1
  45. package/dist/components/comments-section.cjs +2 -2
  46. package/dist/components/comments-section.cjs.map +1 -1
  47. package/dist/components/comments-section.js +2 -2
  48. package/dist/components/comments-section.js.map +1 -1
  49. package/dist/components/discover-community-section.cjs +5 -1
  50. package/dist/components/discover-community-section.cjs.map +1 -1
  51. package/dist/components/discover-community-section.js +5 -1
  52. package/dist/components/discover-community-section.js.map +1 -1
  53. package/dist/components/discover-feed-section.cjs +5 -1
  54. package/dist/components/discover-feed-section.cjs.map +1 -1
  55. package/dist/components/discover-feed-section.js +5 -1
  56. package/dist/components/discover-feed-section.js.map +1 -1
  57. package/dist/components/fast-mint/success-view.cjs +2 -2
  58. package/dist/components/fast-mint/success-view.cjs.map +1 -1
  59. package/dist/components/fast-mint/success-view.js +2 -2
  60. package/dist/components/fast-mint/success-view.js.map +1 -1
  61. package/dist/components/ip-type-page.cjs +3 -2
  62. package/dist/components/ip-type-page.cjs.map +1 -1
  63. package/dist/components/ip-type-page.js +3 -2
  64. package/dist/components/ip-type-page.js.map +1 -1
  65. package/dist/components/markdown-text.cjs +53 -0
  66. package/dist/components/markdown-text.cjs.map +1 -0
  67. package/dist/components/markdown-text.d.cts +7 -0
  68. package/dist/components/markdown-text.d.ts +7 -0
  69. package/dist/components/markdown-text.js +19 -0
  70. package/dist/components/markdown-text.js.map +1 -0
  71. package/dist/components/marketplace-dialog-primitives.cjs +1 -1
  72. package/dist/components/marketplace-dialog-primitives.cjs.map +1 -1
  73. package/dist/components/marketplace-dialog-primitives.js +1 -1
  74. package/dist/components/marketplace-dialog-primitives.js.map +1 -1
  75. package/dist/components/media-wallet/media-wallet-activity.cjs +5 -1
  76. package/dist/components/media-wallet/media-wallet-activity.cjs.map +1 -1
  77. package/dist/components/media-wallet/media-wallet-activity.js +5 -1
  78. package/dist/components/media-wallet/media-wallet-activity.js.map +1 -1
  79. package/dist/components/media-wallet/media-wallet-home.cjs +3 -2
  80. package/dist/components/media-wallet/media-wallet-home.cjs.map +1 -1
  81. package/dist/components/media-wallet/media-wallet-home.js +3 -2
  82. package/dist/components/media-wallet/media-wallet-home.js.map +1 -1
  83. package/dist/components/media-wallet/media-wallet-send.cjs +5 -2
  84. package/dist/components/media-wallet/media-wallet-send.cjs.map +1 -1
  85. package/dist/components/media-wallet/media-wallet-send.js +5 -2
  86. package/dist/components/media-wallet/media-wallet-send.js.map +1 -1
  87. package/dist/components/media-wallet/success-dialog.cjs +5 -11
  88. package/dist/components/media-wallet/success-dialog.cjs.map +1 -1
  89. package/dist/components/media-wallet/success-dialog.js +5 -11
  90. package/dist/components/media-wallet/success-dialog.js.map +1 -1
  91. package/dist/components/pop-claim-button.cjs +2 -2
  92. package/dist/components/pop-claim-button.cjs.map +1 -1
  93. package/dist/components/pop-claim-button.js +2 -2
  94. package/dist/components/pop-claim-button.js.map +1 -1
  95. package/dist/components/pop-manage-page.cjs +3 -2
  96. package/dist/components/pop-manage-page.cjs.map +1 -1
  97. package/dist/components/pop-manage-page.js +3 -2
  98. package/dist/components/pop-manage-page.js.map +1 -1
  99. package/dist/components/portfolio-sponsorships.cjs +14 -7
  100. package/dist/components/portfolio-sponsorships.cjs.map +1 -1
  101. package/dist/components/portfolio-sponsorships.js +14 -7
  102. package/dist/components/portfolio-sponsorships.js.map +1 -1
  103. package/dist/components/service-collections-page.cjs +2 -2
  104. package/dist/components/service-collections-page.cjs.map +1 -1
  105. package/dist/components/service-collections-page.d.cts +2 -2
  106. package/dist/components/service-collections-page.d.ts +2 -2
  107. package/dist/components/service-collections-page.js +2 -2
  108. package/dist/components/service-collections-page.js.map +1 -1
  109. package/dist/components/sponsorship-offer-page.cjs +4 -4
  110. package/dist/components/sponsorship-offer-page.cjs.map +1 -1
  111. package/dist/components/sponsorship-offer-page.js +4 -4
  112. package/dist/components/sponsorship-offer-page.js.map +1 -1
  113. package/dist/components/transaction-success.cjs +2 -5
  114. package/dist/components/transaction-success.cjs.map +1 -1
  115. package/dist/components/transaction-success.js +3 -6
  116. package/dist/components/transaction-success.js.map +1 -1
  117. package/dist/components/transfer-collection-ownership.cjs +2 -5
  118. package/dist/components/transfer-collection-ownership.cjs.map +1 -1
  119. package/dist/components/transfer-collection-ownership.js +2 -5
  120. package/dist/components/transfer-collection-ownership.js.map +1 -1
  121. package/dist/index.cjs +3 -0
  122. package/dist/index.cjs.map +1 -1
  123. package/dist/index.d.cts +1 -0
  124. package/dist/index.d.ts +1 -0
  125. package/dist/index.js +2 -0
  126. package/dist/index.js.map +1 -1
  127. package/dist/utils/empty-messages.cjs +62 -0
  128. package/dist/utils/empty-messages.cjs.map +1 -0
  129. package/dist/utils/empty-messages.d.cts +40 -0
  130. package/dist/utils/empty-messages.d.ts +40 -0
  131. package/dist/utils/empty-messages.js +38 -0
  132. package/dist/utils/empty-messages.js.map +1 -0
  133. package/dist/utils/success-messages.cjs +52 -0
  134. package/dist/utils/success-messages.cjs.map +1 -1
  135. package/dist/utils/success-messages.d.cts +27 -0
  136. package/dist/utils/success-messages.d.ts +27 -0
  137. package/dist/utils/success-messages.js +52 -0
  138. package/dist/utils/success-messages.js.map +1 -1
  139. package/package.json +3 -1
@@ -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 { 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&apos;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&apos;s wallet address. Publishing replaces the previous list and every link\n sent before it — send the new links to everyone who hasn&apos;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":[]}
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 { successMessages } from \"../utils/success-messages.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&apos;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&apos;s wallet address. Publishing replaces the previous list and every link\n sent before it — send the new links to everyone who hasn&apos;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(successMessages.credentialIssued());\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(successMessages.participantsPublished({ count }));\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":";AA+CM,SA0EI,UAzEF,KADF;AA7CN,SAAS,gBAAgB;AACzB,SAAS,wBAAwB;AACjC,SAAS,mBAAmB,eAAe,wBAA2C;AACtF,SAAS,WAAW,OAAO,aAAa,cAAc,UAAU,SAAS,MAAM,aAAa;AAC5F,SAAS,cAAc;AACvB,OAAO,UAAU;AACjB,SAAS,uBAAuB;AAChC,SAAS,cAAc;AACvB,SAAS,gBAAgB;AACzB,SAAS,gBAAgB;AACzB,SAAS,yBAAyB;AAClC,SAAS,0BAA0B;AACnC,SAAS,sBAAsB;AAC/B,SAAS,sBAAsB;AAC/B,SAAS,uBAAuB;AAChC,SAAS,qBAAqB;AAC9B,SAAS,sBAAsB;AAE/B,SAAS,eAAe,KAAuB;AAC7C,SAAO,IACJ,MAAM,UAAU,EAChB,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,EACnB,OAAO,CAAC,MAAM,mBAAmB,KAAK,CAAC,CAAC;AAC7C;AAEA,SAAS,YAAY,OAAuB;AAC1C,QAAM,OAAO,IAAI,gBAAgB,IAAI,KAAK,CAAC,iBAAiB,KAAK,CAAC,GAAG,EAAE,MAAM,WAAW,CAAC,CAAC;AAC1F,QAAM,SAAS,OAAO,OAAO,SAAS,cAAc,GAAG,GAAG,EAAE,MAAM,UAAU,kBAAkB,CAAC;AAC/F,SAAO,MAAM;AACb,MAAI,gBAAgB,IAAI;AAC1B;AAEA,SAAS,aAAa;AAAA,EACpB;AAAA,EACA;AACF,GAGG;AACD,QAAM,CAAC,KAAK,MAAM,IAAI,SAAS,EAAE;AACjC,QAAM,UAAU,IAAI,KAAK;AACzB,QAAM,QAAQ,wBAAwB,KAAK,OAAO;AAElD,SACE,qBAAC,SAAI,WAAU,4BACb;AAAA,yBAAC,SAAI,WAAU,2BACb;AAAA,0BAAC,SAAM,WAAU,0BAAyB;AAAA,MAC1C,oBAAC,UAAK,WAAU,yBAAwB,4BAAc;AAAA,OACxD;AAAA,IACA,oBAAC,OAAE,WAAU,iCAAgC,sJAG7C;AAAA,IACA;AAAA,MAAC;AAAA;AAAA,QACC,MAAK;AAAA,QACL,aAAY;AAAA,QACZ,OAAO;AAAA,QACP,UAAU,CAAC,MAAM,OAAO,EAAE,OAAO,KAAK;AAAA,QACtC,WAAU;AAAA;AAAA,IACZ;AAAA,IACA;AAAA,MAAC;AAAA;AAAA,QACC,MAAK;AAAA,QACL,SAAQ;AAAA,QACR,WAAU;AAAA,QACV,UAAU,CAAC,SAAS;AAAA,QACpB,SAAS,MAAM;AACb,kBAAQ,OAAO;AACf,iBAAO,EAAE;AAAA,QACX;AAAA,QAEA;AAAA,8BAAC,QAAK,WAAU,sBAAqB;AAAA,UAAE;AAAA;AAAA;AAAA,IAEzC;AAAA,KACF;AAEJ;AAEA,SAAS,iBAAiB;AAAA,EACxB;AAAA,EACA;AAAA,EACA;AACF,GAIG;AACD,QAAM,CAAC,KAAK,MAAM,IAAI,SAAS,EAAE;AACjC,QAAM,SAAS,eAAe,GAAG;AAEjC,SACE,qBAAC,SAAI,WAAU,4BACb;AAAA,yBAAC,SAAI,WAAU,2BACb;AAAA,0BAAC,SAAM,WAAU,0BAAyB;AAAA,MAC1C,oBAAC,UAAK,WAAU,yBAAwB,0BAAY;AAAA,MACnD,OAAO,SAAS,KACf,qBAAC,UAAK,WAAU,yCACb;AAAA,eAAO;AAAA,QAAO;AAAA,QAAS,OAAO,WAAW,IAAI,OAAO;AAAA,SACvD;AAAA,OAEJ;AAAA,IACA,oBAAC,OAAE,WAAU,iCAAgC,oRAI7C;AAAA,IACA;AAAA,MAAC;AAAA;AAAA,QACC,aAAa;AAAA,QACb,MAAM;AAAA,QACN,OAAO;AAAA,QACP,UAAU,CAAC,MAAM,OAAO,EAAE,OAAO,KAAK;AAAA,QACtC,WAAU;AAAA;AAAA,IACZ;AAAA,IACA;AAAA,MAAC;AAAA;AAAA,QACC,MAAK;AAAA,QACL,WAAU;AAAA,QACV,UAAU,OAAO,WAAW,KAAK;AAAA,QACjC,SAAS,MAAM,UAAU,MAAM;AAAA,QAE9B,yBACC,iCACE;AAAA,8BAAC,WAAQ,WAAU,mCAAkC;AAAA,UAAE;AAAA,WAEzD,IAEA,iCACE;AAAA,8BAAC,gBAAa,WAAU,sBAAqB;AAAA,UAAE;AAAA,UACtC,OAAO,SAAS,IAAI,GAAG,OAAO,MAAM,eAAe,OAAO,WAAW,IAAI,MAAM,EAAE,KAAK;AAAA,WACjG;AAAA;AAAA,IAEJ;AAAA,IACC,SACC,qBAAC,SAAI,WAAU,kBACb;AAAA,2BAAC,UAAO,SAAQ,WAAU,MAAK,MAAK,WAAU,UAAS,SAAS,MAAM,YAAY,KAAK,GACrF;AAAA,4BAAC,YAAS,WAAU,sBAAqB;AAAA,QAAE;AAAA,SAE7C;AAAA,MACA,oBAAC,QAAG,WAAU,+EACX,gBAAM,IAAI,CAAC,SACV,oBAAC,QAAsB,WAAU,YAAY,eAAK,WAAzC,KAAK,OAA4C,CAC3D,GACH;AAAA,OACF;AAAA,KAEJ;AAEJ;AAEO,SAAS,cAAc,EAAE,SAAS,GAAyB;AAChE,QAAM,MAAM,gBAAgB;AAC5B,QAAM,gBAAgB,IAAI;AAC1B,QAAM,EAAE,YAAY,UAAU,IAAI,cAAc,QAAQ;AACxD,QAAM,KAAK,eAAe;AAC1B,QAAM,CAAC,MAAM,OAAO,IAAI,SAAS,EAAE,OAAO,IAAI,aAAa,GAAG,CAAC;AAC/D,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAgC,IAAI;AAC9D,QAAM,eAAe,GAAG,UAAU,eAAe,GAAG,UAAU,gBAAgB,GAAG,UAAU;AAE3F,QAAM,UACJ,iBACA,YAAY,SACZ,iBAAiB,YAAY,aAAa,MAAM,iBAAiB,YAAY,WAAW,KAAK;AAE/F,QAAM,QAAQ,CAAC,cAAsB;AACnC,YAAQ,gBAAgB,iBAAiB,CAAC;AAC1C,SAAK,GAAG,IAAI,OAAO,WAAW;AAC5B,YAAM,eAAe,QAAQ,MAAM,IAAI,UAAU,EAAE,IAAI,QAAQ,OAAO,cAAc,EAAE,OAAO,OAAO,SAAS,YAAY,UAAU,QAAQ,SAAS,UAAU,CAAC,CAAC;AAAA,IAClK,CAAC;AAAA,EACH;AAEA,QAAM,UAAU,CAAC,cAAwB;AACvC,UAAM,OAAO,kBAAkB,SAAS;AACxC,UAAM,QAAQ,OAAO,KAAK,KAAK,MAAM,EAAE;AACvC,YAAQ,gBAAgB,sBAAsB,EAAE,MAAM,CAAC,CAAC;AACxD,SAAK,GACF,IAAI,OAAO,WAAW;AACrB,YAAM,eAAe,QAAQ,MAAM,IAAI,UAAU,EAAE,IAAI,QAAQ,OAAO,cAAc,EAAE,OAAO,OAAO,SAAS,YAAY,UAAU,QAAQ,sBAAsB,MAAM,KAAK,KAAK,CAAC,CAAC;AAAA,IACrL,CAAC,EACA,KAAK,CAAC,OAAO;AACZ,UAAI,GAAI,UAAS,cAAc,OAAO,SAAS,QAAQ,UAAU,IAAI,CAAC;AAAA,IACxE,CAAC;AAAA,EACL;AAEA,SACE,oBAAC,kBAAe,MAAM,OAAO,OAAM,uBAAsB,aAAY,iCAClE,sBACC,qBAAC,SAAI,WAAU,+CACb;AAAA,wBAAC,YAAS,WAAU,YAAW;AAAA,IAC/B,oBAAC,YAAS,WAAU,2BAA0B;AAAA,IAC9C,oBAAC,YAAS,WAAU,2BAA0B;AAAA,KAChD,IACE,CAAC,aACH,qBAAC,SAAI,WAAU,0DACb;AAAA,wBAAC,eAAY,WAAU,8CAA6C;AAAA,IACpE,oBAAC,OAAE,WAAU,yBAAwB,mCAAqB;AAAA,IAC1D,oBAAC,UAAO,SAAO,MAAC,SAAQ,WAAU,MAAK,MACrC,8BAAC,QAAK,MAAK,kBAAiB,yBAAM,GACpC;AAAA,KACF,IACE,CAAC,UACH,qBAAC,SAAI,WAAU,0DACb;AAAA,wBAAC,SAAM,WAAU,8CAA6C;AAAA,IAC9D,oBAAC,OAAE,WAAU,yBAAwB,sDAAwC;AAAA,IAC7E,oBAAC,UAAO,SAAO,MAAC,SAAQ,WAAU,MAAK,MACrC,8BAAC,QAAK,MAAK,kBAAiB,mCAAgB,GAC9C;AAAA,KACF,IAEA,qBAAC,SAAI,WAAU,+CACb;AAAA,wBAAC,qBAAkB,IAAQ,OAAM,gBAAe,cAAa,6BAAuB,gBAAe,WACjG,8BAAC,sBAAmB,MAAM,WAAW,QAAQ,SAAS,OAAO,KAAK,OAAO,aAAa,KAAK,aAAa,QAAQ,GAAG,QAAQ,SAAS,CAAC,EAAE,OAAO,QAAQ,SAAS,GAAG,MAAM,CAAC,GAAG,GAC9K;AAAA,IAEA,oBAAC,UACC,8BAAC,UAAO,SAAO,MAAC,SAAQ,SAAQ,MAAK,MAAK,WAAU,SAClD,+BAAC,QAAK,MAAK,kBACT;AAAA,0BAAC,aAAU,WAAU,sBAAqB;AAAA,MAAE;AAAA,OAE9C,GACF,GACF;AAAA,IAEA,oBAAC,UAAO,OAAO,MACb,+BAAC,SACC;AAAA,2BAAC,UAAK,WAAU,uCACd;AAAA,4BAAC,SAAM,WAAU,WAAU;AAAA,QAAE;AAAA,SAE/B;AAAA,MACA,oBAAC,QAAG,WAAU,2BAA0B,0BAAY;AAAA,MACpD,oBAAC,OAAE,WAAU,iCAAiC,qBAAW,QAAQ,UAAS;AAAA,OAC5E,GACF;AAAA,IAEA,oBAAC,UAAO,OAAO,MACb,+BAAC,SAAI,WAAU,0CACb;AAAA,0BAAC,SAAM,WAAU,mCAAkC;AAAA,MACnD,qBAAC,OAAE,WAAU,iCAAgC;AAAA;AAAA,QACjB,oBAAC,YAAO,WAAU,mBAAkB,4BAAc;AAAA,QAAS;AAAA,SAEvF;AAAA,OACF,GACF;AAAA,IAEA,oBAAC,UAAO,OAAO,MACb,8BAAC,oBAAiB,WAAW,SAAS,cAA4B,OAAc,GAClF;AAAA,IAEA,oBAAC,UAAO,OAAO,MACb,8BAAC,gBAAa,SAAS,OAAO,cAA4B,GAC5D;AAAA,KACF,GAEJ;AAEJ;","names":[]}
@@ -45,6 +45,8 @@ var import_transaction_dialog = require("./transaction-dialog.js");
45
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
+ var import_empty_messages = require("../utils/empty-messages.js");
49
+ var import_success_messages = require("../utils/success-messages.js");
48
50
  var import_use_transaction = require("../utils/use-transaction.js");
49
51
  function useRowAction(copy) {
50
52
  const app = (0, import_medialane_app.useMedialaneApp)();
@@ -57,7 +59,7 @@ function useRowAction(copy) {
57
59
  await (0, import_run_intent_calls.runIntentCalls)(signer, () => create(app.getClient().api));
58
60
  }).then((ok) => ok ? then() : void 0).finally(() => setActiveId(null));
59
61
  };
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 }] }) });
62
+ 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, ...copy.message, txHash: tx.txHash, actions: [{ label: "Done", onClick: tx.reset }] }) });
61
63
  return { run, dialog, busy, activeId };
62
64
  }
63
65
  function Spinner({ active, idle, className }) {
@@ -66,7 +68,7 @@ function Spinner({ active, idle, className }) {
66
68
  function OfferBidsRow({ offer }) {
67
69
  const { walletAddress } = (0, import_medialane_app.useMedialaneApp)();
68
70
  const { bids, isLoading, mutate } = (0, import_use_sponsorship.useSponsorshipBids)(offer.offerId);
69
- const action = useRowAction({ title: "Accept bid", working: "Accepting the bid\u2026", done: "Bid accepted!", description: "The license is minted to the sponsor." });
71
+ const action = useRowAction({ title: "Accept bid", working: "Accepting the bid\u2026", message: import_success_messages.successMessages.bidAccepted() });
70
72
  if (isLoading || bids.length === 0) return null;
71
73
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "space-y-1.5 rounded-lg bg-muted/30 p-3", children: [
72
74
  action.dialog,
@@ -96,7 +98,7 @@ function OfferBidsRow({ offer }) {
96
98
  }
97
99
  function ReceivedProposals({ walletAddress }) {
98
100
  const { proposals, isLoading, mutate } = (0, import_use_sponsorship.useSponsorshipProposals)({ owner: walletAddress, open: true });
99
- const action = useRowAction({ title: "Respond to proposal", working: "Sending your response\u2026", done: "Response sent!", description: "Your response is now on-chain." });
101
+ const action = useRowAction({ title: "Respond to proposal", working: "Sending your response\u2026", message: import_success_messages.successMessages.responseSent() });
100
102
  if (isLoading) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_skeleton.Skeleton, { className: "h-20 w-full rounded-xl" });
101
103
  if (proposals.length === 0) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-sm text-muted-foreground", children: "No proposals awaiting your decision." });
102
104
  const respond = (proposalId, decision) => action.run(
@@ -124,7 +126,7 @@ function ReceivedProposals({ walletAddress }) {
124
126
  }
125
127
  function SentProposals({ walletAddress }) {
126
128
  const { proposals, isLoading, mutate } = (0, import_use_sponsorship.useSponsorshipProposals)({ proposer: walletAddress, open: true });
127
- const action = useRowAction({ title: "Withdraw proposal", working: "Withdrawing your proposal\u2026", done: "Proposal withdrawn!", description: "Your proposal is no longer open." });
129
+ const action = useRowAction({ title: "Withdraw proposal", working: "Withdrawing your proposal\u2026", message: import_success_messages.successMessages.proposalWithdrawn() });
128
130
  if (isLoading) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_skeleton.Skeleton, { className: "h-20 w-full rounded-xl" });
129
131
  if (proposals.length === 0) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-sm text-muted-foreground", children: "No pending proposals sent." });
130
132
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "space-y-2", children: [
@@ -155,7 +157,12 @@ function SentProposals({ walletAddress }) {
155
157
  }
156
158
  function LicenseList({ loading, empty, children }) {
157
159
  if (loading) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_skeleton.Skeleton, { className: "h-16 w-full rounded-xl" });
158
- if (children.length === 0) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-sm text-muted-foreground", children: empty });
160
+ if (children.length === 0) {
161
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
162
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-sm font-medium", children: empty.title }),
163
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-sm text-muted-foreground", children: empty.description })
164
+ ] });
165
+ }
159
166
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "space-y-2", children });
160
167
  }
161
168
  function PortfolioSponsorships() {
@@ -182,7 +189,7 @@ function PortfolioSponsorships() {
182
189
  ] }),
183
190
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", { className: "space-y-3", children: [
184
191
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h2", { className: "text-sm font-bold", children: "Licenses you hold" }),
185
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(LicenseList, { loading: heldLoading, empty: "No sponsorship licenses yet.", children: held.map((l) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "bento-cell p-4", children: [
192
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(LicenseList, { loading: heldLoading, empty: import_empty_messages.emptyMessages.heldLicenses, children: held.map((l) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "bento-cell p-4", children: [
186
193
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-sm font-semibold", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_link.default, { href: (0, import_sdk.assetHref)("STARKNET", l.assetContract, l.assetTokenId), className: "hover:underline", children: "License on this asset" }) }),
187
194
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { className: "text-xs text-muted-foreground", children: [
188
195
  "from ",
@@ -192,7 +199,7 @@ function PortfolioSponsorships() {
192
199
  ] }),
193
200
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", { className: "space-y-3", children: [
194
201
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h2", { className: "text-sm font-bold", children: "Licenses issued on your work" }),
195
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(LicenseList, { loading: issuedLoading, empty: "No licenses issued yet.", children: issued.map((l) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "bento-cell p-4", children: [
202
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(LicenseList, { loading: issuedLoading, empty: import_empty_messages.emptyMessages.issuedLicenses, children: issued.map((l) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "bento-cell p-4", children: [
196
203
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-sm font-semibold", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_link.default, { href: (0, import_sdk.assetHref)("STARKNET", l.assetContract, l.assetTokenId), className: "hover:underline", children: "License on this asset" }) }),
197
204
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { className: "text-xs text-muted-foreground", children: [
198
205
  "held by ",
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/portfolio-sponsorships.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState } from \"react\";\nimport { CheckCircle2, Handshake, Loader2, X } from \"lucide-react\";\nimport { assetHref, type ApiSponsorshipOffer } from \"@medialane/sdk\";\nimport { AddressDisplay } from \"./address-display.js\";\nimport { Button } from \"./button.js\";\nimport Link from \"./link.js\";\nimport { useMedialaneApp } from \"./medialane-app.js\";\nimport { Skeleton } from \"./skeleton.js\";\nimport { TransactionDialog } from \"./transaction-dialog.js\";\nimport { 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&apos;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 { emptyMessages, type EmptyMessage } from \"../utils/empty-messages.js\";\nimport { successMessages, type SuccessMessage } from \"../utils/success-messages.js\";\nimport { useTransaction } from \"../utils/use-transaction.js\";\n\ntype Api = ReturnType<ReturnType<typeof useMedialaneApp>[\"getClient\"]>[\"api\"];\n\nfunction useRowAction(copy: { title: string; working: string; message: SuccessMessage }) {\n const app = useMedialaneApp();\n const tx = useTransaction();\n const [activeId, setActiveId] = useState<string | null>(null);\n const busy = tx.phase === \"preparing\" || tx.phase === \"submitting\" || tx.phase === \"confirming\";\n\n const run = (id: string, create: (api: Api) => ReturnType<Parameters<typeof runIntentCalls>[1]>, then: () => Promise<unknown>) => {\n setActiveId(id);\n void tx\n .run(async (signer) => {\n await runIntentCalls(signer, () => create(app.getClient().api));\n })\n .then((ok) => (ok ? then() : undefined))\n .finally(() => setActiveId(null));\n };\n\n const dialog = (\n <TransactionDialog tx={tx} title={copy.title} workingLabel={copy.working} firstStepLabel=\"Prepare\">\n <TransactionSuccess name={copy.title} {...copy.message} txHash={tx.txHash} actions={[{ label: \"Done\", onClick: tx.reset }]} />\n </TransactionDialog>\n );\n\n return { run, dialog, busy, activeId };\n}\n\nfunction Spinner({ active, idle, className }: { active: boolean; idle: React.ReactNode; className?: string }) {\n return active ? <Loader2 className={`h-3 w-3 animate-spin ${className ?? \"\"}`} /> : <>{idle}</>;\n}\n\nfunction OfferBidsRow({ offer }: { offer: ApiSponsorshipOffer }) {\n const { walletAddress } = useMedialaneApp();\n const { bids, isLoading, mutate } = useSponsorshipBids(offer.offerId);\n const action = useRowAction({ title: \"Accept bid\", working: \"Accepting the bid…\", message: successMessages.bidAccepted() });\n\n if (isLoading || bids.length === 0) return null;\n\n return (\n <div className=\"space-y-1.5 rounded-lg bg-muted/30 p-3\">\n {action.dialog}\n <p className=\"text-xs font-semibold text-muted-foreground\">\n Bids on <Link href={assetHref(\"STARKNET\", offer.nftContract, offer.tokenId)} className=\"underline underline-offset-2\">View asset</Link>\n </p>\n {bids.map((bid) => (\n <div key={bid.id} className=\"flex items-center justify-between gap-2 text-xs\">\n <AddressDisplay address={bid.sponsor} chars={4} showCopy={false} className=\"text-muted-foreground\" />\n <Button\n size=\"sm\"\n className=\"bg-brand-rose hover:brightness-110 text-white h-7 px-2.5\"\n aria-label=\"Accept bid\"\n disabled={action.busy || !walletAddress}\n onClick={() =>\n action.run(\n bid.id,\n (api) => api.intents.create(\"sponsorship-bid-accept\", { author: walletAddress!, offerId: offer.offerId, sponsor: bid.sponsor }),\n () => mutate(),\n )\n }\n >\n <Spinner active={action.busy && action.activeId === bid.id} idle={<CheckCircle2 className=\"h-3 w-3\" />} />\n </Button>\n </div>\n ))}\n </div>\n );\n}\n\nfunction ReceivedProposals({ walletAddress }: { walletAddress: string }) {\n const { proposals, isLoading, mutate } = useSponsorshipProposals({ owner: walletAddress, open: true });\n const action = useRowAction({ title: \"Respond to proposal\", working: \"Sending your response…\", message: successMessages.responseSent() });\n\n if (isLoading) return <Skeleton className=\"h-20 w-full rounded-xl\" />;\n if (proposals.length === 0) return <p className=\"text-sm text-muted-foreground\">No proposals awaiting your decision.</p>;\n\n const respond = (proposalId: string, decision: \"accept\" | \"reject\") =>\n action.run(\n proposalId,\n (api) =>\n decision === \"accept\"\n ? api.intents.create(\"sponsorship-proposal-accept\", { owner: walletAddress, proposalId })\n : api.intents.create(\"sponsorship-proposal-reject\", { owner: walletAddress, proposalId }),\n () => mutate(),\n );\n\n return (\n <div className=\"space-y-2\">\n {action.dialog}\n {proposals.map((p) => (\n <div key={p.id} className=\"bento-cell p-4 flex items-center justify-between gap-3\">\n <div className=\"min-w-0\">\n <p className=\"text-sm font-semibold\">\n <Link href={assetHref(\"STARKNET\", p.nftContract, p.tokenId)} className=\"hover:underline\">View asset</Link>\n </p>\n <p className=\"text-xs text-muted-foreground\">\n <AddressDisplay address={p.proposer} chars={4} showCopy={false} /> proposed {p.amount}\n </p>\n </div>\n <div className=\"flex gap-1.5 shrink-0\">\n <Button size=\"sm\" variant=\"outline\" aria-label=\"Decline proposal\" disabled={action.busy} onClick={() => respond(p.proposalId, \"reject\")}>\n <Spinner active={action.busy && action.activeId === p.proposalId} idle={<X className=\"h-3 w-3\" />} />\n </Button>\n <Button size=\"sm\" className=\"bg-brand-rose hover:brightness-110 text-white\" aria-label=\"Accept proposal\" disabled={action.busy} onClick={() => respond(p.proposalId, \"accept\")}>\n <Spinner active={action.busy && action.activeId === p.proposalId} idle={<CheckCircle2 className=\"h-3 w-3\" />} />\n </Button>\n </div>\n </div>\n ))}\n </div>\n );\n}\n\nfunction SentProposals({ walletAddress }: { walletAddress: string }) {\n const { proposals, isLoading, mutate } = useSponsorshipProposals({ proposer: walletAddress, open: true });\n const action = useRowAction({ title: \"Withdraw proposal\", working: \"Withdrawing your proposal…\", message: successMessages.proposalWithdrawn() });\n\n if (isLoading) return <Skeleton className=\"h-20 w-full rounded-xl\" />;\n if (proposals.length === 0) return <p className=\"text-sm text-muted-foreground\">No pending proposals sent.</p>;\n\n return (\n <div className=\"space-y-2\">\n {action.dialog}\n {proposals.map((p) => (\n <div key={p.id} className=\"bento-cell p-4 flex items-center justify-between gap-3\">\n <div className=\"min-w-0\">\n <p className=\"text-sm font-semibold\">\n <Link href={assetHref(\"STARKNET\", p.nftContract, p.tokenId)} className=\"hover:underline\">View asset</Link>\n </p>\n <p className=\"text-xs text-muted-foreground\">You proposed {p.amount}</p>\n </div>\n <Button\n size=\"sm\"\n variant=\"outline\"\n disabled={action.busy}\n onClick={() =>\n action.run(p.proposalId, (api) => api.intents.create(\"sponsorship-proposal-withdraw\", { proposer: walletAddress, proposalId: p.proposalId }), () => mutate())\n }\n >\n <Spinner active={action.busy && action.activeId === p.proposalId} idle={null} className=\"mr-1.5\" />\n Withdraw\n </Button>\n </div>\n ))}\n </div>\n );\n}\n\nfunction LicenseList({ loading, empty, children }: { loading: boolean; empty: EmptyMessage; children: React.ReactNode[] }) {\n if (loading) return <Skeleton className=\"h-16 w-full rounded-xl\" />;\n if (children.length === 0) {\n return (\n <div>\n <p className=\"text-sm font-medium\">{empty.title}</p>\n <p className=\"text-sm text-muted-foreground\">{empty.description}</p>\n </div>\n );\n }\n return <div className=\"space-y-2\">{children}</div>;\n}\n\nexport function PortfolioSponsorships() {\n const { walletAddress } = useMedialaneApp();\n const { offers } = useSponsorshipOffers(walletAddress ? { author: walletAddress, open: true } : undefined);\n const { licenses: held, isLoading: heldLoading } = useSponsorshipLicenses(walletAddress ? { holder: walletAddress } : undefined);\n const { licenses: issued, isLoading: issuedLoading } = useSponsorshipLicenses(walletAddress ? { author: walletAddress } : undefined);\n\n if (!walletAddress) return null;\n\n return (\n <div className=\"space-y-8\">\n <section className=\"space-y-3\">\n <h2 className=\"text-sm font-bold flex items-center gap-2\"><Handshake className=\"h-4 w-4 text-brand-rose\" />Proposals awaiting your decision</h2>\n <ReceivedProposals walletAddress={walletAddress} />\n </section>\n\n {offers.length > 0 && (\n <section className=\"space-y-3\">\n <h2 className=\"text-sm font-bold\">Bids on your offers</h2>\n <div className=\"space-y-2\">\n {offers.map((o) => <OfferBidsRow key={o.id} offer={o} />)}\n </div>\n </section>\n )}\n\n <section className=\"space-y-3\">\n <h2 className=\"text-sm font-bold\">Proposals you&apos;ve sent</h2>\n <SentProposals walletAddress={walletAddress} />\n </section>\n\n <section className=\"space-y-3\">\n <h2 className=\"text-sm font-bold\">Licenses you hold</h2>\n <LicenseList loading={heldLoading} empty={emptyMessages.heldLicenses}>\n {held.map((l) => (\n <div key={l.id} className=\"bento-cell p-4\">\n <p className=\"text-sm font-semibold\">\n <Link href={assetHref(\"STARKNET\", l.assetContract, l.assetTokenId)} className=\"hover:underline\">License on this asset</Link>\n </p>\n <p className=\"text-xs text-muted-foreground\">from <AddressDisplay address={l.author} chars={4} showCopy={false} /></p>\n </div>\n ))}\n </LicenseList>\n </section>\n\n <section className=\"space-y-3\">\n <h2 className=\"text-sm font-bold\">Licenses issued on your work</h2>\n <LicenseList loading={issuedLoading} empty={emptyMessages.issuedLicenses}>\n {issued.map((l) => (\n <div key={l.id} className=\"bento-cell p-4\">\n <p className=\"text-sm font-semibold\">\n <Link href={assetHref(\"STARKNET\", l.assetContract, l.assetTokenId)} className=\"hover:underline\">License on this asset</Link>\n </p>\n <p className=\"text-xs text-muted-foreground\">held by <AddressDisplay address={l.currentHolder ?? l.recipient} chars={4} showCopy={false} /></p>\n </div>\n ))}\n </LicenseList>\n </section>\n </div>\n );\n}\n"],"mappings":"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","names":["Link"]}
@@ -12,6 +12,8 @@ import { TransactionDialog } from "./transaction-dialog.js";
12
12
  import { TransactionSuccess } from "./transaction-success.js";
13
13
  import { runIntentCalls } from "../utils/run-intent-calls.js";
14
14
  import { useSponsorshipBids, useSponsorshipLicenses, useSponsorshipOffers, useSponsorshipProposals } from "../utils/use-sponsorship.js";
15
+ import { emptyMessages } from "../utils/empty-messages.js";
16
+ import { successMessages } from "../utils/success-messages.js";
15
17
  import { useTransaction } from "../utils/use-transaction.js";
16
18
  function useRowAction(copy) {
17
19
  const app = useMedialaneApp();
@@ -24,7 +26,7 @@ function useRowAction(copy) {
24
26
  await runIntentCalls(signer, () => create(app.getClient().api));
25
27
  }).then((ok) => ok ? then() : void 0).finally(() => setActiveId(null));
26
28
  };
27
- const dialog = /* @__PURE__ */ jsx(TransactionDialog, { tx, title: copy.title, workingLabel: copy.working, firstStepLabel: "Prepare", children: /* @__PURE__ */ jsx(TransactionSuccess, { name: copy.title, title: copy.done, description: copy.description, txHash: tx.txHash, actions: [{ label: "Done", onClick: tx.reset }] }) });
29
+ const dialog = /* @__PURE__ */ jsx(TransactionDialog, { tx, title: copy.title, workingLabel: copy.working, firstStepLabel: "Prepare", children: /* @__PURE__ */ jsx(TransactionSuccess, { name: copy.title, ...copy.message, txHash: tx.txHash, actions: [{ label: "Done", onClick: tx.reset }] }) });
28
30
  return { run, dialog, busy, activeId };
29
31
  }
30
32
  function Spinner({ active, idle, className }) {
@@ -33,7 +35,7 @@ function Spinner({ active, idle, className }) {
33
35
  function OfferBidsRow({ offer }) {
34
36
  const { walletAddress } = useMedialaneApp();
35
37
  const { bids, isLoading, mutate } = useSponsorshipBids(offer.offerId);
36
- const action = useRowAction({ title: "Accept bid", working: "Accepting the bid\u2026", done: "Bid accepted!", description: "The license is minted to the sponsor." });
38
+ const action = useRowAction({ title: "Accept bid", working: "Accepting the bid\u2026", message: successMessages.bidAccepted() });
37
39
  if (isLoading || bids.length === 0) return null;
38
40
  return /* @__PURE__ */ jsxs("div", { className: "space-y-1.5 rounded-lg bg-muted/30 p-3", children: [
39
41
  action.dialog,
@@ -63,7 +65,7 @@ function OfferBidsRow({ offer }) {
63
65
  }
64
66
  function ReceivedProposals({ walletAddress }) {
65
67
  const { proposals, isLoading, mutate } = useSponsorshipProposals({ owner: walletAddress, open: true });
66
- const action = useRowAction({ title: "Respond to proposal", working: "Sending your response\u2026", done: "Response sent!", description: "Your response is now on-chain." });
68
+ const action = useRowAction({ title: "Respond to proposal", working: "Sending your response\u2026", message: successMessages.responseSent() });
67
69
  if (isLoading) return /* @__PURE__ */ jsx(Skeleton, { className: "h-20 w-full rounded-xl" });
68
70
  if (proposals.length === 0) return /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: "No proposals awaiting your decision." });
69
71
  const respond = (proposalId, decision) => action.run(
@@ -91,7 +93,7 @@ function ReceivedProposals({ walletAddress }) {
91
93
  }
92
94
  function SentProposals({ walletAddress }) {
93
95
  const { proposals, isLoading, mutate } = useSponsorshipProposals({ proposer: walletAddress, open: true });
94
- const action = useRowAction({ title: "Withdraw proposal", working: "Withdrawing your proposal\u2026", done: "Proposal withdrawn!", description: "Your proposal is no longer open." });
96
+ const action = useRowAction({ title: "Withdraw proposal", working: "Withdrawing your proposal\u2026", message: successMessages.proposalWithdrawn() });
95
97
  if (isLoading) return /* @__PURE__ */ jsx(Skeleton, { className: "h-20 w-full rounded-xl" });
96
98
  if (proposals.length === 0) return /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: "No pending proposals sent." });
97
99
  return /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
@@ -122,7 +124,12 @@ function SentProposals({ walletAddress }) {
122
124
  }
123
125
  function LicenseList({ loading, empty, children }) {
124
126
  if (loading) return /* @__PURE__ */ jsx(Skeleton, { className: "h-16 w-full rounded-xl" });
125
- if (children.length === 0) return /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: empty });
127
+ if (children.length === 0) {
128
+ return /* @__PURE__ */ jsxs("div", { children: [
129
+ /* @__PURE__ */ jsx("p", { className: "text-sm font-medium", children: empty.title }),
130
+ /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: empty.description })
131
+ ] });
132
+ }
126
133
  return /* @__PURE__ */ jsx("div", { className: "space-y-2", children });
127
134
  }
128
135
  function PortfolioSponsorships() {
@@ -149,7 +156,7 @@ function PortfolioSponsorships() {
149
156
  ] }),
150
157
  /* @__PURE__ */ jsxs("section", { className: "space-y-3", children: [
151
158
  /* @__PURE__ */ jsx("h2", { className: "text-sm font-bold", children: "Licenses you hold" }),
152
- /* @__PURE__ */ jsx(LicenseList, { loading: heldLoading, empty: "No sponsorship licenses yet.", children: held.map((l) => /* @__PURE__ */ jsxs("div", { className: "bento-cell p-4", children: [
159
+ /* @__PURE__ */ jsx(LicenseList, { loading: heldLoading, empty: emptyMessages.heldLicenses, children: held.map((l) => /* @__PURE__ */ jsxs("div", { className: "bento-cell p-4", children: [
153
160
  /* @__PURE__ */ jsx("p", { className: "text-sm font-semibold", children: /* @__PURE__ */ jsx(Link, { href: assetHref("STARKNET", l.assetContract, l.assetTokenId), className: "hover:underline", children: "License on this asset" }) }),
154
161
  /* @__PURE__ */ jsxs("p", { className: "text-xs text-muted-foreground", children: [
155
162
  "from ",
@@ -159,7 +166,7 @@ function PortfolioSponsorships() {
159
166
  ] }),
160
167
  /* @__PURE__ */ jsxs("section", { className: "space-y-3", children: [
161
168
  /* @__PURE__ */ jsx("h2", { className: "text-sm font-bold", children: "Licenses issued on your work" }),
162
- /* @__PURE__ */ jsx(LicenseList, { loading: issuedLoading, empty: "No licenses issued yet.", children: issued.map((l) => /* @__PURE__ */ jsxs("div", { className: "bento-cell p-4", children: [
169
+ /* @__PURE__ */ jsx(LicenseList, { loading: issuedLoading, empty: emptyMessages.issuedLicenses, children: issued.map((l) => /* @__PURE__ */ jsxs("div", { className: "bento-cell p-4", children: [
163
170
  /* @__PURE__ */ jsx("p", { className: "text-sm font-semibold", children: /* @__PURE__ */ jsx(Link, { href: assetHref("STARKNET", l.assetContract, l.assetTokenId), className: "hover:underline", children: "License on this asset" }) }),
164
171
  /* @__PURE__ */ jsxs("p", { className: "text-xs text-muted-foreground", children: [
165
172
  "held by ",
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/portfolio-sponsorships.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState } from \"react\";\nimport { CheckCircle2, Handshake, Loader2, X } from \"lucide-react\";\nimport { assetHref, type ApiSponsorshipOffer } from \"@medialane/sdk\";\nimport { AddressDisplay } from \"./address-display.js\";\nimport { Button } from \"./button.js\";\nimport Link from \"./link.js\";\nimport { useMedialaneApp } from \"./medialane-app.js\";\nimport { Skeleton } from \"./skeleton.js\";\nimport { TransactionDialog } from \"./transaction-dialog.js\";\nimport { 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&apos;ve sent</h2>\n <SentProposals walletAddress={walletAddress} />\n </section>\n\n <section className=\"space-y-3\">\n <h2 className=\"text-sm font-bold\">Licenses you hold</h2>\n <LicenseList loading={heldLoading} empty=\"No sponsorship licenses yet.\">\n {held.map((l) => (\n <div key={l.id} className=\"bento-cell p-4\">\n <p className=\"text-sm font-semibold\">\n <Link href={assetHref(\"STARKNET\", l.assetContract, l.assetTokenId)} className=\"hover:underline\">License on this asset</Link>\n </p>\n <p className=\"text-xs text-muted-foreground\">from <AddressDisplay address={l.author} chars={4} showCopy={false} /></p>\n </div>\n ))}\n </LicenseList>\n </section>\n\n <section className=\"space-y-3\">\n <h2 className=\"text-sm font-bold\">Licenses issued on your work</h2>\n <LicenseList loading={issuedLoading} empty=\"No licenses issued yet.\">\n {issued.map((l) => (\n <div key={l.id} className=\"bento-cell p-4\">\n <p className=\"text-sm font-semibold\">\n <Link href={assetHref(\"STARKNET\", l.assetContract, l.assetTokenId)} className=\"hover:underline\">License on this asset</Link>\n </p>\n <p className=\"text-xs text-muted-foreground\">held by <AddressDisplay address={l.currentHolder ?? l.recipient} chars={4} showCopy={false} /></p>\n </div>\n ))}\n </LicenseList>\n </section>\n </div>\n );\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/components/portfolio-sponsorships.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState } from \"react\";\nimport { CheckCircle2, Handshake, Loader2, X } from \"lucide-react\";\nimport { assetHref, type ApiSponsorshipOffer } from \"@medialane/sdk\";\nimport { AddressDisplay } from \"./address-display.js\";\nimport { Button } from \"./button.js\";\nimport Link from \"./link.js\";\nimport { useMedialaneApp } from \"./medialane-app.js\";\nimport { Skeleton } from \"./skeleton.js\";\nimport { TransactionDialog } from \"./transaction-dialog.js\";\nimport { TransactionSuccess } from \"./transaction-success.js\";\nimport { runIntentCalls } from \"../utils/run-intent-calls.js\";\nimport { useSponsorshipBids, useSponsorshipLicenses, useSponsorshipOffers, useSponsorshipProposals } from \"../utils/use-sponsorship.js\";\nimport { emptyMessages, type EmptyMessage } from \"../utils/empty-messages.js\";\nimport { successMessages, type SuccessMessage } from \"../utils/success-messages.js\";\nimport { useTransaction } from \"../utils/use-transaction.js\";\n\ntype Api = ReturnType<ReturnType<typeof useMedialaneApp>[\"getClient\"]>[\"api\"];\n\nfunction useRowAction(copy: { title: string; working: string; message: SuccessMessage }) {\n const app = useMedialaneApp();\n const tx = useTransaction();\n const [activeId, setActiveId] = useState<string | null>(null);\n const busy = tx.phase === \"preparing\" || tx.phase === \"submitting\" || tx.phase === \"confirming\";\n\n const run = (id: string, create: (api: Api) => ReturnType<Parameters<typeof runIntentCalls>[1]>, then: () => Promise<unknown>) => {\n setActiveId(id);\n void tx\n .run(async (signer) => {\n await runIntentCalls(signer, () => create(app.getClient().api));\n })\n .then((ok) => (ok ? then() : undefined))\n .finally(() => setActiveId(null));\n };\n\n const dialog = (\n <TransactionDialog tx={tx} title={copy.title} workingLabel={copy.working} firstStepLabel=\"Prepare\">\n <TransactionSuccess name={copy.title} {...copy.message} txHash={tx.txHash} actions={[{ label: \"Done\", onClick: tx.reset }]} />\n </TransactionDialog>\n );\n\n return { run, dialog, busy, activeId };\n}\n\nfunction Spinner({ active, idle, className }: { active: boolean; idle: React.ReactNode; className?: string }) {\n return active ? <Loader2 className={`h-3 w-3 animate-spin ${className ?? \"\"}`} /> : <>{idle}</>;\n}\n\nfunction OfferBidsRow({ offer }: { offer: ApiSponsorshipOffer }) {\n const { walletAddress } = useMedialaneApp();\n const { bids, isLoading, mutate } = useSponsorshipBids(offer.offerId);\n const action = useRowAction({ title: \"Accept bid\", working: \"Accepting the bid…\", message: successMessages.bidAccepted() });\n\n if (isLoading || bids.length === 0) return null;\n\n return (\n <div className=\"space-y-1.5 rounded-lg bg-muted/30 p-3\">\n {action.dialog}\n <p className=\"text-xs font-semibold text-muted-foreground\">\n Bids on <Link href={assetHref(\"STARKNET\", offer.nftContract, offer.tokenId)} className=\"underline underline-offset-2\">View asset</Link>\n </p>\n {bids.map((bid) => (\n <div key={bid.id} className=\"flex items-center justify-between gap-2 text-xs\">\n <AddressDisplay address={bid.sponsor} chars={4} showCopy={false} className=\"text-muted-foreground\" />\n <Button\n size=\"sm\"\n className=\"bg-brand-rose hover:brightness-110 text-white h-7 px-2.5\"\n aria-label=\"Accept bid\"\n disabled={action.busy || !walletAddress}\n onClick={() =>\n action.run(\n bid.id,\n (api) => api.intents.create(\"sponsorship-bid-accept\", { author: walletAddress!, offerId: offer.offerId, sponsor: bid.sponsor }),\n () => mutate(),\n )\n }\n >\n <Spinner active={action.busy && action.activeId === bid.id} idle={<CheckCircle2 className=\"h-3 w-3\" />} />\n </Button>\n </div>\n ))}\n </div>\n );\n}\n\nfunction ReceivedProposals({ walletAddress }: { walletAddress: string }) {\n const { proposals, isLoading, mutate } = useSponsorshipProposals({ owner: walletAddress, open: true });\n const action = useRowAction({ title: \"Respond to proposal\", working: \"Sending your response…\", message: successMessages.responseSent() });\n\n if (isLoading) return <Skeleton className=\"h-20 w-full rounded-xl\" />;\n if (proposals.length === 0) return <p className=\"text-sm text-muted-foreground\">No proposals awaiting your decision.</p>;\n\n const respond = (proposalId: string, decision: \"accept\" | \"reject\") =>\n action.run(\n proposalId,\n (api) =>\n decision === \"accept\"\n ? api.intents.create(\"sponsorship-proposal-accept\", { owner: walletAddress, proposalId })\n : api.intents.create(\"sponsorship-proposal-reject\", { owner: walletAddress, proposalId }),\n () => mutate(),\n );\n\n return (\n <div className=\"space-y-2\">\n {action.dialog}\n {proposals.map((p) => (\n <div key={p.id} className=\"bento-cell p-4 flex items-center justify-between gap-3\">\n <div className=\"min-w-0\">\n <p className=\"text-sm font-semibold\">\n <Link href={assetHref(\"STARKNET\", p.nftContract, p.tokenId)} className=\"hover:underline\">View asset</Link>\n </p>\n <p className=\"text-xs text-muted-foreground\">\n <AddressDisplay address={p.proposer} chars={4} showCopy={false} /> proposed {p.amount}\n </p>\n </div>\n <div className=\"flex gap-1.5 shrink-0\">\n <Button size=\"sm\" variant=\"outline\" aria-label=\"Decline proposal\" disabled={action.busy} onClick={() => respond(p.proposalId, \"reject\")}>\n <Spinner active={action.busy && action.activeId === p.proposalId} idle={<X className=\"h-3 w-3\" />} />\n </Button>\n <Button size=\"sm\" className=\"bg-brand-rose hover:brightness-110 text-white\" aria-label=\"Accept proposal\" disabled={action.busy} onClick={() => respond(p.proposalId, \"accept\")}>\n <Spinner active={action.busy && action.activeId === p.proposalId} idle={<CheckCircle2 className=\"h-3 w-3\" />} />\n </Button>\n </div>\n </div>\n ))}\n </div>\n );\n}\n\nfunction SentProposals({ walletAddress }: { walletAddress: string }) {\n const { proposals, isLoading, mutate } = useSponsorshipProposals({ proposer: walletAddress, open: true });\n const action = useRowAction({ title: \"Withdraw proposal\", working: \"Withdrawing your proposal…\", message: successMessages.proposalWithdrawn() });\n\n if (isLoading) return <Skeleton className=\"h-20 w-full rounded-xl\" />;\n if (proposals.length === 0) return <p className=\"text-sm text-muted-foreground\">No pending proposals sent.</p>;\n\n return (\n <div className=\"space-y-2\">\n {action.dialog}\n {proposals.map((p) => (\n <div key={p.id} className=\"bento-cell p-4 flex items-center justify-between gap-3\">\n <div className=\"min-w-0\">\n <p className=\"text-sm font-semibold\">\n <Link href={assetHref(\"STARKNET\", p.nftContract, p.tokenId)} className=\"hover:underline\">View asset</Link>\n </p>\n <p className=\"text-xs text-muted-foreground\">You proposed {p.amount}</p>\n </div>\n <Button\n size=\"sm\"\n variant=\"outline\"\n disabled={action.busy}\n onClick={() =>\n action.run(p.proposalId, (api) => api.intents.create(\"sponsorship-proposal-withdraw\", { proposer: walletAddress, proposalId: p.proposalId }), () => mutate())\n }\n >\n <Spinner active={action.busy && action.activeId === p.proposalId} idle={null} className=\"mr-1.5\" />\n Withdraw\n </Button>\n </div>\n ))}\n </div>\n );\n}\n\nfunction LicenseList({ loading, empty, children }: { loading: boolean; empty: EmptyMessage; children: React.ReactNode[] }) {\n if (loading) return <Skeleton className=\"h-16 w-full rounded-xl\" />;\n if (children.length === 0) {\n return (\n <div>\n <p className=\"text-sm font-medium\">{empty.title}</p>\n <p className=\"text-sm text-muted-foreground\">{empty.description}</p>\n </div>\n );\n }\n return <div className=\"space-y-2\">{children}</div>;\n}\n\nexport function PortfolioSponsorships() {\n const { walletAddress } = useMedialaneApp();\n const { offers } = useSponsorshipOffers(walletAddress ? { author: walletAddress, open: true } : undefined);\n const { licenses: held, isLoading: heldLoading } = useSponsorshipLicenses(walletAddress ? { holder: walletAddress } : undefined);\n const { licenses: issued, isLoading: issuedLoading } = useSponsorshipLicenses(walletAddress ? { author: walletAddress } : undefined);\n\n if (!walletAddress) return null;\n\n return (\n <div className=\"space-y-8\">\n <section className=\"space-y-3\">\n <h2 className=\"text-sm font-bold flex items-center gap-2\"><Handshake className=\"h-4 w-4 text-brand-rose\" />Proposals awaiting your decision</h2>\n <ReceivedProposals walletAddress={walletAddress} />\n </section>\n\n {offers.length > 0 && (\n <section className=\"space-y-3\">\n <h2 className=\"text-sm font-bold\">Bids on your offers</h2>\n <div className=\"space-y-2\">\n {offers.map((o) => <OfferBidsRow key={o.id} offer={o} />)}\n </div>\n </section>\n )}\n\n <section className=\"space-y-3\">\n <h2 className=\"text-sm font-bold\">Proposals you&apos;ve sent</h2>\n <SentProposals walletAddress={walletAddress} />\n </section>\n\n <section className=\"space-y-3\">\n <h2 className=\"text-sm font-bold\">Licenses you hold</h2>\n <LicenseList loading={heldLoading} empty={emptyMessages.heldLicenses}>\n {held.map((l) => (\n <div key={l.id} className=\"bento-cell p-4\">\n <p className=\"text-sm font-semibold\">\n <Link href={assetHref(\"STARKNET\", l.assetContract, l.assetTokenId)} className=\"hover:underline\">License on this asset</Link>\n </p>\n <p className=\"text-xs text-muted-foreground\">from <AddressDisplay address={l.author} chars={4} showCopy={false} /></p>\n </div>\n ))}\n </LicenseList>\n </section>\n\n <section className=\"space-y-3\">\n <h2 className=\"text-sm font-bold\">Licenses issued on your work</h2>\n <LicenseList loading={issuedLoading} empty={emptyMessages.issuedLicenses}>\n {issued.map((l) => (\n <div key={l.id} className=\"bento-cell p-4\">\n <p className=\"text-sm font-semibold\">\n <Link href={assetHref(\"STARKNET\", l.assetContract, l.assetTokenId)} className=\"hover:underline\">License on this asset</Link>\n </p>\n <p className=\"text-xs text-muted-foreground\">held by <AddressDisplay address={l.currentHolder ?? l.recipient} chars={4} showCopy={false} /></p>\n </div>\n ))}\n </LicenseList>\n </section>\n </div>\n );\n}\n"],"mappings":"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","names":[]}
@@ -54,7 +54,7 @@ const KINDS = {
54
54
  createLabel: "Create collection",
55
55
  sectionLabel: "Your collections",
56
56
  sectionTitle: "Ticket collections",
57
- empty: "No collections yet",
57
+ empty: "Your ticket collections appear here",
58
58
  emptyText: "Create your first tickets collection.",
59
59
  accent: "bg-brand-blue",
60
60
  tint: "bg-brand-blue/10 text-brand-blue/40"
@@ -67,7 +67,7 @@ const KINDS = {
67
67
  createLabel: "Create club",
68
68
  sectionLabel: "Your clubs",
69
69
  sectionTitle: "Club collections",
70
- empty: "No clubs yet",
70
+ empty: "Your clubs appear here",
71
71
  emptyText: "Create your first club.",
72
72
  accent: "bg-brand-purple",
73
73
  tint: "bg-brand-purple/10 text-brand-purple/40"
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/service-collections-page.tsx"],"sourcesContent":["\"use client\";\n\nimport { Plus, Ticket, Users } from \"lucide-react\";\nimport { collectionHref } from \"@medialane/sdk\";\nimport Link from \"./link.js\";\nimport { Button } from \"./button.js\";\nimport { Skeleton } from \"./skeleton.js\";\nimport { FadeIn, Stagger, StaggerItem } from \"./motion-primitives.js\";\nimport { BackButton } from \"./back-button.js\";\nimport { ServiceHeader } from \"./service-header.js\";\nimport { CollectionCard } from \"./collection-card.js\";\nimport { SignInPrompt } from \"./sign-in-prompt.js\";\nimport { useMedialaneApp } from \"./medialane-app.js\";\nimport { useMyClubCollections, useMyTicketCollections } from \"../utils/use-tiers.js\";\n\nconst KINDS = {\n tickets: {\n icon: Ticket,\n title: \"IP Tickets\",\n subtitle: \"Create a tickets collection, then mint tickets from its collection page.\",\n createHref: \"/launchpad/tickets/create\",\n createLabel: \"Create collection\",\n sectionLabel: \"Your collections\",\n sectionTitle: \"Ticket collections\",\n empty: \"No collections yet\",\n emptyText: \"Create your first tickets collection.\",\n accent: \"bg-brand-blue\",\n tint: \"bg-brand-blue/10 text-brand-blue/40\",\n },\n club: {\n icon: Users,\n title: \"IP Club\",\n subtitle: \"Create a club, then create membership tiers from its collection page.\",\n createHref: \"/launchpad/club/create\",\n createLabel: \"Create club\",\n sectionLabel: \"Your clubs\",\n sectionTitle: \"Club collections\",\n empty: \"No clubs yet\",\n emptyText: \"Create your first club.\",\n accent: \"bg-brand-purple\",\n tint: \"bg-brand-purple/10 text-brand-purple/40\",\n },\n} as const;\n\nexport function ServiceCollectionsPage({ kind }: { kind: keyof typeof KINDS }) {\n const config = KINDS[kind];\n const Icon = config.icon;\n const { walletAddress, walletLoading } = useMedialaneApp();\n const tickets = useMyTicketCollections(kind === \"tickets\" ? walletAddress : null);\n const clubs = useMyClubCollections(kind === \"club\" ? walletAddress : null);\n const { collections, isLoading } = kind === \"tickets\" ? tickets : clubs;\n\n const createButton = (\n <Button asChild size=\"sm\" className={`${config.accent} gap-1.5 text-white hover:brightness-110`}>\n <Link href={config.createHref}>\n <Plus className=\"h-3.5 w-3.5\" />\n {config.createLabel}\n </Link>\n </Button>\n );\n const iconTile = (\n <div className={`flex h-16 w-16 items-center justify-center rounded-2xl ${config.tint}`}>\n <Icon className=\"h-8 w-8\" />\n </div>\n );\n\n return (\n <div className=\"mx-auto max-w-5xl space-y-10 pb-16\">\n <section className=\"px-4 pt-10\">\n <BackButton />\n <FadeIn>\n <div className=\"mt-6\">\n <ServiceHeader plain icon={<Icon className=\"h-4 w-4 text-white\" />} title={config.title} subtitle={config.subtitle} headerAccessory={createButton} />\n </div>\n </FadeIn>\n </section>\n\n <section className=\"space-y-4 px-4\">\n <div>\n <p className=\"section-label\">{config.sectionLabel}</p>\n <h2 className=\"mt-0.5 text-xl font-bold\">{config.sectionTitle}</h2>\n </div>\n\n {!walletAddress && !walletLoading ? (\n <SignInPrompt icon={iconTile} title=\"Sign in to see your collections\" />\n ) : isLoading || walletLoading ? (\n <div className=\"grid grid-cols-2 gap-4 sm:grid-cols-3 lg:grid-cols-4\">\n {Array.from({ length: 4 }).map((_, i) => <Skeleton key={i} className=\"aspect-square rounded-2xl\" />)}\n </div>\n ) : collections.length === 0 ? (\n <div className=\"bento-cell space-y-4 border-dashed p-12 text-center\">\n <div className=\"flex justify-center\">{iconTile}</div>\n <div className=\"space-y-1\">\n <p className=\"text-sm font-semibold\">{config.empty}</p>\n <p className=\"text-xs text-muted-foreground\">{config.emptyText}</p>\n </div>\n {createButton}\n </div>\n ) : (\n <Stagger className=\"grid grid-cols-2 gap-4 sm:grid-cols-3 lg:grid-cols-4\">\n {collections.map((col) => (\n <StaggerItem key={col.contractAddress}>\n <CollectionCard collection={col} href={collectionHref(\"STARKNET\", col.contractAddress)} />\n </StaggerItem>\n ))}\n </Stagger>\n )}\n </section>\n </div>\n );\n}\n"],"mappings":"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","names":["Link"]}
1
+ {"version":3,"sources":["../../src/components/service-collections-page.tsx"],"sourcesContent":["\"use client\";\n\nimport { Plus, Ticket, Users } from \"lucide-react\";\nimport { collectionHref } from \"@medialane/sdk\";\nimport Link from \"./link.js\";\nimport { Button } from \"./button.js\";\nimport { Skeleton } from \"./skeleton.js\";\nimport { FadeIn, Stagger, StaggerItem } from \"./motion-primitives.js\";\nimport { BackButton } from \"./back-button.js\";\nimport { ServiceHeader } from \"./service-header.js\";\nimport { CollectionCard } from \"./collection-card.js\";\nimport { SignInPrompt } from \"./sign-in-prompt.js\";\nimport { useMedialaneApp } from \"./medialane-app.js\";\nimport { useMyClubCollections, useMyTicketCollections } from \"../utils/use-tiers.js\";\n\nconst KINDS = {\n tickets: {\n icon: Ticket,\n title: \"IP Tickets\",\n subtitle: \"Create a tickets collection, then mint tickets from its collection page.\",\n createHref: \"/launchpad/tickets/create\",\n createLabel: \"Create collection\",\n sectionLabel: \"Your collections\",\n sectionTitle: \"Ticket collections\",\n empty: \"Your ticket collections appear here\",\n emptyText: \"Create your first tickets collection.\",\n accent: \"bg-brand-blue\",\n tint: \"bg-brand-blue/10 text-brand-blue/40\",\n },\n club: {\n icon: Users,\n title: \"IP Club\",\n subtitle: \"Create a club, then create membership tiers from its collection page.\",\n createHref: \"/launchpad/club/create\",\n createLabel: \"Create club\",\n sectionLabel: \"Your clubs\",\n sectionTitle: \"Club collections\",\n empty: \"Your clubs appear here\",\n emptyText: \"Create your first club.\",\n accent: \"bg-brand-purple\",\n tint: \"bg-brand-purple/10 text-brand-purple/40\",\n },\n} as const;\n\nexport function ServiceCollectionsPage({ kind }: { kind: keyof typeof KINDS }) {\n const config = KINDS[kind];\n const Icon = config.icon;\n const { walletAddress, walletLoading } = useMedialaneApp();\n const tickets = useMyTicketCollections(kind === \"tickets\" ? walletAddress : null);\n const clubs = useMyClubCollections(kind === \"club\" ? walletAddress : null);\n const { collections, isLoading } = kind === \"tickets\" ? tickets : clubs;\n\n const createButton = (\n <Button asChild size=\"sm\" className={`${config.accent} gap-1.5 text-white hover:brightness-110`}>\n <Link href={config.createHref}>\n <Plus className=\"h-3.5 w-3.5\" />\n {config.createLabel}\n </Link>\n </Button>\n );\n const iconTile = (\n <div className={`flex h-16 w-16 items-center justify-center rounded-2xl ${config.tint}`}>\n <Icon className=\"h-8 w-8\" />\n </div>\n );\n\n return (\n <div className=\"mx-auto max-w-5xl space-y-10 pb-16\">\n <section className=\"px-4 pt-10\">\n <BackButton />\n <FadeIn>\n <div className=\"mt-6\">\n <ServiceHeader plain icon={<Icon className=\"h-4 w-4 text-white\" />} title={config.title} subtitle={config.subtitle} headerAccessory={createButton} />\n </div>\n </FadeIn>\n </section>\n\n <section className=\"space-y-4 px-4\">\n <div>\n <p className=\"section-label\">{config.sectionLabel}</p>\n <h2 className=\"mt-0.5 text-xl font-bold\">{config.sectionTitle}</h2>\n </div>\n\n {!walletAddress && !walletLoading ? (\n <SignInPrompt icon={iconTile} title=\"Sign in to see your collections\" />\n ) : isLoading || walletLoading ? (\n <div className=\"grid grid-cols-2 gap-4 sm:grid-cols-3 lg:grid-cols-4\">\n {Array.from({ length: 4 }).map((_, i) => <Skeleton key={i} className=\"aspect-square rounded-2xl\" />)}\n </div>\n ) : collections.length === 0 ? (\n <div className=\"bento-cell space-y-4 border-dashed p-12 text-center\">\n <div className=\"flex justify-center\">{iconTile}</div>\n <div className=\"space-y-1\">\n <p className=\"text-sm font-semibold\">{config.empty}</p>\n <p className=\"text-xs text-muted-foreground\">{config.emptyText}</p>\n </div>\n {createButton}\n </div>\n ) : (\n <Stagger className=\"grid grid-cols-2 gap-4 sm:grid-cols-3 lg:grid-cols-4\">\n {collections.map((col) => (\n <StaggerItem key={col.contractAddress}>\n <CollectionCard collection={col} href={collectionHref(\"STARKNET\", col.contractAddress)} />\n </StaggerItem>\n ))}\n </Stagger>\n )}\n </section>\n </div>\n );\n}\n"],"mappings":"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","names":["Link"]}
@@ -11,7 +11,7 @@ declare const KINDS: {
11
11
  readonly createLabel: "Create collection";
12
12
  readonly sectionLabel: "Your collections";
13
13
  readonly sectionTitle: "Ticket collections";
14
- readonly empty: "No collections yet";
14
+ readonly empty: "Your ticket collections appear here";
15
15
  readonly emptyText: "Create your first tickets collection.";
16
16
  readonly accent: "bg-brand-blue";
17
17
  readonly tint: "bg-brand-blue/10 text-brand-blue/40";
@@ -24,7 +24,7 @@ declare const KINDS: {
24
24
  readonly createLabel: "Create club";
25
25
  readonly sectionLabel: "Your clubs";
26
26
  readonly sectionTitle: "Club collections";
27
- readonly empty: "No clubs yet";
27
+ readonly empty: "Your clubs appear here";
28
28
  readonly emptyText: "Create your first club.";
29
29
  readonly accent: "bg-brand-purple";
30
30
  readonly tint: "bg-brand-purple/10 text-brand-purple/40";
@@ -11,7 +11,7 @@ declare const KINDS: {
11
11
  readonly createLabel: "Create collection";
12
12
  readonly sectionLabel: "Your collections";
13
13
  readonly sectionTitle: "Ticket collections";
14
- readonly empty: "No collections yet";
14
+ readonly empty: "Your ticket collections appear here";
15
15
  readonly emptyText: "Create your first tickets collection.";
16
16
  readonly accent: "bg-brand-blue";
17
17
  readonly tint: "bg-brand-blue/10 text-brand-blue/40";
@@ -24,7 +24,7 @@ declare const KINDS: {
24
24
  readonly createLabel: "Create club";
25
25
  readonly sectionLabel: "Your clubs";
26
26
  readonly sectionTitle: "Club collections";
27
- readonly empty: "No clubs yet";
27
+ readonly empty: "Your clubs appear here";
28
28
  readonly emptyText: "Create your first club.";
29
29
  readonly accent: "bg-brand-purple";
30
30
  readonly tint: "bg-brand-purple/10 text-brand-purple/40";
@@ -21,7 +21,7 @@ const KINDS = {
21
21
  createLabel: "Create collection",
22
22
  sectionLabel: "Your collections",
23
23
  sectionTitle: "Ticket collections",
24
- empty: "No collections yet",
24
+ empty: "Your ticket collections appear here",
25
25
  emptyText: "Create your first tickets collection.",
26
26
  accent: "bg-brand-blue",
27
27
  tint: "bg-brand-blue/10 text-brand-blue/40"
@@ -34,7 +34,7 @@ const KINDS = {
34
34
  createLabel: "Create club",
35
35
  sectionLabel: "Your clubs",
36
36
  sectionTitle: "Club collections",
37
- empty: "No clubs yet",
37
+ empty: "Your clubs appear here",
38
38
  emptyText: "Create your first club.",
39
39
  accent: "bg-brand-purple",
40
40
  tint: "bg-brand-purple/10 text-brand-purple/40"
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/service-collections-page.tsx"],"sourcesContent":["\"use client\";\n\nimport { Plus, Ticket, Users } from \"lucide-react\";\nimport { collectionHref } from \"@medialane/sdk\";\nimport Link from \"./link.js\";\nimport { Button } from \"./button.js\";\nimport { Skeleton } from \"./skeleton.js\";\nimport { FadeIn, Stagger, StaggerItem } from \"./motion-primitives.js\";\nimport { BackButton } from \"./back-button.js\";\nimport { ServiceHeader } from \"./service-header.js\";\nimport { CollectionCard } from \"./collection-card.js\";\nimport { SignInPrompt } from \"./sign-in-prompt.js\";\nimport { useMedialaneApp } from \"./medialane-app.js\";\nimport { useMyClubCollections, useMyTicketCollections } from \"../utils/use-tiers.js\";\n\nconst KINDS = {\n tickets: {\n icon: Ticket,\n title: \"IP Tickets\",\n subtitle: \"Create a tickets collection, then mint tickets from its collection page.\",\n createHref: \"/launchpad/tickets/create\",\n createLabel: \"Create collection\",\n sectionLabel: \"Your collections\",\n sectionTitle: \"Ticket collections\",\n empty: \"No collections yet\",\n emptyText: \"Create your first tickets collection.\",\n accent: \"bg-brand-blue\",\n tint: \"bg-brand-blue/10 text-brand-blue/40\",\n },\n club: {\n icon: Users,\n title: \"IP Club\",\n subtitle: \"Create a club, then create membership tiers from its collection page.\",\n createHref: \"/launchpad/club/create\",\n createLabel: \"Create club\",\n sectionLabel: \"Your clubs\",\n sectionTitle: \"Club collections\",\n empty: \"No clubs yet\",\n emptyText: \"Create your first club.\",\n accent: \"bg-brand-purple\",\n tint: \"bg-brand-purple/10 text-brand-purple/40\",\n },\n} as const;\n\nexport function ServiceCollectionsPage({ kind }: { kind: keyof typeof KINDS }) {\n const config = KINDS[kind];\n const Icon = config.icon;\n const { walletAddress, walletLoading } = useMedialaneApp();\n const tickets = useMyTicketCollections(kind === \"tickets\" ? walletAddress : null);\n const clubs = useMyClubCollections(kind === \"club\" ? walletAddress : null);\n const { collections, isLoading } = kind === \"tickets\" ? tickets : clubs;\n\n const createButton = (\n <Button asChild size=\"sm\" className={`${config.accent} gap-1.5 text-white hover:brightness-110`}>\n <Link href={config.createHref}>\n <Plus className=\"h-3.5 w-3.5\" />\n {config.createLabel}\n </Link>\n </Button>\n );\n const iconTile = (\n <div className={`flex h-16 w-16 items-center justify-center rounded-2xl ${config.tint}`}>\n <Icon className=\"h-8 w-8\" />\n </div>\n );\n\n return (\n <div className=\"mx-auto max-w-5xl space-y-10 pb-16\">\n <section className=\"px-4 pt-10\">\n <BackButton />\n <FadeIn>\n <div className=\"mt-6\">\n <ServiceHeader plain icon={<Icon className=\"h-4 w-4 text-white\" />} title={config.title} subtitle={config.subtitle} headerAccessory={createButton} />\n </div>\n </FadeIn>\n </section>\n\n <section className=\"space-y-4 px-4\">\n <div>\n <p className=\"section-label\">{config.sectionLabel}</p>\n <h2 className=\"mt-0.5 text-xl font-bold\">{config.sectionTitle}</h2>\n </div>\n\n {!walletAddress && !walletLoading ? (\n <SignInPrompt icon={iconTile} title=\"Sign in to see your collections\" />\n ) : isLoading || walletLoading ? (\n <div className=\"grid grid-cols-2 gap-4 sm:grid-cols-3 lg:grid-cols-4\">\n {Array.from({ length: 4 }).map((_, i) => <Skeleton key={i} className=\"aspect-square rounded-2xl\" />)}\n </div>\n ) : collections.length === 0 ? (\n <div className=\"bento-cell space-y-4 border-dashed p-12 text-center\">\n <div className=\"flex justify-center\">{iconTile}</div>\n <div className=\"space-y-1\">\n <p className=\"text-sm font-semibold\">{config.empty}</p>\n <p className=\"text-xs text-muted-foreground\">{config.emptyText}</p>\n </div>\n {createButton}\n </div>\n ) : (\n <Stagger className=\"grid grid-cols-2 gap-4 sm:grid-cols-3 lg:grid-cols-4\">\n {collections.map((col) => (\n <StaggerItem key={col.contractAddress}>\n <CollectionCard collection={col} href={collectionHref(\"STARKNET\", col.contractAddress)} />\n </StaggerItem>\n ))}\n </Stagger>\n )}\n </section>\n </div>\n );\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/components/service-collections-page.tsx"],"sourcesContent":["\"use client\";\n\nimport { Plus, Ticket, Users } from \"lucide-react\";\nimport { collectionHref } from \"@medialane/sdk\";\nimport Link from \"./link.js\";\nimport { Button } from \"./button.js\";\nimport { Skeleton } from \"./skeleton.js\";\nimport { FadeIn, Stagger, StaggerItem } from \"./motion-primitives.js\";\nimport { BackButton } from \"./back-button.js\";\nimport { ServiceHeader } from \"./service-header.js\";\nimport { CollectionCard } from \"./collection-card.js\";\nimport { SignInPrompt } from \"./sign-in-prompt.js\";\nimport { useMedialaneApp } from \"./medialane-app.js\";\nimport { useMyClubCollections, useMyTicketCollections } from \"../utils/use-tiers.js\";\n\nconst KINDS = {\n tickets: {\n icon: Ticket,\n title: \"IP Tickets\",\n subtitle: \"Create a tickets collection, then mint tickets from its collection page.\",\n createHref: \"/launchpad/tickets/create\",\n createLabel: \"Create collection\",\n sectionLabel: \"Your collections\",\n sectionTitle: \"Ticket collections\",\n empty: \"Your ticket collections appear here\",\n emptyText: \"Create your first tickets collection.\",\n accent: \"bg-brand-blue\",\n tint: \"bg-brand-blue/10 text-brand-blue/40\",\n },\n club: {\n icon: Users,\n title: \"IP Club\",\n subtitle: \"Create a club, then create membership tiers from its collection page.\",\n createHref: \"/launchpad/club/create\",\n createLabel: \"Create club\",\n sectionLabel: \"Your clubs\",\n sectionTitle: \"Club collections\",\n empty: \"Your clubs appear here\",\n emptyText: \"Create your first club.\",\n accent: \"bg-brand-purple\",\n tint: \"bg-brand-purple/10 text-brand-purple/40\",\n },\n} as const;\n\nexport function ServiceCollectionsPage({ kind }: { kind: keyof typeof KINDS }) {\n const config = KINDS[kind];\n const Icon = config.icon;\n const { walletAddress, walletLoading } = useMedialaneApp();\n const tickets = useMyTicketCollections(kind === \"tickets\" ? walletAddress : null);\n const clubs = useMyClubCollections(kind === \"club\" ? walletAddress : null);\n const { collections, isLoading } = kind === \"tickets\" ? tickets : clubs;\n\n const createButton = (\n <Button asChild size=\"sm\" className={`${config.accent} gap-1.5 text-white hover:brightness-110`}>\n <Link href={config.createHref}>\n <Plus className=\"h-3.5 w-3.5\" />\n {config.createLabel}\n </Link>\n </Button>\n );\n const iconTile = (\n <div className={`flex h-16 w-16 items-center justify-center rounded-2xl ${config.tint}`}>\n <Icon className=\"h-8 w-8\" />\n </div>\n );\n\n return (\n <div className=\"mx-auto max-w-5xl space-y-10 pb-16\">\n <section className=\"px-4 pt-10\">\n <BackButton />\n <FadeIn>\n <div className=\"mt-6\">\n <ServiceHeader plain icon={<Icon className=\"h-4 w-4 text-white\" />} title={config.title} subtitle={config.subtitle} headerAccessory={createButton} />\n </div>\n </FadeIn>\n </section>\n\n <section className=\"space-y-4 px-4\">\n <div>\n <p className=\"section-label\">{config.sectionLabel}</p>\n <h2 className=\"mt-0.5 text-xl font-bold\">{config.sectionTitle}</h2>\n </div>\n\n {!walletAddress && !walletLoading ? (\n <SignInPrompt icon={iconTile} title=\"Sign in to see your collections\" />\n ) : isLoading || walletLoading ? (\n <div className=\"grid grid-cols-2 gap-4 sm:grid-cols-3 lg:grid-cols-4\">\n {Array.from({ length: 4 }).map((_, i) => <Skeleton key={i} className=\"aspect-square rounded-2xl\" />)}\n </div>\n ) : collections.length === 0 ? (\n <div className=\"bento-cell space-y-4 border-dashed p-12 text-center\">\n <div className=\"flex justify-center\">{iconTile}</div>\n <div className=\"space-y-1\">\n <p className=\"text-sm font-semibold\">{config.empty}</p>\n <p className=\"text-xs text-muted-foreground\">{config.emptyText}</p>\n </div>\n {createButton}\n </div>\n ) : (\n <Stagger className=\"grid grid-cols-2 gap-4 sm:grid-cols-3 lg:grid-cols-4\">\n {collections.map((col) => (\n <StaggerItem key={col.contractAddress}>\n <CollectionCard collection={col} href={collectionHref(\"STARKNET\", col.contractAddress)} />\n </StaggerItem>\n ))}\n </Stagger>\n )}\n </section>\n </div>\n );\n}\n"],"mappings":"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","names":[]}