Skip to content

Commit e958e75

Browse files
committed
feat: add custom auth demo in playground (#5418)
https://linear.app/thirdweb/issue/CNCT-2364/custom-auth-demo-in-playground <!-- start pr-codex --> --- ## PR-Codex overview This PR introduces a new `CustomLoginForm` component for handling user authentication via email in the `in-app-wallet` feature. It allows users to log in with a custom authentication endpoint while integrating with existing wallet functionalities. ### Detailed summary - Added `CustomLoginForm` component in `custom-login-form.tsx`. - Utilized `useMutation` for handling login requests with an email. - Implemented email input and submission handling in the `CustomLoginForm`. - Updated `page.tsx` to include `CustomLoginForm` with a new section for custom authentication UI. > ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}` <!-- end pr-codex -->
1 parent b620dee commit e958e75

File tree

2 files changed

+153
-7
lines changed

2 files changed

+153
-7
lines changed

apps/playground-web/src/app/connect/in-app-wallet/page.tsx

Lines changed: 86 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { CodeExample } from "@/components/code/code-example";
2+
import { CustomLoginForm } from "@/components/in-app-wallet/custom-login-form";
23
import { InAppConnectEmbed } from "../../../components/in-app-wallet/connect-button";
34
import { Profiles } from "../../../components/in-app-wallet/profile-sections";
45
import ThirdwebProvider from "../../../components/thirdweb-provider";
@@ -30,13 +31,16 @@ function AnyAuth() {
3031
base.
3132
</p>
3233
</div>
33-
34-
<CodeExample
35-
preview={<InAppConnectEmbed />}
36-
code={`import { inAppWallet } from "thirdweb/wallets";
34+
<div className="space-y-2">
35+
<h3 className="mb-3 font-medium text-lg">Prebuilt UI</h3>
36+
<p className="max-w-[600px]">
37+
Instant out of the box authentication with a prebuilt UI.
38+
</p>
39+
<CodeExample
40+
preview={<InAppConnectEmbed />}
41+
code={`import { inAppWallet } from "thirdweb/wallets";
3742
import { ConnectEmbed } from "thirdweb/react";
3843
39-
4044
const wallets = [
4145
inAppWallet(
4246
// built-in auth methods
@@ -66,8 +70,83 @@ function AnyAuth() {
6670
return (
6771
<ConnectEmbed client={client} wallets={wallets} />);
6872
};`}
69-
lang="tsx"
70-
/>
73+
lang="tsx"
74+
/>
75+
</div>
76+
<div className="space-y-2">
77+
<h3 className="mb-3 font-medium text-lg">Custom Auth and UI</h3>
78+
<p className="max-w-[600px]">
79+
Customize the login UI and integrate with your existing user base. No
80+
limits on customizations and auth methods.
81+
</p>
82+
<CodeExample
83+
preview={
84+
<div className="w-1/2">
85+
<CustomLoginForm />
86+
</div>
87+
}
88+
code={`import { useMutation } from "@tanstack/react-query";
89+
import { useState } from "react";
90+
import { useConnect } from "thirdweb/react";
91+
import { inAppWallet } from "thirdweb/wallets";
92+
93+
export function CustomLoginForm() {
94+
const [email, setEmail] = useState("");
95+
const { connect, isConnecting, error } = useConnect();
96+
97+
const { mutate: loginWithCustomAuth } = useMutation({
98+
mutationFn: async (email: string) => {
99+
const wallet = await connect(async () => {
100+
const wallet = inAppWallet();
101+
await wallet.connect({
102+
strategy: "auth_endpoint",
103+
client,
104+
// your own custom auth payload here
105+
payload: JSON.stringify({
106+
userId: email,
107+
email,
108+
}),
109+
});
110+
return wallet;
111+
});
112+
return wallet;
113+
}
114+
});
115+
116+
const handleSubmit = (e: React.FormEvent) => {
117+
e.preventDefault();
118+
loginWithCustomAuth(email);
119+
};
120+
121+
return (
122+
<form onSubmit={handleSubmit}>
123+
<div>
124+
<label htmlFor="email">
125+
Email Address
126+
</label>
127+
<input
128+
type="email"
129+
id="email"
130+
value={email}
131+
onChange={(e) => setEmail(e.target.value)}
132+
placeholder="Enter your email"
133+
required
134+
/>
135+
<button
136+
type="submit"
137+
disabled={isConnecting || !email}
138+
>
139+
{isConnecting ? "Submitting..." : "Submit"}
140+
</button>
141+
{error && <p>{error.message}</p>}
142+
</div>
143+
</form>
144+
);
145+
}
146+
`}
147+
lang="tsx"
148+
/>
149+
</div>
71150
</>
72151
);
73152
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
"use client";
2+
3+
import { THIRDWEB_CLIENT } from "@/lib/client";
4+
import { useMutation } from "@tanstack/react-query";
5+
import { useState } from "react";
6+
import { useActiveAccount, useConnect } from "thirdweb/react";
7+
import { inAppWallet } from "thirdweb/wallets";
8+
import { InAppConnectEmbed } from "./connect-button";
9+
10+
export function CustomLoginForm() {
11+
const [email, setEmail] = useState("");
12+
const { connect, isConnecting, error } = useConnect();
13+
const account = useActiveAccount();
14+
15+
const { mutate: loginWithCustomAuthEndpoint } = useMutation({
16+
mutationFn: async (email: string) => {
17+
const wallet = await connect(async () => {
18+
const wallet = inAppWallet();
19+
await wallet.connect({
20+
strategy: "auth_endpoint",
21+
client: THIRDWEB_CLIENT,
22+
payload: JSON.stringify({
23+
userId: email,
24+
email,
25+
}),
26+
});
27+
return wallet;
28+
});
29+
return wallet;
30+
},
31+
});
32+
33+
const handleSubmit = (e: React.FormEvent) => {
34+
e.preventDefault();
35+
loginWithCustomAuthEndpoint(email);
36+
};
37+
if (account) {
38+
return <InAppConnectEmbed />;
39+
}
40+
41+
return (
42+
<form onSubmit={handleSubmit} className="mt-4">
43+
<div className="flex flex-col space-y-2">
44+
<label htmlFor="email" className="font-medium text-sm">
45+
Email Address
46+
</label>
47+
<input
48+
type="email"
49+
id="email"
50+
value={email}
51+
onChange={(e) => setEmail(e.target.value)}
52+
className="rounded-lg border px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500"
53+
placeholder="Enter your email"
54+
required
55+
/>
56+
<button
57+
type="submit"
58+
className="rounded-lg bg-blue-500 px-4 py-2 text-white transition-colors enabled:hover:bg-blue-600"
59+
disabled={isConnecting || !email}
60+
>
61+
{isConnecting ? "Submitting..." : "Submit"}
62+
</button>
63+
{error && <p className="max-w-[300px] text-red-500">{error.message}</p>}
64+
</div>
65+
</form>
66+
);
67+
}

0 commit comments

Comments
 (0)