Skip to content

Commit f5dce62

Browse files
committed
Dashboard: Migrate contract/account from chakra to tailwind
1 parent c8b58f6 commit f5dce62

File tree

5 files changed

+137
-162
lines changed

5 files changed

+137
-162
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,3 @@
1-
import { Flex, SimpleGrid, useBreakpointValue } from "@chakra-ui/react";
2-
import { Card } from "chakra/card";
3-
import { Heading } from "chakra/heading";
4-
import { Text } from "chakra/text";
51
import { formatDistance } from "date-fns";
62
import type { ThirdwebClient } from "thirdweb";
73
import { useActiveAccount } from "thirdweb/react";
@@ -22,15 +18,14 @@ interface AccountSignerProps {
2218
client: ThirdwebClient;
2319
}
2420

25-
export const AccountSigner: React.FC<AccountSignerProps> = ({
21+
export function AccountSigner({
2622
item,
2723
contractChainId,
2824
client,
29-
}) => {
25+
}: AccountSignerProps) {
3026
const address = useActiveAccount()?.address;
3127
const { idToChain } = useAllChainsData();
3228
const chain = contractChainId ? idToChain.get(contractChainId) : undefined;
33-
const isMobile = useBreakpointValue({ base: true, md: false });
3429
const {
3530
isAdmin,
3631
signer,
@@ -39,58 +34,49 @@ export const AccountSigner: React.FC<AccountSignerProps> = ({
3934
endTimestamp,
4035
} = item;
4136
return (
42-
<Card p={8} position="relative">
43-
<Flex direction="column" gap={8}>
44-
<Flex flexDir="column" gap={2} mt={{ base: 4, md: 0 }}>
45-
<Flex
46-
alignItems="center"
47-
flexDir={{ base: "column", lg: "row" }}
48-
gap={3}
49-
>
50-
<Heading size="label.lg">
51-
<WalletAddress
52-
address={signer}
53-
client={client}
54-
shortenAddress={isMobile}
55-
/>
56-
</Heading>
57-
<div className="flex flex-row gap-2">
58-
{isAdmin ? <Badge>Admin Key</Badge> : <Badge>Scoped key</Badge>}
59-
{signer === address && (
60-
<Badge variant="success">Currently connected</Badge>
61-
)}
62-
</div>
63-
</Flex>
64-
</Flex>
37+
<div className="p-4 rounded-lg bg-card border lg:p-6">
38+
<div className="flex lg:items-center lg:justify-between items-start flex-col lg:flex-row gap-4">
39+
<WalletAddress
40+
address={signer}
41+
client={client}
42+
className="h-auto py-1"
43+
iconClassName="size-5"
44+
/>
45+
<div className="flex flex-row gap-2">
46+
{isAdmin ? <Badge>Admin Key</Badge> : <Badge>Scoped key</Badge>}
47+
{signer === address && (
48+
<Badge variant="secondary">Currently connected</Badge>
49+
)}
50+
</div>
51+
</div>
6552

66-
{isAdmin ? null : (
67-
<SimpleGrid columns={{ base: 2, md: 4 }} gap={2}>
68-
<div className="flex flex-col">
69-
<Text fontWeight="bold">Maximum value per transaction</Text>
70-
<Text textTransform="capitalize">
71-
{nativeTokenLimitPerTransaction.toString()}{" "}
72-
{chain?.nativeCurrency.symbol}
73-
</Text>
74-
</div>
75-
<div className="flex flex-col">
76-
<Text fontWeight="bold">Approved targets</Text>
77-
<Text textTransform="capitalize">{approvedTargets.length}</Text>
78-
</div>
79-
<div className="flex flex-col">
80-
<Text fontWeight="bold">Expiration</Text>
81-
<Text>
82-
{formatDistance(
83-
new Date(new Date(Number(endTimestamp * 1000n))),
84-
new Date(),
85-
{
86-
addSuffix: true,
87-
},
88-
)}
89-
</Text>
90-
</div>
91-
</SimpleGrid>
92-
)}
93-
</Flex>
94-
</Card>
53+
<div className="flex flex-col lg:flex-row gap-4 lg:gap-16 border-t pt-4 mt-6 lg:mt-4 border-dashed">
54+
<div className="space-y-0.5 text-sm">
55+
<div className="font-medium">Maximum value per transaction</div>
56+
<div className="capitalize">
57+
{nativeTokenLimitPerTransaction.toString()}{" "}
58+
{chain?.nativeCurrency.symbol}
59+
</div>
60+
</div>
61+
62+
<div className="space-y-0.5 text-sm">
63+
<div className="font-medium">Approved targets</div>
64+
<div className="capitalize">{approvedTargets.length}</div>
65+
</div>
66+
67+
<div className="space-y-0.5 text-sm">
68+
<div className="font-medium">Expiration</div>
69+
<div>
70+
{formatDistance(
71+
new Date(new Date(Number(endTimestamp * 1000n))),
72+
new Date(),
73+
{
74+
addSuffix: true,
75+
},
76+
)}
77+
</div>
78+
</div>
79+
</div>
80+
</div>
9581
);
96-
};
82+
}
Lines changed: 29 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,58 +1,58 @@
11
"use client";
22

3-
import { Heading } from "chakra/heading";
43
import type { ThirdwebContract } from "thirdweb";
54
import type { ChainMetadata } from "thirdweb/chains";
65
import type { ProjectMeta } from "../../../../../team/[team_slug]/[project_slug]/contract/[chainIdOrSlug]/[contractAddress]/types";
76
import { AccountBalance } from "./components/account-balance";
87
import { DepositNative } from "./components/deposit-native";
98
import { NftsOwned } from "./components/nfts-owned";
109

11-
interface AccountPageProps {
10+
export function AccountPage(props: {
1211
contract: ThirdwebContract;
1312
chainMetadata: ChainMetadata;
1413
isLoggedIn: boolean;
1514
isInsightSupported: boolean;
1615
projectMeta: ProjectMeta | undefined;
17-
}
18-
19-
export const AccountPage: React.FC<AccountPageProps> = ({
20-
contract,
21-
chainMetadata,
22-
isLoggedIn,
23-
isInsightSupported,
24-
projectMeta,
25-
}) => {
26-
const symbol = chainMetadata.nativeCurrency.symbol || "Native Token";
16+
}) {
17+
const {
18+
contract,
19+
chainMetadata,
20+
isLoggedIn,
21+
isInsightSupported,
22+
projectMeta,
23+
} = props;
24+
const symbol = chainMetadata.nativeCurrency.symbol;
2725

2826
return (
29-
<div className="flex flex-col gap-6">
30-
<div className="flex flex-row items-center justify-between">
31-
<Heading size="title.sm">Balances</Heading>
32-
</div>
33-
<AccountBalance contract={contract} />
34-
<div className="flex flex-row items-center justify-between">
35-
<Heading size="title.sm">Deposit {symbol}</Heading>
27+
<div className="space-y-6">
28+
<div>
29+
<h2 className="text-lg font-semibold tracking-tight mb-2">Balances</h2>
30+
<AccountBalance contract={contract} />
3631
</div>
3732

38-
{chainMetadata && (
33+
<div>
34+
<h3 className="text-lg font-semibold tracking-tight mb-2">
35+
Deposit {symbol}
36+
</h3>
3937
<DepositNative
4038
address={contract.address}
4139
chain={chainMetadata}
4240
client={contract.client}
4341
isLoggedIn={isLoggedIn}
4442
symbol={symbol}
4543
/>
46-
)}
44+
</div>
4745

48-
<div className="flex flex-row items-center justify-between">
49-
<Heading size="title.sm">NFTs owned</Heading>
46+
<div>
47+
<h3 className="text-lg font-semibold tracking-tight mb-1">
48+
NFTs owned
49+
</h3>
50+
<NftsOwned
51+
contract={contract}
52+
isInsightSupported={isInsightSupported}
53+
projectMeta={projectMeta}
54+
/>
5055
</div>
51-
<NftsOwned
52-
contract={contract}
53-
isInsightSupported={isInsightSupported}
54-
projectMeta={projectMeta}
55-
/>
5656
</div>
5757
);
58-
};
58+
}
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,37 @@
11
"use client";
22

3-
import { SimpleGrid, Stat, StatLabel, StatNumber } from "@chakra-ui/react";
4-
import { Card } from "chakra/card";
53
import type { ThirdwebContract } from "thirdweb";
64
import { useActiveWalletChain, useWalletBalance } from "thirdweb/react";
75
import { useSplitBalances } from "@/hooks/useSplit";
6+
import { StatCard } from "../../overview/components/stat-card";
87

9-
interface AccountBalanceProps {
10-
contract: ThirdwebContract;
11-
}
12-
13-
export const AccountBalance: React.FC<AccountBalanceProps> = ({ contract }) => {
8+
export function AccountBalance(props: { contract: ThirdwebContract }) {
149
const activeChain = useActiveWalletChain();
1510
const { data: balance } = useWalletBalance({
16-
address: contract.address,
11+
address: props.contract.address,
1712
chain: activeChain,
18-
client: contract.client,
13+
client: props.contract.client,
1914
});
20-
const balanceQuery = useSplitBalances(contract);
15+
16+
const balanceQuery = useSplitBalances(props.contract);
2117

2218
return (
23-
<SimpleGrid columns={{ base: 2, md: 4 }} spacing={{ base: 3, md: 6 }}>
24-
<Card as={Stat}>
25-
<StatLabel mb={{ base: 1, md: 0 }}>{balance?.symbol}</StatLabel>
26-
<StatNumber>{balance?.displayValue}</StatNumber>
27-
</Card>
19+
<div className="grid grid-cols-2 gap-3 md:grid-cols-3">
20+
<StatCard
21+
label={balance?.symbol || ""}
22+
value={balance?.displayValue || ""}
23+
isPending={balanceQuery.isPending}
24+
/>
2825
{balanceQuery?.data
2926
?.filter((bl) => bl.name !== "Native Token")
3027
.map((bl) => (
31-
<Card as={Stat} key={bl.symbol}>
32-
<StatLabel mb={{ base: 1, md: 0 }}>{bl.symbol}</StatLabel>
33-
<StatNumber>{bl.display_balance}</StatNumber>
34-
</Card>
28+
<StatCard
29+
key={bl.symbol}
30+
label={bl.symbol}
31+
value={bl.display_balance}
32+
isPending={false}
33+
/>
3534
))}
36-
</SimpleGrid>
35+
</div>
3736
);
38-
};
37+
}
Original file line numberDiff line numberDiff line change
@@ -1,82 +1,68 @@
11
"use client";
22

3-
import { Card } from "chakra/card";
4-
import { type ChangeEvent, useState } from "react";
3+
import { ArrowUpRightIcon } from "lucide-react";
4+
import { useState } from "react";
5+
import { toast } from "sonner";
56
import { prepareTransaction, type ThirdwebClient, toWei } from "thirdweb";
7+
import type { ChainMetadata } from "thirdweb/chains";
68
import { useSendAndConfirmTransaction } from "thirdweb/react";
79
import { TransactionButton } from "@/components/tx-button";
810
import { Input } from "@/components/ui/input";
9-
import { useV5DashboardChain } from "@/hooks/chains/v5-adapter";
10-
import type { StoredChain } from "@/stores/chainStores";
11+
import { mapV4ChainToV5Chain } from "@/utils/map-chains";
1112

12-
interface DepositNativeProps {
13+
export function DepositNative(props: {
1314
address: string;
1415
symbol: string;
15-
chain: StoredChain;
16+
chain: ChainMetadata;
1617
isLoggedIn: boolean;
1718
client: ThirdwebClient;
18-
}
19-
20-
export const DepositNative: React.FC<DepositNativeProps> = ({
21-
address,
22-
symbol,
23-
chain,
24-
isLoggedIn,
25-
client,
26-
}) => {
27-
const { mutate: transfer, isPending } = useSendAndConfirmTransaction();
19+
}) {
20+
const sendTransaction = useSendAndConfirmTransaction();
2821
const [amount, setAmount] = useState("");
29-
const handleChange = (e: ChangeEvent<HTMLInputElement>) => {
30-
setAmount(e.currentTarget.value);
31-
};
32-
const v5Chain = useV5DashboardChain(chain.chainId);
3322

3423
return (
35-
<Card
36-
maxW={{ base: "100%", md: "49%" }}
37-
style={{
38-
alignItems: "center",
39-
display: "flex",
40-
flexDirection: "row",
41-
gap: 16,
42-
}}
43-
>
24+
<div className="flex flex-row items-center max-w-lg">
4425
<Input
45-
onChange={handleChange}
46-
placeholder={`Amount in ${symbol}. ex: 0.001`}
26+
onChange={(e) => setAmount(e.currentTarget.value)}
27+
placeholder="0.001"
4728
type="number"
29+
className="border-r-0 rounded-r-none bg-card"
4830
value={amount}
4931
/>
32+
5033
<TransactionButton
51-
client={client}
52-
disabled={
53-
amount.length === 0 || Number.parseFloat(amount) <= 0 || !address
54-
}
55-
isLoggedIn={isLoggedIn}
56-
isPending={isPending}
34+
client={props.client}
35+
variant="default"
36+
disabled={amount.length === 0 || Number.parseFloat(amount) <= 0}
37+
isLoggedIn={props.isLoggedIn}
38+
className="border-l-0 rounded-l-none px-6"
39+
isPending={sendTransaction.isPending}
5740
onClick={() => {
58-
if (!address) {
59-
throw new Error("Invalid address");
60-
}
61-
6241
const transaction = prepareTransaction({
63-
chain: v5Chain,
64-
client,
65-
to: address,
42+
// eslint-disable-next-line no-restricted-syntax
43+
chain: mapV4ChainToV5Chain(props.chain),
44+
client: props.client,
45+
to: props.address,
6646
value: toWei(amount),
6747
});
68-
transfer(transaction, {
48+
sendTransaction.mutate(transaction, {
6949
onSuccess: () => {
50+
toast.success("Deposit successful");
7051
setAmount("");
7152
},
53+
onError: (error) => {
54+
toast.error("Deposit failed", {
55+
description: error.message,
56+
});
57+
},
7258
});
7359
}}
74-
style={{ minWidth: 160 }}
75-
transactionCount={1}
76-
txChainID={v5Chain.id}
60+
transactionCount={undefined}
61+
txChainID={props.chain.chainId}
7762
>
7863
Deposit
64+
<ArrowUpRightIcon className="w-4 h-4" />
7965
</TransactionButton>
80-
</Card>
66+
</div>
8167
);
82-
};
68+
}

0 commit comments

Comments
 (0)