Skip to content

Commit ac62d8d

Browse files
committed
feat: new payments page ui
1 parent a36c850 commit ac62d8d

File tree

3 files changed

+72
-30
lines changed

3 files changed

+72
-30
lines changed

apps/dashboard/src/app/pay/[id]/page.tsx

Lines changed: 69 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
11
import type { Metadata } from "next";
2+
import Image from "next/image";
23
import { defineChain, getContract } from "thirdweb";
34
import { getCurrencyMetadata } from "thirdweb/extensions/erc20";
5+
import { resolveScheme } from "thirdweb/storage";
46
import { checksumAddress } from "thirdweb/utils";
57
import { getPaymentLink } from "@/api/universal-bridge/links";
8+
import { NEXT_PUBLIC_THIRDWEB_API_HOST } from "@/constants/public-envs";
9+
import { API_SERVER_SECRET } from "@/constants/server-envs";
610
import { getClientThirdwebClient } from "@/constants/thirdweb-client.client";
711
import { PayPageWidget } from "../components/client/PayPageWidget.client";
12+
import { payAppThirdwebClient } from "../constants";
813

914
const title = "thirdweb Pay";
1015
const description = "Fast, secure, and simple payments.";
@@ -38,13 +43,15 @@ export default async function PayPage({
3843
chain: defineChain(Number(paymentLink.destinationToken.chainId)),
3944
client: getClientThirdwebClient(undefined),
4045
});
41-
const {
42-
symbol,
43-
decimals,
44-
name: tokenName,
45-
} = await getCurrencyMetadata({
46+
const currencyMetadataPromise = getCurrencyMetadata({
4647
contract: tokenContract,
4748
});
49+
50+
const projectMetadataPromise = getProjectMetadata(paymentLink.clientId);
51+
52+
const [{ symbol, decimals, name: tokenName }, projectMetadata] =
53+
await Promise.all([currencyMetadataPromise, projectMetadataPromise]);
54+
4855
const token = {
4956
address: checksumAddress(paymentLink.destinationToken.address),
5057
chainId: Number(paymentLink.destinationToken.chainId),
@@ -54,18 +61,62 @@ export default async function PayPage({
5461
};
5562

5663
return (
57-
<PayPageWidget
58-
amount={paymentLink.amount ? BigInt(paymentLink.amount) : undefined}
59-
chainId={Number(paymentLink.destinationToken.chainId)}
60-
clientId={undefined} // Payment links don't need to use the same client ID to be executed
61-
image={paymentLink.imageUrl}
62-
name={paymentLink.title}
63-
paymentLinkId={id}
64-
purchaseData={paymentLink.purchaseData}
65-
recipientAddress={paymentLink.receiver}
66-
redirectUri={redirectUri}
67-
theme={theme}
68-
token={token}
69-
/>
64+
<div className="flex z-10 flex-col lg:flex-row h-full w-full">
65+
<header className="min-w-full lg:min-w-[500px] border-b lg:border-r lg:h-full bg-card flex flex-col gap-4 items-start p-4 lg:p-8">
66+
<div className="flex flex-row items-center justify-center gap-4">
67+
{projectMetadata.image && (
68+
<Image
69+
src={resolveScheme({
70+
uri: projectMetadata.image,
71+
client: payAppThirdwebClient,
72+
})}
73+
alt={projectMetadata.name}
74+
width={25}
75+
height={25}
76+
className="rounded-full overflow-hidden"
77+
/>
78+
)}
79+
<h2 className="text-xl font-bold">{projectMetadata.name}</h2>
80+
</div>
81+
{projectMetadata.description && (
82+
<p className="text-sm text-muted-foreground">
83+
{projectMetadata.description}
84+
</p>
85+
)}
86+
</header>
87+
<main className="flex justify-center p-12 w-full items-center">
88+
<PayPageWidget
89+
amount={paymentLink.amount ? BigInt(paymentLink.amount) : undefined}
90+
chainId={Number(paymentLink.destinationToken.chainId)}
91+
clientId={undefined} // Payment links don't need to use the same client ID to be executed
92+
image={paymentLink.imageUrl}
93+
name={paymentLink.title}
94+
paymentLinkId={id}
95+
purchaseData={paymentLink.purchaseData}
96+
recipientAddress={paymentLink.receiver}
97+
redirectUri={redirectUri}
98+
theme={theme}
99+
token={token}
100+
/>
101+
</main>
102+
</div>
70103
);
71104
}
105+
106+
async function getProjectMetadata(clientId: string) {
107+
const url = new URL(`${NEXT_PUBLIC_THIRDWEB_API_HOST}/v2/keys/lookup`);
108+
url.searchParams.append("clientId", clientId);
109+
const response = await fetch(url.toString(), {
110+
headers: {
111+
"x-service-api-key": API_SERVER_SECRET,
112+
},
113+
});
114+
if (!response.ok) {
115+
throw new Error("Failed to fetch project");
116+
}
117+
118+
const { data } = (await response.json()) as {
119+
data: { name: string; image: string | null; description: string | null };
120+
};
121+
return data;
122+
}

apps/dashboard/src/app/pay/layout.tsx

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -30,17 +30,8 @@ export default async function PayLayout({
3030
disableTransitionOnChange
3131
enableSystem={false}
3232
>
33-
<div className="relative mx-auto flex h-full w-full flex-col items-center justify-center overflow-x-hidden overflow-y-scroll py-10">
34-
<main className="container z-10 flex justify-center">
35-
{children}
36-
</main>
37-
38-
{/* eslint-disable-next-line @next/next/no-img-element */}
39-
<img
40-
alt=""
41-
className="-bottom-12 -right-12 pointer-events-none absolute lg:right-0 lg:bottom-0"
42-
src="/assets/login/background.svg"
43-
/>
33+
<div className="relative mx-auto flex h-full w-full items-center justify-center overflow-x-hidden overflow-y-scroll">
34+
{children}
4435
</div>
4536
</ThemeProvider>
4637
</PayProviders>

apps/dashboard/src/app/pay/page.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { PayPageWidget } from "./components/client/PayPageWidget.client";
77
import type { PayParams } from "./components/types";
88
import { payAppThirdwebClient } from "./constants";
99

10-
const title = "thirdweb Pay";
10+
const title = "thirdweb Payments";
1111
const description = "Fast, secure, and simple payments.";
1212

1313
export const metadata: Metadata = {

0 commit comments

Comments
 (0)