Skip to content

Commit 91b4cac

Browse files
committed
Dashboard: Add supply remaining progress in asset page claim tokens card
1 parent e3e3142 commit 91b4cac

File tree

1 file changed

+55
-4
lines changed
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/claim-tokens

1 file changed

+55
-4
lines changed

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_components/claim-tokens/claim-tokens-ui.tsx

Lines changed: 55 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { Spinner } from "@/components/ui/Spinner/Spinner";
33
import { Button } from "@/components/ui/button";
44
import { DecimalInput } from "@/components/ui/decimal-input";
55
import { Label } from "@/components/ui/label";
6+
import { Progress } from "@/components/ui/progress";
67
import { SkeletonContainer } from "@/components/ui/skeleton";
78
import { cn } from "@/lib/utils";
89
import { useMutation, useQuery } from "@tanstack/react-query";
@@ -31,7 +32,7 @@ import {
3132
useActiveWallet,
3233
useSendTransaction,
3334
} from "thirdweb/react";
34-
import { getClaimParams } from "thirdweb/utils";
35+
import { getClaimParams, maxUint256 } from "thirdweb/utils";
3536
import { tryCatch } from "utils/try-catch";
3637
import { getSDKTheme } from "../../../../../../../../components/sdk-component-theme";
3738
import { PublicPageConnectButton } from "../../../_components/PublicPageConnectButton";
@@ -41,6 +42,11 @@ type ActiveClaimCondition = Awaited<ReturnType<typeof getActiveClaimCondition>>;
4142

4243
// TODO UI improvements - show how many tokens connected wallet can claim at max
4344

45+
const compactNumberFormatter = new Intl.NumberFormat("en-US", {
46+
notation: "compact",
47+
maximumFractionDigits: 10,
48+
});
49+
4450
export function ClaimTokenCardUI(props: {
4551
contract: ThirdwebContract;
4652
name: string;
@@ -304,7 +310,9 @@ export function ClaimTokenCardUI(props: {
304310
return (
305311
<div className="rounded-xl border bg-card ">
306312
<div className="border-b px-4 py-5 lg:px-5">
307-
<h2 className="font-bold text-lg">Buy {props.symbol}</h2>
313+
<h2 className="font-semibold text-lg tracking-tight">
314+
Buy {props.symbol}
315+
</h2>
308316
<p className="text-muted-foreground text-sm">
309317
Buy tokens from the primary sale
310318
</p>
@@ -320,11 +328,18 @@ export function ClaimTokenCardUI(props: {
320328
id="token-amount"
321329
symbol={props.symbol}
322330
/>
323-
{/* <p className="text-xs text-muted-foreground">Maximum purchasable: {tokenData.maxPurchasable} tokens</p> */}
324331
</div>
325332

326333
<div className="h-4" />
327334

335+
<SupplyRemaining
336+
supplyClaimed={props.claimCondition.supplyClaimed}
337+
maxClaimableSupply={props.claimCondition.maxClaimableSupply}
338+
decimals={props.decimals}
339+
/>
340+
341+
<div className="h-4" />
342+
328343
<div className="space-y-3 rounded-lg bg-muted/50 p-3">
329344
{/* Price per token */}
330345
<div className="flex justify-between font-medium text-sm">
@@ -426,6 +441,42 @@ export function ClaimTokenCardUI(props: {
426441
);
427442
}
428443

444+
function SupplyRemaining(props: {
445+
supplyClaimed: bigint;
446+
maxClaimableSupply: bigint;
447+
decimals: number;
448+
}) {
449+
const isMaxClaimableSupplyUnlimited = props.maxClaimableSupply === maxUint256;
450+
const supplyClaimedTokenNumber = Number(
451+
toTokens(props.supplyClaimed, props.decimals),
452+
);
453+
const maxClaimableSupplyTokenNumber = Number(
454+
toTokens(props.maxClaimableSupply, props.decimals),
455+
);
456+
457+
const soldPercentage = isMaxClaimableSupplyUnlimited
458+
? 0
459+
: (supplyClaimedTokenNumber / maxClaimableSupplyTokenNumber) * 100;
460+
461+
return (
462+
<div className="space-y-2">
463+
<div className="flex items-center justify-between">
464+
<span className="font-medium text-sm">Supply Remaining</span>
465+
<span className="font-bold text-sm">
466+
{compactNumberFormatter.format(supplyClaimedTokenNumber)} /{" "}
467+
{isMaxClaimableSupplyUnlimited
468+
? "Unlimited"
469+
: compactNumberFormatter.format(maxClaimableSupplyTokenNumber)}
470+
</span>
471+
</div>
472+
<Progress value={soldPercentage} className="h-2.5" />
473+
<p className="font-medium text-muted-foreground text-xs">
474+
{soldPercentage.toFixed(1)}% Sold
475+
</p>
476+
</div>
477+
);
478+
}
479+
429480
type Status = "idle" | "pending" | "success" | "error";
430481

431482
const statusToIcon: Record<Status, React.FC<{ className: string }>> = {
@@ -472,7 +523,7 @@ function PriceInput(props: {
472523
className="!text-2xl h-auto truncate bg-muted/50 pr-14 font-bold"
473524
/>
474525
{props.symbol && (
475-
<div className="-translate-y-1/2 absolute top-1/2 right-4 font-semibold text-base text-muted-foreground">
526+
<div className="-translate-y-1/2 absolute top-1/2 right-3 font-medium text-muted-foreground text-sm">
476527
{props.symbol}
477528
</div>
478529
)}

0 commit comments

Comments
 (0)