11"use client" ;
22
3- import { FormControl , Input , Select , Skeleton , Spacer } from "@chakra-ui/react" ;
43import { useMutation , useQuery } from "@tanstack/react-query" ;
5- import { FormErrorMessage , FormLabel } from "chakra/form" ;
64import { useMemo } from "react" ;
75import { FormProvider , type UseFormReturn , useForm } from "react-hook-form" ;
86import { toast } from "sonner" ;
@@ -26,8 +24,18 @@ import {
2624 toFunctionSelector ,
2725} from "thirdweb/utils" ;
2826import type { Account } from "thirdweb/wallets" ;
27+ import { FormFieldSetup } from "@/components/blocks/FormFieldSetup" ;
2928import { TransactionButton } from "@/components/tx-button" ;
29+ import { Input } from "@/components/ui/input" ;
3030import { Spinner } from "@/components/ui/Spinner/Spinner" ;
31+ import {
32+ Select ,
33+ SelectContent ,
34+ SelectItem ,
35+ SelectTrigger ,
36+ SelectValue ,
37+ } from "@/components/ui/select" ;
38+ import { Skeleton } from "@/components/ui/skeleton" ;
3139import {
3240 useAllVersions ,
3341 usePublishedContractsQuery ,
@@ -65,7 +73,7 @@ export const InstallModuleForm = (props: InstallModuleFormProps) => {
6573 version : "latest" ,
6674 } ,
6775 } ) ;
68- const { register, watch, formState, resetField, reset } = form ;
76+ const { register, watch, formState, resetField, reset, setValue } = form ;
6977 const { contract, account } = props ;
7078 const { errors } = formState ;
7179
@@ -144,10 +152,6 @@ export const InstallModuleForm = (props: InstallModuleFormProps) => {
144152 installMutation . mutate ( ) ;
145153 } ;
146154
147- const moduleContractInputProps = register ( "moduleContract" , {
148- required : "Module name is required" ,
149- } ) ;
150-
151155 const selectedModule = modulesOnly ?. find (
152156 ( x ) => x . contractId === watch ( "moduleContract" ) ,
153157 ) ;
@@ -267,62 +271,65 @@ export const InstallModuleForm = (props: InstallModuleFormProps) => {
267271 } }
268272 >
269273 < div className = "grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-3" >
270- < FormControl isInvalid = { ! ! errors . publisherAddress } >
271- < FormLabel > Publisher</ FormLabel >
274+ < FormFieldSetup
275+ htmlFor = "publisherAddress"
276+ label = "Publisher"
277+ errorMessage = { errors . publisherAddress ?. message }
278+ isRequired = { true }
279+ >
272280 < Input
273- bg = "backgroundHighlight "
281+ id = "publisherAddress "
274282 disabled = { installMutation . isPending }
275283 placeholder = "Publisher address"
276284 { ...register ( "publisherAddress" , {
277285 required : "Publisher address is required" ,
278286 } ) }
279287 />
280- < FormErrorMessage >
281- { errors . publisherAddress ?. message }
282- </ FormErrorMessage >
283- </ FormControl >
284-
285- < FormControl
286- isInvalid = {
287- ! ! errors . moduleContract || isModuleCompatibleQuery . data === false
288+ </ FormFieldSetup >
289+
290+ < FormFieldSetup
291+ htmlFor = "moduleContract"
292+ label = "Module Name"
293+ errorMessage = {
294+ ! isModuleCompatibleQuery . isFetching &&
295+ isModuleCompatibleQuery . data === false
296+ ? "Module is not compatible"
297+ : errors . moduleContract ?. message
288298 }
289299 isRequired = { true }
290300 >
291- < FormLabel > Module Name</ FormLabel >
292- < Skeleton
293- borderRadius = "lg"
294- isLoaded = { ! ! modulesOnly . length || ! isFetching }
295- >
301+ { ! modulesOnly . length && isFetching ? (
302+ < Skeleton className = "h-10 w-full rounded-md" />
303+ ) : (
296304 < Select
297- bg = "backgroundHighlight"
298305 disabled = {
299306 installMutation . isPending ||
300307 modulesOnly ?. length === 0 ||
301308 isPending
302309 }
303- { ...moduleContractInputProps }
304- onChange = { ( e ) => {
310+ value = { watch ( "moduleContract" ) }
311+ onValueChange = { ( value ) => {
312+ setValue ( "moduleContract" , value ) ;
305313 // reset version when module changes
306314 resetField ( "version" ) ;
307- moduleContractInputProps . onChange ( e ) ;
308315 } }
309- placeholder = {
310- modulesOnly . length === 0 ? "No modules" : "Select module"
311- }
312316 >
313- { modulesOnly . map ( ( { contractId } ) => (
314- < option key = { contractId } value = { contractId } >
315- { contractId }
316- </ option >
317- ) ) }
317+ < SelectTrigger >
318+ < SelectValue
319+ placeholder = {
320+ modulesOnly . length === 0 ? "No modules" : "Select module"
321+ }
322+ />
323+ </ SelectTrigger >
324+ < SelectContent >
325+ { modulesOnly . map ( ( { contractId } ) => (
326+ < SelectItem key = { contractId } value = { contractId } >
327+ { contractId }
328+ </ SelectItem >
329+ ) ) }
330+ </ SelectContent >
318331 </ Select >
319- </ Skeleton >
320- < FormErrorMessage fontWeight = { 500 } >
321- { ! isModuleCompatibleQuery . isFetching &&
322- isModuleCompatibleQuery . data === false &&
323- "Module is not compatible" }
324- { errors . moduleContract ?. message }
325- </ FormErrorMessage >
332+ ) }
326333
327334 { isModuleCompatibleQuery . isFetching && selectedModule && (
328335 < div className = "mt-2 flex items-center gap-1.5 text-link-foreground" >
@@ -338,39 +345,52 @@ export const InstallModuleForm = (props: InstallModuleFormProps) => {
338345 </ p >
339346 </ div >
340347 ) }
341- </ FormControl >
348+ </ FormFieldSetup >
342349
343- < FormControl isInvalid = { ! ! errors . version } isRequired = { true } >
344- < FormLabel > Module Version</ FormLabel >
345- < Skeleton borderRadius = "lg" isLoaded = { ! allVersions . isFetching } >
350+ < FormFieldSetup
351+ htmlFor = "version"
352+ label = "Module Version"
353+ errorMessage = { errors . version ?. message }
354+ isRequired = { true }
355+ >
356+ { allVersions . isFetching ? (
357+ < Skeleton className = "h-10 w-full rounded-md" />
358+ ) : (
346359 < Select
347- bg = "backgroundHighlight"
348360 disabled = {
349361 ! allVersions . data ||
350362 allVersions . isPending ||
351363 isModuleCompatibleQuery . data === false ||
352364 installMutation . isPending ||
353365 isModuleCompatibleQuery . isFetching
354366 }
355- w = "full"
356- { ...register ( "version" , {
357- required : "Version is required" ,
358- } ) }
367+ value = { watch ( "version" ) }
368+ onValueChange = { ( value ) => setValue ( "version" , value ) }
359369 >
360- < option value = "latest" > Latest</ option >
361- { allVersions ?. data ?. map ( ( { version } ) => (
362- < option key = { version } value = { version } >
363- { version }
364- </ option >
365- ) ) }
370+ < SelectTrigger >
371+ < SelectValue placeholder = "Select version" />
372+ </ SelectTrigger >
373+ < SelectContent >
374+ < SelectItem value = "latest" > Latest</ SelectItem >
375+ { allVersions ?. data ?. map ( ( { version } ) => {
376+ if ( ! version ) {
377+ return null ;
378+ }
379+
380+ return (
381+ < SelectItem key = { version } value = { version } >
382+ { version }
383+ </ SelectItem >
384+ ) ;
385+ } ) }
386+ </ SelectContent >
366387 </ Select >
367- </ Skeleton >
368- < FormErrorMessage > { errors . version ?. message } </ FormErrorMessage >
369- </ FormControl >
388+ ) }
389+ </ FormFieldSetup >
370390 </ div >
371391
372392 { moduleInstallParams . isFetching ? (
373- < Skeleton h = "80px" mt = { 4 } />
393+ < Skeleton className = "h-20 w-full mt-4" />
374394 ) : (
375395 moduleInstallParams . data &&
376396 ! isModuleCompatibleQuery . isFetching &&
@@ -383,7 +403,7 @@ export const InstallModuleForm = (props: InstallModuleFormProps) => {
383403 )
384404 ) }
385405
386- < Spacer h = { 5 } />
406+ < div className = "h-5" />
387407
388408 { /* Submit */ }
389409 < div className = "flex justify-end" >
0 commit comments