Skip to content

Commit 91a5b3e

Browse files
committed
feat: ux improvements pt.2
1 parent 8f4943e commit 91a5b3e

File tree

9 files changed

+361
-324
lines changed

9 files changed

+361
-324
lines changed

apps/arkmarket/src/app/collection/[collectionAddress]/components/collection-header-stats.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ export default function CollectionHeaderStats({
1515
const parsedCollectionFloor7dPercentage = parseFloat(
1616
collection.floor_7d_percentage,
1717
);
18-
console.log(collection);
1918

2019
return (
2120
<div className="hidden grid-cols-2 items-center justify-between gap-2 md:flex md:h-12 md:gap-6 md:pr-5 xl:flex">

apps/arkmarket/src/app/collection/[collectionAddress]/components/collection-header.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ export default function CollectionHeader({
3232
collectionAddress,
3333
collection,
3434
}: CollectionHeaderProps) {
35-
const [collapsibleOpen, setCollapsibleOpen] = useState(false);
35+
const [collapsibleOpen, setCollapsibleOpen] = useState(true);
3636

3737
const { data } = useCollection({ address: collectionAddress });
3838

@@ -83,7 +83,7 @@ export default function CollectionHeader({
8383
<ExternalLink href={siteConfig.links.github}>
8484
<Github className="h-4" />
8585
</ExternalLink>
86-
{collection.description && (
86+
{collection.description || description && (
8787
<CollapsibleTrigger asChild>
8888
<button
8989
className={cn(

apps/arkmarket/src/app/collection/[collectionAddress]/components/collection-items-data-grid-view.tsx

Lines changed: 84 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import type { CollectionToken } from "~/types";
1616
import CollectionItemsBuyNow from "./collection-items-buy-now";
1717
import { CollectionTokenImage } from "./collection-token-image";
1818
import { env } from "~/env";
19+
import { useSeasonPass } from "~/hooks/useSeasonPass";
1920

2021
const LargeGridContainer = forwardRef<
2122
HTMLDivElement,
@@ -72,92 +73,99 @@ export default function CollectionItemsDataGridView({
7273
components={components}
7374
itemContent={(index) => {
7475
const token = tokens[index];
75-
7676
if (!token) {
7777
return null;
7878
}
79+
return <CollectionGridTokenItem token={token} viewType={viewType} />
80+
81+
}}
82+
/>
83+
</div>
7984

80-
return (
81-
<NftCard>
82-
<Link
83-
href={`/token/${token.collection_address}/${token.token_id}`}
84-
key={`${token.collection_address}-${token.token_id}`}
85-
prefetch={false}
85+
);
86+
}
87+
88+
function CollectionGridTokenItem({ token, viewType }: { token: CollectionToken, viewType: string }) {
89+
const { realmName, isSeasonPass } = useSeasonPass(token);
90+
const tokenName = isSeasonPass(token.collection_address) ? realmName : token.metadata?.name ?? token.token_id;
91+
92+
return (
93+
<NftCard>
94+
<Link
95+
href={`/token/${token.collection_address}/${token.token_id}`}
96+
key={`${token.collection_address}-${token.token_id}`}
97+
prefetch={false}
98+
>
99+
<NftCardMedia className="aspect-auto">
100+
<CollectionTokenImage
101+
token={token}
102+
height={viewType === "large-grid" ? 540 : 340}
103+
width={viewType === "large-grid" ? 540 : 340}
104+
/>
105+
</NftCardMedia>
106+
<NftCardContent>
107+
<div className="flex w-full justify-between text-foreground">
108+
<div className="w-full">
109+
<div
110+
className={cn(
111+
"font-bold",
112+
viewType === "large-grid" ? "text-xl" : "text-sm",
113+
ellipsableStyles,
114+
)}
86115
>
87-
<NftCardMedia className="aspect-auto">
88-
<CollectionTokenImage
89-
token={token}
90-
height={viewType === "large-grid" ? 540 : 340}
91-
width={viewType === "large-grid" ? 540 : 340}
92-
/>
93-
</NftCardMedia>
94-
<NftCardContent>
95-
<div className="flex w-full justify-between text-foreground">
96-
<div className="w-full">
97-
<div
98-
className={cn(
99-
"font-bold",
100-
viewType === "large-grid" ? "text-xl" : "text-sm",
101-
ellipsableStyles,
102-
)}
103-
>
104-
{token.metadata?.name ?? token.token_id}
105-
</div>
106-
{token.price ? (
107-
<div
108-
className={cn(
109-
"font-medium",
110-
viewType === "large-grid" ? "text-sm" : "text-xs",
111-
ellipsableStyles,
112-
)}
113-
>
114-
{formatUnits(token.price, 18)} LORDS
115-
</div>
116-
) : (
117-
<div
118-
className={cn(
119-
"font-medium",
120-
viewType === "large-grid" ? "text-sm" : "text-xs",
121-
ellipsableStyles,
122-
)}
123-
>
124-
Not for sale
125-
</div>
126-
)}
127-
</div>
128-
</div>
129-
<p className="mt-5 h-5 text-sm font-medium text-secondary-foreground">
130-
{token.last_price ? (
131-
<>Last sale {formatUnits(token.last_price, 18)} LORDS</>
132-
) : null}
133-
</p>
134-
</NftCardContent>
135-
</Link>
136-
{token.buy_in_progress ? (
116+
{tokenName}
117+
</div>
118+
{token.price ? (
137119
<div
138120
className={cn(
139-
"absolute bottom-0 left-0 flex h-10 w-full items-center justify-between gap-2 bg-primary px-3 font-medium text-background",
140-
viewType === "large-grid" ? "text-sm" : "text-sm",
121+
"font-medium",
122+
viewType === "large-grid" ? "text-sm" : "text-xs",
123+
ellipsableStyles,
141124
)}
142125
>
143-
<span className="leading-none">Buy in progress</span>
144-
<LoaderCircle className="left-4 size-4 animate-spin" />
126+
{formatUnits(token.price, 18)} LORDS
145127
</div>
146-
) : token.is_listed && token.listing !== null && !token.listing.is_auction ? (
147-
<CollectionItemsBuyNow token={token} />
148128
) : (
149-
<NftCardAction asChild>
150-
<Link
151-
href={`/token/${token.collection_address}/${token.token_id}`}
152-
>
153-
Details
154-
</Link>
155-
</NftCardAction>
129+
<div
130+
className={cn(
131+
"font-medium",
132+
viewType === "large-grid" ? "text-sm" : "text-xs",
133+
ellipsableStyles,
134+
)}
135+
>
136+
Not for sale
137+
</div>
156138
)}
157-
</NftCard>
158-
);
159-
}}
160-
/>
161-
</div>
162-
);
139+
</div>
140+
</div>
141+
<p className="mt-5 h-5 text-sm font-medium text-secondary-foreground">
142+
{token.last_price ? (
143+
<>Last sale {formatUnits(token.last_price, 18)} LORDS</>
144+
) : null}
145+
</p>
146+
</NftCardContent>
147+
</Link>
148+
{token.buy_in_progress ? (
149+
<div
150+
className={cn(
151+
"absolute bottom-0 left-0 flex h-10 w-full items-center justify-between gap-2 bg-primary px-3 font-medium text-background",
152+
viewType === "large-grid" ? "text-sm" : "text-sm",
153+
)}
154+
>
155+
<span className="leading-none">Buy in progress</span>
156+
<LoaderCircle className="left-4 size-4 animate-spin" />
157+
</div>
158+
) : token.is_listed && token.listing !== null && !token.listing.is_auction ? (
159+
<CollectionItemsBuyNow token={token} />
160+
) : (
161+
<NftCardAction asChild>
162+
<Link
163+
href={`/token/${token.collection_address}/${token.token_id}`}
164+
>
165+
Details
166+
</Link>
167+
</NftCardAction>
168+
)}
169+
</NftCard>
170+
)
163171
}

apps/arkmarket/src/app/collection/[collectionAddress]/components/collection-items-data-list-view.tsx

Lines changed: 73 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
"use client";
22

33
import { useMemo, useRef } from "react";
4+
import type { VirtualItem, Virtualizer } from "@tanstack/react-virtual";
45
import { useWindowVirtualizer } from "@tanstack/react-virtual";
56

67
import { cn, ellipsableStyles, formatUnits } from "@ark-market/ui";
@@ -20,6 +21,7 @@ import Media from "~/components/media";
2021
import { PriceTag } from "@ark-market/ui/price-tag";
2122
import Link from "next/link";
2223
import { env } from "~/env";
24+
import { useSeasonPass } from "~/hooks/useSeasonPass";
2325

2426
const gridTemplateColumnValue =
2527
"grid-cols-[minmax(10rem,2fr)_repeat(5,minmax(7.25rem,1fr))]";
@@ -94,73 +96,79 @@ export default function CollectionItemsDataListView({
9496
return null;
9597
}
9698

97-
return (
98-
<TableRow
99-
data-index={virtualRow.index}
100-
key={`${token.collection_address}-${token.token_id}`}
101-
ref={(node) => rowVirtualizer.measureElement(node)}
102-
className="group absolute flex w-full items-center"
103-
style={{
104-
transform: `translateY(${virtualRow.start}px)`,
105-
}}
106-
>
107-
<Link
108-
prefetch={false}
109-
href={`/token/${token.collection_address}/${token.token_id}`}
110-
className={cn(
111-
"grid h-full w-full items-center",
112-
gridTemplateColumnValue,
113-
)}
114-
>
115-
<TableCell className="pl-5">
116-
<div className="flex items-center gap-4">
117-
<Media
118-
src={token.metadata?.image}
119-
mediaKey={token.metadata?.image_key}
120-
alt={token.metadata?.name ?? "Empty NFT"}
121-
className="h-[2.625rem] w-[2.625rem] rounded-md object-contain"
122-
height={94}
123-
width={94}
124-
/>
125-
<p className={cn("w-full", ellipsableStyles)}>
126-
{token.metadata?.name ?? token.token_id}
127-
</p>
128-
</div>
129-
</TableCell>
130-
<TableCell>
131-
{token.price ? (
132-
<PriceTag price={token.price} token="lords" />
133-
) : (
134-
"_"
135-
)}
136-
</TableCell>
137-
<TableCell>
138-
{token.last_price ? (
139-
<div className="flex items-center">
140-
<LordsLogo className="size-4" />
141-
<p>
142-
{formatUnits(token.last_price, 18)}{" "}
143-
<span className="text-muted-foreground">LORDS</span>
144-
</p>
145-
</div>
146-
) : (
147-
"_"
148-
)}
149-
</TableCell>
150-
<TableCell>_</TableCell>
151-
<TableCell>
152-
<Button asChild variant="link" className="px-0" size="xl">
153-
<Link href={`/wallet/${token.owner}`}>
154-
{token.owner ? `${token.owner.slice(0, 6)}...` : "_"}
155-
</Link>
156-
</Button>
157-
</TableCell>
158-
<TableCell>_</TableCell>
159-
</Link>
160-
</TableRow>
161-
);
99+
return <CollectionTokenItem token={token} rowVirtualizer={rowVirtualizer} virtualRow={virtualRow} />
162100
})}
163101
</TableBody>
164102
</Table>
165103
);
166104
}
105+
function CollectionTokenItem({ token, rowVirtualizer, virtualRow }: { token: CollectionToken, rowVirtualizer: Virtualizer<Window, Element>, virtualRow: VirtualItem }) {
106+
const { realmName, isSeasonPass } = useSeasonPass(token);
107+
const tokenName = isSeasonPass(token.collection_address) ? realmName : token.metadata?.name ?? token.token_id;
108+
109+
return (
110+
<TableRow
111+
data-index={virtualRow.index}
112+
key={`${token.collection_address}-${token.token_id}`}
113+
ref={(node) => rowVirtualizer.measureElement(node)}
114+
className="group absolute flex w-full items-center"
115+
style={{
116+
transform: `translateY(${virtualRow.start}px)`,
117+
}}
118+
>
119+
<Link
120+
prefetch={false}
121+
href={`/token/${token.collection_address}/${token.token_id}`}
122+
className={cn(
123+
"grid h-full w-full items-center",
124+
gridTemplateColumnValue,
125+
)}
126+
>
127+
<TableCell className="pl-5">
128+
<div className="flex items-center gap-4">
129+
<Media
130+
src={token.metadata?.image}
131+
mediaKey={token.metadata?.image_key}
132+
alt={token.metadata?.name ?? "Empty NFT"}
133+
className="h-[2.625rem] w-[2.625rem] rounded-md object-contain"
134+
height={94}
135+
width={94}
136+
/>
137+
<p className={cn("w-full", ellipsableStyles)}>
138+
{tokenName}
139+
</p>
140+
</div>
141+
</TableCell>
142+
<TableCell>
143+
{token.price ? (
144+
<PriceTag price={token.price} token="lords" />
145+
) : (
146+
"_"
147+
)}
148+
</TableCell>
149+
<TableCell>
150+
{token.last_price ? (
151+
<div className="flex items-center">
152+
<LordsLogo className="size-4" />
153+
<p>
154+
{formatUnits(token.last_price, 18)}{" "}
155+
<span className="text-muted-foreground">LORDS</span>
156+
</p>
157+
</div>
158+
) : (
159+
"_"
160+
)}
161+
</TableCell>
162+
<TableCell>_</TableCell>
163+
<TableCell>
164+
<Button asChild variant="link" className="px-0" size="xl">
165+
<Link href={`/wallet/${token.owner}`}>
166+
{token.owner ? `${token.owner.slice(0, 6)}...` : "_"}
167+
</Link>
168+
</Button>
169+
</TableCell>
170+
<TableCell>_</TableCell>
171+
</Link>
172+
</TableRow>
173+
);
174+
}

0 commit comments

Comments
 (0)