@medialane/ui 0.304.0 → 0.305.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/account-page.cjs +151 -0
- package/dist/components/account-page.cjs.map +1 -0
- package/dist/components/account-page.d.cts +15 -0
- package/dist/components/account-page.d.ts +15 -0
- package/dist/components/account-page.js +117 -0
- package/dist/components/account-page.js.map +1 -0
- package/dist/components/button.d.cts +1 -1
- package/dist/components/button.d.ts +1 -1
- package/dist/components/creator-page.cjs +47 -68
- package/dist/components/creator-page.cjs.map +1 -1
- package/dist/components/creator-page.d.cts +2 -3
- package/dist/components/creator-page.d.ts +2 -3
- package/dist/components/creator-page.js +48 -69
- package/dist/components/creator-page.js.map +1 -1
- package/dist/components/fast-mint/fast-mint.d.cts +2 -2
- package/dist/components/fast-mint/fast-mint.d.ts +2 -2
- package/dist/components/launchpad/edition-mint-schema.d.cts +2 -2
- package/dist/components/launchpad/edition-mint-schema.d.ts +2 -2
- package/dist/components/sheet.d.cts +1 -1
- package/dist/components/sheet.d.ts +1 -1
- package/dist/components/underline-tabs.cjs +62 -0
- package/dist/components/underline-tabs.cjs.map +1 -0
- package/dist/components/underline-tabs.d.cts +20 -0
- package/dist/components/underline-tabs.d.ts +20 -0
- package/dist/components/underline-tabs.js +28 -0
- package/dist/components/underline-tabs.js.map +1 -0
- package/dist/index.cjs +8 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.js +6 -1
- package/dist/index.js.map +1 -1
- package/dist/utils/media-wallet/use-erc20-balance.d.cts +1 -1
- package/dist/utils/media-wallet/use-erc20-balance.d.ts +1 -1
- package/dist/utils/query-keys.cjs +1 -0
- package/dist/utils/query-keys.cjs.map +1 -1
- package/dist/utils/query-keys.d.cts +1 -0
- package/dist/utils/query-keys.d.ts +1 -0
- package/dist/utils/query-keys.js +1 -0
- package/dist/utils/query-keys.js.map +1 -1
- package/dist/utils/use-tokens.cjs +23 -0
- package/dist/utils/use-tokens.cjs.map +1 -1
- package/dist/utils/use-tokens.d.cts +180 -1
- package/dist/utils/use-tokens.d.ts +180 -1
- package/dist/utils/use-tokens.js +23 -1
- package/dist/utils/use-tokens.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
"use client";
|
|
3
|
+
var __create = Object.create;
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
6
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
8
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
+
var __export = (target, all) => {
|
|
10
|
+
for (var name in all)
|
|
11
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
12
|
+
};
|
|
13
|
+
var __copyProps = (to, from, except, desc) => {
|
|
14
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
15
|
+
for (let key of __getOwnPropNames(from))
|
|
16
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
17
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
18
|
+
}
|
|
19
|
+
return to;
|
|
20
|
+
};
|
|
21
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
22
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
23
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
24
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
25
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
26
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
27
|
+
mod
|
|
28
|
+
));
|
|
29
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
30
|
+
var account_page_exports = {};
|
|
31
|
+
__export(account_page_exports, {
|
|
32
|
+
AccountPage: () => AccountPage
|
|
33
|
+
});
|
|
34
|
+
module.exports = __toCommonJS(account_page_exports);
|
|
35
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
36
|
+
var import_react = require("react");
|
|
37
|
+
var import_swr = __toESM(require("swr"), 1);
|
|
38
|
+
var import_lucide_react = require("lucide-react");
|
|
39
|
+
var import_load_more_sentinel = require("./load-more-sentinel.js");
|
|
40
|
+
var import_skeleton = require("./skeleton.js");
|
|
41
|
+
var import_tabs = require("./tabs.js");
|
|
42
|
+
var import_underline_tabs = require("./underline-tabs.js");
|
|
43
|
+
var import_address_display = require("./address-display.js");
|
|
44
|
+
var import_hidden_content_banner = require("./hidden-content-banner.js");
|
|
45
|
+
var import_tab_empty_state = require("./tab-empty-state.js");
|
|
46
|
+
var import_token_card = require("./token-card.js");
|
|
47
|
+
var import_collection_card = require("./collection-card.js");
|
|
48
|
+
var import_listing_card = require("./listing-card.js");
|
|
49
|
+
var import_listing_card_menu = require("./listing-card-menu.js");
|
|
50
|
+
var import_activity_timeline_row = require("./activity-timeline-row.js");
|
|
51
|
+
var import_more_menu = require("./more-menu.js");
|
|
52
|
+
var import_medialane_app = require("./medialane-app.js");
|
|
53
|
+
var import_report_dialog = require("./report-dialog.js");
|
|
54
|
+
var import_address = require("../utils/address.js");
|
|
55
|
+
var import_explorer_url = require("../utils/explorer-url.js");
|
|
56
|
+
var import_same_address = require("../utils/same-address.js");
|
|
57
|
+
var import_order_usd = require("../utils/order-usd.js");
|
|
58
|
+
var import_use_medialane_client = require("../utils/use-medialane-client.js");
|
|
59
|
+
var import_use_usd_prices = require("../utils/use-usd-prices.js");
|
|
60
|
+
var import_use_tokens = require("../utils/use-tokens.js");
|
|
61
|
+
var import_use_collections = require("../utils/use-collections.js");
|
|
62
|
+
var import_use_orders = require("../utils/use-orders.js");
|
|
63
|
+
var import_use_activities = require("../utils/use-activities.js");
|
|
64
|
+
const GRID = "grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5 gap-4";
|
|
65
|
+
const isNft = (itemType) => itemType === "ERC721" || itemType === "ERC1155";
|
|
66
|
+
function AccountPage({ address, useAssetActions, useMarketActions }) {
|
|
67
|
+
const { walletAddress } = (0, import_medialane_app.useMedialaneApp)();
|
|
68
|
+
const client = (0, import_use_medialane_client.useMedialaneClient)();
|
|
69
|
+
const prices = (0, import_use_usd_prices.useUsdPrices)();
|
|
70
|
+
const [activeTab, setActiveTab] = (0, import_react.useState)("assets");
|
|
71
|
+
const [reportOpen, setReportOpen] = (0, import_react.useState)(false);
|
|
72
|
+
const [reportToken, setReportToken] = (0, import_react.useState)(null);
|
|
73
|
+
const isOwner = !!walletAddress && (0, import_same_address.isSameAddress)(address, walletAddress);
|
|
74
|
+
const { tokens, total, isLoading: tokensLoading, isLoadingMore, hasMore, loadMore, mutate: refreshTokens } = (0, import_use_tokens.useOwnedTokens)(address);
|
|
75
|
+
const { collections, isLoading: collectionsLoading } = (0, import_use_collections.useCollectionsByOwner)(address);
|
|
76
|
+
const { orders, isLoading: ordersLoading } = (0, import_use_orders.useUserOrders)(address);
|
|
77
|
+
const { activities, isLoading: activitiesLoading } = (0, import_use_activities.useActivitiesByAddress)(activeTab === "activity" ? address : null);
|
|
78
|
+
const { data: hidden } = (0, import_swr.default)(`creator-hidden-${address}`, () => client.api.creators.isHidden(address).catch(() => false));
|
|
79
|
+
const actions = useAssetActions({ refresh: () => void refreshTokens() });
|
|
80
|
+
const market = useMarketActions();
|
|
81
|
+
const listings = orders.filter((o) => o.status === "ACTIVE" && isNft(o.offer.itemType));
|
|
82
|
+
const tabs = [
|
|
83
|
+
{ id: "assets", label: "Assets", icon: import_lucide_react.Image, count: total ?? void 0 },
|
|
84
|
+
{ id: "collections", label: "Collections", icon: import_lucide_react.LayoutGrid, count: collectionsLoading ? void 0 : collections.length },
|
|
85
|
+
{ id: "listings", label: "Listings", icon: import_lucide_react.ShoppingBag, count: ordersLoading ? void 0 : listings.length },
|
|
86
|
+
{ id: "activity", label: "Activity", icon: import_lucide_react.Activity }
|
|
87
|
+
];
|
|
88
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "min-h-screen overflow-x-hidden pb-20", children: [
|
|
89
|
+
hidden === true ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_hidden_content_banner.HiddenContentBanner, {}) : null,
|
|
90
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "space-y-2 px-6 pt-20 pb-6", children: [
|
|
91
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_address_display.AddressDisplay, { address, chars: 10, className: "text-2xl font-black tracking-tight tabular-nums sm:text-3xl" }),
|
|
92
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "inline-flex items-center gap-1.5 rounded-full bg-muted px-2.5 py-1 text-xs font-medium text-muted-foreground", children: [
|
|
93
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "h-1.5 w-1.5 rounded-full bg-brand-blue" }),
|
|
94
|
+
"Starknet"
|
|
95
|
+
] })
|
|
96
|
+
] }),
|
|
97
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
98
|
+
import_underline_tabs.UnderlineTabs,
|
|
99
|
+
{
|
|
100
|
+
tabs,
|
|
101
|
+
value: activeTab,
|
|
102
|
+
onValueChange: (id) => setActiveTab(id),
|
|
103
|
+
trailing: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_more_menu.MoreMenu, { explorerHref: `${import_explorer_url.EXPLORER_URL}/contract/${address}`, shareTitle: (0, import_address.shortenAddress)(address), onReport: () => setReportOpen(true) }),
|
|
104
|
+
children: [
|
|
105
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_tabs.TabsContent, { value: "assets", className: "mt-6 px-6", children: tokensLoading ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: GRID, children: Array.from({ length: 8 }).map((_, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_token_card.TokenCardSkeleton, {}, i)) }) : tokens.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_tab_empty_state.TabEmptyState, { icon: import_lucide_react.Image, heading: "No assets yet", body: "Works this account owns appear here." }) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
106
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: GRID, children: tokens.map((t) => {
|
|
107
|
+
const listing = t.activeOrders?.find((o) => isNft(o.offer.itemType));
|
|
108
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
109
|
+
import_token_card.TokenCard,
|
|
110
|
+
{
|
|
111
|
+
token: t,
|
|
112
|
+
isOwner,
|
|
113
|
+
usdValue: (0, import_order_usd.orderUsd)(listing?.price, prices),
|
|
114
|
+
onList: isOwner ? actions.list : void 0,
|
|
115
|
+
onTransfer: isOwner ? actions.transfer : void 0,
|
|
116
|
+
onCancel: isOwner ? actions.cancel : void 0,
|
|
117
|
+
onBuy: !isOwner && listing ? () => market.buy(listing) : void 0,
|
|
118
|
+
onOffer: isOwner ? void 0 : market.offer,
|
|
119
|
+
onReport: setReportToken
|
|
120
|
+
},
|
|
121
|
+
`${t.contractAddress}-${t.tokenId}`
|
|
122
|
+
);
|
|
123
|
+
}) }),
|
|
124
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_load_more_sentinel.LoadMoreSentinel, { hasMore, isLoading: isLoadingMore, onLoadMore: loadMore })
|
|
125
|
+
] }) }),
|
|
126
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_tabs.TabsContent, { value: "collections", className: "mt-6 px-6", children: collectionsLoading ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "grid grid-cols-2 gap-4 lg:grid-cols-3", children: Array.from({ length: 6 }).map((_, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_collection_card.CollectionCardSkeleton, {}, i)) }) : collections.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_tab_empty_state.TabEmptyState, { icon: import_lucide_react.LayoutGrid, heading: "No collections yet", body: "Collections this account owns appear here." }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "grid grid-cols-2 gap-4 lg:grid-cols-3", children: collections.map((c) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_collection_card.CollectionCard, { collection: c }, c.contractAddress)) }) }),
|
|
127
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_tabs.TabsContent, { value: "listings", className: "mt-6 px-6", children: ordersLoading ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: GRID, children: Array.from({ length: 4 }).map((_, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_listing_card.ListingCardSkeleton, {}, i)) }) : listings.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_tab_empty_state.TabEmptyState, { icon: import_lucide_react.ShoppingBag, heading: "No active listings", body: "Works this account lists for sale appear here." }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: GRID, children: listings.map((o) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_listing_card.ListingCard, { order: o, onBuy: isOwner ? void 0 : market.buy, usdValue: (0, import_order_usd.orderUsd)(o.price, prices), overflowMenu: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_listing_card_menu.ListingCardMenu, { order: o }) }, o.orderHash)) }) }),
|
|
128
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_tabs.TabsContent, { value: "activity", className: "mt-6 max-w-2xl px-6", children: activitiesLoading ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "space-y-5", children: Array.from({ length: 6 }).map((_, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_skeleton.Skeleton, { className: "h-10 w-full rounded-xl" }, i)) }) : activities.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_tab_empty_state.TabEmptyState, { icon: import_lucide_react.Activity, heading: "No activity yet", body: "This account's activity appears here as it happens." }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { children: activities.map((a, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_activity_timeline_row.ActivityTimelineRow, { event: a, isLast: i === activities.length - 1 }, i)) }) })
|
|
129
|
+
]
|
|
130
|
+
}
|
|
131
|
+
),
|
|
132
|
+
actions.dialogs,
|
|
133
|
+
market.dialogs,
|
|
134
|
+
reportToken ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
135
|
+
import_report_dialog.ReportDialog,
|
|
136
|
+
{
|
|
137
|
+
open: !!reportToken,
|
|
138
|
+
onOpenChange: (open) => {
|
|
139
|
+
if (!open) setReportToken(null);
|
|
140
|
+
},
|
|
141
|
+
target: { type: "TOKEN", contract: reportToken.contractAddress, tokenId: reportToken.tokenId, name: reportToken.metadata?.name ?? void 0 }
|
|
142
|
+
}
|
|
143
|
+
) : null,
|
|
144
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_report_dialog.ReportDialog, { open: reportOpen, onOpenChange: setReportOpen, target: { type: "CREATOR", address, name: (0, import_address.shortenAddress)(address) } })
|
|
145
|
+
] });
|
|
146
|
+
}
|
|
147
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
148
|
+
0 && (module.exports = {
|
|
149
|
+
AccountPage
|
|
150
|
+
});
|
|
151
|
+
//# sourceMappingURL=account-page.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/components/account-page.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState } from \"react\";\nimport useSWR from \"swr\";\nimport { Activity, Image as ImageIcon, LayoutGrid, ShoppingBag } from \"lucide-react\";\nimport type { ApiToken } from \"@medialane/sdk\";\nimport { LoadMoreSentinel } from \"./load-more-sentinel.js\";\nimport { Skeleton } from \"./skeleton.js\";\nimport { TabsContent } from \"./tabs.js\";\nimport { UnderlineTabs, type UnderlineTab } from \"./underline-tabs.js\";\nimport { AddressDisplay } from \"./address-display.js\";\nimport { HiddenContentBanner } from \"./hidden-content-banner.js\";\nimport { TabEmptyState } from \"./tab-empty-state.js\";\nimport { TokenCard, TokenCardSkeleton } from \"./token-card.js\";\nimport { CollectionCard, CollectionCardSkeleton } from \"./collection-card.js\";\nimport { ListingCard, ListingCardSkeleton } from \"./listing-card.js\";\nimport { ListingCardMenu } from \"./listing-card-menu.js\";\nimport { ActivityTimelineRow } from \"./activity-timeline-row.js\";\nimport { MoreMenu } from \"./more-menu.js\";\nimport { useMedialaneApp } from \"./medialane-app.js\";\nimport { ReportDialog } from \"./report-dialog.js\";\nimport type { UsePortfolioAssetActions } from \"./portfolio-assets.js\";\nimport type { CollectionMarketActions } from \"./collection-page.js\";\nimport { shortenAddress } from \"../utils/address.js\";\nimport { EXPLORER_URL } from \"../utils/explorer-url.js\";\nimport { isSameAddress } from \"../utils/same-address.js\";\nimport { orderUsd } from \"../utils/order-usd.js\";\nimport { useMedialaneClient } from \"../utils/use-medialane-client.js\";\nimport { useUsdPrices } from \"../utils/use-usd-prices.js\";\nimport { useOwnedTokens } from \"../utils/use-tokens.js\";\nimport { useCollectionsByOwner } from \"../utils/use-collections.js\";\nimport { useUserOrders } from \"../utils/use-orders.js\";\nimport { useActivitiesByAddress } from \"../utils/use-activities.js\";\n\ntype TabId = \"assets\" | \"collections\" | \"listings\" | \"activity\";\n\nconst GRID = \"grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5 gap-4\";\nconst isNft = (itemType: string) => itemType === \"ERC721\" || itemType === \"ERC1155\";\n\nexport interface AccountPageProps {\n address: string;\n useAssetActions: UsePortfolioAssetActions;\n useMarketActions: () => CollectionMarketActions;\n}\n\nexport function AccountPage({ address, useAssetActions, useMarketActions }: AccountPageProps) {\n const { walletAddress } = useMedialaneApp();\n const client = useMedialaneClient();\n const prices = useUsdPrices();\n const [activeTab, setActiveTab] = useState<TabId>(\"assets\");\n const [reportOpen, setReportOpen] = useState(false);\n const [reportToken, setReportToken] = useState<ApiToken | null>(null);\n\n const isOwner = !!walletAddress && isSameAddress(address, walletAddress);\n\n const { tokens, total, isLoading: tokensLoading, isLoadingMore, hasMore, loadMore, mutate: refreshTokens } = useOwnedTokens(address);\n const { collections, isLoading: collectionsLoading } = useCollectionsByOwner(address);\n const { orders, isLoading: ordersLoading } = useUserOrders(address);\n const { activities, isLoading: activitiesLoading } = useActivitiesByAddress(activeTab === \"activity\" ? address : null);\n const { data: hidden } = useSWR(`creator-hidden-${address}`, () => client.api.creators.isHidden(address).catch(() => false));\n const actions = useAssetActions({ refresh: () => void refreshTokens() });\n const market = useMarketActions();\n\n const listings = orders.filter((o) => o.status === \"ACTIVE\" && isNft(o.offer.itemType));\n const tabs: UnderlineTab[] = [\n { id: \"assets\", label: \"Assets\", icon: ImageIcon, count: total ?? undefined },\n { id: \"collections\", label: \"Collections\", icon: LayoutGrid, count: collectionsLoading ? undefined : collections.length },\n { id: \"listings\", label: \"Listings\", icon: ShoppingBag, count: ordersLoading ? undefined : listings.length },\n { id: \"activity\", label: \"Activity\", icon: Activity },\n ];\n\n return (\n <div className=\"min-h-screen overflow-x-hidden pb-20\">\n {hidden === true ? <HiddenContentBanner /> : null}\n\n <div className=\"space-y-2 px-6 pt-20 pb-6\">\n <AddressDisplay address={address} chars={10} className=\"text-2xl font-black tracking-tight tabular-nums sm:text-3xl\" />\n <span className=\"inline-flex items-center gap-1.5 rounded-full bg-muted px-2.5 py-1 text-xs font-medium text-muted-foreground\">\n <span className=\"h-1.5 w-1.5 rounded-full bg-brand-blue\" />\n Starknet\n </span>\n </div>\n\n <UnderlineTabs\n tabs={tabs}\n value={activeTab}\n onValueChange={(id) => setActiveTab(id as TabId)}\n trailing={<MoreMenu explorerHref={`${EXPLORER_URL}/contract/${address}`} shareTitle={shortenAddress(address)} onReport={() => setReportOpen(true)} />}\n >\n <TabsContent value=\"assets\" className=\"mt-6 px-6\">\n {tokensLoading ? (\n <div className={GRID}>{Array.from({ length: 8 }).map((_, i) => <TokenCardSkeleton key={i} />)}</div>\n ) : tokens.length === 0 ? (\n <TabEmptyState icon={ImageIcon} heading=\"No assets yet\" body=\"Works this account owns appear here.\" />\n ) : (\n <>\n <div className={GRID}>\n {tokens.map((t: ApiToken) => {\n const listing = t.activeOrders?.find((o) => isNft(o.offer.itemType));\n return (\n <TokenCard\n key={`${t.contractAddress}-${t.tokenId}`}\n token={t}\n isOwner={isOwner}\n usdValue={orderUsd(listing?.price, prices)}\n onList={isOwner ? actions.list : undefined}\n onTransfer={isOwner ? actions.transfer : undefined}\n onCancel={isOwner ? actions.cancel : undefined}\n onBuy={!isOwner && listing ? () => market.buy(listing) : undefined}\n onOffer={isOwner ? undefined : market.offer}\n onReport={setReportToken}\n />\n );\n })}\n </div>\n <LoadMoreSentinel hasMore={hasMore} isLoading={isLoadingMore} onLoadMore={loadMore} />\n </>\n )}\n </TabsContent>\n\n <TabsContent value=\"collections\" className=\"mt-6 px-6\">\n {collectionsLoading ? (\n <div className=\"grid grid-cols-2 gap-4 lg:grid-cols-3\">{Array.from({ length: 6 }).map((_, i) => <CollectionCardSkeleton key={i} />)}</div>\n ) : collections.length === 0 ? (\n <TabEmptyState icon={LayoutGrid} heading=\"No collections yet\" body=\"Collections this account owns appear here.\" />\n ) : (\n <div className=\"grid grid-cols-2 gap-4 lg:grid-cols-3\">{collections.map((c) => <CollectionCard key={c.contractAddress} collection={c} />)}</div>\n )}\n </TabsContent>\n\n <TabsContent value=\"listings\" className=\"mt-6 px-6\">\n {ordersLoading ? (\n <div className={GRID}>{Array.from({ length: 4 }).map((_, i) => <ListingCardSkeleton key={i} />)}</div>\n ) : listings.length === 0 ? (\n <TabEmptyState icon={ShoppingBag} heading=\"No active listings\" body=\"Works this account lists for sale appear here.\" />\n ) : (\n <div className={GRID}>\n {listings.map((o) => <ListingCard key={o.orderHash} order={o} onBuy={isOwner ? undefined : market.buy} usdValue={orderUsd(o.price, prices)} overflowMenu={<ListingCardMenu order={o} />} />)}\n </div>\n )}\n </TabsContent>\n\n <TabsContent value=\"activity\" className=\"mt-6 max-w-2xl px-6\">\n {activitiesLoading ? (\n <div className=\"space-y-5\">{Array.from({ length: 6 }).map((_, i) => <Skeleton key={i} className=\"h-10 w-full rounded-xl\" />)}</div>\n ) : activities.length === 0 ? (\n <TabEmptyState icon={Activity} heading=\"No activity yet\" body=\"This account's activity appears here as it happens.\" />\n ) : (\n <div>{activities.map((a, i) => <ActivityTimelineRow key={i} event={a} isLast={i === activities.length - 1} />)}</div>\n )}\n </TabsContent>\n </UnderlineTabs>\n\n {actions.dialogs}\n {market.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 ) : null}\n <ReportDialog open={reportOpen} onOpenChange={setReportOpen} target={{ type: \"CREATOR\", address, name: shortenAddress(address) }} />\n </div>\n );\n}\n"],"mappings":"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","names":["useSWR","ImageIcon"]}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { UsePortfolioAssetActions } from './portfolio-assets.cjs';
|
|
3
|
+
import { CollectionMarketActions } from './collection-page.cjs';
|
|
4
|
+
import 'react';
|
|
5
|
+
import '@medialane/sdk';
|
|
6
|
+
import './gated-content.cjs';
|
|
7
|
+
|
|
8
|
+
interface AccountPageProps {
|
|
9
|
+
address: string;
|
|
10
|
+
useAssetActions: UsePortfolioAssetActions;
|
|
11
|
+
useMarketActions: () => CollectionMarketActions;
|
|
12
|
+
}
|
|
13
|
+
declare function AccountPage({ address, useAssetActions, useMarketActions }: AccountPageProps): react_jsx_runtime.JSX.Element;
|
|
14
|
+
|
|
15
|
+
export { AccountPage, type AccountPageProps };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { UsePortfolioAssetActions } from './portfolio-assets.js';
|
|
3
|
+
import { CollectionMarketActions } from './collection-page.js';
|
|
4
|
+
import 'react';
|
|
5
|
+
import '@medialane/sdk';
|
|
6
|
+
import './gated-content.js';
|
|
7
|
+
|
|
8
|
+
interface AccountPageProps {
|
|
9
|
+
address: string;
|
|
10
|
+
useAssetActions: UsePortfolioAssetActions;
|
|
11
|
+
useMarketActions: () => CollectionMarketActions;
|
|
12
|
+
}
|
|
13
|
+
declare function AccountPage({ address, useAssetActions, useMarketActions }: AccountPageProps): react_jsx_runtime.JSX.Element;
|
|
14
|
+
|
|
15
|
+
export { AccountPage, type AccountPageProps };
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useState } from "react";
|
|
4
|
+
import useSWR from "swr";
|
|
5
|
+
import { Activity, Image as ImageIcon, LayoutGrid, ShoppingBag } from "lucide-react";
|
|
6
|
+
import { LoadMoreSentinel } from "./load-more-sentinel.js";
|
|
7
|
+
import { Skeleton } from "./skeleton.js";
|
|
8
|
+
import { TabsContent } from "./tabs.js";
|
|
9
|
+
import { UnderlineTabs } from "./underline-tabs.js";
|
|
10
|
+
import { AddressDisplay } from "./address-display.js";
|
|
11
|
+
import { HiddenContentBanner } from "./hidden-content-banner.js";
|
|
12
|
+
import { TabEmptyState } from "./tab-empty-state.js";
|
|
13
|
+
import { TokenCard, TokenCardSkeleton } from "./token-card.js";
|
|
14
|
+
import { CollectionCard, CollectionCardSkeleton } from "./collection-card.js";
|
|
15
|
+
import { ListingCard, ListingCardSkeleton } from "./listing-card.js";
|
|
16
|
+
import { ListingCardMenu } from "./listing-card-menu.js";
|
|
17
|
+
import { ActivityTimelineRow } from "./activity-timeline-row.js";
|
|
18
|
+
import { MoreMenu } from "./more-menu.js";
|
|
19
|
+
import { useMedialaneApp } from "./medialane-app.js";
|
|
20
|
+
import { ReportDialog } from "./report-dialog.js";
|
|
21
|
+
import { shortenAddress } from "../utils/address.js";
|
|
22
|
+
import { EXPLORER_URL } from "../utils/explorer-url.js";
|
|
23
|
+
import { isSameAddress } from "../utils/same-address.js";
|
|
24
|
+
import { orderUsd } from "../utils/order-usd.js";
|
|
25
|
+
import { useMedialaneClient } from "../utils/use-medialane-client.js";
|
|
26
|
+
import { useUsdPrices } from "../utils/use-usd-prices.js";
|
|
27
|
+
import { useOwnedTokens } from "../utils/use-tokens.js";
|
|
28
|
+
import { useCollectionsByOwner } from "../utils/use-collections.js";
|
|
29
|
+
import { useUserOrders } from "../utils/use-orders.js";
|
|
30
|
+
import { useActivitiesByAddress } from "../utils/use-activities.js";
|
|
31
|
+
const GRID = "grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5 gap-4";
|
|
32
|
+
const isNft = (itemType) => itemType === "ERC721" || itemType === "ERC1155";
|
|
33
|
+
function AccountPage({ address, useAssetActions, useMarketActions }) {
|
|
34
|
+
const { walletAddress } = useMedialaneApp();
|
|
35
|
+
const client = useMedialaneClient();
|
|
36
|
+
const prices = useUsdPrices();
|
|
37
|
+
const [activeTab, setActiveTab] = useState("assets");
|
|
38
|
+
const [reportOpen, setReportOpen] = useState(false);
|
|
39
|
+
const [reportToken, setReportToken] = useState(null);
|
|
40
|
+
const isOwner = !!walletAddress && isSameAddress(address, walletAddress);
|
|
41
|
+
const { tokens, total, isLoading: tokensLoading, isLoadingMore, hasMore, loadMore, mutate: refreshTokens } = useOwnedTokens(address);
|
|
42
|
+
const { collections, isLoading: collectionsLoading } = useCollectionsByOwner(address);
|
|
43
|
+
const { orders, isLoading: ordersLoading } = useUserOrders(address);
|
|
44
|
+
const { activities, isLoading: activitiesLoading } = useActivitiesByAddress(activeTab === "activity" ? address : null);
|
|
45
|
+
const { data: hidden } = useSWR(`creator-hidden-${address}`, () => client.api.creators.isHidden(address).catch(() => false));
|
|
46
|
+
const actions = useAssetActions({ refresh: () => void refreshTokens() });
|
|
47
|
+
const market = useMarketActions();
|
|
48
|
+
const listings = orders.filter((o) => o.status === "ACTIVE" && isNft(o.offer.itemType));
|
|
49
|
+
const tabs = [
|
|
50
|
+
{ id: "assets", label: "Assets", icon: ImageIcon, count: total ?? void 0 },
|
|
51
|
+
{ id: "collections", label: "Collections", icon: LayoutGrid, count: collectionsLoading ? void 0 : collections.length },
|
|
52
|
+
{ id: "listings", label: "Listings", icon: ShoppingBag, count: ordersLoading ? void 0 : listings.length },
|
|
53
|
+
{ id: "activity", label: "Activity", icon: Activity }
|
|
54
|
+
];
|
|
55
|
+
return /* @__PURE__ */ jsxs("div", { className: "min-h-screen overflow-x-hidden pb-20", children: [
|
|
56
|
+
hidden === true ? /* @__PURE__ */ jsx(HiddenContentBanner, {}) : null,
|
|
57
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-2 px-6 pt-20 pb-6", children: [
|
|
58
|
+
/* @__PURE__ */ jsx(AddressDisplay, { address, chars: 10, className: "text-2xl font-black tracking-tight tabular-nums sm:text-3xl" }),
|
|
59
|
+
/* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1.5 rounded-full bg-muted px-2.5 py-1 text-xs font-medium text-muted-foreground", children: [
|
|
60
|
+
/* @__PURE__ */ jsx("span", { className: "h-1.5 w-1.5 rounded-full bg-brand-blue" }),
|
|
61
|
+
"Starknet"
|
|
62
|
+
] })
|
|
63
|
+
] }),
|
|
64
|
+
/* @__PURE__ */ jsxs(
|
|
65
|
+
UnderlineTabs,
|
|
66
|
+
{
|
|
67
|
+
tabs,
|
|
68
|
+
value: activeTab,
|
|
69
|
+
onValueChange: (id) => setActiveTab(id),
|
|
70
|
+
trailing: /* @__PURE__ */ jsx(MoreMenu, { explorerHref: `${EXPLORER_URL}/contract/${address}`, shareTitle: shortenAddress(address), onReport: () => setReportOpen(true) }),
|
|
71
|
+
children: [
|
|
72
|
+
/* @__PURE__ */ jsx(TabsContent, { value: "assets", className: "mt-6 px-6", children: tokensLoading ? /* @__PURE__ */ jsx("div", { className: GRID, children: Array.from({ length: 8 }).map((_, i) => /* @__PURE__ */ jsx(TokenCardSkeleton, {}, i)) }) : tokens.length === 0 ? /* @__PURE__ */ jsx(TabEmptyState, { icon: ImageIcon, heading: "No assets yet", body: "Works this account owns appear here." }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
73
|
+
/* @__PURE__ */ jsx("div", { className: GRID, children: tokens.map((t) => {
|
|
74
|
+
const listing = t.activeOrders?.find((o) => isNft(o.offer.itemType));
|
|
75
|
+
return /* @__PURE__ */ jsx(
|
|
76
|
+
TokenCard,
|
|
77
|
+
{
|
|
78
|
+
token: t,
|
|
79
|
+
isOwner,
|
|
80
|
+
usdValue: orderUsd(listing?.price, prices),
|
|
81
|
+
onList: isOwner ? actions.list : void 0,
|
|
82
|
+
onTransfer: isOwner ? actions.transfer : void 0,
|
|
83
|
+
onCancel: isOwner ? actions.cancel : void 0,
|
|
84
|
+
onBuy: !isOwner && listing ? () => market.buy(listing) : void 0,
|
|
85
|
+
onOffer: isOwner ? void 0 : market.offer,
|
|
86
|
+
onReport: setReportToken
|
|
87
|
+
},
|
|
88
|
+
`${t.contractAddress}-${t.tokenId}`
|
|
89
|
+
);
|
|
90
|
+
}) }),
|
|
91
|
+
/* @__PURE__ */ jsx(LoadMoreSentinel, { hasMore, isLoading: isLoadingMore, onLoadMore: loadMore })
|
|
92
|
+
] }) }),
|
|
93
|
+
/* @__PURE__ */ jsx(TabsContent, { value: "collections", className: "mt-6 px-6", children: collectionsLoading ? /* @__PURE__ */ jsx("div", { className: "grid grid-cols-2 gap-4 lg:grid-cols-3", children: Array.from({ length: 6 }).map((_, i) => /* @__PURE__ */ jsx(CollectionCardSkeleton, {}, i)) }) : collections.length === 0 ? /* @__PURE__ */ jsx(TabEmptyState, { icon: LayoutGrid, heading: "No collections yet", body: "Collections this account owns appear here." }) : /* @__PURE__ */ jsx("div", { className: "grid grid-cols-2 gap-4 lg:grid-cols-3", children: collections.map((c) => /* @__PURE__ */ jsx(CollectionCard, { collection: c }, c.contractAddress)) }) }),
|
|
94
|
+
/* @__PURE__ */ jsx(TabsContent, { value: "listings", className: "mt-6 px-6", children: ordersLoading ? /* @__PURE__ */ jsx("div", { className: GRID, children: Array.from({ length: 4 }).map((_, i) => /* @__PURE__ */ jsx(ListingCardSkeleton, {}, i)) }) : listings.length === 0 ? /* @__PURE__ */ jsx(TabEmptyState, { icon: ShoppingBag, heading: "No active listings", body: "Works this account lists for sale appear here." }) : /* @__PURE__ */ jsx("div", { className: GRID, children: listings.map((o) => /* @__PURE__ */ jsx(ListingCard, { order: o, onBuy: isOwner ? void 0 : market.buy, usdValue: orderUsd(o.price, prices), overflowMenu: /* @__PURE__ */ jsx(ListingCardMenu, { order: o }) }, o.orderHash)) }) }),
|
|
95
|
+
/* @__PURE__ */ jsx(TabsContent, { value: "activity", className: "mt-6 max-w-2xl px-6", children: activitiesLoading ? /* @__PURE__ */ jsx("div", { className: "space-y-5", children: Array.from({ length: 6 }).map((_, i) => /* @__PURE__ */ jsx(Skeleton, { className: "h-10 w-full rounded-xl" }, i)) }) : activities.length === 0 ? /* @__PURE__ */ jsx(TabEmptyState, { icon: Activity, heading: "No activity yet", body: "This account's activity appears here as it happens." }) : /* @__PURE__ */ jsx("div", { children: activities.map((a, i) => /* @__PURE__ */ jsx(ActivityTimelineRow, { event: a, isLast: i === activities.length - 1 }, i)) }) })
|
|
96
|
+
]
|
|
97
|
+
}
|
|
98
|
+
),
|
|
99
|
+
actions.dialogs,
|
|
100
|
+
market.dialogs,
|
|
101
|
+
reportToken ? /* @__PURE__ */ jsx(
|
|
102
|
+
ReportDialog,
|
|
103
|
+
{
|
|
104
|
+
open: !!reportToken,
|
|
105
|
+
onOpenChange: (open) => {
|
|
106
|
+
if (!open) setReportToken(null);
|
|
107
|
+
},
|
|
108
|
+
target: { type: "TOKEN", contract: reportToken.contractAddress, tokenId: reportToken.tokenId, name: reportToken.metadata?.name ?? void 0 }
|
|
109
|
+
}
|
|
110
|
+
) : null,
|
|
111
|
+
/* @__PURE__ */ jsx(ReportDialog, { open: reportOpen, onOpenChange: setReportOpen, target: { type: "CREATOR", address, name: shortenAddress(address) } })
|
|
112
|
+
] });
|
|
113
|
+
}
|
|
114
|
+
export {
|
|
115
|
+
AccountPage
|
|
116
|
+
};
|
|
117
|
+
//# sourceMappingURL=account-page.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/components/account-page.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState } from \"react\";\nimport useSWR from \"swr\";\nimport { Activity, Image as ImageIcon, LayoutGrid, ShoppingBag } from \"lucide-react\";\nimport type { ApiToken } from \"@medialane/sdk\";\nimport { LoadMoreSentinel } from \"./load-more-sentinel.js\";\nimport { Skeleton } from \"./skeleton.js\";\nimport { TabsContent } from \"./tabs.js\";\nimport { UnderlineTabs, type UnderlineTab } from \"./underline-tabs.js\";\nimport { AddressDisplay } from \"./address-display.js\";\nimport { HiddenContentBanner } from \"./hidden-content-banner.js\";\nimport { TabEmptyState } from \"./tab-empty-state.js\";\nimport { TokenCard, TokenCardSkeleton } from \"./token-card.js\";\nimport { CollectionCard, CollectionCardSkeleton } from \"./collection-card.js\";\nimport { ListingCard, ListingCardSkeleton } from \"./listing-card.js\";\nimport { ListingCardMenu } from \"./listing-card-menu.js\";\nimport { ActivityTimelineRow } from \"./activity-timeline-row.js\";\nimport { MoreMenu } from \"./more-menu.js\";\nimport { useMedialaneApp } from \"./medialane-app.js\";\nimport { ReportDialog } from \"./report-dialog.js\";\nimport type { UsePortfolioAssetActions } from \"./portfolio-assets.js\";\nimport type { CollectionMarketActions } from \"./collection-page.js\";\nimport { shortenAddress } from \"../utils/address.js\";\nimport { EXPLORER_URL } from \"../utils/explorer-url.js\";\nimport { isSameAddress } from \"../utils/same-address.js\";\nimport { orderUsd } from \"../utils/order-usd.js\";\nimport { useMedialaneClient } from \"../utils/use-medialane-client.js\";\nimport { useUsdPrices } from \"../utils/use-usd-prices.js\";\nimport { useOwnedTokens } from \"../utils/use-tokens.js\";\nimport { useCollectionsByOwner } from \"../utils/use-collections.js\";\nimport { useUserOrders } from \"../utils/use-orders.js\";\nimport { useActivitiesByAddress } from \"../utils/use-activities.js\";\n\ntype TabId = \"assets\" | \"collections\" | \"listings\" | \"activity\";\n\nconst GRID = \"grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5 gap-4\";\nconst isNft = (itemType: string) => itemType === \"ERC721\" || itemType === \"ERC1155\";\n\nexport interface AccountPageProps {\n address: string;\n useAssetActions: UsePortfolioAssetActions;\n useMarketActions: () => CollectionMarketActions;\n}\n\nexport function AccountPage({ address, useAssetActions, useMarketActions }: AccountPageProps) {\n const { walletAddress } = useMedialaneApp();\n const client = useMedialaneClient();\n const prices = useUsdPrices();\n const [activeTab, setActiveTab] = useState<TabId>(\"assets\");\n const [reportOpen, setReportOpen] = useState(false);\n const [reportToken, setReportToken] = useState<ApiToken | null>(null);\n\n const isOwner = !!walletAddress && isSameAddress(address, walletAddress);\n\n const { tokens, total, isLoading: tokensLoading, isLoadingMore, hasMore, loadMore, mutate: refreshTokens } = useOwnedTokens(address);\n const { collections, isLoading: collectionsLoading } = useCollectionsByOwner(address);\n const { orders, isLoading: ordersLoading } = useUserOrders(address);\n const { activities, isLoading: activitiesLoading } = useActivitiesByAddress(activeTab === \"activity\" ? address : null);\n const { data: hidden } = useSWR(`creator-hidden-${address}`, () => client.api.creators.isHidden(address).catch(() => false));\n const actions = useAssetActions({ refresh: () => void refreshTokens() });\n const market = useMarketActions();\n\n const listings = orders.filter((o) => o.status === \"ACTIVE\" && isNft(o.offer.itemType));\n const tabs: UnderlineTab[] = [\n { id: \"assets\", label: \"Assets\", icon: ImageIcon, count: total ?? undefined },\n { id: \"collections\", label: \"Collections\", icon: LayoutGrid, count: collectionsLoading ? undefined : collections.length },\n { id: \"listings\", label: \"Listings\", icon: ShoppingBag, count: ordersLoading ? undefined : listings.length },\n { id: \"activity\", label: \"Activity\", icon: Activity },\n ];\n\n return (\n <div className=\"min-h-screen overflow-x-hidden pb-20\">\n {hidden === true ? <HiddenContentBanner /> : null}\n\n <div className=\"space-y-2 px-6 pt-20 pb-6\">\n <AddressDisplay address={address} chars={10} className=\"text-2xl font-black tracking-tight tabular-nums sm:text-3xl\" />\n <span className=\"inline-flex items-center gap-1.5 rounded-full bg-muted px-2.5 py-1 text-xs font-medium text-muted-foreground\">\n <span className=\"h-1.5 w-1.5 rounded-full bg-brand-blue\" />\n Starknet\n </span>\n </div>\n\n <UnderlineTabs\n tabs={tabs}\n value={activeTab}\n onValueChange={(id) => setActiveTab(id as TabId)}\n trailing={<MoreMenu explorerHref={`${EXPLORER_URL}/contract/${address}`} shareTitle={shortenAddress(address)} onReport={() => setReportOpen(true)} />}\n >\n <TabsContent value=\"assets\" className=\"mt-6 px-6\">\n {tokensLoading ? (\n <div className={GRID}>{Array.from({ length: 8 }).map((_, i) => <TokenCardSkeleton key={i} />)}</div>\n ) : tokens.length === 0 ? (\n <TabEmptyState icon={ImageIcon} heading=\"No assets yet\" body=\"Works this account owns appear here.\" />\n ) : (\n <>\n <div className={GRID}>\n {tokens.map((t: ApiToken) => {\n const listing = t.activeOrders?.find((o) => isNft(o.offer.itemType));\n return (\n <TokenCard\n key={`${t.contractAddress}-${t.tokenId}`}\n token={t}\n isOwner={isOwner}\n usdValue={orderUsd(listing?.price, prices)}\n onList={isOwner ? actions.list : undefined}\n onTransfer={isOwner ? actions.transfer : undefined}\n onCancel={isOwner ? actions.cancel : undefined}\n onBuy={!isOwner && listing ? () => market.buy(listing) : undefined}\n onOffer={isOwner ? undefined : market.offer}\n onReport={setReportToken}\n />\n );\n })}\n </div>\n <LoadMoreSentinel hasMore={hasMore} isLoading={isLoadingMore} onLoadMore={loadMore} />\n </>\n )}\n </TabsContent>\n\n <TabsContent value=\"collections\" className=\"mt-6 px-6\">\n {collectionsLoading ? (\n <div className=\"grid grid-cols-2 gap-4 lg:grid-cols-3\">{Array.from({ length: 6 }).map((_, i) => <CollectionCardSkeleton key={i} />)}</div>\n ) : collections.length === 0 ? (\n <TabEmptyState icon={LayoutGrid} heading=\"No collections yet\" body=\"Collections this account owns appear here.\" />\n ) : (\n <div className=\"grid grid-cols-2 gap-4 lg:grid-cols-3\">{collections.map((c) => <CollectionCard key={c.contractAddress} collection={c} />)}</div>\n )}\n </TabsContent>\n\n <TabsContent value=\"listings\" className=\"mt-6 px-6\">\n {ordersLoading ? (\n <div className={GRID}>{Array.from({ length: 4 }).map((_, i) => <ListingCardSkeleton key={i} />)}</div>\n ) : listings.length === 0 ? (\n <TabEmptyState icon={ShoppingBag} heading=\"No active listings\" body=\"Works this account lists for sale appear here.\" />\n ) : (\n <div className={GRID}>\n {listings.map((o) => <ListingCard key={o.orderHash} order={o} onBuy={isOwner ? undefined : market.buy} usdValue={orderUsd(o.price, prices)} overflowMenu={<ListingCardMenu order={o} />} />)}\n </div>\n )}\n </TabsContent>\n\n <TabsContent value=\"activity\" className=\"mt-6 max-w-2xl px-6\">\n {activitiesLoading ? (\n <div className=\"space-y-5\">{Array.from({ length: 6 }).map((_, i) => <Skeleton key={i} className=\"h-10 w-full rounded-xl\" />)}</div>\n ) : activities.length === 0 ? (\n <TabEmptyState icon={Activity} heading=\"No activity yet\" body=\"This account's activity appears here as it happens.\" />\n ) : (\n <div>{activities.map((a, i) => <ActivityTimelineRow key={i} event={a} isLast={i === activities.length - 1} />)}</div>\n )}\n </TabsContent>\n </UnderlineTabs>\n\n {actions.dialogs}\n {market.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 ) : null}\n <ReportDialog open={reportOpen} onOpenChange={setReportOpen} target={{ type: \"CREATOR\", address, name: shortenAddress(address) }} />\n </div>\n );\n}\n"],"mappings":"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","names":[]}
|
|
@@ -3,7 +3,7 @@ import * as React from 'react';
|
|
|
3
3
|
import { VariantProps } from 'class-variance-authority';
|
|
4
4
|
|
|
5
5
|
declare const buttonVariants: (props?: ({
|
|
6
|
-
variant?: "
|
|
6
|
+
variant?: "link" | "default" | "destructive" | "outline" | "secondary" | "ghost" | "premium" | "tonal" | "gradient-border" | "gradient-fill" | null | undefined;
|
|
7
7
|
size?: "icon" | "default" | "sm" | "lg" | null | undefined;
|
|
8
8
|
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
9
9
|
interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement>, VariantProps<typeof buttonVariants> {
|
|
@@ -3,7 +3,7 @@ import * as React from 'react';
|
|
|
3
3
|
import { VariantProps } from 'class-variance-authority';
|
|
4
4
|
|
|
5
5
|
declare const buttonVariants: (props?: ({
|
|
6
|
-
variant?: "
|
|
6
|
+
variant?: "link" | "default" | "destructive" | "outline" | "secondary" | "ghost" | "premium" | "tonal" | "gradient-border" | "gradient-fill" | null | undefined;
|
|
7
7
|
size?: "icon" | "default" | "sm" | "lg" | null | undefined;
|
|
8
8
|
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
9
9
|
interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement>, VariantProps<typeof buttonVariants> {
|
|
@@ -39,7 +39,8 @@ var import_lucide_react = require("lucide-react");
|
|
|
39
39
|
var import_link = __toESM(require("./link.js"), 1);
|
|
40
40
|
var import_button = require("./button.js");
|
|
41
41
|
var import_skeleton = require("./skeleton.js");
|
|
42
|
-
var
|
|
42
|
+
var import_tabs = require("./tabs.js");
|
|
43
|
+
var import_underline_tabs = require("./underline-tabs.js");
|
|
43
44
|
var import_creator_header = require("./creator-header.js");
|
|
44
45
|
var import_hidden_content_banner = require("./hidden-content-banner.js");
|
|
45
46
|
var import_tab_empty_state = require("./tab-empty-state.js");
|
|
@@ -64,15 +65,9 @@ var import_use_collections = require("../utils/use-collections.js");
|
|
|
64
65
|
var import_use_orders = require("../utils/use-orders.js");
|
|
65
66
|
var import_use_activities = require("../utils/use-activities.js");
|
|
66
67
|
var import_use_profiles = require("../utils/use-profiles.js");
|
|
67
|
-
const TABS = [
|
|
68
|
-
{ id: "assets", label: "Assets", Icon: import_lucide_react.Image },
|
|
69
|
-
{ id: "collections", label: "Collections", Icon: import_lucide_react.LayoutGrid },
|
|
70
|
-
{ id: "listings", label: "Listings", Icon: import_lucide_react.ShoppingBag },
|
|
71
|
-
{ id: "activity", label: "Activity", Icon: import_lucide_react.Activity }
|
|
72
|
-
];
|
|
73
68
|
const GRID = "grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5 gap-4";
|
|
74
69
|
const isNft = (itemType) => itemType === "ERC721" || itemType === "ERC1155";
|
|
75
|
-
function CreatorPage({
|
|
70
|
+
function CreatorPage({ username, useAssetActions, useMarketActions }) {
|
|
76
71
|
const { walletAddress } = (0, import_medialane_app.useMedialaneApp)();
|
|
77
72
|
const client = (0, import_use_medialane_client.useMedialaneClient)();
|
|
78
73
|
const resolveImage = (0, import_use_image_url.useImageUrl)();
|
|
@@ -80,10 +75,8 @@ function CreatorPage({ address: addressProp, username, useAssetActions, useMarke
|
|
|
80
75
|
const [activeTab, setActiveTab] = (0, import_react.useState)("assets");
|
|
81
76
|
const [reportOpen, setReportOpen] = (0, import_react.useState)(false);
|
|
82
77
|
const [reportToken, setReportToken] = (0, import_react.useState)(null);
|
|
83
|
-
const
|
|
84
|
-
const
|
|
85
|
-
const creator = username ? byName.creator : byAddress.profile;
|
|
86
|
-
const address = username ? creator?.walletAddress ?? null : addressProp ?? null;
|
|
78
|
+
const { creator, isLoading: creatorLoading } = (0, import_use_profiles.useCreatorByUsername)(username);
|
|
79
|
+
const address = creator?.walletAddress ?? null;
|
|
87
80
|
const isOwner = !!address && !!walletAddress && (0, import_same_address.isSameAddress)(address, walletAddress);
|
|
88
81
|
const { tokens, meta, isLoading: tokensLoading, mutate: refreshTokens } = (0, import_use_tokens.useTokensByOwner)(address, 1, 20);
|
|
89
82
|
const { collections, isLoading: collectionsLoading } = (0, import_use_collections.useCollectionsByOwner)(address);
|
|
@@ -94,13 +87,13 @@ function CreatorPage({ address: addressProp, username, useAssetActions, useMarke
|
|
|
94
87
|
const market = useMarketActions();
|
|
95
88
|
const listings = orders.filter((o) => o.status === "ACTIVE" && isNft(o.offer.itemType));
|
|
96
89
|
const identity = (0, import_profile_identity.profileIdentity)({ username: creator?.username, name: creator?.name, walletAddress: address });
|
|
97
|
-
if (
|
|
90
|
+
if (creatorLoading) {
|
|
98
91
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "min-h-screen pb-20", children: [
|
|
99
92
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "px-6 pt-20 pb-6", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_creator_header.CreatorHeader, { creator: null, image: null, stats: [], loading: true }) }),
|
|
100
93
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: (0, import_cn.cn)("px-6", GRID), children: Array.from({ length: 8 }).map((_, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_token_card.TokenCardSkeleton, {}, i)) })
|
|
101
94
|
] });
|
|
102
95
|
}
|
|
103
|
-
if (
|
|
96
|
+
if (!creator) {
|
|
104
97
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "mx-auto max-w-lg space-y-4 px-4 py-24 text-center", children: [
|
|
105
98
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h1", { className: "text-2xl font-bold", children: "Creator not found" }),
|
|
106
99
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { className: "text-muted-foreground", children: [
|
|
@@ -113,14 +106,15 @@ function CreatorPage({ address: addressProp, username, useAssetActions, useMarke
|
|
|
113
106
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_button.Button, { variant: "outline", asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_link.default, { href: "/creators", children: "Browse creators" }) })
|
|
114
107
|
] });
|
|
115
108
|
}
|
|
116
|
-
const
|
|
117
|
-
assets: meta?.total ?? void 0,
|
|
118
|
-
collections: collectionsLoading ? void 0 : collections.length,
|
|
119
|
-
|
|
120
|
-
|
|
109
|
+
const tabs = [
|
|
110
|
+
{ id: "assets", label: "Assets", icon: import_lucide_react.Image, count: meta?.total ?? void 0 },
|
|
111
|
+
{ id: "collections", label: "Collections", icon: import_lucide_react.LayoutGrid, count: collectionsLoading ? void 0 : collections.length },
|
|
112
|
+
{ id: "listings", label: "Listings", icon: import_lucide_react.ShoppingBag, count: activeTab === "listings" && !ordersLoading ? listings.length : void 0 },
|
|
113
|
+
{ id: "activity", label: "Activity", icon: import_lucide_react.Activity }
|
|
114
|
+
];
|
|
121
115
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "min-h-screen overflow-x-hidden pb-20", children: [
|
|
122
116
|
hidden === true ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_hidden_content_banner.HiddenContentBanner, {}) : null,
|
|
123
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "px-6 pt-20 pb-6", children:
|
|
117
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "px-6 pt-20 pb-6", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
124
118
|
import_creator_header.CreatorHeader,
|
|
125
119
|
{
|
|
126
120
|
creator,
|
|
@@ -130,54 +124,39 @@ function CreatorPage({ address: addressProp, username, useAssetActions, useMarke
|
|
|
130
124
|
{ label: "Collections", value: collectionsLoading ? null : collections.length }
|
|
131
125
|
]
|
|
132
126
|
}
|
|
133
|
-
)
|
|
134
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
usdValue: (0, import_order_usd.orderUsd)(listing?.price, prices),
|
|
167
|
-
onList: isOwner ? actions.list : void 0,
|
|
168
|
-
onTransfer: isOwner ? actions.transfer : void 0,
|
|
169
|
-
onCancel: isOwner ? actions.cancel : void 0,
|
|
170
|
-
onBuy: !isOwner && listing ? () => market.buy(listing) : void 0,
|
|
171
|
-
onOffer: isOwner ? void 0 : market.offer,
|
|
172
|
-
onReport: setReportToken
|
|
173
|
-
},
|
|
174
|
-
`${t.contractAddress}-${t.tokenId}`
|
|
175
|
-
);
|
|
176
|
-
}) })),
|
|
177
|
-
activeTab === "collections" && (collectionsLoading ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "grid grid-cols-2 gap-4 lg:grid-cols-3", children: Array.from({ length: 6 }).map((_, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_collection_card.CollectionCardSkeleton, {}, i)) }) : collections.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_tab_empty_state.TabEmptyState, { icon: import_lucide_react.LayoutGrid, heading: "No collections yet", body: "Collections this creator makes appear here." }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "grid grid-cols-2 gap-4 lg:grid-cols-3", children: collections.map((c) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_collection_card.CollectionCard, { collection: c }, c.contractAddress)) })),
|
|
178
|
-
activeTab === "listings" && (ordersLoading ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: GRID, children: Array.from({ length: 4 }).map((_, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_listing_card.ListingCardSkeleton, {}, i)) }) : listings.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_tab_empty_state.TabEmptyState, { icon: import_lucide_react.ShoppingBag, heading: "No active listings", body: "Works this creator lists for sale appear here." }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: GRID, children: listings.map((o) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_listing_card.ListingCard, { order: o, onBuy: isOwner ? void 0 : market.buy, usdValue: (0, import_order_usd.orderUsd)(o.price, prices), overflowMenu: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_listing_card_menu.ListingCardMenu, { order: o }) }, o.orderHash)) })),
|
|
179
|
-
activeTab === "activity" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "max-w-2xl", children: activitiesLoading ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "space-y-5", children: Array.from({ length: 6 }).map((_, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_skeleton.Skeleton, { className: "h-10 w-full rounded-xl" }, i)) }) : activities.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_tab_empty_state.TabEmptyState, { icon: import_lucide_react.Activity, heading: "No activity yet", body: "This creator's activity appears here as it happens." }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { children: activities.map((a, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_activity_timeline_row.ActivityTimelineRow, { event: a, isLast: i === activities.length - 1 }, i)) }) })
|
|
180
|
-
] }),
|
|
127
|
+
) }),
|
|
128
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
129
|
+
import_underline_tabs.UnderlineTabs,
|
|
130
|
+
{
|
|
131
|
+
tabs,
|
|
132
|
+
value: activeTab,
|
|
133
|
+
onValueChange: (id) => setActiveTab(id),
|
|
134
|
+
trailing: address ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_more_menu.MoreMenu, { explorerHref: `${import_explorer_url.EXPLORER_URL}/contract/${address}`, shareTitle: identity.name ?? identity.identity, onReport: () => setReportOpen(true) }) : null,
|
|
135
|
+
children: [
|
|
136
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_tabs.TabsContent, { value: "assets", className: "mt-6 px-6", children: tokensLoading ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: GRID, children: Array.from({ length: 8 }).map((_, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_token_card.TokenCardSkeleton, {}, i)) }) : tokens.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_tab_empty_state.TabEmptyState, { icon: import_lucide_react.Image, heading: "No assets yet", body: "Works this creator makes on Medialane appear here." }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: GRID, children: tokens.map((t) => {
|
|
137
|
+
const listing = t.activeOrders?.find((o) => isNft(o.offer.itemType));
|
|
138
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
139
|
+
import_token_card.TokenCard,
|
|
140
|
+
{
|
|
141
|
+
token: t,
|
|
142
|
+
isOwner,
|
|
143
|
+
usdValue: (0, import_order_usd.orderUsd)(listing?.price, prices),
|
|
144
|
+
onList: isOwner ? actions.list : void 0,
|
|
145
|
+
onTransfer: isOwner ? actions.transfer : void 0,
|
|
146
|
+
onCancel: isOwner ? actions.cancel : void 0,
|
|
147
|
+
onBuy: !isOwner && listing ? () => market.buy(listing) : void 0,
|
|
148
|
+
onOffer: isOwner ? void 0 : market.offer,
|
|
149
|
+
onReport: setReportToken
|
|
150
|
+
},
|
|
151
|
+
`${t.contractAddress}-${t.tokenId}`
|
|
152
|
+
);
|
|
153
|
+
}) }) }),
|
|
154
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_tabs.TabsContent, { value: "collections", className: "mt-6 px-6", children: collectionsLoading ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "grid grid-cols-2 gap-4 lg:grid-cols-3", children: Array.from({ length: 6 }).map((_, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_collection_card.CollectionCardSkeleton, {}, i)) }) : collections.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_tab_empty_state.TabEmptyState, { icon: import_lucide_react.LayoutGrid, heading: "No collections yet", body: "Collections this creator makes appear here." }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "grid grid-cols-2 gap-4 lg:grid-cols-3", children: collections.map((c) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_collection_card.CollectionCard, { collection: c }, c.contractAddress)) }) }),
|
|
155
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_tabs.TabsContent, { value: "listings", className: "mt-6 px-6", children: ordersLoading ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: GRID, children: Array.from({ length: 4 }).map((_, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_listing_card.ListingCardSkeleton, {}, i)) }) : listings.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_tab_empty_state.TabEmptyState, { icon: import_lucide_react.ShoppingBag, heading: "No active listings", body: "Works this creator lists for sale appear here." }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: GRID, children: listings.map((o) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_listing_card.ListingCard, { order: o, onBuy: isOwner ? void 0 : market.buy, usdValue: (0, import_order_usd.orderUsd)(o.price, prices), overflowMenu: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_listing_card_menu.ListingCardMenu, { order: o }) }, o.orderHash)) }) }),
|
|
156
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_tabs.TabsContent, { value: "activity", className: "mt-6 max-w-2xl px-6", children: activitiesLoading ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "space-y-5", children: Array.from({ length: 6 }).map((_, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_skeleton.Skeleton, { className: "h-10 w-full rounded-xl" }, i)) }) : activities.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_tab_empty_state.TabEmptyState, { icon: import_lucide_react.Activity, heading: "No activity yet", body: "This creator's activity appears here as it happens." }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { children: activities.map((a, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_activity_timeline_row.ActivityTimelineRow, { event: a, isLast: i === activities.length - 1 }, i)) }) })
|
|
157
|
+
]
|
|
158
|
+
}
|
|
159
|
+
),
|
|
181
160
|
actions.dialogs,
|
|
182
161
|
market.dialogs,
|
|
183
162
|
reportToken ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|