diff --git a/packages/frontend/src/app/dataContract/[identifier]/DataContract.js b/packages/frontend/src/app/dataContract/[identifier]/DataContract.js index f4a6e21c1..4d023c2c9 100644 --- a/packages/frontend/src/app/dataContract/[identifier]/DataContract.js +++ b/packages/frontend/src/app/dataContract/[identifier]/DataContract.js @@ -1,21 +1,19 @@ 'use client' import { useState, useEffect } from 'react' -import Link from 'next/link' import * as Api from '../../../util/Api' import DocumentsList from '../../../components/documents/DocumentsList' -import { LoadingLine, LoadingBlock } from '../../../components/loading' +import { LoadingBlock } from '../../../components/loading' import { ErrorMessageBlock } from '../../../components/Errors' -import { fetchHandlerSuccess, fetchHandlerError } from '../../../util' -import ImageGenerator from '../../../components/imageGenerator' +import { fetchHandlerSuccess, fetchHandlerError, setLoadingProp, paginationHandler } from '../../../util' import { usePathname, useRouter, useSearchParams } from 'next/navigation' import { CodeBlock } from '../../../components/data' -import { - Box, - Container, - TableContainer, Table, Thead, Tbody, Tr, Th, Td, - Tabs, TabList, TabPanels, Tab, TabPanel -} from '@chakra-ui/react' +import { InfoContainer, PageDataContainer } from '../../../components/ui/containers' +import { DataContractDigestCard, DataContractTotalCard } from '../../../components/dataContracts' +import { Container, Tabs, TabList, TabPanels, Tab, TabPanel } from '@chakra-ui/react' +import { useBreadcrumbs } from '../../../contexts/BreadcrumbsContext' +import { TransactionsList } from '../../../components/transactions' +import './DataContract.scss' const pagintationConfig = { itemsOnPage: { @@ -33,37 +31,34 @@ const tabs = [ const defaultTabName = 'documents' function DataContract ({ identifier }) { + const { setBreadcrumbs } = useBreadcrumbs() const [dataContract, setDataContract] = useState({ data: {}, loading: true, error: false }) - const [documents, setDocuments] = useState({ data: {}, props: { printCount: 5 }, loading: true, error: false }) + const [documents, setDocuments] = useState({ data: {}, props: { currentPage: 0 }, loading: true, error: false }) + const [transactions, setTransactions] = useState({ data: {}, props: { currentPage: 0 }, loading: true, error: false }) + const [rate, setRate] = useState({ data: {}, loading: true, error: false }) const pageSize = pagintationConfig.itemsOnPage.default - const [total, setTotal] = useState(1) - const [currentPage, setCurrentPage] = useState(0) - const pageCount = Math.ceil(total / pageSize) const [activeTab, setActiveTab] = useState(tabs.indexOf(defaultTabName.toLowerCase()) !== -1 ? tabs.indexOf(defaultTabName.toLowerCase()) : 0) - const tdTitleWidth = 250 const router = useRouter() const pathname = usePathname() const searchParams = useSearchParams() - const fetchData = () => { - Promise.all([ - Api.getDataContractByIdentifier(identifier) - .then(res => fetchHandlerSuccess(setDataContract, res)) - .catch(err => fetchHandlerError(setDataContract, err)), - Api.getDocumentsByDataContract( - identifier, - pagintationConfig.defaultPage, - pageSize) - .then(res => { - fetchHandlerSuccess(setDocuments, res) - setTotal(res.pagination.total) - }) - .catch(err => fetchHandlerError(setDocuments, err)) + useEffect(() => { + setBreadcrumbs([ + { label: 'Home', path: '/' }, + { label: 'Data Contracts', path: '/dataContracts' }, + { label: dataContract.data?.name || identifier, avatarSource: identifier } ]) - .catch(console.error) - } + }, [setBreadcrumbs, identifier, dataContract]) + + useEffect(() => { + Api.getDataContractByIdentifier(identifier) + .then(res => fetchHandlerSuccess(setDataContract, res)) + .catch(err => fetchHandlerError(setDataContract, err)) - useEffect(fetchData, [identifier]) + Api.getRate() + .then(res => fetchHandlerSuccess(setRate, res)) + .catch(err => fetchHandlerError(setRate, err)) + }, [identifier]) useEffect(() => { const tab = searchParams.get('tab') @@ -89,165 +84,97 @@ function DataContract ({ identifier }) { router.replace(`${pathname}?${urlParameters.toString()}`, { scroll: false }) }, [activeTab]) - const handlePageClick = ({ selected }) => { - setDocuments(state => ({ ...state, loading: true })) - setCurrentPage(selected) - - Api.getDocumentsByDataContract( - identifier, - selected + 1, - pagintationConfig.itemsOnPage.default) - .then(res => setDocuments({ data: res, loading: false, error: false })) - .catch(err => { - console.error(err) - setDocuments({ data: null, loading: false, error: true }) + useEffect(() => { + if (!identifier) return + setLoadingProp(setDocuments) + + Api.getDocumentsByDataContract(identifier, documents.props.currentPage + 1, pageSize, 'desc') + .then(res => fetchHandlerSuccess(setDocuments, res)) + .catch(err => fetchHandlerError(setDocuments, err)) + }, [identifier, documents.props.currentPage]) + + useEffect(() => { + if (!identifier) return + setLoadingProp(setTransactions) + + Api.getDataContractTransactions(identifier, transactions.props.currentPage + 1, pageSize, 'desc') + .then(res => { + fetchHandlerSuccess(setDataContract, { transactionsCount: res?.pagination?.total }) + fetchHandlerSuccess(setTransactions, res) }) - } + .catch(err => fetchHandlerError(setTransactions, err)) + }, [identifier, transactions.props.currentPage]) return ( - - - {!dataContract.error - ? - - - - - - - - - - - - {dataContract.data?.name && - - - - - } - - - - - - - - - {!dataContract.data?.isSystem && - - - - - } - - - - - - - - - {!dataContract.data?.isSystem && - - - - - } - -
Data contract info -
- {dataContract?.data?.name || ''} - {dataContract.data?.identifier - ? - : - } -
-
Identifier - {dataContract.data?.identifier} -
Name - {dataContract.data?.name} -
Owner - - {dataContract.data?.isSystem - ? dataContract.data?.owner - : {dataContract.data?.owner} - } - -
System - {dataContract.data?.isSystem ? 'true' : 'false'} -
Created - {new Date(dataContract.data?.timestamp).toLocaleString()} -
Documents Count - {dataContract.data?.documentsCount} -
Revision - {dataContract.data?.version} -
Transaction - - {dataContract.data?.txHash} - -
- : } -
- - - - - Documents - Schema - - - - - {!documents.error - ? - - - : - } - - - - - {!dataContract.error - ? - {dataContract.data?.schema - ? - : } - - : - } - - - - - -
+
+ + +
+ + + setActiveTab(index)} index={activeTab}> + + Transactions {transactions.data?.resultSet?.length !== undefined + ? + {transactions.data?.resultSet?.length} + + : ''} + + Documents {dataContract.data?.documentsCount !== undefined + ? + {dataContract.data?.documentsCount} + + : ''} + + Schema + + + + {!transactions.error + ? paginationHandler(setTransactions, pagination.selected), + pageCount: Math.ceil(transactions.data?.pagination?.total / pageSize) || 1, + forcePage: transactions.props.currentPage + }} + /> + : + } + + + {!documents.error + ? paginationHandler(setDocuments, pagination.selected), + pageCount: Math.ceil(documents.data?.pagination?.total / pageSize) || 1, + forcePage: documents.props.currentPage + }} + /> + : + } + + + {!dataContract.error + ? + {dataContract.data?.schema + ? + : } + + : + } + + + + + ) } diff --git a/packages/frontend/src/app/dataContract/[identifier]/DataContract.scss b/packages/frontend/src/app/dataContract/[identifier]/DataContract.scss index abf3834e1..92656a976 100644 --- a/packages/frontend/src/app/dataContract/[identifier]/DataContract.scss +++ b/packages/frontend/src/app/dataContract/[identifier]/DataContract.scss @@ -1,27 +1,48 @@ @use '../../../styles/mixins.scss'; @import '../../../styles/variables.scss'; -.DataContractSchema { - white-space: break-spaces; - height: 80%; - padding: 0 10px; - word-wrap: break-word; - box-sizing: border-box; - width: 100%; - max-height: 400px; - overflow-y: auto; - overflow-x: hidden; - - &__Code { - padding: 10px; - font-family: $font-mono; - font-size: 12pt; - width: 100%; +.DataContract { + $gap: 1.5rem; + + .PageDataContainer__Content { + display: flex; + flex-direction: column; + gap: $gap; + } + + &__InfoBlocks { + display: flex; + gap: $gap; + } + + &__InfoBlock { + width: 50%; + } + + @media screen and (max-width: $breakpoint-lg) { + &__InfoBlocks { + flex-direction: column; + } + + &__InfoBlock { + width: 100%; + } + } + + @media screen and (max-width: $breakpoint-md) { + $gap: 0.75rem; + + .PageDataContainer__Content { + gap: $gap; + } + + &__InfoBlocks { + flex-direction: column; + gap: $gap; } -} -@media screen and (max-width: 1020px) { - .DataContractSchema { - width: 100%; + &__InfoBlock { + width: 100%; } + } } diff --git a/packages/frontend/src/components/breadcrumbs/Breadcrumbs.js b/packages/frontend/src/components/breadcrumbs/Breadcrumbs.js index 43346b82c..855301e5d 100644 --- a/packages/frontend/src/components/breadcrumbs/Breadcrumbs.js +++ b/packages/frontend/src/components/breadcrumbs/Breadcrumbs.js @@ -20,17 +20,18 @@ const Breadcrumbs = () => { return (
) diff --git a/packages/frontend/src/components/breadcrumbs/Breadcrumbs.scss b/packages/frontend/src/components/breadcrumbs/Breadcrumbs.scss index 158823d7f..96b943a7a 100644 --- a/packages/frontend/src/components/breadcrumbs/Breadcrumbs.scss +++ b/packages/frontend/src/components/breadcrumbs/Breadcrumbs.scss @@ -5,8 +5,11 @@ max-width: var(--chakra-sizes-container-maxPageW); background: rgba(var(--chakra-colors-gray-675-rgb), .5); border-radius: 0 0 20px 20px; - margin: -500px auto 0; - padding: 512px 12px 12px 12px; + margin: -31.25rem auto 0; + padding-top: 32rem; + padding-bottom: 0.75rem; + @include mixins.navContainerPadding(padding-left); + @include mixins.navContainerPadding(padding-right); &__LinksContainer { display: flex; @@ -62,10 +65,6 @@ } } - @media screen and (max-width: 1440px) { - padding: 512px 24px 12px 24px; - } - @media screen and (max-width: $breakpoint-lg) { display: none; } diff --git a/packages/frontend/src/components/cards/ValueCard.scss b/packages/frontend/src/components/cards/ValueCard.scss index 1e001f1fa..df4e02332 100644 --- a/packages/frontend/src/components/cards/ValueCard.scss +++ b/packages/frontend/src/components/cards/ValueCard.scss @@ -4,7 +4,7 @@ .ValueCard { padding: 8px 12px; border-radius: $border-radius-def; - background-color: var(--chakra-colors-gray-650); + background-color: rgba(var(--chakra-colors-gray-800-rgb), 0.5); border: 1px solid var(--chakra-colors-gray-550); display: flex; align-items: center; diff --git a/packages/frontend/src/components/charts/TimeframeMenu.scss b/packages/frontend/src/components/charts/TimeframeMenu.scss index 133cc0d19..d87957f71 100644 --- a/packages/frontend/src/components/charts/TimeframeMenu.scss +++ b/packages/frontend/src/components/charts/TimeframeMenu.scss @@ -3,7 +3,7 @@ .TimeframeMenu { padding: 12px; - border-radius: 20px; + border-radius: $border-radius-medium; &__ValuesContainer { display: flex; diff --git a/packages/frontend/src/components/data/CodeBlock.js b/packages/frontend/src/components/data/CodeBlock.js index 839a5de97..c26961a12 100644 --- a/packages/frontend/src/components/data/CodeBlock.js +++ b/packages/frontend/src/components/data/CodeBlock.js @@ -6,13 +6,21 @@ import { CopyButton } from '../ui/Buttons' import { SmoothSize } from '../ui/containers' import './CodeBlock.scss' -function CodeBlock ({ code }) { +function CodeBlock ({ code, smoothSize = true, className = '' }) { + const [isAnimating, setIsAnimating] = useState(false) const [fullSize, setFullSize] = useState(false) const [isOverflowing, setIsOverflowing] = useState(false) const parsedCode = code ? JSON.stringify(JSON.parse(code), null, 2) : '' const codeContainerRef = useRef(null) const codeRef = useRef(null) + useEffect(() => { + let timer + if (!smoothSize) setIsAnimating(false) + else timer = setTimeout(() => setIsAnimating(true), 10) + return () => clearTimeout(timer) + }, [smoothSize]) + useEffect(() => { const container = codeContainerRef?.current const code = codeRef?.current @@ -33,9 +41,9 @@ function CodeBlock ({ code }) { }, []) return ( -
+
- + } - : n/a + : } ) diff --git a/packages/frontend/src/components/data/CreditsBlock.scss b/packages/frontend/src/components/data/CreditsBlock.scss index e82f5e18c..cbcbce981 100644 --- a/packages/frontend/src/components/data/CreditsBlock.scss +++ b/packages/frontend/src/components/data/CreditsBlock.scss @@ -35,8 +35,4 @@ background-color: rgba(var(--chakra-colors-green-emeralds-rgb), .2); border-radius: 8px; } - - &__NotActive { - @include mixins.NotActiveText; - } } \ No newline at end of file diff --git a/packages/frontend/src/components/data/Identifier.js b/packages/frontend/src/components/data/Identifier.js index 9219bb300..848429b07 100644 --- a/packages/frontend/src/components/data/Identifier.js +++ b/packages/frontend/src/components/data/Identifier.js @@ -11,6 +11,12 @@ export default function Identifier ({ children, ellipsis = true, avatar, styles return null })() + const sizeClass = (() => { + if (styles.includes('size-32')) return 'Identifier--Size32' + if (styles.includes('size-44')) return 'Identifier--Size44' + return '' + })() + const HighlightedID = ({ children, mode }) => { if (!children) return n/a @@ -29,7 +35,7 @@ export default function Identifier ({ children, ellipsis = true, avatar, styles } return ( -
+
{avatar && children && ( )} diff --git a/packages/frontend/src/components/data/Identifier.scss b/packages/frontend/src/components/data/Identifier.scss index 6a50eab67..e909df287 100644 --- a/packages/frontend/src/components/data/Identifier.scss +++ b/packages/frontend/src/components/data/Identifier.scss @@ -10,6 +10,18 @@ white-space: wrap; word-break: break-all; + &--Size32, &--Size44 { + container-type: inline-size; + width: 100%; + overflow: hidden; + } + + &--Size32 & , &--Size44 & { + &__SymbolsContainer { + width: max-content; + } + } + &--Ellipsis { overflow: hidden; } @@ -22,6 +34,26 @@ } } + &--Size44:not(&--Ellipsis) &__SymbolsContainer { + @container (max-width: 22rem) { + width: calc(22ch); + } + + @container (max-width: 12rem) { + width: calc(15ch); + } + } + + &--Size32:not(&--Ellipsis) &__SymbolsContainer { + @container (max-width: 20rem) { + width: calc(16ch); + } + + @container (max-width: 13rem) { + width: calc(11ch); + } + } + &__SymbolsContainer { color: var(--chakra-colors-gray-250); } diff --git a/packages/frontend/src/components/data/InfoLine.js b/packages/frontend/src/components/data/InfoLine.js index 8a0d91804..3fc6127a2 100644 --- a/packages/frontend/src/components/data/InfoLine.js +++ b/packages/frontend/src/components/data/InfoLine.js @@ -1,13 +1,14 @@ +import { NotActive } from './index' import './InfoLine.scss' function InfoLine ({ title, value, loading, error, className }) { return ( -
+
{title}:
{!error ? !loading && value - : 'n/a' + : }
diff --git a/packages/frontend/src/components/data/InfoLine.scss b/packages/frontend/src/components/data/InfoLine.scss index 8aa2d75d2..6b3f043f5 100644 --- a/packages/frontend/src/components/data/InfoLine.scss +++ b/packages/frontend/src/components/data/InfoLine.scss @@ -29,10 +29,4 @@ max-width: 100%; } } - - &--Error & { - &__Value { - color: var(--chakra-colors-gray-250); - } - } } \ No newline at end of file diff --git a/packages/frontend/src/components/data/NotActive.js b/packages/frontend/src/components/data/NotActive.js new file mode 100644 index 000000000..a6c66629e --- /dev/null +++ b/packages/frontend/src/components/data/NotActive.js @@ -0,0 +1,9 @@ +import './NotActive.scss' + +function NotActive ({ children, className }) { + return ( + {children || 'n/a'} + ) +} + +export default NotActive diff --git a/packages/frontend/src/components/data/NotActive.scss b/packages/frontend/src/components/data/NotActive.scss new file mode 100644 index 000000000..24c95ff0b --- /dev/null +++ b/packages/frontend/src/components/data/NotActive.scss @@ -0,0 +1,6 @@ +@use '../../styles/mixins.scss'; +@import '../../styles/variables.scss'; + +.NotActive { + @include mixins.NotActiveText; +} \ No newline at end of file diff --git a/packages/frontend/src/components/data/TimeDelta.js b/packages/frontend/src/components/data/TimeDelta.js index c6f4d849b..f01504ff5 100644 --- a/packages/frontend/src/components/data/TimeDelta.js +++ b/packages/frontend/src/components/data/TimeDelta.js @@ -1,13 +1,17 @@ 'use client' -import React, { useEffect, useState } from 'react' +import { useEffect, useState } from 'react' import { getTimeDelta } from '../../util' +import { NotActive } from './index' function TimeDelta ({ startDate, endDate, format = 'default' }) { - const [timeDelta, setTimeDelta] = useState('n/a') + const [timeDelta, setTimeDelta] = useState(null) useEffect(() => { - if (!endDate) return + if (!endDate) { + setTimeDelta(null) + return + } let timeout @@ -33,7 +37,7 @@ function TimeDelta ({ startDate, endDate, format = 'default' }) { return () => clearTimeout(timeout) }, [startDate, endDate, format]) - return <>{timeDelta} + return <>{timeDelta || } } export default TimeDelta diff --git a/packages/frontend/src/components/data/index.js b/packages/frontend/src/components/data/index.js index 3ec4fac32..4aba3a9ad 100644 --- a/packages/frontend/src/components/data/index.js +++ b/packages/frontend/src/components/data/index.js @@ -11,6 +11,7 @@ import PrefundedBalance from './PrefundedBalance' import TimeDelta from './TimeDelta' import BigNumber from './BigNumber' import CodeBlock from './CodeBlock' +import NotActive from './NotActive' export { Identifier, @@ -25,5 +26,6 @@ export { PrefundedBalance, TimeDelta, BigNumber, - CodeBlock + CodeBlock, + NotActive } diff --git a/packages/frontend/src/components/dataContracts/DataContractDigestCard.js b/packages/frontend/src/components/dataContracts/DataContractDigestCard.js new file mode 100644 index 000000000..15f347f39 --- /dev/null +++ b/packages/frontend/src/components/dataContracts/DataContractDigestCard.js @@ -0,0 +1,72 @@ +import { DocumentIcon, TransactionsIcon } from '../ui/icons' +import { CreditsBlock, Identifier, InfoLine } from '../data' +import { ValueCard } from '../cards' +import './DataContractDigestCard.scss' + +function DataContractDigestCard ({ dataContract, rate }) { + return ( +
+
+
+ Total transactions)} + value={dataContract.data?.transactionsCount} + loading={dataContract.loading} + error={dataContract.error || dataContract.data?.transactionsCount === undefined} + /> +
+ +
+ Total Documents)} + value={dataContract.data?.documentsCount} + loading={dataContract.loading} + error={dataContract.error || dataContract.data?.documentsCount === undefined} + /> +
+
+ + + + {dataContract.data?.topIdentity} + + + )} + loading={dataContract.loading} + error={dataContract.error || !dataContract.data?.topIdentity} + /> + + + + } + loading={dataContract.loading} + error={dataContract.error || !dataContract.data?.totalGasUsed} + /> + + } + loading={dataContract.loading} + error={dataContract.error || !dataContract.data?.averageGasUsed} + /> +
+ ) +} + +export default DataContractDigestCard diff --git a/packages/frontend/src/components/dataContracts/DataContractDigestCard.scss b/packages/frontend/src/components/dataContracts/DataContractDigestCard.scss new file mode 100644 index 000000000..5086cab46 --- /dev/null +++ b/packages/frontend/src/components/dataContracts/DataContractDigestCard.scss @@ -0,0 +1,47 @@ +@use '../../styles/mixins.scss'; +@import '../../styles/variables.scss'; + +.DataContractDigestCard { + @include mixins.DigestCard(); + border-radius: $border-radius-medium; + container-type: inline-size; + + &__InfoLine { + &--TopIdentity { + .InfoLine__Value { + overflow: hidden; + } + } + + &--TotalTransactions, &--DocumentsCount { + width: 100%; + + .InfoLine__Title { + &, span { + align-items: center; + display: flex; + } + + span { + gap: 0.75rem; + } + } + + .InfoLine__Value { + font-size: 0.813rem; + } + } + } + + @container (max-width: 37.5rem) and (max-width: 37.5rem) { + &__RowContainer { + flex-wrap: wrap; + } + } + + @media screen and (max-width: $breakpoint-sm) { + &__InfoLine { + flex-wrap: wrap; + } + } +} diff --git a/packages/frontend/src/components/dataContracts/DataContractTotalCard.js b/packages/frontend/src/components/dataContracts/DataContractTotalCard.js new file mode 100644 index 000000000..4f64571b5 --- /dev/null +++ b/packages/frontend/src/components/dataContracts/DataContractTotalCard.js @@ -0,0 +1,91 @@ +import ImageGenerator from '../imageGenerator' +import { DateBlock, Identifier, InfoLine } from '../data' +import { HorisontalSeparator } from '../ui/separators' +import { ValueCard } from '../cards' +import './DataContractTotalCard.scss' + +function DataContractTotalCard ({ dataContract, className }) { + return ( +
+ {dataContract.data?.name && +
+ {dataContract.data.name} +
+ } + +
+
+ {!dataContract.error + ? + : 'n/a' + } +
+ +
+ + {dataContract.data?.identifier} + + } + /> + + + + {dataContract.data?.owner} + + + } + /> +
+
+ + + +
+ + + } + loading={dataContract.loading} + error={dataContract.error} + /> +
+
+ ) +} + +export default DataContractTotalCard diff --git a/packages/frontend/src/components/dataContracts/DataContractTotalCard.scss b/packages/frontend/src/components/dataContracts/DataContractTotalCard.scss new file mode 100644 index 000000000..7c6964f7d --- /dev/null +++ b/packages/frontend/src/components/dataContracts/DataContractTotalCard.scss @@ -0,0 +1,79 @@ +@use '../../styles/mixins.scss'; +@import '../../styles/variables.scss'; + +.DataContractTotalCard { + @include mixins.EntityCard(); + + &__Title { + font-weight: 700; + font-size: 0.875rem; + margin-bottom: 0.875rem; + } + + &__HeaderLines { + width: 100%; + } + + &__Identifier, &__Owner { + .InfoLine__Value { + width: 100%; + text-align: right; + + .Identifier { + justify-content: flex-end; + } + } + } + + &__Owner { + .ValueCard { + max-width: max-content; + margin-left: auto; + } + } + + @media screen and (max-width: $breakpoint-md) { + &__Header { + .InfoLine { + flex-wrap: wrap; + justify-content: flex-start; + gap: 5px; + + &__Title { + width: 100%; + } + + &__Value { + width: 100%; + justify-content: flex-start; + text-align: left; + } + } + } + + &__Identifier { + .Identifier { + justify-content: flex-start !important; + } + } + + &__HeaderLines { + padding-right: 90px; + } + + &__Owner { + .ValueCard { + width: max-content; + max-width: 100%; + margin-left: 0; + } + } + + &__Avatar { + position: absolute; + right: 16px; + top: 20px; + margin-right: 0; + } + } +} \ No newline at end of file diff --git a/packages/frontend/src/components/dataContracts/index.js b/packages/frontend/src/components/dataContracts/index.js index 7c8d0c343..30fcbdd56 100644 --- a/packages/frontend/src/components/dataContracts/index.js +++ b/packages/frontend/src/components/dataContracts/index.js @@ -1,9 +1,13 @@ import DataContractsList from './DataContractsList' import { DataContractCards } from './Cards' import InternalConfigCard from './InternalConfigCard' +import DataContractTotalCard from './DataContractTotalCard' +import DataContractDigestCard from './DataContractDigestCard' export { DataContractsList, DataContractCards, - InternalConfigCard + InternalConfigCard, + DataContractTotalCard, + DataContractDigestCard } diff --git a/packages/frontend/src/components/documents/DocumentsListItem.js b/packages/frontend/src/components/documents/DocumentsListItem.js index f532b3d7d..3427fd6b2 100644 --- a/packages/frontend/src/components/documents/DocumentsListItem.js +++ b/packages/frontend/src/components/documents/DocumentsListItem.js @@ -1,5 +1,5 @@ import { Grid, GridItem } from '@chakra-ui/react' -import { Identifier, TimeDelta } from '../data' +import { Identifier, NotActive, TimeDelta } from '../data' import { LinkContainer } from '../ui/containers' import Link from 'next/link' import { useRouter } from 'next/navigation' @@ -12,13 +12,13 @@ function DocumentsListItem ({ document }) { - + {document?.identifier ? {document?.identifier} - : - + : } @@ -34,7 +34,7 @@ function DocumentsListItem ({ document }) { > {document?.owner} - : - + : } diff --git a/packages/frontend/src/components/documents/_variables.scss b/packages/frontend/src/components/documents/_variables.scss index a2b60e852..bc47f7b7b 100644 --- a/packages/frontend/src/components/documents/_variables.scss +++ b/packages/frontend/src/components/documents/_variables.scss @@ -30,6 +30,7 @@ &--Owner { overflow: hidden; + justify-content: flex-end; } @container (max-width: 22rem) { diff --git a/packages/frontend/src/components/identities/IdentityDigestCard.scss b/packages/frontend/src/components/identities/IdentityDigestCard.scss index 18ea4d430..7f0862379 100644 --- a/packages/frontend/src/components/identities/IdentityDigestCard.scss +++ b/packages/frontend/src/components/identities/IdentityDigestCard.scss @@ -2,17 +2,7 @@ @import '../../styles/variables'; .IdentityDigestCard { - @include mixins.InfoContainerPadding(padding, 0px, false); - flex-direction: column; - background: rgba(var(--chakra-colors-gray-800-rgb), .5); - border-radius: $border-radius-def; - container-type: inline-size; - - &--Loading { - .InfoLine__Value { - height: 24px; - } - } + @include mixins.DigestCard(); &, &__Transfers, &__LinesContainer { display: flex; @@ -27,10 +17,6 @@ } } - &__LinesContainer { - flex-direction: column; - } - &__Transfer { width: 50%; display: flex; diff --git a/packages/frontend/src/components/layout/navbar/Navbar.js b/packages/frontend/src/components/layout/navbar/Navbar.js index fb087ed63..cc851f4ad 100644 --- a/packages/frontend/src/components/layout/navbar/Navbar.js +++ b/packages/frontend/src/components/layout/navbar/Navbar.js @@ -46,7 +46,8 @@ function Navbar () { const breadcrumbsActiveRoutes = [ '/validator/', '/transaction/', - '/identity/' + '/identity/', + '/dataContract/' ] const displayBreadcrumbs = breadcrumbsActiveRoutes.some(route => pathname.indexOf(route) !== -1) diff --git a/packages/frontend/src/components/publicKeys/PublicKeysListItem.js b/packages/frontend/src/components/publicKeys/PublicKeysListItem.js index 4d2dafca5..7a5abda6a 100644 --- a/packages/frontend/src/components/publicKeys/PublicKeysListItem.js +++ b/packages/frontend/src/components/publicKeys/PublicKeysListItem.js @@ -4,6 +4,7 @@ import PublicKeyBoundCard from './PublicKeyBoundCard' import { ValueContainer } from '../ui/containers' import { CopyButton } from '../ui/Buttons' import * as pkEnums from '../../enums/publicKey' +import { NotActive } from '../data' import './PublicKeysListItem.scss' import './PublicKeyBoundCard.scss' @@ -15,15 +16,15 @@ function PublicKeysListItem ({ publicKey, className }) {
- {publicKey?.keyId !== undefined ? publicKey?.keyId : '-'} + {publicKey?.keyId !== undefined ? publicKey?.keyId : -} {publicKey?.hash !== undefined ? {publicKey?.hash} - - : n/a + + : } @@ -31,15 +32,15 @@ function PublicKeysListItem ({ publicKey, className }) { ? {pkEnums.KeyTypeEnum?.[publicKey?.type] || '-'} - : n/a + : } {purpose?.title !== undefined ? - {purpose?.title} - - : n/a + {purpose?.title} + + : } @@ -47,7 +48,7 @@ function PublicKeysListItem ({ publicKey, className }) { ? {securityLevel?.title} - : n/a + : } @@ -55,7 +56,7 @@ function PublicKeysListItem ({ publicKey, className }) { ? {publicKey?.readOnly ? 'True' : 'False'} - : n/a + : } @@ -64,7 +65,7 @@ function PublicKeysListItem ({ publicKey, className }) { {publicKey?.data} - : n/a + : } {publicKey?.contractBounds && - : n/a + : } {transaction?.hash ? {transaction.hash} - : n/a + : } @@ -44,7 +44,7 @@ function TransactionsListItem ({ transaction, rate }) { > {transaction.gasUsed} Credits - : n/a + : } @@ -66,13 +66,13 @@ function TransactionsListItem ({ transaction, rate }) { : {transaction?.owner?.identifier} } - : n/a + : } {transaction?.type !== undefined ? - : n/a + : } diff --git a/packages/frontend/src/components/transfers/TransfersListItem.js b/packages/frontend/src/components/transfers/TransfersListItem.js index 83f3873a9..337eb8ad4 100644 --- a/packages/frontend/src/components/transfers/TransfersListItem.js +++ b/packages/frontend/src/components/transfers/TransfersListItem.js @@ -2,7 +2,7 @@ import { Grid, GridItem } from '@chakra-ui/react' import { LinkContainer } from '../ui/containers' -import { BigNumber, Identifier, TimeDelta } from '../data' +import { BigNumber, Identifier, NotActive, TimeDelta } from '../data' import { RateTooltip } from '../ui/Tooltips' import Link from 'next/link' import { useRef } from 'react' @@ -15,7 +15,7 @@ function TransfersListItem ({ transfer, rate }) { const router = useRouter() const Recipient = () => { - if (!transfer?.recipient) return - + if (!transfer?.recipient) return - return ( {transfer?.timestamp ? - : n/a + : } {transfer?.txHash ? {transfer.txHash} - : n/a + : } @@ -66,7 +66,7 @@ function TransfersListItem ({ transfer, rate }) { ? {transfer.amount} - : - + : - } @@ -75,12 +75,15 @@ function TransfersListItem ({ transfer, rate }) { ? {transfer.gasUsed} - : - + : - } - + {transfer?.type + ? + : + } diff --git a/packages/frontend/src/components/ui/containers/PageDataContainer.scss b/packages/frontend/src/components/ui/containers/PageDataContainer.scss index 08d50289d..0750d75e2 100644 --- a/packages/frontend/src/components/ui/containers/PageDataContainer.scss +++ b/packages/frontend/src/components/ui/containers/PageDataContainer.scss @@ -86,7 +86,7 @@ $borderRadius: 20px; margin-bottom: 12px; &::before { - border-radius: 20px; + border-radius: $border-radius-medium; } } } diff --git a/packages/frontend/src/components/ui/containers/ValueContainer.scss b/packages/frontend/src/components/ui/containers/ValueContainer.scss index 7db3f9bc4..5c24e8582 100644 --- a/packages/frontend/src/components/ui/containers/ValueContainer.scss +++ b/packages/frontend/src/components/ui/containers/ValueContainer.scss @@ -6,7 +6,7 @@ align-items: center; flex-wrap: nowrap; border-radius: $border-radius-def; - background-color: var(--chakra-colors-gray-650); + background-color: rgba(var(--chakra-colors-gray-800-rgb), 0.5); padding: 12px; transition: all .1s; diff --git a/packages/frontend/src/components/ui/icons/index.js b/packages/frontend/src/components/ui/icons/index.js index 010ac52e7..4ccfa3af6 100644 --- a/packages/frontend/src/components/ui/icons/index.js +++ b/packages/frontend/src/components/ui/icons/index.js @@ -142,6 +142,38 @@ const PshenmicLogoIcon = (props) => ( ) +const TransactionsIcon = (props) => ( + + + + + + + + + + + +) + +const DocumentIcon = (props) => ( + + + + + + + + + +) + export { CalendarIcon, CalendarIcon2, @@ -158,5 +190,7 @@ export { BigClockIcon, CheckmarkIcon, ErrorCircleIcon, - PshenmicLogoIcon + PshenmicLogoIcon, + TransactionsIcon, + DocumentIcon } diff --git a/packages/frontend/src/styles/components/InfoBlock.scss b/packages/frontend/src/styles/components/InfoBlock.scss index 3e37fb717..c33ae0db9 100644 --- a/packages/frontend/src/styles/components/InfoBlock.scss +++ b/packages/frontend/src/styles/components/InfoBlock.scss @@ -16,7 +16,7 @@ $border-radius: var(--chakra-radii-block); &--Gradient { overflow: hidden; background-color: transparent; - border-radius: 20px; + border-radius: $border-radius-medium; padding: 20px 24px !important; &::before { diff --git a/packages/frontend/src/styles/mixins.scss b/packages/frontend/src/styles/mixins.scss index 08cc9eacf..1d6cf6cff 100644 --- a/packages/frontend/src/styles/mixins.scss +++ b/packages/frontend/src/styles/mixins.scss @@ -81,10 +81,6 @@ white-space: nowrap; color: #fff; } - - &__NotActiveText { - @include NotActiveText; - } } @mixin defListTitles { @@ -425,6 +421,18 @@ } @mixin EntityCard () { + &--Loading { + .InfoLine__Value { + height: 1.5rem; + } + } + + &__Header { + display: flex; + width: 100%; + align-items: center; + } + &__Avatar { display: flex; align-items: center; @@ -452,6 +460,68 @@ &__InfoLine { gap: 14px; } + + &__CommonInfo { + display: flex; + flex-direction: column; + gap: 1.5rem; + } +} + +@mixin DigestCard () { + @include InfoContainerPadding(padding, 0px, false); + font-family: $font-mono; + font-size: 0.75rem; + display: flex; + flex-direction: column; + gap: 0.875rem; + background: rgba(var(--chakra-colors-gray-800-rgb), .5); + border-radius: $border-radius-def; + container-type: inline-size; + + &--Loading { + .InfoLine__Value { + height: 1.5rem; + } + } + + &--Loading & { + &__InfoContainer { + overflow: hidden; + } + + &__InfoContainerValue { + width: 100px; + max-width: 100%; + } + } + + &__RowContainer { + display: flex; + justify-content: space-between; + gap: 0.875rem; + } + + &__InfoContainer { + display: flex; + flex-direction: row; + align-items: center; + justify-content: space-between; + gap: 4px; + padding: 24px; + background: rgba(var(--chakra-colors-gray-800-rgb), .5); + border-radius: $border-radius-def; + width: 100%; + + svg { + width: 1.75rem; + height: 1.75rem; + } + } + + &__LinesContainer { + flex-direction: column; + } } @mixin BrandScroll () { diff --git a/packages/frontend/src/styles/variables.scss b/packages/frontend/src/styles/variables.scss index 21e1e02d9..39ecafe88 100644 --- a/packages/frontend/src/styles/variables.scss +++ b/packages/frontend/src/styles/variables.scss @@ -5,6 +5,7 @@ $breakpoint-xl: '80em'; $breakpoint-2xl: '96em'; $border-radius-def: 10px; +$border-radius-medium: 20px; $font-heading: var(--chakra-fonts-heading); $font-body: var(--chakra-fonts-body); diff --git a/packages/frontend/src/util/Api.js b/packages/frontend/src/util/Api.js index 1590b1d63..274f0ad9d 100644 --- a/packages/frontend/src/util/Api.js +++ b/packages/frontend/src/util/Api.js @@ -63,6 +63,10 @@ const getDataContractByIdentifier = (identifier) => { return call(`dataContract/${identifier}`, 'GET') } +const getDataContractTransactions = (identifier, page = 1, limit = 30, order = 'asc') => { + return call(`dataContract/${identifier}/transactions?page=${page}&limit=${limit}&order=${order}`, 'GET') +} + const getDataContracts = (page = 1, limit = 30, order = 'asc', orderBy) => { return call(`dataContracts?page=${page}&limit=${limit}&order=${order}${orderBy ? `&order_by=${orderBy}` : ''}`, 'GET') } @@ -161,6 +165,7 @@ export { getIdentity, getTransactionsByIdentity, getDataContractsByIdentity, + getDataContractTransactions, getDocumentsByIdentity, getTransfersByIdentity, getWithdrawalsByIdentity,