@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.
- package/dist/components/asset-page.cjs +3 -2
- package/dist/components/asset-page.cjs.map +1 -1
- package/dist/components/asset-page.js +3 -2
- package/dist/components/asset-page.js.map +1 -1
- package/dist/components/badge.d.cts +1 -1
- package/dist/components/badge.d.ts +1 -1
- package/dist/components/button.d.cts +1 -1
- package/dist/components/button.d.ts +1 -1
- package/dist/components/collection-page.cjs +3 -2
- package/dist/components/collection-page.cjs.map +1 -1
- package/dist/components/collection-page.js +3 -2
- package/dist/components/collection-page.js.map +1 -1
- package/dist/components/comments-section.cjs +3 -3
- package/dist/components/comments-section.cjs.map +1 -1
- package/dist/components/comments-section.js +2 -2
- package/dist/components/comments-section.js.map +1 -1
- package/dist/components/creator-page.cjs +6 -5
- package/dist/components/creator-page.cjs.map +1 -1
- package/dist/components/creator-page.js +5 -4
- package/dist/components/creator-page.js.map +1 -1
- package/dist/components/launchpad/edition-mint-schema.d.cts +2 -2
- package/dist/components/launchpad/edition-mint-schema.d.ts +2 -2
- package/dist/components/listing-card-menu.cjs +10 -13
- package/dist/components/listing-card-menu.cjs.map +1 -1
- package/dist/components/listing-card-menu.js +10 -13
- package/dist/components/listing-card-menu.js.map +1 -1
- package/dist/components/medialane-app.cjs.map +1 -1
- package/dist/components/medialane-app.d.cts +2 -8
- package/dist/components/medialane-app.d.ts +2 -8
- package/dist/components/medialane-app.js.map +1 -1
- package/dist/components/portfolio-assets.cjs +4 -5
- package/dist/components/portfolio-assets.cjs.map +1 -1
- package/dist/components/portfolio-assets.js +3 -4
- package/dist/components/portfolio-assets.js.map +1 -1
- package/dist/components/report-dialog.cjs +191 -0
- package/dist/components/report-dialog.cjs.map +1 -0
- package/dist/components/report-dialog.d.cts +17 -0
- package/dist/components/report-dialog.d.ts +17 -0
- package/dist/components/report-dialog.js +167 -0
- package/dist/components/report-dialog.js.map +1 -0
- package/dist/index.cjs +3 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- 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 {
|
|
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":";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AA6CI;AA3CJ,mBAAoD;AAEpD,0BAA0B;AAC1B,4BAA6B;AAC7B,gCAAiC;AACjC,wBAA0B;AAC1B,2BAA6B;AAC7B,uBAAyB;AACzB,4BAA6B;AAC7B,wBAAiC;AAWjC,MAAM,YAAY;AAClB,MAAM,OAAO;AAEb,SAAS,OAAO,OAAiB,QAAwD;AACvF,QAAM,QAAQ,MAAM,cAAc,KAAK,CAAC,MAAM,EAAE,MAAM,aAAa,YAAY,EAAE,MAAM,aAAa,SAAS;AAC7G,aAAO,2BAAS,OAAO,OAAO,MAAM;AACtC;AAEO,SAAS,gBAAgB,EAAE,SAAS,WAAW,GAA8D;AAClH,QAAM,CAAC,MAAM,OAAO,QAAI,uBAAS,CAAC;AAClC,QAAM,CAAC,KAAK,MAAM,QAAI,uBAAqB,CAAC,CAAC;AAC7C,QAAM,CAAC,aAAa,cAAc,QAAI,uBAA0B,IAAI;AACpE,QAAM,EAAE,QAAQ,MAAM,WAAW,OAAO,OAAO,QAAI,oCAAiB,SAAS,MAAM,SAAS;AAC5F,QAAM,aAAS,oCAAa;AAE5B,8BAAU,MAAM,OAAO,CAAC,SAAU,SAAS,IAAI,SAAS,CAAC,GAAG,MAAM,GAAG,MAAM,CAAE,GAAG,CAAC,QAAQ,IAAI,CAAC;AAC9F,8BAAU,MAAM;AAAE,YAAQ,CAAC;AAAG,WAAO,CAAC,CAAC;AAAA,EAAG,GAAG,CAAC,OAAO,CAAC;AAEtD,QAAM,UAAU,WAAW,EAAE,SAAS,MAAM;AAAE,YAAQ,CAAC;AAAG,WAAO,CAAC,CAAC;AAAG,SAAK,OAAO;AAAA,EAAG,EAAE,CAAC;AACxF,QAAM,QAAQ,SAAS,IAAI,SAAS;AACpC,QAAM,UAAU,QAAQ,KAAK,SAAS,KAAK,MAAM,SAAS;AAE1D,SACE,4EACE;AAAA;AAAA,MAAC;AAAA;AAAA,QACC,WAAW,aAAa,SAAS;AAAA,QACjC;AAAA,QACA,SAAS,MAAM,WAAW,KAAK,CAAC;AAAA,QAChC,SAAS,MAAM,KAAK,OAAO;AAAA,QAC3B,YAAW;AAAA,QACX,kBAAiB;AAAA,QACjB,UAAU,EAAE,OAAO,2BAA2B,MAAM,6BAA6B;AAAA,QACjF,WAAW,4CAAC,iCAAU,WAAU,iCAAgC;AAAA,QAChE,cACE,4CAAC,SAAI,WAAW,MACb,gBAAM,KAAK,EAAE,QAAQ,GAAG,CAAC,EAAE,IAAI,CAAC,GAAG,MAClC,6CAAC,SAAY,WAAU,qDACrB;AAAA,sDAAC,SAAI,WAAU,+CAA8C;AAAA,UAC7D,6CAAC,SAAI,WAAU,iBACb;AAAA,wDAAC,SAAI,WAAU,4CAA2C;AAAA,YAC1D,4CAAC,SAAI,WAAU,4CAA2C;AAAA,aAC5D;AAAA,aALQ,CAMV,CACD,GACH;AAAA,QAGF;AAAA,sDAAC,SAAI,WAAW,MACb,gBAAM,IAAI,CAAC,UACV;AAAA,YAAC;AAAA;AAAA,cAEC;AAAA,cACA,SAAO;AAAA,cACP,UAAU,OAAO,OAAO,MAAM;AAAA,cAC9B,QAAQ,QAAQ;AAAA,cAChB,YAAY,QAAQ;AAAA,cACpB,UAAU,QAAQ;AAAA,cAClB,UAAU;AAAA;AAAA,YAPL,GAAG,MAAM,eAAe,IAAI,MAAM,OAAO;AAAA,UAQhD,CACD,GACH;AAAA,UACA,4CAAC,8CAAiB,SAAkB,WAAsB,YAAY,MAAM,QAAQ,CAAC,MAAM,IAAI,CAAC,GAAG;AAAA;AAAA;AAAA,IACrG;AAAA,IACC,QAAQ;AAAA,IACR,eACC;AAAA,MAAC;AAAA;AAAA,QACC,MAAM,CAAC,CAAC;AAAA,QACR,cAAc,CAAC,SAAS;AAAE,cAAI,CAAC,KAAM,gBAAe,IAAI;AAAA,QAAG;AAAA,QAC3D,QAAQ,EAAE,MAAM,SAAS,UAAU,YAAY,iBAAiB,SAAS,YAAY,SAAS,MAAM,YAAY,UAAU,QAAQ,OAAU;AAAA;AAAA,IAC9I;AAAA,KAEJ;AAEJ;","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 {
|
|
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:
|
|
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
|
-
|
|
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 {
|
|
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'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":";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AA6FU;AA3FV,mBAAyB;AACzB,0BAAwD;AACxD,iBAAkC;AAClC,oBAA+E;AAC/E,oBAAuB;AACvB,sBAAyB;AACzB,sBAAyB;AACzB,mBAAsB;AACtB,2BAAmD;AACnD,4BAA8B;AAE9B,MAAM,aAAa;AAAA,EACjB,EAAE,OAAO,oBAAoB,OAAO,qBAAqB;AAAA,EACzD,EAAE,OAAO,oBAAoB,OAAO,6BAA6B;AAAA,EACjE,EAAE,OAAO,eAAe,OAAO,cAAc;AAAA,EAC7C,EAAE,OAAO,cAAc,OAAO,eAAe;AAAA,EAC7C,EAAE,OAAO,QAAQ,OAAO,OAAO;AAAA,EAC/B,EAAE,OAAO,QAAQ,OAAO,uBAAuB;AAAA,EAC/C,EAAE,OAAO,SAAS,OAAO,QAAQ;AACnC;AAQO,SAAS,aAAa,EAAE,QAAQ,MAAM,aAAa,GAAsB;AAC9E,QAAM,EAAE,WAAW,eAAe,QAAI,sCAAgB;AACtD,QAAM,CAAC,YAAY,aAAa,QAAI,uBAAmB,CAAC,CAAC;AACzD,QAAM,CAAC,aAAa,cAAc,QAAI,uBAAS,EAAE;AACjD,QAAM,CAAC,YAAY,aAAa,QAAI,uBAAsD,MAAM;AAChG,QAAM,CAAC,aAAa,cAAc,QAAI,uBAAwB,IAAI;AAElE,QAAM,iBAAiB,CAAC,UAAkB;AACxC;AAAA,MAAc,CAAC,SACb,KAAK,SAAS,KAAK,IAAI,KAAK,OAAO,CAAC,MAAM,MAAM,KAAK,IAAI,CAAC,GAAG,MAAM,KAAK;AAAA,IAC1E;AAAA,EACF;AAEA,QAAM,QAAQ,MAAM;AAClB,kBAAc,CAAC,CAAC;AAChB,mBAAe,EAAE;AACjB,kBAAc,MAAM;AACpB,mBAAe,IAAI;AACnB,iBAAa,KAAK;AAAA,EACpB;AAEA,QAAM,mBAAmB,CAAC,SAAkB;AAC1C,QAAI,CAAC,QAAQ,eAAe,aAAc,OAAM;AAAA,EAClD;AAEA,QAAM,eAAe,YAAY;AAC/B,QAAI,WAAW,WAAW,KAAK,eAAe,aAAc;AAC5D,kBAAc,YAAY;AAC1B,mBAAe,IAAI;AAEnB,QAAI;AACF,YAAM,iBAAiB;AACvB,YAAM,UAAU,EAAE,IAAI,SAAS,aAAa;AAAA,QACxC,YAAY,OAAO;AAAA,QACnB;AAAA,QACA,aAAa,YAAY,KAAK,KAAK;AAAA,QACnC,GAAI,OAAO,SAAS,UAAU,EAAE,gBAAgB,OAAO,UAAU,eAAe,OAAO,QAAQ,IAAI,CAAC;AAAA,QACpG,GAAI,OAAO,SAAS,eAAe,EAAE,gBAAgB,OAAO,SAAS,IAAI,CAAC;AAAA,QAC1E,GAAI,OAAO,SAAS,YAAY,EAAE,eAAe,OAAO,QAAQ,IAAI,CAAC;AAAA,QACrE,GAAI,OAAO,SAAS,YAAY,EAAE,UAAU,OAAO,UAAU,IAAI,CAAC;AAAA,MACpE,CAAC;AAEH,oBAAc,SAAS;AAAA,IACzB,SAAS,KAAK;AACZ,oBAAc,OAAO;AACrB,UAAI,eAAe,gCAAqB,IAAI,WAAW,KAAK;AAC1D,uBAAe,uCAAuC;AAAA,MACxD,WAAW,eAAe,gCAAqB,IAAI,WAAW,KAAK;AACjE,uBAAe,0DAAqD;AAAA,MACtE,OAAO;AACL,2BAAe,qCAAc,GAAG,EAAE,OAAO;AAAA,MAC3C;AAAA,IACF;AAAA,EACF;AAEA,QAAM,cACJ,OAAO,SAAS,aAAa,OAAO,OAChC,IAAI,OAAO,IAAI,MACf,OAAO,KAAK,OAAO,CAAC,IAAI,OAAO,KAAK,MAAM,CAAC,EAAE,YAAY;AAE/D,SACE,4CAAC,wBAAO,MAAY,cAAc,kBAChC,uDAAC,+BAAc,WAAU,YACvB;AAAA,gDAAC,8BACC,uDAAC,6BAAY,WAAU,2BACrB;AAAA,kDAAC,4BAAK,WAAU,WAAU;AAAA,MAAE;AAAA,MACpB;AAAA,OACV,GACF;AAAA,IAEC,eAAe,YACd,6CAAC,SAAI,WAAU,qDACb;AAAA,kDAAC,mCAAY,WAAU,8BAA6B;AAAA,MACpD,6CAAC,SAAI,WAAU,aACb;AAAA,oDAAC,OAAE,WAAU,iBAAgB,8BAAgB;AAAA,QAC7C,4CAAC,OAAE,WAAU,iCAAgC,sCAAwB;AAAA,SACvE;AAAA,MACA,4CAAC,wBAAO,WAAU,UAAS,SAAS,OAAO,kBAAI;AAAA,OACjD,IACE,eAAe,UACjB,6CAAC,SAAI,WAAU,qDACb;AAAA,kDAAC,mCAAY,WAAU,8BAA6B;AAAA,MACpD,4CAAC,OAAE,WAAU,iCAAiC,uBAAY;AAAA,MAC1D,6CAAC,SAAI,WAAU,qBACb;AAAA,oDAAC,wBAAO,SAAQ,WAAU,WAAU,UAAS,SAAS,MAAM;AAAE,wBAAc,MAAM;AAAG,yBAAe,IAAI;AAAA,QAAG,GAAG,uBAAS;AAAA,QACvH,4CAAC,wBAAO,SAAQ,WAAU,WAAU,UAAS,SAAS,OAAO,qBAAO;AAAA,SACtE;AAAA,OACF,IAEA,4EACE;AAAA,mDAAC,SAAI,WAAU,aACb;AAAA,qDAAC,SAAI,WAAU,aACb;AAAA,uDAAC,sBAAM,WAAU,uBAAsB;AAAA;AAAA,YACA;AAAA,YACrC,4CAAC,UAAK,WAAU,qCAAoC,qCAEpD;AAAA,aACF;AAAA,UACA,4CAAC,SAAI,WAAU,0BACZ,qBAAW,IAAI,CAAC,EAAE,OAAO,MAAM,MAC9B,6CAAC,SAAgB,WAAU,+BACzB;AAAA;AAAA,cAAC;AAAA;AAAA,gBACC,IAAI;AAAA,gBACJ,SAAS,WAAW,SAAS,KAAK;AAAA,gBAClC,iBAAiB,MAAM,eAAe,KAAK;AAAA,gBAC3C,UAAU,eAAe;AAAA;AAAA,YAC3B;AAAA,YACA;AAAA,cAAC;AAAA;AAAA,gBACC,SAAS;AAAA,gBACT,WAAU;AAAA,gBAET;AAAA;AAAA,YACH;AAAA,eAZQ,KAaV,CACD,GACH;AAAA,WACF;AAAA,QAEA,6CAAC,SAAI,WAAU,aACb;AAAA,uDAAC,sBAAM,SAAQ,sBAAqB,WAAU,uBAAsB;AAAA;AAAA,YAC/C;AAAA,YACnB,4CAAC,UAAK,WAAU,qCAAoC,wBAAU;AAAA,aAChE;AAAA,UACA;AAAA,YAAC;AAAA;AAAA,cACC,IAAG;AAAA,cACH,aAAY;AAAA,cACZ,OAAO;AAAA,cACP,UAAU,CAAC,MAAM,eAAe,EAAE,OAAO,KAAK;AAAA,cAC9C,WAAW;AAAA,cACX,WAAU;AAAA,cACV,UAAU,eAAe;AAAA;AAAA,UAC3B;AAAA,UACA,6CAAC,OAAE,WAAU,4CACV;AAAA,wBAAY;AAAA,YAAO;AAAA,aACtB;AAAA,WACF;AAAA,QAEA,4CAAC,OAAE,WAAU,iCAAgC,iIAG7C;AAAA,SACF;AAAA,MAEA,6CAAC,8BACC;AAAA,oDAAC,wBAAO,SAAQ,SAAQ,SAAS,OAAO,UAAU,eAAe,cAAc,oBAE/E;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACC,SAAS;AAAA,YACT,UAAU,WAAW,WAAW,KAAK,eAAe;AAAA,YAEnD,yBAAe,eAAe,4EAAE;AAAA,0DAAC,+BAAQ,WAAU,6BAA4B;AAAA,cAAE;AAAA,eAAW,IAAM;AAAA;AAAA,QACrG;AAAA,SACF;AAAA,OACF;AAAA,KAEJ,GACF;AAEJ;","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'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,
|