diff --git a/docs/images/profile-bg-image.webp b/docs/images/profile-bg-image.webp
new file mode 100755
index 000000000..80fbdc288
Binary files /dev/null and b/docs/images/profile-bg-image.webp differ
diff --git a/hapi/src/config/eos.config.js b/hapi/src/config/eos.config.js
index d61c547d4..53d2a5ad2 100644
--- a/hapi/src/config/eos.config.js
+++ b/hapi/src/config/eos.config.js
@@ -52,10 +52,11 @@ module.exports = {
wax: 'wax'
},
healthCheckAPIs: [
- { name: 'chain-api', api: '/v1/chain/get_info' },
- { name: 'atomic-assets-api', api: '/atomicassets/v1/config' },
- { name: 'hyperion-v2', api: '/v2/health' },
- { name: 'light-api', api: '/api/status' }
+ { pattern: /^chain-api$/, api: '/v1/chain/get_info' },
+ { pattern: /^atomic-assets-api$/, api: '/atomicassets/v1/config' },
+ { pattern: /^hyperion-v2$/, api: '/v2/health' },
+ { pattern: /^light-api$/, api: '/api/status' },
+ { pattern: /^libre-.+$/, api: ''},
],
rewardsToken: process.env.HAPI_REWARDS_TOKEN,
eosRateUrl: process.env.HAPI_EOSRATE_GET_STATS_URL,
diff --git a/hapi/src/routes/get-eos-rate-stats.route.js b/hapi/src/routes/get-eos-rate-stats.route.js
index dd0fa54c4..cab2c3c21 100644
--- a/hapi/src/routes/get-eos-rate-stats.route.js
+++ b/hapi/src/routes/get-eos-rate-stats.route.js
@@ -1,16 +1,19 @@
+const Joi = require('joi')
+
const { eosConfig } = require('../config')
const { axiosUtil } = require('../utils')
module.exports = {
method: 'POST',
path: '/get-eos-rate',
- handler: async () => {
+ handler: async ({ payload: { input } }) => {
if (
!eosConfig.eosRateUrl ||
!eosConfig.eosRateUser ||
- !eosConfig.eosRatePassword
+ !eosConfig.eosRatePassword ||
+ !input?.bp
) {
- return []
+ return {}
}
const buf = Buffer.from(
@@ -27,9 +30,16 @@ module.exports = {
}
)
- return data?.getRatesStats?.bpsStats || []
+ return data?.getRatesStats?.bpsStats?.find(rating => rating?.bp === input?.bp) || {}
},
options: {
+ validate: {
+ payload: Joi.object({
+ input: Joi.object({
+ bp: Joi.string().required()
+ }).required()
+ }).options({ stripUnknown: true })
+ },
auth: false
}
}
diff --git a/hapi/src/services/producer.service.js b/hapi/src/services/producer.service.js
index 7ce3168f2..78d1886dc 100644
--- a/hapi/src/services/producer.service.js
+++ b/hapi/src/services/producer.service.js
@@ -279,7 +279,7 @@ const getHealthCheckResponse = async endpoint => {
if (endpoint?.features?.length) {
for (const API of eosConfig.healthCheckAPIs) {
- if (endpoint.features?.some(feature => feature === API.name)) {
+ if (endpoint.features?.some(feature => API.pattern?.test(feature))) {
startTime = new Date()
response = await producerUtil.getNodeInfo(endpoint.value, API.api)
diff --git a/hapi/src/services/stats.service.js b/hapi/src/services/stats.service.js
index bd682b2a0..4094e449c 100644
--- a/hapi/src/services/stats.service.js
+++ b/hapi/src/services/stats.service.js
@@ -425,7 +425,7 @@ const syncTransactionsInfo = async () => {
}
payload.average_daily_transactions_in_last_week =
- payload.transactions_in_last_day / 7 || 0
+ payload.transactions_in_last_week / 7 || 0
const stats = await getStats()
diff --git a/hasura/metadata/actions.graphql b/hasura/metadata/actions.graphql
index fa62826d5..2550492fd 100644
--- a/hasura/metadata/actions.graphql
+++ b/hasura/metadata/actions.graphql
@@ -19,7 +19,9 @@ type Mutation {
}
type Query {
- eosrate_stats: [EOSRateStats]
+ eosrate_stats(
+ bp: String!
+ ): EOSRateStats
}
type Query {
diff --git a/webapp/src/components/ComplianceBar/index.js b/webapp/src/components/ComplianceBar/index.js
new file mode 100644
index 000000000..25d2703a3
--- /dev/null
+++ b/webapp/src/components/ComplianceBar/index.js
@@ -0,0 +1,45 @@
+import React from 'react'
+import styled from 'styled-components'
+import { makeStyles } from '@mui/styles'
+import Typography from '@mui/material/Typography'
+
+import styles from './styles'
+
+const useStyles = makeStyles(styles)
+
+const PercentageBar = styled.div`
+ width: 80%;
+ height: 8px;
+ & div {
+ border-radius: ${props => props.theme.spacing(4)};
+ position: relative;
+ height: 100%;
+ max-width: 100%;
+ }
+ & > div + div {
+ width: calc( ${props => props.$percentage} * 100% );
+ top: -100%;
+ background-color: ${props =>
+ props.$percentage >= 0.8
+ ? props.theme.palette.success.main
+ : props.$percentage >= 0.5
+ ? props.theme.palette.warning.main
+ : props.theme.palette.error.main};
+ }
+ `
+
+const ComplianceBar = ({ pass, total }) => {
+ const classes = useStyles()
+
+ return (
+
+
{`${pass}/${total}`}
+
+
+
+
+
+ )
+}
+
+export default ComplianceBar
diff --git a/webapp/src/components/ComplianceBar/styles.js b/webapp/src/components/ComplianceBar/styles.js
new file mode 100644
index 000000000..4ffd2a3ba
--- /dev/null
+++ b/webapp/src/components/ComplianceBar/styles.js
@@ -0,0 +1,10 @@
+export default (theme) => ({
+ container: {
+ display: 'flex',
+ flexDirection: 'column',
+ alignItems: 'center',
+ },
+ bar: {
+ backgroundColor: theme.palette.neutral.light,
+ },
+})
diff --git a/webapp/src/components/ContractTables/index.js b/webapp/src/components/ContractTables/index.js
index 0e0f2b0c5..38a28e81f 100644
--- a/webapp/src/components/ContractTables/index.js
+++ b/webapp/src/components/ContractTables/index.js
@@ -234,8 +234,8 @@ const ContractTables = ({
color="primary"
className={classes.refreshButton}
onClick={() => handleSubmit()}
+ startIcon={}
>
-
{t('refreshData')}
)}
diff --git a/webapp/src/components/CountryFlag/index.js b/webapp/src/components/CountryFlag/index.js
index 990eecea8..3005ee286 100644
--- a/webapp/src/components/CountryFlag/index.js
+++ b/webapp/src/components/CountryFlag/index.js
@@ -25,7 +25,7 @@ const CountryFlag = ({ code = '' }) => {
}
CountryFlag.propTypes = {
- code: PropTypes.string
+ code: PropTypes.string,
}
export default CountryFlag
diff --git a/webapp/src/components/CountryFlag/styles.js b/webapp/src/components/CountryFlag/styles.js
index 3506c5341..164837b39 100644
--- a/webapp/src/components/CountryFlag/styles.js
+++ b/webapp/src/components/CountryFlag/styles.js
@@ -1,6 +1,12 @@
export default (theme) => ({
country: {
marginRight: theme.spacing(0.5),
- marginLeft: theme.spacing(1)
- }
+ marginLeft: theme.spacing(1),
+ '& .flag-icon': {
+ borderRadius: '50%',
+ width: '24px !important',
+ height: '24px !important',
+ top: '-5px',
+ },
+ },
})
diff --git a/webapp/src/components/EmptyState/EmptyStateRow.js b/webapp/src/components/EmptyState/EmptyStateRow.js
new file mode 100644
index 000000000..77f89b0cf
--- /dev/null
+++ b/webapp/src/components/EmptyState/EmptyStateRow.js
@@ -0,0 +1,23 @@
+import React from 'react'
+import { makeStyles } from '@mui/styles'
+import { useTranslation } from 'react-i18next'
+
+import AlertSvg from 'components/Icons/Alert'
+
+import styles from './styles'
+
+const useStyles = makeStyles(styles)
+
+const EmptyStateRow = () => {
+ const classes = useStyles()
+ const { t } = useTranslation('producerCardComponent')
+
+ return (
+
+ )
+}
+
+export default EmptyStateRow
diff --git a/webapp/src/components/EmptyState/index.js b/webapp/src/components/EmptyState/index.js
new file mode 100644
index 000000000..a2211fdec
--- /dev/null
+++ b/webapp/src/components/EmptyState/index.js
@@ -0,0 +1,37 @@
+import React from 'react'
+import { Link as RouterLink } from 'react-router-dom'
+import { makeStyles } from '@mui/styles'
+import { useTranslation } from 'react-i18next'
+import Link from '@mui/material/Link'
+
+import styles from './styles'
+
+const useStyles = makeStyles(styles)
+
+const EmptyState = () => {
+ const classes = useStyles()
+ const { t } = useTranslation('producerCardComponent')
+
+ return (
+
+
+
{t('emptyState')}
+
+ {t('viewList')}
+
+
+ )
+}
+
+export default EmptyState
diff --git a/webapp/src/components/EmptyState/styles.js b/webapp/src/components/EmptyState/styles.js
new file mode 100644
index 000000000..d92168157
--- /dev/null
+++ b/webapp/src/components/EmptyState/styles.js
@@ -0,0 +1,44 @@
+export default (theme) => ({
+ emptyState: {
+ display: 'flex',
+ flexDirection: 'column',
+ alignItems: 'center',
+ width: '100%',
+ '& a': {
+ color: theme.palette.primary.main,
+ textDecorationColor: theme.palette.primary.main,
+ },
+ },
+ emptyStateContainer: {
+ '& span': {
+ width: '16em',
+ height: '45px',
+ fontSize: '1em',
+ fontWeight: 'bold',
+ fontStretch: 'normal',
+ fontStyle: 'normal',
+ letterSpacing: '-0.22px',
+ textAlign: 'center',
+ color: theme.palette.neutral.darker,
+ },
+ },
+ emptyStateRow: {
+ display: 'flex',
+ alignItems: 'center',
+ justifyContent: 'center',
+ '& span': {
+ marginTop: theme.spacing(1),
+ },
+ },
+ imgError: {
+ [theme.breakpoints.down('lg')]: {
+ width: '200px',
+ height: '120px',
+ },
+ [theme.breakpoints.up('lg')]: {
+ width: '260px',
+ height: '160px',
+ },
+ objectFit: 'contain',
+ },
+})
diff --git a/webapp/src/components/Header/index.js b/webapp/src/components/Header/index.js
index 3a3eae5cd..99f77cdb1 100644
--- a/webapp/src/components/Header/index.js
+++ b/webapp/src/components/Header/index.js
@@ -1,7 +1,12 @@
-import React, { useEffect, useState } from 'react'
+import React, { useEffect, useState, lazy, Suspense } from 'react'
import PropTypes from 'prop-types'
import { makeStyles } from '@mui/styles'
-import { Hidden, Menu, MenuItem, AppBar, IconButton } from '@mui/material'
+import Hidden from '@mui/material/Hidden'
+import Menu from '@mui/material/Menu'
+import MenuItem from '@mui/material/MenuItem'
+import AppBar from '@mui/material/AppBar'
+import IconButton from '@mui/material/IconButton'
+import Skeleton from '@mui/material/Skeleton'
import Button from '@mui/material/Button'
import Toolbar from '@mui/material/Toolbar'
import MenuIcon from '@mui/icons-material/Menu'
@@ -10,9 +15,10 @@ import { useTranslation } from 'react-i18next'
import moment from 'moment'
import 'moment/locale/es'
-import AuthButton from './AuthButton'
import styles from './styles'
+const AuthButton = lazy(() => import('./AuthButton'))
+
const useStyles = makeStyles(styles)
const languages = [
@@ -72,9 +78,7 @@ const LanguageMenu = () => {
onClick={toggleMenu}
className={classes.btnLanguage}
>
-
- {currentLanguaje.toUpperCase()}
-
+ {currentLanguaje.toUpperCase()}