Skip to content

Commit 992cdba

Browse files
committed
Migrate Marketplace listing cards on overview page to shadcn/tailwind
1 parent ccff347 commit 992cdba

File tree

2 files changed

+102
-90
lines changed

2 files changed

+102
-90
lines changed

apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/components/MarketplaceDetails.tsx

Lines changed: 100 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,7 @@
11
import { WalletAddress } from "@/components/blocks/wallet-address";
2-
import {
3-
GridItem,
4-
SimpleGrid,
5-
Skeleton,
6-
SkeletonText,
7-
useBreakpointValue,
8-
} from "@chakra-ui/react";
2+
import { Badge } from "@/components/ui/badge";
3+
import { SkeletonContainer } from "@/components/ui/skeleton";
4+
import { TrackedLinkTW } from "@/components/ui/tracked-link";
95
import { ListingStatsV3 } from "contract-ui/tabs/listings/components/listing-stats";
106
import { useMemo } from "react";
117
import type { ThirdwebContract } from "thirdweb";
@@ -19,7 +15,6 @@ import {
1915
} from "thirdweb/extensions/marketplace";
2016
import { useReadContract } from "thirdweb/react";
2117
import { min } from "thirdweb/utils";
22-
import { Badge, Card, Heading, Text, TrackedLink } from "tw-components";
2318
import { NFTMediaWithEmptyState } from "tw-components/nft-media";
2419

2520
type ListingData =
@@ -87,18 +82,14 @@ const DirectListingCards: React.FC<ListingCardsSectionProps> = ({
8782
<h2 className="font-semibold text-2xl tracking-tight">
8883
Direct Listing
8984
</h2>
90-
<TrackedLink
85+
<TrackedLinkTW
9186
category={trackingCategory}
9287
label="view_all_direct_listings"
93-
color="blue.400"
94-
_light={{
95-
color: "blue.600",
96-
}}
97-
gap={4}
88+
className="text-link-foreground hover:text-foreground"
9889
href={directListingsHref}
9990
>
10091
View all -&gt;
101-
</TrackedLink>
92+
</TrackedLinkTW>
10293
</div>
10394
<ListingCards
10495
listings={listings}
@@ -151,19 +142,17 @@ const EnglishAuctionCards: React.FC<ListingCardsSectionProps> = ({
151142
return (
152143
<>
153144
<div className="flex w-full items-center justify-between">
154-
<Heading size="label.lg">English Auctions</Heading>
155-
<TrackedLink
145+
<h2 className="font-semibold text-2xl tracking-tight">
146+
English Auctions
147+
</h2>
148+
<TrackedLinkTW
156149
category={trackingCategory}
157150
label="view_all_english_auctions"
158-
color="blue.400"
159-
_light={{
160-
color: "blue.600",
161-
}}
162-
gap={4}
151+
className="text-link-foreground hover:text-foreground"
163152
href={englishAuctionsHref}
164153
>
165154
View all -&gt;
166-
</TrackedLink>
155+
</TrackedLinkTW>
167156
</div>
168157
<ListingCards
169158
listings={auctions}
@@ -200,15 +189,15 @@ export const MarketplaceDetails: React.FC<MarketplaceDetailsVersionProps> = ({
200189
hasEnglishAuctions={hasEnglishAuctions}
201190
/>
202191

203-
{hasDirectListings && contract && (
192+
{hasDirectListings && (
204193
<DirectListingCards
205194
contract={contract}
206195
trackingCategory={trackingCategory}
207196
chainSlug={chainSlug}
208197
/>
209198
)}
210199

211-
{hasEnglishAuctions && contract && (
200+
{hasEnglishAuctions && (
212201
<EnglishAuctionCards
213202
contract={contract}
214203
trackingCategory={trackingCategory}
@@ -263,82 +252,105 @@ const ListingCards: React.FC<ListingCardsProps> = ({
263252
chainSlug,
264253
contractAddress,
265254
}) => {
266-
const isMobile = useBreakpointValue({ base: true, md: false });
267-
268255
listings = isPending
269-
? Array.from({ length: isMobile ? 2 : 3 }).map((_, idx) =>
270-
dummyMetadata(idx),
271-
)
272-
: listings.slice(0, isMobile ? 2 : 3);
256+
? Array.from({ length: 3 }).map((_, idx) => dummyMetadata(idx))
257+
: listings.slice(0, 3);
273258

274259
const directListingsHref = `/${chainSlug}/${contractAddress}/direct-listings`;
275260
const englishAuctionsHref = `/${chainSlug}/${contractAddress}/english-auctions`;
276261

277262
return (
278-
<SimpleGrid gap={{ base: 3, md: 6 }} columns={{ base: 2, md: 3 }}>
263+
<div className="grid grid-cols-2 gap-3 md:grid-cols-3 md:gap-6 max-sm:[&>*:nth-child(n+3)]:hidden">
279264
{listings.map((listing, index) => (
280-
<GridItem
265+
<div
266+
className="relative rounded-lg border border-border bg-muted/50 hover:border-foreground hover:bg-muted"
281267
key={`${listing.creatorAddress}-${index}`}
282-
as={TrackedLink}
283-
category={trackingCategory}
284-
href={
285-
listing.type === "direct-listing"
286-
? directListingsHref
287-
: englishAuctionsHref
288-
}
289-
_hover={{ opacity: 0.75, textDecoration: "none" }}
290268
>
291-
<Card p={0} position="relative">
292-
<div className="relative aspect-square w-full overflow-hidden rounded-xl">
293-
<Skeleton isLoaded={!isPending}>
294-
<NFTMediaWithEmptyState
295-
metadata={listing.asset.metadata}
296-
requireInteraction
297-
width="100%"
298-
height="100%"
299-
/>
300-
</Skeleton>
301-
</div>
302-
<div className="flex flex-col gap-1 p-4 pb-3">
303-
<Skeleton w={!isPending ? "100%" : "50%"} isLoaded={!isPending}>
304-
<Heading size="label.md">{listing.asset.metadata.name}</Heading>
305-
</Skeleton>
306-
{isMarketplaceV1 && (
307-
<SkeletonText isLoaded={!isPending}>
308-
<Text size="body.sm">
309-
{listing.type === "direct-listing"
269+
<div className="relative aspect-square w-full overflow-hidden rounded-lg">
270+
{/* Image */}
271+
<SkeletonContainer
272+
loadedData={isPending ? undefined : listing.asset.metadata}
273+
skeletonData={listing.asset.metadata}
274+
className="block h-full w-full"
275+
render={(v) => {
276+
return (
277+
<NFTMediaWithEmptyState
278+
metadata={v}
279+
requireInteraction
280+
width="100%"
281+
height="100%"
282+
/>
283+
);
284+
}}
285+
/>
286+
</div>
287+
288+
<div className="flex flex-col gap-1 p-4 pb-3">
289+
{/* Card Link + Title */}
290+
<SkeletonContainer
291+
loadedData={isPending ? undefined : listing.asset.metadata.name}
292+
skeletonData="Listing Title"
293+
render={(v) => (
294+
<TrackedLinkTW
295+
category={trackingCategory}
296+
className="before:absolute before:inset-0"
297+
href={
298+
listing.type === "direct-listing"
299+
? directListingsHref
300+
: englishAuctionsHref
301+
}
302+
>
303+
{v}
304+
</TrackedLinkTW>
305+
)}
306+
/>
307+
308+
{isMarketplaceV1 && (
309+
<SkeletonContainer
310+
className="self-start"
311+
loadedData={
312+
isPending
313+
? undefined
314+
: listing.type === "direct-listing"
310315
? "Direct Listing"
311-
: "English Auction"}
312-
</Text>
313-
</SkeletonText>
316+
: "English Auction"
317+
}
318+
skeletonData={listing.type}
319+
render={(v) => (
320+
<p className="text-muted-foreground text-sm">{v}</p>
321+
)}
322+
/>
323+
)}
324+
325+
<SkeletonContainer
326+
loadedData={isPending ? undefined : listing.creatorAddress}
327+
skeletonData={listing.creatorAddress}
328+
className="mt-4"
329+
render={(v) => (
330+
<div>
331+
<p className="text-muted-foreground text-sm">Seller</p>
332+
<WalletAddress
333+
className="relative z-[1] self-start"
334+
address={v}
335+
/>
336+
</div>
314337
)}
338+
/>
315339

316-
<Text size="body.sm" mt={4}>
317-
Seller
318-
</Text>
319-
<SkeletonText isLoaded={!isPending}>
320-
<WalletAddress address={listing.creatorAddress} />
321-
</SkeletonText>
322-
<SkeletonText
323-
as={Badge}
324-
background="backgroundHighlight"
325-
isLoaded={!isPending}
326-
skeletonHeight={3.5}
327-
noOfLines={1}
328-
position="absolute"
329-
rounded="lg"
330-
size="body.xs"
331-
p={2}
332-
top={2}
333-
right={2}
340+
{!isPending && (
341+
<Badge
342+
variant="outline"
343+
className="absolute top-2 right-2 bg-background py-1.5"
334344
>
335-
<b>{listing.currencyValue.displayValue}</b>{" "}
336-
{listing.currencyValue.symbol}
337-
</SkeletonText>
338-
</div>
339-
</Card>
340-
</GridItem>
345+
<p className="line-clamp-1">
346+
<b>{listing.currencyValue.displayValue}</b>{" "}
347+
{listing.currencyValue.symbol}
348+
</p>
349+
</Badge>
350+
)}
351+
</div>
352+
</div>
341353
))}
342-
</SimpleGrid>
354+
</div>
343355
);
344356
};

apps/dashboard/src/tw-components/nft-media.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ export const NFTMediaWithEmptyState: React.FC<{
2626
height: props.height,
2727
}}
2828
className={cn(
29-
"grid flex-shrink-0 place-items-center overflow-hidden rounded-xl border border-border object-contain",
29+
"grid flex-shrink-0 place-items-center overflow-hidden rounded-lg border border-border object-contain",
3030
props.className,
3131
)}
3232
>
@@ -44,7 +44,7 @@ export const NFTMediaWithEmptyState: React.FC<{
4444
height: props.height,
4545
}}
4646
className={cn(
47-
"flex-shrink-0 overflow-hidden rounded-xl object-contain",
47+
"flex-shrink-0 overflow-hidden rounded-lg object-contain",
4848
props.className,
4949
)}
5050
>

0 commit comments

Comments
 (0)