Skip to content

Commit 70a0408

Browse files
committed
feat: payment links table
1 parent fad201c commit 70a0408

File tree

5 files changed

+55
-28
lines changed

5 files changed

+55
-28
lines changed

apps/dashboard/src/@/api/universal-bridge/developer.ts

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,33 @@ export async function createPaymentLink(props: {
203203
return;
204204
}
205205

206+
export async function deletePaymentLink(props: {
207+
clientId: string;
208+
teamId: string;
209+
paymentLinkId: string;
210+
}) {
211+
const authToken = await getAuthToken();
212+
const res = await fetch(
213+
`${UB_BASE_URL}/v1/developer/links/${props.paymentLinkId}`,
214+
{
215+
headers: {
216+
Authorization: `Bearer ${authToken}`,
217+
"Content-Type": "application/json",
218+
"x-client-id": props.clientId,
219+
"x-team-id": props.teamId,
220+
},
221+
method: "DELETE",
222+
},
223+
);
224+
225+
if (!res.ok) {
226+
const text = await res.text();
227+
throw new Error(text);
228+
}
229+
230+
return;
231+
}
232+
206233
export type Fee = {
207234
feeRecipient: string;
208235
feeBps: number;
@@ -309,28 +336,21 @@ export async function getPayments(props: {
309336
const authToken = await getAuthToken();
310337

311338
// Build URL with query parameters if provided
312-
let url = `${UB_BASE_URL}/v1/developer/payments`;
313-
const queryParams = new URLSearchParams();
339+
const url = new URL(`${UB_BASE_URL}/v1/developer/payments`);
314340

315341
if (props.limit) {
316-
queryParams.append("limit", props.limit.toString());
342+
url.searchParams.append("limit", props.limit.toString());
317343
}
318344

319345
if (props.offset) {
320-
queryParams.append("offset", props.offset.toString());
346+
url.searchParams.append("offset", props.offset.toString());
321347
}
322348

323349
if (props.paymentLinkId) {
324-
queryParams.append("paymentLinkId", props.paymentLinkId);
325-
}
326-
327-
// Append query params to URL if any exist
328-
const queryString = queryParams.toString();
329-
if (queryString) {
330-
url = `${url}?${queryString}`;
350+
url.searchParams.append("paymentLinkId", props.paymentLinkId);
331351
}
332352

333-
const res = await fetch(url, {
353+
const res = await fetch(url.toString(), {
334354
headers: {
335355
Authorization: `Bearer ${authToken}`,
336356
"Content-Type": "application/json",

apps/dashboard/src/@/components/blocks/TokenSelector.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ export function TokenSelector(props: {
190190
tokensQuery.isPending ? (
191191
<div className="flex items-center gap-2">
192192
<Spinner className="size-4" />
193-
<span>Loading Tokens</span>
193+
<span>Loading tokens</span>
194194
</div>
195195
) : (
196196
props.placeholder || "Select Token"

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ const formSchema = z.object({
4848
});
4949

5050
export function CreatePaymentLinkButton(
51-
props: PropsWithChildren<{ teamId: string }>,
51+
props: PropsWithChildren<{ clientId: string; teamId: string }>,
5252
) {
5353
const [open, setOpen] = useState(false);
5454
const [image, setImage] = useState<File>();
@@ -87,7 +87,7 @@ export function CreatePaymentLinkButton(
8787
}
8888

8989
await createPaymentLink({
90-
clientId: client.clientId,
90+
clientId: props.clientId,
9191
teamId: props.teamId,
9292
intent: {
9393
destinationChainId: values.chainId,
@@ -103,7 +103,7 @@ export function CreatePaymentLinkButton(
103103
onSuccess: () => {
104104
toast.success("Payment link created successfully.");
105105
return queryClient.invalidateQueries({
106-
queryKey: ["payment-links", client.clientId, props.teamId],
106+
queryKey: ["payment-links", props.clientId, props.teamId],
107107
});
108108
},
109109
onError: (err) => {

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

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { type PropsWithChildren, useState } from "react";
66
import { toast } from "sonner";
77
import { toTokens } from "thirdweb";
88
import {
9+
deletePaymentLink,
910
deleteWebhook,
1011
getPaymentLinks,
1112
getPayments,
@@ -106,6 +107,7 @@ export function PaymentLinksTable(props: { clientId: string; teamId: string }) {
106107
buttons={[
107108
<CreatePaymentLinkButton
108109
key="create-payment-link"
110+
clientId={props.clientId}
109111
teamId={props.teamId}
110112
>
111113
<Button className="gap-1" variant="default" size="sm">
@@ -195,15 +197,15 @@ export function PaymentLinksTable(props: { clientId: string; teamId: string }) {
195197
/>
196198
</TableCell>
197199
<TableCell className="text-center">
198-
<DeleteWebhookButton
200+
<DeletePaymentLinkButton
199201
clientId={props.clientId}
200202
teamId={props.teamId}
201-
webhookId={paymentLink.id}
203+
paymentLinkId={paymentLink.id}
202204
>
203205
<Button size="icon" variant="ghost">
204206
<TrashIcon className="size-5" strokeWidth={1} />
205207
</Button>
206-
</DeleteWebhookButton>
208+
</DeletePaymentLinkButton>
207209
</TableCell>
208210
</TableRow>
209211
))
@@ -243,17 +245,21 @@ function SkeletonTableRow() {
243245
);
244246
}
245247

246-
function DeleteWebhookButton(
247-
props: PropsWithChildren<PayWebhooksPageProps & { webhookId: string }>,
248+
function DeletePaymentLinkButton(
249+
props: PropsWithChildren<{
250+
paymentLinkId: string;
251+
clientId: string;
252+
teamId: string;
253+
}>,
248254
) {
249255
const [open, setOpen] = useState(false);
250256
const queryClient = useQueryClient();
251257
const deleteMutation = useMutation({
252258
mutationFn: async (id: string) => {
253-
await deleteWebhook({
259+
await deletePaymentLink({
254260
clientId: props.clientId,
255261
teamId: props.teamId,
256-
webhookId: id,
262+
paymentLinkId: id,
257263
});
258264
return null;
259265
},
@@ -271,7 +277,7 @@ function DeleteWebhookButton(
271277
<DialogTitle>Are you sure?</DialogTitle>
272278
<DialogDescription>
273279
This action cannot be undone. This will permanently delete the
274-
webhook.
280+
payment link.
275281
</DialogDescription>
276282
</DialogHeader>
277283

@@ -280,17 +286,17 @@ function DeleteWebhookButton(
280286
className="gap-2"
281287
disabled={deleteMutation.isPending}
282288
onClick={() => {
283-
deleteMutation.mutateAsync(props.webhookId, {
289+
deleteMutation.mutateAsync(props.paymentLinkId, {
284290
onError(err) {
285-
toast.error("Failed to delete webhook", {
291+
toast.error("Failed to delete payment link.", {
286292
description: err instanceof Error ? err.message : undefined,
287293
});
288294
},
289295
onSuccess: () => {
290-
toast.success("Webhook deleted successfully");
296+
toast.success("Payment link deleted successfully.");
291297
setOpen(false);
292298
return queryClient.invalidateQueries({
293-
queryKey: ["webhooks", props.clientId],
299+
queryKey: ["payment-link", props.clientId],
294300
});
295301
},
296302
});

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ export default async function Page(props: {
3939
</div>
4040
<CreatePaymentLinkButton
4141
key="create-payment-link"
42+
clientId={project.publishableKey}
4243
teamId={project.teamId}
4344
>
4445
<Button className="gap-1" variant="default" size="sm">

0 commit comments

Comments
 (0)