Skip to content

Commit cbbc794

Browse files
committed
frontend: create DetailsDialog component
Extract the transactions details dialog in transactions.tsx into its own component to make the transaction component itself more concice and easier to understand.
1 parent b0607b9 commit cbbc794

File tree

2 files changed

+218
-142
lines changed

2 files changed

+218
-142
lines changed
Lines changed: 198 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,198 @@
1+
/**
2+
* Copyright 2024 Shift Crypto AG
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
import { useEffect, useState } from 'react';
18+
import { useTranslation } from 'react-i18next';
19+
import { ITransaction, IAmount, getTransaction } from '@/api/account';
20+
import { A } from '@/components/anchor/anchor';
21+
import { Dialog } from '@/components/dialog/dialog';
22+
import { FiatConversion } from '@/components/rates/rates';
23+
import { Amount } from '@/components/amount/amount';
24+
import { Note } from '@/components/transactions/note';
25+
import { TxDetail } from './detail';
26+
import { Arrow } from './arrow';
27+
import { TxDateDetail } from './date';
28+
import { TxStatusDetail } from './status';
29+
import { TxDetailCopyableValues } from './address-or-txid';
30+
import parentStyle from '@/components/transactions/transaction.module.css';
31+
32+
type TProps = {
33+
open: boolean;
34+
onClose: () => void;
35+
accountCode: string;
36+
internalID: string;
37+
note: string;
38+
status: ITransaction['status'];
39+
type: ITransaction['type'];
40+
numConfirmations: number;
41+
numConfirmationsComplete: number;
42+
time: string | null;
43+
amount: IAmount;
44+
sign: string;
45+
typeClassName: string;
46+
explorerURL: string;
47+
}
48+
49+
export const TxDetailsDialog = ({
50+
open,
51+
onClose,
52+
accountCode,
53+
internalID,
54+
note,
55+
status,
56+
type,
57+
numConfirmations,
58+
numConfirmationsComplete,
59+
time,
60+
amount,
61+
sign,
62+
typeClassName,
63+
explorerURL,
64+
}: TProps) => {
65+
const { t } = useTranslation();
66+
67+
const [transactionInfo, setTransactionInfo] = useState<ITransaction | null>(null);
68+
69+
useEffect(() => {
70+
if (!transactionInfo && open) {
71+
getTransaction(accountCode, internalID).then(transaction => {
72+
if (!transaction) {
73+
console.error(`Unable to retrieve transaction ${internalID}`);
74+
}
75+
setTransactionInfo(transaction);
76+
}).catch(console.error);
77+
}
78+
}, [accountCode, internalID, open, transactionInfo]);
79+
80+
// Amount and Confirmations info are displayed using props data
81+
// instead of transactionInfo because they are live updated.
82+
return (
83+
<Dialog
84+
open={open && !!transactionInfo}
85+
title={t('transaction.details.title')}
86+
onClose={onClose}
87+
slim
88+
medium>
89+
{transactionInfo && (
90+
<>
91+
<Note
92+
accountCode={accountCode}
93+
internalID={internalID}
94+
note={note}
95+
/>
96+
<TxDetail label={t('transaction.details.type')}>
97+
<Arrow
98+
status={status}
99+
type={type}
100+
/>
101+
</TxDetail>
102+
<TxDetail label={t('transaction.confirmation')}>{numConfirmations}</TxDetail>
103+
<TxStatusDetail
104+
status={status}
105+
numConfirmations={numConfirmations}
106+
numConfirmationsComplete={numConfirmationsComplete}
107+
/>
108+
<TxDateDetail time={time} />
109+
<TxDetail label={t('transaction.details.fiat')}>
110+
<span className={`${parentStyle.fiat} ${typeClassName}`}>
111+
<FiatConversion amount={amount} sign={sign} noAction />
112+
</span>
113+
</TxDetail>
114+
<TxDetail label={t('transaction.details.fiatAtTime')}>
115+
<span className={`${parentStyle.fiat} ${typeClassName}`}>
116+
{transactionInfo.amountAtTime ?
117+
<FiatConversion amount={transactionInfo.amountAtTime} sign={sign} noAction />
118+
:
119+
<FiatConversion noAction />
120+
}
121+
</span>
122+
</TxDetail>
123+
<TxDetail label={t('transaction.details.amount')}>
124+
<span className={`${parentStyle.amount} ${typeClassName}`}>
125+
{sign}
126+
<Amount amount={amount.amount} unit={amount.unit} />
127+
</span>
128+
{' '}
129+
<span className={`${parentStyle.currencyUnit} ${typeClassName}`}>{transactionInfo.amount.unit}</span>
130+
</TxDetail>
131+
{
132+
transactionInfo.fee && transactionInfo.fee.amount ? (
133+
<TxDetail label={t('transaction.fee')}>
134+
<Amount amount={transactionInfo.fee.amount} unit={transactionInfo.fee.unit} />
135+
{' '}
136+
<span className={parentStyle.currencyUnit}>{transactionInfo.fee.unit}</span>
137+
</TxDetail>
138+
) : (
139+
<TxDetail label={t('transaction.fee')}>---</TxDetail>
140+
)
141+
}
142+
<TxDetailCopyableValues
143+
label={t('transaction.details.address')}
144+
values={transactionInfo.addresses}
145+
/>
146+
{
147+
transactionInfo.gas ? (
148+
<TxDetail label={t('transaction.gas')}>{transactionInfo.gas}</TxDetail>
149+
) : null
150+
}
151+
{
152+
transactionInfo.nonce ? (
153+
<TxDetail label="Nonce">{transactionInfo.nonce}</TxDetail>
154+
) : null
155+
}
156+
{
157+
transactionInfo.weight ? (
158+
<TxDetail label={t('transaction.weight')}>
159+
{transactionInfo.weight}
160+
{' '}
161+
<span className={parentStyle.currencyUnit}>WU</span>
162+
</TxDetail>
163+
) : null
164+
}
165+
{
166+
transactionInfo.vsize ? (
167+
<TxDetail label={t('transaction.vsize')}>
168+
{transactionInfo.vsize}
169+
{' '}
170+
<span className={parentStyle.currencyUnit}>b</span>
171+
</TxDetail>
172+
) : null
173+
}
174+
{
175+
transactionInfo.size ? (
176+
<TxDetail label={t('transaction.size')}>
177+
{transactionInfo.size}
178+
{' '}
179+
<span className={parentStyle.currencyUnit}>b</span>
180+
</TxDetail>
181+
) : null
182+
}
183+
<TxDetailCopyableValues
184+
label={t('transaction.explorer')}
185+
values={[transactionInfo.txID]}
186+
/>
187+
<div className={`${parentStyle.detail} flex-center`}>
188+
<A
189+
href={explorerURL + transactionInfo.txID}
190+
title={`${t('transaction.explorerTitle')}\n${explorerURL}${transactionInfo.txID}`}>
191+
{t('transaction.explorerTitle')}
192+
</A>
193+
</div>
194+
</>
195+
)}
196+
</Dialog>
197+
);
198+
};

0 commit comments

Comments
 (0)