Skip to content

Commit 88bceb7

Browse files
authored
Merge branch 'main' into ph/teamsEngineRoutes
2 parents 689fd31 + d1845f3 commit 88bceb7

File tree

104 files changed

+2203
-671
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

104 files changed

+2203
-671
lines changed

.changeset/clever-carrots-march.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"thirdweb": minor
3+
---
4+
5+
Add headless components: ChainProvider, ChainIcon & ChainName

apps/dashboard/src/@/api/analytics.ts

Lines changed: 47 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,12 @@
11
import { fetchAnalytics } from "data/analytics/fetch-analytics";
2-
3-
export interface WalletStats {
4-
date: string;
5-
uniqueWalletsConnected: number;
6-
totalConnections: number;
7-
walletType: string;
8-
}
9-
10-
export interface WalletUserStats {
11-
date: string;
12-
newUsers: number;
13-
returningUsers: number;
14-
totalUsers: number;
15-
}
16-
17-
export interface InAppWalletStats {
18-
date: string;
19-
authenticationMethod: string;
20-
uniqueWalletsConnected: number;
21-
}
22-
23-
export interface EcosystemWalletStats extends InAppWalletStats {}
24-
25-
export interface UserOpStats {
26-
date: string;
27-
successful: number;
28-
failed: number;
29-
sponsoredUsd: number;
30-
chainId?: string;
31-
}
32-
33-
interface AnalyticsQueryParams {
34-
clientId?: string;
35-
accountId?: string;
36-
from?: Date;
37-
to?: Date;
38-
period?: "day" | "week" | "month" | "year" | "all";
39-
}
2+
import type {
3+
AnalyticsQueryParams,
4+
InAppWalletStats,
5+
RpcMethodStats,
6+
UserOpStats,
7+
WalletStats,
8+
WalletUserStats,
9+
} from "types/analytics";
4010

4111
function buildSearchParams(params: AnalyticsQueryParams): URLSearchParams {
4212
const searchParams = new URLSearchParams();
@@ -115,6 +85,27 @@ export async function getUserOpUsage(
11585
return json.data as UserOpStats[];
11686
}
11787

88+
export async function getRpcMethodUsage(
89+
params: AnalyticsQueryParams,
90+
): Promise<RpcMethodStats[]> {
91+
const searchParams = buildSearchParams(params);
92+
const res = await fetchAnalytics(
93+
`v1/rpc/evm-methods?${searchParams.toString()}`,
94+
{
95+
method: "GET",
96+
headers: { "Content-Type": "application/json" },
97+
},
98+
);
99+
100+
if (res?.status !== 200) {
101+
console.error("Failed to fetch RPC method usage");
102+
return [];
103+
}
104+
105+
const json = await res.json();
106+
return json.data as RpcMethodStats[];
107+
}
108+
118109
export async function getWalletUsers(
119110
params: AnalyticsQueryParams,
120111
): Promise<WalletUserStats[]> {
@@ -135,3 +126,21 @@ export async function getWalletUsers(
135126
const json = await res.json();
136127
return json.data as WalletUserStats[];
137128
}
129+
130+
export async function isProjectActive(
131+
params: AnalyticsQueryParams,
132+
): Promise<boolean> {
133+
const searchParams = buildSearchParams(params);
134+
const res = await fetchAnalytics(`v1/active?${searchParams.toString()}`, {
135+
method: "GET",
136+
headers: { "Content-Type": "application/json" },
137+
});
138+
139+
if (res?.status !== 200) {
140+
console.error("Failed to fetch project active status");
141+
return false;
142+
}
143+
144+
const json = await res.json();
145+
return json.data.isActive as boolean;
146+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { cn } from "@/lib/utils";
2+
3+
export function TextDivider(props: {
4+
text: string;
5+
className?: string;
6+
}) {
7+
return (
8+
<div
9+
className={cn(
10+
"flex items-center text-muted-foreground text-sm",
11+
props.className,
12+
)}
13+
>
14+
<span className="h-[1px] flex-1 bg-border" />
15+
<span className="mx-4">{props.text}</span>
16+
<span className="h-[1px] flex-1 bg-border" />
17+
</div>
18+
);
19+
}

apps/dashboard/src/components/homepage/sections/PricingCard.tsx renamed to apps/dashboard/src/@/components/blocks/pricing-card.tsx

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
import type { Team } from "@/api/team";
2+
import { CheckoutButton } from "@/components/billing";
23
import { Badge } from "@/components/ui/badge";
34
import { Button } from "@/components/ui/button";
5+
import { ToolTipLabel } from "@/components/ui/tooltip";
46
import { TrackedLinkTW } from "@/components/ui/tracked-link";
57
import { cn } from "@/lib/utils";
8+
import { CheckIcon, CircleDollarSignIcon } from "lucide-react";
69
import type React from "react";
710
import { TEAM_PLANS } from "utils/pricing";
8-
import { CheckoutButton } from "../../../@/components/billing";
911
import { remainingDays } from "../../../utils/date-utils";
10-
import { FeatureItem } from "./FeatureItem";
1112

1213
type ButtonProps = React.ComponentProps<typeof Button>;
1314

@@ -31,6 +32,7 @@ type PricingCardProps = {
3132
current?: boolean;
3233
canTrialGrowth?: boolean;
3334
activeTrialEndsAt?: string;
35+
redirectPath: string;
3436
};
3537

3638
export const PricingCard: React.FC<PricingCardProps> = ({
@@ -41,6 +43,7 @@ export const PricingCard: React.FC<PricingCardProps> = ({
4143
current = false,
4244
canTrialGrowth = false,
4345
activeTrialEndsAt,
46+
redirectPath,
4447
}) => {
4548
const plan = TEAM_PLANS[billingPlan];
4649
const isCustomPrice = typeof plan.price === "string";
@@ -128,6 +131,7 @@ export const PricingCard: React.FC<PricingCardProps> = ({
128131
variant={cta.variant || "outline"}
129132
teamSlug={teamSlug}
130133
sku={billingPlan === "starter" ? "plan:starter" : "plan:growth"}
134+
redirectPath={redirectPath}
131135
>
132136
{cta.title}
133137
</CheckoutButton>
@@ -154,3 +158,30 @@ export const PricingCard: React.FC<PricingCardProps> = ({
154158
</div>
155159
);
156160
};
161+
162+
type FeatureItemProps = {
163+
text: string | string[];
164+
};
165+
166+
function FeatureItem({ text }: FeatureItemProps) {
167+
const titleStr = Array.isArray(text) ? text[0] : text;
168+
169+
return (
170+
<div className="flex items-center gap-2">
171+
<CheckIcon className="size-4 shrink-0 text-green-500" />
172+
{Array.isArray(text) ? (
173+
<div className="flex items-center gap-2">
174+
<p className="text-muted-foreground">
175+
{titleStr}{" "}
176+
<span className="text-muted-foreground md:hidden">{text[1]}</span>
177+
</p>
178+
<ToolTipLabel label={text[1]}>
179+
<CircleDollarSignIcon className="hidden size-4 text-muted-foreground md:block" />
180+
</ToolTipLabel>
181+
</div>
182+
) : (
183+
<p className="text-muted-foreground">{titleStr}</p>
184+
)}
185+
</div>
186+
);
187+
}

apps/dashboard/src/@/components/ui/inline-code.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ export function InlineCode({
77
return (
88
<code
99
className={cn(
10-
"inline-block rounded bg-muted px-2 font-mono text-sm",
10+
"mx-0.5 inline rounded-lg border border-border px-1.5 py-[3px] font-mono text-[0.85em] text-foreground",
1111
className,
1212
)}
1313
>

apps/dashboard/src/@/constants/env.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,14 +34,14 @@ export const THIRDWEB_ACCESS_TOKEN = process.env.THIRDWEB_ACCESS_TOKEN;
3434
// Comma-separated list of chain IDs to disable faucet for.
3535
export const DISABLE_FAUCET_CHAIN_IDS = process.env.DISABLE_FAUCET_CHAIN_IDS;
3636

37+
export const BASE_URL = isProd
38+
? "https://thirdweb.com"
39+
: (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL
40+
? `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`
41+
: "http://localhost:3000") || "https://thirdweb-dev.com";
42+
3743
export function getAbsoluteUrlFromPath(path: string) {
38-
const url = new URL(
39-
isProd
40-
? "https://thirdweb.com"
41-
: (process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL
42-
? `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`
43-
: "http://localhost:3000") || "https://thirdweb-dev.com",
44-
);
44+
const url = new URL(BASE_URL);
4545

4646
url.pathname = path;
4747
return url;

apps/dashboard/src/@3rdweb-sdk/react/components/connect-wallet/index.tsx

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import {
2121
useConnectModal,
2222
} from "thirdweb/react";
2323
import { useFavoriteChainIds } from "../../../../app/(dashboard)/(chain)/components/client/star-button";
24+
import { doLogout } from "../../../../app/login/auth-actions";
2425
import { LazyConfigureNetworkModal } from "../../../../components/configure-networks/LazyConfigureNetworkModal";
2526
import { useAllChainsData } from "../../../../hooks/chains/allChains";
2627
import {
@@ -174,10 +175,7 @@ export const CustomConnectWallet = (props: {
174175
}}
175176
onDisconnect={async () => {
176177
try {
177-
// log out the user
178-
await fetch("/api/auth/logout", {
179-
method: "POST",
180-
});
178+
await doLogout();
181179
} catch (err) {
182180
console.error("Failed to log out", err);
183181
}

apps/dashboard/src/@3rdweb-sdk/react/hooks/useApi.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import type { UserOpStats } from "@/api/analytics";
21
import type { Team } from "@/api/team";
32
import {
43
type Query,
@@ -9,6 +8,7 @@ import {
98
import { THIRDWEB_ANALYTICS_API_HOST, THIRDWEB_API_HOST } from "constants/urls";
109
import { useAllChainsData } from "hooks/chains/allChains";
1110
import invariant from "tiny-invariant";
11+
import type { UserOpStats } from "types/analytics";
1212
import { accountKeys, apiKeys, authorizedWallets } from "../cache-keys";
1313
import { useLoggedInUser } from "./useLoggedInUser";
1414

apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/(chainPage)/components/client/FaucetButton.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import { toUnits } from "thirdweb";
2323
import type { ChainMetadata } from "thirdweb/chains";
2424
import { useActiveAccount, useWalletBalance } from "thirdweb/react";
2525
import { z } from "zod";
26-
import { isOnboardingComplete } from "../../../../../../login/isOnboardingRequired";
26+
import { isOnboardingComplete } from "../../../../../../login/onboarding/isOnboardingRequired";
2727

2828
function formatTime(seconds: number) {
2929
const rtf = new Intl.RelativeTimeFormat("en", { numeric: "auto" });

apps/dashboard/src/app/account/components/AccountHeader.tsx

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { useAccount } from "@3rdweb-sdk/react/hooks/useApi";
99
import { useCallback, useState } from "react";
1010
import { useActiveWallet, useDisconnect } from "thirdweb/react";
1111
import { LazyCreateAPIKeyDialog } from "../../../components/settings/ApiKeys/Create/LazyCreateAPIKeyDialog";
12+
import { doLogout } from "../../login/auth-actions";
1213
import {
1314
type AccountHeaderCompProps,
1415
AccountHeaderDesktopUI,
@@ -27,11 +28,8 @@ export function AccountHeader(props: {
2728
const { disconnect } = useDisconnect();
2829

2930
const logout = useCallback(async () => {
30-
// log out the user
3131
try {
32-
await fetch("/api/auth/logout", {
33-
method: "POST",
34-
});
32+
await doLogout();
3533
if (wallet) {
3634
disconnect(wallet);
3735
}

0 commit comments

Comments
 (0)