Skip to content

Commit bb554e5

Browse files
committed
[NEB-211] Nebula: Hide tx button after transaction is confirmed (#6859)
<!-- ## 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 enhancing the UI and functionality of the `ExecuteTransactionCard` component in the dashboard app. It includes visual improvements and adjustments to transaction handling. ### Detailed summary - Updated the border styling for child elements in the main `div`. - Changed text styles for labels (`From`, `To`, `Value`, `Status`, and `Transaction Hash`) to use `font-medium`. - Added a conditional rendering for the footer based on transaction status. - Improved transaction tracking event labels. - Refactored the transaction submission logic for clarity. > ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}` <!-- end pr-codex -->
1 parent 90823ef commit bb554e5

File tree

1 file changed

+76
-71
lines changed

1 file changed

+76
-71
lines changed

apps/dashboard/src/app/nebula-app/(app)/components/ExecuteTransactionCard.tsx

Lines changed: 76 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -95,10 +95,10 @@ export function ExecuteTransactionCardLayout(props: {
9595
</h3>
9696

9797
{/* content */}
98-
<div className="px-4 text-sm lg:px-6 [&>*]:h-12 [&>*]:border-b lg:[&>*]:h-14">
98+
<div className="px-4 text-sm lg:px-6 [&>*:not(:last-child)]:border-b [&>*]:h-12 lg:[&>*]:h-14">
9999
{/* From */}
100100
<div className="flex items-center justify-between gap-2">
101-
<span className="text-muted-foreground">From</span>
101+
<span className="font-medium text-muted-foreground">From</span>
102102
{account ? (
103103
<WalletAddress
104104
address={account.address}
@@ -113,7 +113,7 @@ export function ExecuteTransactionCardLayout(props: {
113113
{/* To */}
114114
{txData.to && (
115115
<div className="flex items-center justify-between gap-2">
116-
<span className="text-muted-foreground">To</span>
116+
<span className="font-medium text-muted-foreground">To</span>
117117

118118
<WalletAddress
119119
address={txData.to}
@@ -125,7 +125,7 @@ export function ExecuteTransactionCardLayout(props: {
125125

126126
{/* Value */}
127127
<div className="flex items-center justify-between gap-2">
128-
<span className="text-muted-foreground">Value</span>
128+
<span className="font-medium text-muted-foreground">Value</span>
129129
{toEther(BigInt(txData.value))} {chain.nativeCurrency?.symbol}
130130
</div>
131131

@@ -147,7 +147,7 @@ export function ExecuteTransactionCardLayout(props: {
147147
{/* Status */}
148148
{props.status.type !== "idle" && (
149149
<div className="flex items-center justify-between gap-2">
150-
<span className="text-muted-foreground">Status</span>
150+
<span className="font-medium text-muted-foreground">Status</span>
151151
<div className="flex items-center gap-1.5">
152152
<span
153153
className={cn(
@@ -193,7 +193,9 @@ export function ExecuteTransactionCardLayout(props: {
193193
{/* Transaction Hash */}
194194
{"txHash" in props.status && props.status.txHash && (
195195
<div className="flex items-center justify-between gap-1">
196-
<span className="text-muted-foreground">Transaction Hash</span>
196+
<span className="font-medium text-muted-foreground">
197+
Transaction Hash
198+
</span>
197199
<div className="flex justify-end gap-2.5">
198200
{explorer ? (
199201
<Button
@@ -226,83 +228,86 @@ export function ExecuteTransactionCardLayout(props: {
226228
</div>
227229

228230
{/* footer */}
229-
<div className="flex items-center justify-end px-4 py-6 lg:px-6">
230-
<TransactionButton
231-
isPending={sendTransaction.isPending}
232-
transactionCount={undefined}
233-
txChainID={txData.chainId}
234-
variant="default"
235-
disabled={isTransactionPending}
236-
size="sm"
237-
onClick={async () => {
238-
trackEvent({
239-
category: "nebula",
240-
action: "execute_transaction",
241-
label: "attempt",
242-
chainId: txData.chainId,
243-
});
244-
245-
const tx = prepareTransaction({
246-
chain: chain,
247-
client: props.client,
248-
data: txData.data,
249-
to: txData.to,
250-
value: BigInt(txData.value),
251-
});
252-
253-
let txHash: string | undefined;
254-
255-
try {
256-
// submit transaction
257-
props.setStatus({ type: "sending" });
258-
const submittedReceipt = await sendTransaction.mutateAsync(tx);
259-
txHash = submittedReceipt.transactionHash;
260-
231+
{props.status.type !== "confirmed" && (
232+
<div className="flex items-center justify-end border-t px-4 py-6 lg:px-6">
233+
<TransactionButton
234+
isPending={sendTransaction.isPending}
235+
transactionCount={undefined}
236+
txChainID={txData.chainId}
237+
variant="default"
238+
disabled={isTransactionPending}
239+
size="sm"
240+
onClick={async () => {
261241
trackEvent({
262242
category: "nebula",
263243
action: "execute_transaction",
264-
label: "sent",
244+
label: "attempt",
265245
chainId: txData.chainId,
266246
});
267247

268-
// wait for receipt
269-
props.setStatus({
270-
type: "confirming",
271-
txHash: submittedReceipt.transactionHash,
248+
const tx = prepareTransaction({
249+
chain: chain,
250+
client: props.client,
251+
data: txData.data,
252+
to: txData.to,
253+
value: BigInt(txData.value),
272254
});
273255

274-
const confirmReceipt = await waitForReceipt(submittedReceipt);
275-
txHash = confirmReceipt.transactionHash;
276-
props.setStatus({
277-
type: "confirmed",
278-
txHash: confirmReceipt.transactionHash,
279-
});
256+
let txHash: string | undefined;
280257

281-
props.onTxSettled(txHash);
258+
try {
259+
// submit transaction
260+
props.setStatus({ type: "sending" });
261+
const submittedReceipt =
262+
await sendTransaction.mutateAsync(tx);
263+
txHash = submittedReceipt.transactionHash;
264+
265+
trackEvent({
266+
category: "nebula",
267+
action: "execute_transaction",
268+
label: "sent",
269+
chainId: txData.chainId,
270+
});
271+
272+
// wait for receipt
273+
props.setStatus({
274+
type: "confirming",
275+
txHash: submittedReceipt.transactionHash,
276+
});
277+
278+
const confirmReceipt = await waitForReceipt(submittedReceipt);
279+
txHash = confirmReceipt.transactionHash;
280+
props.setStatus({
281+
type: "confirmed",
282+
txHash: confirmReceipt.transactionHash,
283+
});
282284

283-
trackEvent({
284-
category: "nebula",
285-
action: "execute_transaction",
286-
label: "confirmed",
287-
chainId: txData.chainId,
288-
});
289-
} catch {
290-
if (txHash) {
291285
props.onTxSettled(txHash);
286+
287+
trackEvent({
288+
category: "nebula",
289+
action: "execute_transaction",
290+
label: "confirmed",
291+
chainId: txData.chainId,
292+
});
293+
} catch {
294+
if (txHash) {
295+
props.onTxSettled(txHash);
296+
}
297+
props.setStatus({
298+
type: "failed",
299+
txHash: txHash,
300+
});
292301
}
293-
props.setStatus({
294-
type: "failed",
295-
txHash: txHash,
296-
});
297-
}
298-
}}
299-
className="gap-2"
300-
isLoggedIn={true}
301-
>
302-
<ArrowRightLeftIcon className="size-4" />
303-
Execute Transaction
304-
</TransactionButton>
305-
</div>
302+
}}
303+
className="gap-2"
304+
isLoggedIn={true}
305+
>
306+
<ArrowRightLeftIcon className="size-4" />
307+
Execute Transaction
308+
</TransactionButton>
309+
</div>
310+
)}
306311
</div>
307312
</div>
308313
);

0 commit comments

Comments
 (0)