Skip to content

Commit b22b7b7

Browse files
MananTankjakeloo
andauthored
[TOOL-4689] Dashboard: Update coin creation flow (#7344)
Signed-off-by: Manan Tank <manantankm@gmail.com> Co-authored-by: Jake Loo <2171134+jakeloo@users.noreply.github.com>
1 parent 3cf7fe4 commit b22b7b7

File tree

37 files changed

+2025
-504
lines changed

37 files changed

+2025
-504
lines changed

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

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,11 @@ export function reportChainConfigurationAdded(properties: {
224224
// ASSETS
225225
// ----------------------------
226226

227-
type AssetContractType = "DropERC20" | "DropERC1155" | "DropERC721";
227+
type AssetContractType =
228+
| "DropERC20"
229+
| "DropERC1155"
230+
| "DropERC721"
231+
| "ERC20Asset";
228232

229233
/**
230234
* ### Why do we need to report this event?
@@ -334,6 +338,15 @@ export function reportAssetCreationSuccessful(properties: {
334338
});
335339
}
336340

341+
type CoinCreationStep =
342+
| "erc20-asset:deploy-contract"
343+
| "erc20-asset:airdrop-tokens"
344+
| "erc20-asset:approve-airdrop-tokens"
345+
| "drop-erc20:deploy-contract"
346+
| "drop-erc20:set-claim-conditions"
347+
| "drop-erc20:mint-tokens"
348+
| "drop-erc20:airdrop-tokens";
349+
337350
/**
338351
* ### Why do we need to report this event?
339352
* - To track number of failed asset creations
@@ -355,11 +368,7 @@ export function reportAssetCreationFailed(
355368
}
356369
| {
357370
assetType: "coin";
358-
step:
359-
| "deploy-contract"
360-
| "set-claim-conditions"
361-
| "mint-tokens"
362-
| "airdrop-tokens";
371+
step: CoinCreationStep;
363372
}
364373
),
365374
) {

apps/dashboard/src/@/components/blocks/NetworkSelectors.tsx

Lines changed: 41 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -29,16 +29,18 @@ export function MultiNetworkSelector(props: {
2929
client: ThirdwebClient;
3030
chainIds?: number[];
3131
}) {
32-
let { allChains, idToChain } = useAllChainsData();
33-
34-
if (props.chainIds && props.chainIds.length > 0) {
35-
allChains = allChains.filter((chain) =>
36-
props.chainIds?.includes(chain.chainId),
37-
);
38-
}
32+
const { allChains, idToChain } = useAllChainsData();
3933

4034
const options = useMemo(() => {
41-
let sortedChains = allChains;
35+
let chains = allChains.filter((chain) => chain.status !== "deprecated");
36+
37+
if (props.chainIds && props.chainIds.length > 0) {
38+
chains = allChains.filter((chain) =>
39+
props.chainIds?.includes(chain.chainId),
40+
);
41+
}
42+
43+
let sortedChains = chains;
4244

4345
if (props.priorityChains) {
4446
const priorityChainsSet = new Set();
@@ -69,7 +71,13 @@ export function MultiNetworkSelector(props: {
6971
value: String(chain.chainId),
7072
};
7173
});
72-
}, [allChains, props.priorityChains, idToChain, props.hideTestnets]);
74+
}, [
75+
allChains,
76+
props.priorityChains,
77+
idToChain,
78+
props.hideTestnets,
79+
props.chainIds,
80+
]);
7381

7482
const searchFn = useCallback(
7583
(option: Option, searchValue: string) => {
@@ -155,16 +163,38 @@ export function SingleNetworkSelector(props: {
155163
disableDeprecated?: boolean;
156164
placeholder?: string;
157165
client: ThirdwebClient;
166+
priorityChains?: number[];
158167
}) {
159168
const { allChains, idToChain } = useAllChainsData();
160169

161170
const chainsToShow = useMemo(() => {
162171
let chains = allChains;
163172

173+
chains = chains.filter((chain) => chain.status !== "deprecated");
174+
164175
if (props.disableTestnets) {
165176
chains = chains.filter((chain) => !chain.testnet);
166177
}
167178

179+
if (props.priorityChains) {
180+
const priorityChainsSet = new Set();
181+
for (const chainId of props.priorityChains || []) {
182+
priorityChainsSet.add(chainId);
183+
}
184+
185+
const priorityChains = (props.priorityChains || [])
186+
.map((chainId) => {
187+
return idToChain.get(chainId);
188+
})
189+
.filter((v) => !!v);
190+
191+
const otherChains = allChains.filter(
192+
(chain) => !priorityChainsSet.has(chain.chainId),
193+
);
194+
195+
chains = [...priorityChains, ...otherChains];
196+
}
197+
168198
if (props.chainIds) {
169199
const chainIdSet = new Set(props.chainIds);
170200
chains = chains.filter((chain) => chainIdSet.has(chain.chainId));
@@ -180,6 +210,8 @@ export function SingleNetworkSelector(props: {
180210
props.chainIds,
181211
props.disableTestnets,
182212
props.disableDeprecated,
213+
props.priorityChains,
214+
idToChain,
183215
]);
184216

185217
const options = useMemo(() => {

apps/dashboard/src/@/components/blocks/TokenSelector.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ export function TokenSelector(props: {
204204
searchPlaceholder="Search by name or symbol"
205205
showCheck={props.showCheck}
206206
side={props.side}
207-
value={selectedValue}
207+
value={tokensQuery.isPending ? undefined : selectedValue}
208208
/>
209209
);
210210
}

apps/dashboard/src/@/components/blocks/distribution-chart.tsx

Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,15 @@ import { cn } from "@/lib/utils";
33
export type Segment = {
44
label: string;
55
percent: number;
6+
value: string;
67
color: string;
78
};
89

910
type DistributionBarChartProps = {
1011
segments: Segment[];
11-
title: string;
12+
title?: string;
13+
titleClassName?: string;
14+
barClassName?: string;
1215
};
1316

1417
export function DistributionBarChart(props: DistributionBarChartProps) {
@@ -21,24 +24,36 @@ export function DistributionBarChart(props: DistributionBarChartProps) {
2124

2225
return (
2326
<div>
24-
<div className="mb-2 flex items-center justify-between">
25-
<h3 className="font-medium text-sm">{props.title}</h3>
26-
<div
27-
className={cn(
28-
"font-medium text-muted-foreground text-sm",
29-
invalidTotalPercentage && "text-red-500",
30-
)}
31-
>
32-
Total: {totalPercentage}%
27+
{props.title && (
28+
<div className="mb-2 flex items-center justify-between">
29+
<h3 className={cn("font-medium text-sm", props.titleClassName)}>
30+
{props.title}
31+
</h3>
32+
<div
33+
className={cn(
34+
"font-medium text-muted-foreground text-sm",
35+
invalidTotalPercentage && "text-red-500",
36+
)}
37+
>
38+
Total: {totalPercentage}%
39+
</div>
3340
</div>
34-
</div>
41+
)}
3542

3643
{/* Bar */}
37-
<div className="flex h-3 overflow-hidden rounded-lg">
44+
<div
45+
className={cn(
46+
"flex h-3 overflow-hidden rounded-lg",
47+
props.barClassName,
48+
)}
49+
>
3850
{props.segments.map((segment) => {
3951
return (
4052
<div
41-
className="flex h-full items-center justify-center transition-all duration-200"
53+
className={cn(
54+
"flex h-full items-center justify-center transition-all duration-200",
55+
segment.percent > 0 && "border-r-2 border-background",
56+
)}
4257
key={segment.label}
4358
style={{
4459
backgroundColor: segment.color,
@@ -67,7 +82,7 @@ export function DistributionBarChart(props: DistributionBarChartProps) {
6782
"text-destructive-text",
6883
)}
6984
>
70-
{segment.label}: {segment.percent}%
85+
{segment.label}: {segment.value}
7186
</p>
7287
</div>
7388
);

apps/dashboard/src/@/components/blocks/multi-step-status/multi-step-status.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ export function MultiStepStatus<T extends string>(props: {
3434
}) {
3535
return (
3636
<DynamicHeight>
37-
<div className="space-y-4">
37+
<div className="space-y-4 overflow-hidden">
3838
{props.steps.map((step) => (
3939
<div className="flex items-start space-x-3 " key={step.label}>
4040
{step.status.type === "completed" ? (
@@ -46,7 +46,7 @@ export function MultiStepStatus<T extends string>(props: {
4646
) : (
4747
<CircleIcon className="mt-0.5 size-5 flex-shrink-0 text-muted-foreground/70" />
4848
)}
49-
<div className="flex-1">
49+
<div className="grow">
5050
<p
5151
className={`font-medium ${
5252
step.status.type === "pending"
@@ -73,7 +73,7 @@ export function MultiStepStatus<T extends string>(props: {
7373
{step.status.type === "error"
7474
? props.renderError?.(step, step.status.message) || (
7575
<div className="mt-1 space-y-2">
76-
<p className="mb-1 text-red-500 text-sm">
76+
<p className="mb-1 text-red-500 text-sm whitespace-pre-wrap break-all">
7777
{step.status.message}
7878
</p>
7979
<Button

apps/dashboard/src/@/components/blocks/wallet-address.tsx

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
"use client";
2-
import { CheckIcon, CopyIcon, XIcon } from "lucide-react";
2+
import { CheckIcon, CircleSlashIcon, CopyIcon, XIcon } from "lucide-react";
33
import { useMemo } from "react";
44
import { isAddress, type ThirdwebClient, ZERO_ADDRESS } from "thirdweb";
55
import { Blobbie, type SocialProfile, useSocialProfiles } from "thirdweb/react";
@@ -23,6 +23,7 @@ export function WalletAddress(props: {
2323
className?: string;
2424
iconClassName?: string;
2525
client: ThirdwebClient;
26+
fallbackIcon?: React.ReactNode;
2627
}) {
2728
// default back to zero address if no address provided
2829
const address = useMemo(() => props.address || ZERO_ADDRESS, [props.address]);
@@ -59,9 +60,16 @@ export function WalletAddress(props: {
5960
// special case for zero address
6061
if (address === ZERO_ADDRESS) {
6162
return (
62-
<span className={cn("cursor-pointer font-mono", props.className)}>
63-
{shortenedAddress}
64-
</span>
63+
<div className="flex items-center gap-2 py-2">
64+
<CircleSlashIcon
65+
className={cn("size-6 text-muted-foreground/70", props.iconClassName)}
66+
/>
67+
<span
68+
className={cn("cursor-pointer font-mono text-sm", props.className)}
69+
>
70+
{shortenedAddress}
71+
</span>
72+
</div>
6573
);
6674
}
6775

@@ -82,6 +90,7 @@ export function WalletAddress(props: {
8290
iconClassName={props.iconClassName}
8391
profiles={profiles.data || []}
8492
thirdwebClient={props.client}
93+
fallbackIcon={props.fallbackIcon}
8594
/>
8695
)}
8796
<span className="cursor-pointer font-mono">
@@ -173,6 +182,7 @@ function WalletAvatar(props: {
173182
profiles: SocialProfile[];
174183
thirdwebClient: ThirdwebClient;
175184
iconClassName?: string;
185+
fallbackIcon?: React.ReactNode;
176186
}) {
177187
const avatar = useMemo(() => {
178188
return props.profiles.find(
@@ -199,6 +209,8 @@ function WalletAvatar(props: {
199209
className={cn("size-5 object-cover", props.iconClassName)}
200210
src={resolvedAvatarSrc}
201211
/>
212+
) : props.fallbackIcon ? (
213+
props.fallbackIcon
202214
) : (
203215
<Blobbie
204216
address={props.address}

apps/dashboard/src/@/components/contract-components/tables/contract-table.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,7 @@ const contractTypeToAssetTypeRecord: Record<string, string | undefined> = {
300300
DropERC20: "Coin",
301301
DropERC721: "NFT Collection",
302302
DropERC1155: "NFT Collection",
303+
ERC20Asset: "Coin",
303304
};
304305

305306
const NetworkFilterCell = React.memo(function NetworkFilterCell({

apps/dashboard/src/@/components/ui/CopyAddressButton.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ export function CopyAddressButton(props: {
2525
copyIconPosition={props.copyIconPosition}
2626
textToCopy={props.address}
2727
textToShow={shortenedAddress}
28+
iconClassName={props.iconClassName}
2829
tooltip={props.tooltip || "Copy Address"}
2930
variant={props.variant}
3031
/>

apps/dashboard/src/@/components/ui/tabs.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ export function TabButtons(props: {
9898
shadowColor?: string;
9999
tabIconClassName?: string;
100100
hideBottomLine?: boolean;
101+
bottomLineClassName?: string;
101102
}) {
102103
const { containerRef, lineRef, activeTabRef } =
103104
useUnderline<HTMLButtonElement>();
@@ -106,7 +107,12 @@ export function TabButtons(props: {
106107
<div className={cn("relative", props.containerClassName)}>
107108
{/* Bottom line */}
108109
{!props.hideBottomLine && (
109-
<div className="absolute right-0 bottom-0 left-0 h-[1px] bg-border" />
110+
<div
111+
className={cn(
112+
"absolute right-0 bottom-0 left-0 h-[1px] bg-border",
113+
props.bottomLineClassName,
114+
)}
115+
/>
110116
)}
111117

112118
<ScrollShadow

apps/dashboard/src/@/contexts/error-handler.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
"use client";
2-
32
import { CircleAlertIcon, InfoIcon } from "lucide-react";
43
import Link from "next/link";
54
import { createContext, useCallback, useContext, useState } from "react";

0 commit comments

Comments
 (0)