Skip to content

Commit 6c4e684

Browse files
committed
[PRO-90] Dashboard: Project > Bridge page changes (#8406)
<!-- ## 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 focuses on refactoring the payments and bridge components in the dashboard application. It updates routes, modifies component structures, and enhances the user interface for better functionality and clarity. ### Detailed summary - Deleted `view-tx-status.tsx` and `project-settings-breadcrumb.tsx`. - Updated payment-related paths to bridge configuration. - Refactored `FeatureCard` and `QuickstartSection` components. - Changed `TableRow` to `PurchaseTableRow` in `PaymentsTableRow`. - Modified layout and routing in `bridge/layout.tsx` and `bridge/page.tsx`. - Enhanced UI components for better responsiveness and clarity. > ✨ 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 * **New Features** * Added a Bridge configuration page with Overview and Configuration tabs. * Transaction hashes now show as copyable links in the payments table. * **Improvements** * Updated Quickstart cards and labels to streamline onboarding and emphasize bridge setup. * Navigation paths updated to the Bridge configuration flow. * Added a styling hook for link icons and refined payments table layout and semantics. * **Removals** * Removed a legacy breadcrumb component and an old transaction status widget. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
1 parent 6897871 commit 6c4e684

File tree

18 files changed

+224
-254
lines changed

18 files changed

+224
-254
lines changed

apps/dashboard/src/@/components/ui/link-with-copy-button.tsx

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ export function LinkWithCopyButton(props: {
1212
textToCopy: string;
1313
copyTooltip: string;
1414
className?: string;
15+
linkIconClassName?: string;
1516
}) {
1617
const [isCopied, setIsCopied] = useState(false);
1718
const Icon = isCopied ? CheckIcon : CopyIcon;
@@ -37,8 +38,15 @@ export function LinkWithCopyButton(props: {
3738
target="_blank"
3839
className="text-sm text-muted-foreground hover:underline flex items-center gap-1 tabular-nums flex-1 truncate hover:text-foreground group"
3940
>
40-
<span className="max-w-full truncate">{props.textToShow}</span>
41-
<ArrowUpRightIcon className="size-3.5 opacity-70 shrink-0 group-hover:opacity-100" />
41+
<span className="max-w-full truncate tabular-nums">
42+
{props.textToShow}
43+
</span>
44+
<ArrowUpRightIcon
45+
className={cn(
46+
"size-3.5 opacity-70 shrink-0 group-hover:opacity-100",
47+
props.linkIconClassName,
48+
)}
49+
/>
4250
</Link>
4351
</div>
4452
);

apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/bridge/QuickstartSection.client.tsx

Lines changed: 20 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,6 @@
11
"use client";
22

3-
import {
4-
ArrowRightLeftIcon,
5-
BadgeDollarSignIcon,
6-
WebhookIcon,
7-
} from "lucide-react";
3+
import { CodeIcon, WebhookIcon } from "lucide-react";
84
import { FeatureCard } from "../payments/components/FeatureCard.client";
95

106
export function QuickStartSection(props: {
@@ -24,40 +20,43 @@ export function QuickStartSection(props: {
2420
</div>
2521
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6">
2622
<FeatureCard
27-
title="Cross-chain Swap Tokens"
28-
icon={ArrowRightLeftIcon}
29-
setupTime={5}
23+
title="Buy Widget Component"
24+
icon={CodeIcon}
3025
id="swap_tokens"
31-
features={["Swap any token", "Cross-chain swap"]}
32-
description="Swap tokens cross-chain with dedicated swapping endpoints."
26+
features={[
27+
"React component",
28+
"Cross-chain token swaps across 85+ blockchains",
29+
"Fiat onramp support to buy tokens with credit/debit cards",
30+
"Customizable UI",
31+
]}
32+
description={undefined}
3333
link={{
3434
href: `https://portal.thirdweb.com/bridge/swap`,
35-
label: "Setup Swap",
35+
label: "Get Started",
3636
}}
3737
/>
3838

3939
<FeatureCard
40-
title="Earn Fees"
41-
description="Setup fees to earn any time a user swaps or bridges funds."
42-
icon={BadgeDollarSignIcon}
40+
title="Bridge Widget Script"
41+
description={undefined}
42+
icon={CodeIcon}
4343
id="fees"
44-
setupTime={1}
4544
features={[
46-
"Fees on every purchase",
47-
"Custom percentage",
48-
"Directly to your wallet",
45+
"Integrate with a script tag",
46+
"Cross-chain token swaps across 85+ blockchains",
47+
"Fiat onramp support to buy tokens with credit/debit cards",
48+
"Customizable UI",
4949
]}
5050
link={{
51-
href: `/team/${props.teamSlug}/${props.projectSlug}/settings/payments`,
52-
label: "Configure Fees",
51+
href: `/team/${props.teamSlug}/${props.projectSlug}/bridge/configuration`,
52+
label: "Get Started",
5353
}}
5454
/>
5555

5656
<FeatureCard
5757
title="Webhooks"
5858
description="Create Webhooks to get notified on each purchase or transaction."
5959
icon={WebhookIcon}
60-
setupTime={5}
6160
id="webhooks"
6261
features={["Instant events", "Transaction verification"]}
6362
link={{
Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@ import { getAuthToken } from "@/api/auth-token";
33
import { getProject } from "@/api/project/projects";
44
import { getTeamBySlug } from "@/api/team/get-team";
55
import { getFees } from "@/api/universal-bridge/developer";
6+
import { getClientThirdwebClient } from "@/constants/thirdweb-client.client";
67
import { getProjectWallet } from "@/lib/server/project-wallet";
78
import { loginRedirect } from "@/utils/redirects";
8-
import { ProjectSettingsBreadcrumb } from "../_components/project-settings-breadcrumb";
9+
import { RouteDiscovery } from "../RouteDiscovery";
910
import { PayConfig } from "./PayConfig";
1011

1112
export default async function Page(props: {
@@ -21,7 +22,7 @@ export default async function Page(props: {
2122
]);
2223

2324
if (!authToken) {
24-
loginRedirect(`/team/${team_slug}/${project_slug}/settings/payments`);
25+
loginRedirect(`/team/${team_slug}/${project_slug}/bridge/configuration`);
2526
}
2627

2728
if (!team) {
@@ -56,14 +57,13 @@ export default async function Page(props: {
5657
};
5758
}
5859

59-
return (
60-
<div className="flex flex-col gap-5">
61-
<ProjectSettingsBreadcrumb
62-
teamSlug={team_slug}
63-
projectSlug={project_slug}
64-
page="Payments"
65-
/>
60+
const client = getClientThirdwebClient({
61+
jwt: authToken,
62+
teamId: project.teamId,
63+
});
6664

65+
return (
66+
<div className="flex flex-col gap-6">
6767
<PayConfig
6868
fees={fees}
6969
project={project}
@@ -72,6 +72,8 @@ export default async function Page(props: {
7272
teamSlug={team_slug}
7373
authToken={authToken}
7474
/>
75+
76+
<RouteDiscovery client={client} project={project} />
7577
</div>
7678
);
7779
}
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
import { WebhookIcon } from "lucide-react";
2+
import { redirect } from "next/navigation";
3+
import { getAuthToken } from "@/api/auth-token";
4+
import { getProject } from "@/api/project/projects";
5+
import { ProjectPage } from "@/components/blocks/project-page/project-page";
6+
import { getClientThirdwebClient } from "@/constants/thirdweb-client.client";
7+
import { BridgeIcon } from "@/icons/BridgeIcon";
8+
import { loginRedirect } from "@/utils/redirects";
9+
10+
export default async function Layout(props: {
11+
params: Promise<{
12+
team_slug: string;
13+
project_slug: string;
14+
}>;
15+
children: React.ReactNode;
16+
}) {
17+
const [params, authToken] = await Promise.all([props.params, getAuthToken()]);
18+
19+
const project = await getProject(params.team_slug, params.project_slug);
20+
21+
if (!authToken) {
22+
loginRedirect(`/team/${params.team_slug}/${params.project_slug}/bridge`);
23+
}
24+
25+
if (!project) {
26+
redirect(`/team/${params.team_slug}`);
27+
}
28+
29+
const client = getClientThirdwebClient({
30+
jwt: authToken,
31+
teamId: project.teamId,
32+
});
33+
34+
return (
35+
<ProjectPage
36+
header={{
37+
client,
38+
title: "Bridge",
39+
icon: BridgeIcon,
40+
description: (
41+
<>
42+
Bridge lets developers swap and transfer any token across any chain
43+
instantly
44+
</>
45+
),
46+
actions: {
47+
secondary: {
48+
href: `/team/${params.team_slug}/${params.project_slug}/webhooks/payments`,
49+
label: "Webhooks",
50+
icon: <WebhookIcon className="size-3.5 text-muted-foreground" />,
51+
},
52+
},
53+
links: [
54+
{
55+
type: "docs",
56+
href: "https://portal.thirdweb.com/bridge",
57+
},
58+
{
59+
type: "playground",
60+
href: "https://playground.thirdweb.com/bridge/swap-widget",
61+
},
62+
{
63+
type: "api",
64+
href: "https://api.thirdweb.com/reference#tag/bridge",
65+
},
66+
],
67+
}}
68+
tabs={[
69+
{
70+
name: "Overview",
71+
path: `/team/${params.team_slug}/${params.project_slug}/bridge`,
72+
exactMatch: true,
73+
},
74+
{
75+
name: "Configuration",
76+
path: `/team/${params.team_slug}/${params.project_slug}/bridge/configuration`,
77+
},
78+
]}
79+
>
80+
{props.children}
81+
</ProjectPage>
82+
);
83+
}
Lines changed: 20 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,12 @@
1-
import { WebhookIcon } from "lucide-react";
21
import { redirect } from "next/navigation";
32
import { ResponsiveSearchParamsProvider } from "responsive-rsc";
43
import { getAuthToken } from "@/api/auth-token";
54
import { getProject } from "@/api/project/projects";
6-
import { ProjectPage } from "@/components/blocks/project-page/project-page";
75
import { getClientThirdwebClient } from "@/constants/thirdweb-client.client";
8-
import { BridgeIcon } from "@/icons/BridgeIcon";
96
import { loginRedirect } from "@/utils/redirects";
107
import { PayAnalytics } from "../payments/components/PayAnalytics";
118
import { getUniversalBridgeFiltersFromSearchParams } from "../payments/components/time";
129
import { QuickStartSection } from "./QuickstartSection.client";
13-
import { RouteDiscovery } from "./RouteDiscovery";
14-
import { ViewTxStatus } from "./view-tx-status";
1510

1611
export default async function Page(props: {
1712
params: Promise<{
@@ -51,69 +46,27 @@ export default async function Page(props: {
5146
});
5247

5348
return (
54-
<ProjectPage
55-
header={{
56-
client,
57-
title: "Bridge",
58-
icon: BridgeIcon,
59-
description: (
60-
<>
61-
Bridge lets developers swap and transfer any token across any chain
62-
instantly
63-
</>
64-
),
65-
actions: {
66-
secondary: {
67-
href: `/team/${params.team_slug}/${params.project_slug}/webhooks/payments`,
68-
label: "Webhooks",
69-
icon: <WebhookIcon className="size-3.5 text-muted-foreground" />,
70-
},
71-
},
72-
settings: {
73-
href: `/team/${params.team_slug}/${params.project_slug}/settings/payments`,
74-
},
75-
links: [
76-
{
77-
type: "docs",
78-
href: "https://portal.thirdweb.com/bridge",
79-
},
80-
{
81-
type: "playground",
82-
href: "https://playground.thirdweb.com/bridge/swap-widget",
83-
},
84-
{
85-
type: "api",
86-
href: "https://api.thirdweb.com/reference#tag/bridge",
87-
},
88-
],
89-
}}
90-
>
91-
<div className="flex flex-col gap-6">
92-
<ResponsiveSearchParamsProvider value={searchParams}>
93-
<PayAnalytics
94-
client={client}
95-
interval={interval}
96-
projectClientId={project.publishableKey}
97-
projectId={project.id}
98-
range={range}
99-
teamId={project.teamId}
100-
authToken={authToken}
101-
/>
102-
</ResponsiveSearchParamsProvider>
49+
<div className="flex flex-col gap-6">
50+
<ResponsiveSearchParamsProvider value={searchParams}>
51+
<PayAnalytics
52+
client={client}
53+
interval={interval}
54+
projectClientId={project.publishableKey}
55+
projectId={project.id}
56+
range={range}
57+
teamId={project.teamId}
58+
authToken={authToken}
59+
/>
60+
</ResponsiveSearchParamsProvider>
10361

104-
<RouteDiscovery client={client} project={project} />
105-
106-
<ViewTxStatus client={client} />
107-
108-
<div className="pt-4">
109-
<QuickStartSection
110-
projectSlug={params.project_slug}
111-
teamSlug={params.team_slug}
112-
clientId={project.publishableKey}
113-
teamId={project.teamId}
114-
/>
115-
</div>
62+
<div className="pt-4">
63+
<QuickStartSection
64+
projectSlug={params.project_slug}
65+
teamSlug={params.team_slug}
66+
clientId={project.publishableKey}
67+
teamId={project.teamId}
68+
/>
11669
</div>
117-
</ProjectPage>
70+
</div>
11871
);
11972
}

0 commit comments

Comments
 (0)