diff --git a/.gitattributes b/.gitattributes deleted file mode 100644 index d4431e2963..0000000000 --- a/.gitattributes +++ /dev/null @@ -1 +0,0 @@ -__snapshots__/** filter=lfs diff=lfs merge=lfs -text diff --git a/.husky/pre-push b/.husky/pre-push deleted file mode 100755 index 216e91527e..0000000000 --- a/.husky/pre-push +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh -command -v git-lfs >/dev/null 2>&1 || { echo >&2 "\nThis repository is configured for Git LFS but 'git-lfs' was not found on your path. If you no longer wish to use Git LFS, remove this hook by deleting '.git/hooks/pre-push'.\n"; exit 2; } -git lfs pre-push "$@" diff --git a/eslint.config.mjs b/eslint.config.mjs index 8483f6bede..440e036060 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -410,7 +410,6 @@ export default tseslint.config( // rules customizations eqeqeq: [ 'error', 'allow-null' ], 'id-match': [ 'error', '^[\\w$]+$' ], - 'max-len': [ 'error', 160, 4 ], 'no-console': 'error', 'no-implicit-coercion': [ 'error', { number: true, diff --git a/lib/hooks/useNavItems.tsx b/lib/hooks/useNavItems.tsx index 34389468aa..68e6ba16e7 100644 --- a/lib/hooks/useNavItems.tsx +++ b/lib/hooks/useNavItems.tsx @@ -223,31 +223,6 @@ export default function useNavItems(): ReturnType { }, ].filter(Boolean); - const apiNavItems: Array = [ - config.features.restApiDocs.isEnabled ? { - text: 'REST API', - nextRoute: { pathname: '/api-docs' as const }, - icon: 'restAPI', - isActive: pathname === '/api-docs', - } : null, - config.features.graphqlApiDocs.isEnabled ? { - text: 'GraphQL', - nextRoute: { pathname: '/graphiql' as const }, - icon: 'graphQL', - isActive: pathname === '/graphiql', - } : null, - !config.UI.navigation.hiddenLinks?.rpc_api && { - text: 'RPC API', - icon: 'RPC', - url: 'https://docs.blockscout.com/for-users/api/rpc-endpoints', - }, - !config.UI.navigation.hiddenLinks?.eth_rpc_api && { - text: 'Eth RPC API', - icon: 'RPC', - url: ' https://docs.blockscout.com/for-users/api/eth-rpc', - }, - ].filter(Boolean); - const otherNavItems: Array | Array> = [ { text: 'Verify contract', @@ -303,12 +278,6 @@ export default function useNavItems(): ReturnType { icon: 'stats', isActive: pathname.startsWith('/stats'), } : null, - apiNavItems.length > 0 && { - text: 'API', - icon: 'restAPI', - isActive: apiNavItems.some(item => isInternalItem(item) && item.isActive), - subItems: apiNavItems, - }, { text: 'Other', icon: 'gear', diff --git a/toolkit/chakra/skeleton.tsx b/toolkit/chakra/skeleton.tsx index 1fbfc86138..3746b24fe0 100644 --- a/toolkit/chakra/skeleton.tsx +++ b/toolkit/chakra/skeleton.tsx @@ -53,7 +53,7 @@ export const Skeleton = React.forwardRef( const { loading = false, ...rest } = props; return ( { - const background = { - _light: - config.UI.homepage.heroBanner?.background?.[0] || - config.UI.homepage.plate.background || - BACKGROUND_DEFAULT, - _dark: - config.UI.homepage.heroBanner?.background?.[1] || - config.UI.homepage.heroBanner?.background?.[0] || - config.UI.homepage.plate.background || - BACKGROUND_DEFAULT, - }; + // Use config background if provided (could be gradient string), otherwise use premium gradient + const configBackgroundLight = config.UI.homepage.heroBanner?.background?.[0] || config.UI.homepage.plate.background; + const configBackgroundDark = config.UI.homepage.heroBanner?.background?.[1] || + config.UI.homepage.heroBanner?.background?.[0] || + config.UI.homepage.plate.background; + + const hasConfigBackground = Boolean(configBackgroundLight); + + // Bright cyan-based gradient matching OpenGradient branding + const premiumGradientLight = 'linear-gradient(135deg, #00d4ff 0%, #00a3cc 25%, #0066ff 50%, #00d4ff 75%, #00ffff 100%)'; + const premiumGradientDark = 'linear-gradient(135deg, #001a33 0%, #003366 25%, #004080 50%, #001a33 75%, #002244 100%)'; + + const backgroundValue = hasConfigBackground ? + { _light: configBackgroundLight, _dark: configBackgroundDark } : + { _light: premiumGradientLight, _dark: premiumGradientDark }; const textColor = { _light: @@ -50,44 +53,90 @@ const HeroBanner = () => { }; return ( - - - - - { - config.meta.seo.enhancedDataEnabled ? - `${ config.chain.name } Testnet Explorer` : - `${ config.chain.name } Testnet Explorer` - } - - { config.UI.navigation.layout === 'vertical' && ( - - { config.features.rewards.isEnabled && } - { - (config.features.account.isEnabled && ) || - (config.features.blockchainInteraction.isEnabled && ) - } + + + + + + + { + config.meta.seo.enhancedDataEnabled ? + `${ config.chain.name } Explorer` : + `${ config.chain.name } Explorer` + } + + + { config.UI.navigation.layout === 'vertical' && ( + + { config.features.rewards.isEnabled && } + { + (config.features.account.isEnabled && ) || + (config.features.blockchainInteraction.isEnabled && ) + } + + ) } + + + - ) } - - - - - + + + + + ); }; diff --git a/ui/home/LatestBlocks.tsx b/ui/home/LatestBlocks.tsx index 4991555835..c11cd41b61 100644 --- a/ui/home/LatestBlocks.tsx +++ b/ui/home/LatestBlocks.tsx @@ -1,4 +1,4 @@ -import { chakra, Box, Flex, Text, VStack } from '@chakra-ui/react'; +import { chakra, Box, Text } from '@chakra-ui/react'; import { useQueryClient } from '@tanstack/react-query'; import React from 'react'; @@ -11,14 +11,12 @@ import config from 'configs/app'; import useApiQuery, { getResourceKey } from 'lib/api/useApiQuery'; import useInitialList from 'lib/hooks/useInitialList'; import useIsMobile from 'lib/hooks/useIsMobile'; -import { nbsp } from 'lib/html-entities'; import useSocketChannel from 'lib/socket/useSocketChannel'; import useSocketMessage from 'lib/socket/useSocketMessage'; import { BLOCK } from 'stubs/block'; import { HOMEPAGE_STATS } from 'stubs/stats'; import { Heading } from 'toolkit/chakra/heading'; import { Link } from 'toolkit/chakra/link'; -import { Skeleton } from 'toolkit/chakra/skeleton'; import LatestBlocksItem from './LatestBlocksItem'; @@ -27,9 +25,9 @@ const LatestBlocks = () => { // const blocksMaxCount = isMobile ? 2 : 3; let blocksMaxCount: number; if (config.features.rollup.isEnabled || config.UI.views.block.hiddenFields?.total_reward) { - blocksMaxCount = isMobile ? 4 : 5; + blocksMaxCount = isMobile ? 6 : 10; } else { - blocksMaxCount = isMobile ? 2 : 3; + blocksMaxCount = isMobile ? 4 : 8; } const { data, isPlaceholderData, isError } = useApiQuery('homepage_blocks', { queryOptions: { @@ -84,43 +82,62 @@ const LatestBlocks = () => { content = ( <> - + { dataToShow.map(((block, index) => ( - + + + ))) } - - - View all blocks - + + + + View all blocks + + ); } return ( - Latest blocks - { statsQueryResult.data?.network_utilization_percentage !== undefined && ( - - - Network utilization:{ nbsp } - - - { statsQueryResult.data?.network_utilization_percentage.toFixed(2) }% - - - ) } - { statsQueryResult.data?.celo && ( - - Current epoch: - #{ statsQueryResult.data.celo.epoch_number } - - ) } - + + + Latest blocks + + { statsQueryResult.data?.celo && ( + + Current epoch: + #{ statsQueryResult.data.celo.epoch_number } + + ) } + + { content } diff --git a/ui/home/LatestBlocksItem.tsx b/ui/home/LatestBlocksItem.tsx index 3199bf755c..fed7a72e28 100644 --- a/ui/home/LatestBlocksItem.tsx +++ b/ui/home/LatestBlocksItem.tsx @@ -1,10 +1,9 @@ -import { Box, Flex, Grid } from '@chakra-ui/react'; +import { Box, Flex, Text } from '@chakra-ui/react'; import React from 'react'; import type { Block } from 'types/api/block'; import config from 'configs/app'; -import getBlockTotalReward from 'lib/block/getBlockTotalReward'; import getNetworkValidatorTitle from 'lib/networks/getNetworkValidatorTitle'; import { Skeleton } from 'toolkit/chakra/skeleton'; import { Tooltip } from 'toolkit/chakra/tooltip'; @@ -20,27 +19,28 @@ type Props = { }; const LatestBlocksItem = ({ block, isLoading, animation }: Props) => { - const totalReward = getBlockTotalReward(block); return ( - + { block.celo?.is_epoch_block && ( - + ) } { enableIncrement={ !isLoading } isLoading={ isLoading } color="text.secondary" - display="inline-block" - textStyle="sm" + textStyle="xs" flexShrink={ 0 } - ml={ 2 } /> - - Txn - { block.transaction_count } - - { !config.features.rollup.isEnabled && !config.UI.views.block.hiddenFields?.total_reward && ( - <> - Reward - { totalReward.dp(10).toFixed() } - - ) } - + + + Txn + + { block.transaction_count } + + { !config.features.rollup.isEnabled && !config.UI.views.block.hiddenFields?.miner && ( - <> - { getNetworkValidatorTitle() } - - + + + { getNetworkValidatorTitle() } + + + + + ) } - + ); }; diff --git a/ui/home/LatestTxs.tsx b/ui/home/LatestTxs.tsx index 08fcf8d9de..113a687110 100644 --- a/ui/home/LatestTxs.tsx +++ b/ui/home/LatestTxs.tsx @@ -1,4 +1,4 @@ -import { Box, Flex, Text } from '@chakra-ui/react'; +import { Box, Text } from '@chakra-ui/react'; import React from 'react'; import { route } from 'nextjs-routes'; @@ -34,7 +34,7 @@ const LatestTransactions = () => { return ( <> - + { data.slice(0, txsCount).map(((tx, index) => ( { ))) } - + { data.slice(0, txsCount).map(((tx, index) => ( { ))) } - - View all transactions - + + + View all transactions + + ); } diff --git a/ui/home/LatestTxsItem.tsx b/ui/home/LatestTxsItem.tsx index d9f87739e2..0bc802332e 100644 --- a/ui/home/LatestTxsItem.tsx +++ b/ui/home/LatestTxsItem.tsx @@ -3,23 +3,18 @@ import { Flex, HStack, Text, - Grid, } from '@chakra-ui/react'; import React from 'react'; import type { Transaction } from 'types/api/transaction'; -import config from 'configs/app'; -import getValueWithUnit from 'lib/getValueWithUnit'; -import { currencyUnits } from 'lib/units'; -import { Skeleton } from 'toolkit/chakra/skeleton'; +import { SUPPORTED_INFERENCE_ADDRESSES } from 'lib/inferences/address'; +import { Badge } from 'toolkit/chakra/badge'; import AddressFromTo from 'ui/shared/address/AddressFromTo'; import TxEntity from 'ui/shared/entities/tx/TxEntity'; import TxStatus from 'ui/shared/statusTag/TxStatus'; import TimeAgoWithTooltip from 'ui/shared/TimeAgoWithTooltip'; -import TxFee from 'ui/shared/tx/TxFee'; import TxWatchListTags from 'ui/shared/tx/TxWatchListTags'; -import TxAdditionalInfo from 'ui/txs/TxAdditionalInfo'; import TxType from 'ui/txs/TxType'; type Props = { @@ -29,73 +24,64 @@ type Props = { const LatestTxsItem = ({ tx, isLoading }: Props) => { const dataTo = tx.to ? tx.to : tx.created_contract; - const columnNum = config.UI.views.tx.hiddenFields?.value && config.UI.views.tx.hiddenFields?.tx_fee ? 2 : 3; + const hasInference = tx.to?.hash === SUPPORTED_INFERENCE_ADDRESSES.InferenceHub; return ( - - - - - - - - - - - - - + + + + + Txn + + + + + + + { hasInference && ( + + Inference + + ) } + + + + + + - - - { !config.UI.views.tx.hiddenFields?.value && ( - - Value - { getValueWithUnit(tx.value).dp(5).toFormat() } { currencyUnits.ether } - - ) } - { !config.UI.views.tx.hiddenFields?.tx_fee && ( - - Fee - - - ) } - - + ); }; diff --git a/ui/home/LatestTxsItemMobile.tsx b/ui/home/LatestTxsItemMobile.tsx index 593d26a6a1..dcf2b7fd6a 100644 --- a/ui/home/LatestTxsItemMobile.tsx +++ b/ui/home/LatestTxsItemMobile.tsx @@ -8,17 +8,13 @@ import React from 'react'; import type { Transaction } from 'types/api/transaction'; -import config from 'configs/app'; -import getValueWithUnit from 'lib/getValueWithUnit'; -import { currencyUnits } from 'lib/units'; -import { Skeleton } from 'toolkit/chakra/skeleton'; +import { SUPPORTED_INFERENCE_ADDRESSES } from 'lib/inferences/address'; +import { Badge } from 'toolkit/chakra/badge'; import AddressFromTo from 'ui/shared/address/AddressFromTo'; import TxEntity from 'ui/shared/entities/tx/TxEntity'; import TxStatus from 'ui/shared/statusTag/TxStatus'; import TimeAgoWithTooltip from 'ui/shared/TimeAgoWithTooltip'; -import TxFee from 'ui/shared/tx/TxFee'; import TxWatchListTags from 'ui/shared/tx/TxWatchListTags'; -import TxAdditionalInfo from 'ui/txs/TxAdditionalInfo'; import TxType from 'ui/txs/TxType'; type Props = { @@ -28,66 +24,65 @@ type Props = { const LatestTxsItem = ({ tx, isLoading }: Props) => { const dataTo = tx.to ? tx.to : tx.created_contract; + const hasInference = tx.to?.hash === SUPPORTED_INFERENCE_ADDRESSES.InferenceHub; return ( - - - - - - - - - + + Txn + + - - { !config.UI.views.tx.hiddenFields?.value && ( - - Value - { getValueWithUnit(tx.value).dp(5).toFormat() } { currencyUnits.ether } - - ) } - { !config.UI.views.tx.hiddenFields?.tx_fee && ( - - Fee - - - ) } + + + + { hasInference && ( + + Inference + + ) } + + + + + ); }; diff --git a/ui/home/Transactions.tsx b/ui/home/Transactions.tsx index c5ee6f1ec2..e74543ba1c 100644 --- a/ui/home/Transactions.tsx +++ b/ui/home/Transactions.tsx @@ -1,3 +1,4 @@ +import { Box } from '@chakra-ui/react'; import React from 'react'; import config from 'configs/app'; @@ -25,15 +26,36 @@ const TransactionsHome = () => { ].filter(Boolean); return ( <> - Transactions - + + + Transactions + + + + + ); } return ( <> - Latest transactions + + + Latest transactions + + ); diff --git a/ui/home/indicators/ChainIndicatorItem.tsx b/ui/home/indicators/ChainIndicatorItem.tsx index 184841f001..71a5e03d96 100644 --- a/ui/home/indicators/ChainIndicatorItem.tsx +++ b/ui/home/indicators/ChainIndicatorItem.tsx @@ -57,7 +57,7 @@ const ChainIndicatorItem = ({ id, title, value, valueDiff, icon, isSelected, onC px={{ base: '6px', lg: 2 }} py="6px" as="li" - borderRadius="base" + borderRadius="none" cursor="pointer" color={ isSelected ? { _light: 'gray.500', _dark: 'gray.400' } : 'link' } bgColor={ isSelected ? { _light: 'white', _dark: 'black' } : undefined } diff --git a/ui/home/indicators/ChainIndicators.tsx b/ui/home/indicators/ChainIndicators.tsx index 84949333d7..7c6a5a647d 100644 --- a/ui/home/indicators/ChainIndicators.tsx +++ b/ui/home/indicators/ChainIndicators.tsx @@ -117,7 +117,9 @@ const ChainIndicators = () => { { flexShrink={ 0 } flexDir="column" as="ul" - borderRadius="lg" + borderRadius="none" rowGap="6px" m={{ base: 'auto 0', lg: 0 }} > diff --git a/ui/home/indicators/utils/indicators.tsx b/ui/home/indicators/utils/indicators.tsx index 08b91111cd..493ce18355 100644 --- a/ui/home/indicators/utils/indicators.tsx +++ b/ui/home/indicators/utils/indicators.tsx @@ -17,7 +17,7 @@ const INDICATORS: Array = [ valueMicroservice: (stats) => stats.yesterday_transactions?.value === null ? 'N/A' : Number(stats.yesterday_transactions?.value).toLocaleString(undefined, { maximumFractionDigits: 2, notation: 'compact' }), - icon: , + icon: , hint: `Number of transactions yesterday (0:00 - 23:59 UTC). The chart displays daily transactions for the past 30 days.`, hintMicroservice: (stats) => stats.daily_new_transactions?.info?.description, }, @@ -29,7 +29,7 @@ const INDICATORS: Array = [ valueMicroservice: (stats) => stats.yesterday_operational_transactions?.value === null ? 'N/A' : Number(stats.yesterday_operational_transactions?.value).toLocaleString(undefined, { maximumFractionDigits: 2, notation: 'compact' }), - icon: , + icon: , hint: `Number of operational transactions yesterday (0:00 - 23:59 UTC). The chart displays daily operational transactions for the past 30 days.`, hintMicroservice: (stats) => stats.daily_new_operational_transactions?.info?.description, }, @@ -59,7 +59,7 @@ const INDICATORS: Array = [ value: (stats) => stats.market_cap === null ? '$N/A' : '$' + Number(stats.market_cap).toLocaleString(undefined, { maximumFractionDigits: 2, notation: 'compact' }), - icon: , + icon: , // eslint-disable-next-line max-len hint: 'The total market value of a cryptocurrency\'s circulating supply. It is analogous to the free-float capitalization in the stock market. Market Cap = Current Price x Circulating Supply.', }, @@ -69,7 +69,7 @@ const INDICATORS: Array = [ value: (stats) => stats.tvl === null ? '$N/A' : '$' + Number(stats.tvl).toLocaleString(undefined, { maximumFractionDigits: 2, notation: 'compact' }), - icon: , + icon: , hint: 'Total value of digital assets locked or staked in a chain', }, ]; diff --git a/ui/home/latestBatches/LatestBatchItem.tsx b/ui/home/latestBatches/LatestBatchItem.tsx index baea846c8e..f9eedcb535 100644 --- a/ui/home/latestBatches/LatestBatchItem.tsx +++ b/ui/home/latestBatches/LatestBatchItem.tsx @@ -21,7 +21,7 @@ const LatestBatchItem = ({ number, timestamp, txCount, status, isLoading, animat return ( { })(); return ( - + - - - - - - - { leftWidget } - - + + + + + + + + + + + + + + - + + + + + { leftWidget } + + + + + + + + + ); }; diff --git a/ui/shared/SocketNewItemsNotice.tsx b/ui/shared/SocketNewItemsNotice.tsx index 1beec5aa66..5154a899d6 100644 --- a/ui/shared/SocketNewItemsNotice.tsx +++ b/ui/shared/SocketNewItemsNotice.tsx @@ -44,7 +44,7 @@ const SocketNewItemsNotice = chakra(({ children, className, url, num, alert, typ } if (!num) { - return `scanning new ${ name }s...`; + return `🔍 Monitoring new ${ name }s...`; } return ( @@ -58,10 +58,13 @@ const SocketNewItemsNotice = chakra(({ children, className, url, num, alert, typ const content = !isLoading ? ( { alertContent } diff --git a/ui/shared/address/AddressFromTo.tsx b/ui/shared/address/AddressFromTo.tsx index 7d33b6bdf8..e2033206ae 100644 --- a/ui/shared/address/AddressFromTo.tsx +++ b/ui/shared/address/AddressFromTo.tsx @@ -1,5 +1,5 @@ import type { ConditionalValue } from '@chakra-ui/react'; -import { Flex, Grid, chakra, useBreakpointValue } from '@chakra-ui/react'; +import { Flex, Text, chakra, useBreakpointValue } from '@chakra-ui/react'; import React from 'react'; import type { AddressParam } from 'types/api/addressParams'; @@ -8,9 +8,6 @@ import type { EntityProps } from 'ui/shared/entities/address/AddressEntity'; import AddressEntity from 'ui/shared/entities/address/AddressEntity'; import AddressEntityWithTokenFilter from 'ui/shared/entities/address/AddressEntityWithTokenFilter'; -import AddressFromToIcon from './AddressFromToIcon'; -import { getTxCourseType } from './utils'; - type Mode = 'compact' | 'long'; interface Props { @@ -23,9 +20,10 @@ interface Props { tokenHash?: string; truncation?: EntityProps['truncation']; noIcon?: boolean; + noCopy?: boolean; } -const AddressFromTo = ({ from, to, current, mode: modeProp, className, isLoading, tokenHash = '', noIcon }: Props) => { +const AddressFromTo = ({ from, to, current, mode: modeProp, className, isLoading, tokenHash = '', noIcon, noCopy }: Props) => { const mode = useBreakpointValue( { base: (typeof modeProp === 'object' && 'base' in modeProp ? modeProp.base : modeProp), @@ -38,75 +36,72 @@ const AddressFromTo = ({ from, to, current, mode: modeProp, className, isLoading if (mode === 'compact') { return ( - + - + From { to && ( - + + To + + ) } ); } const isOutgoing = current === from.hash; - const iconSize = 20; return ( - - - - { to && ( + + + From + + { to && ( + + To + + ) } - + ); }; diff --git a/ui/shared/layout/LayoutHome.tsx b/ui/shared/layout/LayoutHome.tsx index ef2c6c4d07..3d549551ba 100644 --- a/ui/shared/layout/LayoutHome.tsx +++ b/ui/shared/layout/LayoutHome.tsx @@ -11,7 +11,6 @@ import * as Layout from './components'; const LayoutHome = ({ children }: Props) => { return ( - diff --git a/ui/shared/stats/StatsWidget.tsx b/ui/shared/stats/StatsWidget.tsx index 9194329f0e..ee326b5e70 100644 --- a/ui/shared/stats/StatsWidget.tsx +++ b/ui/shared/stats/StatsWidget.tsx @@ -58,23 +58,38 @@ const StatsWidget = ({ { icon && ( - + alignItems="center" + justifyContent="center" + > + + ) } { typeof hint === 'string' ? ( - + ) : hint } diff --git a/ui/shared/statusTag/StatusTag.tsx b/ui/shared/statusTag/StatusTag.tsx index eca9b45c8e..8b8a1932a5 100644 --- a/ui/shared/statusTag/StatusTag.tsx +++ b/ui/shared/statusTag/StatusTag.tsx @@ -5,7 +5,6 @@ import capitalizeFirstLetter from 'lib/capitalizeFirstLetter'; import type { BadgeProps } from 'toolkit/chakra/badge'; import { Badge } from 'toolkit/chakra/badge'; import { Tooltip } from 'toolkit/chakra/tooltip'; -import type { IconName } from 'ui/shared/IconSvg'; export type StatusTagType = 'ok' | 'error' | 'pending'; @@ -18,29 +17,33 @@ export interface Props { } const StatusTag = ({ type, text, errorText, isLoading, className }: Props) => { - let icon: IconName; let colorPalette: BadgeProps['colorPalette']; const capitalizedText = capitalizeFirstLetter(text); switch (type) { case 'ok': - icon = 'status/success'; colorPalette = 'green'; break; case 'error': - icon = 'status/error'; colorPalette = 'red'; break; case 'pending': - icon = 'status/pending'; colorPalette = 'gray'; break; } return ( - + { capitalizedText } diff --git a/ui/snippets/navigation/NavLinkIcon.tsx b/ui/snippets/navigation/NavLinkIcon.tsx index 21ba3c7c50..3381d2813e 100644 --- a/ui/snippets/navigation/NavLinkIcon.tsx +++ b/ui/snippets/navigation/NavLinkIcon.tsx @@ -12,11 +12,11 @@ interface Props { const NavLinkIcon = ({ item, className }: Props) => { if ('icon' in item && item.icon) { - return ; + return ; } if ('iconComponent' in item && item.iconComponent) { const IconComponent = item.iconComponent; - return ; + return ; } return null; diff --git a/ui/snippets/navigation/useNavLinkStyleProps.tsx b/ui/snippets/navigation/useNavLinkStyleProps.tsx index 755d625fff..11a612d475 100644 --- a/ui/snippets/navigation/useNavLinkStyleProps.tsx +++ b/ui/snippets/navigation/useNavLinkStyleProps.tsx @@ -4,26 +4,25 @@ type Props = { isActive?: boolean; }; -export default function useNavLinkStyleProps({ isExpanded, isCollapsed, isActive }: Props) { +export default function useNavLinkStyleProps({ isActive }: Props) { return { itemProps: { variant: 'navigation' as const, - py: '9px', + py: 2.5, + px: 3, display: 'flex', ...(isActive ? { 'data-selected': true } : {}), - borderRadius: 'base', - transitionProperty: 'width, padding', - transitionDuration: 'normal', - transitionTimingFunction: 'ease', + borderRadius: 'none', + transitionProperty: 'background-color, color', + transitionDuration: '150ms', + transitionTimingFunction: 'ease-out', }, textProps: { variant: 'inherit', fontSize: 'sm', + fontWeight: isActive ? 500 : 400, lineHeight: '20px', - opacity: { base: '1', lg: isExpanded ? '1' : '0', xl: isCollapsed ? '0' : '1' }, - transitionProperty: 'opacity', - transitionDuration: 'normal', - transitionTimingFunction: 'ease', + opacity: 1, }, }; } diff --git a/ui/snippets/navigation/vertical/NavLink.tsx b/ui/snippets/navigation/vertical/NavLink.tsx index bdca3f0670..3c22343dc0 100644 --- a/ui/snippets/navigation/vertical/NavLink.tsx +++ b/ui/snippets/navigation/vertical/NavLink.tsx @@ -1,14 +1,12 @@ -import { HStack, Box, useBreakpointValue, chakra } from '@chakra-ui/react'; +import { HStack, Box, chakra } from '@chakra-ui/react'; import React from 'react'; import type { NavItem } from 'types/client/navigation'; import { route } from 'nextjs-routes'; -import useIsMobile from 'lib/hooks/useIsMobile'; import { isInternalItem } from 'lib/hooks/useNavItems'; import { Link } from 'toolkit/chakra/link'; -import { Tooltip } from 'toolkit/chakra/tooltip'; import LightningLabel, { LIGHTNING_LABEL_CLASS_NAME } from '../LightningLabel'; import NavLinkIcon from '../NavLinkIcon'; @@ -22,65 +20,65 @@ type Props = { isDisabled?: boolean; }; -const NavLink = ({ item, onClick, isCollapsed, isDisabled }: Props) => { - const isMobile = useIsMobile(); - +const NavLink = ({ item, onClick, isDisabled }: Props) => { const isInternalLink = isInternalItem(item); - const isExpanded = isCollapsed === false; - - const styleProps = useNavLinkStyleProps({ isCollapsed, isExpanded, isActive: isInternalLink && item.isActive }); - const isXLScreen = useBreakpointValue({ base: false, xl: true }); + const styleProps = useNavLinkStyleProps({ isExpanded: true, isCollapsed: false, isActive: isInternalLink && item.isActive }); const isHighlighted = checkRouteHighlight(item); + let hoverColor: string | { _light: string; _dark: string }; + if (isDisabled) { + hoverColor = 'inherit'; + } else if (isInternalLink && item.isActive) { + hoverColor = { _light: 'gray.900', _dark: 'white' }; + } else { + hoverColor = { _light: 'gray.900', _dark: 'gray.100' }; + } + return ( - - - - - { item.text } - - { isHighlighted && ( - - ) } - - + + + + { item.text } + + { isHighlighted && ( + + ) } + ); diff --git a/ui/snippets/navigation/vertical/NavLinkGroup.tsx b/ui/snippets/navigation/vertical/NavLinkGroup.tsx index c168374eb7..786efc96ce 100644 --- a/ui/snippets/navigation/vertical/NavLinkGroup.tsx +++ b/ui/snippets/navigation/vertical/NavLinkGroup.tsx @@ -17,29 +17,31 @@ type Props = { isCollapsed?: boolean; }; -const NavLinkGroup = ({ item, isCollapsed }: Props) => { - const isExpanded = isCollapsed === false; - - const styleProps = useNavLinkStyleProps({ isCollapsed, isExpanded, isActive: item.isActive }); +const NavLinkGroup = ({ item }: Props) => { + const styleProps = useNavLinkStyleProps({ isActive: item.isActive }); const isHighlighted = checkRouteHighlight(item.subItems); const content = ( - - - { item.text } - - + + { item.subItems.map((subItem, index) => Array.isArray(subItem) ? ( { subItem.map(subSubItem => ) } @@ -55,23 +57,43 @@ const NavLinkGroup = ({ item, isCollapsed }: Props) => { - + { { isHighlighted && ( ) } diff --git a/ui/snippets/navigation/vertical/NavigationDesktop.tsx b/ui/snippets/navigation/vertical/NavigationDesktop.tsx index 335f4f3120..03cc4b5f54 100644 --- a/ui/snippets/navigation/vertical/NavigationDesktop.tsx +++ b/ui/snippets/navigation/vertical/NavigationDesktop.tsx @@ -2,10 +2,7 @@ import { Flex, Box, VStack } from '@chakra-ui/react'; import React from 'react'; import config from 'configs/app'; -import { useAppContext } from 'lib/contexts/app'; -import * as cookies from 'lib/cookies'; import useNavItems, { isGroupItem } from 'lib/hooks/useNavItems'; -import IconSvg from 'ui/shared/IconSvg'; import useIsAuth from 'ui/snippets/auth/useIsAuth'; import NetworkLogo from 'ui/snippets/networkMenu/NetworkLogo'; import NetworkMenu from 'ui/snippets/networkMenu/NetworkMenu'; @@ -16,55 +13,23 @@ import NavLinkGroup from './NavLinkGroup'; import NavLinkRewards from './NavLinkRewards'; const NavigationDesktop = () => { - const appProps = useAppContext(); - const cookiesString = appProps.cookies; - - const isNavBarCollapsedCookie = cookies.get(cookies.NAMES.NAV_BAR_COLLAPSED, cookiesString); - let isNavBarCollapsed; - if (isNavBarCollapsedCookie === 'true') { - isNavBarCollapsed = true; - } - if (isNavBarCollapsedCookie === 'false') { - isNavBarCollapsed = false; - } - const { mainNavItems, accountNavItems } = useNavItems(); - const isAuth = useIsAuth(); - const [ isCollapsed, setCollapsedState ] = React.useState(isNavBarCollapsed); - - const handleTogglerClick = React.useCallback(() => { - setCollapsedState((flag) => !flag); - cookies.set(cookies.NAMES.NAV_BAR_COLLAPSED, isCollapsed ? 'false' : 'true'); - }, [ isCollapsed ]); - - const handleContainerClick = React.useCallback((event: React.MouseEvent) => { - if (event.target === event.currentTarget) { - handleTogglerClick(); - } - }, [ handleTogglerClick ]); - - const isExpanded = isCollapsed === false; - return ( - { alignItems="center" flexDirection="row" w="100%" - pl={{ lg: isExpanded ? 3 : '15px', xl: isCollapsed ? '15px' : 3 }} - pr={{ lg: isExpanded ? 0 : '15px', xl: isCollapsed ? '15px' : 0 }} - h={ 10 } - transitionProperty="padding" - transitionDuration="normal" - transitionTimingFunction="ease" + mb={ 8 } + pb={ 6 } + borderBottom="1px solid" + borderColor={{ _light: 'gray.200', _dark: 'whiteAlpha.200' }} > - - { Boolean(config.UI.navigation.featuredNetworks) && } + + { Boolean(config.UI.navigation.featuredNetworks) && } + - - + + { mainNavItems.map((item) => { if (isGroupItem(item)) { - return ; + return ; } else { - return ; + return ; } }) } { isAuth && ( - - - - { accountNavItems.map((item) => ) } + + + + { accountNavItems.map((item) => ) } ) } - ); }; diff --git a/ui/snippets/searchBar/SearchBar.tsx b/ui/snippets/searchBar/SearchBar.tsx index 4e39a420cf..5859a18bba 100644 --- a/ui/snippets/searchBar/SearchBar.tsx +++ b/ui/snippets/searchBar/SearchBar.tsx @@ -197,7 +197,7 @@ const SearchBar = ({ isHomepage }: Props) => { ) } - + { !isHomepage && } ); }; diff --git a/ui/snippets/searchBar/SearchBarInput.tsx b/ui/snippets/searchBar/SearchBarInput.tsx index 9dfc26e20a..02581498a0 100644 --- a/ui/snippets/searchBar/SearchBarInput.tsx +++ b/ui/snippets/searchBar/SearchBarInput.tsx @@ -116,7 +116,6 @@ const SearchBarInput = (
diff --git a/ui/tx/details/TxInfo.tsx b/ui/tx/details/TxInfo.tsx index ec30d2c4a6..78731899fe 100644 --- a/ui/tx/details/TxInfo.tsx +++ b/ui/tx/details/TxInfo.tsx @@ -161,9 +161,8 @@ const TxInfo = ({ data, isLoading, socketStatus }: Props) => { { data.status === null && } - + { data.hash.slice(0, 6) }...{ data.hash.slice(-6) } - { config.features.metasuites.isEnabled && ( <> @@ -432,10 +431,13 @@ const TxInfo = ({ data, isLoading, socketStatus }: Props) => { From - + + + { data.from.name && { data.from.name } } { addressFromTags.length > 0 && ( @@ -458,21 +460,27 @@ const TxInfo = ({ data, isLoading, socketStatus }: Props) => { <> { data.to && data.to.hash ? ( - + + + { executionSuccessBadge } { executionFailedBadge } ) : ( [Contract - + + + created] { executionSuccessBadge } { executionFailedBadge } @@ -820,7 +828,7 @@ const TxInfo = ({ data, isLoading, socketStatus }: Props) => { { data.l1_fee && ( <> diff --git a/ui/txs/TxType.tsx b/ui/txs/TxType.tsx index 670c673c94..60ec42aecf 100644 --- a/ui/txs/TxType.tsx +++ b/ui/txs/TxType.tsx @@ -29,27 +29,27 @@ const TxType = ({ types, isLoading }: Props) => { switch (typeToShow) { case 'contract_call': - label = 'Contract call'; + label = 'Call'; colorPalette = 'blue'; break; case 'blob_transaction': - label = 'Blob txn'; + label = 'Blob'; colorPalette = 'yellow'; break; case 'contract_creation': - label = 'Contract creation'; + label = 'Create'; colorPalette = 'blue'; break; case 'token_transfer': - label = 'Token transfer'; + label = 'Transfer'; colorPalette = 'orange'; break; case 'token_creation': - label = 'Token creation'; + label = 'Token'; colorPalette = 'orange'; break; case 'coin_transfer': - label = 'Coin transfer'; + label = 'Transfer'; colorPalette = 'orange'; break; case 'rootstock_remasc': @@ -61,13 +61,20 @@ const TxType = ({ types, isLoading }: Props) => { colorPalette = 'blue'; break; default: - label = 'Transaction'; + label = 'Txn'; colorPalette = 'purple'; } return ( - + { label } );