Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions apps/dashboard/src/@/components/ui/link-with-copy-button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export function LinkWithCopyButton(props: {
textToCopy: string;
copyTooltip: string;
className?: string;
linkIconClassName?: string;
}) {
const [isCopied, setIsCopied] = useState(false);
const Icon = isCopied ? CheckIcon : CopyIcon;
Expand All @@ -37,8 +38,15 @@ export function LinkWithCopyButton(props: {
target="_blank"
className="text-sm text-muted-foreground hover:underline flex items-center gap-1 tabular-nums flex-1 truncate hover:text-foreground group"
>
<span className="max-w-full truncate">{props.textToShow}</span>
<ArrowUpRightIcon className="size-3.5 opacity-70 shrink-0 group-hover:opacity-100" />
<span className="max-w-full truncate tabular-nums">
{props.textToShow}
</span>
<ArrowUpRightIcon
className={cn(
"size-3.5 opacity-70 shrink-0 group-hover:opacity-100",
props.linkIconClassName,
)}
/>
</Link>
</div>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
"use client";

import {
ArrowRightLeftIcon,
BadgeDollarSignIcon,
WebhookIcon,
} from "lucide-react";
import { CodeIcon, WebhookIcon } from "lucide-react";
import { FeatureCard } from "../payments/components/FeatureCard.client";

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

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

<FeatureCard
title="Webhooks"
description="Create Webhooks to get notified on each purchase or transaction."
icon={WebhookIcon}
setupTime={5}
id="webhooks"
features={["Instant events", "Transaction verification"]}
link={{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ import { getAuthToken } from "@/api/auth-token";
import { getProject } from "@/api/project/projects";
import { getTeamBySlug } from "@/api/team/get-team";
import { getFees } from "@/api/universal-bridge/developer";
import { getClientThirdwebClient } from "@/constants/thirdweb-client.client";
import { getProjectWallet } from "@/lib/server/project-wallet";
import { loginRedirect } from "@/utils/redirects";
import { ProjectSettingsBreadcrumb } from "../_components/project-settings-breadcrumb";
import { RouteDiscovery } from "../RouteDiscovery";
import { PayConfig } from "./PayConfig";

export default async function Page(props: {
Expand All @@ -21,7 +22,7 @@ export default async function Page(props: {
]);

if (!authToken) {
loginRedirect(`/team/${team_slug}/${project_slug}/settings/payments`);
loginRedirect(`/team/${team_slug}/${project_slug}/bridge/configuration`);
}

if (!team) {
Expand Down Expand Up @@ -56,14 +57,13 @@ export default async function Page(props: {
};
}

return (
<div className="flex flex-col gap-5">
<ProjectSettingsBreadcrumb
teamSlug={team_slug}
projectSlug={project_slug}
page="Payments"
/>
const client = getClientThirdwebClient({
jwt: authToken,
teamId: project.teamId,
});

return (
<div className="flex flex-col gap-6">
<PayConfig
fees={fees}
project={project}
Expand All @@ -72,6 +72,8 @@ export default async function Page(props: {
teamSlug={team_slug}
authToken={authToken}
/>

<RouteDiscovery client={client} project={project} />
</div>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import { WebhookIcon } from "lucide-react";
import { redirect } from "next/navigation";
import { getAuthToken } from "@/api/auth-token";
import { getProject } from "@/api/project/projects";
import { ProjectPage } from "@/components/blocks/project-page/project-page";
import { getClientThirdwebClient } from "@/constants/thirdweb-client.client";
import { BridgeIcon } from "@/icons/BridgeIcon";
import { loginRedirect } from "@/utils/redirects";

export default async function Layout(props: {
params: Promise<{
team_slug: string;
project_slug: string;
}>;
children: React.ReactNode;
}) {
const [params, authToken] = await Promise.all([props.params, getAuthToken()]);

const project = await getProject(params.team_slug, params.project_slug);

if (!authToken) {
loginRedirect(`/team/${params.team_slug}/${params.project_slug}/bridge`);
}

if (!project) {
redirect(`/team/${params.team_slug}`);
}

const client = getClientThirdwebClient({
jwt: authToken,
teamId: project.teamId,
});

return (
<ProjectPage
header={{
client,
title: "Bridge",
icon: BridgeIcon,
description: (
<>
Bridge lets developers swap and transfer any token across any chain
instantly
</>
),
actions: {
secondary: {
href: `/team/${params.team_slug}/${params.project_slug}/webhooks/payments`,
label: "Webhooks",
icon: <WebhookIcon className="size-3.5 text-muted-foreground" />,
},
},
links: [
{
type: "docs",
href: "https://portal.thirdweb.com/bridge",
},
{
type: "playground",
href: "https://playground.thirdweb.com/bridge/swap-widget",
},
{
type: "api",
href: "https://api.thirdweb.com/reference#tag/bridge",
},
],
}}
tabs={[
{
name: "Overview",
path: `/team/${params.team_slug}/${params.project_slug}/bridge`,
exactMatch: true,
},
{
name: "Configuration",
path: `/team/${params.team_slug}/${params.project_slug}/bridge/configuration`,
},
]}
>
{props.children}
</ProjectPage>
);
}
Original file line number Diff line number Diff line change
@@ -1,17 +1,12 @@
import { WebhookIcon } from "lucide-react";
import { redirect } from "next/navigation";
import { ResponsiveSearchParamsProvider } from "responsive-rsc";
import { getAuthToken } from "@/api/auth-token";
import { getProject } from "@/api/project/projects";
import { ProjectPage } from "@/components/blocks/project-page/project-page";
import { getClientThirdwebClient } from "@/constants/thirdweb-client.client";
import { BridgeIcon } from "@/icons/BridgeIcon";
import { loginRedirect } from "@/utils/redirects";
import { PayAnalytics } from "../payments/components/PayAnalytics";
import { getUniversalBridgeFiltersFromSearchParams } from "../payments/components/time";
import { QuickStartSection } from "./QuickstartSection.client";
import { RouteDiscovery } from "./RouteDiscovery";
import { ViewTxStatus } from "./view-tx-status";

export default async function Page(props: {
params: Promise<{
Expand Down Expand Up @@ -51,69 +46,27 @@ export default async function Page(props: {
});

return (
<ProjectPage
header={{
client,
title: "Bridge",
icon: BridgeIcon,
description: (
<>
Bridge lets developers swap and transfer any token across any chain
instantly
</>
),
actions: {
secondary: {
href: `/team/${params.team_slug}/${params.project_slug}/webhooks/payments`,
label: "Webhooks",
icon: <WebhookIcon className="size-3.5 text-muted-foreground" />,
},
},
settings: {
href: `/team/${params.team_slug}/${params.project_slug}/settings/payments`,
},
links: [
{
type: "docs",
href: "https://portal.thirdweb.com/bridge",
},
{
type: "playground",
href: "https://playground.thirdweb.com/bridge/swap-widget",
},
{
type: "api",
href: "https://api.thirdweb.com/reference#tag/bridge",
},
],
}}
>
<div className="flex flex-col gap-6">
<ResponsiveSearchParamsProvider value={searchParams}>
<PayAnalytics
client={client}
interval={interval}
projectClientId={project.publishableKey}
projectId={project.id}
range={range}
teamId={project.teamId}
authToken={authToken}
/>
</ResponsiveSearchParamsProvider>
<div className="flex flex-col gap-6">
<ResponsiveSearchParamsProvider value={searchParams}>
<PayAnalytics
client={client}
interval={interval}
projectClientId={project.publishableKey}
projectId={project.id}
range={range}
teamId={project.teamId}
authToken={authToken}
/>
</ResponsiveSearchParamsProvider>

<RouteDiscovery client={client} project={project} />

<ViewTxStatus client={client} />

<div className="pt-4">
<QuickStartSection
projectSlug={params.project_slug}
teamSlug={params.team_slug}
clientId={project.publishableKey}
teamId={project.teamId}
/>
</div>
<div className="pt-4">
<QuickStartSection
projectSlug={params.project_slug}
teamSlug={params.team_slug}
clientId={project.publishableKey}
teamId={project.teamId}
/>
</div>
</ProjectPage>
</div>
);
}
Loading
Loading