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,33 @@ export const NFTRevealButton: React.FC<NFTRevealButtonProps> = ({
67
89
) ;
68
90
}
69
91
92
+ const onSubmit = ( data : RevealFormData ) => {
93
+ const tx = reveal ( {
94
+ batchId : BigInt ( data . batchId ) ,
95
+ contract,
96
+ password : data . password ,
97
+ } ) ;
98
+
99
+ const promise = 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
+ toast . promise ( promise , {
113
+ error : "Failed to reveal batch" ,
114
+ loading : "Revealing batch" ,
115
+ success : "Batch revealed successfully" ,
116
+ } ) ;
117
+ } ;
118
+
70
119
return (
71
120
< MinterOnly contract = { contract } >
72
121
< Sheet onOpenChange = { setOpen } open = { open } >
@@ -75,80 +124,80 @@ export const NFTRevealButton: React.FC<NFTRevealButtonProps> = ({
75
124
< EyeIcon className = "size-4" /> Reveal NFTs
76
125
</ Button >
77
126
</ SheetTrigger >
78
- < SheetContent className = "w-full overflow-y-auto sm:min-w-[540px] lg:min -w-[700px] " >
127
+ < SheetContent className = "! w-full lg:!max -w-lg " >
79
128
< SheetHeader >
80
129
< SheetTitle className = "text-left" > Reveal batch</ SheetTitle >
81
130
</ 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"
131
+ < Form { ...form } >
132
+ < form
133
+ className = "mt-4 space-y-6"
134
+ onSubmit = { form . handleSubmit ( onSubmit ) }
146
135
>
147
- Reveal NFTs
148
- </ TransactionButton >
149
- </ div >
136
+ < FormField
137
+ control = { form . control }
138
+ name = "batchId"
139
+ render = { ( { field } ) => (
140
+ < FormItem >
141
+ < FormLabel > Select a batch</ FormLabel >
142
+ < Select onValueChange = { field . onChange } value = { field . value } >
143
+ < FormControl >
144
+ < SelectTrigger className = "bg-card" >
145
+ < SelectValue placeholder = "Select a batch" />
146
+ </ SelectTrigger >
147
+ </ FormControl >
148
+ < SelectContent >
149
+ { batchesQuery . data . map ( ( batch ) => (
150
+ < SelectItem
151
+ disabled = { batch . batchUri === "0x" }
152
+ key = { batch . batchId . toString ( ) }
153
+ value = { batch . batchId . toString ( ) }
154
+ >
155
+ { batch . placeholderMetadata ?. name ||
156
+ batch . batchId . toString ( ) } { " " }
157
+ { batch . batchUri === "0x" && "(REVEALED)" }
158
+ </ SelectItem >
159
+ ) ) }
160
+ </ SelectContent >
161
+ </ Select >
162
+ < FormMessage />
163
+ </ FormItem >
164
+ ) }
165
+ />
166
+ < FormField
167
+ control = { form . control }
168
+ name = "password"
169
+ render = { ( { field } ) => (
170
+ < FormItem >
171
+ < FormLabel > Password</ FormLabel >
172
+ < FormControl >
173
+ < Input
174
+ { ...field }
175
+ placeholder = "The one you used to upload this batch"
176
+ type = "password"
177
+ className = "bg-card"
178
+ />
179
+ </ FormControl >
180
+ < FormMessage />
181
+ </ FormItem >
182
+ ) }
183
+ />
184
+
185
+ < div className = "flex justify-end" >
186
+ < TransactionButton
187
+ client = { contract . client }
188
+ isLoggedIn = { isLoggedIn }
189
+ isPending = { sendTxMutation . isPending }
190
+ transactionCount = { 1 }
191
+ txChainID = { contract . chain . id }
192
+ type = "submit"
193
+ >
194
+ Reveal NFTs
195
+ </ TransactionButton >
196
+ </ div >
197
+ </ form >
198
+ </ Form >
150
199
</ SheetContent >
151
200
</ Sheet >
152
201
</ MinterOnly >
153
202
) ;
154
- } ;
203
+ }
0 commit comments