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
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ export function QuickStartSection(props: {
id="webhooks"
features={["Instant events", "Transaction verification"]}
link={{
href: `/team/${props.teamSlug}/${props.projectSlug}/webhooks/payments`,
href: `/team/${props.teamSlug}/${props.projectSlug}/bridge/webhooks`,
label: "Setup Webhooks",
}}
/>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { WebhookIcon } from "lucide-react";
import { redirect } from "next/navigation";
import { getAuthToken } from "@/api/auth-token";
import { getProject } from "@/api/project/projects";
Expand Down Expand Up @@ -43,13 +42,7 @@ export default async function Layout(props: {
instantly
</>
),
actions: {
secondary: {
href: `/team/${params.team_slug}/${params.project_slug}/webhooks/payments`,
label: "Webhooks",
icon: <WebhookIcon className="size-3.5 text-muted-foreground" />,
},
},
actions: null,
links: [
{
type: "docs",
Expand All @@ -75,6 +68,10 @@ export default async function Layout(props: {
name: "Configuration",
path: `/team/${params.team_slug}/${params.project_slug}/bridge/configuration`,
},
{
name: "Webhooks",
path: `/team/${params.team_slug}/${params.project_slug}/bridge/webhooks`,
},
]}
>
{props.children}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export default async function Page(props: {
<BreadcrumbItem>
<BreadcrumbLink asChild>
<Link
href={`/team/${params.team_slug}/${params.project_slug}/webhooks/payments`}
href={`/team/${params.team_slug}/${params.project_slug}/bridge/webhooks`}
>
Webhooks
</Link>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
PlusIcon,
TrashIcon,
WebhookIcon,
XIcon,
} from "lucide-react";
import Link from "next/link";
import { type PropsWithChildren, useMemo, useState } from "react";
Expand Down Expand Up @@ -95,9 +96,14 @@ export function PayWebhooksPage(props: PayWebhooksPageProps) {
if (!webhooksQuery.data?.length) {
return (
<div className="flex flex-col items-center gap-6 rounded-lg border border-border bg-card p-8 text-center">
<div className="flex flex-col gap-2">
<h2 className="font-semibold text-xl">No webhooks configured</h2>
<p className="text-sm text-muted-foreground">
<div className="flex flex-col items-center">
<div className="rounded-full p-2 border bg-background inline-flex mb-3">
<XIcon className="size-4 text-muted-foreground" />
</div>
<h2 className="font-semibold text-base mb-1">
No webhooks configured
</h2>
<p className="text-muted-foreground text-sm">
Create a webhook to receive notifications for bridge, swap or onramp
events.
</p>
Expand Down Expand Up @@ -126,7 +132,7 @@ export function PayWebhooksPage(props: PayWebhooksPageProps) {
webhook={webhook}
clientId={props.clientId}
teamId={props.teamId}
layoutPath={`/team/${props.teamSlug}/${props.projectSlug}/webhooks/payments`}
layoutPath={`/team/${props.teamSlug}/${props.projectSlug}/bridge/webhooks`}
/>
))}
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { notFound } from "next/navigation";
import { getAuthToken } from "@/api/auth-token";
import { getProject } from "@/api/project/projects";
import { PayWebhooksPage } from "../../payments/webhooks/components/webhooks.client";
import { PayWebhooksPage } from "./components/webhooks.client";

export default async function Page(props: {
params: Promise<{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import {
DoorOpenIcon,
HomeIcon,
Settings2Icon,
WebhookIcon,
} from "lucide-react";
import {
FullWidthSidebarLayout,
Expand Down Expand Up @@ -136,14 +135,6 @@ export function ProjectSidebarLayout(props: {
{
separator: true,
},
{
href: `${props.layoutPath}/webhooks/contracts`,
icon: WebhookIcon,
isActive: (pathname) => {
return pathname.startsWith(`${props.layoutPath}/webhooks`);
},
label: "Webhooks",
},
{
href: `${props.layoutPath}/settings`,
icon: Settings2Icon,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export function AdvancedSection({
id="webhooks"
features={["Instant events", "Transaction verification"]}
link={{
href: `/team/${teamSlug}/${projectSlug}/webhooks/payments`,
href: `/team/${teamSlug}/${projectSlug}/bridge/webhooks`,
label: "Setup Webhooks",
}}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ export default async function Page(props: {
),
},
secondary: {
href: `/team/${params.team_slug}/${params.project_slug}/webhooks/payments`,
href: `/team/${params.team_slug}/${params.project_slug}/bridge/webhooks`,
label: "Webhooks",
icon: <WebhookIcon className="size-3.5 text-muted-foreground" />,
},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,10 @@
import { Button } from "@workspace/ui/components/button";
import { PlusIcon } from "lucide-react";
import { redirect } from "next/navigation";
import { Suspense } from "react";
import type { ThirdwebClient } from "thirdweb";
import { getAuthToken } from "@/api/auth-token";
import { getFilteredProjectContracts } from "@/api/project/getSortedDeployedContracts";
import { getProject } from "@/api/project/projects";
import { getTeamBySlug } from "@/api/team/get-team";
import { ClientOnly } from "@/components/blocks/client-only";
import { ProjectPage } from "@/components/blocks/project-page/project-page";
import { GenericLoadingPage } from "@/components/blocks/skeletons/GenericLoadingPage";
import { ContractTable } from "@/components/contract-components/tables/contract-table";
import {
Dialog,
DialogContent,
Expand All @@ -21,10 +15,11 @@ import {
import { getClientThirdwebClient } from "@/constants/thirdweb-client.client";
import { TokenIcon } from "@/icons/TokenIcon";
import { loginRedirect } from "@/utils/redirects";
import { Cards, ImportTokenButton } from "./cards";
import { Cards, ImportTokenButton } from "../cards";

export default async function Page(props: {
export default async function Layout(props: {
params: Promise<{ team_slug: string; project_slug: string }>;
children: React.ReactNode;
}) {
const params = await props.params;

Expand Down Expand Up @@ -110,48 +105,19 @@ export default async function Page(props: {
},
],
}}
tabs={[
{
name: "Overview",
path: `/team/${params.team_slug}/${params.project_slug}/tokens`,
exactMatch: true,
},
{
name: "Webhooks",
path: `/team/${params.team_slug}/${params.project_slug}/tokens/webhooks`,
},
]}
>
<Suspense fallback={<GenericLoadingPage />}>
<AssetsPageAsync
authToken={authToken}
client={client}
projectId={project.id}
projectSlug={params.project_slug}
teamId={team.id}
teamSlug={params.team_slug}
/>
</Suspense>
{props.children}
</ProjectPage>
);
}

async function AssetsPageAsync(props: {
teamId: string;
projectId: string;
authToken: string;
client: ThirdwebClient;
teamSlug: string;
projectSlug: string;
}) {
const deployedContracts = await getFilteredProjectContracts({
authToken: props.authToken,
type: "token-contracts",
projectId: props.projectId,
teamId: props.teamId,
});

return (
<ClientOnly ssr={<GenericLoadingPage />}>
<ContractTable
client={props.client}
contracts={deployedContracts}
pageSize={10}
projectId={props.projectId}
projectSlug={props.projectSlug}
teamId={props.teamId}
teamSlug={props.teamSlug}
variant="asset"
/>
</ClientOnly>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import { redirect } from "next/navigation";
import { Suspense } from "react";
import type { ThirdwebClient } from "thirdweb";
import { getAuthToken } from "@/api/auth-token";
import { getFilteredProjectContracts } from "@/api/project/getSortedDeployedContracts";
import { getProject } from "@/api/project/projects";
import { getTeamBySlug } from "@/api/team/get-team";
import { ClientOnly } from "@/components/blocks/client-only";
import { GenericLoadingPage } from "@/components/blocks/skeletons/GenericLoadingPage";
import { ContractTable } from "@/components/contract-components/tables/contract-table";
import { getClientThirdwebClient } from "@/constants/thirdweb-client.client";
import { loginRedirect } from "@/utils/redirects";

export default async function Page(props: {
params: Promise<{ team_slug: string; project_slug: string }>;
}) {
const params = await props.params;

const [authToken, team, project] = await Promise.all([
getAuthToken(),
getTeamBySlug(params.team_slug),
getProject(params.team_slug, params.project_slug),
]);
if (!authToken) {
loginRedirect(`/team/${params.team_slug}/${params.project_slug}/tokens`);
}

if (!team) {
redirect("/team");
}

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

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

return (
<Suspense fallback={<GenericLoadingPage />}>
<AssetsPageAsync
authToken={authToken}
client={client}
projectId={project.id}
projectSlug={params.project_slug}
teamId={team.id}
teamSlug={params.team_slug}
/>
</Suspense>
);
}

async function AssetsPageAsync(props: {
teamId: string;
projectId: string;
authToken: string;
client: ThirdwebClient;
teamSlug: string;
projectSlug: string;
}) {
const deployedContracts = await getFilteredProjectContracts({
authToken: props.authToken,
type: "token-contracts",
projectId: props.projectId,
teamId: props.teamId,
});

return (
<ClientOnly ssr={<GenericLoadingPage />}>
<ContractTable
client={props.client}
contracts={deployedContracts}
pageSize={10}
projectId={props.projectId}
projectSlug={props.projectSlug}
teamId={props.teamId}
teamSlug={props.teamSlug}
variant="asset"
/>
</ClientOnly>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
import { Input } from "@/components/ui/input";
import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group";
import { cn } from "@/lib/utils";
import type { WebhookFormValues } from "../utils/webhookTypes";
import type { WebhookFormValues } from "./utils/webhookTypes";

interface BasicInfoStepProps {
form: UseFormReturn<WebhookFormValues>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,26 +16,26 @@ import {
} from "@/components/ui/dialog";
import { Form } from "@/components/ui/form";
import { useDashboardRouter } from "@/lib/DashboardRouter";
import { useAbiMultiFetch } from "../hooks/useAbiProcessing";
import { useTestWebhook } from "../hooks/useTestWebhook";
import BasicInfoStep from "./BasicInfoStep";
import { FilterDetailsStep } from "./FilterDetailsStep";
import ReviewStep from "./ReviewStep";
import { useAbiMultiFetch } from "./useAbiProcessing";
import { useTestWebhook } from "./useTestWebhook";
import {
extractEventSignatures,
extractFunctionSignatures,
} from "../utils/abiUtils";
import type { WebhookPayload } from "../utils/webhookPayloadUtils";
} from "./utils/abiUtils";
import type { WebhookPayload } from "./utils/webhookPayloadUtils";
import {
buildEventWebhookPayload,
buildTransactionWebhookPayload,
} from "../utils/webhookPayloadUtils";
} from "./utils/webhookPayloadUtils";
import {
type WebhookFormStep,
WebhookFormSteps,
type WebhookFormValues,
webhookFormSchema,
} from "../utils/webhookTypes";
import BasicInfoStep from "./BasicInfoStep";
import { FilterDetailsStep } from "./FilterDetailsStep";
import ReviewStep from "./ReviewStep";
} from "./utils/webhookTypes";

interface CreateWebhookModalProps {
projectClientId: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,13 @@ import {
import { Input } from "@/components/ui/input";
import { Spinner } from "@/components/ui/Spinner";
import { Textarea } from "@/components/ui/textarea";
import { truncateMiddle } from "../utils/abiUtils";
import { truncateMiddle } from "./utils/abiUtils";
import type {
AbiData,
EventSignature,
FunctionSignature,
WebhookFormValues,
} from "../utils/webhookTypes";
} from "./utils/webhookTypes";

interface FilterDetailsStepProps {
form: UseFormReturn<WebhookFormValues>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import { CheckIcon, PlayIcon, XIcon } from "lucide-react";
import type { UseFormReturn } from "react-hook-form";
import { Button } from "@/components/ui/button";
import { Spinner } from "@/components/ui/Spinner";
import { truncateMiddle } from "../utils/abiUtils";
import type { WebhookFormValues } from "../utils/webhookTypes";
import { truncateMiddle } from "./utils/abiUtils";
import type { WebhookFormValues } from "./utils/webhookTypes";

interface WebhookTestResult {
status: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ import { Button } from "@/components/ui/button";
import { CopyTextButton } from "@/components/ui/CopyTextButton";
import { Spinner } from "@/components/ui/Spinner";
import { useDashboardRouter } from "@/lib/DashboardRouter";
import { useTestWebhook } from "../hooks/useTestWebhook";
import { CreateContractWebhookButton } from "./CreateWebhookModal";
import { RelativeTime } from "./RelativeTime";
import { useTestWebhook } from "./useTestWebhook";

function getEventType(filters: WebhookFilters): string {
if (!filters || typeof filters !== "object") {
Expand Down
Loading
Loading