diff --git a/packages/frontend/src/app/block/[hash]/Block.js b/packages/frontend/src/app/block/[hash]/Block.js index 8cc25b0da..dae44d3c3 100644 --- a/packages/frontend/src/app/block/[hash]/Block.js +++ b/packages/frontend/src/app/block/[hash]/Block.js @@ -15,6 +15,7 @@ import { function Block ({ hash }) { const [block, setBlock] = useState({ data: {}, loading: true, error: false }) + const [rate, setRate] = useState({ data: {}, loading: true, error: false }) const txHashes = block.data?.txs || [] const tdTitleWidth = 250 @@ -24,6 +25,10 @@ function Block ({ hash }) { Api.getBlockByHash(hash) .then(res => fetchHandlerSuccess(setBlock, res)) .catch(err => fetchHandlerError(setBlock, err)) + + Api.getRate() + .then(res => fetchHandlerSuccess(setRate, res)) + .catch(err => fetchHandlerError(setRate, err)) } useEffect(fetchData, [hash]) @@ -117,6 +122,7 @@ function Block ({ hash }) { ({ hash }))} type={'hashes'} + rate={rate.data} /> : null} diff --git a/packages/frontend/src/app/home/Home.js b/packages/frontend/src/app/home/Home.js index 75595a433..55898c67a 100644 --- a/packages/frontend/src/app/home/Home.js +++ b/packages/frontend/src/app/home/Home.js @@ -162,7 +162,7 @@ function Home () { Transactions {!transactions.loading ? !transactions.error - ? + ? : : } diff --git a/packages/frontend/src/app/identity/[identifier]/Identity.js b/packages/frontend/src/app/identity/[identifier]/Identity.js index 52d75d79a..049ae12bb 100644 --- a/packages/frontend/src/app/identity/[identifier]/Identity.js +++ b/packages/frontend/src/app/identity/[identifier]/Identity.js @@ -252,7 +252,7 @@ function Identity ({ identifier }) { {!transactions.error ? !transactions.loading - ? + ? : : } diff --git a/packages/frontend/src/app/transactions/Transactions.js b/packages/frontend/src/app/transactions/Transactions.js index 8914a986d..4417770f2 100644 --- a/packages/frontend/src/app/transactions/Transactions.js +++ b/packages/frontend/src/app/transactions/Transactions.js @@ -21,6 +21,7 @@ const paginateConfig = { function Transactions ({ defaultPage = 1, defaultPageSize }) { const [transactions, setTransactions] = useState({ data: {}, loading: true, error: false }) + const [rate, setRate] = useState({ data: {}, loading: true, error: false }) const [total, setTotal] = useState(1) const [pageSize, setPageSize] = useState(defaultPageSize || paginateConfig.pageSize.default) const [currentPage, setCurrentPage] = useState(defaultPage ? defaultPage - 1 : 0) @@ -41,6 +42,10 @@ function Transactions ({ defaultPage = 1, defaultPageSize }) { setTotal(res.pagination.total) }) .catch(err => fetchHandlerError(setTransactions, err)) + + Api.getRate() + .then(res => fetchHandlerSuccess(setRate, res)) + .catch(err => fetchHandlerError(setRate, err)) } useEffect(() => fetchData(currentPage + 1, pageSize), [pageSize, currentPage]) @@ -72,30 +77,30 @@ function Transactions ({ defaultPage = 1, defaultPageSize }) { className={'Transactions'} > - Transactions + Transactions - {!transactions.error - ? !transactions.loading - ? - : - : - } + {!transactions.error + ? !transactions.loading + ? + : + : + } - {transactions.data?.resultSet?.length > 0 && -
- - setCurrentPage(selected)} - pageCount={pageCount} - forcePage={currentPage} - /> - setPageSize(Number(e.target.value))} - value={pageSize} - items={paginateConfig.pageSize.values} - /> -
- } + {transactions.data?.resultSet?.length > 0 && +
+ + setCurrentPage(selected)} + pageCount={pageCount} + forcePage={currentPage} + /> + setPageSize(Number(e.target.value))} + value={pageSize} + items={paginateConfig.pageSize.values} + /> +
+ }
) diff --git a/packages/frontend/src/components/transactions/StatusIcon.js b/packages/frontend/src/components/transactions/StatusIcon.js new file mode 100644 index 000000000..2455f52c5 --- /dev/null +++ b/packages/frontend/src/components/transactions/StatusIcon.js @@ -0,0 +1,15 @@ +import { SuccessIcon, ErrorIcon, QueuedIcon, PooledIcon, BroadcastedIcon } from '../ui/icons' + +function StatusIcon ({ status, ...props }) { + const StatusIcons = { + SUCCESS: , + FAIL: , + QUEUED: , + POOLED: , + BROADCASTED: + } + + return StatusIcons[status] || <> +} + +export default StatusIcon diff --git a/packages/frontend/src/components/transactions/TransactionsList.js b/packages/frontend/src/components/transactions/TransactionsList.js index e5f6f50c7..426ce4bdd 100644 --- a/packages/frontend/src/components/transactions/TransactionsList.js +++ b/packages/frontend/src/components/transactions/TransactionsList.js @@ -4,7 +4,7 @@ import { EmptyListMessage } from '../ui/lists' import { Grid, GridItem } from '@chakra-ui/react' import './TransactionsList.scss' -export default function TransactionsList ({ transactions = [], showMoreLink, type = 'full', headerStyles = 'default' }) { +export default function TransactionsList ({ transactions = [], showMoreLink, type = 'full', headerStyles = 'default', rate }) { const headerExtraClass = { default: '', light: 'BlocksList__ColumnTitles--Light' @@ -14,11 +14,17 @@ export default function TransactionsList ({ transactions = [], showMoreLink, typ
{type === 'full' && - + Time - Transaction Hash + Hash + + + Gas used + + + Sender Type @@ -31,6 +37,7 @@ export default function TransactionsList ({ transactions = [], showMoreLink, typ )) : There are no transactions yet. diff --git a/packages/frontend/src/components/transactions/TransactionsList.scss b/packages/frontend/src/components/transactions/TransactionsList.scss index b801e5c88..2fc1b1704 100644 --- a/packages/frontend/src/components/transactions/TransactionsList.scss +++ b/packages/frontend/src/components/transactions/TransactionsList.scss @@ -1,13 +1,19 @@ @use '../../styles/mixins.scss'; +@use './variables' as txs; @import '../../styles/variables.scss'; .TransactionsList { + container-type: inline-size; + &__ColumnTitles { @include mixins.defListTitles; - grid-template-columns: 100px calc(100% - 270px) 170px; + @include txs.Columns(); } &__ColumnTitle { + @include txs.Column(); + width: 100%; + display: block; word-break: normal; white-space: normal; overflow-wrap: break-word; @@ -21,15 +27,13 @@ } } - @media screen and (max-width: $breakpoint-sm) { - &__ColumnTitles { - grid-template-columns: 1fr 1fr; - } - + @container (max-width: 660px) { &__ColumnTitle { - &--Hash { - display: none; + &--Sender { + width: 0; + height: 0; + visibility: hidden; } } } -} \ No newline at end of file +} diff --git a/packages/frontend/src/components/transactions/TransactionsListItem.js b/packages/frontend/src/components/transactions/TransactionsListItem.js index b3bf6dcfb..ab8d47bd6 100644 --- a/packages/frontend/src/components/transactions/TransactionsListItem.js +++ b/packages/frontend/src/components/transactions/TransactionsListItem.js @@ -4,10 +4,12 @@ import Link from 'next/link' import { getTimeDelta } from '../../util/index' import { Grid, GridItem } from '@chakra-ui/react' import TypeBadge from './TypeBadge' -import { Identifier } from '../data' +import { Identifier, Credits } from '../data' +import StatusIcon from './StatusIcon' +import { RateTooltip } from '../ui/Tooltips' import './TransactionsListItem.scss' -function TransactionsListItem ({ transaction }) { +function TransactionsListItem ({ transaction, rate }) { return ( {transaction?.timestamp && + {getTimeDelta(new Date(), new Date(transaction.timestamp))} } {transaction?.hash && - - {transaction.hash} + + {transaction.hash} + + } + {transaction?.gasUsed && + + + {transaction.gasUsed} Credits + + + } + {(transaction?.sender || true) && + + 3TfBxpwdmiHsrajx7EmErGnV597uYdH3JGhvwpVDcdAT } {transaction?.type !== undefined && - + } diff --git a/packages/frontend/src/components/transactions/TransactionsListItem.scss b/packages/frontend/src/components/transactions/TransactionsListItem.scss index 64532b333..dae5d4721 100644 --- a/packages/frontend/src/components/transactions/TransactionsListItem.scss +++ b/packages/frontend/src/components/transactions/TransactionsListItem.scss @@ -1,4 +1,5 @@ @use '../../styles/mixins.scss'; +@use './variables' as txs; @import '../../styles/variables.scss'; .TransactionsListItem { @@ -6,8 +7,7 @@ display: block; &__Content { - display: grid; - grid-template-columns: 100px 1fr auto; + @include txs.Columns(); &--Inline { display: inline !important; @@ -15,24 +15,20 @@ } &__Column { - display: flex; - align-items: center; + @include txs.Column(); &--Timestamp { font-family: $font-mono; - font-size: 12px; - margin-right: 16px; + font-size: 0.75rem; white-space: nowrap; color: #fff; } - &--Identifier { + &--Hash, &--Sender { color: var(--chakra-colors-gray-250); font-family: $font-mono; flex-grow: 1; - margin-right: 16px; - font-size: 12px; - + font-size: 0.75rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; @@ -48,28 +44,46 @@ justify-content: flex-end; white-space: nowrap; } - } - @media screen and (max-width: $breakpoint-sm) { - &__Column { - &--Timestamp { - grid-column: 1 / 1; - } + &--GasUsed { + font-size: 0.75rem; + text-transform: uppercase; + color: #fff; + white-space: nowrap; + text-align: left; + } + } - &--Identifier { - order: 3; - grid-column: 1 / -1; - margin-right: 0; - margin-top: 12px; + @container (max-width: 660px) { + &__Column { + &--Sender { + .Identifier__SymbolsContainer { + display: none; } - &--Type { - grid-column: 0 / 1; + .Identifier__Avatar { + margin: 0; } } + } + } + + @container (max-width: 400px) { + padding: 5px 8px; - &__Content { - grid-template-columns: 1fr 1fr; + &__Column { + &, .Identifier { + font-size: 0.563rem; } + } + + &__TypeBadge { + font-size: 0.438rem !important; + line-height: 15px; + } + + &__StatusIcon { + display: none !important; + } } } \ No newline at end of file diff --git a/packages/frontend/src/components/transactions/TypeBadge.js b/packages/frontend/src/components/transactions/TypeBadge.js index 9478ae22b..1556db1fc 100644 --- a/packages/frontend/src/components/transactions/TypeBadge.js +++ b/packages/frontend/src/components/transactions/TypeBadge.js @@ -3,7 +3,7 @@ import { getTransitionTypeKeyById } from '../../util/index' import { TransactionTypesEnum, TransactionTypesColors } from '../../enums/state.transition.type' import { Tooltip } from '../ui/Tooltips' -function TypeBadge ({ typeId }) { +function TypeBadge ({ typeId, ...props }) { const TransitionTypeKey = getTransitionTypeKeyById(typeId) const descriptions = { @@ -24,7 +24,10 @@ function TypeBadge ({ typeId }) { content={descriptions[TransitionTypeKey]} placement={'top'} > - + {TransactionTypesEnum[TransitionTypeKey]} diff --git a/packages/frontend/src/components/transactions/_variables.scss b/packages/frontend/src/components/transactions/_variables.scss new file mode 100644 index 000000000..79a8e465c --- /dev/null +++ b/packages/frontend/src/components/transactions/_variables.scss @@ -0,0 +1,77 @@ +@mixin Columns () { + display: grid; + gap: 16px; + + grid-template-columns: + minmax(120px, 120px) + minmax(0, 600px) + minmax(0, 150px) + minmax(0, 400px) + 150px; + + @container (max-width: 810px) { + grid-template-columns: + minmax(120px, 120px) + minmax(0, 240px) + minmax(0, 1fr) + auto; + } + + @container (max-width: 660px) { + grid-template-columns: + minmax(120px, 120px) + minmax(0, 600px) + 20px + auto; + } + + @container (max-width: 430px) { + gap: 12px; + grid-template-columns: + minmax(120px, 120px) + minmax(0, 600px) + auto; + } + + @container (max-width: 400px) { + grid-template-columns: + minmax(80px, 80px) + minmax(0, 600px) + auto; + } +} + +@mixin Column () { + display: flex; + align-items: center; + + &--Hash { + max-width: 600px; + } + + &--Sender { + max-width: 400px; + width: 100%; + } + + &--Type { + justify-content: flex-end; + white-space: nowrap; + } + + &--GasUsed { + width: 150px; + } + + @container (max-width: 810px) { + &--GasUsed { + display: none; + } + } + + @container (max-width: 430px) { + &--Sender { + display: none; + } + } +} diff --git a/packages/frontend/src/components/ui/Tooltips/RateTooltip.js b/packages/frontend/src/components/ui/Tooltips/RateTooltip.js index f0266b80d..9adfa201c 100644 --- a/packages/frontend/src/components/ui/Tooltips/RateTooltip.js +++ b/packages/frontend/src/components/ui/Tooltips/RateTooltip.js @@ -2,7 +2,7 @@ import Tooltip from './Tooltip' import { roundUsd, creditsToDash } from '../../../util' import './RateTooltip.scss' -export default function RateTooltip ({ credits, dash, usd, rate, children }) { +export default function RateTooltip ({ credits, dash, usd, rate, children, placement }) { if (!dash && typeof credits === 'number') dash = creditsToDash(credits) if (!usd && typeof dash === 'number' && rate?.usd) usd = dash * rate?.usd @@ -14,7 +14,7 @@ export default function RateTooltip ({ credits, dash, usd, rate, children }) { {typeof usd === 'number' &&
~{roundUsd(Number(usd))}$
}
)} - placement={'right'} + placement={placement || 'right'} > {children} diff --git a/packages/frontend/src/components/ui/icons/index.js b/packages/frontend/src/components/ui/icons/index.js index 49b8c2d01..fe24b1ae4 100644 --- a/packages/frontend/src/components/ui/icons/index.js +++ b/packages/frontend/src/components/ui/icons/index.js @@ -24,8 +24,61 @@ const ArrowCornerIcon = (props) => ( ) +const SuccessIcon = (props) => ( + + + + + + +) + +const ErrorIcon = (props) => ( + + + + + + + +) + +const QueuedIcon = (props) => ( + + + + + + +) + +const PooledIcon = (props) => ( + + + + + + + + +) + +const BroadcastedIcon = (props) => ( + + + + + + +) + export { CalendarIcon, CircleIcon, - ArrowCornerIcon + ArrowCornerIcon, + SuccessIcon, + ErrorIcon, + QueuedIcon, + PooledIcon, + BroadcastedIcon } diff --git a/packages/frontend/src/util/index.js b/packages/frontend/src/util/index.js index f1b8fed63..fb964016b 100644 --- a/packages/frontend/src/util/index.js +++ b/packages/frontend/src/util/index.js @@ -62,9 +62,9 @@ function getTimeDelta (startDate, endDate, format) { } else if (hours > 0) { return `${hours}h ${isFuture ? 'left' : 'ago'}` } else if (minutes > 0) { - return `${minutes} min. ${isFuture ? 'left' : 'ago'}` + return `${minutes} min ${isFuture ? 'left' : 'ago'}` } else { - return `${seconds} sec. ${isFuture ? 'left' : 'ago'}` + return `${seconds} sec ${isFuture ? 'left' : 'ago'}` } }