@medialane/ui 0.288.0 → 0.289.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/dist/components/asset-page.cjs +3 -2
  2. package/dist/components/asset-page.cjs.map +1 -1
  3. package/dist/components/asset-page.js +3 -2
  4. package/dist/components/asset-page.js.map +1 -1
  5. package/dist/components/badge.d.cts +1 -1
  6. package/dist/components/badge.d.ts +1 -1
  7. package/dist/components/button.d.cts +1 -1
  8. package/dist/components/button.d.ts +1 -1
  9. package/dist/components/collection-page.cjs +3 -2
  10. package/dist/components/collection-page.cjs.map +1 -1
  11. package/dist/components/collection-page.js +3 -2
  12. package/dist/components/collection-page.js.map +1 -1
  13. package/dist/components/comments-section.cjs +3 -3
  14. package/dist/components/comments-section.cjs.map +1 -1
  15. package/dist/components/comments-section.js +2 -2
  16. package/dist/components/comments-section.js.map +1 -1
  17. package/dist/components/creator-page.cjs +6 -5
  18. package/dist/components/creator-page.cjs.map +1 -1
  19. package/dist/components/creator-page.js +5 -4
  20. package/dist/components/creator-page.js.map +1 -1
  21. package/dist/components/launchpad/edition-mint-schema.d.cts +2 -2
  22. package/dist/components/launchpad/edition-mint-schema.d.ts +2 -2
  23. package/dist/components/listing-card-menu.cjs +10 -13
  24. package/dist/components/listing-card-menu.cjs.map +1 -1
  25. package/dist/components/listing-card-menu.js +10 -13
  26. package/dist/components/listing-card-menu.js.map +1 -1
  27. package/dist/components/medialane-app.cjs.map +1 -1
  28. package/dist/components/medialane-app.d.cts +2 -8
  29. package/dist/components/medialane-app.d.ts +2 -8
  30. package/dist/components/medialane-app.js.map +1 -1
  31. package/dist/components/portfolio-assets.cjs +4 -5
  32. package/dist/components/portfolio-assets.cjs.map +1 -1
  33. package/dist/components/portfolio-assets.js +3 -4
  34. package/dist/components/portfolio-assets.js.map +1 -1
  35. package/dist/components/report-dialog.cjs +191 -0
  36. package/dist/components/report-dialog.cjs.map +1 -0
  37. package/dist/components/report-dialog.d.cts +17 -0
  38. package/dist/components/report-dialog.d.ts +17 -0
  39. package/dist/components/report-dialog.js +167 -0
  40. package/dist/components/report-dialog.js.map +1 -0
  41. package/dist/index.cjs +3 -0
  42. package/dist/index.cjs.map +1 -1
  43. package/dist/index.d.cts +2 -1
  44. package/dist/index.d.ts +2 -1
  45. package/dist/index.js +2 -0
  46. package/dist/index.js.map +1 -1
  47. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/portfolio-assets.tsx"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useState, type ReactNode } from \"react\";\nimport type { ApiToken } from \"@medialane/sdk\";\nimport { ImageIcon } from \"lucide-react\";\nimport { EmptyOrError } from \"./empty-or-error.js\";\nimport { LoadMoreSentinel } from \"./load-more-sentinel.js\";\nimport { TokenCard } from \"./token-card.js\";\nimport { useMedialaneApp } from \"./medialane-app.js\";\nimport { orderUsd } from \"../utils/order-usd.js\";\nimport { useUsdPrices } from \"../utils/use-usd-prices.js\";\nimport { useTokensByOwner } from \"../utils/use-tokens.js\";\n\nexport interface PortfolioAssetActions {\n list: (token: ApiToken) => void;\n transfer: (token: ApiToken) => void;\n cancel: (token: ApiToken) => void;\n dialogs?: ReactNode;\n}\n\nexport type UsePortfolioAssetActions = (context: { refresh: () => void }) => PortfolioAssetActions;\n\nconst PAGE_SIZE = 20;\nconst GRID = \"grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5 gap-4\";\n\nfunction usdFor(token: ApiToken, prices: ReturnType<typeof useUsdPrices>): string | null {\n const order = token.activeOrders?.find((o) => o.offer.itemType === \"ERC721\" || o.offer.itemType === \"ERC1155\");\n return orderUsd(order?.price, prices);\n}\n\nexport function PortfolioAssets({ address, useActions }: { address: string; useActions: UsePortfolioAssetActions }) {\n const { ReportDialog } = useMedialaneApp();\n const [page, setPage] = useState(1);\n const [all, setAll] = useState<ApiToken[]>([]);\n const [reportToken, setReportToken] = useState<ApiToken | null>(null);\n const { tokens, meta, isLoading, error, mutate } = useTokensByOwner(address, page, PAGE_SIZE);\n const prices = useUsdPrices();\n\n useEffect(() => setAll((prev) => (page === 1 ? tokens : [...prev, ...tokens])), [tokens, page]);\n useEffect(() => { setPage(1); setAll([]); }, [address]);\n\n const actions = useActions({ refresh: () => { setPage(1); setAll([]); void mutate(); } });\n const shown = page === 1 ? tokens : all;\n const hasMore = meta ? (meta.total ?? 0) > shown.length : false;\n\n return (\n <>\n <EmptyOrError\n isLoading={isLoading && page === 1}\n error={error}\n isEmpty={shown.length === 0 && !isLoading}\n onRetry={() => void mutate()}\n emptyTitle=\"No assets yet\"\n emptyDescription=\"Create your first asset to get started.\"\n emptyCta={{ label: \"Create your first asset\", href: \"/launchpad/single-editions\" }}\n emptyIcon={<ImageIcon className=\"h-7 w-7 text-muted-foreground\" />}\n skeletonNode={\n <div className={GRID}>\n {Array.from({ length: 10 }).map((_, i) => (\n <div key={i} className=\"animate-pulse overflow-hidden rounded-xl bg-muted\">\n <div className=\"aspect-square w-full bg-muted-foreground/10\" />\n <div className=\"space-y-2 p-3\">\n <div className=\"h-4 w-3/4 rounded bg-muted-foreground/10\" />\n <div className=\"h-3 w-1/2 rounded bg-muted-foreground/10\" />\n </div>\n </div>\n ))}\n </div>\n }\n >\n <div className={GRID}>\n {shown.map((token) => (\n <TokenCard\n key={`${token.contractAddress}-${token.tokenId}`}\n token={token}\n isOwner\n usdValue={usdFor(token, prices)}\n onList={actions.list}\n onTransfer={actions.transfer}\n onCancel={actions.cancel}\n onReport={ReportDialog ? setReportToken : undefined}\n />\n ))}\n </div>\n <LoadMoreSentinel hasMore={hasMore} isLoading={isLoading} onLoadMore={() => setPage((p) => p + 1)} />\n </EmptyOrError>\n {actions.dialogs}\n {ReportDialog && reportToken && (\n <ReportDialog\n open={!!reportToken}\n onOpenChange={(open) => { if (!open) setReportToken(null); }}\n target={{ type: \"TOKEN\", contract: reportToken.contractAddress, tokenId: reportToken.tokenId, name: reportToken.metadata?.name ?? undefined }}\n />\n )}\n </>\n );\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/components/portfolio-assets.tsx"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useState, type ReactNode } from \"react\";\nimport type { ApiToken } from \"@medialane/sdk\";\nimport { ImageIcon } from \"lucide-react\";\nimport { EmptyOrError } from \"./empty-or-error.js\";\nimport { LoadMoreSentinel } from \"./load-more-sentinel.js\";\nimport { TokenCard } from \"./token-card.js\";\nimport { ReportDialog } from \"./report-dialog.js\";\nimport { orderUsd } from \"../utils/order-usd.js\";\nimport { useUsdPrices } from \"../utils/use-usd-prices.js\";\nimport { useTokensByOwner } from \"../utils/use-tokens.js\";\n\nexport interface PortfolioAssetActions {\n list: (token: ApiToken) => void;\n transfer: (token: ApiToken) => void;\n cancel: (token: ApiToken) => void;\n dialogs?: ReactNode;\n}\n\nexport type UsePortfolioAssetActions = (context: { refresh: () => void }) => PortfolioAssetActions;\n\nconst PAGE_SIZE = 20;\nconst GRID = \"grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5 gap-4\";\n\nfunction usdFor(token: ApiToken, prices: ReturnType<typeof useUsdPrices>): string | null {\n const order = token.activeOrders?.find((o) => o.offer.itemType === \"ERC721\" || o.offer.itemType === \"ERC1155\");\n return orderUsd(order?.price, prices);\n}\n\nexport function PortfolioAssets({ address, useActions }: { address: string; useActions: UsePortfolioAssetActions }) {\n const [page, setPage] = useState(1);\n const [all, setAll] = useState<ApiToken[]>([]);\n const [reportToken, setReportToken] = useState<ApiToken | null>(null);\n const { tokens, meta, isLoading, error, mutate } = useTokensByOwner(address, page, PAGE_SIZE);\n const prices = useUsdPrices();\n\n useEffect(() => setAll((prev) => (page === 1 ? tokens : [...prev, ...tokens])), [tokens, page]);\n useEffect(() => { setPage(1); setAll([]); }, [address]);\n\n const actions = useActions({ refresh: () => { setPage(1); setAll([]); void mutate(); } });\n const shown = page === 1 ? tokens : all;\n const hasMore = meta ? (meta.total ?? 0) > shown.length : false;\n\n return (\n <>\n <EmptyOrError\n isLoading={isLoading && page === 1}\n error={error}\n isEmpty={shown.length === 0 && !isLoading}\n onRetry={() => void mutate()}\n emptyTitle=\"No assets yet\"\n emptyDescription=\"Create your first asset to get started.\"\n emptyCta={{ label: \"Create your first asset\", href: \"/launchpad/single-editions\" }}\n emptyIcon={<ImageIcon className=\"h-7 w-7 text-muted-foreground\" />}\n skeletonNode={\n <div className={GRID}>\n {Array.from({ length: 10 }).map((_, i) => (\n <div key={i} className=\"animate-pulse overflow-hidden rounded-xl bg-muted\">\n <div className=\"aspect-square w-full bg-muted-foreground/10\" />\n <div className=\"space-y-2 p-3\">\n <div className=\"h-4 w-3/4 rounded bg-muted-foreground/10\" />\n <div className=\"h-3 w-1/2 rounded bg-muted-foreground/10\" />\n </div>\n </div>\n ))}\n </div>\n }\n >\n <div className={GRID}>\n {shown.map((token) => (\n <TokenCard\n key={`${token.contractAddress}-${token.tokenId}`}\n token={token}\n isOwner\n usdValue={usdFor(token, prices)}\n onList={actions.list}\n onTransfer={actions.transfer}\n onCancel={actions.cancel}\n onReport={setReportToken}\n />\n ))}\n </div>\n <LoadMoreSentinel hasMore={hasMore} isLoading={isLoading} onLoadMore={() => setPage((p) => p + 1)} />\n </EmptyOrError>\n {actions.dialogs}\n {reportToken && (\n <ReportDialog\n open={!!reportToken}\n onOpenChange={(open) => { if (!open) setReportToken(null); }}\n target={{ type: \"TOKEN\", contract: reportToken.contractAddress, tokenId: reportToken.tokenId, name: reportToken.metadata?.name ?? undefined }}\n />\n )}\n </>\n );\n}\n"],"mappings":"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","names":[]}
@@ -5,7 +5,7 @@ import { ImageIcon } from "lucide-react";
5
5
  import { EmptyOrError } from "./empty-or-error.js";
6
6
  import { LoadMoreSentinel } from "./load-more-sentinel.js";
7
7
  import { TokenCard } from "./token-card.js";
8
- import { useMedialaneApp } from "./medialane-app.js";
8
+ import { ReportDialog } from "./report-dialog.js";
9
9
  import { orderUsd } from "../utils/order-usd.js";
10
10
  import { useUsdPrices } from "../utils/use-usd-prices.js";
11
11
  import { useTokensByOwner } from "../utils/use-tokens.js";
@@ -16,7 +16,6 @@ function usdFor(token, prices) {
16
16
  return orderUsd(order?.price, prices);
17
17
  }
18
18
  function PortfolioAssets({ address, useActions }) {
19
- const { ReportDialog } = useMedialaneApp();
20
19
  const [page, setPage] = useState(1);
21
20
  const [all, setAll] = useState([]);
22
21
  const [reportToken, setReportToken] = useState(null);
@@ -63,7 +62,7 @@ function PortfolioAssets({ address, useActions }) {
63
62
  onList: actions.list,
64
63
  onTransfer: actions.transfer,
65
64
  onCancel: actions.cancel,
66
- onReport: ReportDialog ? setReportToken : void 0
65
+ onReport: setReportToken
67
66
  },
68
67
  `${token.contractAddress}-${token.tokenId}`
69
68
  )) }),
@@ -72,7 +71,7 @@ function PortfolioAssets({ address, useActions }) {
72
71
  }
73
72
  ),
74
73
  actions.dialogs,
75
- ReportDialog && reportToken && /* @__PURE__ */ jsx(
74
+ reportToken && /* @__PURE__ */ jsx(
76
75
  ReportDialog,
77
76
  {
78
77
  open: !!reportToken,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/portfolio-assets.tsx"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useState, type ReactNode } from \"react\";\nimport type { ApiToken } from \"@medialane/sdk\";\nimport { ImageIcon } from \"lucide-react\";\nimport { EmptyOrError } from \"./empty-or-error.js\";\nimport { LoadMoreSentinel } from \"./load-more-sentinel.js\";\nimport { TokenCard } from \"./token-card.js\";\nimport { useMedialaneApp } from \"./medialane-app.js\";\nimport { orderUsd } from \"../utils/order-usd.js\";\nimport { useUsdPrices } from \"../utils/use-usd-prices.js\";\nimport { useTokensByOwner } from \"../utils/use-tokens.js\";\n\nexport interface PortfolioAssetActions {\n list: (token: ApiToken) => void;\n transfer: (token: ApiToken) => void;\n cancel: (token: ApiToken) => void;\n dialogs?: ReactNode;\n}\n\nexport type UsePortfolioAssetActions = (context: { refresh: () => void }) => PortfolioAssetActions;\n\nconst PAGE_SIZE = 20;\nconst GRID = \"grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5 gap-4\";\n\nfunction usdFor(token: ApiToken, prices: ReturnType<typeof useUsdPrices>): string | null {\n const order = token.activeOrders?.find((o) => o.offer.itemType === \"ERC721\" || o.offer.itemType === \"ERC1155\");\n return orderUsd(order?.price, prices);\n}\n\nexport function PortfolioAssets({ address, useActions }: { address: string; useActions: UsePortfolioAssetActions }) {\n const { ReportDialog } = useMedialaneApp();\n const [page, setPage] = useState(1);\n const [all, setAll] = useState<ApiToken[]>([]);\n const [reportToken, setReportToken] = useState<ApiToken | null>(null);\n const { tokens, meta, isLoading, error, mutate } = useTokensByOwner(address, page, PAGE_SIZE);\n const prices = useUsdPrices();\n\n useEffect(() => setAll((prev) => (page === 1 ? tokens : [...prev, ...tokens])), [tokens, page]);\n useEffect(() => { setPage(1); setAll([]); }, [address]);\n\n const actions = useActions({ refresh: () => { setPage(1); setAll([]); void mutate(); } });\n const shown = page === 1 ? tokens : all;\n const hasMore = meta ? (meta.total ?? 0) > shown.length : false;\n\n return (\n <>\n <EmptyOrError\n isLoading={isLoading && page === 1}\n error={error}\n isEmpty={shown.length === 0 && !isLoading}\n onRetry={() => void mutate()}\n emptyTitle=\"No assets yet\"\n emptyDescription=\"Create your first asset to get started.\"\n emptyCta={{ label: \"Create your first asset\", href: \"/launchpad/single-editions\" }}\n emptyIcon={<ImageIcon className=\"h-7 w-7 text-muted-foreground\" />}\n skeletonNode={\n <div className={GRID}>\n {Array.from({ length: 10 }).map((_, i) => (\n <div key={i} className=\"animate-pulse overflow-hidden rounded-xl bg-muted\">\n <div className=\"aspect-square w-full bg-muted-foreground/10\" />\n <div className=\"space-y-2 p-3\">\n <div className=\"h-4 w-3/4 rounded bg-muted-foreground/10\" />\n <div className=\"h-3 w-1/2 rounded bg-muted-foreground/10\" />\n </div>\n </div>\n ))}\n </div>\n }\n >\n <div className={GRID}>\n {shown.map((token) => (\n <TokenCard\n key={`${token.contractAddress}-${token.tokenId}`}\n token={token}\n isOwner\n usdValue={usdFor(token, prices)}\n onList={actions.list}\n onTransfer={actions.transfer}\n onCancel={actions.cancel}\n onReport={ReportDialog ? setReportToken : undefined}\n />\n ))}\n </div>\n <LoadMoreSentinel hasMore={hasMore} isLoading={isLoading} onLoadMore={() => setPage((p) => p + 1)} />\n </EmptyOrError>\n {actions.dialogs}\n {ReportDialog && reportToken && (\n <ReportDialog\n open={!!reportToken}\n onOpenChange={(open) => { if (!open) setReportToken(null); }}\n target={{ type: \"TOKEN\", contract: reportToken.contractAddress, tokenId: reportToken.tokenId, name: reportToken.metadata?.name ?? undefined }}\n />\n )}\n </>\n );\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/components/portfolio-assets.tsx"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useState, type ReactNode } from \"react\";\nimport type { ApiToken } from \"@medialane/sdk\";\nimport { ImageIcon } from \"lucide-react\";\nimport { EmptyOrError } from \"./empty-or-error.js\";\nimport { LoadMoreSentinel } from \"./load-more-sentinel.js\";\nimport { TokenCard } from \"./token-card.js\";\nimport { ReportDialog } from \"./report-dialog.js\";\nimport { orderUsd } from \"../utils/order-usd.js\";\nimport { useUsdPrices } from \"../utils/use-usd-prices.js\";\nimport { useTokensByOwner } from \"../utils/use-tokens.js\";\n\nexport interface PortfolioAssetActions {\n list: (token: ApiToken) => void;\n transfer: (token: ApiToken) => void;\n cancel: (token: ApiToken) => void;\n dialogs?: ReactNode;\n}\n\nexport type UsePortfolioAssetActions = (context: { refresh: () => void }) => PortfolioAssetActions;\n\nconst PAGE_SIZE = 20;\nconst GRID = \"grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5 gap-4\";\n\nfunction usdFor(token: ApiToken, prices: ReturnType<typeof useUsdPrices>): string | null {\n const order = token.activeOrders?.find((o) => o.offer.itemType === \"ERC721\" || o.offer.itemType === \"ERC1155\");\n return orderUsd(order?.price, prices);\n}\n\nexport function PortfolioAssets({ address, useActions }: { address: string; useActions: UsePortfolioAssetActions }) {\n const [page, setPage] = useState(1);\n const [all, setAll] = useState<ApiToken[]>([]);\n const [reportToken, setReportToken] = useState<ApiToken | null>(null);\n const { tokens, meta, isLoading, error, mutate } = useTokensByOwner(address, page, PAGE_SIZE);\n const prices = useUsdPrices();\n\n useEffect(() => setAll((prev) => (page === 1 ? tokens : [...prev, ...tokens])), [tokens, page]);\n useEffect(() => { setPage(1); setAll([]); }, [address]);\n\n const actions = useActions({ refresh: () => { setPage(1); setAll([]); void mutate(); } });\n const shown = page === 1 ? tokens : all;\n const hasMore = meta ? (meta.total ?? 0) > shown.length : false;\n\n return (\n <>\n <EmptyOrError\n isLoading={isLoading && page === 1}\n error={error}\n isEmpty={shown.length === 0 && !isLoading}\n onRetry={() => void mutate()}\n emptyTitle=\"No assets yet\"\n emptyDescription=\"Create your first asset to get started.\"\n emptyCta={{ label: \"Create your first asset\", href: \"/launchpad/single-editions\" }}\n emptyIcon={<ImageIcon className=\"h-7 w-7 text-muted-foreground\" />}\n skeletonNode={\n <div className={GRID}>\n {Array.from({ length: 10 }).map((_, i) => (\n <div key={i} className=\"animate-pulse overflow-hidden rounded-xl bg-muted\">\n <div className=\"aspect-square w-full bg-muted-foreground/10\" />\n <div className=\"space-y-2 p-3\">\n <div className=\"h-4 w-3/4 rounded bg-muted-foreground/10\" />\n <div className=\"h-3 w-1/2 rounded bg-muted-foreground/10\" />\n </div>\n </div>\n ))}\n </div>\n }\n >\n <div className={GRID}>\n {shown.map((token) => (\n <TokenCard\n key={`${token.contractAddress}-${token.tokenId}`}\n token={token}\n isOwner\n usdValue={usdFor(token, prices)}\n onList={actions.list}\n onTransfer={actions.transfer}\n onCancel={actions.cancel}\n onReport={setReportToken}\n />\n ))}\n </div>\n <LoadMoreSentinel hasMore={hasMore} isLoading={isLoading} onLoadMore={() => setPage((p) => p + 1)} />\n </EmptyOrError>\n {actions.dialogs}\n {reportToken && (\n <ReportDialog\n open={!!reportToken}\n onOpenChange={(open) => { if (!open) setReportToken(null); }}\n target={{ type: \"TOKEN\", contract: reportToken.contractAddress, tokenId: reportToken.tokenId, name: reportToken.metadata?.name ?? undefined }}\n />\n )}\n </>\n );\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,191 @@
1
+ "use strict";
2
+ "use client";
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") {
13
+ for (let key of __getOwnPropNames(from))
14
+ if (!__hasOwnProp.call(to, key) && key !== except)
15
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
+ }
17
+ return to;
18
+ };
19
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
20
+ var report_dialog_exports = {};
21
+ __export(report_dialog_exports, {
22
+ ReportDialog: () => ReportDialog
23
+ });
24
+ module.exports = __toCommonJS(report_dialog_exports);
25
+ var import_jsx_runtime = require("react/jsx-runtime");
26
+ var import_react = require("react");
27
+ var import_lucide_react = require("lucide-react");
28
+ var import_sdk = require("@medialane/sdk");
29
+ var import_dialog = require("./dialog.js");
30
+ var import_button = require("./button.js");
31
+ var import_checkbox = require("./checkbox.js");
32
+ var import_textarea = require("./textarea.js");
33
+ var import_label = require("./label.js");
34
+ var import_medialane_app = require("./medialane-app.js");
35
+ var import_describe_error = require("../utils/describe-error.js");
36
+ const CATEGORIES = [
37
+ { value: "COPYRIGHT_PIRACY", label: "Copyright / Piracy" },
38
+ { value: "VIOLENCE_GRAPHIC", label: "Violence / Graphic content" },
39
+ { value: "HATE_SPEECH", label: "Hate speech" },
40
+ { value: "SCAM_FRAUD", label: "Scam / Fraud" },
41
+ { value: "SPAM", label: "Spam" },
42
+ { value: "NSFW", label: "NSFW / Adult content" },
43
+ { value: "OTHER", label: "Other" }
44
+ ];
45
+ function ReportDialog({ target, open, onOpenChange }) {
46
+ const { getClient, ensureSignedIn } = (0, import_medialane_app.useMedialaneApp)();
47
+ const [categories, setCategories] = (0, import_react.useState)([]);
48
+ const [description, setDescription] = (0, import_react.useState)("");
49
+ const [submitStep, setSubmitStep] = (0, import_react.useState)("idle");
50
+ const [submitError, setSubmitError] = (0, import_react.useState)(null);
51
+ const toggleCategory = (value) => {
52
+ setCategories(
53
+ (prev) => prev.includes(value) ? prev.filter((c) => c !== value) : [...prev, value]
54
+ );
55
+ };
56
+ const close = () => {
57
+ setCategories([]);
58
+ setDescription("");
59
+ setSubmitStep("idle");
60
+ setSubmitError(null);
61
+ onOpenChange(false);
62
+ };
63
+ const handleOpenChange = (next) => {
64
+ if (!next && submitStep !== "submitting") close();
65
+ };
66
+ const handleSubmit = async () => {
67
+ if (categories.length === 0 || submitStep === "submitting") return;
68
+ setSubmitStep("submitting");
69
+ setSubmitError(null);
70
+ try {
71
+ await ensureSignedIn?.();
72
+ await getClient().api.platform.submitReport({
73
+ targetType: target.type,
74
+ categories,
75
+ description: description.trim() || void 0,
76
+ ...target.type === "TOKEN" ? { targetContract: target.contract, targetTokenId: target.tokenId } : {},
77
+ ...target.type === "COLLECTION" ? { targetContract: target.contract } : {},
78
+ ...target.type === "CREATOR" ? { targetAddress: target.address } : {},
79
+ ...target.type === "COMMENT" ? { targetId: target.commentId } : {}
80
+ });
81
+ setSubmitStep("success");
82
+ } catch (err) {
83
+ setSubmitStep("error");
84
+ if (err instanceof import_sdk.MedialaneApiError && err.status === 409) {
85
+ setSubmitError("You've already reported this content.");
86
+ } else if (err instanceof import_sdk.MedialaneApiError && err.status === 429) {
87
+ setSubmitError("Too many reports \u2014 please wait before trying again.");
88
+ } else {
89
+ setSubmitError((0, import_describe_error.describeError)(err).message);
90
+ }
91
+ }
92
+ };
93
+ const targetLabel = target.type !== "COMMENT" && target.name ? `"${target.name}"` : target.type.charAt(0) + target.type.slice(1).toLowerCase();
94
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dialog.Dialog, { open, onOpenChange: handleOpenChange, children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_dialog.DialogContent, { className: "max-w-md", children: [
95
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dialog.DialogHeader, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_dialog.DialogTitle, { className: "flex items-center gap-2", children: [
96
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.Flag, { className: "w-4 h-4" }),
97
+ "Report ",
98
+ targetLabel
99
+ ] }) }),
100
+ submitStep === "success" ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex flex-col items-center gap-4 py-4 text-center", children: [
101
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.CheckCircle, { className: "h-10 w-10 text-emerald-500" }),
102
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "space-y-1", children: [
103
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "font-semibold", children: "Report submitted" }),
104
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-sm text-muted-foreground", children: "Our team will review it." })
105
+ ] }),
106
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_button.Button, { className: "w-full", onClick: close, children: "Done" })
107
+ ] }) : submitStep === "error" ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex flex-col items-center gap-4 py-4 text-center", children: [
108
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.AlertCircle, { className: "h-10 w-10 text-destructive" }),
109
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-sm text-muted-foreground", children: submitError }),
110
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex gap-2 w-full", children: [
111
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_button.Button, { variant: "outline", className: "flex-1", onClick: () => {
112
+ setSubmitStep("idle");
113
+ setSubmitError(null);
114
+ }, children: "Try again" }),
115
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_button.Button, { variant: "outline", className: "flex-1", onClick: close, children: "Dismiss" })
116
+ ] })
117
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
118
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "space-y-4", children: [
119
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "space-y-3", children: [
120
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_label.Label, { className: "text-sm font-medium", children: [
121
+ "What's wrong with this content?",
122
+ " ",
123
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "text-muted-foreground font-normal", children: "(select all that apply)" })
124
+ ] }),
125
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "grid grid-cols-1 gap-2", children: CATEGORIES.map(({ value, label }) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex items-center space-x-2", children: [
126
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
127
+ import_checkbox.Checkbox,
128
+ {
129
+ id: value,
130
+ checked: categories.includes(value),
131
+ onCheckedChange: () => toggleCategory(value),
132
+ disabled: submitStep === "submitting"
133
+ }
134
+ ),
135
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
136
+ "label",
137
+ {
138
+ htmlFor: value,
139
+ className: "text-sm cursor-pointer leading-none",
140
+ children: label
141
+ }
142
+ )
143
+ ] }, value)) })
144
+ ] }),
145
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "space-y-2", children: [
146
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_label.Label, { htmlFor: "report-description", className: "text-sm font-medium", children: [
147
+ "Additional details",
148
+ " ",
149
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "text-muted-foreground font-normal", children: "(optional)" })
150
+ ] }),
151
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
152
+ import_textarea.Textarea,
153
+ {
154
+ id: "report-description",
155
+ placeholder: "Describe the issue in more detail (optional)",
156
+ value: description,
157
+ onChange: (e) => setDescription(e.target.value),
158
+ maxLength: 500,
159
+ className: "resize-none h-24",
160
+ disabled: submitStep === "submitting"
161
+ }
162
+ ),
163
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { className: "text-xs text-muted-foreground text-right", children: [
164
+ description.length,
165
+ "/500"
166
+ ] })
167
+ ] }),
168
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-xs text-muted-foreground", children: "Reports are reviewed by the Medialane DAO team. Content remains accessible onchain and via the permissionless dapp." })
169
+ ] }),
170
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_dialog.DialogFooter, { children: [
171
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_button.Button, { variant: "ghost", onClick: close, disabled: submitStep === "submitting", children: "Cancel" }),
172
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
173
+ import_button.Button,
174
+ {
175
+ onClick: handleSubmit,
176
+ disabled: categories.length === 0 || submitStep === "submitting",
177
+ children: submitStep === "submitting" ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
178
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.Loader2, { className: "h-4 w-4 mr-2 animate-spin" }),
179
+ "Submitting\u2026"
180
+ ] }) : "Submit Report"
181
+ }
182
+ )
183
+ ] })
184
+ ] })
185
+ ] }) });
186
+ }
187
+ // Annotate the CommonJS export names for ESM import in node:
188
+ 0 && (module.exports = {
189
+ ReportDialog
190
+ });
191
+ //# sourceMappingURL=report-dialog.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/components/report-dialog.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState } from \"react\";\nimport { AlertCircle, CheckCircle, Flag, Loader2 } from \"lucide-react\";\nimport { MedialaneApiError } from \"@medialane/sdk\";\nimport { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter } from \"./dialog.js\";\nimport { Button } from \"./button.js\";\nimport { Checkbox } from \"./checkbox.js\";\nimport { Textarea } from \"./textarea.js\";\nimport { Label } from \"./label.js\";\nimport { useMedialaneApp, type ReportTarget } from \"./medialane-app.js\";\nimport { describeError } from \"../utils/describe-error.js\";\n\nconst CATEGORIES = [\n { value: \"COPYRIGHT_PIRACY\", label: \"Copyright / Piracy\" },\n { value: \"VIOLENCE_GRAPHIC\", label: \"Violence / Graphic content\" },\n { value: \"HATE_SPEECH\", label: \"Hate speech\" },\n { value: \"SCAM_FRAUD\", label: \"Scam / Fraud\" },\n { value: \"SPAM\", label: \"Spam\" },\n { value: \"NSFW\", label: \"NSFW / Adult content\" },\n { value: \"OTHER\", label: \"Other\" },\n] as const;\n\nexport interface ReportDialogProps {\n target: ReportTarget;\n open: boolean;\n onOpenChange: (open: boolean) => void;\n}\n\nexport function ReportDialog({ target, open, onOpenChange }: ReportDialogProps) {\n const { getClient, ensureSignedIn } = useMedialaneApp();\n const [categories, setCategories] = useState<string[]>([]);\n const [description, setDescription] = useState(\"\");\n const [submitStep, setSubmitStep] = useState<\"idle\" | \"submitting\" | \"success\" | \"error\">(\"idle\");\n const [submitError, setSubmitError] = useState<string | null>(null);\n\n const toggleCategory = (value: string) => {\n setCategories((prev) =>\n prev.includes(value) ? prev.filter((c) => c !== value) : [...prev, value]\n );\n };\n\n const close = () => {\n setCategories([]);\n setDescription(\"\");\n setSubmitStep(\"idle\");\n setSubmitError(null);\n onOpenChange(false);\n };\n\n const handleOpenChange = (next: boolean) => {\n if (!next && submitStep !== \"submitting\") close();\n };\n\n const handleSubmit = async () => {\n if (categories.length === 0 || submitStep === \"submitting\") return;\n setSubmitStep(\"submitting\");\n setSubmitError(null);\n\n try {\n await ensureSignedIn?.();\n await getClient().api.platform.submitReport({\n targetType: target.type,\n categories,\n description: description.trim() || undefined,\n ...(target.type === \"TOKEN\" ? { targetContract: target.contract, targetTokenId: target.tokenId } : {}),\n ...(target.type === \"COLLECTION\" ? { targetContract: target.contract } : {}),\n ...(target.type === \"CREATOR\" ? { targetAddress: target.address } : {}),\n ...(target.type === \"COMMENT\" ? { targetId: target.commentId } : {}),\n });\n\n setSubmitStep(\"success\");\n } catch (err) {\n setSubmitStep(\"error\");\n if (err instanceof MedialaneApiError && err.status === 409) {\n setSubmitError(\"You've already reported this content.\");\n } else if (err instanceof MedialaneApiError && err.status === 429) {\n setSubmitError(\"Too many reports — please wait before trying again.\");\n } else {\n setSubmitError(describeError(err).message);\n }\n }\n };\n\n const targetLabel =\n target.type !== \"COMMENT\" && target.name\n ? `\"${target.name}\"`\n : target.type.charAt(0) + target.type.slice(1).toLowerCase();\n\n return (\n <Dialog open={open} onOpenChange={handleOpenChange}>\n <DialogContent className=\"max-w-md\">\n <DialogHeader>\n <DialogTitle className=\"flex items-center gap-2\">\n <Flag className=\"w-4 h-4\" />\n Report {targetLabel}\n </DialogTitle>\n </DialogHeader>\n\n {submitStep === \"success\" ? (\n <div className=\"flex flex-col items-center gap-4 py-4 text-center\">\n <CheckCircle className=\"h-10 w-10 text-emerald-500\" />\n <div className=\"space-y-1\">\n <p className=\"font-semibold\">Report submitted</p>\n <p className=\"text-sm text-muted-foreground\">Our team will review it.</p>\n </div>\n <Button className=\"w-full\" onClick={close}>Done</Button>\n </div>\n ) : submitStep === \"error\" ? (\n <div className=\"flex flex-col items-center gap-4 py-4 text-center\">\n <AlertCircle className=\"h-10 w-10 text-destructive\" />\n <p className=\"text-sm text-muted-foreground\">{submitError}</p>\n <div className=\"flex gap-2 w-full\">\n <Button variant=\"outline\" className=\"flex-1\" onClick={() => { setSubmitStep(\"idle\"); setSubmitError(null); }}>Try again</Button>\n <Button variant=\"outline\" className=\"flex-1\" onClick={close}>Dismiss</Button>\n </div>\n </div>\n ) : (\n <>\n <div className=\"space-y-4\">\n <div className=\"space-y-3\">\n <Label className=\"text-sm font-medium\">\n What&apos;s wrong with this content?{\" \"}\n <span className=\"text-muted-foreground font-normal\">\n (select all that apply)\n </span>\n </Label>\n <div className=\"grid grid-cols-1 gap-2\">\n {CATEGORIES.map(({ value, label }) => (\n <div key={value} className=\"flex items-center space-x-2\">\n <Checkbox\n id={value}\n checked={categories.includes(value)}\n onCheckedChange={() => toggleCategory(value)}\n disabled={submitStep === \"submitting\"}\n />\n <label\n htmlFor={value}\n className=\"text-sm cursor-pointer leading-none\"\n >\n {label}\n </label>\n </div>\n ))}\n </div>\n </div>\n\n <div className=\"space-y-2\">\n <Label htmlFor=\"report-description\" className=\"text-sm font-medium\">\n Additional details{\" \"}\n <span className=\"text-muted-foreground font-normal\">(optional)</span>\n </Label>\n <Textarea\n id=\"report-description\"\n placeholder=\"Describe the issue in more detail (optional)\"\n value={description}\n onChange={(e) => setDescription(e.target.value)}\n maxLength={500}\n className=\"resize-none h-24\"\n disabled={submitStep === \"submitting\"}\n />\n <p className=\"text-xs text-muted-foreground text-right\">\n {description.length}/500\n </p>\n </div>\n\n <p className=\"text-xs text-muted-foreground\">\n Reports are reviewed by the Medialane DAO team. Content remains\n accessible onchain and via the permissionless dapp.\n </p>\n </div>\n\n <DialogFooter>\n <Button variant=\"ghost\" onClick={close} disabled={submitStep === \"submitting\"}>\n Cancel\n </Button>\n <Button\n onClick={handleSubmit}\n disabled={categories.length === 0 || submitStep === \"submitting\"}\n >\n {submitStep === \"submitting\" ? <><Loader2 className=\"h-4 w-4 mr-2 animate-spin\" />Submitting…</> : \"Submit Report\"}\n </Button>\n </DialogFooter>\n </>\n )}\n </DialogContent>\n </Dialog>\n );\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,17 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { ReportTarget } from './medialane-app.cjs';
3
+ import 'react';
4
+ import '@medialane/sdk/starknet';
5
+ import './fast-mint/types.cjs';
6
+ import 'starknet';
7
+ import '@medialane/sdk';
8
+ import '../utils/ipfs.cjs';
9
+
10
+ interface ReportDialogProps {
11
+ target: ReportTarget;
12
+ open: boolean;
13
+ onOpenChange: (open: boolean) => void;
14
+ }
15
+ declare function ReportDialog({ target, open, onOpenChange }: ReportDialogProps): react_jsx_runtime.JSX.Element;
16
+
17
+ export { ReportDialog, type ReportDialogProps };
@@ -0,0 +1,17 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { ReportTarget } from './medialane-app.js';
3
+ import 'react';
4
+ import '@medialane/sdk/starknet';
5
+ import './fast-mint/types.js';
6
+ import 'starknet';
7
+ import '@medialane/sdk';
8
+ import '../utils/ipfs.js';
9
+
10
+ interface ReportDialogProps {
11
+ target: ReportTarget;
12
+ open: boolean;
13
+ onOpenChange: (open: boolean) => void;
14
+ }
15
+ declare function ReportDialog({ target, open, onOpenChange }: ReportDialogProps): react_jsx_runtime.JSX.Element;
16
+
17
+ export { ReportDialog, type ReportDialogProps };
@@ -0,0 +1,167 @@
1
+ "use client";
2
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
3
+ import { useState } from "react";
4
+ import { AlertCircle, CheckCircle, Flag, Loader2 } from "lucide-react";
5
+ import { MedialaneApiError } from "@medialane/sdk";
6
+ import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter } from "./dialog.js";
7
+ import { Button } from "./button.js";
8
+ import { Checkbox } from "./checkbox.js";
9
+ import { Textarea } from "./textarea.js";
10
+ import { Label } from "./label.js";
11
+ import { useMedialaneApp } from "./medialane-app.js";
12
+ import { describeError } from "../utils/describe-error.js";
13
+ const CATEGORIES = [
14
+ { value: "COPYRIGHT_PIRACY", label: "Copyright / Piracy" },
15
+ { value: "VIOLENCE_GRAPHIC", label: "Violence / Graphic content" },
16
+ { value: "HATE_SPEECH", label: "Hate speech" },
17
+ { value: "SCAM_FRAUD", label: "Scam / Fraud" },
18
+ { value: "SPAM", label: "Spam" },
19
+ { value: "NSFW", label: "NSFW / Adult content" },
20
+ { value: "OTHER", label: "Other" }
21
+ ];
22
+ function ReportDialog({ target, open, onOpenChange }) {
23
+ const { getClient, ensureSignedIn } = useMedialaneApp();
24
+ const [categories, setCategories] = useState([]);
25
+ const [description, setDescription] = useState("");
26
+ const [submitStep, setSubmitStep] = useState("idle");
27
+ const [submitError, setSubmitError] = useState(null);
28
+ const toggleCategory = (value) => {
29
+ setCategories(
30
+ (prev) => prev.includes(value) ? prev.filter((c) => c !== value) : [...prev, value]
31
+ );
32
+ };
33
+ const close = () => {
34
+ setCategories([]);
35
+ setDescription("");
36
+ setSubmitStep("idle");
37
+ setSubmitError(null);
38
+ onOpenChange(false);
39
+ };
40
+ const handleOpenChange = (next) => {
41
+ if (!next && submitStep !== "submitting") close();
42
+ };
43
+ const handleSubmit = async () => {
44
+ if (categories.length === 0 || submitStep === "submitting") return;
45
+ setSubmitStep("submitting");
46
+ setSubmitError(null);
47
+ try {
48
+ await ensureSignedIn?.();
49
+ await getClient().api.platform.submitReport({
50
+ targetType: target.type,
51
+ categories,
52
+ description: description.trim() || void 0,
53
+ ...target.type === "TOKEN" ? { targetContract: target.contract, targetTokenId: target.tokenId } : {},
54
+ ...target.type === "COLLECTION" ? { targetContract: target.contract } : {},
55
+ ...target.type === "CREATOR" ? { targetAddress: target.address } : {},
56
+ ...target.type === "COMMENT" ? { targetId: target.commentId } : {}
57
+ });
58
+ setSubmitStep("success");
59
+ } catch (err) {
60
+ setSubmitStep("error");
61
+ if (err instanceof MedialaneApiError && err.status === 409) {
62
+ setSubmitError("You've already reported this content.");
63
+ } else if (err instanceof MedialaneApiError && err.status === 429) {
64
+ setSubmitError("Too many reports \u2014 please wait before trying again.");
65
+ } else {
66
+ setSubmitError(describeError(err).message);
67
+ }
68
+ }
69
+ };
70
+ const targetLabel = target.type !== "COMMENT" && target.name ? `"${target.name}"` : target.type.charAt(0) + target.type.slice(1).toLowerCase();
71
+ return /* @__PURE__ */ jsx(Dialog, { open, onOpenChange: handleOpenChange, children: /* @__PURE__ */ jsxs(DialogContent, { className: "max-w-md", children: [
72
+ /* @__PURE__ */ jsx(DialogHeader, { children: /* @__PURE__ */ jsxs(DialogTitle, { className: "flex items-center gap-2", children: [
73
+ /* @__PURE__ */ jsx(Flag, { className: "w-4 h-4" }),
74
+ "Report ",
75
+ targetLabel
76
+ ] }) }),
77
+ submitStep === "success" ? /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-4 py-4 text-center", children: [
78
+ /* @__PURE__ */ jsx(CheckCircle, { className: "h-10 w-10 text-emerald-500" }),
79
+ /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
80
+ /* @__PURE__ */ jsx("p", { className: "font-semibold", children: "Report submitted" }),
81
+ /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: "Our team will review it." })
82
+ ] }),
83
+ /* @__PURE__ */ jsx(Button, { className: "w-full", onClick: close, children: "Done" })
84
+ ] }) : submitStep === "error" ? /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-4 py-4 text-center", children: [
85
+ /* @__PURE__ */ jsx(AlertCircle, { className: "h-10 w-10 text-destructive" }),
86
+ /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: submitError }),
87
+ /* @__PURE__ */ jsxs("div", { className: "flex gap-2 w-full", children: [
88
+ /* @__PURE__ */ jsx(Button, { variant: "outline", className: "flex-1", onClick: () => {
89
+ setSubmitStep("idle");
90
+ setSubmitError(null);
91
+ }, children: "Try again" }),
92
+ /* @__PURE__ */ jsx(Button, { variant: "outline", className: "flex-1", onClick: close, children: "Dismiss" })
93
+ ] })
94
+ ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
95
+ /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
96
+ /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
97
+ /* @__PURE__ */ jsxs(Label, { className: "text-sm font-medium", children: [
98
+ "What's wrong with this content?",
99
+ " ",
100
+ /* @__PURE__ */ jsx("span", { className: "text-muted-foreground font-normal", children: "(select all that apply)" })
101
+ ] }),
102
+ /* @__PURE__ */ jsx("div", { className: "grid grid-cols-1 gap-2", children: CATEGORIES.map(({ value, label }) => /* @__PURE__ */ jsxs("div", { className: "flex items-center space-x-2", children: [
103
+ /* @__PURE__ */ jsx(
104
+ Checkbox,
105
+ {
106
+ id: value,
107
+ checked: categories.includes(value),
108
+ onCheckedChange: () => toggleCategory(value),
109
+ disabled: submitStep === "submitting"
110
+ }
111
+ ),
112
+ /* @__PURE__ */ jsx(
113
+ "label",
114
+ {
115
+ htmlFor: value,
116
+ className: "text-sm cursor-pointer leading-none",
117
+ children: label
118
+ }
119
+ )
120
+ ] }, value)) })
121
+ ] }),
122
+ /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
123
+ /* @__PURE__ */ jsxs(Label, { htmlFor: "report-description", className: "text-sm font-medium", children: [
124
+ "Additional details",
125
+ " ",
126
+ /* @__PURE__ */ jsx("span", { className: "text-muted-foreground font-normal", children: "(optional)" })
127
+ ] }),
128
+ /* @__PURE__ */ jsx(
129
+ Textarea,
130
+ {
131
+ id: "report-description",
132
+ placeholder: "Describe the issue in more detail (optional)",
133
+ value: description,
134
+ onChange: (e) => setDescription(e.target.value),
135
+ maxLength: 500,
136
+ className: "resize-none h-24",
137
+ disabled: submitStep === "submitting"
138
+ }
139
+ ),
140
+ /* @__PURE__ */ jsxs("p", { className: "text-xs text-muted-foreground text-right", children: [
141
+ description.length,
142
+ "/500"
143
+ ] })
144
+ ] }),
145
+ /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: "Reports are reviewed by the Medialane DAO team. Content remains accessible onchain and via the permissionless dapp." })
146
+ ] }),
147
+ /* @__PURE__ */ jsxs(DialogFooter, { children: [
148
+ /* @__PURE__ */ jsx(Button, { variant: "ghost", onClick: close, disabled: submitStep === "submitting", children: "Cancel" }),
149
+ /* @__PURE__ */ jsx(
150
+ Button,
151
+ {
152
+ onClick: handleSubmit,
153
+ disabled: categories.length === 0 || submitStep === "submitting",
154
+ children: submitStep === "submitting" ? /* @__PURE__ */ jsxs(Fragment, { children: [
155
+ /* @__PURE__ */ jsx(Loader2, { className: "h-4 w-4 mr-2 animate-spin" }),
156
+ "Submitting\u2026"
157
+ ] }) : "Submit Report"
158
+ }
159
+ )
160
+ ] })
161
+ ] })
162
+ ] }) });
163
+ }
164
+ export {
165
+ ReportDialog
166
+ };
167
+ //# sourceMappingURL=report-dialog.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/components/report-dialog.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState } from \"react\";\nimport { AlertCircle, CheckCircle, Flag, Loader2 } from \"lucide-react\";\nimport { MedialaneApiError } from \"@medialane/sdk\";\nimport { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter } from \"./dialog.js\";\nimport { Button } from \"./button.js\";\nimport { Checkbox } from \"./checkbox.js\";\nimport { Textarea } from \"./textarea.js\";\nimport { Label } from \"./label.js\";\nimport { useMedialaneApp, type ReportTarget } from \"./medialane-app.js\";\nimport { describeError } from \"../utils/describe-error.js\";\n\nconst CATEGORIES = [\n { value: \"COPYRIGHT_PIRACY\", label: \"Copyright / Piracy\" },\n { value: \"VIOLENCE_GRAPHIC\", label: \"Violence / Graphic content\" },\n { value: \"HATE_SPEECH\", label: \"Hate speech\" },\n { value: \"SCAM_FRAUD\", label: \"Scam / Fraud\" },\n { value: \"SPAM\", label: \"Spam\" },\n { value: \"NSFW\", label: \"NSFW / Adult content\" },\n { value: \"OTHER\", label: \"Other\" },\n] as const;\n\nexport interface ReportDialogProps {\n target: ReportTarget;\n open: boolean;\n onOpenChange: (open: boolean) => void;\n}\n\nexport function ReportDialog({ target, open, onOpenChange }: ReportDialogProps) {\n const { getClient, ensureSignedIn } = useMedialaneApp();\n const [categories, setCategories] = useState<string[]>([]);\n const [description, setDescription] = useState(\"\");\n const [submitStep, setSubmitStep] = useState<\"idle\" | \"submitting\" | \"success\" | \"error\">(\"idle\");\n const [submitError, setSubmitError] = useState<string | null>(null);\n\n const toggleCategory = (value: string) => {\n setCategories((prev) =>\n prev.includes(value) ? prev.filter((c) => c !== value) : [...prev, value]\n );\n };\n\n const close = () => {\n setCategories([]);\n setDescription(\"\");\n setSubmitStep(\"idle\");\n setSubmitError(null);\n onOpenChange(false);\n };\n\n const handleOpenChange = (next: boolean) => {\n if (!next && submitStep !== \"submitting\") close();\n };\n\n const handleSubmit = async () => {\n if (categories.length === 0 || submitStep === \"submitting\") return;\n setSubmitStep(\"submitting\");\n setSubmitError(null);\n\n try {\n await ensureSignedIn?.();\n await getClient().api.platform.submitReport({\n targetType: target.type,\n categories,\n description: description.trim() || undefined,\n ...(target.type === \"TOKEN\" ? { targetContract: target.contract, targetTokenId: target.tokenId } : {}),\n ...(target.type === \"COLLECTION\" ? { targetContract: target.contract } : {}),\n ...(target.type === \"CREATOR\" ? { targetAddress: target.address } : {}),\n ...(target.type === \"COMMENT\" ? { targetId: target.commentId } : {}),\n });\n\n setSubmitStep(\"success\");\n } catch (err) {\n setSubmitStep(\"error\");\n if (err instanceof MedialaneApiError && err.status === 409) {\n setSubmitError(\"You've already reported this content.\");\n } else if (err instanceof MedialaneApiError && err.status === 429) {\n setSubmitError(\"Too many reports — please wait before trying again.\");\n } else {\n setSubmitError(describeError(err).message);\n }\n }\n };\n\n const targetLabel =\n target.type !== \"COMMENT\" && target.name\n ? `\"${target.name}\"`\n : target.type.charAt(0) + target.type.slice(1).toLowerCase();\n\n return (\n <Dialog open={open} onOpenChange={handleOpenChange}>\n <DialogContent className=\"max-w-md\">\n <DialogHeader>\n <DialogTitle className=\"flex items-center gap-2\">\n <Flag className=\"w-4 h-4\" />\n Report {targetLabel}\n </DialogTitle>\n </DialogHeader>\n\n {submitStep === \"success\" ? (\n <div className=\"flex flex-col items-center gap-4 py-4 text-center\">\n <CheckCircle className=\"h-10 w-10 text-emerald-500\" />\n <div className=\"space-y-1\">\n <p className=\"font-semibold\">Report submitted</p>\n <p className=\"text-sm text-muted-foreground\">Our team will review it.</p>\n </div>\n <Button className=\"w-full\" onClick={close}>Done</Button>\n </div>\n ) : submitStep === \"error\" ? (\n <div className=\"flex flex-col items-center gap-4 py-4 text-center\">\n <AlertCircle className=\"h-10 w-10 text-destructive\" />\n <p className=\"text-sm text-muted-foreground\">{submitError}</p>\n <div className=\"flex gap-2 w-full\">\n <Button variant=\"outline\" className=\"flex-1\" onClick={() => { setSubmitStep(\"idle\"); setSubmitError(null); }}>Try again</Button>\n <Button variant=\"outline\" className=\"flex-1\" onClick={close}>Dismiss</Button>\n </div>\n </div>\n ) : (\n <>\n <div className=\"space-y-4\">\n <div className=\"space-y-3\">\n <Label className=\"text-sm font-medium\">\n What&apos;s wrong with this content?{\" \"}\n <span className=\"text-muted-foreground font-normal\">\n (select all that apply)\n </span>\n </Label>\n <div className=\"grid grid-cols-1 gap-2\">\n {CATEGORIES.map(({ value, label }) => (\n <div key={value} className=\"flex items-center space-x-2\">\n <Checkbox\n id={value}\n checked={categories.includes(value)}\n onCheckedChange={() => toggleCategory(value)}\n disabled={submitStep === \"submitting\"}\n />\n <label\n htmlFor={value}\n className=\"text-sm cursor-pointer leading-none\"\n >\n {label}\n </label>\n </div>\n ))}\n </div>\n </div>\n\n <div className=\"space-y-2\">\n <Label htmlFor=\"report-description\" className=\"text-sm font-medium\">\n Additional details{\" \"}\n <span className=\"text-muted-foreground font-normal\">(optional)</span>\n </Label>\n <Textarea\n id=\"report-description\"\n placeholder=\"Describe the issue in more detail (optional)\"\n value={description}\n onChange={(e) => setDescription(e.target.value)}\n maxLength={500}\n className=\"resize-none h-24\"\n disabled={submitStep === \"submitting\"}\n />\n <p className=\"text-xs text-muted-foreground text-right\">\n {description.length}/500\n </p>\n </div>\n\n <p className=\"text-xs text-muted-foreground\">\n Reports are reviewed by the Medialane DAO team. Content remains\n accessible onchain and via the permissionless dapp.\n </p>\n </div>\n\n <DialogFooter>\n <Button variant=\"ghost\" onClick={close} disabled={submitStep === \"submitting\"}>\n Cancel\n </Button>\n <Button\n onClick={handleSubmit}\n disabled={categories.length === 0 || submitStep === \"submitting\"}\n >\n {submitStep === \"submitting\" ? <><Loader2 className=\"h-4 w-4 mr-2 animate-spin\" />Submitting…</> : \"Submit Report\"}\n </Button>\n </DialogFooter>\n </>\n )}\n </DialogContent>\n </Dialog>\n );\n}\n"],"mappings":"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","names":[]}
package/dist/index.cjs CHANGED
@@ -321,6 +321,7 @@ __export(index_exports, {
321
321
  RemixBrowsePage: () => import_remix_browse_page.RemixBrowsePage,
322
322
  RemixMint: () => import_remix_mint.RemixMint,
323
323
  RemixesTab: () => import_remixes_tab.RemixesTab,
324
+ ReportDialog: () => import_report_dialog.ReportDialog,
324
325
  ResultThumbnail: () => import_result_thumbnail.ResultThumbnail,
325
326
  RewardEarned: () => import_reward_earned.RewardEarned,
326
327
  RewardsDashboard: () => import_rewards_dashboard.RewardsDashboard,
@@ -682,6 +683,7 @@ var import_drop_action_box = require("./components/drop/page/drop-action-box.js"
682
683
  var import_drop_activity = require("./components/drop/page/drop-activity.js");
683
684
  var import_claim_proof = require("./utils/drop/claim-proof.js");
684
685
  var import_medialane_app = require("./components/medialane-app.js");
686
+ var import_report_dialog = require("./components/report-dialog.js");
685
687
  var import_run_intent_calls = require("./utils/run-intent-calls.js");
686
688
  var import_gated_content_types = require("./data/gated-content-types.js");
687
689
  var import_collapsible_section = require("./components/collapsible-section.js");
@@ -1176,6 +1178,7 @@ var import_asset_accents = require("./utils/asset-accents.js");
1176
1178
  RemixBrowsePage,
1177
1179
  RemixMint,
1178
1180
  RemixesTab,
1181
+ ReportDialog,
1179
1182
  ResultThumbnail,
1180
1183
  RewardEarned,
1181
1184
  RewardsDashboard,