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
7 changes: 4 additions & 3 deletions apps/dashboard/src/@/api/analytics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -270,9 +270,10 @@ type ActiveStatus = {
ecosystemWallet: boolean;
};

export async function isProjectActive(
params: AnalyticsQueryParams,
): Promise<ActiveStatus> {
export async function isProjectActive(params: {
teamId: string;
projectId: string;
}): Promise<ActiveStatus> {
const searchParams = buildSearchParams(params);
const res = await fetchAnalytics(
`v2/active-usage?${searchParams.toString()}`,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ function IntegrateAPIKeySection({
<div>
<h3>Client ID</h3>
<p className="mb-2 text-muted-foreground text-sm">
Identifies your application.
Identifies your application
</p>

<CopyTextButton
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
"use client";

import { CopyTextButton } from "@/components/ui/CopyTextButton";
import { Button } from "@/components/ui/button";
import { TabButtons } from "@/components/ui/tabs";
import { TrackedLinkTW } from "@/components/ui/tracked-link";
import { ExternalLinkIcon } from "lucide-react";
import { useState } from "react";

export function WaitingForIntegrationCard(props: {
title: string;
clientId: string;
codeTabs: {
code: React.ReactNode;
label: string;
}[];
ctas: {
label: string;
href: string;
trackingLabel: string;
}[];
}) {
const [selectedTab, setSelectedTab] = useState(props.codeTabs[0]?.label);
return (
<div className="rounded-lg border bg-card">
<div className="border-b px-4 py-4 lg:px-6">
<h2 className="font-semibold text-xl tracking-tight">{props.title}</h2>
</div>

<div className="px-4 py-6 lg:p-6">
{/* Client ID */}
<div className="flex w-full flex-col">
<h3 className="font-medium">Client ID</h3>
<p className="mb-2 text-muted-foreground text-sm">
Identifies your application
</p>

<CopyTextButton
textToCopy={props.clientId}
className="!h-auto w-full max-w-[400px] justify-between truncate bg-background px-3 py-3 font-mono"
textToShow={props.clientId}
copyIconPosition="right"
tooltip="Copy Client ID"
/>
</div>

<div className="h-4" />

{/* Code */}
<div>
<TabButtons
tabClassName="!text-sm"
tabs={props.codeTabs.map((tab) => ({
name: tab.label,
onClick: () => setSelectedTab(tab.label),
isActive: tab.label === selectedTab,
}))}
/>
<div className="h-2" />
{props.codeTabs.find((tab) => tab.label === selectedTab)?.code}
</div>
</div>

<div className="flex flex-col gap-3 border-t p-4 lg:flex-row lg:items-center lg:justify-between lg:p-6">
<div className="flex gap-3">
{props.ctas.map((cta) => (
<Button asChild key={cta.label} variant="outline" size="sm">
<TrackedLinkTW
href={cta.href}
key={cta.label}
target="_blank"
className="gap-2"
category="insight-ftux"
label={cta.trackingLabel}
>
{cta.label}
<ExternalLinkIcon className="size-4 text-muted-foreground" />
</TrackedLinkTW>
</Button>
))}
</div>

<p className="flex items-center gap-2 rounded-full border bg-background px-3.5 py-1.5 text-sm">
<span className="!pointer-events-auto relative flex size-2">
<span className="absolute inline-flex h-full w-full animate-ping rounded-full bg-sky-400 opacity-75" />
<span className="relative inline-flex size-2 rounded-full bg-primary" />
</span>
Waiting for integration
</p>
</div>
</div>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import { Button } from "@/components/ui/button";
import {
Code2Icon,
DatabaseIcon,
ExternalLinkIcon,
ZapIcon,
} from "lucide-react";
import Link from "next/link";

export function BlueprintCard() {
const features = [
{
icon: Code2Icon,
title: "Easy-to-Use API",
description: "RESTful endpoints for any application",
},
{
icon: DatabaseIcon,
title: "Managed Infrastructure",
description:
"No need to index blockchains yourself or manage infrastructure and RPC costs.",
},
{
icon: ZapIcon,
title: "Lightning-Fast Queries",
description: "Access any transaction, event or token API data",
},
];

return (
<div className="rounded-lg border bg-card">
{/* header */}
<div className="border-b p-4 lg:px-6 lg:py-4">
<div className="flex items-center justify-between">
<h2 className="font-semibold text-2xl tracking-tight">Blueprints</h2>

<div className="flex items-center gap-2">
<Button asChild variant="outline" className="gap-2 bg-background">
<Link
href="https://portal.thirdweb.com/insight/blueprints"
target="_blank"
>
Docs <ExternalLinkIcon className="size-4" />
</Link>
</Button>
</div>
</div>
</div>

{/* Content */}
<div className="p-4 lg:p-6">
<p className="mb-2 font-semibold text-xl leading-tight tracking-tight lg:mb-1">
Simple endpoints for querying rich blockchain data
</p>
<p className="text-muted-foreground text-sm">
A blueprint is an API that provides access to on-chain data in a
user-friendly format. <br /> No need for ABIs, decoding, RPC, or web3
knowledge required to fetch blockchain data.
</p>

<div className="h-6" />

{/* Features */}
<div className="flex flex-col gap-6">
{features.map((feature) => (
<div key={feature.title} className="flex items-start gap-3">
<div className="rounded-full border p-2">
<feature.icon className="size-4 text-muted-foreground" />
</div>
<div>
<h4 className="font-medium">{feature.title}</h4>
<p className="text-muted-foreground text-sm">
{feature.description}
</p>
</div>
</div>
))}
</div>
</div>

{/* Playground link */}
<div className="border-t p-4 lg:p-6">
<Button className="w-full gap-2" asChild>
<Link href="https://playground.thirdweb.com/insight" target="_blank">
Try Insight blueprints in the playground
<ExternalLinkIcon className="size-4" />
</Link>
</Button>
</div>
</div>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import { CodeServer } from "@/components/ui/code/code.server";
import { isProd } from "@/constants/env";
import { WaitingForIntegrationCard } from "../components/WaitingForIntegrationCard/WaitingForIntegrationCard";

export function InsightFTUX(props: {
clientId: string;
}) {
return (
<WaitingForIntegrationCard
title="Integrate Insight"
clientId={props.clientId}
codeTabs={[
{
label: "JavaScript",
code: (
<CodeServer
code={jsCode(props.clientId)}
className="bg-background"
lang="ts"
/>
),
},
{
label: "Python",
code: (
<CodeServer
code={pythonCode(props.clientId)}
className="bg-background"
lang="python"
/>
),
},
{
label: "Curl",
code: (
<CodeServer
code={curlCode(props.clientId)}
className="bg-background"
lang="bash"
/>
),
},
]}
ctas={[
{
label: "Try on Playground",
href: "https://playground.thirdweb.com/insight",
trackingLabel: "playground",
},
{
label: "View Docs",
href: "https://portal.thirdweb.com/insight",
trackingLabel: "docs",
},
]}
/>
);
}

const twDomain = isProd ? "thirdweb" : "thirdweb-dev";

const jsCode = (clientId: string) => `\
// Example: Get latest 10 transactions on Ethereum
const res = await fetch("https://insight.${twDomain}.com/v1/transactions?chain=1&limit=10&clientId=${clientId}");
const data = await res.json();
`;

const curlCode = (clientId: string) => `\
# Example: Get latest 10 transactions on Ethereum
curl -X GET "https://insight.${twDomain}.com/v1/transactions?chain=1&limit=10&clientId=${clientId}"
`;

const pythonCode = (clientId: string) => `\
# Example: Get latest 10 transactions on Ethereum
import requests

response = requests.get("https://insight.${twDomain}.com/v1/transactions?chain=1&limit=10&clientId=${clientId}")
data = response.json()
`;
Loading
Loading