1
+ "use client" ;
2
+
3
+ import { FormFieldSetup } from "@/components/blocks/FormFieldSetup" ;
4
+ import { Spinner } from "@/components/ui/Spinner/Spinner" ;
5
+ import { Badge } from "@/components/ui/badge" ;
6
+ import { Button } from "@/components/ui/button" ;
7
+ import {
8
+ Dialog ,
9
+ DialogContent ,
10
+ DialogFooter ,
11
+ DialogHeader ,
12
+ DialogTitle ,
13
+ } from "@/components/ui/dialog" ;
14
+ import { Input } from "@/components/ui/input" ;
1
15
import {
2
16
type CreateBackendWalletInput ,
3
17
useEngineCreateBackendWallet ,
4
18
useEngineWalletConfig ,
5
19
} from "@3rdweb-sdk/react/hooks/useEngine" ;
6
- import {
7
- Flex ,
8
- FormControl ,
9
- Input ,
10
- Modal ,
11
- ModalBody ,
12
- ModalCloseButton ,
13
- ModalContent ,
14
- ModalFooter ,
15
- ModalHeader ,
16
- ModalOverlay ,
17
- useDisclosure ,
18
- } from "@chakra-ui/react" ;
19
20
import { useTrack } from "hooks/analytics/useTrack" ;
20
- import { useTxNotifications } from "hooks/useTxNotifications " ;
21
+ import { useState } from "react " ;
21
22
import { useForm } from "react-hook-form" ;
22
- import { Button , FormLabel , Text } from "tw-components " ;
23
+ import { toast } from "sonner " ;
23
24
24
- interface CreateBackendWalletButtonProps {
25
+ export function CreateBackendWalletButton ( props : {
25
26
instanceUrl : string ;
26
- }
27
-
28
- export const CreateBackendWalletButton : React . FC <
29
- CreateBackendWalletButtonProps
30
- > = ( { instanceUrl } ) => {
31
- const { isOpen, onOpen, onClose } = useDisclosure ( ) ;
27
+ } ) {
28
+ const { instanceUrl } = props ;
29
+ const [ isOpen , setIsOpen ] = useState ( false ) ;
32
30
const { data : walletConfig } = useEngineWalletConfig ( instanceUrl ) ;
33
- const { mutate : createBackendWallet } =
34
- useEngineCreateBackendWallet ( instanceUrl ) ;
35
- const { onSuccess, onError } = useTxNotifications (
36
- "Wallet created successfully." ,
37
- "Failed to create wallet." ,
38
- ) ;
31
+ const createWallet = useEngineCreateBackendWallet ( instanceUrl ) ;
39
32
const trackEvent = useTrack ( ) ;
40
33
const form = useForm < CreateBackendWalletInput > ( ) ;
41
34
42
35
const onSubmit = async ( data : CreateBackendWalletInput ) => {
43
- createBackendWallet ( data , {
36
+ const promise = createWallet . mutateAsync ( data , {
44
37
onSuccess : ( ) => {
45
- onSuccess ( ) ;
46
- onClose ( ) ;
38
+ setIsOpen ( false ) ;
47
39
trackEvent ( {
48
40
category : "engine" ,
49
41
action : "create-backend-wallet" ,
@@ -52,7 +44,6 @@ export const CreateBackendWalletButton: React.FC<
52
44
} ) ;
53
45
} ,
54
46
onError : ( error ) => {
55
- onError ( error ) ;
56
47
trackEvent ( {
57
48
category : "engine" ,
58
49
action : "create-backend-wallet" ,
@@ -62,6 +53,11 @@ export const CreateBackendWalletButton: React.FC<
62
53
} ) ;
63
54
} ,
64
55
} ) ;
56
+
57
+ toast . promise ( promise , {
58
+ success : "Wallet created successfully" ,
59
+ error : "Failed to create wallet" ,
60
+ } ) ;
65
61
} ;
66
62
67
63
const walletType =
@@ -73,43 +69,58 @@ export const CreateBackendWalletButton: React.FC<
73
69
74
70
return (
75
71
< >
76
- < Button onClick = { onOpen } colorScheme = "primary" >
77
- Create
78
- </ Button >
79
- < Modal isOpen = { isOpen } onClose = { onClose } isCentered >
80
- < ModalOverlay />
81
- < ModalContent className = "!bg-background rounded-lg border border-border" >
72
+ < Button onClick = { ( ) => setIsOpen ( true ) } > Create </ Button >
73
+ < Dialog open = { isOpen } onOpenChange = { setIsOpen } >
74
+ < DialogContent
75
+ className = "z-[10001] p-0"
76
+ dialogOverlayClassName = "z-[10000]"
77
+ >
82
78
< form onSubmit = { form . handleSubmit ( onSubmit ) } >
83
- < ModalHeader > Create { walletType } wallet</ ModalHeader >
84
- < ModalCloseButton />
85
- < ModalBody >
79
+ < div className = "p-6" >
80
+ < DialogHeader className = "mb-4" >
81
+ < DialogTitle className = "font-semibold text-2xl tracking-tight" >
82
+ Create { walletType } wallet
83
+ </ DialogTitle >
84
+ </ DialogHeader >
85
+
86
86
< div className = "flex flex-col gap-4" >
87
- < FormControl >
88
- < FormLabel > Wallet Type</ FormLabel >
89
- < Text > { walletType } </ Text >
90
- </ FormControl >
91
- < FormControl >
92
- < FormLabel > Label</ FormLabel >
87
+ < div >
88
+ < p className = "mb-1 text-sm" > Wallet Type</ p >
89
+ < Badge className = "text-sm" variant = "outline" >
90
+ { walletType }
91
+ </ Badge >
92
+ </ div >
93
+
94
+ < FormFieldSetup
95
+ label = "Label"
96
+ errorMessage = {
97
+ form . getFieldState ( "label" , form . formState ) . error ?. message
98
+ }
99
+ htmlFor = "wallet-label"
100
+ isRequired = { false }
101
+ >
93
102
< Input
103
+ id = "wallet-label"
94
104
type = "text"
95
105
placeholder = "Enter a descriptive label"
96
106
{ ...form . register ( "label" ) }
97
107
/>
98
- </ FormControl >
108
+ </ FormFieldSetup >
99
109
</ div >
100
- </ ModalBody >
110
+ </ div >
101
111
102
- < ModalFooter as = { Flex } gap = { 3 } >
103
- < Button onClick = { onClose } variant = "ghost " >
112
+ < DialogFooter className = "!flex-row !justify-end mt-4 gap-3 border-border border-t bg-muted/50 p-6" >
113
+ < Button onClick = { ( ) => setIsOpen ( false ) } variant = "outline " >
104
114
Cancel
105
115
</ Button >
106
- < Button type = "submit" colorScheme = "primary" >
116
+ < Button type = "submit" className = "min-w-28 gap-2" >
117
+ { createWallet . isPending && < Spinner className = "size-4" /> }
107
118
Create
108
119
</ Button >
109
- </ ModalFooter >
120
+ </ DialogFooter >
110
121
</ form >
111
- </ ModalContent >
112
- </ Modal >
122
+ </ DialogContent >
123
+ </ Dialog >
113
124
</ >
114
125
) ;
115
- } ;
126
+ }
0 commit comments