Skip to content

Commit

Permalink
feat: ux improvements pt.2
Browse files Browse the repository at this point in the history
  • Loading branch information
MartianGreed committed Dec 6, 2024
1 parent 8f4943e commit 91a5b3e
Show file tree
Hide file tree
Showing 9 changed files with 361 additions and 324 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ export default function CollectionHeaderStats({
const parsedCollectionFloor7dPercentage = parseFloat(
collection.floor_7d_percentage,
);
console.log(collection);

return (
<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">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export default function CollectionHeader({
collectionAddress,
collection,
}: CollectionHeaderProps) {
const [collapsibleOpen, setCollapsibleOpen] = useState(false);
const [collapsibleOpen, setCollapsibleOpen] = useState(true);

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

Expand Down Expand Up @@ -83,7 +83,7 @@ export default function CollectionHeader({
<ExternalLink href={siteConfig.links.github}>
<Github className="h-4" />
</ExternalLink>
{collection.description && (
{collection.description || description && (
<CollapsibleTrigger asChild>
<button
className={cn(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import type { CollectionToken } from "~/types";
import CollectionItemsBuyNow from "./collection-items-buy-now";
import { CollectionTokenImage } from "./collection-token-image";
import { env } from "~/env";
import { useSeasonPass } from "~/hooks/useSeasonPass";

const LargeGridContainer = forwardRef<
HTMLDivElement,
Expand Down Expand Up @@ -72,92 +73,99 @@ export default function CollectionItemsDataGridView({
components={components}
itemContent={(index) => {
const token = tokens[index];

if (!token) {
return null;
}
return <CollectionGridTokenItem token={token} viewType={viewType} />

}}
/>
</div>

return (
<NftCard>
<Link
href={`/token/${token.collection_address}/${token.token_id}`}
key={`${token.collection_address}-${token.token_id}`}
prefetch={false}
);
}

function CollectionGridTokenItem({ token, viewType }: { token: CollectionToken, viewType: string }) {
const { realmName, isSeasonPass } = useSeasonPass(token);
const tokenName = isSeasonPass(token.collection_address) ? realmName : token.metadata?.name ?? token.token_id;

return (
<NftCard>
<Link
href={`/token/${token.collection_address}/${token.token_id}`}
key={`${token.collection_address}-${token.token_id}`}
prefetch={false}
>
<NftCardMedia className="aspect-auto">
<CollectionTokenImage
token={token}
height={viewType === "large-grid" ? 540 : 340}
width={viewType === "large-grid" ? 540 : 340}
/>
</NftCardMedia>
<NftCardContent>
<div className="flex w-full justify-between text-foreground">
<div className="w-full">
<div
className={cn(
"font-bold",
viewType === "large-grid" ? "text-xl" : "text-sm",
ellipsableStyles,
)}
>
<NftCardMedia className="aspect-auto">
<CollectionTokenImage
token={token}
height={viewType === "large-grid" ? 540 : 340}
width={viewType === "large-grid" ? 540 : 340}
/>
</NftCardMedia>
<NftCardContent>
<div className="flex w-full justify-between text-foreground">
<div className="w-full">
<div
className={cn(
"font-bold",
viewType === "large-grid" ? "text-xl" : "text-sm",
ellipsableStyles,
)}
>
{token.metadata?.name ?? token.token_id}
</div>
{token.price ? (
<div
className={cn(
"font-medium",
viewType === "large-grid" ? "text-sm" : "text-xs",
ellipsableStyles,
)}
>
{formatUnits(token.price, 18)} LORDS
</div>
) : (
<div
className={cn(
"font-medium",
viewType === "large-grid" ? "text-sm" : "text-xs",
ellipsableStyles,
)}
>
Not for sale
</div>
)}
</div>
</div>
<p className="mt-5 h-5 text-sm font-medium text-secondary-foreground">
{token.last_price ? (
<>Last sale {formatUnits(token.last_price, 18)} LORDS</>
) : null}
</p>
</NftCardContent>
</Link>
{token.buy_in_progress ? (
{tokenName}
</div>
{token.price ? (
<div
className={cn(
"absolute bottom-0 left-0 flex h-10 w-full items-center justify-between gap-2 bg-primary px-3 font-medium text-background",
viewType === "large-grid" ? "text-sm" : "text-sm",
"font-medium",
viewType === "large-grid" ? "text-sm" : "text-xs",
ellipsableStyles,
)}
>
<span className="leading-none">Buy in progress</span>
<LoaderCircle className="left-4 size-4 animate-spin" />
{formatUnits(token.price, 18)} LORDS
</div>
) : token.is_listed && token.listing !== null && !token.listing.is_auction ? (
<CollectionItemsBuyNow token={token} />
) : (
<NftCardAction asChild>
<Link
href={`/token/${token.collection_address}/${token.token_id}`}
>
Details
</Link>
</NftCardAction>
<div
className={cn(
"font-medium",
viewType === "large-grid" ? "text-sm" : "text-xs",
ellipsableStyles,
)}
>
Not for sale
</div>
)}
</NftCard>
);
}}
/>
</div>
);
</div>
</div>
<p className="mt-5 h-5 text-sm font-medium text-secondary-foreground">
{token.last_price ? (
<>Last sale {formatUnits(token.last_price, 18)} LORDS</>
) : null}
</p>
</NftCardContent>
</Link>
{token.buy_in_progress ? (
<div
className={cn(
"absolute bottom-0 left-0 flex h-10 w-full items-center justify-between gap-2 bg-primary px-3 font-medium text-background",
viewType === "large-grid" ? "text-sm" : "text-sm",
)}
>
<span className="leading-none">Buy in progress</span>
<LoaderCircle className="left-4 size-4 animate-spin" />
</div>
) : token.is_listed && token.listing !== null && !token.listing.is_auction ? (
<CollectionItemsBuyNow token={token} />
) : (
<NftCardAction asChild>
<Link
href={`/token/${token.collection_address}/${token.token_id}`}
>
Details
</Link>
</NftCardAction>
)}
</NftCard>
)
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"use client";

import { useMemo, useRef } from "react";
import type { VirtualItem, Virtualizer } from "@tanstack/react-virtual";
import { useWindowVirtualizer } from "@tanstack/react-virtual";

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

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

return (
<TableRow
data-index={virtualRow.index}
key={`${token.collection_address}-${token.token_id}`}
ref={(node) => rowVirtualizer.measureElement(node)}
className="group absolute flex w-full items-center"
style={{
transform: `translateY(${virtualRow.start}px)`,
}}
>
<Link
prefetch={false}
href={`/token/${token.collection_address}/${token.token_id}`}
className={cn(
"grid h-full w-full items-center",
gridTemplateColumnValue,
)}
>
<TableCell className="pl-5">
<div className="flex items-center gap-4">
<Media
src={token.metadata?.image}
mediaKey={token.metadata?.image_key}
alt={token.metadata?.name ?? "Empty NFT"}
className="h-[2.625rem] w-[2.625rem] rounded-md object-contain"
height={94}
width={94}
/>
<p className={cn("w-full", ellipsableStyles)}>
{token.metadata?.name ?? token.token_id}
</p>
</div>
</TableCell>
<TableCell>
{token.price ? (
<PriceTag price={token.price} token="lords" />
) : (
"_"
)}
</TableCell>
<TableCell>
{token.last_price ? (
<div className="flex items-center">
<LordsLogo className="size-4" />
<p>
{formatUnits(token.last_price, 18)}{" "}
<span className="text-muted-foreground">LORDS</span>
</p>
</div>
) : (
"_"
)}
</TableCell>
<TableCell>_</TableCell>
<TableCell>
<Button asChild variant="link" className="px-0" size="xl">
<Link href={`/wallet/${token.owner}`}>
{token.owner ? `${token.owner.slice(0, 6)}...` : "_"}
</Link>
</Button>
</TableCell>
<TableCell>_</TableCell>
</Link>
</TableRow>
);
return <CollectionTokenItem token={token} rowVirtualizer={rowVirtualizer} virtualRow={virtualRow} />
})}
</TableBody>
</Table>
);
}
function CollectionTokenItem({ token, rowVirtualizer, virtualRow }: { token: CollectionToken, rowVirtualizer: Virtualizer<Window, Element>, virtualRow: VirtualItem }) {
const { realmName, isSeasonPass } = useSeasonPass(token);
const tokenName = isSeasonPass(token.collection_address) ? realmName : token.metadata?.name ?? token.token_id;

return (
<TableRow
data-index={virtualRow.index}
key={`${token.collection_address}-${token.token_id}`}
ref={(node) => rowVirtualizer.measureElement(node)}
className="group absolute flex w-full items-center"
style={{
transform: `translateY(${virtualRow.start}px)`,
}}
>
<Link
prefetch={false}
href={`/token/${token.collection_address}/${token.token_id}`}
className={cn(
"grid h-full w-full items-center",
gridTemplateColumnValue,
)}
>
<TableCell className="pl-5">
<div className="flex items-center gap-4">
<Media
src={token.metadata?.image}
mediaKey={token.metadata?.image_key}
alt={token.metadata?.name ?? "Empty NFT"}
className="h-[2.625rem] w-[2.625rem] rounded-md object-contain"
height={94}
width={94}
/>
<p className={cn("w-full", ellipsableStyles)}>
{tokenName}
</p>
</div>
</TableCell>
<TableCell>
{token.price ? (
<PriceTag price={token.price} token="lords" />
) : (
"_"
)}
</TableCell>
<TableCell>
{token.last_price ? (
<div className="flex items-center">
<LordsLogo className="size-4" />
<p>
{formatUnits(token.last_price, 18)}{" "}
<span className="text-muted-foreground">LORDS</span>
</p>
</div>
) : (
"_"
)}
</TableCell>
<TableCell>_</TableCell>
<TableCell>
<Button asChild variant="link" className="px-0" size="xl">
<Link href={`/wallet/${token.owner}`}>
{token.owner ? `${token.owner.slice(0, 6)}...` : "_"}
</Link>
</Button>
</TableCell>
<TableCell>_</TableCell>
</Link>
</TableRow>
);
}
Loading

0 comments on commit 91a5b3e

Please sign in to comment.