Skip to content

Commit c6150be

Browse files
committed
Dashboard: Create Payment link dialog fixes/ui tweaks (#7908)
<!-- ## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes" If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000): ## Notes for the reviewer Anything important to call out? Be sure to also clarify these in your comments. ## How to test Unit tests, playground, etc. --> <!-- start pr-codex --> --- ## PR-Codex overview This PR updates the `CreatePaymentLinkButton` component to enhance its dialog interface and improve the overall user experience. It replaces the `LinkIcon` with a `PlusIcon`, refines form elements, and cleans up unused code. ### Detailed summary - Replaced `LinkIcon` with `PlusIcon`. - Updated dialog structure and content. - Changed `RequiredFormLabel` to `FormLabel` for consistency. - Improved styling by adding `bg-card` class to input fields. - Removed commented-out code related to image upload functionality. - Enhanced form layout and submission handling. > ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}` <!-- end pr-codex --> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **Refactor** - Streamlined the payment link creation flow with a clearer dialog and improved form handling for a smoother experience. - **Style** - Updated to a plus icon, added a header with title and description, standardized labels, themed inputs, and introduced a bottom action bar. - **Bug Fixes** - Chain and token changes now properly reset related fields. - Improved validation for recipient address and token selection. - Added progress indicator during creation. - Success toast and automatic refresh ensure newly created payment links appear immediately. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
1 parent 27f50a8 commit c6150be

File tree

1 file changed

+107
-117
lines changed

1 file changed

+107
-117
lines changed

apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/payments/links/components/CreatePaymentLinkButton.client.tsx

Lines changed: 107 additions & 117 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import { zodResolver } from "@hookform/resolvers/zod";
44
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
5-
import { LinkIcon } from "lucide-react";
5+
import { PlusIcon } from "lucide-react";
66
import { type PropsWithChildren, useState } from "react";
77
import { useForm } from "react-hook-form";
88
import { 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";
2726
import {
2827
Form,
29-
FormDescription,
3028
FormField,
3129
FormItem,
30+
FormLabel,
3231
FormMessage,
33-
RequiredFormLabel,
3432
} from "@/components/ui/form";
3533
import { Input } from "@/components/ui/input";
3634
import { 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

Comments
 (0)