Skip to content

Commit 543b68f

Browse files
committed
UI adjustments and cleanup
1 parent e3ec814 commit 543b68f

File tree

6 files changed

+465
-456
lines changed

6 files changed

+465
-456
lines changed
Lines changed: 88 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -1,74 +1,87 @@
1+
"use client";
2+
13
import {
24
Form,
35
FormControl,
46
FormField,
57
FormItem,
68
FormLabel,
9+
FormMessage,
710
} from "@/components/ui/form";
811
import { Input } from "@/components/ui/input";
912
import { Skeleton } from "@/components/ui/skeleton";
1013
import { zodResolver } from "@hookform/resolvers/zod";
1114
import { useMutation } from "@tanstack/react-query";
15+
import { useCallback } from "react";
1216
import { useForm } from "react-hook-form";
1317
import { toast } from "sonner";
14-
import { type ContractOptions, waitForReceipt } from "thirdweb";
18+
import { isAddress, sendAndConfirmTransaction } from "thirdweb";
1519
import { MintableERC721 } from "thirdweb/modules";
16-
import { useReadContract, useSendTransaction } from "thirdweb/react";
20+
import { useReadContract } from "thirdweb/react";
1721
import { z } from "zod";
1822
import { ModuleCardUI, type ModuleCardUIProps } from "./module-card";
23+
import type { ModuleInstanceProps } from "./module-instance";
1924

2025
const formSchema = z.object({
21-
primarySaleRecipient: z.string(),
26+
primarySaleRecipient: z.string().refine(
27+
(v) => {
28+
// don't return isAddress(v) directly to avoid typecasting to `0x${string}`
29+
if (isAddress(v)) {
30+
return true;
31+
}
32+
return false;
33+
},
34+
{
35+
message: "Invalid Address",
36+
},
37+
),
2238
});
2339

2440
export type MintableModuleFormValues = z.infer<typeof formSchema>;
2541

26-
export function MintableModule(
27-
props: Omit<ModuleCardUIProps, "children"> & {
28-
contract: ContractOptions;
29-
isOwnerAccount: boolean;
30-
},
31-
) {
32-
const { contract } = props;
33-
const { mutateAsync: sendTransaction } = useSendTransaction();
34-
const { data: primarySaleRecipient, isLoading } = useReadContract(
42+
function MintableModule(props: ModuleInstanceProps) {
43+
const { contract, ownerAccount } = props;
44+
45+
const primarySaleRecipientQuery = useReadContract(
3546
MintableERC721.getSaleConfig,
3647
{
37-
contract,
48+
contract: contract,
3849
},
3950
);
4051

41-
async function update(values: MintableModuleFormValues) {
42-
const setSaleConfigTransaction = MintableERC721.setSaleConfig({
43-
contract,
44-
primarySaleRecipient: values.primarySaleRecipient,
45-
});
52+
const update = useCallback(
53+
async (values: MintableModuleFormValues) => {
54+
if (!ownerAccount) {
55+
throw new Error("Not an owner account");
56+
}
4657

47-
const setSaleConfigTxResult = await sendTransaction(
48-
setSaleConfigTransaction,
49-
);
58+
const setSaleConfigTx = MintableERC721.setSaleConfig({
59+
contract: contract,
60+
primarySaleRecipient: values.primarySaleRecipient,
61+
});
5062

51-
try {
52-
await waitForReceipt(setSaleConfigTxResult);
53-
toast.success("Successfully updated primary sale recipient");
54-
} catch (_) {
55-
toast.error("Failed to update the primary sale recipient");
56-
}
57-
}
63+
await sendAndConfirmTransaction({
64+
account: ownerAccount,
65+
transaction: setSaleConfigTx,
66+
});
67+
},
68+
[contract, ownerAccount],
69+
);
5870

5971
return (
6072
<MintableModuleUI
61-
isPending={isLoading}
62-
primarySaleRecipient={primarySaleRecipient || ""}
63-
update={update}
6473
{...props}
74+
isPending={primarySaleRecipientQuery.isPending}
75+
primarySaleRecipient={primarySaleRecipientQuery.data}
76+
update={update}
77+
isOwnerAccount={!!ownerAccount}
6578
/>
6679
);
6780
}
6881

6982
export function MintableModuleUI(
7083
props: Omit<ModuleCardUIProps, "children" | "updateButton"> & {
71-
primarySaleRecipient: string;
84+
primarySaleRecipient: string | undefined;
7285
isPending: boolean;
7386
isOwnerAccount: boolean;
7487
update: (values: MintableModuleFormValues) => Promise<void>;
@@ -77,7 +90,7 @@ export function MintableModuleUI(
7790
const form = useForm<MintableModuleFormValues>({
7891
resolver: zodResolver(formSchema),
7992
values: {
80-
primarySaleRecipient: props.primarySaleRecipient,
93+
primarySaleRecipient: props.primarySaleRecipient || "",
8194
},
8295
reValidateMode: "onChange",
8396
});
@@ -87,47 +100,50 @@ export function MintableModuleUI(
87100
});
88101

89102
const onSubmit = async () => {
90-
const _values = form.getValues();
91-
const values = { ..._values };
92-
93-
updateMutation.mutate(values);
103+
const promise = updateMutation.mutateAsync(form.getValues());
104+
toast.promise(promise, {
105+
success: "Successfully updated primary sale recipient",
106+
error: "Failed to update primary sale recipient",
107+
});
94108
};
95109

96-
if (props.isPending) {
97-
return <Skeleton className="h-36" />;
98-
}
99-
100110
return (
101-
<ModuleCardUI
102-
{...props}
103-
updateButton={{
104-
onClick: onSubmit,
105-
isPending: updateMutation.isPending,
106-
isDisabled: !form.formState.isDirty,
107-
}}
108-
>
109-
<Form {...form}>
110-
<form onSubmit={form.handleSubmit(onSubmit)}>
111-
<div className="flex flex-col gap-4">
112-
<FormField
113-
control={form.control}
114-
name="primarySaleRecipient"
115-
render={({ field }) => (
116-
<FormItem className="flex flex-1 flex-col gap-3">
117-
<FormLabel>Primary Sale Recipient</FormLabel>
118-
<FormControl>
119-
<Input
120-
placeholder="0x..."
121-
{...field}
122-
disabled={!props.isOwnerAccount}
123-
/>
124-
</FormControl>
125-
</FormItem>
126-
)}
127-
/>
128-
</div>
129-
</form>
130-
</Form>
131-
</ModuleCardUI>
111+
<Form {...form}>
112+
<form onSubmit={form.handleSubmit(onSubmit)}>
113+
<ModuleCardUI
114+
{...props}
115+
updateButton={{
116+
isPending: updateMutation.isPending,
117+
isDisabled: !form.formState.isDirty,
118+
}}
119+
>
120+
{props.isPending && <Skeleton className="h-[74px]" />}
121+
122+
{!props.isPending && (
123+
<div className="flex flex-col gap-4">
124+
<FormField
125+
control={form.control}
126+
name="primarySaleRecipient"
127+
render={({ field }) => (
128+
<FormItem>
129+
<FormLabel>Primary Sale Recipient</FormLabel>
130+
<FormControl>
131+
<Input
132+
placeholder="0x..."
133+
{...field}
134+
disabled={!props.isOwnerAccount}
135+
/>
136+
</FormControl>
137+
<FormMessage />
138+
</FormItem>
139+
)}
140+
/>
141+
</div>
142+
)}
143+
</ModuleCardUI>
144+
</form>
145+
</Form>
132146
);
133147
}
148+
149+
export default MintableModule;

0 commit comments

Comments
 (0)