From c7da204a27d9ce5cfd5b1553e8e4deb43cbdc6fe Mon Sep 17 00:00:00 2001 From: "balogh.adam@icloud.com" Date: Thu, 20 Nov 2025 16:12:44 -0500 Subject: [PATCH 1/9] design --- ui/home/HeroBanner.tsx | 85 ++++++++++++++++++++------ ui/home/LatestBlocks.tsx | 34 ++++++++--- ui/home/LatestBlocksItem.tsx | 13 +++- ui/home/Transactions.tsx | 55 ++++++++++++++--- ui/home/indicators/ChainIndicators.tsx | 30 ++++++--- ui/pages/Home.tsx | 20 ++++-- ui/shared/stats/StatsWidget.tsx | 64 ++++++++++++++----- 7 files changed, 234 insertions(+), 67 deletions(-) diff --git a/ui/home/HeroBanner.tsx b/ui/home/HeroBanner.tsx index 200255e373..97e8247dd3 100644 --- a/ui/home/HeroBanner.tsx +++ b/ui/home/HeroBanner.tsx @@ -1,6 +1,6 @@ // we use custom heading size for hero banner // eslint-disable-next-line no-restricted-imports -import { Box, Flex, Heading } from '@chakra-ui/react'; +import { Box, Flex, Heading, Text } from '@chakra-ui/react'; import React from 'react'; import config from 'configs/app'; @@ -11,7 +11,7 @@ import UserProfileDesktop from 'ui/snippets/user/profile/UserProfileDesktop'; import UserWalletDesktop from 'ui/snippets/user/wallet/UserWalletDesktop'; export const BACKGROUND_DEFAULT = - 'radial-gradient(103.03% 103.03% at 0% 0%, rgba(183, 148, 244, 0.8) 0%, rgba(0, 163, 196, 0.8) 100%), var(--chakra-colors-blue-400)'; + 'linear-gradient(135deg, rgba(99, 102, 241, 0.95) 0%, rgba(139, 92, 246, 0.95) 25%, rgba(59, 130, 246, 0.95) 50%, rgba(16, 185, 129, 0.95) 75%, rgba(99, 102, 241, 0.95) 100%), radial-gradient(circle at 20% 50%, rgba(139, 92, 246, 0.3) 0%, transparent 50%), radial-gradient(circle at 80% 80%, rgba(59, 130, 246, 0.3) 0%, transparent 50%)'; const TEXT_COLOR_DEFAULT = 'white'; const BORDER_DEFAULT = 'none'; @@ -54,26 +54,63 @@ const HeroBanner = () => { w="100%" background={ background } border={ border } - borderRadius="md" - p={{ base: 4, lg: 8 }} + borderRadius="xl" + p={{ base: 6, lg: 10 }} columnGap={ 8 } alignItems="center" + position="relative" + overflow="hidden" + boxShadow="0 20px 60px -15px rgba(0, 0, 0, 0.3), 0 0 0 1px rgba(255, 255, 255, 0.1)" + _before={{ + content: '""', + position: 'absolute', + top: 0, + left: 0, + right: 0, + bottom: 0, + background: 'linear-gradient(135deg, rgba(255, 255, 255, 0.1) 0%, transparent 50%)', + pointerEvents: 'none', + }} + _after={{ + content: '""', + position: 'absolute', + top: '-50%', + right: '-20%', + width: '600px', + height: '600px', + background: 'radial-gradient(circle, rgba(255, 255, 255, 0.15) 0%, transparent 70%)', + borderRadius: '50%', + pointerEvents: 'none', + opacity: 0.6, + }} > - - - - { - config.meta.seo.enhancedDataEnabled ? - `${ config.chain.name } Testnet Explorer` : - `${ config.chain.name } Testnet Explorer` - } - + + + + + { + config.meta.seo.enhancedDataEnabled ? + `${ config.chain.name } Explorer` : + `${ config.chain.name } Explorer` + } + + + Advanced blockchain explorer powered by AI + + { config.UI.navigation.layout === 'vertical' && ( { config.features.rewards.isEnabled && } @@ -84,7 +121,15 @@ const HeroBanner = () => { ) } - + + + diff --git a/ui/home/LatestBlocks.tsx b/ui/home/LatestBlocks.tsx index 4991555835..bf955bef86 100644 --- a/ui/home/LatestBlocks.tsx +++ b/ui/home/LatestBlocks.tsx @@ -102,25 +102,45 @@ const LatestBlocks = () => { } return ( - - Latest blocks + + 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 } ) } - + { content } diff --git a/ui/home/LatestBlocksItem.tsx b/ui/home/LatestBlocksItem.tsx index 3199bf755c..274aca4ecd 100644 --- a/ui/home/LatestBlocksItem.tsx +++ b/ui/home/LatestBlocksItem.tsx @@ -24,10 +24,17 @@ const LatestBlocksItem = ({ block, isLoading, animation }: Props) => { return ( { { id: 'deposits', title: 'Deposits (L1→L2 txn)', component: }, isAuth && { id: 'watchlist', title: 'Watch list', component: }, ].filter(Boolean); - return ( - <> - Transactions - - - ); + return ( + + Transactions + + + ); } return ( - <> - Latest transactions + + Latest transactions - + ); }; diff --git a/ui/home/indicators/ChainIndicators.tsx b/ui/home/indicators/ChainIndicators.tsx index 84949333d7..b9df22d044 100644 --- a/ui/home/indicators/ChainIndicators.tsx +++ b/ui/home/indicators/ChainIndicators.tsx @@ -92,7 +92,7 @@ const ChainIndicators = () => { } return ( - + { indicatorValue } ); @@ -115,22 +115,36 @@ const ChainIndicators = () => { return ( - - { title } + + { title } { hint && } - + { valueTitle } { valueDiff } diff --git a/ui/pages/Home.tsx b/ui/pages/Home.tsx index 36af7cb459..c08554d332 100644 --- a/ui/pages/Home.tsx +++ b/ui/pages/Home.tsx @@ -31,14 +31,26 @@ const Home = () => { return ( - + - - + + { leftWidget } - + diff --git a/ui/shared/stats/StatsWidget.tsx b/ui/shared/stats/StatsWidget.tsx index 9194329f0e..97ab7048cd 100644 --- a/ui/shared/stats/StatsWidget.tsx +++ b/ui/shared/stats/StatsWidget.tsx @@ -58,39 +58,71 @@ const StatsWidget = ({ { icon && ( - + alignItems="center" + justifyContent="center" + > + + ) } - + -

{ label }

+ { label }
{ valuePrefix && { valuePrefix } } { typeof value === 'string' ? ( @@ -101,7 +133,7 @@ const StatsWidget = ({ { valuePostfix && { valuePostfix } } { diff && Number(diff) > 0 && ( <> - + +{ diffFormatted || Number(diff).toLocaleString() } ({ diffPeriod }) From 5ac97332bbd196d69927a06471c14883277f5335 Mon Sep 17 00:00:00 2001 From: "balogh.adam@icloud.com" Date: Thu, 20 Nov 2025 16:19:17 -0500 Subject: [PATCH 2/9] Revert "design" This reverts commit c7da204a27d9ce5cfd5b1553e8e4deb43cbdc6fe. --- ui/home/HeroBanner.tsx | 85 ++++++-------------------- ui/home/LatestBlocks.tsx | 34 +++-------- ui/home/LatestBlocksItem.tsx | 13 +--- ui/home/Transactions.tsx | 55 +++-------------- ui/home/indicators/ChainIndicators.tsx | 30 +++------ ui/pages/Home.tsx | 20 ++---- ui/shared/stats/StatsWidget.tsx | 64 +++++-------------- 7 files changed, 67 insertions(+), 234 deletions(-) diff --git a/ui/home/HeroBanner.tsx b/ui/home/HeroBanner.tsx index 97e8247dd3..200255e373 100644 --- a/ui/home/HeroBanner.tsx +++ b/ui/home/HeroBanner.tsx @@ -1,6 +1,6 @@ // we use custom heading size for hero banner // eslint-disable-next-line no-restricted-imports -import { Box, Flex, Heading, Text } from '@chakra-ui/react'; +import { Box, Flex, Heading } from '@chakra-ui/react'; import React from 'react'; import config from 'configs/app'; @@ -11,7 +11,7 @@ import UserProfileDesktop from 'ui/snippets/user/profile/UserProfileDesktop'; import UserWalletDesktop from 'ui/snippets/user/wallet/UserWalletDesktop'; export const BACKGROUND_DEFAULT = - 'linear-gradient(135deg, rgba(99, 102, 241, 0.95) 0%, rgba(139, 92, 246, 0.95) 25%, rgba(59, 130, 246, 0.95) 50%, rgba(16, 185, 129, 0.95) 75%, rgba(99, 102, 241, 0.95) 100%), radial-gradient(circle at 20% 50%, rgba(139, 92, 246, 0.3) 0%, transparent 50%), radial-gradient(circle at 80% 80%, rgba(59, 130, 246, 0.3) 0%, transparent 50%)'; + 'radial-gradient(103.03% 103.03% at 0% 0%, rgba(183, 148, 244, 0.8) 0%, rgba(0, 163, 196, 0.8) 100%), var(--chakra-colors-blue-400)'; const TEXT_COLOR_DEFAULT = 'white'; const BORDER_DEFAULT = 'none'; @@ -54,63 +54,26 @@ const HeroBanner = () => { w="100%" background={ background } border={ border } - borderRadius="xl" - p={{ base: 6, lg: 10 }} + borderRadius="md" + p={{ base: 4, lg: 8 }} columnGap={ 8 } alignItems="center" - position="relative" - overflow="hidden" - boxShadow="0 20px 60px -15px rgba(0, 0, 0, 0.3), 0 0 0 1px rgba(255, 255, 255, 0.1)" - _before={{ - content: '""', - position: 'absolute', - top: 0, - left: 0, - right: 0, - bottom: 0, - background: 'linear-gradient(135deg, rgba(255, 255, 255, 0.1) 0%, transparent 50%)', - pointerEvents: 'none', - }} - _after={{ - content: '""', - position: 'absolute', - top: '-50%', - right: '-20%', - width: '600px', - height: '600px', - background: 'radial-gradient(circle, rgba(255, 255, 255, 0.15) 0%, transparent 70%)', - borderRadius: '50%', - pointerEvents: 'none', - opacity: 0.6, - }} > - - - - - { - config.meta.seo.enhancedDataEnabled ? - `${ config.chain.name } Explorer` : - `${ config.chain.name } Explorer` - } - - - Advanced blockchain explorer powered by AI - - + + + + { + config.meta.seo.enhancedDataEnabled ? + `${ config.chain.name } Testnet Explorer` : + `${ config.chain.name } Testnet Explorer` + } + { config.UI.navigation.layout === 'vertical' && ( { config.features.rewards.isEnabled && } @@ -121,15 +84,7 @@ const HeroBanner = () => { ) } - - - + diff --git a/ui/home/LatestBlocks.tsx b/ui/home/LatestBlocks.tsx index bf955bef86..4991555835 100644 --- a/ui/home/LatestBlocks.tsx +++ b/ui/home/LatestBlocks.tsx @@ -102,45 +102,25 @@ const LatestBlocks = () => { } return ( - - Latest blocks + + 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 } ) } - + { content } diff --git a/ui/home/LatestBlocksItem.tsx b/ui/home/LatestBlocksItem.tsx index 274aca4ecd..3199bf755c 100644 --- a/ui/home/LatestBlocksItem.tsx +++ b/ui/home/LatestBlocksItem.tsx @@ -24,17 +24,10 @@ const LatestBlocksItem = ({ block, isLoading, animation }: Props) => { return ( { { id: 'deposits', title: 'Deposits (L1→L2 txn)', component: }, isAuth && { id: 'watchlist', title: 'Watch list', component: }, ].filter(Boolean); - return ( - - Transactions - - - ); + return ( + <> + Transactions + + + ); } return ( - - Latest transactions + <> + Latest transactions - + ); }; diff --git a/ui/home/indicators/ChainIndicators.tsx b/ui/home/indicators/ChainIndicators.tsx index b9df22d044..84949333d7 100644 --- a/ui/home/indicators/ChainIndicators.tsx +++ b/ui/home/indicators/ChainIndicators.tsx @@ -92,7 +92,7 @@ const ChainIndicators = () => { } return ( - + { indicatorValue } ); @@ -115,36 +115,22 @@ const ChainIndicators = () => { return ( - - { title } + + { title } { hint && } - + { valueTitle } { valueDiff } diff --git a/ui/pages/Home.tsx b/ui/pages/Home.tsx index c08554d332..36af7cb459 100644 --- a/ui/pages/Home.tsx +++ b/ui/pages/Home.tsx @@ -31,26 +31,14 @@ const Home = () => { return ( - + - - + + { leftWidget } - + diff --git a/ui/shared/stats/StatsWidget.tsx b/ui/shared/stats/StatsWidget.tsx index 97ab7048cd..9194329f0e 100644 --- a/ui/shared/stats/StatsWidget.tsx +++ b/ui/shared/stats/StatsWidget.tsx @@ -58,71 +58,39 @@ const StatsWidget = ({ { icon && ( - - - + /> ) } - + - { label } +

{ label }

{ valuePrefix && { valuePrefix } } { typeof value === 'string' ? ( @@ -133,7 +101,7 @@ const StatsWidget = ({ { valuePostfix && { valuePostfix } } { diff && Number(diff) > 0 && ( <> - + +{ diffFormatted || Number(diff).toLocaleString() } ({ diffPeriod }) From a5bda8f42a21f8c25ab56d25b530790c41f41307 Mon Sep 17 00:00:00 2001 From: "balogh.adam@icloud.com" Date: Thu, 20 Nov 2025 16:28:13 -0500 Subject: [PATCH 3/9] design --- toolkit/chakra/skeleton.tsx | 2 +- ui/home/HeroBanner.tsx | 32 ++--- ui/home/LatestBlocksItem.tsx | 2 +- ui/home/indicators/ChainIndicatorItem.tsx | 2 +- ui/home/indicators/ChainIndicators.tsx | 6 +- ui/home/indicators/utils/indicators.tsx | 8 +- ui/home/latestBatches/LatestBatchItem.tsx | 2 +- ui/pages/Home.tsx | 6 +- ui/shared/stats/StatsWidget.tsx | 8 +- ui/snippets/navigation/NavLinkIcon.tsx | 4 +- .../navigation/useNavLinkStyleProps.tsx | 19 ++- ui/snippets/navigation/vertical/NavLink.tsx | 80 +++++++------ .../navigation/vertical/NavLinkGroup.tsx | 55 ++++++--- .../navigation/vertical/NavigationDesktop.tsx | 109 +++++------------- 14 files changed, 153 insertions(+), 182 deletions(-) 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 flat color + 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); + const backgroundValue = hasConfigBackground ? + { _light: configBackgroundLight, _dark: configBackgroundDark } : + { _light: BACKGROUND_DEFAULT._light, _dark: BACKGROUND_DEFAULT._dark }; const textColor = { _light: @@ -52,9 +50,11 @@ const HeroBanner = () => { return ( {
- +
); }; diff --git a/ui/home/LatestBlocksItem.tsx b/ui/home/LatestBlocksItem.tsx index 3199bf755c..f271c2e144 100644 --- a/ui/home/LatestBlocksItem.tsx +++ b/ui/home/LatestBlocksItem.tsx @@ -24,7 +24,7 @@ const LatestBlocksItem = ({ block, isLoading, animation }: Props) => { return ( { { 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 } diff --git a/ui/shared/stats/StatsWidget.tsx b/ui/shared/stats/StatsWidget.tsx index 9194329f0e..d18abb883d 100644 --- a/ui/shared/stats/StatsWidget.tsx +++ b/ui/shared/stats/StatsWidget.tsx @@ -60,7 +60,9 @@ const StatsWidget = ({ alignItems="center" bgColor={ isLoading ? { _light: 'blackAlpha.50', _dark: 'whiteAlpha.50' } : { _light: 'gray.50', _dark: 'whiteAlpha.100' } } p={ 3 } - borderRadius="base" + borderRadius="none" + border="1px solid" + borderColor={{ _light: 'gray.200', _dark: 'whiteAlpha.200' }} justifyContent="space-between" columnGap={ 2 } w="100%" @@ -71,7 +73,7 @@ const StatsWidget = ({ p={ 2 } boxSize="40px" isLoading={ isLoading } - borderRadius="base" + borderRadius="none" display={{ base: 'none', lg: 'block' }} flexShrink={ 0 } /> @@ -111,7 +113,7 @@ const StatsWidget = ({
{ typeof hint === 'string' ? ( - + ) : hint } 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..c129fd9ffd 100644 --- a/ui/snippets/navigation/vertical/NavLinkGroup.tsx +++ b/ui/snippets/navigation/vertical/NavLinkGroup.tsx @@ -25,11 +25,27 @@ const NavLinkGroup = ({ item, isCollapsed }: Props) => { const isHighlighted = checkRouteHighlight(item.subItems); const content = ( - - + + { item.text } - + { item.subItems.map((subItem, index) => Array.isArray(subItem) ? ( { > - + { { 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) => ) } ) } - ); }; From af9f06879931bdff8457d2ecab57e5174bcedc4e Mon Sep 17 00:00:00 2001 From: "balogh.adam@icloud.com" Date: Thu, 20 Nov 2025 16:33:20 -0500 Subject: [PATCH 4/9] menu --- lib/hooks/useNavItems.tsx | 31 -------------- .../navigation/vertical/NavLinkGroup.tsx | 40 +++++++++---------- 2 files changed, 18 insertions(+), 53 deletions(-) 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/ui/snippets/navigation/vertical/NavLinkGroup.tsx b/ui/snippets/navigation/vertical/NavLinkGroup.tsx index c129fd9ffd..786efc96ce 100644 --- a/ui/snippets/navigation/vertical/NavLinkGroup.tsx +++ b/ui/snippets/navigation/vertical/NavLinkGroup.tsx @@ -17,45 +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 => ) } @@ -71,17 +57,27 @@ const NavLinkGroup = ({ item, isCollapsed }: Props) => { Date: Thu, 20 Nov 2025 16:34:41 -0500 Subject: [PATCH 5/9] lfs --- .gitattributes | 1 - 1 file changed, 1 deletion(-) delete mode 100644 .gitattributes 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 From fc8038268ad58e9e52b2195143a7f3df6898a11b Mon Sep 17 00:00:00 2001 From: "balogh.adam@icloud.com" Date: Thu, 20 Nov 2025 16:36:14 -0500 Subject: [PATCH 6/9] hook --- .husky/pre-push | 3 --- 1 file changed, 3 deletions(-) delete mode 100755 .husky/pre-push 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 "$@" From 5362a84fd0fb280dd0a9b7ab97372a80217620cf Mon Sep 17 00:00:00 2001 From: "balogh.adam@icloud.com" Date: Thu, 20 Nov 2025 16:59:37 -0500 Subject: [PATCH 7/9] stylel --- eslint.config.mjs | 1 - ui/home/HeroBanner.tsx | 151 +++++++++++++++++------ ui/home/LatestBlocks.tsx | 58 +++++---- ui/home/LatestBlocksItem.tsx | 73 ++++++----- ui/home/LatestTxs.tsx | 14 ++- ui/home/LatestTxsItem.tsx | 111 +++++++---------- ui/home/LatestTxsItemMobile.tsx | 48 +++---- ui/home/Transactions.tsx | 28 ++++- ui/pages/Home.tsx | 144 +++++++++++++++++++-- ui/shared/layout/LayoutHome.tsx | 1 - ui/shared/stats/StatsWidget.tsx | 39 ++++-- ui/snippets/searchBar/SearchBarInput.tsx | 16 ++- 12 files changed, 445 insertions(+), 239 deletions(-) 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/ui/home/HeroBanner.tsx b/ui/home/HeroBanner.tsx index 479299b190..55c56376d3 100644 --- a/ui/home/HeroBanner.tsx +++ b/ui/home/HeroBanner.tsx @@ -1,6 +1,6 @@ // we use custom heading size for hero banner // eslint-disable-next-line no-restricted-imports -import { Box, Flex, Heading } from '@chakra-ui/react'; +import { Box, Flex, Heading, VStack } from '@chakra-ui/react'; import React from 'react'; import config from 'configs/app'; @@ -15,16 +15,21 @@ const TEXT_COLOR_DEFAULT = 'white'; const BORDER_DEFAULT = 'none'; const HeroBanner = () => { - // Use config background if provided (could be gradient string), otherwise use flat color + // 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); + + // Premium gradient backgrounds for web3/AI aesthetic + const premiumGradientLight = 'linear-gradient(135deg, #667eea 0%, #764ba2 25%, #f093fb 50%, #4facfe 75%, #00f2fe 100%)'; + const premiumGradientDark = 'linear-gradient(135deg, #0f0c29 0%, #302b63 25%, #24243e 50%, #1a1a2e 75%, #16213e 100%)'; + const backgroundValue = hasConfigBackground ? { _light: configBackgroundLight, _dark: configBackgroundDark } : - { _light: BACKGROUND_DEFAULT._light, _dark: BACKGROUND_DEFAULT._dark }; + { _light: premiumGradientLight, _dark: premiumGradientDark }; const textColor = { _light: @@ -48,46 +53,118 @@ 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..5a3aed6203 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, Flex, 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,7 +82,7 @@ const LatestBlocks = () => { content = ( <> - + { dataToShow.map(((block, index) => ( { animation={ initialList.getAnimationProp(block) } /> ))) } - +
- View all blocks + + View all blocks + ); @@ -103,24 +109,24 @@ const LatestBlocks = () => { 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 f271c2e144..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..1c3e95792a 100644 --- a/ui/home/LatestTxs.tsx +++ b/ui/home/LatestTxs.tsx @@ -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..e78ae15df4 100644 --- a/ui/home/LatestTxsItem.tsx +++ b/ui/home/LatestTxsItem.tsx @@ -2,24 +2,16 @@ import { Box, 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 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 +21,54 @@ 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; return ( - - - - - - - - - - - - - + + + + + + + + + + + + + + + + - - - { !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..e214e11128 100644 --- a/ui/home/LatestTxsItemMobile.tsx +++ b/ui/home/LatestTxsItemMobile.tsx @@ -2,23 +2,16 @@ import { Box, Flex, HStack, - Text, } 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 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 = { @@ -32,30 +25,33 @@ const LatestTxsItem = ({ tx, isLoading }: Props) => { return ( - - + + - { enableIncrement isLoading={ isLoading } color="text.secondary" - fontWeight="400" - fontSize="sm" - ml={ 3 } + textStyle="xs" + flexShrink={ 0 } /> - { !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/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/pages/Home.tsx b/ui/pages/Home.tsx index 3e7362c7d8..8fe228d658 100644 --- a/ui/pages/Home.tsx +++ b/ui/pages/Home.tsx @@ -1,4 +1,4 @@ -import { Box, Flex } from '@chakra-ui/react'; +import { Box, Flex, Container } from '@chakra-ui/react'; import React from 'react'; import config from 'configs/app'; @@ -29,19 +29,139 @@ const Home = () => { })(); return ( - + - - - - - - - { leftWidget } - - + + + + + + + + + + + + + + - + + + + + { leftWidget } + + + + + + + + + ); }; 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 d18abb883d..ee326b5e70 100644 --- a/ui/shared/stats/StatsWidget.tsx +++ b/ui/shared/stats/StatsWidget.tsx @@ -58,25 +58,38 @@ const StatsWidget = ({ { icon && ( - + alignItems="center" + justifyContent="center" + > + + ) } From 548989c02eeb36eb874ee6818448fe642774d8ab Mon Sep 17 00:00:00 2001 From: "balogh.adam@icloud.com" Date: Thu, 20 Nov 2025 17:18:57 -0500 Subject: [PATCH 8/9] style --- ui/home/LatestBlocks.tsx | 31 ++++++---- ui/home/LatestTxs.tsx | 18 ++++-- ui/home/LatestTxsItem.tsx | 27 ++++++--- ui/home/LatestTxsItemMobile.tsx | 57 +++++++++++------- ui/pages/Home.tsx | 15 ----- ui/shared/SocketNewItemsNotice.tsx | 7 ++- ui/shared/address/AddressFromTo.tsx | 89 ++++++++++++++--------------- ui/shared/statusTag/StatusTag.tsx | 15 +++-- ui/tx/details/TxInfo.tsx | 40 +++++++------ ui/txs/TxType.tsx | 23 +++++--- 10 files changed, 185 insertions(+), 137 deletions(-) diff --git a/ui/home/LatestBlocks.tsx b/ui/home/LatestBlocks.tsx index 5a3aed6203..c11cd41b61 100644 --- a/ui/home/LatestBlocks.tsx +++ b/ui/home/LatestBlocks.tsx @@ -1,4 +1,4 @@ -import { chakra, Box, Flex, Text } from '@chakra-ui/react'; +import { chakra, Box, Text } from '@chakra-ui/react'; import { useQueryClient } from '@tanstack/react-query'; import React from 'react'; @@ -84,25 +84,36 @@ const LatestBlocks = () => { <> { dataToShow.map(((block, index) => ( - + + + ))) } - + View all blocks - + ); } diff --git a/ui/home/LatestTxs.tsx b/ui/home/LatestTxs.tsx index 1c3e95792a..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'; @@ -54,17 +54,27 @@ const LatestTransactions = () => { ))) } - + View all transactions - +
); } diff --git a/ui/home/LatestTxsItem.tsx b/ui/home/LatestTxsItem.tsx index e78ae15df4..0bc802332e 100644 --- a/ui/home/LatestTxsItem.tsx +++ b/ui/home/LatestTxsItem.tsx @@ -2,11 +2,14 @@ import { Box, Flex, HStack, + Text, } from '@chakra-ui/react'; import React from 'react'; import type { Transaction } from 'types/api/transaction'; +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'; @@ -21,6 +24,7 @@ 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 { flexShrink={ 0 } /> + + + + { hasInference && ( + + Inference + + ) } + + - + diff --git a/ui/home/LatestTxsItemMobile.tsx b/ui/home/LatestTxsItemMobile.tsx index e214e11128..dcf2b7fd6a 100644 --- a/ui/home/LatestTxsItemMobile.tsx +++ b/ui/home/LatestTxsItemMobile.tsx @@ -2,11 +2,14 @@ import { Box, Flex, HStack, + Text, } from '@chakra-ui/react'; import React from 'react'; import type { Transaction } from 'types/api/transaction'; +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'; @@ -21,6 +24,7 @@ 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 ( { }} display={{ base: 'block', lg: 'none' }} > - - - - - - - - + + Txn + + { flexShrink={ 0 } /> - + + + + { hasInference && ( + + Inference + + ) } + + + + + ); }; diff --git a/ui/pages/Home.tsx b/ui/pages/Home.tsx index 8fe228d658..a4f98fe72c 100644 --- a/ui/pages/Home.tsx +++ b/ui/pages/Home.tsx @@ -111,21 +111,6 @@ const Home = () => { { 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/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/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 } ); From 8d8bb93ed6f64f88c96fe5e42cc9c02fb04437fc Mon Sep 17 00:00:00 2001 From: "balogh.adam@icloud.com" Date: Thu, 20 Nov 2025 17:31:04 -0500 Subject: [PATCH 9/9] sarch --- ui/home/HeroBanner.tsx | 44 ++++++----------------------- ui/snippets/searchBar/SearchBar.tsx | 2 +- 2 files changed, 9 insertions(+), 37 deletions(-) diff --git a/ui/home/HeroBanner.tsx b/ui/home/HeroBanner.tsx index 55c56376d3..47214a0a6c 100644 --- a/ui/home/HeroBanner.tsx +++ b/ui/home/HeroBanner.tsx @@ -23,9 +23,9 @@ const HeroBanner = () => { const hasConfigBackground = Boolean(configBackgroundLight); - // Premium gradient backgrounds for web3/AI aesthetic - const premiumGradientLight = 'linear-gradient(135deg, #667eea 0%, #764ba2 25%, #f093fb 50%, #4facfe 75%, #00f2fe 100%)'; - const premiumGradientDark = 'linear-gradient(135deg, #0f0c29 0%, #302b63 25%, #24243e 50%, #1a1a2e 75%, #16213e 100%)'; + // 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 } : @@ -70,10 +70,10 @@ const HeroBanner = () => { left: 0, right: 0, bottom: 0, - background: 'radial-gradient(circle at 20% 50%, rgba(120, 119, 198, 0.3) 0%, transparent 50%), radial-gradient(circle at 80% 80%, rgba(255, 119, 198, 0.3) 0%, transparent 50%)', + background: 'radial-gradient(circle at 20% 50%, rgba(0, 212, 255, 0.4) 0%, transparent 50%), radial-gradient(circle at 80% 80%, rgba(0, 102, 255, 0.4) 0%, transparent 50%)', pointerEvents: 'none', _dark: { - background: 'radial-gradient(circle at 20% 50%, rgba(66, 153, 225, 0.15) 0%, transparent 50%), radial-gradient(circle at 80% 80%, rgba(139, 92, 246, 0.15) 0%, transparent 50%)', + background: 'radial-gradient(circle at 20% 50%, rgba(0, 212, 255, 0.25) 0%, transparent 50%), radial-gradient(circle at 80% 80%, rgba(0, 102, 255, 0.25) 0%, transparent 50%)', }, }} > @@ -97,17 +97,11 @@ const HeroBanner = () => { { config.meta.seo.enhancedDataEnabled ? @@ -129,30 +123,8 @@ const HeroBanner = () => { - - - + 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 && } ); };