Skip to content

Commit b87f2e1

Browse files
committed
added in transferable and mintable
1 parent 939e7ab commit b87f2e1

File tree

5 files changed

+760
-1
lines changed

5 files changed

+760
-1
lines changed
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
import {
2+
Form,
3+
FormControl,
4+
FormField,
5+
FormItem,
6+
FormLabel,
7+
} from "@/components/ui/form";
8+
import { Input } from "@/components/ui/input";
9+
import { Skeleton } from "@/components/ui/skeleton";
10+
import { zodResolver } from "@hookform/resolvers/zod";
11+
import { useMutation } from "@tanstack/react-query";
12+
import { useForm } from "react-hook-form";
13+
import { toast } from "sonner";
14+
import { type ContractOptions, waitForReceipt } from "thirdweb";
15+
import { MintableERC721 } from "thirdweb/modules";
16+
import { useReadContract, useSendTransaction } from "thirdweb/react";
17+
import { z } from "zod";
18+
import { ModuleCardUI, type ModuleCardUIProps } from "./module-card";
19+
20+
const formSchema = z.object({
21+
primarySaleRecipient: z.string(),
22+
});
23+
24+
export type MintableModuleFormValues = z.infer<typeof formSchema>;
25+
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(
35+
MintableERC721.getSaleConfig,
36+
{
37+
contract,
38+
},
39+
);
40+
41+
async function update(values: MintableModuleFormValues) {
42+
const setSaleConfigTransaction = MintableERC721.setSaleConfig({
43+
contract,
44+
primarySaleRecipient: values.primarySaleRecipient,
45+
});
46+
47+
const setSaleConfigTxResult = await sendTransaction(
48+
setSaleConfigTransaction,
49+
);
50+
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+
}
58+
59+
return (
60+
<MintableModuleUI
61+
isPending={isLoading}
62+
primarySaleRecipient={primarySaleRecipient || ""}
63+
update={update}
64+
{...props}
65+
/>
66+
);
67+
}
68+
69+
export function MintableModuleUI(
70+
props: Omit<ModuleCardUIProps, "children" | "updateButton"> & {
71+
primarySaleRecipient: string;
72+
isPending: boolean;
73+
isOwnerAccount: boolean;
74+
update: (values: MintableModuleFormValues) => Promise<void>;
75+
},
76+
) {
77+
const form = useForm<MintableModuleFormValues>({
78+
resolver: zodResolver(formSchema),
79+
values: {
80+
primarySaleRecipient: props.primarySaleRecipient,
81+
},
82+
reValidateMode: "onChange",
83+
});
84+
85+
const updateMutation = useMutation({
86+
mutationFn: props.update,
87+
});
88+
89+
const onSubmit = async () => {
90+
const _values = form.getValues();
91+
const values = { ..._values };
92+
93+
updateMutation.mutate(values);
94+
};
95+
96+
if (props.isPending) {
97+
return <Skeleton className="h-36" />;
98+
}
99+
100+
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>
132+
);
133+
}

0 commit comments

Comments
 (0)