Skip to content

Commit 51f7418

Browse files
committed
[MNY-128] Dashboard: UI tweaks in token creation flow (#7939)
<!-- ## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes" If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000): ## Notes for the reviewer Anything important to call out? Be sure to also clarify these in your comments. ## How to test Unit tests, playground, etc. --> <!-- start pr-codex --> --- ## PR-Codex overview This PR focuses on improving the user interface and error handling in the token and NFT launch processes, as well as refining the layout and component interactions in the distribution section. ### Detailed summary - Removed `isPending` state checks from token and NFT launch components. - Updated button layouts to improve user experience in `launch-token.tsx` and `launch-nft.tsx`. - Changed error message text in `token-distribution.tsx`. - Added `errorMessage` prop to `StepCard` for better error display. - Adjusted layout and styling for improved responsiveness and alignment. > ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}` <!-- end pr-codex --> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - New Features - Step headers can now display error messages. - Distribution chart moved into the main form flow for clearer visibility. - Post-launch actions updated: show “View NFT Collection” or “View Coin” when available; show “Cancel” before completion. - Refactor - Simplified bottom action areas and removed pending-based button disabling for a more predictable flow. - Style - Improved spacing, alignment, and responsiveness in forms. - Updated error text to “Token allocation exceeds total supply” for clearer guidance. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
1 parent dc3df4b commit 51f7418

File tree

4 files changed

+89
-95
lines changed

4 files changed

+89
-95
lines changed

apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/_common/step-card.tsx

Lines changed: 42 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { Button } from "@/components/ui/button";
33

44
export function StepCard(props: {
55
title: string;
6+
errorMessage?: string;
67
prevButton:
78
| undefined
89
| {
@@ -35,40 +36,50 @@ export function StepCard(props: {
3536
{props.children}
3637

3738
{(props.prevButton || props.nextButton) && (
38-
<div className="flex justify-end gap-3 border-t p-4 md:p-6">
39-
{props.prevButton && (
40-
<Button
41-
className="gap-2"
42-
onClick={() => {
43-
props.prevButton?.onClick();
44-
}}
45-
variant="outline"
46-
>
47-
<ArrowLeftIcon className="size-4" />
48-
Back
49-
</Button>
39+
<div className="flex justify-between items-center gap-3 border-t p-4 md:px-6 md:py-5">
40+
{props.errorMessage ? (
41+
<div className="text-destructive-text text-sm">
42+
{props.errorMessage}
43+
</div>
44+
) : (
45+
<div />
5046
)}
5147

52-
{nextButton && nextButton.type !== "custom" && (
53-
<Button
54-
className="gap-2"
55-
disabled={nextButton.disabled}
56-
onClick={() => {
57-
if (nextButton.type === "click") {
58-
nextButton.onClick();
59-
}
60-
}}
61-
type="submit"
62-
variant="default"
63-
>
64-
Next
65-
<ArrowRightIcon className="size-4" />
66-
</Button>
67-
)}
48+
<div className="flex gap-3">
49+
{props.prevButton && (
50+
<Button
51+
className="gap-2"
52+
onClick={() => {
53+
props.prevButton?.onClick();
54+
}}
55+
variant="outline"
56+
>
57+
<ArrowLeftIcon className="size-4" />
58+
Back
59+
</Button>
60+
)}
61+
62+
{nextButton && nextButton.type !== "custom" && (
63+
<Button
64+
className="gap-2"
65+
disabled={nextButton.disabled}
66+
onClick={() => {
67+
if (nextButton.type === "click") {
68+
nextButton.onClick();
69+
}
70+
}}
71+
type="submit"
72+
variant="default"
73+
>
74+
Next
75+
<ArrowRightIcon className="size-4" />
76+
</Button>
77+
)}
6878

69-
{props.nextButton &&
70-
props.nextButton.type === "custom" &&
71-
props.nextButton.custom}
79+
{props.nextButton &&
80+
props.nextButton.type === "custom" &&
81+
props.nextButton.custom}
82+
</div>
7283
</div>
7384
)}
7485
</div>

apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/nft/launch/launch-nft.tsx

Lines changed: 19 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,6 @@ export function LaunchNFT(props: {
303303
}
304304

305305
const isComplete = steps.every((step) => step.status.type === "completed");
306-
const isPending = steps.some((step) => step.status.type === "pending");
307306

308307
const isPriceSame = props.values.nfts.every(
309308
(nft) => nft.price_amount === props.values.nfts[0]?.price_amount,
@@ -392,30 +391,25 @@ export function LaunchNFT(props: {
392391
/>
393392
</div>
394393

395-
<div className="mt-2 flex justify-between gap-4 border-border border-t bg-card p-6">
396-
{isComplete && contractLink ? (
397-
<div>
398-
<Button asChild className="gap-2">
399-
<Link href={contractLink}>
400-
View NFT <ArrowRightIcon className="size-4" />
401-
</Link>
402-
</Button>
403-
</div>
404-
) : (
405-
<div />
406-
)}
407-
408-
<Button
409-
disabled={isPending}
410-
onClick={() => {
411-
setIsModalOpen(false);
412-
// reset steps
413-
setSteps([]);
414-
}}
415-
variant="outline"
416-
>
417-
{isComplete ? "Close" : "Cancel"}
418-
</Button>
394+
<div className="mt-2 flex justify-end gap-4 border-border border-t bg-card p-6">
395+
{!isComplete ? (
396+
<Button
397+
onClick={() => {
398+
setIsModalOpen(false);
399+
// reset steps
400+
setSteps([]);
401+
}}
402+
variant="outline"
403+
>
404+
Cancel
405+
</Button>
406+
) : contractLink ? (
407+
<Button asChild className="gap-2">
408+
<Link href={contractLink}>
409+
View NFT Collection <ArrowRightIcon className="size-4" />
410+
</Link>
411+
</Button>
412+
) : null}
419413
</div>
420414
</DialogContent>
421415
</Dialog>

apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/token/distribution/token-distribution.tsx

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ export function TokenDistributionFieldset(props: {
5050
onClick: props.onPrevious,
5151
}}
5252
title="Coin Distribution"
53+
errorMessage={distributionError}
5354
>
5455
<div>
5556
<div className="p-4 md:px-6 md:py-6">
@@ -60,13 +61,19 @@ export function TokenDistributionFieldset(props: {
6061
isRequired
6162
label="Total Supply"
6263
>
63-
<div className="relative max-w-96">
64+
<div className="relative lg:max-w-xs">
6465
<Input id={supplyId} {...form.register("supply")} />
6566
<span className="-translate-y-1/2 absolute top-1/2 right-3 text-muted-foreground text-sm">
6667
{props.tokenSymbol || "Tokens"}
6768
</span>
6869
</div>
6970
</FormFieldSetup>
71+
72+
<div className="h-6" />
73+
74+
<TokenDistributionBarChart
75+
distributionFormValues={form.watch()}
76+
/>
7077
</div>
7178

7279
{form.watch("saleMode") === "drop-erc20:token-drop" ? (
@@ -85,18 +92,6 @@ export function TokenDistributionFieldset(props: {
8592
)}
8693

8794
<TokenAirdropSection client={props.client} form={form} />
88-
89-
<div className="flex flex-col gap-3 p-4 py-8 md:px-6 border-t border-dashed">
90-
<TokenDistributionBarChart
91-
distributionFormValues={form.watch()}
92-
/>
93-
94-
{distributionError && (
95-
<div className="text-destructive-text text-sm">
96-
{distributionError}
97-
</div>
98-
)}
99-
</div>
10095
</div>
10196
</StepCard>
10297
</form>
@@ -125,7 +120,7 @@ function getDistributionError(form: TokenDistributionForm) {
125120
const totalSumOfSupply = totalAirdrop + saleSupply + ownerSupply;
126121

127122
if (totalSumOfSupply > supply) {
128-
return "Token distribution exceeds total supply";
123+
return "Token allocation exceeds total supply";
129124
}
130125

131126
return undefined;

apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/tokens/create/token/launch/launch-token.tsx

Lines changed: 19 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,6 @@ export function LaunchTokenStatus(props: {
166166
}
167167

168168
const isComplete = steps.every((step) => step.status.type === "completed");
169-
const isPending = steps.some((step) => step.status.type === "pending");
170169

171170
async function executeStep(stepId: StepId, gasless: boolean) {
172171
const params = {
@@ -435,30 +434,25 @@ export function LaunchTokenStatus(props: {
435434
/>
436435
</div>
437436

438-
<div className="mt-2 flex justify-between gap-4 border-border border-t bg-card p-6">
439-
{isComplete && contractLink ? (
440-
<div>
441-
<Button asChild className="gap-2">
442-
<Link href={contractLink}>
443-
View Coin <ArrowRightIcon className="size-4" />
444-
</Link>
445-
</Button>
446-
</div>
447-
) : (
448-
<div />
449-
)}
450-
451-
<Button
452-
disabled={isPending}
453-
onClick={() => {
454-
setIsModalOpen(false);
455-
// reset steps
456-
setSteps([]);
457-
}}
458-
variant="outline"
459-
>
460-
{isComplete ? "Close" : "Cancel"}
461-
</Button>
437+
<div className="mt-2 flex justify-end gap-4 border-border border-t bg-card p-6">
438+
{!isComplete ? (
439+
<Button
440+
onClick={() => {
441+
setIsModalOpen(false);
442+
// reset steps
443+
setSteps([]);
444+
}}
445+
variant="outline"
446+
>
447+
Cancel
448+
</Button>
449+
) : contractLink ? (
450+
<Button asChild className="gap-2">
451+
<Link href={contractLink}>
452+
View Coin <ArrowRightIcon className="size-4" />
453+
</Link>
454+
</Button>
455+
) : null}
462456
</div>
463457
</DialogContent>
464458
</Dialog>

0 commit comments

Comments
 (0)