@@ -3,6 +3,7 @@ import { Spinner } from "@/components/ui/Spinner/Spinner";
33import { Button } from "@/components/ui/button" ;
44import { DecimalInput } from "@/components/ui/decimal-input" ;
55import { Label } from "@/components/ui/label" ;
6+ import { Progress } from "@/components/ui/progress" ;
67import { SkeletonContainer } from "@/components/ui/skeleton" ;
78import { cn } from "@/lib/utils" ;
89import { 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" ;
3536import { tryCatch } from "utils/try-catch" ;
3637import { getSDKTheme } from "../../../../../../../../components/sdk-component-theme" ;
3738import { 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+
4450export 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+
429480type Status = "idle" | "pending" | "success" | "error" ;
430481
431482const 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