Skip to content

Commit

Permalink
frontend: revamp send confirm dialog / view
Browse files Browse the repository at this point in the history
Using `View fullscreen` instead of WaitDialog and UI improvement
in general in order to improve UX (easier to read).
  • Loading branch information
shonsirsha committed Aug 26, 2024
1 parent 4b318b8 commit 0694e58
Show file tree
Hide file tree
Showing 6 changed files with 303 additions and 191 deletions.
2 changes: 2 additions & 0 deletions frontends/web/src/locales/en/app.json
Original file line number Diff line number Diff line change
Expand Up @@ -1533,8 +1533,10 @@
"title": "Send from output"
},
"confirm": {
"infoMessage": "Carefully verify the amount and address are correct on the BitBox02",
"selected-coins": "Selected coins",
"title": "Confirm and send transaction",
"to": "To",
"total": "Total"
},
"error": {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
.bitBoxContainer {
margin-bottom: var(--space-half);
}

.bitBoxContainer img {
max-width: 220px;
}

.confirmationItemWrapper {
align-items: center;
display: flex;
justify-content: space-between;
}

.confirmItem {
margin-bottom: calc(var(--space-half) + var(--space-quarter));
}

.confirmItem p {
margin: 0;
word-break: break-all;
}

.fiatValue {
color: var(--color-secondary);
font-size: 16px;
}

label {
color: var(--color-secondary);
margin: 0 !important;
}

.title {
text-align: center;
}

.totalWrapper {
align-items: center;
display: flex;
}

.totalWrapper .fiatValue {
margin-left: auto;
}

.totalWrapper label {
margin-right: var(--space-quarter) !important;
}

.valueOriginal {
font-size: 16px;
font-weight: 500;
}

.valueOriginalLarge {
font-size: var(--header-default-font-size);
font-weight: 500;
}

@media (max-width: 768px) {
.bitBoxContainer img {
padding-right: 16px;
max-width: 190px;
}

.bitBoxContainer svg {
max-width: 16px;
}

label {
font-size: 16px !important;
}

.fiatValue,
.valueOriginal {
font-size: 14px;
}
}
219 changes: 219 additions & 0 deletions frontends/web/src/routes/account/send/components/confirm/confirm.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,219 @@
/**
* Copyright 2024 Shift Crypto AG
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import { useTranslation } from 'react-i18next';
import { CoinCode, ConversionUnit, FeeTargetCode, Fiat, IAmount } from '@/api/account';
import { Amount } from '@/components/amount/amount';
import { customFeeUnit } from '@/routes/account/utils';
import { TSignProgress } from '@/api/devicessync';
import { View, ViewContent, ViewHeader } from '@/components/view/view';
import { Message } from '@/components/message/message';
import { PointToBitBox02 } from '@/components/icon';
import style from './confirm.module.css';

type TransactionStatus = {
isConfirming: boolean;
signConfirm: boolean;
signProgress?: TSignProgress;
}

type TransactionDetails = {
proposedAmount?: IAmount;
proposedFee?: IAmount;
proposedTotal?: IAmount;
feeTarget?: FeeTargetCode;
customFee: string;
recipientAddress: string;
fiatUnit: Fiat;
}

type TProps = {
baseCurrencyUnit: ConversionUnit;
note: string;
hasSelectedUTXOs: boolean;
selectedUTXOs: string[];
coinCode: CoinCode;
transactionStatus: TransactionStatus;
transactionDetails: TransactionDetails;
}

type TFiatValueProps = {
baseCurrencyUnit: ConversionUnit;
amount: string
}

export const ConfirmSend = ({
baseCurrencyUnit,
note,
hasSelectedUTXOs,
selectedUTXOs,
coinCode,
transactionStatus,
transactionDetails
}: TProps) => {

const { t } = useTranslation();
const { isConfirming, signProgress } = transactionStatus;
const {
proposedFee,
proposedAmount,
proposedTotal,
customFee,
feeTarget,
recipientAddress,
fiatUnit
} = transactionDetails;


const confirmPrequel = (signProgress && signProgress.steps > 0) ? (
<div className="m-top-none m-bottom-half">
<span>
{
t('send.signprogress.description', {
steps: signProgress.steps.toString(),
})
}
<br />
{t('send.signprogress.label')}: {signProgress.step}/{signProgress.steps}
</span>
</div>
) : undefined;


if (!isConfirming) {
return null;
}

const canShowSendAmountFiatValue = proposedAmount && proposedAmount.conversions && proposedAmount.conversions[fiatUnit];
const canShowFeeFiatValue = proposedFee && proposedFee.conversions && proposedFee.conversions[fiatUnit];
const canShowTotalFiatValue = (proposedTotal && proposedTotal.conversions) && proposedTotal.conversions[fiatUnit];


return <View fullscreen>
<ViewHeader title={<div className={style.title}>{t('send.confirm.title')}</div>} />
<ViewContent>
{confirmPrequel}
<Message type="info">
{t('send.confirm.infoMessage')}
</Message>
<div className={style.bitBoxContainer}>
<PointToBitBox02 />
</div>

{/*Send amount*/}
<div className={style.confirmItem}>
<label>{t('button.send')}</label>
<div className={style.confirmationItemWrapper}>
<p className={`${style.valueOriginalLarge}`}>
{(proposedAmount &&
<Amount alwaysShowAmounts amount={proposedAmount.amount} unit={proposedAmount.unit}/>) || 'N/A'}
{' '}
<small>{(proposedAmount && proposedAmount.unit) || 'N/A'}</small>
</p>
{canShowSendAmountFiatValue &&
(<FiatValue baseCurrencyUnit={baseCurrencyUnit} amount={proposedAmount.conversions![fiatUnit] || ''} />)
}
</div>
</div>

{/*To (recipient address)*/}
<div className={style.confirmItem}>
<label>{t('send.confirm.to')}</label>
<div className={style.confirmationItemWrapper}>
<p className={`${style.valueOriginal}`}>
{recipientAddress || 'N/A'}
</p>
</div>
</div>

{/*Note*/}
{note ? (
<div className={style.confirmItem}>
<label>{t('note.title')}</label>
<p className={style.valueOriginal}>{note}</p>
</div>
) : null}

{/*Selected UTXOs*/}
{
hasSelectedUTXOs && (
<div className={[style.confirmItem].join(' ')}>
<label>{t('send.confirm.selected-coins')}</label>
{
selectedUTXOs.map((uxto, i) => (
<p className={style.valueOriginal} key={`selectedCoin-${i}`}>{uxto}</p>
))
}
</div>
)
}


{/*Fee*/}
<div className={style.confirmItem}>
<label>{t('send.fee.label')}{feeTarget ? ' (' + t(`send.feeTarget.label.${feeTarget}`) + ')' : ''}</label>
<div className={style.confirmationItemWrapper}>
<p className={style.valueOriginal}>
{(proposedFee &&
<Amount alwaysShowAmounts amount={proposedFee.amount} unit={proposedFee.unit}/>) || 'N/A'}
{' '}
{(proposedFee && proposedFee.unit) || 'N/A'}
{customFee ? (
<span>
<br/>
<small>({customFee} {customFeeUnit(coinCode)})</small>
</span>
) : null}
</p>
{canShowFeeFiatValue &&
(<FiatValue baseCurrencyUnit={baseCurrencyUnit} amount={proposedFee.conversions![fiatUnit] || ''} />)
}

</div>
</div>

{/*Total*/}
<div className={style.confirmItem}>
<div className={style.totalWrapper}>
<label>{t('send.confirm.total')}</label>
<p className={style.valueOriginal}>
<strong>
{(proposedTotal &&
<Amount alwaysShowAmounts amount={proposedTotal.amount} unit={proposedTotal.unit}/>) || 'N/A'}
</strong>
{' '}
<small>{(proposedTotal && proposedTotal.unit) || 'N/A'}</small>
</p>
{canShowTotalFiatValue &&
(<FiatValue baseCurrencyUnit={baseCurrencyUnit} amount={proposedTotal.conversions![fiatUnit] || ''} />)
}
</div>
</div>

</ViewContent>
</View >;

};


const FiatValue = ({ baseCurrencyUnit, amount }: TFiatValueProps) => {
return <p className={style.fiatValue}>
<span>
<Amount alwaysShowAmounts amount={amount} unit={baseCurrencyUnit} />
{' '}<small>{baseCurrencyUnit}</small>
</span>
</p>;
};

This file was deleted.

Loading

0 comments on commit 0694e58

Please sign in to comment.