Skip to content

Commit

Permalink
Handle pending/failed transactions on submission page
Browse files Browse the repository at this point in the history
  • Loading branch information
soerenbf committed Oct 24, 2024
1 parent 548477d commit ffa505f
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,22 @@
margin: rem(8px) 0;
}

svg {
svg, .loader-x {
margin-bottom: rem(30px);
}
}

&__details-btn {
margin-top: rem(24px);
}

&__failed-icon {
width: rem(48px);
height: rem(48px);
margin-bottom: rem(18px) !important;

& path {
fill: $color-red-attention !important;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React from 'react';
import { Navigate, useNavigate, useParams } from 'react-router-dom';

import CheckCircle from '@assets/svgX/check-circle.svg';
import Cross from '@assets/svgX/close.svg';
import Arrow from '@assets/svgX/arrow-right.svg';
import Button from '@popup/popupX/shared/Button';
import Page from '@popup/popupX/shared/Page';
Expand All @@ -26,20 +27,23 @@ import {
import { useAtomValue } from 'jotai';
import { grpcClientAtom } from '@popup/store/settings';
import { formatCcdAmount } from '@popup/popupX/shared/utils/helpers';
import { LoaderInline } from '@popup/popupX/shared/Loader';
import { useTranslation } from 'react-i18next';

const TX_TIMEOUT = 60 * 1000; // 1 minute

type DelegationBodyProps = BaseAccountTransactionSummary & ConfigureDelegationSummary;

function DelegationBody({ events }: DelegationBodyProps) {
const { t } = useTranslation('x', { keyPrefix: 'submittedTransaction.success.configureDelegation' });
const stakeChange = events.find((e) =>
[TransactionEventTag.DelegationStakeIncreased, TransactionEventTag.DelegationStakeDecreased].includes(e.tag)
) as DelegationStakeChangedEvent | undefined;

if (stakeChange !== undefined) {
return (
<>
<span className="capture__main_small">You’ve delegated</span>
<span className="capture__main_small">{t('changeStake')}</span>
<span className="heading_large">{formatCcdAmount(stakeChange.newStake)}</span>
<span className="capture__main_small">CCD</span>
</>
Expand All @@ -51,10 +55,10 @@ function DelegationBody({ events }: DelegationBodyProps) {
| undefined;

if (removal !== undefined) {
return <span className="capture__main_small">You’ve removed your delegated stake</span>;
return <span className="capture__main_small">{t('removed')}</span>;
}

return <span className="capture__main_small">You’ve updated your delegation settings</span>;
return <span className="capture__main_small">{t('updated')}</span>;
}

type SuccessSummary = Exclude<AccountTransactionSummary, FailedTransactionSummary>;
Expand All @@ -69,16 +73,15 @@ type SuccessProps = {
tx: SuccessSummary;
};

// TODO:
// 1. Handle delegation transaction case
function Success({ tx }: SuccessProps) {
const { t } = useTranslation('x', { keyPrefix: 'submittedTransaction' });
return (
<>
<CheckCircle />
{tx.transactionType === TransactionKindString.Transfer && (
<>
<span className="capture__main_small">You’ve sent</span>
<span className="heading_large">12,600.00</span>
<span className="capture__main_small">{t('success.transfer.label')}</span>
<span className="heading_large">{formatCcdAmount(tx.transfer.amount)}</span>
<span className="capture__main_small">CCD</span>
</>
)}
Expand All @@ -90,24 +93,21 @@ type FailureProps = {
message: string;
};

// TODO:
// 1. Proper error icon
function Failure({ message }: FailureProps) {
return (
<>
<CheckCircle />
<Cross className="submitted-tx__failed-icon" />
<span className="capture__main_small">{message}</span>
</>
);
}

// TODO:
// 1. Proper error icon
function Finalizing() {
const { t } = useTranslation('x', { keyPrefix: 'submittedTransaction' });
return (
<>
<CheckCircle />
<span className="capture__main_small">Finalizing on chain</span>
<LoaderInline />
<span className="capture__main_small">{t('pending.label')}</span>
</>
);
}
Expand All @@ -117,7 +117,9 @@ export type SubmittedTransactionParams = {
transactionHash: HexString;
};

/** Component displaying the status of a submitted transaction. Must be given a transaction hash as a route parameter */
export default function SubmittedTransaction() {
const { t } = useTranslation('x', { keyPrefix: 'submittedTransaction' });
const { transactionHash } = useParams<SubmittedTransactionParams>();
const nav = useNavigate();
const grpc = useAtomValue(grpcClientAtom);
Expand Down Expand Up @@ -157,22 +159,20 @@ export default function SubmittedTransaction() {
return <Navigate to={absoluteRoutes.home.path} />;
}

// FIXME:
// 1. translations...
return (
<Page className="submitted-tx">
<Card type="transparent" className="submitted-tx__card">
{status === undefined && <Finalizing />}
{status?.type === 'success' && <Success tx={status.summary} />}
{status?.type === 'failure' && (
<Failure message={`The transaction failed: ${status.summary.rejectReason.tag}`} />
<Failure message={t('failure.label', { reason: status.summary.rejectReason.tag })} />
)}
{status?.type === 'error' && <Failure message={status.message} />}
</Card>
{status?.type !== undefined && status.type !== 'error' && (
<Button.IconText
icon={<Arrow />}
label="Transaction details"
label={t('detailsButton')}
className="submitted-tx__details-btn"
leftLabel
onClick={() => nav(transactionDetailsRoute(status.summary.sender, status.summary.hash))}
Expand All @@ -182,7 +182,7 @@ export default function SubmittedTransaction() {
<Button.Main
className="button-main"
onClick={() => nav(absoluteRoutes.home.path)}
label="Return to Account"
label={t('continue')}
/>
</Page.Footer>
</Page>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
const t = {
success: {
configureDelegation: {
changeStake: "You've delegated",
removed: "You've removed your delegated stake",
updated: "You've updated your delegation settings",
},
transfer: {
label: "You've sent",
},
},
pending: {
label: 'Transaction in progress',
},
failure: {
label: 'The transaction failed: {{reason}}',
},
detailsButton: 'Transaction details',
continue: 'Return to account',
};

export default t;
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
import clsx from 'clsx';
import React from 'react';
import { ClassName } from 'wallet-common-helpers';

export function LoaderInline({ className }: ClassName) {
return <span className={clsx('loader-x', className)} />;
}

export default function Loader() {
return (
<div className="loader-x-container">
<span className="loader-x" />
<LoaderInline />
</div>
);
}
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export { default } from './Loader';
export { default, LoaderInline } from './Loader';
2 changes: 2 additions & 0 deletions packages/browser-wallet/src/popup/shell/i18n/locales/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ import header from '@popup/popupX/page-layouts/MainLayout/Header/i18n/en';
import web3Id from '@popup/popupX/pages/Web3Id/i18n/en';
import earn from '@popup/popupX/pages/EarningRewards/i18n/en';
import connectionRequestX from '@popup/popupX/pages/prompts/ConnectionRequest/i18n/en';
import submittedTransaction from '@popup/popupX/pages/SubmittedTransaction/i18n/en';

const t = {
shared,
Expand Down Expand Up @@ -99,6 +100,7 @@ const t = {
web3Id,
earn,
prompts: { connectionRequestX },
submittedTransaction,
},
};

Expand Down

0 comments on commit ffa505f

Please sign in to comment.