diff --git a/apps/dashboard/src/@/analytics/report.ts b/apps/dashboard/src/@/analytics/report.ts index 849149dc0b2..21dd3a67e57 100644 --- a/apps/dashboard/src/@/analytics/report.ts +++ b/apps/dashboard/src/@/analytics/report.ts @@ -224,7 +224,11 @@ export function reportChainConfigurationAdded(properties: { // ASSETS // ---------------------------- -type AssetContractType = "DropERC20" | "DropERC1155" | "DropERC721"; +type AssetContractType = + | "DropERC20" + | "DropERC1155" + | "DropERC721" + | "ERC20Asset"; /** * ### Why do we need to report this event? @@ -334,6 +338,15 @@ export function reportAssetCreationSuccessful(properties: { }); } +type CoinCreationStep = + | "erc20-asset:deploy-contract" + | "erc20-asset:airdrop-tokens" + | "erc20-asset:approve-airdrop-tokens" + | "drop-erc20:deploy-contract" + | "drop-erc20:set-claim-conditions" + | "drop-erc20:mint-tokens" + | "drop-erc20:airdrop-tokens"; + /** * ### Why do we need to report this event? * - To track number of failed asset creations @@ -355,11 +368,7 @@ export function reportAssetCreationFailed( } | { assetType: "coin"; - step: - | "deploy-contract" - | "set-claim-conditions" - | "mint-tokens" - | "airdrop-tokens"; + step: CoinCreationStep; } ), ) { diff --git a/apps/dashboard/src/@/components/blocks/NetworkSelectors.tsx b/apps/dashboard/src/@/components/blocks/NetworkSelectors.tsx index e6507f45d6d..c3dd895db25 100644 --- a/apps/dashboard/src/@/components/blocks/NetworkSelectors.tsx +++ b/apps/dashboard/src/@/components/blocks/NetworkSelectors.tsx @@ -29,16 +29,18 @@ export function MultiNetworkSelector(props: { client: ThirdwebClient; chainIds?: number[]; }) { - let { allChains, idToChain } = useAllChainsData(); - - if (props.chainIds && props.chainIds.length > 0) { - allChains = allChains.filter((chain) => - props.chainIds?.includes(chain.chainId), - ); - } + const { allChains, idToChain } = useAllChainsData(); const options = useMemo(() => { - let sortedChains = allChains; + let chains = allChains.filter((chain) => chain.status !== "deprecated"); + + if (props.chainIds && props.chainIds.length > 0) { + chains = allChains.filter((chain) => + props.chainIds?.includes(chain.chainId), + ); + } + + let sortedChains = chains; if (props.priorityChains) { const priorityChainsSet = new Set(); @@ -69,7 +71,13 @@ export function MultiNetworkSelector(props: { value: String(chain.chainId), }; }); - }, [allChains, props.priorityChains, idToChain, props.hideTestnets]); + }, [ + allChains, + props.priorityChains, + idToChain, + props.hideTestnets, + props.chainIds, + ]); const searchFn = useCallback( (option: Option, searchValue: string) => { @@ -155,16 +163,38 @@ export function SingleNetworkSelector(props: { disableDeprecated?: boolean; placeholder?: string; client: ThirdwebClient; + priorityChains?: number[]; }) { const { allChains, idToChain } = useAllChainsData(); const chainsToShow = useMemo(() => { let chains = allChains; + chains = chains.filter((chain) => chain.status !== "deprecated"); + if (props.disableTestnets) { chains = chains.filter((chain) => !chain.testnet); } + if (props.priorityChains) { + const priorityChainsSet = new Set(); + for (const chainId of props.priorityChains || []) { + priorityChainsSet.add(chainId); + } + + const priorityChains = (props.priorityChains || []) + .map((chainId) => { + return idToChain.get(chainId); + }) + .filter((v) => !!v); + + const otherChains = allChains.filter( + (chain) => !priorityChainsSet.has(chain.chainId), + ); + + chains = [...priorityChains, ...otherChains]; + } + if (props.chainIds) { const chainIdSet = new Set(props.chainIds); chains = chains.filter((chain) => chainIdSet.has(chain.chainId)); @@ -180,6 +210,8 @@ export function SingleNetworkSelector(props: { props.chainIds, props.disableTestnets, props.disableDeprecated, + props.priorityChains, + idToChain, ]); const options = useMemo(() => { diff --git a/apps/dashboard/src/@/components/blocks/TokenSelector.tsx b/apps/dashboard/src/@/components/blocks/TokenSelector.tsx index a85978aec36..e6145bf8660 100644 --- a/apps/dashboard/src/@/components/blocks/TokenSelector.tsx +++ b/apps/dashboard/src/@/components/blocks/TokenSelector.tsx @@ -204,7 +204,7 @@ export function TokenSelector(props: { searchPlaceholder="Search by name or symbol" showCheck={props.showCheck} side={props.side} - value={selectedValue} + value={tokensQuery.isPending ? undefined : selectedValue} /> ); } diff --git a/apps/dashboard/src/@/components/blocks/distribution-chart.tsx b/apps/dashboard/src/@/components/blocks/distribution-chart.tsx index 8abb8373679..b34094aadda 100644 --- a/apps/dashboard/src/@/components/blocks/distribution-chart.tsx +++ b/apps/dashboard/src/@/components/blocks/distribution-chart.tsx @@ -3,12 +3,15 @@ import { cn } from "@/lib/utils"; export type Segment = { label: string; percent: number; + value: string; color: string; }; type DistributionBarChartProps = { segments: Segment[]; - title: string; + title?: string; + titleClassName?: string; + barClassName?: string; }; export function DistributionBarChart(props: DistributionBarChartProps) { @@ -21,24 +24,36 @@ export function DistributionBarChart(props: DistributionBarChartProps) { return (
-
-

{props.title}

-
- Total: {totalPercentage}% + {props.title && ( +
+

+ {props.title} +

+
+ Total: {totalPercentage}% +
-
+ )} {/* Bar */} -
+
{props.segments.map((segment) => { return (
0 && "border-r-2 border-background", + )} key={segment.label} style={{ backgroundColor: segment.color, @@ -67,7 +82,7 @@ export function DistributionBarChart(props: DistributionBarChartProps) { "text-destructive-text", )} > - {segment.label}: {segment.percent}% + {segment.label}: {segment.value}

); diff --git a/apps/dashboard/src/@/components/blocks/multi-step-status/multi-step-status.tsx b/apps/dashboard/src/@/components/blocks/multi-step-status/multi-step-status.tsx index 33b6002e809..4ca36385f1e 100644 --- a/apps/dashboard/src/@/components/blocks/multi-step-status/multi-step-status.tsx +++ b/apps/dashboard/src/@/components/blocks/multi-step-status/multi-step-status.tsx @@ -34,7 +34,7 @@ export function MultiStepStatus(props: { }) { return ( -
+
{props.steps.map((step) => (
{step.status.type === "completed" ? ( @@ -46,7 +46,7 @@ export function MultiStepStatus(props: { ) : ( )} -
+

(props: { {step.status.type === "error" ? props.renderError?.(step, step.status.message) || (

-

+

{step.status.message}

+ + + + +
))} @@ -183,6 +222,34 @@ function RecentTransfersUI(props: { ); } +function timestamp(block_timestamp: string) { + return formatDistanceToNow( + new Date( + block_timestamp.endsWith("Z") ? block_timestamp : `${block_timestamp}Z`, + ), + { + addSuffix: true, + }, + ); +} + +function TokenAmount(props: { + amount: string; + decimals: number; + symbol: string; +}) { + return ( +
+ + {tokenAmountFormatter.format( + Number(toTokens(BigInt(props.amount), props.decimals)), + )} + + {props.symbol} +
+ ); +} + function SkeletonRow() { return ( @@ -199,7 +266,7 @@ function SkeletonRow() { - + ); diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/_apis/create-token-on-bridge.ts b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/_apis/create-token-on-bridge.ts new file mode 100644 index 00000000000..2d7eee9fef3 --- /dev/null +++ b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/_apis/create-token-on-bridge.ts @@ -0,0 +1,23 @@ +import type { ThirdwebClient } from "thirdweb"; +import { isProd } from "@/constants/env-utils"; + +export async function createTokenOnUniversalBridge(params: { + chainId: number; + tokenAddress: string; + client: ThirdwebClient; +}) { + const domain = isProd ? "thirdweb.com" : "thirdweb-dev.com"; + const res = await fetch(`https://bridge.${domain}/v1/tokens`, { + body: JSON.stringify({ + chainId: params.chainId.toString(), + tokenAddress: params.tokenAddress, + }), + headers: { + "Content-Type": "application/json", + "x-client-id": params.client.clientId, + }, + method: "POST", + }); + + return res; +} diff --git a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/_common/SocialUrls.tsx b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/_common/SocialUrls.tsx index 9990f1718c7..cb9e8c18494 100644 --- a/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/_common/SocialUrls.tsx +++ b/apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/_common/SocialUrls.tsx @@ -34,7 +34,7 @@ export function SocialUrlsFieldset(props: {

Social URLs

{fields.length > 0 && ( -
+
{fields.map((field, index) => (
+
{props.prevButton && (