1
1
"use client" ;
2
2
3
- import { FormControl , Input , Select } from "@chakra-ui/react" ;
4
- import { FormErrorMessage , FormLabel } from "chakra/form" ;
3
+ import { zodResolver } from "@hookform/resolvers/zod" ;
5
4
import { EyeIcon } from "lucide-react" ;
6
5
import { useState } from "react" ;
7
6
import { useForm } from "react-hook-form" ;
8
7
import { toast } from "sonner" ;
9
8
import type { ThirdwebContract } from "thirdweb" ;
10
9
import { getBatchesToReveal , reveal } from "thirdweb/extensions/erc721" ;
11
10
import { useReadContract , useSendAndConfirmTransaction } from "thirdweb/react" ;
11
+ import * as z from "zod" ;
12
12
import { MinterOnly } from "@/components/contracts/roles/minter-only" ;
13
13
import { TransactionButton } from "@/components/tx-button" ;
14
14
import { Button } from "@/components/ui/button" ;
15
+ import {
16
+ Form ,
17
+ FormControl ,
18
+ FormField ,
19
+ FormItem ,
20
+ FormLabel ,
21
+ FormMessage ,
22
+ } from "@/components/ui/form" ;
23
+ import { Input } from "@/components/ui/input" ;
24
+ import {
25
+ Select ,
26
+ SelectContent ,
27
+ SelectItem ,
28
+ SelectTrigger ,
29
+ SelectValue ,
30
+ } from "@/components/ui/select" ;
15
31
import {
16
32
Sheet ,
17
33
SheetContent ,
@@ -20,29 +36,35 @@ import {
20
36
SheetTrigger ,
21
37
} from "@/components/ui/sheet" ;
22
38
import { ToolTipLabel } from "@/components/ui/tooltip" ;
39
+ import { parseError } from "@/utils/errorParser" ;
23
40
24
- interface NFTRevealButtonProps {
25
- contract : ThirdwebContract ;
26
- isLoggedIn : boolean ;
27
- }
41
+ const revealFormSchema = z . object ( {
42
+ batchId : z . string ( ) . min ( 1 , "Please select a batch" ) ,
43
+ password : z . string ( ) . min ( 1 , "Password is required" ) ,
44
+ } ) ;
28
45
29
- const REVEAL_FORM_ID = "reveal-form" ;
46
+ type RevealFormData = z . infer < typeof revealFormSchema > ;
30
47
31
- export const NFTRevealButton : React . FC < NFTRevealButtonProps > = ( {
48
+ export function NFTRevealButton ( {
32
49
contract,
33
50
isLoggedIn,
34
- } ) => {
51
+ } : {
52
+ contract : ThirdwebContract ;
53
+ isLoggedIn : boolean ;
54
+ } ) {
35
55
const batchesQuery = useReadContract ( getBatchesToReveal , {
36
56
contract,
37
57
} ) ;
38
58
39
59
const sendTxMutation = useSendAndConfirmTransaction ( ) ;
40
60
41
- const {
42
- register,
43
- handleSubmit,
44
- formState : { errors, isDirty } ,
45
- } = useForm < { batchId : string ; password : string } > ( ) ;
61
+ const form = useForm < RevealFormData > ( {
62
+ resolver : zodResolver ( revealFormSchema ) ,
63
+ defaultValues : {
64
+ batchId : "" ,
65
+ password : "" ,
66
+ } ,
67
+ } ) ;
46
68
47
69
const [ open , setOpen ] = useState ( false ) ;
48
70
@@ -67,6 +89,27 @@ export const NFTRevealButton: React.FC<NFTRevealButtonProps> = ({
67
89
) ;
68
90
}
69
91
92
+ const onSubmit = async ( data : RevealFormData ) => {
93
+ const tx = reveal ( {
94
+ batchId : BigInt ( data . batchId ) ,
95
+ contract,
96
+ password : data . password ,
97
+ } ) ;
98
+
99
+ await sendTxMutation . mutateAsync ( tx , {
100
+ onError : ( error ) => {
101
+ toast . error ( "Failed to reveal batch" , {
102
+ description : parseError ( error ) ,
103
+ } ) ;
104
+ console . error ( error ) ;
105
+ } ,
106
+ onSuccess : ( ) => {
107
+ toast . success ( "Batch revealed successfully" ) ;
108
+ setOpen ( false ) ;
109
+ } ,
110
+ } ) ;
111
+ } ;
112
+
70
113
return (
71
114
< MinterOnly contract = { contract } >
72
115
< Sheet onOpenChange = { setOpen } open = { open } >
@@ -75,80 +118,80 @@ export const NFTRevealButton: React.FC<NFTRevealButtonProps> = ({
75
118
< EyeIcon className = "size-4" /> Reveal NFTs
76
119
</ Button >
77
120
</ SheetTrigger >
78
- < SheetContent className = "w-full overflow-y-auto sm:min-w-[540px] lg:min -w-[700px] " >
121
+ < SheetContent className = "! w-full lg:!max -w-lg " >
79
122
< SheetHeader >
80
123
< SheetTitle className = "text-left" > Reveal batch</ SheetTitle >
81
124
</ SheetHeader >
82
- < form
83
- className = "mt-10 flex flex-col gap-6"
84
- id = { REVEAL_FORM_ID }
85
- onSubmit = { handleSubmit ( ( data ) => {
86
- const tx = reveal ( {
87
- batchId : BigInt ( data . batchId ) ,
88
- contract,
89
- password : data . password ,
90
- } ) ;
91
-
92
- const promise = sendTxMutation . mutateAsync ( tx , {
93
- onError : ( error ) => {
94
- console . error ( error ) ;
95
- } ,
96
- onSuccess : ( ) => {
97
- setOpen ( false ) ;
98
- } ,
99
- } ) ;
100
-
101
- toast . promise ( promise , {
102
- error : "Failed to reveal batch" ,
103
- loading : "Revealing batch" ,
104
- success : "Batch revealed successfully" ,
105
- } ) ;
106
- } ) }
107
- >
108
- < FormControl isInvalid = { ! ! errors . password } isRequired mr = { 4 } >
109
- < FormLabel > Select a batch</ FormLabel >
110
- < Select { ...register ( "batchId" ) } autoFocus >
111
- { batchesQuery . data . map ( ( batch ) => (
112
- < option
113
- disabled = { batch . batchUri === "0x" }
114
- key = { batch . batchId . toString ( ) }
115
- value = { batch . batchId . toString ( ) }
116
- >
117
- { batch . placeholderMetadata ?. name ||
118
- batch . batchId . toString ( ) } { " " }
119
- { batch . batchUri === "0x" && "(REVEALED)" }
120
- </ option >
121
- ) ) }
122
- </ Select >
123
- < FormErrorMessage > { errors ?. password ?. message } </ FormErrorMessage >
124
- </ FormControl >
125
- < FormControl isInvalid = { ! ! errors . password } isRequired mr = { 4 } >
126
- < FormLabel > Password</ FormLabel >
127
- < Input
128
- { ...register ( "password" ) }
129
- autoFocus
130
- placeholder = "The one you used to upload this batch"
131
- type = "password"
132
- />
133
- < FormErrorMessage > { errors ?. password ?. message } </ FormErrorMessage >
134
- </ FormControl >
135
- </ form >
136
- < div className = "mt-4 flex justify-end" >
137
- < TransactionButton
138
- client = { contract . client }
139
- disabled = { ! isDirty }
140
- form = { REVEAL_FORM_ID }
141
- isLoggedIn = { isLoggedIn }
142
- isPending = { sendTxMutation . isPending }
143
- transactionCount = { 1 }
144
- txChainID = { contract . chain . id }
145
- type = "submit"
125
+ < Form { ...form } >
126
+ < form
127
+ className = "mt-4 space-y-6"
128
+ onSubmit = { form . handleSubmit ( onSubmit ) }
146
129
>
147
- Reveal NFTs
148
- </ TransactionButton >
149
- </ div >
130
+ < FormField
131
+ control = { form . control }
132
+ name = "batchId"
133
+ render = { ( { field } ) => (
134
+ < FormItem >
135
+ < FormLabel > Select a batch</ FormLabel >
136
+ < Select onValueChange = { field . onChange } value = { field . value } >
137
+ < FormControl >
138
+ < SelectTrigger className = "bg-card" >
139
+ < SelectValue placeholder = "Select a batch" />
140
+ </ SelectTrigger >
141
+ </ FormControl >
142
+ < SelectContent >
143
+ { batchesQuery . data . map ( ( batch ) => (
144
+ < SelectItem
145
+ disabled = { batch . batchUri === "0x" }
146
+ key = { batch . batchId . toString ( ) }
147
+ value = { batch . batchId . toString ( ) }
148
+ >
149
+ { batch . placeholderMetadata ?. name ||
150
+ batch . batchId . toString ( ) } { " " }
151
+ { batch . batchUri === "0x" && "(REVEALED)" }
152
+ </ SelectItem >
153
+ ) ) }
154
+ </ SelectContent >
155
+ </ Select >
156
+ < FormMessage />
157
+ </ FormItem >
158
+ ) }
159
+ />
160
+ < FormField
161
+ control = { form . control }
162
+ name = "password"
163
+ render = { ( { field } ) => (
164
+ < FormItem >
165
+ < FormLabel > Password</ FormLabel >
166
+ < FormControl >
167
+ < Input
168
+ { ...field }
169
+ placeholder = "The one you used to upload this batch"
170
+ type = "password"
171
+ className = "bg-card"
172
+ />
173
+ </ FormControl >
174
+ < FormMessage />
175
+ </ FormItem >
176
+ ) }
177
+ />
178
+
179
+ < div className = "flex justify-end" >
180
+ < TransactionButton
181
+ client = { contract . client }
182
+ isLoggedIn = { isLoggedIn }
183
+ isPending = { sendTxMutation . isPending }
184
+ transactionCount = { 1 }
185
+ txChainID = { contract . chain . id }
186
+ type = "submit"
187
+ >
188
+ Reveal NFTs
189
+ </ TransactionButton >
190
+ </ div >
191
+ </ form >
192
+ </ Form >
150
193
</ SheetContent >
151
194
</ Sheet >
152
195
</ MinterOnly >
153
196
) ;
154
- } ;
197
+ }
0 commit comments