Skip to content

Commit 5d345e7

Browse files
committed
[TOOL-3497] Dashboard: Add Linked Wallets page in account layout, minor UI tweaks in account layout (#6313)
<!-- start pr-codex --> ## PR-Codex overview This PR focuses on enhancing the account management features in the dashboard by introducing linked wallets functionality, refining UI elements, and improving code organization. ### Detailed summary - Added `/account/wallets` route with "Linked Wallets" label. - Updated button text from "Create a Team" to "Create Team". - Changed `<div>` to `<header>` in `AccountSettingsPage.tsx`. - Enhanced `Devices` page structure with headers and descriptions. - Implemented `getLinkedWallets` API function. - Updated `Page` component to fetch linked wallets and account info. - Refactored `LinkWallet` and `LinkWalletUI` components for better state management and UI. - Added stubs for unlinking wallets in `LinkWalletsUI.stories.tsx`. - Improved wallet unlinking functionality with confirmation dialogs. > ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}` <!-- end pr-codex -->
1 parent 43638e5 commit 5d345e7

File tree

10 files changed

+345
-115
lines changed

10 files changed

+345
-115
lines changed
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import { getAuthToken } from "../../app/api/lib/getAuthToken";
2+
import { API_SERVER_URL } from "../constants/env";
3+
4+
export type LinkedWallet = {
5+
createdAt: string;
6+
id: string;
7+
walletAddress: string;
8+
};
9+
10+
export async function getLinkedWallets() {
11+
const token = await getAuthToken();
12+
13+
if (!token) {
14+
return null;
15+
}
16+
17+
const res = await fetch(`${API_SERVER_URL}/v1/account/wallets`, {
18+
headers: {
19+
Authorization: `Bearer ${token}`,
20+
},
21+
});
22+
23+
if (res.ok) {
24+
const json = (await res.json()) as {
25+
data: LinkedWallet[];
26+
};
27+
28+
return json.data;
29+
}
30+
31+
return null;
32+
}

apps/dashboard/src/app/account/devices/AccountDevicesPage.tsx

Lines changed: 7 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -11,25 +11,12 @@ export function AccountDevicesPage() {
1111
const authorizedWalletsQuery = useAuthorizedWallets();
1212

1313
return (
14-
<div className="container py-8">
15-
<div className="flex flex-col gap-8">
16-
<div className="flex flex-col gap-2">
17-
<div className="flex flex-col justify-between gap-4">
18-
<h1 className="font-semibold text-3xl tracking-tight">Devices</h1>
19-
<p className="text-muted-foreground">
20-
List of authorized devices that can perform actions on behalf of
21-
your account.
22-
</p>
23-
<ChakraProviderSetup>
24-
<AuthorizedWalletsTable
25-
authorizedWallets={authorizedWalletsQuery.data || []}
26-
isPending={authorizedWalletsQuery.isPending}
27-
isFetched={authorizedWalletsQuery.isFetched}
28-
/>
29-
</ChakraProviderSetup>
30-
</div>
31-
</div>
32-
</div>
33-
</div>
14+
<ChakraProviderSetup>
15+
<AuthorizedWalletsTable
16+
authorizedWallets={authorizedWalletsQuery.data || []}
17+
isPending={authorizedWalletsQuery.isPending}
18+
isFetched={authorizedWalletsQuery.isFetched}
19+
/>
20+
</ChakraProviderSetup>
3421
);
3522
}

apps/dashboard/src/app/account/devices/page.tsx

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,21 @@ export default async function Page() {
55
// enforce valid account
66
await getValidAccount("/account/devices");
77

8-
return <AccountDevicesPage />;
8+
return (
9+
<div>
10+
<header className="border-border border-b py-10">
11+
<div className="container max-w-[950px]">
12+
<h1 className="font-semibold text-3xl tracking-tight">Devices</h1>
13+
<p className="mt-1 text-muted-foreground text-sm">
14+
List of authorized devices that can perform actions on behalf of
15+
your account.
16+
</p>
17+
</div>
18+
</header>
19+
20+
<div className="container max-w-[950px] py-8">
21+
<AccountDevicesPage />
22+
</div>
23+
</div>
24+
);
925
}

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

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -70,11 +70,10 @@ async function HeaderAndNav(props: {
7070
path: "/account/settings",
7171
name: "Settings",
7272
},
73-
// TODO - enable these links after they are functional
74-
// {
75-
// path: "/account/wallets",
76-
// name: "Wallets",
77-
// },
73+
{
74+
path: "/account/wallets",
75+
name: "Linked Wallets",
76+
},
7877
{
7978
path: "/account/devices",
8079
name: "Devices",

apps/dashboard/src/app/account/overview/AccountTeamsUI.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,9 @@ export function AccountTeamsUI(props: {
4646
</div>
4747

4848
<ToolTipLabel label="Coming Soon">
49-
<Button variant="primary" disabled className="gap-2 max-sm:w-full">
49+
<Button disabled className="gap-2 max-sm:w-full">
5050
<PlusIcon className="size-4" />
51-
Create a Team
51+
Create Team
5252
</Button>
5353
</ToolTipLabel>
5454
</div>

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

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,19 @@
11
import { getTeams } from "@/api/team";
22
import { getMembers } from "@/api/team-members";
33
import { getThirdwebClient } from "@/constants/thirdweb.server";
4+
import { getAuthToken } from "../api/lib/getAuthToken";
45
import { loginRedirect } from "../login/loginRedirect";
56
import { AccountTeamsUI } from "./overview/AccountTeamsUI";
67
import { getValidAccount } from "./settings/getAccount";
78

89
export default async function Page() {
9-
const account = await getValidAccount("/account");
10-
const teams = await getTeams();
11-
if (!teams) {
10+
const [authToken, account, teams] = await Promise.all([
11+
getAuthToken(),
12+
getValidAccount("/account"),
13+
getTeams(),
14+
]);
15+
16+
if (!authToken || !teams) {
1217
loginRedirect("/account");
1318
}
1419

@@ -36,11 +41,19 @@ export default async function Page() {
3641
).filter((x) => !!x);
3742

3843
return (
39-
<div className="container grow py-8">
40-
<AccountTeamsUI
41-
teamsWithRole={teamsWithRole}
42-
client={getThirdwebClient()}
43-
/>
44+
<div className="flex grow flex-col">
45+
<header className="border-border border-b py-10">
46+
<div className="container max-w-[950px]">
47+
<h1 className="font-semibold text-3xl tracking-tight">Overview</h1>
48+
</div>
49+
</header>
50+
51+
<div className="container flex max-w-[950px] grow flex-col py-8">
52+
<AccountTeamsUI
53+
teamsWithRole={teamsWithRole}
54+
client={getThirdwebClient(authToken)}
55+
/>
56+
</div>
4457
</div>
4558
);
4659
}

apps/dashboard/src/app/account/settings/AccountSettingsPage.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,14 @@ export function AccountSettingsPage(props: {
1515
const router = useDashboardRouter();
1616
return (
1717
<div>
18-
<div className="border-border border-b py-10">
18+
<header className="border-border border-b py-10">
1919
<div className="container max-w-[950px]">
2020
<h1 className="font-semibold text-3xl tracking-tight">
2121
Account Settings
2222
</h1>
2323
</div>
24-
</div>
24+
</header>
25+
2526
<div className="container max-w-[950px] grow pt-8 pb-20">
2627
<AccountSettingsPageUI
2728
hideDeleteAccount

0 commit comments

Comments
 (0)