Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add pending transaction list on address page #175

Merged
merged 9 commits into from
Dec 21, 2023
148 changes: 148 additions & 0 deletions src/components/LiteTransactionList/LiteTransactionList.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
.container {
padding: 0 2rem;
background: #fff;

table {
width: 100%;

th,
td {
height: 4rem;
padding: 0 8px;
white-space: nowrap;
font-size: 1rem;
font-weight: 500;
text-align: left;

&:first-child {
padding-left: 0;
}

&:last-child {
padding-right: 0;
text-align: right;
}

&.noRecords:last-child {
text-align: center;
}
}

thead {
th {
font-weight: 600;
}
}

tbody {
tr {
border-top: 1px solid #e5e5e5;
}
}
}

a {
color: var(--primary-color);
}

.hash {
font-size: 0.875rem;
max-width: 25vw;
}

.height {
font-family: Roboto, inherit, sans-serif;
}

.cells {
white-space: pre;
}

.income > span {
display: inline-flex;

* {
color: inherit;
font-size: 1rem;

// REFACTOR: it's hard to maintain, the component of decimal should be refactored
:global {
div.addition,
div.subtraction {
font-size: 0.875rem;
}
}
}

&[data-is-positive='true'][data-is-zero='false'] {
color: var(--primary-color);

&::before {
content: '+';
}
}

&[data-is-zero='true'] {
color: #999;
}

&[data-is-positive='false'] {
color: var(--accent-color);
}
}

// TODO: use https://github.com/Magickbase/ckb-explorer-frontend/pull/178/files#diff-0f21b8f9c1d917feff4b138db3e62f202f2e3c1b691a2cd309397400edfca591R3
@media screen and (width <= 1200px) {
padding: 0;

table {
thead {
display: none;
}

tbody {
tr {
display: flex;
flex-direction: column;
align-items: stretch;
border-top: 4px solid #ededed;
}

td {
position: relative;
display: flex;
flex-direction: column;
height: auto;
padding: 0.625rem 1rem;

&:first-child {
padding-left: 1rem;
max-width: calc(100vw - 2.25rem);
}

&:last-child {
text-align: left;
}

&:not(:last-child)::after {
position: absolute;
bottom: 0;
left: 1rem;
right: 1rem;
content: '';
display: block;
height: 1px;
background: #f5f5f5;
}

&::before {
content: attr(title);
font-size: 1rem;
color: #666;
margin-bottom: 0.5rem;
}
}
}
}
}
}
125 changes: 125 additions & 0 deletions src/components/LiteTransactionList/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
import { useEffect, useState } from 'react'
import { Link } from 'react-router-dom'
import { useTranslation } from 'react-i18next'
import BigNumber from 'bignumber.js'
import type { Transaction } from '../../models/Transaction'
import { useSearchParams } from '../../hooks'
import styles from './LiteTransactionList.module.scss'
import AddressText from '../AddressText'
import { localeNumberString } from '../../utils/number'
import { useParseDate } from '../../utils/date'
import DecimalCapacity from '../DecimalCapacity'
import { shannonToCkb } from '../../utils/util'

const LiteTransactionList: React.FC<{
address?: string
list: Transaction[]
}> = ({ address, list }) => {
const [t] = useTranslation()
const [timeBase, setTimeBase] = useState(Date.now())
const dateParser = useParseDate()

useEffect(() => {
const timer = setInterval(() => {
setTimeBase(Date.now())
}, 1000)
return () => {
clearInterval(timer)
}
}, [setTimeBase])

const { tx_status: txStatus } = useSearchParams('tx_status')

const isPendingListActive = txStatus === 'pending'

const headers = [
t('transaction.transaction_hash'),
isPendingListActive ? null : t('transaction.height'),
t('transaction.time'),
`${t('transaction.input')} & ${t('transaction.output')}`,
address ? t('transaction.capacity_change') : null,
].filter(v => v)

return (
<div className={styles.container}>
<table>
<thead>
<tr>
{headers.map(header => (
<th key={header}>{header}</th>
))}
</tr>
</thead>
<tbody>
{list.length ? (
list.map(item => {
let timestamp = 0
if (item.blockTimestamp) {
timestamp = +item.blockTimestamp
} else if (item.createTimestamp) {
// FIXME: round the timestamp because sometimes a decimal is returned from the API, could be removed when the API is fixed
timestamp = Math.floor(Number(item.createTimestamp))
}

const dateTime = new Date(timestamp).toISOString()
const localTime = dateParser(timestamp, timeBase)

let bigIncome = new BigNumber(item.income)
if (bigIncome.isNaN()) {
bigIncome = new BigNumber(0)
}
const isIncome = bigIncome.isGreaterThanOrEqualTo(0)
return (
<tr key={item.transactionHash}>
<td className={styles.hash} title={t('transaction.transaction_hash')}>
<AddressText
disableTooltip
linkProps={{
to: `/transaction/${item.transactionHash}`,
}}
>
{item.transactionHash}
</AddressText>
</td>
{isPendingListActive ? null : (
<td className={styles.height} title={t('transaction.height')}>
<Link className={styles.blockLink} to={`/block/${item.blockNumber}`}>
{localeNumberString(item.blockNumber)}
</Link>
</td>
)}
<td className={styles.time} title={t('transaction.time')}>
<time dateTime={dateTime}>{localTime}</time>
</td>
<td className={styles.cells} title={`${t('transaction.input')} & ${t('transaction.output')}`}>
{`${t('transaction.input')}: ${item.displayInputs.length} ${t('transaction.output')}: ${
item.displayOutputs.length
}`}
</td>
{address ? (
<td className={styles.income} title={t('transaction.capacity_change')}>
<span data-is-positive={bigIncome.isPositive()} data-is-zero={bigIncome.isZero()}>
<DecimalCapacity
value={localeNumberString(shannonToCkb(bigIncome))}
balanceChangeType={isIncome ? 'income' : 'payment'}
/>
</span>
</td>
) : null}
</tr>
)
})
) : (
<tr>
<td colSpan={headers.length} className={styles.noRecords}>
{t('transaction.no_records')}
</td>
</tr>
)}
</tbody>
</table>
</div>
)
}

export default LiteTransactionList

This file was deleted.

23 changes: 0 additions & 23 deletions src/components/TransactionItem/TransactionLiteIncome/index.tsx

This file was deleted.

Loading