Skip to content

Commit ed901d9

Browse files
committed
[TOOL-4886] Dashboard: Show Remaining supply progress bar ui in claim tokens card
1 parent 91b4cac commit ed901d9

File tree

2 files changed

+78
-40
lines changed

2 files changed

+78
-40
lines changed

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

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import {
1818
ChevronRightIcon,
1919
ExternalLinkIcon,
2020
} from "lucide-react";
21-
import { useEffect, useState } from "react";
21+
import { useState } from "react";
2222
import { type ThirdwebClient, type ThirdwebContract, toTokens } from "thirdweb";
2323
import type { ChainMetadata } from "thirdweb/chains";
2424
import {
@@ -171,7 +171,7 @@ function RecentTransfersUI(props: {
171171
<Button
172172
variant="outline"
173173
size="sm"
174-
disabled={props.isPending || props.data.length === 0}
174+
disabled={props.isPending || props.data.length < props.rowsPerPage}
175175
className="gap-1.5 bg-background"
176176
onClick={() => props.setPage(props.page + 1)}
177177
>
@@ -213,7 +213,6 @@ export function RecentTransfers(props: {
213213
}) {
214214
const rowsPerPage = 10;
215215
const [page, setPage] = useState(0);
216-
const [hasFetchedOnce, setHasFetchedOnce] = useState(false);
217216

218217
const tokenQuery = useTokenTransfers({
219218
chainId: props.clientContract.chain.id,
@@ -222,18 +221,11 @@ export function RecentTransfers(props: {
222221
limit: rowsPerPage,
223222
});
224223

225-
// eslint-disable-next-line no-restricted-syntax
226-
useEffect(() => {
227-
if (!tokenQuery.isPending) {
228-
setHasFetchedOnce(true);
229-
}
230-
}, [tokenQuery.isPending]);
231-
232224
return (
233225
<div>
234226
<RecentTransfersUI
235227
data={tokenQuery.data ?? []}
236-
isPending={tokenQuery.isPending && !hasFetchedOnce}
228+
isPending={tokenQuery.isPending}
237229
rowsPerPage={rowsPerPage}
238230
client={props.clientContract.client}
239231
tokenMetadata={{

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

Lines changed: 75 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,13 @@ import { cn } from "@/lib/utils";
99
import { useMutation, useQuery } from "@tanstack/react-query";
1010
import { TransactionButton } from "components/buttons/TransactionButton";
1111
import { useTrack } from "hooks/analytics/useTrack";
12-
import { CheckIcon, CircleIcon, ExternalLinkIcon, XIcon } from "lucide-react";
12+
import {
13+
CheckIcon,
14+
CircleAlertIcon,
15+
CircleIcon,
16+
ExternalLinkIcon,
17+
XIcon,
18+
} from "lucide-react";
1319
import { useTheme } from "next-themes";
1420
import Link from "next/link";
1521
import { useState } from "react";
@@ -34,6 +40,7 @@ import {
3440
} from "thirdweb/react";
3541
import { getClaimParams, maxUint256 } from "thirdweb/utils";
3642
import { tryCatch } from "utils/try-catch";
43+
import { ToolTipLabel } from "../../../../../../../../../../@/components/ui/tooltip";
3744
import { getSDKTheme } from "../../../../../../../../components/sdk-component-theme";
3845
import { PublicPageConnectButton } from "../../../_components/PublicPageConnectButton";
3946
import { getCurrencyMeta } from "../../_utils/getCurrencyMeta";
@@ -216,23 +223,23 @@ export function ClaimTokenCardUI(props: {
216223
},
217224
});
218225

226+
const publicPrice = {
227+
pricePerTokenWei: props.claimCondition.pricePerToken,
228+
currencyAddress: props.claimCondition.currency,
229+
decimals: props.claimConditionCurrency.decimals,
230+
symbol: props.claimConditionCurrency.symbol,
231+
};
232+
219233
const claimParamsQuery = useQuery({
220234
queryKey: ["claim-params", props.contract.address, account?.address],
221235
queryFn: async () => {
222-
const defaultPricing = {
223-
pricePerTokenWei: props.claimCondition.pricePerToken,
224-
currencyAddress: props.claimCondition.currency,
225-
decimals: props.claimConditionCurrency.decimals,
226-
symbol: props.claimConditionCurrency.symbol,
227-
};
228-
229236
if (!account) {
230-
return defaultPricing;
237+
return publicPrice;
231238
}
232239

233240
const merkleRoot = props.claimCondition.merkleRoot;
234241
if (!merkleRoot || merkleRoot === padHex("0x", { size: 32 })) {
235-
return defaultPricing;
242+
return publicPrice;
236243
}
237244

238245
const claimParams = await getClaimParams({
@@ -307,6 +314,11 @@ export function ClaimTokenCardUI(props: {
307314
);
308315
}
309316

317+
const isShowingCustomPrice =
318+
claimParamsData &&
319+
(claimParamsData.pricePerTokenWei !== publicPrice.pricePerTokenWei ||
320+
claimParamsData.currencyAddress !== publicPrice.currencyAddress);
321+
310322
return (
311323
<div className="rounded-xl border bg-card ">
312324
<div className="border-b px-4 py-5 lg:px-5">
@@ -342,25 +354,22 @@ export function ClaimTokenCardUI(props: {
342354

343355
<div className="space-y-3 rounded-lg bg-muted/50 p-3">
344356
{/* Price per token */}
345-
<div className="flex justify-between font-medium text-sm">
346-
<span>Price per token</span>
347-
348-
<SkeletonContainer
349-
skeletonData={`0.00 ${props.claimConditionCurrency.symbol}`}
350-
loadedData={
351-
claimParamsData
352-
? claimParamsData.pricePerTokenWei === 0n
353-
? "FREE"
354-
: `${toTokens(
355-
claimParamsData.pricePerTokenWei,
356-
claimParamsData.decimals,
357-
)} ${claimParamsData.symbol}`
358-
: undefined
359-
}
360-
render={(v) => {
361-
return <span className="">{v}</span>;
362-
}}
363-
/>
357+
<div className="flex items-start justify-between font-medium text-sm">
358+
<span className="flex items-center gap-2">
359+
Price per token
360+
{isShowingCustomPrice && (
361+
<ToolTipLabel label="Your connected wallet address is added in the allowlist and is getting a special price">
362+
<CircleAlertIcon className="size-3.5 text-muted-foreground" />
363+
</ToolTipLabel>
364+
)}
365+
</span>
366+
367+
<div className="flex flex-col items-end gap-1">
368+
{isShowingCustomPrice && (
369+
<TokenPrice data={publicPrice} strikethrough={true} />
370+
)}
371+
<TokenPrice data={claimParamsData} strikethrough={false} />
372+
</div>
364373
</div>
365374

366375
{/* Quantity */}
@@ -441,6 +450,43 @@ export function ClaimTokenCardUI(props: {
441450
);
442451
}
443452

453+
function TokenPrice(props: {
454+
strikethrough: boolean;
455+
data:
456+
| {
457+
pricePerTokenWei: bigint;
458+
decimals: number;
459+
symbol: string;
460+
}
461+
| undefined;
462+
}) {
463+
return (
464+
<SkeletonContainer
465+
skeletonData={"0.00 ETH"}
466+
loadedData={
467+
props.data
468+
? props.data.pricePerTokenWei === 0n
469+
? "FREE"
470+
: `${toTokens(
471+
props.data.pricePerTokenWei,
472+
props.data.decimals,
473+
)} ${props.data.symbol}`
474+
: undefined
475+
}
476+
render={(v) => {
477+
if (props.strikethrough) {
478+
return (
479+
<s className="font-medium text-muted-foreground text-sm line-through decoration-muted-foreground/50">
480+
{v}
481+
</s>
482+
);
483+
}
484+
return <span className="font-medium text-foreground text-sm">{v}</span>;
485+
}}
486+
/>
487+
);
488+
}
489+
444490
function SupplyRemaining(props: {
445491
supplyClaimed: bigint;
446492
maxClaimableSupply: bigint;

0 commit comments

Comments
 (0)