@medialane/ui 0.331.0 → 0.333.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/input-otp.d.cts +2 -2
- package/dist/components/account/input-otp.d.ts +2 -2
- package/dist/components/asset-page.cjs +24 -33
- package/dist/components/asset-page.cjs.map +1 -1
- package/dist/components/asset-page.d.cts +4 -2
- package/dist/components/asset-page.d.ts +4 -2
- package/dist/components/asset-page.js +24 -33
- package/dist/components/asset-page.js.map +1 -1
- package/dist/components/asset-top-sections.cjs +24 -28
- package/dist/components/asset-top-sections.cjs.map +1 -1
- package/dist/components/asset-top-sections.d.cts +2 -2
- package/dist/components/asset-top-sections.d.ts +2 -2
- package/dist/components/asset-top-sections.js +24 -28
- package/dist/components/asset-top-sections.js.map +1 -1
- package/dist/components/button.d.cts +2 -2
- package/dist/components/button.d.ts +2 -2
- package/dist/components/discover-community-section.cjs +79 -67
- package/dist/components/discover-community-section.cjs.map +1 -1
- package/dist/components/discover-community-section.js +79 -67
- package/dist/components/discover-community-section.js.map +1 -1
- package/dist/components/discover-features.cjs +4 -3
- package/dist/components/discover-features.cjs.map +1 -1
- package/dist/components/discover-features.js +5 -3
- package/dist/components/discover-features.js.map +1 -1
- package/dist/components/discover-page.cjs +1 -1
- package/dist/components/discover-page.cjs.map +1 -1
- package/dist/components/discover-page.js +1 -1
- package/dist/components/discover-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/media-header.cjs +2 -0
- package/dist/components/media-header.cjs.map +1 -1
- package/dist/components/media-header.js +2 -0
- package/dist/components/media-header.js.map +1 -1
- package/dist/components/rewards/leaderboard-panel.cjs +2 -2
- package/dist/components/rewards/leaderboard-panel.cjs.map +1 -1
- package/dist/components/rewards/leaderboard-panel.js +2 -2
- package/dist/components/rewards/leaderboard-panel.js.map +1 -1
- package/dist/components/rewards/leaderboard-table.cjs +1 -1
- package/dist/components/rewards/leaderboard-table.cjs.map +1 -1
- package/dist/components/rewards/leaderboard-table.js +1 -1
- package/dist/components/rewards/leaderboard-table.js.map +1 -1
- package/dist/components/scroll-section.cjs.map +1 -1
- package/dist/components/scroll-section.d.cts +1 -1
- package/dist/components/scroll-section.d.ts +1 -1
- package/dist/components/scroll-section.js.map +1 -1
- package/dist/components/section-heading.cjs +1 -1
- package/dist/components/section-heading.cjs.map +1 -1
- package/dist/components/section-heading.d.cts +1 -1
- package/dist/components/section-heading.d.ts +1 -1
- package/dist/components/section-heading.js +1 -1
- package/dist/components/section-heading.js.map +1 -1
- package/dist/components/sheet.d.cts +1 -1
- package/dist/components/sheet.d.ts +1 -1
- package/dist/utils/use-collections.cjs +3 -3
- package/dist/utils/use-collections.cjs.map +1 -1
- package/dist/utils/use-collections.d.cts +2 -2
- package/dist/utils/use-collections.d.ts +2 -2
- package/dist/utils/use-collections.js +3 -3
- package/dist/utils/use-collections.js.map +1 -1
- package/dist/utils/use-tokens.cjs +4 -3
- package/dist/utils/use-tokens.cjs.map +1 -1
- package/dist/utils/use-tokens.d.cts +2 -1
- package/dist/utils/use-tokens.d.ts +2 -1
- package/dist/utils/use-tokens.js +4 -3
- package/dist/utils/use-tokens.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/discover-page.tsx"],"sourcesContent":["\"use client\";\n\nimport { assetHref, collectionHref } from \"@medialane/sdk\";\nimport { Sparkles } from \"lucide-react\";\nimport { PageContainer } from \"./page-container.js\";\nimport { DiscoverHero } from \"./discover-hero.js\";\nimport { DiscoverCollectionsStrip } from \"./discover-collections-strip.js\";\nimport { DiscoverActivityStrip } from \"./discover-feed-section.js\";\nimport { DiscoverCommunitySection } from \"./discover-community-section.js\";\nimport { DiscoverFeatures } from \"./discover-features.js\";\nimport { IpTypeNav } from \"./ip-type-nav.js\";\nimport { useMedialaneApp } from \"./medialane-app.js\";\nimport type { CollectionMarketActions } from \"./collection-page.js\";\nimport { useOrders } from \"../utils/use-orders.js\";\nimport { useCollections } from \"../utils/use-collections.js\";\nimport { usePlatformStats } from \"../utils/use-platform-stats.js\";\nimport { isSameAddress } from \"../utils/same-address.js\";\n\nexport interface DiscoverPageProps {\n useMarketActions: () => CollectionMarketActions;\n heroBadge?: string;\n heroHeadline?: string;\n}\n\nexport function DiscoverPage({ useMarketActions, heroBadge, heroHeadline }: DiscoverPageProps) {\n const { walletAddress } = useMedialaneApp();\n const market = useMarketActions();\n const { stats } = usePlatformStats();\n const { orders: tickerOrders } = useOrders({ status: \"ACTIVE\", sort: \"recent\", limit: 14 });\n const { orders: feedOrders, isLoading: feedLoading } = useOrders({ status: \"ACTIVE\", sort: \"recent\", limit: 10 });\n const { collections: featured, isLoading: featuredLoading } = useCollections(1, 8, true);\n const { collections, isLoading: collectionsLoading } = useCollections(1, 8);\n\n return (\n <PageContainer className=\"box-border max-w-full space-y-14 px-4 pt-20 sm:space-y-20 sm:px-5 lg:px-6\">\n <div className=\"space-y-8 sm:space-y-10\">\n <DiscoverHero\n stats={stats ?? null}\n orders={tickerOrders}\n badgeText={heroBadge}\n headlineText={heroHeadline}\n getTickerHref={(o) => assetHref(\"STARKNET\", o.nftContract, o.nftTokenId)}\n />\n <div className=\"space-y-14 sm:space-y-20\">\n {(featuredLoading || featured.length > 0) && (\n <DiscoverCollectionsStrip\n collections={featured}\n isLoading={featuredLoading}\n getHref={(c) => collectionHref(\"STARKNET\", c.contractAddress)}\n allCollectionsHref=\"/collections\"\n title=\"Featured\"\n icon={<Sparkles />}\n />\n )}\n <DiscoverCollectionsStrip\n collections={collections}\n isLoading={collectionsLoading}\n getHref={(c) => collectionHref(\"STARKNET\", c.contractAddress)}\n allCollectionsHref=\"/collections\"\n />\n </div>\n </div>\n <DiscoverActivityStrip\n orders={feedOrders}\n isLoading={feedLoading}\n marketplaceHref=\"/marketplace\"\n onBuyOrder={market.buy}\n isOwnOrder={(o) => !!walletAddress && !!o.offerer && isSameAddress(o.offerer, walletAddress)}\n />\n <IpTypeNav />\n <
|
|
1
|
+
{"version":3,"sources":["../../src/components/discover-page.tsx"],"sourcesContent":["\"use client\";\n\nimport { assetHref, collectionHref } from \"@medialane/sdk\";\nimport { Sparkles } from \"lucide-react\";\nimport { PageContainer } from \"./page-container.js\";\nimport { DiscoverHero } from \"./discover-hero.js\";\nimport { DiscoverCollectionsStrip } from \"./discover-collections-strip.js\";\nimport { DiscoverActivityStrip } from \"./discover-feed-section.js\";\nimport { DiscoverCommunitySection } from \"./discover-community-section.js\";\nimport { DiscoverFeatures } from \"./discover-features.js\";\nimport { IpTypeNav } from \"./ip-type-nav.js\";\nimport { useMedialaneApp } from \"./medialane-app.js\";\nimport type { CollectionMarketActions } from \"./collection-page.js\";\nimport { useOrders } from \"../utils/use-orders.js\";\nimport { useCollections } from \"../utils/use-collections.js\";\nimport { usePlatformStats } from \"../utils/use-platform-stats.js\";\nimport { isSameAddress } from \"../utils/same-address.js\";\n\nexport interface DiscoverPageProps {\n useMarketActions: () => CollectionMarketActions;\n heroBadge?: string;\n heroHeadline?: string;\n}\n\nexport function DiscoverPage({ useMarketActions, heroBadge, heroHeadline }: DiscoverPageProps) {\n const { walletAddress } = useMedialaneApp();\n const market = useMarketActions();\n const { stats } = usePlatformStats();\n const { orders: tickerOrders } = useOrders({ status: \"ACTIVE\", sort: \"recent\", limit: 14 });\n const { orders: feedOrders, isLoading: feedLoading } = useOrders({ status: \"ACTIVE\", sort: \"recent\", limit: 10 });\n const { collections: featured, isLoading: featuredLoading } = useCollections(1, 8, true);\n const { collections, isLoading: collectionsLoading } = useCollections(1, 8);\n\n return (\n <PageContainer className=\"box-border max-w-full space-y-14 px-4 pt-20 sm:space-y-20 sm:px-5 lg:px-6\">\n <div className=\"space-y-8 sm:space-y-10\">\n <DiscoverHero\n stats={stats ?? null}\n orders={tickerOrders}\n badgeText={heroBadge}\n headlineText={heroHeadline}\n getTickerHref={(o) => assetHref(\"STARKNET\", o.nftContract, o.nftTokenId)}\n />\n <div className=\"space-y-14 sm:space-y-20\">\n {(featuredLoading || featured.length > 0) && (\n <DiscoverCollectionsStrip\n collections={featured}\n isLoading={featuredLoading}\n getHref={(c) => collectionHref(\"STARKNET\", c.contractAddress)}\n allCollectionsHref=\"/collections\"\n title=\"Featured\"\n icon={<Sparkles />}\n />\n )}\n <DiscoverCollectionsStrip\n collections={collections}\n isLoading={collectionsLoading}\n getHref={(c) => collectionHref(\"STARKNET\", c.contractAddress)}\n allCollectionsHref=\"/collections\"\n />\n </div>\n </div>\n <DiscoverActivityStrip\n orders={feedOrders}\n isLoading={feedLoading}\n marketplaceHref=\"/marketplace\"\n onBuyOrder={market.buy}\n isOwnOrder={(o) => !!walletAddress && !!o.offerer && isSameAddress(o.offerer, walletAddress)}\n />\n <IpTypeNav />\n <DiscoverCommunitySection />\n <DiscoverFeatures />\n {market.dialogs}\n </PageContainer>\n );\n}\n"],"mappings":";AAoCQ,cAOA,YAPA;AAlCR,SAAS,WAAW,sBAAsB;AAC1C,SAAS,gBAAgB;AACzB,SAAS,qBAAqB;AAC9B,SAAS,oBAAoB;AAC7B,SAAS,gCAAgC;AACzC,SAAS,6BAA6B;AACtC,SAAS,gCAAgC;AACzC,SAAS,wBAAwB;AACjC,SAAS,iBAAiB;AAC1B,SAAS,uBAAuB;AAEhC,SAAS,iBAAiB;AAC1B,SAAS,sBAAsB;AAC/B,SAAS,wBAAwB;AACjC,SAAS,qBAAqB;AAQvB,SAAS,aAAa,EAAE,kBAAkB,WAAW,aAAa,GAAsB;AAC7F,QAAM,EAAE,cAAc,IAAI,gBAAgB;AAC1C,QAAM,SAAS,iBAAiB;AAChC,QAAM,EAAE,MAAM,IAAI,iBAAiB;AACnC,QAAM,EAAE,QAAQ,aAAa,IAAI,UAAU,EAAE,QAAQ,UAAU,MAAM,UAAU,OAAO,GAAG,CAAC;AAC1F,QAAM,EAAE,QAAQ,YAAY,WAAW,YAAY,IAAI,UAAU,EAAE,QAAQ,UAAU,MAAM,UAAU,OAAO,GAAG,CAAC;AAChH,QAAM,EAAE,aAAa,UAAU,WAAW,gBAAgB,IAAI,eAAe,GAAG,GAAG,IAAI;AACvF,QAAM,EAAE,aAAa,WAAW,mBAAmB,IAAI,eAAe,GAAG,CAAC;AAE1E,SACE,qBAAC,iBAAc,WAAU,6EACvB;AAAA,yBAAC,SAAI,WAAU,2BACb;AAAA;AAAA,QAAC;AAAA;AAAA,UACC,OAAO,SAAS;AAAA,UAChB,QAAQ;AAAA,UACR,WAAW;AAAA,UACX,cAAc;AAAA,UACd,eAAe,CAAC,MAAM,UAAU,YAAY,EAAE,aAAa,EAAE,UAAU;AAAA;AAAA,MACzE;AAAA,MACA,qBAAC,SAAI,WAAU,4BACX;AAAA,4BAAmB,SAAS,SAAS,MACrC;AAAA,UAAC;AAAA;AAAA,YACC,aAAa;AAAA,YACb,WAAW;AAAA,YACX,SAAS,CAAC,MAAM,eAAe,YAAY,EAAE,eAAe;AAAA,YAC5D,oBAAmB;AAAA,YACnB,OAAM;AAAA,YACN,MAAM,oBAAC,YAAS;AAAA;AAAA,QAClB;AAAA,QAEF;AAAA,UAAC;AAAA;AAAA,YACC;AAAA,YACA,WAAW;AAAA,YACX,SAAS,CAAC,MAAM,eAAe,YAAY,EAAE,eAAe;AAAA,YAC5D,oBAAmB;AAAA;AAAA,QACrB;AAAA,SACF;AAAA,OACF;AAAA,IACA;AAAA,MAAC;AAAA;AAAA,QACC,QAAQ;AAAA,QACR,WAAW;AAAA,QACX,iBAAgB;AAAA,QAChB,YAAY,OAAO;AAAA,QACnB,YAAY,CAAC,MAAM,CAAC,CAAC,iBAAiB,CAAC,CAAC,EAAE,WAAW,cAAc,EAAE,SAAS,aAAa;AAAA;AAAA,IAC7F;AAAA,IACA,oBAAC,aAAU;AAAA,IACX,oBAAC,4BAAyB;AAAA,IAC1B,oBAAC,oBAAiB;AAAA,IACjB,OAAO;AAAA,KACV;AAEJ;","names":[]}
|
|
@@ -16,6 +16,7 @@ declare const editionMintSchema: z.ZodObject<{
|
|
|
16
16
|
royalty: z.ZodNumber;
|
|
17
17
|
}, "strip", z.ZodTypeAny, {
|
|
18
18
|
name: string;
|
|
19
|
+
value: string;
|
|
19
20
|
ipType: "Audio" | "Video" | "Art" | "Photography" | "NFT" | "Software" | "RWA" | "Patents" | "Posts" | "Publications" | "Documents" | "Custom";
|
|
20
21
|
licenseType: string;
|
|
21
22
|
commercialUse: "Yes" | "No";
|
|
@@ -24,12 +25,12 @@ declare const editionMintSchema: z.ZodObject<{
|
|
|
24
25
|
geographicScope: string;
|
|
25
26
|
aiPolicy: "Allowed" | "Not Allowed" | "Training Only";
|
|
26
27
|
royalty: number;
|
|
27
|
-
value: string;
|
|
28
28
|
recipient: string;
|
|
29
29
|
description?: string | undefined;
|
|
30
30
|
external_url?: string | undefined;
|
|
31
31
|
}, {
|
|
32
32
|
name: string;
|
|
33
|
+
value: string;
|
|
33
34
|
ipType: "Audio" | "Video" | "Art" | "Photography" | "NFT" | "Software" | "RWA" | "Patents" | "Posts" | "Publications" | "Documents" | "Custom";
|
|
34
35
|
licenseType: string;
|
|
35
36
|
commercialUse: "Yes" | "No";
|
|
@@ -38,7 +39,6 @@ declare const editionMintSchema: z.ZodObject<{
|
|
|
38
39
|
geographicScope: string;
|
|
39
40
|
aiPolicy: "Allowed" | "Not Allowed" | "Training Only";
|
|
40
41
|
royalty: number;
|
|
41
|
-
value: string;
|
|
42
42
|
recipient: string;
|
|
43
43
|
description?: string | undefined;
|
|
44
44
|
external_url?: string | undefined;
|
|
@@ -16,6 +16,7 @@ declare const editionMintSchema: z.ZodObject<{
|
|
|
16
16
|
royalty: z.ZodNumber;
|
|
17
17
|
}, "strip", z.ZodTypeAny, {
|
|
18
18
|
name: string;
|
|
19
|
+
value: string;
|
|
19
20
|
ipType: "Audio" | "Video" | "Art" | "Photography" | "NFT" | "Software" | "RWA" | "Patents" | "Posts" | "Publications" | "Documents" | "Custom";
|
|
20
21
|
licenseType: string;
|
|
21
22
|
commercialUse: "Yes" | "No";
|
|
@@ -24,12 +25,12 @@ declare const editionMintSchema: z.ZodObject<{
|
|
|
24
25
|
geographicScope: string;
|
|
25
26
|
aiPolicy: "Allowed" | "Not Allowed" | "Training Only";
|
|
26
27
|
royalty: number;
|
|
27
|
-
value: string;
|
|
28
28
|
recipient: string;
|
|
29
29
|
description?: string | undefined;
|
|
30
30
|
external_url?: string | undefined;
|
|
31
31
|
}, {
|
|
32
32
|
name: string;
|
|
33
|
+
value: string;
|
|
33
34
|
ipType: "Audio" | "Video" | "Art" | "Photography" | "NFT" | "Software" | "RWA" | "Patents" | "Posts" | "Publications" | "Documents" | "Custom";
|
|
34
35
|
licenseType: string;
|
|
35
36
|
commercialUse: "Yes" | "No";
|
|
@@ -38,7 +39,6 @@ declare const editionMintSchema: z.ZodObject<{
|
|
|
38
39
|
geographicScope: string;
|
|
39
40
|
aiPolicy: "Allowed" | "Not Allowed" | "Training Only";
|
|
40
41
|
royalty: number;
|
|
41
|
-
value: string;
|
|
42
42
|
recipient: string;
|
|
43
43
|
description?: string | undefined;
|
|
44
44
|
external_url?: string | undefined;
|
|
@@ -36,6 +36,8 @@ function PageBackdrop({ image }) {
|
|
|
36
36
|
src: image,
|
|
37
37
|
alt: "",
|
|
38
38
|
"aria-hidden": true,
|
|
39
|
+
loading: "lazy",
|
|
40
|
+
decoding: "async",
|
|
39
41
|
className: "absolute inset-0 w-full h-full object-cover opacity-50 dark:opacity-40 scale-110",
|
|
40
42
|
style: { filter: "blur(80px) saturate(1.8)" }
|
|
41
43
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/media-header.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState, type ElementType, type ReactNode } from \"react\";\nimport { Skeleton } from \"./skeleton.js\";\n\nexport interface MediaHeaderProps {\n image: string | null;\n imageAlt: string;\n fallbackIcon: ElementType;\n loading?: boolean;\n children: ReactNode;\n}\n\nexport function PageBackdrop({ image }: { image: string | null }) {\n if (!image) return null;\n return (\n <div className=\"fixed inset-0 -z-10 overflow-hidden pointer-events-none\">\n <img\n src={image}\n alt=\"\"\n aria-hidden\n className=\"absolute inset-0 w-full h-full object-cover opacity-50 dark:opacity-40 scale-110\"\n style={{ filter: \"blur(80px) saturate(1.8)\" }}\n />\n </div>\n );\n}\n\nconst FRAME = \"w-full sm:w-44 lg:w-56 shrink-0 rounded-2xl overflow-hidden bg-muted\";\n\nexport function MediaHeader({ image, imageAlt, fallbackIcon: FallbackIcon, loading = false, children }: MediaHeaderProps) {\n const [imgError, setImgError] = useState(false);\n\n if (loading) {\n return (\n <div className=\"flex flex-col sm:flex-row gap-6 lg:gap-8 items-start lg:max-w-5xl lg:mx-auto\">\n <Skeleton className={`${FRAME} aspect-square`} />\n <div className=\"flex-1 w-full space-y-3\">\n <Skeleton className=\"h-6 w-40\" />\n <Skeleton className=\"h-10 w-2/3\" />\n <Skeleton className=\"h-16 w-full\" />\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"flex flex-col sm:flex-row gap-6 lg:gap-8 items-start lg:max-w-5xl lg:mx-auto\">\n <PageBackdrop image={image} />\n\n <div className={FRAME}>\n {image && !imgError ? (\n <img src={image} alt={imageAlt} onError={() => setImgError(true)} className=\"block w-full h-auto max-h-[80vh] object-contain sm:aspect-square sm:h-full sm:object-cover\" />\n ) : (\n <div className=\"aspect-square w-full flex items-center justify-center\">\n <FallbackIcon className=\"h-1/3 w-1/3 text-muted-foreground/40\" />\n </div>\n )}\n </div>\n\n <div className=\"flex-1 space-y-5 min-w-0 w-full\">{children}</div>\n </div>\n );\n}\n\nexport function HeaderStats({ children }: { children: ReactNode }) {\n return <div className=\"flex flex-wrap items-center gap-x-4 gap-y-1 text-sm text-muted-foreground\">{children}</div>;\n}\n\nexport function HeaderStat({ label, children }: { label: string; children: ReactNode }) {\n return (\n <span className=\"inline-flex items-center gap-1.5\">\n <span>{label}</span>\n <span className=\"font-semibold text-foreground tabular-nums\">{children}</span>\n </span>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAiBM;AAfN,mBAA2D;AAC3D,sBAAyB;AAUlB,SAAS,aAAa,EAAE,MAAM,GAA6B;AAChE,MAAI,CAAC,MAAO,QAAO;AACnB,SACE,4CAAC,SAAI,WAAU,2DACb;AAAA,IAAC;AAAA;AAAA,MACC,KAAK;AAAA,MACL,KAAI;AAAA,MACJ,eAAW;AAAA,MACX,WAAU;AAAA,MACV,OAAO,EAAE,QAAQ,2BAA2B;AAAA;AAAA,EAC9C,GACF;AAEJ;AAEA,MAAM,QAAQ;AAEP,SAAS,YAAY,EAAE,OAAO,UAAU,cAAc,cAAc,UAAU,OAAO,SAAS,GAAqB;AACxH,QAAM,CAAC,UAAU,WAAW,QAAI,uBAAS,KAAK;AAE9C,MAAI,SAAS;AACX,WACE,6CAAC,SAAI,WAAU,gFACb;AAAA,kDAAC,4BAAS,WAAW,GAAG,KAAK,kBAAkB;AAAA,MAC/C,6CAAC,SAAI,WAAU,2BACb;AAAA,oDAAC,4BAAS,WAAU,YAAW;AAAA,QAC/B,4CAAC,4BAAS,WAAU,cAAa;AAAA,QACjC,4CAAC,4BAAS,WAAU,eAAc;AAAA,SACpC;AAAA,OACF;AAAA,EAEJ;AAEA,SACE,6CAAC,SAAI,WAAU,gFACb;AAAA,gDAAC,gBAAa,OAAc;AAAA,IAE5B,4CAAC,SAAI,WAAW,OACb,mBAAS,CAAC,WACT,4CAAC,SAAI,KAAK,OAAO,KAAK,UAAU,SAAS,MAAM,YAAY,IAAI,GAAG,WAAU,8FAA6F,IAEzK,4CAAC,SAAI,WAAU,yDACb,sDAAC,gBAAa,WAAU,wCAAuC,GACjE,GAEJ;AAAA,IAEA,4CAAC,SAAI,WAAU,mCAAmC,UAAS;AAAA,KAC7D;AAEJ;AAEO,SAAS,YAAY,EAAE,SAAS,GAA4B;AACjE,SAAO,4CAAC,SAAI,WAAU,6EAA6E,UAAS;AAC9G;AAEO,SAAS,WAAW,EAAE,OAAO,SAAS,GAA2C;AACtF,SACE,6CAAC,UAAK,WAAU,oCACd;AAAA,gDAAC,UAAM,iBAAM;AAAA,IACb,4CAAC,UAAK,WAAU,8CAA8C,UAAS;AAAA,KACzE;AAEJ;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/components/media-header.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState, type ElementType, type ReactNode } from \"react\";\nimport { Skeleton } from \"./skeleton.js\";\n\nexport interface MediaHeaderProps {\n image: string | null;\n imageAlt: string;\n fallbackIcon: ElementType;\n loading?: boolean;\n children: ReactNode;\n}\n\nexport function PageBackdrop({ image }: { image: string | null }) {\n if (!image) return null;\n return (\n <div className=\"fixed inset-0 -z-10 overflow-hidden pointer-events-none\">\n <img\n src={image}\n alt=\"\"\n aria-hidden\n loading=\"lazy\"\n decoding=\"async\"\n className=\"absolute inset-0 w-full h-full object-cover opacity-50 dark:opacity-40 scale-110\"\n style={{ filter: \"blur(80px) saturate(1.8)\" }}\n />\n </div>\n );\n}\n\nconst FRAME = \"w-full sm:w-44 lg:w-56 shrink-0 rounded-2xl overflow-hidden bg-muted\";\n\nexport function MediaHeader({ image, imageAlt, fallbackIcon: FallbackIcon, loading = false, children }: MediaHeaderProps) {\n const [imgError, setImgError] = useState(false);\n\n if (loading) {\n return (\n <div className=\"flex flex-col sm:flex-row gap-6 lg:gap-8 items-start lg:max-w-5xl lg:mx-auto\">\n <Skeleton className={`${FRAME} aspect-square`} />\n <div className=\"flex-1 w-full space-y-3\">\n <Skeleton className=\"h-6 w-40\" />\n <Skeleton className=\"h-10 w-2/3\" />\n <Skeleton className=\"h-16 w-full\" />\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"flex flex-col sm:flex-row gap-6 lg:gap-8 items-start lg:max-w-5xl lg:mx-auto\">\n <PageBackdrop image={image} />\n\n <div className={FRAME}>\n {image && !imgError ? (\n <img src={image} alt={imageAlt} onError={() => setImgError(true)} className=\"block w-full h-auto max-h-[80vh] object-contain sm:aspect-square sm:h-full sm:object-cover\" />\n ) : (\n <div className=\"aspect-square w-full flex items-center justify-center\">\n <FallbackIcon className=\"h-1/3 w-1/3 text-muted-foreground/40\" />\n </div>\n )}\n </div>\n\n <div className=\"flex-1 space-y-5 min-w-0 w-full\">{children}</div>\n </div>\n );\n}\n\nexport function HeaderStats({ children }: { children: ReactNode }) {\n return <div className=\"flex flex-wrap items-center gap-x-4 gap-y-1 text-sm text-muted-foreground\">{children}</div>;\n}\n\nexport function HeaderStat({ label, children }: { label: string; children: ReactNode }) {\n return (\n <span className=\"inline-flex items-center gap-1.5\">\n <span>{label}</span>\n <span className=\"font-semibold text-foreground tabular-nums\">{children}</span>\n </span>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAiBM;AAfN,mBAA2D;AAC3D,sBAAyB;AAUlB,SAAS,aAAa,EAAE,MAAM,GAA6B;AAChE,MAAI,CAAC,MAAO,QAAO;AACnB,SACE,4CAAC,SAAI,WAAU,2DACb;AAAA,IAAC;AAAA;AAAA,MACC,KAAK;AAAA,MACL,KAAI;AAAA,MACJ,eAAW;AAAA,MACX,SAAQ;AAAA,MACR,UAAS;AAAA,MACT,WAAU;AAAA,MACV,OAAO,EAAE,QAAQ,2BAA2B;AAAA;AAAA,EAC9C,GACF;AAEJ;AAEA,MAAM,QAAQ;AAEP,SAAS,YAAY,EAAE,OAAO,UAAU,cAAc,cAAc,UAAU,OAAO,SAAS,GAAqB;AACxH,QAAM,CAAC,UAAU,WAAW,QAAI,uBAAS,KAAK;AAE9C,MAAI,SAAS;AACX,WACE,6CAAC,SAAI,WAAU,gFACb;AAAA,kDAAC,4BAAS,WAAW,GAAG,KAAK,kBAAkB;AAAA,MAC/C,6CAAC,SAAI,WAAU,2BACb;AAAA,oDAAC,4BAAS,WAAU,YAAW;AAAA,QAC/B,4CAAC,4BAAS,WAAU,cAAa;AAAA,QACjC,4CAAC,4BAAS,WAAU,eAAc;AAAA,SACpC;AAAA,OACF;AAAA,EAEJ;AAEA,SACE,6CAAC,SAAI,WAAU,gFACb;AAAA,gDAAC,gBAAa,OAAc;AAAA,IAE5B,4CAAC,SAAI,WAAW,OACb,mBAAS,CAAC,WACT,4CAAC,SAAI,KAAK,OAAO,KAAK,UAAU,SAAS,MAAM,YAAY,IAAI,GAAG,WAAU,8FAA6F,IAEzK,4CAAC,SAAI,WAAU,yDACb,sDAAC,gBAAa,WAAU,wCAAuC,GACjE,GAEJ;AAAA,IAEA,4CAAC,SAAI,WAAU,mCAAmC,UAAS;AAAA,KAC7D;AAEJ;AAEO,SAAS,YAAY,EAAE,SAAS,GAA4B;AACjE,SAAO,4CAAC,SAAI,WAAU,6EAA6E,UAAS;AAC9G;AAEO,SAAS,WAAW,EAAE,OAAO,SAAS,GAA2C;AACtF,SACE,6CAAC,UAAK,WAAU,oCACd;AAAA,gDAAC,UAAM,iBAAM;AAAA,IACb,4CAAC,UAAK,WAAU,8CAA8C,UAAS;AAAA,KACzE;AAEJ;","names":[]}
|
|
@@ -10,6 +10,8 @@ function PageBackdrop({ image }) {
|
|
|
10
10
|
src: image,
|
|
11
11
|
alt: "",
|
|
12
12
|
"aria-hidden": true,
|
|
13
|
+
loading: "lazy",
|
|
14
|
+
decoding: "async",
|
|
13
15
|
className: "absolute inset-0 w-full h-full object-cover opacity-50 dark:opacity-40 scale-110",
|
|
14
16
|
style: { filter: "blur(80px) saturate(1.8)" }
|
|
15
17
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/media-header.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState, type ElementType, type ReactNode } from \"react\";\nimport { Skeleton } from \"./skeleton.js\";\n\nexport interface MediaHeaderProps {\n image: string | null;\n imageAlt: string;\n fallbackIcon: ElementType;\n loading?: boolean;\n children: ReactNode;\n}\n\nexport function PageBackdrop({ image }: { image: string | null }) {\n if (!image) return null;\n return (\n <div className=\"fixed inset-0 -z-10 overflow-hidden pointer-events-none\">\n <img\n src={image}\n alt=\"\"\n aria-hidden\n className=\"absolute inset-0 w-full h-full object-cover opacity-50 dark:opacity-40 scale-110\"\n style={{ filter: \"blur(80px) saturate(1.8)\" }}\n />\n </div>\n );\n}\n\nconst FRAME = \"w-full sm:w-44 lg:w-56 shrink-0 rounded-2xl overflow-hidden bg-muted\";\n\nexport function MediaHeader({ image, imageAlt, fallbackIcon: FallbackIcon, loading = false, children }: MediaHeaderProps) {\n const [imgError, setImgError] = useState(false);\n\n if (loading) {\n return (\n <div className=\"flex flex-col sm:flex-row gap-6 lg:gap-8 items-start lg:max-w-5xl lg:mx-auto\">\n <Skeleton className={`${FRAME} aspect-square`} />\n <div className=\"flex-1 w-full space-y-3\">\n <Skeleton className=\"h-6 w-40\" />\n <Skeleton className=\"h-10 w-2/3\" />\n <Skeleton className=\"h-16 w-full\" />\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"flex flex-col sm:flex-row gap-6 lg:gap-8 items-start lg:max-w-5xl lg:mx-auto\">\n <PageBackdrop image={image} />\n\n <div className={FRAME}>\n {image && !imgError ? (\n <img src={image} alt={imageAlt} onError={() => setImgError(true)} className=\"block w-full h-auto max-h-[80vh] object-contain sm:aspect-square sm:h-full sm:object-cover\" />\n ) : (\n <div className=\"aspect-square w-full flex items-center justify-center\">\n <FallbackIcon className=\"h-1/3 w-1/3 text-muted-foreground/40\" />\n </div>\n )}\n </div>\n\n <div className=\"flex-1 space-y-5 min-w-0 w-full\">{children}</div>\n </div>\n );\n}\n\nexport function HeaderStats({ children }: { children: ReactNode }) {\n return <div className=\"flex flex-wrap items-center gap-x-4 gap-y-1 text-sm text-muted-foreground\">{children}</div>;\n}\n\nexport function HeaderStat({ label, children }: { label: string; children: ReactNode }) {\n return (\n <span className=\"inline-flex items-center gap-1.5\">\n <span>{label}</span>\n <span className=\"font-semibold text-foreground tabular-nums\">{children}</span>\n </span>\n );\n}\n"],"mappings":";AAiBM,
|
|
1
|
+
{"version":3,"sources":["../../src/components/media-header.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState, type ElementType, type ReactNode } from \"react\";\nimport { Skeleton } from \"./skeleton.js\";\n\nexport interface MediaHeaderProps {\n image: string | null;\n imageAlt: string;\n fallbackIcon: ElementType;\n loading?: boolean;\n children: ReactNode;\n}\n\nexport function PageBackdrop({ image }: { image: string | null }) {\n if (!image) return null;\n return (\n <div className=\"fixed inset-0 -z-10 overflow-hidden pointer-events-none\">\n <img\n src={image}\n alt=\"\"\n aria-hidden\n loading=\"lazy\"\n decoding=\"async\"\n className=\"absolute inset-0 w-full h-full object-cover opacity-50 dark:opacity-40 scale-110\"\n style={{ filter: \"blur(80px) saturate(1.8)\" }}\n />\n </div>\n );\n}\n\nconst FRAME = \"w-full sm:w-44 lg:w-56 shrink-0 rounded-2xl overflow-hidden bg-muted\";\n\nexport function MediaHeader({ image, imageAlt, fallbackIcon: FallbackIcon, loading = false, children }: MediaHeaderProps) {\n const [imgError, setImgError] = useState(false);\n\n if (loading) {\n return (\n <div className=\"flex flex-col sm:flex-row gap-6 lg:gap-8 items-start lg:max-w-5xl lg:mx-auto\">\n <Skeleton className={`${FRAME} aspect-square`} />\n <div className=\"flex-1 w-full space-y-3\">\n <Skeleton className=\"h-6 w-40\" />\n <Skeleton className=\"h-10 w-2/3\" />\n <Skeleton className=\"h-16 w-full\" />\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"flex flex-col sm:flex-row gap-6 lg:gap-8 items-start lg:max-w-5xl lg:mx-auto\">\n <PageBackdrop image={image} />\n\n <div className={FRAME}>\n {image && !imgError ? (\n <img src={image} alt={imageAlt} onError={() => setImgError(true)} className=\"block w-full h-auto max-h-[80vh] object-contain sm:aspect-square sm:h-full sm:object-cover\" />\n ) : (\n <div className=\"aspect-square w-full flex items-center justify-center\">\n <FallbackIcon className=\"h-1/3 w-1/3 text-muted-foreground/40\" />\n </div>\n )}\n </div>\n\n <div className=\"flex-1 space-y-5 min-w-0 w-full\">{children}</div>\n </div>\n );\n}\n\nexport function HeaderStats({ children }: { children: ReactNode }) {\n return <div className=\"flex flex-wrap items-center gap-x-4 gap-y-1 text-sm text-muted-foreground\">{children}</div>;\n}\n\nexport function HeaderStat({ label, children }: { label: string; children: ReactNode }) {\n return (\n <span className=\"inline-flex items-center gap-1.5\">\n <span>{label}</span>\n <span className=\"font-semibold text-foreground tabular-nums\">{children}</span>\n </span>\n );\n}\n"],"mappings":";AAiBM,cAsBE,YAtBF;AAfN,SAAS,gBAAkD;AAC3D,SAAS,gBAAgB;AAUlB,SAAS,aAAa,EAAE,MAAM,GAA6B;AAChE,MAAI,CAAC,MAAO,QAAO;AACnB,SACE,oBAAC,SAAI,WAAU,2DACb;AAAA,IAAC;AAAA;AAAA,MACC,KAAK;AAAA,MACL,KAAI;AAAA,MACJ,eAAW;AAAA,MACX,SAAQ;AAAA,MACR,UAAS;AAAA,MACT,WAAU;AAAA,MACV,OAAO,EAAE,QAAQ,2BAA2B;AAAA;AAAA,EAC9C,GACF;AAEJ;AAEA,MAAM,QAAQ;AAEP,SAAS,YAAY,EAAE,OAAO,UAAU,cAAc,cAAc,UAAU,OAAO,SAAS,GAAqB;AACxH,QAAM,CAAC,UAAU,WAAW,IAAI,SAAS,KAAK;AAE9C,MAAI,SAAS;AACX,WACE,qBAAC,SAAI,WAAU,gFACb;AAAA,0BAAC,YAAS,WAAW,GAAG,KAAK,kBAAkB;AAAA,MAC/C,qBAAC,SAAI,WAAU,2BACb;AAAA,4BAAC,YAAS,WAAU,YAAW;AAAA,QAC/B,oBAAC,YAAS,WAAU,cAAa;AAAA,QACjC,oBAAC,YAAS,WAAU,eAAc;AAAA,SACpC;AAAA,OACF;AAAA,EAEJ;AAEA,SACE,qBAAC,SAAI,WAAU,gFACb;AAAA,wBAAC,gBAAa,OAAc;AAAA,IAE5B,oBAAC,SAAI,WAAW,OACb,mBAAS,CAAC,WACT,oBAAC,SAAI,KAAK,OAAO,KAAK,UAAU,SAAS,MAAM,YAAY,IAAI,GAAG,WAAU,8FAA6F,IAEzK,oBAAC,SAAI,WAAU,yDACb,8BAAC,gBAAa,WAAU,wCAAuC,GACjE,GAEJ;AAAA,IAEA,oBAAC,SAAI,WAAU,mCAAmC,UAAS;AAAA,KAC7D;AAEJ;AAEO,SAAS,YAAY,EAAE,SAAS,GAA4B;AACjE,SAAO,oBAAC,SAAI,WAAU,6EAA6E,UAAS;AAC9G;AAEO,SAAS,WAAW,EAAE,OAAO,SAAS,GAA2C;AACtF,SACE,qBAAC,UAAK,WAAU,oCACd;AAAA,wBAAC,UAAM,iBAAM;AAAA,IACb,oBAAC,UAAK,WAAU,8CAA8C,UAAS;AAAA,KACzE;AAEJ;","names":[]}
|
|
@@ -54,7 +54,7 @@ function CreatorIdentity({ address, compact }) {
|
|
|
54
54
|
walletAddress: address
|
|
55
55
|
});
|
|
56
56
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "inline-flex min-w-0 items-center gap-2.5", children: [
|
|
57
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className:
|
|
57
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "relative h-9 w-9 shrink-0 overflow-hidden rounded-full bg-foreground/[0.08]", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
58
58
|
import_image.default,
|
|
59
59
|
{
|
|
60
60
|
src: avatarUrl ?? "/icon.png",
|
|
@@ -83,7 +83,7 @@ function LeaderboardPanel({
|
|
|
83
83
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "flex h-7 w-7 items-center justify-center rounded-lg bg-gradient-to-br from-brand-rose to-brand-orange text-white shrink-0", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.Sparkles, { className: "h-3.5 w-3.5" }) }),
|
|
84
84
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h2", { className: "text-sm font-black", children: "Community Rewards" })
|
|
85
85
|
] }),
|
|
86
|
-
isLoading ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: compact ? "divide-y divide-border/40" : "space-y-1.5", children: Array.from({ length: Math.min(limit, 6) }).map((_, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_skeleton.Skeleton, { className: compact ? "h-
|
|
86
|
+
isLoading ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: compact ? "divide-y divide-border/40" : "space-y-1.5", children: Array.from({ length: Math.min(limit, 6) }).map((_, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_skeleton.Skeleton, { className: compact ? "h-16 w-full rounded-none" : "h-10 w-full rounded-lg" }, i)) }) : rows.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: (0, import_cn.cn)("text-sm text-muted-foreground py-4", compact && "px-4"), children: "Nobody's earned points yet \u2014 be the first." }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
87
87
|
import_leaderboard_table.LeaderboardTable,
|
|
88
88
|
{
|
|
89
89
|
entries: rows,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/rewards/leaderboard-panel.tsx"],"sourcesContent":["\"use client\";\n\nimport { Sparkles } from \"lucide-react\";\nimport { normalizeAddress, profileHref } from \"@medialane/sdk\";\nimport Image from \"../image.js\";\nimport Link from \"../link.js\";\nimport { Skeleton } from \"../skeleton.js\";\nimport { AddressDisplay } from \"../address-display.js\";\nimport { LeaderboardTable } from \"./leaderboard-table.js\";\nimport { cn } from \"../../utils/cn.js\";\nimport { profileIdentity } from \"../../utils/profile-identity.js\";\nimport { useCreatorProfile } from \"../../utils/use-profiles.js\";\nimport { useImageUrl } from \"../../utils/use-image-url.js\";\nimport { useLeaderboard } from \"../../utils/use-rewards.js\";\n\nexport interface LeaderboardPanelProps {\n myAddress?: string | null;\n limit?: number;\n showHeading?: boolean;\n viewAllHref?: string;\n compact?: boolean;\n className?: string;\n}\n\nfunction CreatorIdentity({ address, compact }: { address: string; compact?: boolean }) {\n const { profile } = useCreatorProfile(address);\n const avatarUrl = useImageUrl()(profile?.avatarImage, { width: 96 });\n const { identity: name } = profileIdentity({\n username: profile?.username,\n name: profile?.name,\n walletAddress: address,\n });\n\n return (\n <span className=\"inline-flex min-w-0 items-center gap-2.5\">\n <span className
|
|
1
|
+
{"version":3,"sources":["../../../src/components/rewards/leaderboard-panel.tsx"],"sourcesContent":["\"use client\";\n\nimport { Sparkles } from \"lucide-react\";\nimport { normalizeAddress, profileHref } from \"@medialane/sdk\";\nimport Image from \"../image.js\";\nimport Link from \"../link.js\";\nimport { Skeleton } from \"../skeleton.js\";\nimport { AddressDisplay } from \"../address-display.js\";\nimport { LeaderboardTable } from \"./leaderboard-table.js\";\nimport { cn } from \"../../utils/cn.js\";\nimport { profileIdentity } from \"../../utils/profile-identity.js\";\nimport { useCreatorProfile } from \"../../utils/use-profiles.js\";\nimport { useImageUrl } from \"../../utils/use-image-url.js\";\nimport { useLeaderboard } from \"../../utils/use-rewards.js\";\n\nexport interface LeaderboardPanelProps {\n myAddress?: string | null;\n limit?: number;\n showHeading?: boolean;\n viewAllHref?: string;\n compact?: boolean;\n className?: string;\n}\n\nfunction CreatorIdentity({ address, compact }: { address: string; compact?: boolean }) {\n const { profile } = useCreatorProfile(address);\n const avatarUrl = useImageUrl()(profile?.avatarImage, { width: 96 });\n const { identity: name } = profileIdentity({\n username: profile?.username,\n name: profile?.name,\n walletAddress: address,\n });\n\n return (\n <span className=\"inline-flex min-w-0 items-center gap-2.5\">\n <span className=\"relative h-9 w-9 shrink-0 overflow-hidden rounded-full bg-foreground/[0.08]\">\n <Image\n src={avatarUrl ?? \"/icon.png\"}\n alt=\"\"\n fill\n unoptimized\n className={avatarUrl ? \"object-cover\" : \"object-cover p-[15%] opacity-50\"}\n />\n </span>\n {name ? (\n <span className={cn(\"truncate font-bold\", compact ? \"text-sm font-semibold\" : \"text-base\")}>{name}</span>\n ) : (\n <AddressDisplay address={address} chars={4} showCopy={false} className={compact ? \"text-sm font-semibold\" : \"text-base font-bold\"} />\n )}\n </span>\n );\n}\n\nexport function LeaderboardPanel({\n myAddress,\n limit = 20,\n showHeading = true,\n viewAllHref,\n compact,\n className,\n}: LeaderboardPanelProps) {\n const { data, isLoading } = useLeaderboard(1, limit);\n const rows = data?.data ?? [];\n\n const highlightAddress = myAddress ? normalizeAddress(\"STARKNET\", myAddress) : null;\n\n return (\n <div className={cn(compact ? \"\" : \"space-y-3\", className)}>\n {showHeading && (\n <div className=\"flex items-center gap-2\">\n <div className=\"flex h-7 w-7 items-center justify-center rounded-lg bg-gradient-to-br from-brand-rose to-brand-orange text-white shrink-0\">\n <Sparkles className=\"h-3.5 w-3.5\" />\n </div>\n <h2 className=\"text-sm font-black\">Community Rewards</h2>\n </div>\n )}\n\n {isLoading ? (\n <div className={compact ? \"divide-y divide-border/40\" : \"space-y-1.5\"}>\n {Array.from({ length: Math.min(limit, 6) }).map((_, i) => (\n <Skeleton key={i} className={compact ? \"h-16 w-full rounded-none\" : \"h-10 w-full rounded-lg\"} />\n ))}\n </div>\n ) : rows.length === 0 ? (\n <p className={cn(\"text-sm text-muted-foreground py-4\", compact && \"px-4\")}>\n Nobody's earned points yet — be the first.\n </p>\n ) : (\n <LeaderboardTable\n entries={rows}\n highlightAddress={highlightAddress}\n compact={compact}\n renderAddress={(address) => (\n <Link href={profileHref({ address })} className=\"hover:text-foreground transition-colors\">\n <CreatorIdentity address={address} compact={compact} />\n </Link>\n )}\n />\n )}\n\n {viewAllHref && rows.length > 0 && (\n <Link\n href={viewAllHref}\n className=\"inline-flex items-center gap-1 text-xs font-semibold text-muted-foreground hover:text-foreground transition-colors pt-1\"\n >\n View scoreboard →\n </Link>\n )}\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAkCI;AAhCJ,0BAAyB;AACzB,iBAA8C;AAC9C,mBAAkB;AAClB,kBAAiB;AACjB,sBAAyB;AACzB,6BAA+B;AAC/B,+BAAiC;AACjC,gBAAmB;AACnB,8BAAgC;AAChC,0BAAkC;AAClC,2BAA4B;AAC5B,yBAA+B;AAW/B,SAAS,gBAAgB,EAAE,SAAS,QAAQ,GAA2C;AACrF,QAAM,EAAE,QAAQ,QAAI,uCAAkB,OAAO;AAC7C,QAAM,gBAAY,kCAAY,EAAE,SAAS,aAAa,EAAE,OAAO,GAAG,CAAC;AACnE,QAAM,EAAE,UAAU,KAAK,QAAI,yCAAgB;AAAA,IACzC,UAAU,SAAS;AAAA,IACnB,MAAM,SAAS;AAAA,IACf,eAAe;AAAA,EACjB,CAAC;AAED,SACE,6CAAC,UAAK,WAAU,4CACd;AAAA,gDAAC,UAAK,WAAU,+EACd;AAAA,MAAC,aAAAA;AAAA,MAAA;AAAA,QACC,KAAK,aAAa;AAAA,QAClB,KAAI;AAAA,QACJ,MAAI;AAAA,QACJ,aAAW;AAAA,QACX,WAAW,YAAY,iBAAiB;AAAA;AAAA,IAC1C,GACF;AAAA,IACC,OACC,4CAAC,UAAK,eAAW,cAAG,sBAAsB,UAAU,0BAA0B,WAAW,GAAI,gBAAK,IAElG,4CAAC,yCAAe,SAAkB,OAAO,GAAG,UAAU,OAAO,WAAW,UAAU,0BAA0B,uBAAuB;AAAA,KAEvI;AAEJ;AAEO,SAAS,iBAAiB;AAAA,EAC/B;AAAA,EACA,QAAQ;AAAA,EACR,cAAc;AAAA,EACd;AAAA,EACA;AAAA,EACA;AACF,GAA0B;AACxB,QAAM,EAAE,MAAM,UAAU,QAAI,mCAAe,GAAG,KAAK;AACnD,QAAM,OAAO,MAAM,QAAQ,CAAC;AAE5B,QAAM,mBAAmB,gBAAY,6BAAiB,YAAY,SAAS,IAAI;AAE/E,SACE,6CAAC,SAAI,eAAW,cAAG,UAAU,KAAK,aAAa,SAAS,GACrD;AAAA,mBACC,6CAAC,SAAI,WAAU,2BACb;AAAA,kDAAC,SAAI,WAAU,6HACb,sDAAC,gCAAS,WAAU,eAAc,GACpC;AAAA,MACA,4CAAC,QAAG,WAAU,sBAAqB,+BAAiB;AAAA,OACtD;AAAA,IAGD,YACC,4CAAC,SAAI,WAAW,UAAU,8BAA8B,eACrD,gBAAM,KAAK,EAAE,QAAQ,KAAK,IAAI,OAAO,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,GAAG,MAClD,4CAAC,4BAAiB,WAAW,UAAU,6BAA6B,4BAArD,CAA+E,CAC/F,GACH,IACE,KAAK,WAAW,IAClB,4CAAC,OAAE,eAAW,cAAG,sCAAsC,WAAW,MAAM,GAAG,6DAE3E,IAEA;AAAA,MAAC;AAAA;AAAA,QACC,SAAS;AAAA,QACT;AAAA,QACA;AAAA,QACA,eAAe,CAAC,YACd,4CAAC,YAAAC,SAAA,EAAK,UAAM,wBAAY,EAAE,QAAQ,CAAC,GAAG,WAAU,2CAC9C,sDAAC,mBAAgB,SAAkB,SAAkB,GACvD;AAAA;AAAA,IAEJ;AAAA,IAGD,eAAe,KAAK,SAAS,KAC5B;AAAA,MAAC,YAAAA;AAAA,MAAA;AAAA,QACC,MAAM;AAAA,QACN,WAAU;AAAA,QACX;AAAA;AAAA,IAED;AAAA,KAEJ;AAEJ;","names":["Image","Link"]}
|
|
@@ -21,7 +21,7 @@ function CreatorIdentity({ address, compact }) {
|
|
|
21
21
|
walletAddress: address
|
|
22
22
|
});
|
|
23
23
|
return /* @__PURE__ */ jsxs("span", { className: "inline-flex min-w-0 items-center gap-2.5", children: [
|
|
24
|
-
/* @__PURE__ */ jsx("span", { className:
|
|
24
|
+
/* @__PURE__ */ jsx("span", { className: "relative h-9 w-9 shrink-0 overflow-hidden rounded-full bg-foreground/[0.08]", children: /* @__PURE__ */ jsx(
|
|
25
25
|
Image,
|
|
26
26
|
{
|
|
27
27
|
src: avatarUrl ?? "/icon.png",
|
|
@@ -50,7 +50,7 @@ function LeaderboardPanel({
|
|
|
50
50
|
/* @__PURE__ */ jsx("div", { className: "flex h-7 w-7 items-center justify-center rounded-lg bg-gradient-to-br from-brand-rose to-brand-orange text-white shrink-0", children: /* @__PURE__ */ jsx(Sparkles, { className: "h-3.5 w-3.5" }) }),
|
|
51
51
|
/* @__PURE__ */ jsx("h2", { className: "text-sm font-black", children: "Community Rewards" })
|
|
52
52
|
] }),
|
|
53
|
-
isLoading ? /* @__PURE__ */ jsx("div", { className: compact ? "divide-y divide-border/40" : "space-y-1.5", children: Array.from({ length: Math.min(limit, 6) }).map((_, i) => /* @__PURE__ */ jsx(Skeleton, { className: compact ? "h-
|
|
53
|
+
isLoading ? /* @__PURE__ */ jsx("div", { className: compact ? "divide-y divide-border/40" : "space-y-1.5", children: Array.from({ length: Math.min(limit, 6) }).map((_, i) => /* @__PURE__ */ jsx(Skeleton, { className: compact ? "h-16 w-full rounded-none" : "h-10 w-full rounded-lg" }, i)) }) : rows.length === 0 ? /* @__PURE__ */ jsx("p", { className: cn("text-sm text-muted-foreground py-4", compact && "px-4"), children: "Nobody's earned points yet \u2014 be the first." }) : /* @__PURE__ */ jsx(
|
|
54
54
|
LeaderboardTable,
|
|
55
55
|
{
|
|
56
56
|
entries: rows,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/rewards/leaderboard-panel.tsx"],"sourcesContent":["\"use client\";\n\nimport { Sparkles } from \"lucide-react\";\nimport { normalizeAddress, profileHref } from \"@medialane/sdk\";\nimport Image from \"../image.js\";\nimport Link from \"../link.js\";\nimport { Skeleton } from \"../skeleton.js\";\nimport { AddressDisplay } from \"../address-display.js\";\nimport { LeaderboardTable } from \"./leaderboard-table.js\";\nimport { cn } from \"../../utils/cn.js\";\nimport { profileIdentity } from \"../../utils/profile-identity.js\";\nimport { useCreatorProfile } from \"../../utils/use-profiles.js\";\nimport { useImageUrl } from \"../../utils/use-image-url.js\";\nimport { useLeaderboard } from \"../../utils/use-rewards.js\";\n\nexport interface LeaderboardPanelProps {\n myAddress?: string | null;\n limit?: number;\n showHeading?: boolean;\n viewAllHref?: string;\n compact?: boolean;\n className?: string;\n}\n\nfunction CreatorIdentity({ address, compact }: { address: string; compact?: boolean }) {\n const { profile } = useCreatorProfile(address);\n const avatarUrl = useImageUrl()(profile?.avatarImage, { width: 96 });\n const { identity: name } = profileIdentity({\n username: profile?.username,\n name: profile?.name,\n walletAddress: address,\n });\n\n return (\n <span className=\"inline-flex min-w-0 items-center gap-2.5\">\n <span className
|
|
1
|
+
{"version":3,"sources":["../../../src/components/rewards/leaderboard-panel.tsx"],"sourcesContent":["\"use client\";\n\nimport { Sparkles } from \"lucide-react\";\nimport { normalizeAddress, profileHref } from \"@medialane/sdk\";\nimport Image from \"../image.js\";\nimport Link from \"../link.js\";\nimport { Skeleton } from \"../skeleton.js\";\nimport { AddressDisplay } from \"../address-display.js\";\nimport { LeaderboardTable } from \"./leaderboard-table.js\";\nimport { cn } from \"../../utils/cn.js\";\nimport { profileIdentity } from \"../../utils/profile-identity.js\";\nimport { useCreatorProfile } from \"../../utils/use-profiles.js\";\nimport { useImageUrl } from \"../../utils/use-image-url.js\";\nimport { useLeaderboard } from \"../../utils/use-rewards.js\";\n\nexport interface LeaderboardPanelProps {\n myAddress?: string | null;\n limit?: number;\n showHeading?: boolean;\n viewAllHref?: string;\n compact?: boolean;\n className?: string;\n}\n\nfunction CreatorIdentity({ address, compact }: { address: string; compact?: boolean }) {\n const { profile } = useCreatorProfile(address);\n const avatarUrl = useImageUrl()(profile?.avatarImage, { width: 96 });\n const { identity: name } = profileIdentity({\n username: profile?.username,\n name: profile?.name,\n walletAddress: address,\n });\n\n return (\n <span className=\"inline-flex min-w-0 items-center gap-2.5\">\n <span className=\"relative h-9 w-9 shrink-0 overflow-hidden rounded-full bg-foreground/[0.08]\">\n <Image\n src={avatarUrl ?? \"/icon.png\"}\n alt=\"\"\n fill\n unoptimized\n className={avatarUrl ? \"object-cover\" : \"object-cover p-[15%] opacity-50\"}\n />\n </span>\n {name ? (\n <span className={cn(\"truncate font-bold\", compact ? \"text-sm font-semibold\" : \"text-base\")}>{name}</span>\n ) : (\n <AddressDisplay address={address} chars={4} showCopy={false} className={compact ? \"text-sm font-semibold\" : \"text-base font-bold\"} />\n )}\n </span>\n );\n}\n\nexport function LeaderboardPanel({\n myAddress,\n limit = 20,\n showHeading = true,\n viewAllHref,\n compact,\n className,\n}: LeaderboardPanelProps) {\n const { data, isLoading } = useLeaderboard(1, limit);\n const rows = data?.data ?? [];\n\n const highlightAddress = myAddress ? normalizeAddress(\"STARKNET\", myAddress) : null;\n\n return (\n <div className={cn(compact ? \"\" : \"space-y-3\", className)}>\n {showHeading && (\n <div className=\"flex items-center gap-2\">\n <div className=\"flex h-7 w-7 items-center justify-center rounded-lg bg-gradient-to-br from-brand-rose to-brand-orange text-white shrink-0\">\n <Sparkles className=\"h-3.5 w-3.5\" />\n </div>\n <h2 className=\"text-sm font-black\">Community Rewards</h2>\n </div>\n )}\n\n {isLoading ? (\n <div className={compact ? \"divide-y divide-border/40\" : \"space-y-1.5\"}>\n {Array.from({ length: Math.min(limit, 6) }).map((_, i) => (\n <Skeleton key={i} className={compact ? \"h-16 w-full rounded-none\" : \"h-10 w-full rounded-lg\"} />\n ))}\n </div>\n ) : rows.length === 0 ? (\n <p className={cn(\"text-sm text-muted-foreground py-4\", compact && \"px-4\")}>\n Nobody's earned points yet — be the first.\n </p>\n ) : (\n <LeaderboardTable\n entries={rows}\n highlightAddress={highlightAddress}\n compact={compact}\n renderAddress={(address) => (\n <Link href={profileHref({ address })} className=\"hover:text-foreground transition-colors\">\n <CreatorIdentity address={address} compact={compact} />\n </Link>\n )}\n />\n )}\n\n {viewAllHref && rows.length > 0 && (\n <Link\n href={viewAllHref}\n className=\"inline-flex items-center gap-1 text-xs font-semibold text-muted-foreground hover:text-foreground transition-colors pt-1\"\n >\n View scoreboard →\n </Link>\n )}\n </div>\n );\n}\n"],"mappings":";AAkCI,SAEI,KAFJ;AAhCJ,SAAS,gBAAgB;AACzB,SAAS,kBAAkB,mBAAmB;AAC9C,OAAO,WAAW;AAClB,OAAO,UAAU;AACjB,SAAS,gBAAgB;AACzB,SAAS,sBAAsB;AAC/B,SAAS,wBAAwB;AACjC,SAAS,UAAU;AACnB,SAAS,uBAAuB;AAChC,SAAS,yBAAyB;AAClC,SAAS,mBAAmB;AAC5B,SAAS,sBAAsB;AAW/B,SAAS,gBAAgB,EAAE,SAAS,QAAQ,GAA2C;AACrF,QAAM,EAAE,QAAQ,IAAI,kBAAkB,OAAO;AAC7C,QAAM,YAAY,YAAY,EAAE,SAAS,aAAa,EAAE,OAAO,GAAG,CAAC;AACnE,QAAM,EAAE,UAAU,KAAK,IAAI,gBAAgB;AAAA,IACzC,UAAU,SAAS;AAAA,IACnB,MAAM,SAAS;AAAA,IACf,eAAe;AAAA,EACjB,CAAC;AAED,SACE,qBAAC,UAAK,WAAU,4CACd;AAAA,wBAAC,UAAK,WAAU,+EACd;AAAA,MAAC;AAAA;AAAA,QACC,KAAK,aAAa;AAAA,QAClB,KAAI;AAAA,QACJ,MAAI;AAAA,QACJ,aAAW;AAAA,QACX,WAAW,YAAY,iBAAiB;AAAA;AAAA,IAC1C,GACF;AAAA,IACC,OACC,oBAAC,UAAK,WAAW,GAAG,sBAAsB,UAAU,0BAA0B,WAAW,GAAI,gBAAK,IAElG,oBAAC,kBAAe,SAAkB,OAAO,GAAG,UAAU,OAAO,WAAW,UAAU,0BAA0B,uBAAuB;AAAA,KAEvI;AAEJ;AAEO,SAAS,iBAAiB;AAAA,EAC/B;AAAA,EACA,QAAQ;AAAA,EACR,cAAc;AAAA,EACd;AAAA,EACA;AAAA,EACA;AACF,GAA0B;AACxB,QAAM,EAAE,MAAM,UAAU,IAAI,eAAe,GAAG,KAAK;AACnD,QAAM,OAAO,MAAM,QAAQ,CAAC;AAE5B,QAAM,mBAAmB,YAAY,iBAAiB,YAAY,SAAS,IAAI;AAE/E,SACE,qBAAC,SAAI,WAAW,GAAG,UAAU,KAAK,aAAa,SAAS,GACrD;AAAA,mBACC,qBAAC,SAAI,WAAU,2BACb;AAAA,0BAAC,SAAI,WAAU,6HACb,8BAAC,YAAS,WAAU,eAAc,GACpC;AAAA,MACA,oBAAC,QAAG,WAAU,sBAAqB,+BAAiB;AAAA,OACtD;AAAA,IAGD,YACC,oBAAC,SAAI,WAAW,UAAU,8BAA8B,eACrD,gBAAM,KAAK,EAAE,QAAQ,KAAK,IAAI,OAAO,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,GAAG,MAClD,oBAAC,YAAiB,WAAW,UAAU,6BAA6B,4BAArD,CAA+E,CAC/F,GACH,IACE,KAAK,WAAW,IAClB,oBAAC,OAAE,WAAW,GAAG,sCAAsC,WAAW,MAAM,GAAG,6DAE3E,IAEA;AAAA,MAAC;AAAA;AAAA,QACC,SAAS;AAAA,QACT;AAAA,QACA;AAAA,QACA,eAAe,CAAC,YACd,oBAAC,QAAK,MAAM,YAAY,EAAE,QAAQ,CAAC,GAAG,WAAU,2CAC9C,8BAAC,mBAAgB,SAAkB,SAAkB,GACvD;AAAA;AAAA,IAEJ;AAAA,IAGD,eAAe,KAAK,SAAS,KAC5B;AAAA,MAAC;AAAA;AAAA,QACC,MAAM;AAAA,QACN,WAAU;AAAA,QACX;AAAA;AAAA,IAED;AAAA,KAEJ;AAEJ;","names":[]}
|
|
@@ -30,7 +30,7 @@ function LeaderboardTable({ entries, highlightAddress, renderAddress, compact, c
|
|
|
30
30
|
if (compact) {
|
|
31
31
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: (0, import_cn.cn)("divide-y divide-border/40", className), children: entries.map((e) => {
|
|
32
32
|
const isViewer = highlightAddress != null && e.address === highlightAddress;
|
|
33
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: (0, import_cn.cn)("flex items-center gap-3 px-4
|
|
33
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: (0, import_cn.cn)("flex h-16 items-center gap-3 px-4", isViewer && "bg-brand-rose/10"), children: [
|
|
34
34
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "w-4 shrink-0 text-xs font-medium tabular-nums text-muted-foreground", children: e.rank }),
|
|
35
35
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "min-w-0 flex-1 truncate text-sm font-semibold", children: [
|
|
36
36
|
renderAddress ? renderAddress(e.address) : (0, import_address.shortenAddress)(e.address),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/rewards/leaderboard-table.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport { cn } from \"../../utils/cn.js\";\nimport { shortenAddress } from \"../../utils/address.js\";\nimport { LevelBadge } from \"./level-badge.js\";\n\nexport interface LeaderboardEntryLike {\n\n rank: number;\n address: string;\n publicId?: string | null;\n totalXp: number;\n currentLevel: number;\n currentLevelName: string;\n badgeColor: string;\n}\n\nexport interface LeaderboardTableProps {\n entries: LeaderboardEntryLike[];\n\n highlightAddress?: string | null;\n\n renderAddress?: (address: string) => ReactNode;\n compact?: boolean;\n className?: string;\n}\n\nexport function LeaderboardTable({ entries, highlightAddress, renderAddress, compact, className }: LeaderboardTableProps) {\n if (compact) {\n return (\n <div className={cn(\"divide-y divide-border/40\", className)}>\n {entries.map((e) => {\n const isViewer = highlightAddress != null && e.address === highlightAddress;\n return (\n <div key={e.address} className={cn(\"flex items-center gap-3 px-4
|
|
1
|
+
{"version":3,"sources":["../../../src/components/rewards/leaderboard-table.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport { cn } from \"../../utils/cn.js\";\nimport { shortenAddress } from \"../../utils/address.js\";\nimport { LevelBadge } from \"./level-badge.js\";\n\nexport interface LeaderboardEntryLike {\n\n rank: number;\n address: string;\n publicId?: string | null;\n totalXp: number;\n currentLevel: number;\n currentLevelName: string;\n badgeColor: string;\n}\n\nexport interface LeaderboardTableProps {\n entries: LeaderboardEntryLike[];\n\n highlightAddress?: string | null;\n\n renderAddress?: (address: string) => ReactNode;\n compact?: boolean;\n className?: string;\n}\n\nexport function LeaderboardTable({ entries, highlightAddress, renderAddress, compact, className }: LeaderboardTableProps) {\n if (compact) {\n return (\n <div className={cn(\"divide-y divide-border/40\", className)}>\n {entries.map((e) => {\n const isViewer = highlightAddress != null && e.address === highlightAddress;\n return (\n <div key={e.address} className={cn(\"flex h-16 items-center gap-3 px-4\", isViewer && \"bg-brand-rose/10\")}>\n <span className=\"w-4 shrink-0 text-xs font-medium tabular-nums text-muted-foreground\">{e.rank}</span>\n <span className=\"min-w-0 flex-1 truncate text-sm font-semibold\">\n {renderAddress ? renderAddress(e.address) : shortenAddress(e.address)}\n {isViewer && <span className=\"ml-1.5 text-xs font-medium text-foreground/50\">(you)</span>}\n </span>\n <LevelBadge level={e.currentLevel} name={e.currentLevelName} badgeColor={e.badgeColor} size=\"sm\" className=\"hidden sm:inline-flex\" />\n <span className=\"shrink-0 text-sm font-bold tabular-nums\">\n {e.totalXp.toLocaleString()}\n <span className=\"ml-1 text-xs font-medium text-foreground/40\">XP</span>\n </span>\n </div>\n );\n })}\n </div>\n );\n }\n return (\n <div className={cn(\"space-y-1.5\", className)}>\n {entries.map((e) => {\n const isViewer = highlightAddress != null && e.address === highlightAddress;\n return (\n <div\n key={e.address}\n className={cn(\n \"flex items-center gap-4 rounded-2xl px-4 py-3.5 transition-colors\",\n isViewer ? \"bg-brand-rose/10\" : \"bg-foreground/[0.04] hover:bg-foreground/[0.07]\"\n )}\n >\n <span className=\"min-w-0 flex-1 truncate text-base font-bold\">\n {renderAddress ? renderAddress(e.address) : shortenAddress(e.address)}\n {isViewer && <span className=\"ml-1.5 text-xs font-medium text-foreground/50\">(you)</span>}\n </span>\n <LevelBadge level={e.currentLevel} name={e.currentLevelName} badgeColor={e.badgeColor} size=\"sm\" className=\"hidden sm:inline-flex\" />\n <span className=\"shrink-0 text-lg font-black tabular-nums\">\n {e.totalXp.toLocaleString()}\n <span className=\"ml-1 text-xs font-bold text-foreground/40\">XP</span>\n </span>\n </div>\n );\n })}\n </div>\n );\n}\n\nexport interface LeaderboardWidgetProps {\n entries: LeaderboardEntryLike[];\n title?: string;\n\n href?: string;\n renderAddress?: (address: string) => ReactNode;\n className?: string;\n}\n\nexport function LeaderboardWidget({ entries, title = \"Community Rewards\", href, renderAddress, className }: LeaderboardWidgetProps) {\n if (entries.length === 0) return null;\n return (\n <section className={cn(\"rounded-2xl bg-foreground/[0.04] p-5\", className)}>\n <div className=\"mb-3 flex items-center justify-between\">\n <h2 className=\"text-lg font-black\">{title}</h2>\n {href && (\n <a href={href} className=\"text-xs font-bold text-foreground/50 hover:text-foreground active:opacity-70\">\n View scoreboard →\n </a>\n )}\n </div>\n <ol className=\"space-y-2.5\">\n {entries.map((e) => (\n <li key={e.address} className=\"flex items-center gap-2.5\">\n <span className=\"min-w-0 flex-1 truncate text-sm font-bold\">\n {renderAddress ? renderAddress(e.address) : shortenAddress(e.address)}\n </span>\n <LevelBadge level={e.currentLevel} name={e.currentLevelName} badgeColor={e.badgeColor} size=\"sm\" />\n </li>\n ))}\n </ol>\n </section>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAkCc;AAjCd,gBAAmB;AACnB,qBAA+B;AAC/B,yBAA2B;AAuBpB,SAAS,iBAAiB,EAAE,SAAS,kBAAkB,eAAe,SAAS,UAAU,GAA0B;AACxH,MAAI,SAAS;AACX,WACE,4CAAC,SAAI,eAAW,cAAG,6BAA6B,SAAS,GACtD,kBAAQ,IAAI,CAAC,MAAM;AAClB,YAAM,WAAW,oBAAoB,QAAQ,EAAE,YAAY;AAC3D,aACE,6CAAC,SAAoB,eAAW,cAAG,qCAAqC,YAAY,kBAAkB,GACpG;AAAA,oDAAC,UAAK,WAAU,uEAAuE,YAAE,MAAK;AAAA,QAC9F,6CAAC,UAAK,WAAU,iDACb;AAAA,0BAAgB,cAAc,EAAE,OAAO,QAAI,+BAAe,EAAE,OAAO;AAAA,UACnE,YAAY,4CAAC,UAAK,WAAU,iDAAgD,mBAAK;AAAA,WACpF;AAAA,QACA,4CAAC,iCAAW,OAAO,EAAE,cAAc,MAAM,EAAE,kBAAkB,YAAY,EAAE,YAAY,MAAK,MAAK,WAAU,yBAAwB;AAAA,QACnI,6CAAC,UAAK,WAAU,2CACb;AAAA,YAAE,QAAQ,eAAe;AAAA,UAC1B,4CAAC,UAAK,WAAU,+CAA8C,gBAAE;AAAA,WAClE;AAAA,WAVQ,EAAE,OAWZ;AAAA,IAEJ,CAAC,GACH;AAAA,EAEJ;AACA,SACE,4CAAC,SAAI,eAAW,cAAG,eAAe,SAAS,GACxC,kBAAQ,IAAI,CAAC,MAAM;AAClB,UAAM,WAAW,oBAAoB,QAAQ,EAAE,YAAY;AAC3D,WACE;AAAA,MAAC;AAAA;AAAA,QAEC,eAAW;AAAA,UACT;AAAA,UACA,WAAW,qBAAqB;AAAA,QAClC;AAAA,QAEA;AAAA,uDAAC,UAAK,WAAU,+CACb;AAAA,4BAAgB,cAAc,EAAE,OAAO,QAAI,+BAAe,EAAE,OAAO;AAAA,YACnE,YAAY,4CAAC,UAAK,WAAU,iDAAgD,mBAAK;AAAA,aACpF;AAAA,UACA,4CAAC,iCAAW,OAAO,EAAE,cAAc,MAAM,EAAE,kBAAkB,YAAY,EAAE,YAAY,MAAK,MAAK,WAAU,yBAAwB;AAAA,UACnI,6CAAC,UAAK,WAAU,4CACb;AAAA,cAAE,QAAQ,eAAe;AAAA,YAC1B,4CAAC,UAAK,WAAU,6CAA4C,gBAAE;AAAA,aAChE;AAAA;AAAA;AAAA,MAdK,EAAE;AAAA,IAeT;AAAA,EAEJ,CAAC,GACH;AAEJ;AAWO,SAAS,kBAAkB,EAAE,SAAS,QAAQ,qBAAqB,MAAM,eAAe,UAAU,GAA2B;AAClI,MAAI,QAAQ,WAAW,EAAG,QAAO;AACjC,SACE,6CAAC,aAAQ,eAAW,cAAG,wCAAwC,SAAS,GACtE;AAAA,iDAAC,SAAI,WAAU,0CACb;AAAA,kDAAC,QAAG,WAAU,sBAAsB,iBAAM;AAAA,MACzC,QACC,4CAAC,OAAE,MAAY,WAAU,gFAA+E,oCAExG;AAAA,OAEJ;AAAA,IACA,4CAAC,QAAG,WAAU,eACX,kBAAQ,IAAI,CAAC,MACZ,6CAAC,QAAmB,WAAU,6BAC5B;AAAA,kDAAC,UAAK,WAAU,6CACb,0BAAgB,cAAc,EAAE,OAAO,QAAI,+BAAe,EAAE,OAAO,GACtE;AAAA,MACA,4CAAC,iCAAW,OAAO,EAAE,cAAc,MAAM,EAAE,kBAAkB,YAAY,EAAE,YAAY,MAAK,MAAK;AAAA,SAJ1F,EAAE,OAKX,CACD,GACH;AAAA,KACF;AAEJ;","names":[]}
|
|
@@ -6,7 +6,7 @@ function LeaderboardTable({ entries, highlightAddress, renderAddress, compact, c
|
|
|
6
6
|
if (compact) {
|
|
7
7
|
return /* @__PURE__ */ jsx("div", { className: cn("divide-y divide-border/40", className), children: entries.map((e) => {
|
|
8
8
|
const isViewer = highlightAddress != null && e.address === highlightAddress;
|
|
9
|
-
return /* @__PURE__ */ jsxs("div", { className: cn("flex items-center gap-3 px-4
|
|
9
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("flex h-16 items-center gap-3 px-4", isViewer && "bg-brand-rose/10"), children: [
|
|
10
10
|
/* @__PURE__ */ jsx("span", { className: "w-4 shrink-0 text-xs font-medium tabular-nums text-muted-foreground", children: e.rank }),
|
|
11
11
|
/* @__PURE__ */ jsxs("span", { className: "min-w-0 flex-1 truncate text-sm font-semibold", children: [
|
|
12
12
|
renderAddress ? renderAddress(e.address) : shortenAddress(e.address),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/rewards/leaderboard-table.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport { cn } from \"../../utils/cn.js\";\nimport { shortenAddress } from \"../../utils/address.js\";\nimport { LevelBadge } from \"./level-badge.js\";\n\nexport interface LeaderboardEntryLike {\n\n rank: number;\n address: string;\n publicId?: string | null;\n totalXp: number;\n currentLevel: number;\n currentLevelName: string;\n badgeColor: string;\n}\n\nexport interface LeaderboardTableProps {\n entries: LeaderboardEntryLike[];\n\n highlightAddress?: string | null;\n\n renderAddress?: (address: string) => ReactNode;\n compact?: boolean;\n className?: string;\n}\n\nexport function LeaderboardTable({ entries, highlightAddress, renderAddress, compact, className }: LeaderboardTableProps) {\n if (compact) {\n return (\n <div className={cn(\"divide-y divide-border/40\", className)}>\n {entries.map((e) => {\n const isViewer = highlightAddress != null && e.address === highlightAddress;\n return (\n <div key={e.address} className={cn(\"flex items-center gap-3 px-4
|
|
1
|
+
{"version":3,"sources":["../../../src/components/rewards/leaderboard-table.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport { cn } from \"../../utils/cn.js\";\nimport { shortenAddress } from \"../../utils/address.js\";\nimport { LevelBadge } from \"./level-badge.js\";\n\nexport interface LeaderboardEntryLike {\n\n rank: number;\n address: string;\n publicId?: string | null;\n totalXp: number;\n currentLevel: number;\n currentLevelName: string;\n badgeColor: string;\n}\n\nexport interface LeaderboardTableProps {\n entries: LeaderboardEntryLike[];\n\n highlightAddress?: string | null;\n\n renderAddress?: (address: string) => ReactNode;\n compact?: boolean;\n className?: string;\n}\n\nexport function LeaderboardTable({ entries, highlightAddress, renderAddress, compact, className }: LeaderboardTableProps) {\n if (compact) {\n return (\n <div className={cn(\"divide-y divide-border/40\", className)}>\n {entries.map((e) => {\n const isViewer = highlightAddress != null && e.address === highlightAddress;\n return (\n <div key={e.address} className={cn(\"flex h-16 items-center gap-3 px-4\", isViewer && \"bg-brand-rose/10\")}>\n <span className=\"w-4 shrink-0 text-xs font-medium tabular-nums text-muted-foreground\">{e.rank}</span>\n <span className=\"min-w-0 flex-1 truncate text-sm font-semibold\">\n {renderAddress ? renderAddress(e.address) : shortenAddress(e.address)}\n {isViewer && <span className=\"ml-1.5 text-xs font-medium text-foreground/50\">(you)</span>}\n </span>\n <LevelBadge level={e.currentLevel} name={e.currentLevelName} badgeColor={e.badgeColor} size=\"sm\" className=\"hidden sm:inline-flex\" />\n <span className=\"shrink-0 text-sm font-bold tabular-nums\">\n {e.totalXp.toLocaleString()}\n <span className=\"ml-1 text-xs font-medium text-foreground/40\">XP</span>\n </span>\n </div>\n );\n })}\n </div>\n );\n }\n return (\n <div className={cn(\"space-y-1.5\", className)}>\n {entries.map((e) => {\n const isViewer = highlightAddress != null && e.address === highlightAddress;\n return (\n <div\n key={e.address}\n className={cn(\n \"flex items-center gap-4 rounded-2xl px-4 py-3.5 transition-colors\",\n isViewer ? \"bg-brand-rose/10\" : \"bg-foreground/[0.04] hover:bg-foreground/[0.07]\"\n )}\n >\n <span className=\"min-w-0 flex-1 truncate text-base font-bold\">\n {renderAddress ? renderAddress(e.address) : shortenAddress(e.address)}\n {isViewer && <span className=\"ml-1.5 text-xs font-medium text-foreground/50\">(you)</span>}\n </span>\n <LevelBadge level={e.currentLevel} name={e.currentLevelName} badgeColor={e.badgeColor} size=\"sm\" className=\"hidden sm:inline-flex\" />\n <span className=\"shrink-0 text-lg font-black tabular-nums\">\n {e.totalXp.toLocaleString()}\n <span className=\"ml-1 text-xs font-bold text-foreground/40\">XP</span>\n </span>\n </div>\n );\n })}\n </div>\n );\n}\n\nexport interface LeaderboardWidgetProps {\n entries: LeaderboardEntryLike[];\n title?: string;\n\n href?: string;\n renderAddress?: (address: string) => ReactNode;\n className?: string;\n}\n\nexport function LeaderboardWidget({ entries, title = \"Community Rewards\", href, renderAddress, className }: LeaderboardWidgetProps) {\n if (entries.length === 0) return null;\n return (\n <section className={cn(\"rounded-2xl bg-foreground/[0.04] p-5\", className)}>\n <div className=\"mb-3 flex items-center justify-between\">\n <h2 className=\"text-lg font-black\">{title}</h2>\n {href && (\n <a href={href} className=\"text-xs font-bold text-foreground/50 hover:text-foreground active:opacity-70\">\n View scoreboard →\n </a>\n )}\n </div>\n <ol className=\"space-y-2.5\">\n {entries.map((e) => (\n <li key={e.address} className=\"flex items-center gap-2.5\">\n <span className=\"min-w-0 flex-1 truncate text-sm font-bold\">\n {renderAddress ? renderAddress(e.address) : shortenAddress(e.address)}\n </span>\n <LevelBadge level={e.currentLevel} name={e.currentLevelName} badgeColor={e.badgeColor} size=\"sm\" />\n </li>\n ))}\n </ol>\n </section>\n );\n}\n"],"mappings":"AAkCc,cACA,YADA;AAjCd,SAAS,UAAU;AACnB,SAAS,sBAAsB;AAC/B,SAAS,kBAAkB;AAuBpB,SAAS,iBAAiB,EAAE,SAAS,kBAAkB,eAAe,SAAS,UAAU,GAA0B;AACxH,MAAI,SAAS;AACX,WACE,oBAAC,SAAI,WAAW,GAAG,6BAA6B,SAAS,GACtD,kBAAQ,IAAI,CAAC,MAAM;AAClB,YAAM,WAAW,oBAAoB,QAAQ,EAAE,YAAY;AAC3D,aACE,qBAAC,SAAoB,WAAW,GAAG,qCAAqC,YAAY,kBAAkB,GACpG;AAAA,4BAAC,UAAK,WAAU,uEAAuE,YAAE,MAAK;AAAA,QAC9F,qBAAC,UAAK,WAAU,iDACb;AAAA,0BAAgB,cAAc,EAAE,OAAO,IAAI,eAAe,EAAE,OAAO;AAAA,UACnE,YAAY,oBAAC,UAAK,WAAU,iDAAgD,mBAAK;AAAA,WACpF;AAAA,QACA,oBAAC,cAAW,OAAO,EAAE,cAAc,MAAM,EAAE,kBAAkB,YAAY,EAAE,YAAY,MAAK,MAAK,WAAU,yBAAwB;AAAA,QACnI,qBAAC,UAAK,WAAU,2CACb;AAAA,YAAE,QAAQ,eAAe;AAAA,UAC1B,oBAAC,UAAK,WAAU,+CAA8C,gBAAE;AAAA,WAClE;AAAA,WAVQ,EAAE,OAWZ;AAAA,IAEJ,CAAC,GACH;AAAA,EAEJ;AACA,SACE,oBAAC,SAAI,WAAW,GAAG,eAAe,SAAS,GACxC,kBAAQ,IAAI,CAAC,MAAM;AAClB,UAAM,WAAW,oBAAoB,QAAQ,EAAE,YAAY;AAC3D,WACE;AAAA,MAAC;AAAA;AAAA,QAEC,WAAW;AAAA,UACT;AAAA,UACA,WAAW,qBAAqB;AAAA,QAClC;AAAA,QAEA;AAAA,+BAAC,UAAK,WAAU,+CACb;AAAA,4BAAgB,cAAc,EAAE,OAAO,IAAI,eAAe,EAAE,OAAO;AAAA,YACnE,YAAY,oBAAC,UAAK,WAAU,iDAAgD,mBAAK;AAAA,aACpF;AAAA,UACA,oBAAC,cAAW,OAAO,EAAE,cAAc,MAAM,EAAE,kBAAkB,YAAY,EAAE,YAAY,MAAK,MAAK,WAAU,yBAAwB;AAAA,UACnI,qBAAC,UAAK,WAAU,4CACb;AAAA,cAAE,QAAQ,eAAe;AAAA,YAC1B,oBAAC,UAAK,WAAU,6CAA4C,gBAAE;AAAA,aAChE;AAAA;AAAA;AAAA,MAdK,EAAE;AAAA,IAeT;AAAA,EAEJ,CAAC,GACH;AAEJ;AAWO,SAAS,kBAAkB,EAAE,SAAS,QAAQ,qBAAqB,MAAM,eAAe,UAAU,GAA2B;AAClI,MAAI,QAAQ,WAAW,EAAG,QAAO;AACjC,SACE,qBAAC,aAAQ,WAAW,GAAG,wCAAwC,SAAS,GACtE;AAAA,yBAAC,SAAI,WAAU,0CACb;AAAA,0BAAC,QAAG,WAAU,sBAAsB,iBAAM;AAAA,MACzC,QACC,oBAAC,OAAE,MAAY,WAAU,gFAA+E,oCAExG;AAAA,OAEJ;AAAA,IACA,oBAAC,QAAG,WAAU,eACX,kBAAQ,IAAI,CAAC,MACZ,qBAAC,QAAmB,WAAU,6BAC5B;AAAA,0BAAC,UAAK,WAAU,6CACb,0BAAgB,cAAc,EAAE,OAAO,IAAI,eAAe,EAAE,OAAO,GACtE;AAAA,MACA,oBAAC,cAAW,OAAO,EAAE,cAAc,MAAM,EAAE,kBAAkB,YAAY,EAAE,YAAY,MAAK,MAAK;AAAA,SAJ1F,EAAE,OAKX,CACD,GACH;AAAA,KACF;AAEJ;","names":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/scroll-section.tsx"],"sourcesContent":["\"use client\";\n\nimport { SectionHeading } from \"./section-heading.js\";\n\nexport interface ScrollSectionProps {\n icon: React.ReactNode;\n title: string;\n subtitle?: React.ReactNode;\n href
|
|
1
|
+
{"version":3,"sources":["../../src/components/scroll-section.tsx"],"sourcesContent":["\"use client\";\n\nimport { SectionHeading } from \"./section-heading.js\";\n\nexport interface ScrollSectionProps {\n icon: React.ReactNode;\n title: string;\n subtitle?: React.ReactNode;\n href?: string;\n linkLabel?: string;\n children: React.ReactNode;\n}\n\nexport function ScrollSection({ icon, title, subtitle, href, linkLabel, children }: ScrollSectionProps) {\n return (\n <section className=\"space-y-4\">\n <SectionHeading icon={icon} title={title} subtitle={subtitle} href={href} linkLabel={linkLabel} />\n\n <div className=\"w-full overflow-x-auto scrollbar-hide\">\n <div className=\"flex gap-5 sm:gap-6 snap-x snap-mandatory pb-2\" style={{ width: \"max-content\" }}>\n {children}\n </div>\n </div>\n </section>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAeI;AAbJ,6BAA+B;AAWxB,SAAS,cAAc,EAAE,MAAM,OAAO,UAAU,MAAM,WAAW,SAAS,GAAuB;AACtG,SACE,6CAAC,aAAQ,WAAU,aACjB;AAAA,gDAAC,yCAAe,MAAY,OAAc,UAAoB,MAAY,WAAsB;AAAA,IAEhG,4CAAC,SAAI,WAAU,yCACb,sDAAC,SAAI,WAAU,kDAAiD,OAAO,EAAE,OAAO,cAAc,GAC3F,UACH,GACF;AAAA,KACF;AAEJ;","names":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/scroll-section.tsx"],"sourcesContent":["\"use client\";\n\nimport { SectionHeading } from \"./section-heading.js\";\n\nexport interface ScrollSectionProps {\n icon: React.ReactNode;\n title: string;\n subtitle?: React.ReactNode;\n href
|
|
1
|
+
{"version":3,"sources":["../../src/components/scroll-section.tsx"],"sourcesContent":["\"use client\";\n\nimport { SectionHeading } from \"./section-heading.js\";\n\nexport interface ScrollSectionProps {\n icon: React.ReactNode;\n title: string;\n subtitle?: React.ReactNode;\n href?: string;\n linkLabel?: string;\n children: React.ReactNode;\n}\n\nexport function ScrollSection({ icon, title, subtitle, href, linkLabel, children }: ScrollSectionProps) {\n return (\n <section className=\"space-y-4\">\n <SectionHeading icon={icon} title={title} subtitle={subtitle} href={href} linkLabel={linkLabel} />\n\n <div className=\"w-full overflow-x-auto scrollbar-hide\">\n <div className=\"flex gap-5 sm:gap-6 snap-x snap-mandatory pb-2\" style={{ width: \"max-content\" }}>\n {children}\n </div>\n </div>\n </section>\n );\n}\n"],"mappings":";AAeI,SACE,KADF;AAbJ,SAAS,sBAAsB;AAWxB,SAAS,cAAc,EAAE,MAAM,OAAO,UAAU,MAAM,WAAW,SAAS,GAAuB;AACtG,SACE,qBAAC,aAAQ,WAAU,aACjB;AAAA,wBAAC,kBAAe,MAAY,OAAc,UAAoB,MAAY,WAAsB;AAAA,IAEhG,oBAAC,SAAI,WAAU,yCACb,8BAAC,SAAI,WAAU,kDAAiD,OAAO,EAAE,OAAO,cAAc,GAC3F,UACH,GACF;AAAA,KACF;AAEJ;","names":[]}
|
|
@@ -44,7 +44,7 @@ function SectionHeading({ icon, title, subtitle, href, linkLabel = "View all" })
|
|
|
44
44
|
subtitle && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "mt-1 flex items-center gap-1 text-2xs text-muted-foreground", children: subtitle })
|
|
45
45
|
] })
|
|
46
46
|
] }),
|
|
47
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
47
|
+
href && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
48
48
|
import_link.default,
|
|
49
49
|
{
|
|
50
50
|
href,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/section-heading.tsx"],"sourcesContent":["\"use client\";\n\nimport Link from \"./link.js\";\nimport { ArrowRight } from \"lucide-react\";\n\nexport interface SectionHeadingProps {\n icon: React.ReactNode;\n title: string;\n subtitle?: React.ReactNode;\n href
|
|
1
|
+
{"version":3,"sources":["../../src/components/section-heading.tsx"],"sourcesContent":["\"use client\";\n\nimport Link from \"./link.js\";\nimport { ArrowRight } from \"lucide-react\";\n\nexport interface SectionHeadingProps {\n icon: React.ReactNode;\n title: string;\n subtitle?: React.ReactNode;\n href?: string;\n linkLabel?: string;\n}\n\nexport function SectionHeading({ icon, title, subtitle, href, linkLabel = \"View all\" }: SectionHeadingProps) {\n return (\n <div className=\"flex items-center justify-between gap-3\">\n <div className=\"flex min-w-0 items-center gap-2\">\n <span className=\"shrink-0 text-muted-foreground [&>svg]:h-4 [&>svg]:w-4\">{icon}</span>\n <div className=\"min-w-0\">\n <h2 className=\"text-sm font-semibold leading-none tracking-tight text-foreground\">{title}</h2>\n {subtitle && <p className=\"mt-1 flex items-center gap-1 text-2xs text-muted-foreground\">{subtitle}</p>}\n </div>\n </div>\n {href && (\n <Link\n href={href}\n className=\"inline-flex shrink-0 items-center gap-1 text-xs text-muted-foreground transition-colors hover:text-foreground\"\n >\n {linkLabel} <ArrowRight className=\"h-3 w-3\" />\n </Link>\n )}\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAiBQ;AAfR,kBAAiB;AACjB,0BAA2B;AAUpB,SAAS,eAAe,EAAE,MAAM,OAAO,UAAU,MAAM,YAAY,WAAW,GAAwB;AAC3G,SACE,6CAAC,SAAI,WAAU,2CACb;AAAA,iDAAC,SAAI,WAAU,mCACb;AAAA,kDAAC,UAAK,WAAU,0DAA0D,gBAAK;AAAA,MAC/E,6CAAC,SAAI,WAAU,WACb;AAAA,oDAAC,QAAG,WAAU,qEAAqE,iBAAM;AAAA,QACxF,YAAY,4CAAC,OAAE,WAAU,+DAA+D,oBAAS;AAAA,SACpG;AAAA,OACF;AAAA,IACC,QACC;AAAA,MAAC,YAAAA;AAAA,MAAA;AAAA,QACC;AAAA,QACA,WAAU;AAAA,QAET;AAAA;AAAA,UAAU;AAAA,UAAC,4CAAC,kCAAW,WAAU,WAAU;AAAA;AAAA;AAAA,IAC9C;AAAA,KAEJ;AAEJ;","names":["Link"]}
|
|
@@ -4,7 +4,7 @@ interface SectionHeadingProps {
|
|
|
4
4
|
icon: React.ReactNode;
|
|
5
5
|
title: string;
|
|
6
6
|
subtitle?: React.ReactNode;
|
|
7
|
-
href
|
|
7
|
+
href?: string;
|
|
8
8
|
linkLabel?: string;
|
|
9
9
|
}
|
|
10
10
|
declare function SectionHeading({ icon, title, subtitle, href, linkLabel }: SectionHeadingProps): react_jsx_runtime.JSX.Element;
|
|
@@ -4,7 +4,7 @@ interface SectionHeadingProps {
|
|
|
4
4
|
icon: React.ReactNode;
|
|
5
5
|
title: string;
|
|
6
6
|
subtitle?: React.ReactNode;
|
|
7
|
-
href
|
|
7
|
+
href?: string;
|
|
8
8
|
linkLabel?: string;
|
|
9
9
|
}
|
|
10
10
|
declare function SectionHeading({ icon, title, subtitle, href, linkLabel }: SectionHeadingProps): react_jsx_runtime.JSX.Element;
|
|
@@ -11,7 +11,7 @@ function SectionHeading({ icon, title, subtitle, href, linkLabel = "View all" })
|
|
|
11
11
|
subtitle && /* @__PURE__ */ jsx("p", { className: "mt-1 flex items-center gap-1 text-2xs text-muted-foreground", children: subtitle })
|
|
12
12
|
] })
|
|
13
13
|
] }),
|
|
14
|
-
/* @__PURE__ */ jsxs(
|
|
14
|
+
href && /* @__PURE__ */ jsxs(
|
|
15
15
|
Link,
|
|
16
16
|
{
|
|
17
17
|
href,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/section-heading.tsx"],"sourcesContent":["\"use client\";\n\nimport Link from \"./link.js\";\nimport { ArrowRight } from \"lucide-react\";\n\nexport interface SectionHeadingProps {\n icon: React.ReactNode;\n title: string;\n subtitle?: React.ReactNode;\n href
|
|
1
|
+
{"version":3,"sources":["../../src/components/section-heading.tsx"],"sourcesContent":["\"use client\";\n\nimport Link from \"./link.js\";\nimport { ArrowRight } from \"lucide-react\";\n\nexport interface SectionHeadingProps {\n icon: React.ReactNode;\n title: string;\n subtitle?: React.ReactNode;\n href?: string;\n linkLabel?: string;\n}\n\nexport function SectionHeading({ icon, title, subtitle, href, linkLabel = \"View all\" }: SectionHeadingProps) {\n return (\n <div className=\"flex items-center justify-between gap-3\">\n <div className=\"flex min-w-0 items-center gap-2\">\n <span className=\"shrink-0 text-muted-foreground [&>svg]:h-4 [&>svg]:w-4\">{icon}</span>\n <div className=\"min-w-0\">\n <h2 className=\"text-sm font-semibold leading-none tracking-tight text-foreground\">{title}</h2>\n {subtitle && <p className=\"mt-1 flex items-center gap-1 text-2xs text-muted-foreground\">{subtitle}</p>}\n </div>\n </div>\n {href && (\n <Link\n href={href}\n className=\"inline-flex shrink-0 items-center gap-1 text-xs text-muted-foreground transition-colors hover:text-foreground\"\n >\n {linkLabel} <ArrowRight className=\"h-3 w-3\" />\n </Link>\n )}\n </div>\n );\n}\n"],"mappings":";AAiBQ,cACA,YADA;AAfR,OAAO,UAAU;AACjB,SAAS,kBAAkB;AAUpB,SAAS,eAAe,EAAE,MAAM,OAAO,UAAU,MAAM,YAAY,WAAW,GAAwB;AAC3G,SACE,qBAAC,SAAI,WAAU,2CACb;AAAA,yBAAC,SAAI,WAAU,mCACb;AAAA,0BAAC,UAAK,WAAU,0DAA0D,gBAAK;AAAA,MAC/E,qBAAC,SAAI,WAAU,WACb;AAAA,4BAAC,QAAG,WAAU,qEAAqE,iBAAM;AAAA,QACxF,YAAY,oBAAC,OAAE,WAAU,+DAA+D,oBAAS;AAAA,SACpG;AAAA,OACF;AAAA,IACC,QACC;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,WAAU;AAAA,QAET;AAAA;AAAA,UAAU;AAAA,UAAC,oBAAC,cAAW,WAAU,WAAU;AAAA;AAAA;AAAA,IAC9C;AAAA,KAEJ;AAEJ;","names":[]}
|
|
@@ -10,7 +10,7 @@ declare const SheetClose: React.ForwardRefExoticComponent<SheetPrimitive.DialogC
|
|
|
10
10
|
declare const SheetPortal: React.FC<SheetPrimitive.DialogPortalProps>;
|
|
11
11
|
declare const SheetOverlay: React.ForwardRefExoticComponent<Omit<SheetPrimitive.DialogOverlayProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
12
12
|
declare const sheetVariants: (props?: ({
|
|
13
|
-
side?: "
|
|
13
|
+
side?: "left" | "right" | "bottom" | "top" | null | undefined;
|
|
14
14
|
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
15
15
|
interface SheetContentProps extends React.ComponentPropsWithoutRef<typeof SheetPrimitive.Content>, VariantProps<typeof sheetVariants> {
|
|
16
16
|
overlayClassName?: string;
|
|
@@ -10,7 +10,7 @@ declare const SheetClose: React.ForwardRefExoticComponent<SheetPrimitive.DialogC
|
|
|
10
10
|
declare const SheetPortal: React.FC<SheetPrimitive.DialogPortalProps>;
|
|
11
11
|
declare const SheetOverlay: React.ForwardRefExoticComponent<Omit<SheetPrimitive.DialogOverlayProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
12
12
|
declare const sheetVariants: (props?: ({
|
|
13
|
-
side?: "
|
|
13
|
+
side?: "left" | "right" | "bottom" | "top" | null | undefined;
|
|
14
14
|
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
15
15
|
interface SheetContentProps extends React.ComponentPropsWithoutRef<typeof SheetPrimitive.Content>, VariantProps<typeof sheetVariants> {
|
|
16
16
|
overlayClassName?: string;
|
|
@@ -60,14 +60,14 @@ function useCollections(page = 1, limit = 20, isFeatured, sort = "recent", hideE
|
|
|
60
60
|
mutate
|
|
61
61
|
};
|
|
62
62
|
}
|
|
63
|
-
function useCollection(contract) {
|
|
63
|
+
function useCollection(contract, initial) {
|
|
64
64
|
const client = (0, import_use_medialane_client.useMedialaneClient)();
|
|
65
65
|
const { data, error, isLoading } = (0, import_swr.default)(
|
|
66
66
|
contract ? import_query_keys.queryKeys.collection(contract) : null,
|
|
67
67
|
() => client.api.collections.get(contract),
|
|
68
|
-
{ revalidateOnFocus: false }
|
|
68
|
+
{ revalidateOnFocus: false, fallbackData: initial ?? void 0 }
|
|
69
69
|
);
|
|
70
|
-
return { collection: data ?? null, isLoading, error };
|
|
70
|
+
return { collection: data ?? null, isLoading: isLoading && !data, error };
|
|
71
71
|
}
|
|
72
72
|
function useCollectionsByOwner(owner) {
|
|
73
73
|
const client = (0, import_use_medialane_client.useMedialaneClient)();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utils/use-collections.ts"],"sourcesContent":["\"use client\";\n\nimport useSWR from \"swr\";\nimport { useMedialaneClient } from \"./use-medialane-client.js\";\nimport type { ApiCollection, ApiResponse, CollectionTokensSort } from \"@medialane/sdk\";\nimport { queryKeys } from \"./query-keys.js\";\n\nexport type CollectionSort = \"recent\" | \"supply\" | \"floor\" | \"volume\" | \"name\";\n\nexport function useCollections(\n page = 1,\n limit = 20,\n isFeatured?: boolean,\n sort: CollectionSort = \"recent\",\n hideEmpty = true,\n service?: string,\n\n standard?: string,\n\n fallback?: ApiCollection[]\n) {\n const client = useMedialaneClient();\n const key = `${queryKeys.collections(page, limit, isFeatured, sort, hideEmpty, service)}-${standard ?? \"\"}`;\n\n const { data, error, isLoading, mutate } = useSWR<ApiResponse<ApiCollection[]>>(\n key,\n async () => {\n return client.api.collections.list({ page, limit, isFeatured, sort, service, standard, hideEmpty });\n },\n {\n revalidateOnFocus: false,\n ...(fallback ? { fallbackData: { data: fallback } as ApiResponse<ApiCollection[]> } : {}),\n }\n );\n\n return {\n collections: data?.data ?? [],\n meta: data?.meta,\n isLoading,\n error,\n mutate,\n };\n}\n\nexport function useCollection( contract: string | null) {\n const client = useMedialaneClient();\n\n const { data, error, isLoading } = useSWR(\n contract ? queryKeys.collection(contract) : null,\n () => client.api.collections.get(contract!),\n { revalidateOnFocus: false }\n );\n\n return { collection: data ?? null, isLoading, error };\n}\n\nexport function useCollectionsByOwner( owner: string | null) {\n const client = useMedialaneClient();\n\n const { data, error, isLoading, mutate } = useSWR(\n owner ? queryKeys.collectionsOwner(owner) : null,\n () => client.api.collections.list({ owner: owner!, limit: 50 }),\n { revalidateOnFocus: false, refreshInterval: 60_000 }\n );\n\n return { collections: data?.data ?? [], isLoading, error, mutate };\n}\n\nexport function useCollectionTokens(\n contract: string | null,\n page = 1,\n limit = 24,\n sort: CollectionTokensSort = \"recent\"\n) {\n const client = useMedialaneClient();\n\n const { data, error, isLoading, mutate } = useSWR(\n contract ? queryKeys.collectionTokens(contract, page, limit, sort) : null,\n () => client.api.collections.tokens(contract!, { page: page, limit: limit, sort: sort }),\n { revalidateOnFocus: false }\n );\n\n return { tokens: data?.data ?? [], meta: data?.meta, isLoading, error, mutate };\n}\n\nfunction pickNearbyTokens<T extends { tokenId: string }>(\n tokens: T[],\n currentTokenId: string | null,\n count: number\n): T[] {\n if (!currentTokenId) return tokens.slice(0, count);\n const idx = tokens.findIndex((t) => String(t.tokenId) === String(currentTokenId));\n if (idx === -1) return tokens.slice(0, count);\n\n const picked: T[] = [];\n let after = idx + 1;\n let before = idx - 1;\n while (picked.length < count && (after < tokens.length || before >= 0)) {\n if (after < tokens.length) picked.push(tokens[after++]);\n if (picked.length < count && before >= 0) picked.push(tokens[before--]);\n }\n return picked.sort((a, b) => Number(a.tokenId) - Number(b.tokenId));\n}\n\nexport function useNearbyCollectionTokens(\n contract: string | null,\n currentTokenId: string | null,\n count = 4,\n poolSize = 60\n) {\n const { tokens, isLoading, error } = useCollectionTokens(contract, 1, poolSize, \"oldest\");\n return { tokens: pickNearbyTokens(tokens, currentTokenId, count), isLoading, error };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,iBAAmB;AACnB,kCAAmC;AAEnC,wBAA0B;AAInB,SAAS,eACd,OAAO,GACP,QAAQ,IACR,YACA,OAAuB,UACvB,YAAY,MACZ,SAEA,UAEA,UACA;AACA,QAAM,aAAS,gDAAmB;AAClC,QAAM,MAAM,GAAG,4BAAU,YAAY,MAAM,OAAO,YAAY,MAAM,WAAW,OAAO,CAAC,IAAI,YAAY,EAAE;AAEzG,QAAM,EAAE,MAAM,OAAO,WAAW,OAAO,QAAI,WAAAA;AAAA,IACzC;AAAA,IACA,YAAY;AACV,aAAO,OAAO,IAAI,YAAY,KAAK,EAAE,MAAM,OAAO,YAAY,MAAM,SAAS,UAAU,UAAU,CAAC;AAAA,IACpG;AAAA,IACA;AAAA,MACE,mBAAmB;AAAA,MACnB,GAAI,WAAW,EAAE,cAAc,EAAE,MAAM,SAAS,EAAkC,IAAI,CAAC;AAAA,IACzF;AAAA,EACF;AAEA,SAAO;AAAA,IACL,aAAa,MAAM,QAAQ,CAAC;AAAA,IAC5B,MAAM,MAAM;AAAA,IACZ;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEO,SAAS,cAAe,UAAyB;
|
|
1
|
+
{"version":3,"sources":["../../src/utils/use-collections.ts"],"sourcesContent":["\"use client\";\n\nimport useSWR from \"swr\";\nimport { useMedialaneClient } from \"./use-medialane-client.js\";\nimport type { ApiCollection, ApiResponse, CollectionTokensSort } from \"@medialane/sdk\";\nimport { queryKeys } from \"./query-keys.js\";\n\nexport type CollectionSort = \"recent\" | \"supply\" | \"floor\" | \"volume\" | \"name\";\n\nexport function useCollections(\n page = 1,\n limit = 20,\n isFeatured?: boolean,\n sort: CollectionSort = \"recent\",\n hideEmpty = true,\n service?: string,\n\n standard?: string,\n\n fallback?: ApiCollection[]\n) {\n const client = useMedialaneClient();\n const key = `${queryKeys.collections(page, limit, isFeatured, sort, hideEmpty, service)}-${standard ?? \"\"}`;\n\n const { data, error, isLoading, mutate } = useSWR<ApiResponse<ApiCollection[]>>(\n key,\n async () => {\n return client.api.collections.list({ page, limit, isFeatured, sort, service, standard, hideEmpty });\n },\n {\n revalidateOnFocus: false,\n ...(fallback ? { fallbackData: { data: fallback } as ApiResponse<ApiCollection[]> } : {}),\n }\n );\n\n return {\n collections: data?.data ?? [],\n meta: data?.meta,\n isLoading,\n error,\n mutate,\n };\n}\n\nexport function useCollection( contract: string | null, initial?: ApiCollection | null) {\n const client = useMedialaneClient();\n\n const { data, error, isLoading } = useSWR(\n contract ? queryKeys.collection(contract) : null,\n () => client.api.collections.get(contract!),\n { revalidateOnFocus: false, fallbackData: initial ?? undefined }\n );\n\n return { collection: data ?? null, isLoading: isLoading && !data, error };\n}\n\nexport function useCollectionsByOwner( owner: string | null) {\n const client = useMedialaneClient();\n\n const { data, error, isLoading, mutate } = useSWR(\n owner ? queryKeys.collectionsOwner(owner) : null,\n () => client.api.collections.list({ owner: owner!, limit: 50 }),\n { revalidateOnFocus: false, refreshInterval: 60_000 }\n );\n\n return { collections: data?.data ?? [], isLoading, error, mutate };\n}\n\nexport function useCollectionTokens(\n contract: string | null,\n page = 1,\n limit = 24,\n sort: CollectionTokensSort = \"recent\"\n) {\n const client = useMedialaneClient();\n\n const { data, error, isLoading, mutate } = useSWR(\n contract ? queryKeys.collectionTokens(contract, page, limit, sort) : null,\n () => client.api.collections.tokens(contract!, { page: page, limit: limit, sort: sort }),\n { revalidateOnFocus: false }\n );\n\n return { tokens: data?.data ?? [], meta: data?.meta, isLoading, error, mutate };\n}\n\nfunction pickNearbyTokens<T extends { tokenId: string }>(\n tokens: T[],\n currentTokenId: string | null,\n count: number\n): T[] {\n if (!currentTokenId) return tokens.slice(0, count);\n const idx = tokens.findIndex((t) => String(t.tokenId) === String(currentTokenId));\n if (idx === -1) return tokens.slice(0, count);\n\n const picked: T[] = [];\n let after = idx + 1;\n let before = idx - 1;\n while (picked.length < count && (after < tokens.length || before >= 0)) {\n if (after < tokens.length) picked.push(tokens[after++]);\n if (picked.length < count && before >= 0) picked.push(tokens[before--]);\n }\n return picked.sort((a, b) => Number(a.tokenId) - Number(b.tokenId));\n}\n\nexport function useNearbyCollectionTokens(\n contract: string | null,\n currentTokenId: string | null,\n count = 4,\n poolSize = 60\n) {\n const { tokens, isLoading, error } = useCollectionTokens(contract, 1, poolSize, \"oldest\");\n return { tokens: pickNearbyTokens(tokens, currentTokenId, count), isLoading, error };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,iBAAmB;AACnB,kCAAmC;AAEnC,wBAA0B;AAInB,SAAS,eACd,OAAO,GACP,QAAQ,IACR,YACA,OAAuB,UACvB,YAAY,MACZ,SAEA,UAEA,UACA;AACA,QAAM,aAAS,gDAAmB;AAClC,QAAM,MAAM,GAAG,4BAAU,YAAY,MAAM,OAAO,YAAY,MAAM,WAAW,OAAO,CAAC,IAAI,YAAY,EAAE;AAEzG,QAAM,EAAE,MAAM,OAAO,WAAW,OAAO,QAAI,WAAAA;AAAA,IACzC;AAAA,IACA,YAAY;AACV,aAAO,OAAO,IAAI,YAAY,KAAK,EAAE,MAAM,OAAO,YAAY,MAAM,SAAS,UAAU,UAAU,CAAC;AAAA,IACpG;AAAA,IACA;AAAA,MACE,mBAAmB;AAAA,MACnB,GAAI,WAAW,EAAE,cAAc,EAAE,MAAM,SAAS,EAAkC,IAAI,CAAC;AAAA,IACzF;AAAA,EACF;AAEA,SAAO;AAAA,IACL,aAAa,MAAM,QAAQ,CAAC;AAAA,IAC5B,MAAM,MAAM;AAAA,IACZ;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEO,SAAS,cAAe,UAAyB,SAAgC;AACtF,QAAM,aAAS,gDAAmB;AAElC,QAAM,EAAE,MAAM,OAAO,UAAU,QAAI,WAAAA;AAAA,IACjC,WAAW,4BAAU,WAAW,QAAQ,IAAI;AAAA,IAC5C,MAAM,OAAO,IAAI,YAAY,IAAI,QAAS;AAAA,IAC1C,EAAE,mBAAmB,OAAO,cAAc,WAAW,OAAU;AAAA,EACjE;AAEA,SAAO,EAAE,YAAY,QAAQ,MAAM,WAAW,aAAa,CAAC,MAAM,MAAM;AAC1E;AAEO,SAAS,sBAAuB,OAAsB;AAC3D,QAAM,aAAS,gDAAmB;AAElC,QAAM,EAAE,MAAM,OAAO,WAAW,OAAO,QAAI,WAAAA;AAAA,IACzC,QAAQ,4BAAU,iBAAiB,KAAK,IAAI;AAAA,IAC5C,MAAM,OAAO,IAAI,YAAY,KAAK,EAAE,OAAe,OAAO,GAAG,CAAC;AAAA,IAC9D,EAAE,mBAAmB,OAAO,iBAAiB,IAAO;AAAA,EACtD;AAEA,SAAO,EAAE,aAAa,MAAM,QAAQ,CAAC,GAAG,WAAW,OAAO,OAAO;AACnE;AAEO,SAAS,oBACd,UACA,OAAO,GACP,QAAQ,IACR,OAA6B,UAC7B;AACA,QAAM,aAAS,gDAAmB;AAElC,QAAM,EAAE,MAAM,OAAO,WAAW,OAAO,QAAI,WAAAA;AAAA,IACzC,WAAW,4BAAU,iBAAiB,UAAU,MAAM,OAAO,IAAI,IAAI;AAAA,IACrE,MAAM,OAAO,IAAI,YAAY,OAAO,UAAW,EAAE,MAAY,OAAc,KAAW,CAAC;AAAA,IACvF,EAAE,mBAAmB,MAAM;AAAA,EAC7B;AAEA,SAAO,EAAE,QAAQ,MAAM,QAAQ,CAAC,GAAG,MAAM,MAAM,MAAM,WAAW,OAAO,OAAO;AAChF;AAEA,SAAS,iBACP,QACA,gBACA,OACK;AACL,MAAI,CAAC,eAAgB,QAAO,OAAO,MAAM,GAAG,KAAK;AACjD,QAAM,MAAM,OAAO,UAAU,CAAC,MAAM,OAAO,EAAE,OAAO,MAAM,OAAO,cAAc,CAAC;AAChF,MAAI,QAAQ,GAAI,QAAO,OAAO,MAAM,GAAG,KAAK;AAE5C,QAAM,SAAc,CAAC;AACrB,MAAI,QAAQ,MAAM;AAClB,MAAI,SAAS,MAAM;AACnB,SAAO,OAAO,SAAS,UAAU,QAAQ,OAAO,UAAU,UAAU,IAAI;AACtE,QAAI,QAAQ,OAAO,OAAQ,QAAO,KAAK,OAAO,OAAO,CAAC;AACtD,QAAI,OAAO,SAAS,SAAS,UAAU,EAAG,QAAO,KAAK,OAAO,QAAQ,CAAC;AAAA,EACxE;AACA,SAAO,OAAO,KAAK,CAAC,GAAG,MAAM,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,OAAO,CAAC;AACpE;AAEO,SAAS,0BACd,UACA,gBACA,QAAQ,GACR,WAAW,IACX;AACA,QAAM,EAAE,QAAQ,WAAW,MAAM,IAAI,oBAAoB,UAAU,GAAG,UAAU,QAAQ;AACxF,SAAO,EAAE,QAAQ,iBAAiB,QAAQ,gBAAgB,KAAK,GAAG,WAAW,MAAM;AACrF;","names":["useSWR"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as swr from 'swr';
|
|
2
2
|
import * as _medialane_sdk from '@medialane/sdk';
|
|
3
|
-
import { CollectionTokensSort, ApiResponse
|
|
3
|
+
import { ApiCollection, CollectionTokensSort, ApiResponse } from '@medialane/sdk';
|
|
4
4
|
|
|
5
5
|
type CollectionSort = "recent" | "supply" | "floor" | "volume" | "name";
|
|
6
6
|
declare function useCollections(page?: number, limit?: number, isFeatured?: boolean, sort?: CollectionSort, hideEmpty?: boolean, service?: string, standard?: string, fallback?: ApiCollection[]): {
|
|
@@ -84,7 +84,7 @@ declare function useCollections(page?: number, limit?: number, isFeatured?: bool
|
|
|
84
84
|
} | null;
|
|
85
85
|
}[]>>;
|
|
86
86
|
};
|
|
87
|
-
declare function useCollection(contract: string | null): {
|
|
87
|
+
declare function useCollection(contract: string | null, initial?: ApiCollection | null): {
|
|
88
88
|
collection: {
|
|
89
89
|
id: string;
|
|
90
90
|
chain: string;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as swr from 'swr';
|
|
2
2
|
import * as _medialane_sdk from '@medialane/sdk';
|
|
3
|
-
import { CollectionTokensSort, ApiResponse
|
|
3
|
+
import { ApiCollection, CollectionTokensSort, ApiResponse } from '@medialane/sdk';
|
|
4
4
|
|
|
5
5
|
type CollectionSort = "recent" | "supply" | "floor" | "volume" | "name";
|
|
6
6
|
declare function useCollections(page?: number, limit?: number, isFeatured?: boolean, sort?: CollectionSort, hideEmpty?: boolean, service?: string, standard?: string, fallback?: ApiCollection[]): {
|
|
@@ -84,7 +84,7 @@ declare function useCollections(page?: number, limit?: number, isFeatured?: bool
|
|
|
84
84
|
} | null;
|
|
85
85
|
}[]>>;
|
|
86
86
|
};
|
|
87
|
-
declare function useCollection(contract: string | null): {
|
|
87
|
+
declare function useCollection(contract: string | null, initial?: ApiCollection | null): {
|
|
88
88
|
collection: {
|
|
89
89
|
id: string;
|
|
90
90
|
chain: string;
|