Skip to content

Commit 7bb7107

Browse files
committed
[TOOL-2876] Improve Transaction error toast messages (#5853)
## Problem solved Short description of the bug fixed or feature added <!-- start pr-codex --> --- ## PR-Codex overview This PR focuses on enhancing user feedback for NFT and token transactions by integrating `useTxNotifications` for success and error notifications across various components. ### Detailed summary - Added `useTxNotifications` to multiple components for transaction feedback. - Replaced toast notifications with `onSuccess` and `onError` methods from `useTxNotifications`. - Updated success and error messages for lazy minting, airdropping, minting, claiming, and listing NFTs/tokens. > ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}` <!-- end pr-codex -->
1 parent 84d3dc4 commit 7bb7107

File tree

10 files changed

+119
-98
lines changed

10 files changed

+119
-98
lines changed

apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/(marketplace)/components/list-form.tsx

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import { CurrencySelector } from "components/shared/CurrencySelector";
1818
import { SolidityInput } from "contract-ui/components/solidity-inputs";
1919
import { useTrack } from "hooks/analytics/useTrack";
2020
import { useAllChainsData } from "hooks/chains/allChains";
21+
import { useTxNotifications } from "hooks/useTxNotifications";
2122
import { isAlchemySupported } from "lib/wallet/nfts/alchemy";
2223
import { isMoralisSupported } from "lib/wallet/nfts/moralis";
2324
import { isSimpleHashSupported } from "lib/wallet/nfts/simpleHash";
@@ -125,6 +126,15 @@ export const CreateListingsForm: React.FC<CreateListingsFormProps> = ({
125126
walletAddress: account?.address,
126127
});
127128
const sendAndConfirmTx = useSendAndConfirmTransaction();
129+
const listingNotifications = useTxNotifications(
130+
"NFT listed Successfully",
131+
"Failed to list NFT",
132+
);
133+
134+
const auctionNotifications = useTxNotifications(
135+
"Auction created successfully",
136+
"Failed to create an auction",
137+
);
128138

129139
const form = useForm<ListForm>({
130140
defaultValues:
@@ -351,14 +361,11 @@ export const CreateListingsForm: React.FC<CreateListingsFormProps> = ({
351361
endTimestamp,
352362
});
353363

354-
const promise = sendAndConfirmTx.mutateAsync(transaction, {
364+
await sendAndConfirmTx.mutateAsync(transaction, {
355365
onSuccess: () => setOpen(false),
356366
});
357-
toast.promise(promise, {
358-
loading: "Listing NFT",
359-
success: "NFT listed successfully",
360-
error: "Failed to list NFT",
361-
});
367+
368+
listingNotifications.onSuccess();
362369
} else if (formData.listingType === "auction") {
363370
let minimumBidAmountWei: bigint;
364371
let buyoutBidAmountWei: bigint;
@@ -403,7 +410,7 @@ export const CreateListingsForm: React.FC<CreateListingsFormProps> = ({
403410
buyoutBidAmountWei: buyoutBidAmountWei * selectedQuantity,
404411
});
405412

406-
const promise = sendAndConfirmTx.mutateAsync(transaction, {
413+
await sendAndConfirmTx.mutateAsync(transaction, {
407414
onSuccess: () => {
408415
trackEvent({
409416
category: "marketplace",
@@ -423,15 +430,15 @@ export const CreateListingsForm: React.FC<CreateListingsFormProps> = ({
423430
});
424431
},
425432
});
426-
toast.promise(promise, {
427-
loading: "Creating auction",
428-
success: "Auction created successfully",
429-
error: "Failed to create auction",
430-
});
433+
auctionNotifications.onSuccess();
431434
}
432435
} catch (err) {
433436
console.error(err);
434-
toast.error("Failed to list NFT");
437+
if (formData.listingType === "auction") {
438+
auctionNotifications.onError(err);
439+
} else {
440+
listingNotifications.onError(err);
441+
}
435442
}
436443

437444
setIsFormLoading(false);

apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/[tokenId]/components/airdrop-tab.tsx

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import { cn } from "@/lib/utils";
1212
import type { Account } from "@3rdweb-sdk/react/hooks/useApi";
1313
import { TransactionButton } from "components/buttons/TransactionButton";
1414
import { useTrack } from "hooks/analytics/useTrack";
15+
import { useTxNotifications } from "hooks/useTxNotifications";
1516
import { UploadIcon } from "lucide-react";
1617
import { useState } from "react";
1718
import { useForm } from "react-hook-form";
@@ -49,6 +50,10 @@ const AirdropTab: React.FC<AirdropTabProps> = ({
4950
const sendAndConfirmTx = useSendAndConfirmTransaction();
5051
const addresses = watch("addresses");
5152
const [open, setOpen] = useState(false);
53+
const airdropNotifications = useTxNotifications(
54+
"NFTs airdropped successfully",
55+
"Failed to airdrop NFTs",
56+
);
5257

5358
return (
5459
<div className="flex w-full flex-col gap-2">
@@ -86,7 +91,7 @@ const AirdropTab: React.FC<AirdropTabProps> = ({
8691
}),
8792
);
8893
const transaction = multicall({ contract, data });
89-
const promise = sendAndConfirmTx.mutateAsync(transaction, {
94+
await sendAndConfirmTx.mutateAsync(transaction, {
9095
onSuccess: () => {
9196
trackEvent({
9297
category: "nft",
@@ -108,14 +113,11 @@ const AirdropTab: React.FC<AirdropTabProps> = ({
108113
});
109114
},
110115
});
111-
toast.promise(promise, {
112-
loading: "Airdropping NFTs",
113-
success: "Airdropped successfully",
114-
error: "Failed to airdrop",
115-
});
116+
117+
airdropNotifications.onSuccess();
116118
} catch (err) {
117119
console.error(err);
118-
toast.error("Failed to airdrop NFTs");
120+
airdropNotifications.onError(err);
119121
}
120122
})}
121123
>

apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/[tokenId]/components/update-metadata-form.tsx

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import { PropertiesFormControl } from "components/contract-pages/forms/propertie
1818
import { FileInput } from "components/shared/FileInput";
1919
import { useTrack } from "hooks/analytics/useTrack";
2020
import { useImageFileOrUrl } from "hooks/useImageFileOrUrl";
21+
import { useTxNotifications } from "hooks/useTxNotifications";
2122
import { type Dispatch, type SetStateAction, useMemo } from "react";
2223
import { useForm } from "react-hook-form";
2324
import { toast } from "sonner";
@@ -166,12 +167,16 @@ export const UpdateNftMetadata: React.FC<UpdateNftMetadataForm> = ({
166167
watch("animation_url") instanceof File ||
167168
watch("external_url") instanceof File;
168169
const sendAndConfirmTx = useSendAndConfirmTransaction();
170+
const updateMetadataNotifications = useTxNotifications(
171+
"NFT metadata updated successfully",
172+
"Failed to update NFT metadata",
173+
);
169174

170175
return (
171176
<form
172177
className="flex flex-col gap-6"
173178
id={UPDATE_METADATA_FORM_ID}
174-
onSubmit={handleSubmit((data) => {
179+
onSubmit={handleSubmit(async (data) => {
175180
if (!address) {
176181
toast.error("Please connect your wallet to update metadata.");
177182
return;
@@ -217,7 +222,7 @@ export const UpdateNftMetadata: React.FC<UpdateNftMetadataForm> = ({
217222
tokenId: BigInt(nft.id),
218223
newMetadata,
219224
});
220-
const promise = sendAndConfirmTx.mutateAsync(transaction, {
225+
await sendAndConfirmTx.mutateAsync(transaction, {
221226
onSuccess: () => {
222227
trackEvent({
223228
category: "nft",
@@ -237,13 +242,10 @@ export const UpdateNftMetadata: React.FC<UpdateNftMetadataForm> = ({
237242
},
238243
});
239244

240-
toast.promise(promise, {
241-
error: "Failed to update NFT metadata",
242-
success: "NFT metadata updated successfully",
243-
});
245+
updateMetadataNotifications.onSuccess();
244246
} catch (err) {
245247
console.error(err);
246-
toast.error("Failed to update NFT metadata");
248+
updateMetadataNotifications.onError(err);
247249
}
248250
})}
249251
>

apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/components/claim-button.tsx

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import type { Account } from "@3rdweb-sdk/react/hooks/useApi";
1212
import { FormControl, Input } from "@chakra-ui/react";
1313
import { TransactionButton } from "components/buttons/TransactionButton";
1414
import { useTrack } from "hooks/analytics/useTrack";
15+
import { useTxNotifications } from "hooks/useTxNotifications";
1516
import { GemIcon } from "lucide-react";
1617
import { useState } from "react";
1718
import { useForm } from "react-hook-form";
@@ -46,6 +47,10 @@ export const NFTClaimButton: React.FC<NFTClaimButtonProps> = ({
4647
const sendAndConfirmTx = useSendAndConfirmTransaction();
4748
const account = useActiveAccount();
4849
const [open, setOpen] = useState(false);
50+
const claimNFTNotifications = useTxNotifications(
51+
"NFT claimed successfully",
52+
"Failed to claim NFT",
53+
);
4954

5055
return (
5156
<Sheet open={open} onOpenChange={setOpen}>
@@ -135,7 +140,7 @@ export const NFTClaimButton: React.FC<NFTClaimButtonProps> = ({
135140
await promise;
136141
}
137142

138-
const promise = sendAndConfirmTx.mutateAsync(transaction, {
143+
await sendAndConfirmTx.mutateAsync(transaction, {
139144
onSuccess: () => {
140145
trackEvent({
141146
category: "nft",
@@ -154,14 +159,10 @@ export const NFTClaimButton: React.FC<NFTClaimButtonProps> = ({
154159
},
155160
});
156161

157-
toast.promise(promise, {
158-
loading: "Claiming NFT(s)",
159-
success: "NFT(s) claimed successfully",
160-
error: "Failed to claim NFT(s)",
161-
});
162+
claimNFTNotifications.onSuccess();
162163
} catch (error) {
163164
console.error(error);
164-
toast.error((error as Error).message || "Error claiming NFT");
165+
claimNFTNotifications.onError(error);
165166
trackEvent({
166167
category: "nft",
167168
action: "claim",

apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/components/lazy-mint-form.tsx

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import { PropertiesFormControl } from "components/contract-pages/forms/propertie
1919
import { FileInput } from "components/shared/FileInput";
2020
import { useTrack } from "hooks/analytics/useTrack";
2121
import { useImageFileOrUrl } from "hooks/useImageFileOrUrl";
22+
import { useTxNotifications } from "hooks/useTxNotifications";
2223
import type { Dispatch, SetStateAction } from "react";
2324
import { useForm } from "react-hook-form";
2425
import { toast } from "sonner";
@@ -134,6 +135,11 @@ export const LazyMintNftForm: React.FC<LazyMintNftFormParams> = ({
134135
watch("animation_url") instanceof File ||
135136
watch("external_url") instanceof File;
136137

138+
const lazyMintNotifications = useTxNotifications(
139+
"NFT lazy minted successfully",
140+
"Failed to lazy mint NFT",
141+
);
142+
137143
return (
138144
<>
139145
<form
@@ -155,7 +161,7 @@ export const LazyMintNftForm: React.FC<LazyMintNftFormParams> = ({
155161
? lazyMint721({ contract, nfts })
156162
: lazyMint1155({ contract, nfts });
157163

158-
const promise = sendAndConfirmTx.mutateAsync(transaction, {
164+
await sendAndConfirmTx.mutateAsync(transaction, {
159165
onSuccess: () => {
160166
trackEvent({
161167
category: "nft",
@@ -174,14 +180,10 @@ export const LazyMintNftForm: React.FC<LazyMintNftFormParams> = ({
174180
},
175181
});
176182

177-
toast.promise(promise, {
178-
loading: "Lazy minting NFT",
179-
error: "Failed to lazy mint NFT",
180-
success: "Lazy minted successfully",
181-
});
183+
lazyMintNotifications.onSuccess();
182184
} catch (err) {
183185
console.error(err);
184-
toast.error("Failed to lazy mint NFT");
186+
lazyMintNotifications.onError(err);
185187
}
186188
})}
187189
>

apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/components/mint-form.tsx

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import { PropertiesFormControl } from "components/contract-pages/forms/propertie
1818
import { FileInput } from "components/shared/FileInput";
1919
import { useTrack } from "hooks/analytics/useTrack";
2020
import { useImageFileOrUrl } from "hooks/useImageFileOrUrl";
21+
import { useTxNotifications } from "hooks/useTxNotifications";
2122
import type { Dispatch, SetStateAction } from "react";
2223
import { useForm } from "react-hook-form";
2324
import { toast } from "sonner";
@@ -133,13 +134,17 @@ export const NFTMintForm: React.FC<NFTMintForm> = ({
133134
watch("external_url") instanceof File;
134135

135136
const sendAndConfirmTx = useSendAndConfirmTransaction();
137+
const nftMintNotifications = useTxNotifications(
138+
"NFT minted successfully",
139+
"Failed to mint NFT",
140+
);
136141

137142
return (
138143
<>
139144
<form
140145
className="mt-6 flex flex-col gap-6"
141146
id={MINT_FORM_ID}
142-
onSubmit={handleSubmit((data) => {
147+
onSubmit={handleSubmit(async (data) => {
143148
if (!address) {
144149
toast.error("Please connect your wallet to mint.");
145150
return;
@@ -166,7 +171,7 @@ export const NFTMintForm: React.FC<NFTMintForm> = ({
166171
nft,
167172
supply: BigInt(data.supply),
168173
});
169-
const promise = sendAndConfirmTx.mutateAsync(transaction, {
174+
await sendAndConfirmTx.mutateAsync(transaction, {
170175
onSuccess: () => {
171176
trackEvent({
172177
category: "nft",
@@ -186,14 +191,10 @@ export const NFTMintForm: React.FC<NFTMintForm> = ({
186191
},
187192
});
188193

189-
toast.promise(promise, {
190-
loading: "Minting NFT",
191-
success: "NFT minted successfully",
192-
error: "Failed to mint NFT",
193-
});
194+
nftMintNotifications.onSuccess();
194195
} catch (err) {
196+
nftMintNotifications.onError(err);
195197
console.error(err);
196-
toast.error("Failed to mint NFT");
197198
}
198199
})}
199200
>

apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/nfts/components/shared-metadata-form.tsx

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import { TransactionButton } from "components/buttons/TransactionButton";
1616
import { FileInput } from "components/shared/FileInput";
1717
import { useTrack } from "hooks/analytics/useTrack";
1818
import { useImageFileOrUrl } from "hooks/useImageFileOrUrl";
19+
import { useTxNotifications } from "hooks/useTxNotifications";
1920
import type { Dispatch, SetStateAction } from "react";
2021
import { useForm } from "react-hook-form";
2122
import { toast } from "sonner";
@@ -116,12 +117,17 @@ export const SharedMetadataForm: React.FC<{
116117
watch("animation_url") instanceof File ||
117118
watch("external_url") instanceof File;
118119

120+
const setSharedMetaNotifications = useTxNotifications(
121+
"Shared metadata updated successfully",
122+
"Failed to update shared metadata",
123+
);
124+
119125
return (
120126
<>
121127
<form
122128
className="mt-6 flex flex-col gap-6"
123129
id={SHARED_METADATA_FORM_ID}
124-
onSubmit={handleSubmit((data) => {
130+
onSubmit={handleSubmit(async (data) => {
125131
if (!address) {
126132
toast.error("Please connect your wallet.");
127133
return;
@@ -143,7 +149,7 @@ export const SharedMetadataForm: React.FC<{
143149
contract,
144150
nft: parseAttributes(dataWithCustom),
145151
});
146-
const promise = sendAndConfirmTx.mutateAsync(transaction, {
152+
await sendAndConfirmTx.mutateAsync(transaction, {
147153
onSuccess: () => {
148154
trackEvent({
149155
category: "nft",
@@ -163,14 +169,10 @@ export const SharedMetadataForm: React.FC<{
163169
},
164170
});
165171

166-
toast.promise(promise, {
167-
loading: "Setting shared metadata",
168-
error: "Error setting NFT metadata",
169-
success: "Shared metadata updated successfully",
170-
});
172+
setSharedMetaNotifications.onSuccess();
171173
} catch (err) {
172174
console.error(err);
173-
toast.error("Failed to set shared metadata");
175+
setSharedMetaNotifications.onError(err);
174176
}
175177
})}
176178
>

0 commit comments

Comments
 (0)