22
33import { zodResolver } from "@hookform/resolvers/zod" ;
44import { useMutation , useQuery , useQueryClient } from "@tanstack/react-query" ;
5- import { LinkIcon } from "lucide-react" ;
5+ import { PlusIcon } from "lucide-react" ;
66import { type PropsWithChildren , useState } from "react" ;
77import { useForm } from "react-hook-form" ;
88import { toast } from "sonner" ;
@@ -19,18 +19,16 @@ import {
1919 Dialog ,
2020 DialogContent ,
2121 DialogDescription ,
22- DialogFooter ,
2322 DialogHeader ,
2423 DialogTitle ,
2524 DialogTrigger ,
2625} from "@/components/ui/dialog" ;
2726import {
2827 Form ,
29- FormDescription ,
3028 FormField ,
3129 FormItem ,
30+ FormLabel ,
3231 FormMessage ,
33- RequiredFormLabel ,
3432} from "@/components/ui/form" ;
3533import { Input } from "@/components/ui/input" ;
3634import { Spinner } from "@/components/ui/Spinner/Spinner" ;
@@ -50,7 +48,26 @@ export function CreatePaymentLinkButton(
5048 props : PropsWithChildren < { clientId : string ; teamId : string } > ,
5149) {
5250 const [ open , setOpen ] = useState ( false ) ;
53- // const [image, setImage] = useState<File>();
51+
52+ return (
53+ < Dialog onOpenChange = { setOpen } open = { open } >
54+ < DialogTrigger asChild > { props . children } </ DialogTrigger >
55+ < DialogContent className = "p-0 !max-w-lg" >
56+ < CreatePaymentLinkDialogContent
57+ clientId = { props . clientId }
58+ setOpen = { setOpen }
59+ teamId = { props . teamId }
60+ />
61+ </ DialogContent >
62+ </ Dialog >
63+ ) ;
64+ }
65+
66+ function CreatePaymentLinkDialogContent ( props : {
67+ clientId : string ;
68+ teamId : string ;
69+ setOpen : ( open : boolean ) => void ;
70+ } ) {
5471 const client = getClientThirdwebClient ( ) ;
5572
5673 const form = useForm < z . infer < typeof formSchema > > ( {
@@ -117,108 +134,83 @@ export function CreatePaymentLinkButton(
117134 toast . error ( parseErrorToMessage ( err ) , { duration : 5000 } ) ;
118135 } ,
119136 } ) ;
120- // const uploadMutation = useMutation({
121- // mutationFn: async (file: File) => {
122- // const uploadClient = createThirdwebClient({
123- // clientId: "f958464759859da7a1c6f9d905c90a43", //7ae789153cf9ecde8f35649f2d8a4333", // Special client ID for uploads only on thirdweb.com
124- // });
125- // const uri = await upload({
126- // client: uploadClient,
127- // files: [file],
128- // });
129- //
130- // // eslint-disable-next-line no-restricted-syntax
131- // const resolvedUrl = resolveScheme({
132- // client: uploadClient,
133- // uri,
134- // });
135- //
136- // form.setValue("imageUrl", resolvedUrl);
137- // return;
138- // },
139- // onSuccess: () => {
140- // toast.success("Image uploaded successfully.");
141- // },
142- // onError: (e) => {
143- // console.error(e);
144- // // setImage(undefined);
145- // toast.error(parseErrorToMessage(e), { duration: 5000 });
146- // },
147- // });
148137
149138 return (
150- < Dialog onOpenChange = { setOpen } open = { open } >
151- < DialogTrigger asChild > { props . children } </ DialogTrigger >
152- < DialogContent className = "!max-w-xl" >
153- < Form { ...form } >
154- < form
155- className = "flex flex-col gap-6"
156- onSubmit = { form . handleSubmit ( ( values ) =>
157- createMutation . mutateAsync ( values , {
158- onSuccess : ( result ) => {
159- reportPaymentLinkCreated ( {
160- linkId : result . id ,
161- clientId : props . clientId ,
162- } ) ;
139+ < div >
140+ < DialogHeader className = "p-4 lg:p-6" >
141+ < DialogTitle > Create a Payment</ DialogTitle >
142+ < DialogDescription >
143+ Get paid in any token on any chain.
144+ </ DialogDescription >
145+ </ DialogHeader >
163146
164- setOpen ( false ) ;
165- form . reset ( ) ;
166- form . clearErrors ( ) ;
167- } ,
168- } ) ,
169- ) }
170- >
171- < DialogHeader >
172- < DialogTitle > Create a Payment</ DialogTitle >
173- < DialogDescription >
174- Get paid in any token on any chain.
175- </ DialogDescription >
176- </ DialogHeader >
147+ < Form { ...form } >
148+ < form
149+ onSubmit = { form . handleSubmit ( ( values ) =>
150+ createMutation . mutateAsync ( values , {
151+ onSuccess : ( result ) => {
152+ reportPaymentLinkCreated ( {
153+ linkId : result . id ,
154+ clientId : props . clientId ,
155+ } ) ;
177156
178- < div className = "flex flex-col gap-6 w-full" >
179- < FormField
180- name = "title"
181- render = { ( { field } ) => (
182- < FormItem className = "" >
183- < RequiredFormLabel > Title</ RequiredFormLabel >
184- < Input { ...field } placeholder = "Payment for..." />
185- < FormMessage />
186- </ FormItem >
187- ) }
188- />
157+ props . setOpen ( false ) ;
158+ form . reset ( ) ;
159+ form . clearErrors ( ) ;
160+ } ,
161+ } ) ,
162+ ) }
163+ >
164+ < div className = "px-4 lg:px-6 space-y-4 pb-8" >
165+ < FormField
166+ name = "title"
167+ render = { ( { field } ) => (
168+ < FormItem className = "" >
169+ < FormLabel > Title</ FormLabel >
170+ < Input
171+ { ...field }
172+ placeholder = "Payment for..."
173+ className = "bg-card"
174+ />
175+ < FormMessage />
176+ </ FormItem >
177+ ) }
178+ />
189179
190- < FormField
191- name = "recipient"
192- render = { ( { field } ) => (
193- < FormItem >
194- < RequiredFormLabel > Recipient Address</ RequiredFormLabel >
195- < Input
196- className = "w-full"
197- { ...field }
198- onChange = { field . onChange }
199- value = { field . value }
200- placeholder = "Address or ENS"
201- required
202- />
203- < FormDescription > Address or ENS</ FormDescription >
204- < FormMessage />
205- </ FormItem >
206- ) }
207- />
208- </ div >
180+ < FormField
181+ name = "recipient"
182+ render = { ( { field } ) => (
183+ < FormItem >
184+ < FormLabel > Recipient Address</ FormLabel >
185+ < Input
186+ className = "w-full bg-card"
187+ { ...field }
188+ onChange = { field . onChange }
189+ value = { field . value }
190+ placeholder = "Address or ENS"
191+ required
192+ />
193+ < FormMessage />
194+ </ FormItem >
195+ ) }
196+ />
209197
210198 < FormField
211199 name = "chainId"
212200 render = { ( { field } ) => (
213201 < FormItem >
214- < RequiredFormLabel > Chain</ RequiredFormLabel >
202+ < FormLabel > Chain</ FormLabel >
215203 < SingleNetworkSelector
216204 chainIds = { chainsQuery . data ?. map ( ( x ) => x . chainId ) }
217205 chainId = { field . value }
218- className = "w-full"
206+ className = "w-full bg-card"
207+ disableChainId
219208 client = { client }
220209 disableTestnets
221- onChange = { field . onChange }
210+ onChange = { ( v ) => {
211+ field . onChange ( v ) ;
212+ form . resetField ( "tokenAddress" ) ;
213+ } }
222214 />
223215 < FormMessage />
224216 </ FormItem >
@@ -229,11 +221,11 @@ export function CreatePaymentLinkButton(
229221 name = "tokenAddress"
230222 render = { ( { field } ) => (
231223 < FormItem >
232- < RequiredFormLabel > Token</ RequiredFormLabel >
224+ < FormLabel > Token</ FormLabel >
233225 < TokenSelector
234226 addNativeTokenIfMissing = { false }
235227 chainId = { form . getValues ( ) . chainId }
236- className = "w-full"
228+ className = "w-full bg-card "
237229 client = { client }
238230 disabled = { ! form . getValues ( ) . chainId }
239231 onChange = { ( token ) => {
@@ -258,9 +250,9 @@ export function CreatePaymentLinkButton(
258250 name = "amount"
259251 render = { ( { field } ) => (
260252 < FormItem >
261- < RequiredFormLabel > Amount</ RequiredFormLabel >
253+ < FormLabel > Amount</ FormLabel >
262254 < Input
263- className = "w-full"
255+ className = "w-full bg-card "
264256 { ...field }
265257 placeholder = "0.0"
266258 required
@@ -271,27 +263,25 @@ export function CreatePaymentLinkButton(
271263 </ FormItem >
272264 ) }
273265 />
266+ </ div >
274267
275- < DialogFooter >
276- < div className = "flex gap-2" >
277- < Button
278- size = "sm"
279- className = "flex-1 flex gap-2 items-center"
280- type = "submit"
281- disabled = { createMutation . isPending }
282- >
283- { createMutation . isPending ? (
284- < Spinner className = "size-4" />
285- ) : (
286- < LinkIcon className = "size-4" />
287- ) }
288- { createMutation . isPending ? "Creating..." : "Create" }
289- </ Button >
290- </ div >
291- </ DialogFooter >
292- </ form >
293- </ Form >
294- </ DialogContent >
295- </ Dialog >
268+ < div className = "gap-2 border-t p-4 lg:p-6 bg-card flex justify-end rounded-b-lg" >
269+ < Button
270+ size = "sm"
271+ className = "gap-2 items-center"
272+ type = "submit"
273+ disabled = { createMutation . isPending }
274+ >
275+ { createMutation . isPending ? (
276+ < Spinner className = "size-4" />
277+ ) : (
278+ < PlusIcon className = "size-4" />
279+ ) }
280+ { createMutation . isPending ? "Creating..." : "Create" }
281+ </ Button >
282+ </ div >
283+ </ form >
284+ </ Form >
285+ </ div >
296286 ) ;
297287}
0 commit comments