Patch over newest

This commit is contained in:
2025-02-02 13:02:47 -06:00
parent 6d34eded7c
commit dec00de7bd
28 changed files with 23229 additions and 3913 deletions
+7 -7
View File
@@ -1,27 +1,25 @@
<h1 align="center">Lux Explore</h1>
<h1 align="center">Blockscout frontend</h1>
<p align="center">
<span>Frontend application for </span>
<a href="https://github.com/luxfi/explore/blob/master/README.md">Lux Explorer</a>
<a href="https://github.com/blockscout/blockscout/blob/master/README.md">Blockscout</a>
<span> blockchain explorer</span>
</p>
## Running and configuring the app
App is distributed as a docker image. Here you can find information about the [package](https://github.com/luxfi/explore/pkgs/container/frontend) and its recent [releases](https://github.com/luxfi/explore/releases).
App is distributed as a docker image. Here you can find information about the [package](https://github.com/blockscout/frontend/pkgs/container/frontend) and its recent [releases](https://github.com/blockscout/frontend/releases).
You can configure your app by passing necessary environment variables when starting the container. See full list of ENVs and their description [here](./docs/ENVS.md).
```sh
docker run -p 3000:3000 --env-file <path-to-your-env-file> ghcr.io/luxfi/explore:latest
docker run -p 3000:3000 --env-file <path-to-your-env-file> ghcr.io/blockscout/frontend:latest
```
Alternatively, you can build your own docker image and run your app from that. Please follow this [guide](./docs/CUSTOM_BUILD.md).
<<<<<<< HEAD
=======
For more information on migrating from the previous frontend, please see the [frontend migration docs](https://docs.blockscout.com/for-developers/frontend-migration).
>>>>>>> c463e20f1 (Update luxfi links)
## Contributing
See our [Contribution guide](./docs/CONTRIBUTING.md) for pull request protocol. We expect contributors to follow our [code of conduct](./CODE_OF_CONDUCT.md) when submitting code or comments.
@@ -30,6 +28,8 @@ See our [Contribution guide](./docs/CONTRIBUTING.md) for pull request protocol.
- [App ENVs list](./docs/ENVS.md)
- [Contribution guide](./docs/CONTRIBUTING.md)
- [Making a custom build](./docs/CUSTOM_BUILD.md)
- [Frontend migration guide](https://docs.blockscout.com/for-developers/frontend-migration)
- [Manual deployment guide with backend and microservices](https://docs.blockscout.com/for-developers/deployment/manual-deployment-guide)
## License
+1 -1
View File
@@ -24,7 +24,7 @@ export default function useIssueUrl(backendVersion: string | undefined) {
'frontend-version': [ config.UI.footer.frontendVersion, config.UI.footer.frontendCommit ].filter(Boolean).join('+'),
'additional-information': `**User Agent:** ${ window.navigator.userAgent }`,
});
return `https://github.com/luxfi/explore/issues/new/?${ searchParams.toString() }`;
return `https://github.com/blockscout/blockscout/issues/new/?${ searchParams.toString() }`;
// we need to update link whenever page url changes
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [ backendVersion, isLoading, router.asPath ]);
+1 -1
View File
@@ -8,7 +8,7 @@ function generateCspPolicy() {
descriptors.cloudFlare(),
descriptors.gasHawk(),
descriptors.googleAnalytics(),
//descriptors.googleFonts(),
descriptors.googleFonts(),
descriptors.googleReCaptcha(),
descriptors.growthBook(),
descriptors.helia(),
+5 -35
View File
@@ -5,11 +5,6 @@
// prettier-ignore
declare module "nextjs-routes" {
import type {
GetServerSidePropsContext as NextGetServerSidePropsContext,
GetServerSidePropsResult as NextGetServerSidePropsResult
} from "nextjs";
export type Route =
| StaticRoute<"/404">
| StaticRoute<"/account/api-key">
@@ -105,33 +100,6 @@ declare module "nextjs-routes" {
* route({ pathname: "/foos/[foo]", query: { foo: "bar" }}) will produce "/foos/bar".
*/
export declare function route(r: Route): string;
/**
* Nearly identical to GetServerSidePropsContext from next, but further narrows
* types based on nextjs-route's route data.
*/
export type GetServerSidePropsContext<
Pathname extends Route["pathname"] = Route["pathname"],
Preview extends NextGetServerSidePropsContext["previewData"] = NextGetServerSidePropsContext["previewData"]
> = Omit<NextGetServerSidePropsContext, 'params' | 'query' | 'defaultLocale' | 'locale' | 'locales'> & {
params: Extract<Route, { pathname: Pathname }>["query"];
query: Query;
defaultLocale?: undefined;
locale?: Locale;
locales?: undefined;
};
/**
* Nearly identical to GetServerSideProps from next, but further narrows
* types based on nextjs-route's route data.
*/
export type GetServerSideProps<
Props extends { [key: string]: any } = { [key: string]: any },
Pathname extends Route["pathname"] = Route["pathname"],
Preview extends NextGetServerSideProps["previewData"] = NextGetServerSideProps["previewData"]
> = (
context: GetServerSidePropsContext<Pathname, Preview>
) => Promise<NextGetServerSidePropsResult<Props>>
}
// prettier-ignore
@@ -146,12 +114,13 @@ declare module "next/link" {
} from "react";
export * from "next/dist/client/link";
type Query = { query?: { [key: string]: string | string[] | undefined } };
type StaticRoute = Exclude<Route, { query: any }>["pathname"];
export interface LinkProps
extends Omit<NextLinkProps, "href" | "locale">,
AnchorHTMLAttributes<HTMLAnchorElement> {
href: Route | StaticRoute | Omit<Route, "pathname">
href: Route | StaticRoute | Query;
locale?: false;
}
@@ -179,6 +148,7 @@ declare module "next/router" {
type NextTransitionOptions = NonNullable<Parameters<Router["push"]>[2]>;
type StaticRoute = Exclude<Route, { query: any }>["pathname"];
type Query = { query?: { [key: string]: string | string[] | undefined } };
interface TransitionOptions extends Omit<NextTransitionOptions, "locale"> {
locale?: false;
@@ -200,12 +170,12 @@ declare module "next/router" {
locale?: Locale;
locales?: undefined;
push(
url: Route | StaticRoute | Omit<Route, "pathname">,
url: Route | StaticRoute | Query,
as?: string,
options?: TransitionOptions
): Promise<boolean>;
replace(
url: Route | StaticRoute | Omit<Route, "pathname">,
url: Route | StaticRoute | Query,
as?: string,
options?: TransitionOptions
): Promise<boolean>;
+1 -4
View File
@@ -2,7 +2,7 @@
"name": "@luxfi/explore",
"version": "1.0.0",
"private": false,
"homepage": "https://github.com/luxfi/explore#readme",
"homepage": "https://github.com/blockscout/frontend#readme",
"engines": {
"node": "22.11.0",
"npm": "10.9.0"
@@ -45,8 +45,6 @@
"@chakra-ui/anatomy": "^2.2.2",
"@chakra-ui/lazy-utils": "2.0.5",
"@chakra-ui/react": "2.7.1",
"@chakra-ui/styled-system": "^2.9.2",
"@chakra-ui/system": "^2.6.2",
"@chakra-ui/theme-tools": "^2.0.18",
"@cloudnouns/kit": "1.1.6",
"@emotion/react": "^11.10.4",
@@ -141,7 +139,6 @@
"@types/dom-to-image": "^2.6.4",
"@types/jest": "^29.2.0",
"@types/js-cookie": "^3.0.2",
"@types/lodash": "^4.17.7",
"@types/mixpanel-browser": "^2.38.1",
"@types/node": "20.16.7",
"@types/phoenix": "^1.5.4",
+2 -6
View File
@@ -10,9 +10,6 @@ import config from 'configs/app';
import theme from 'theme/theme';
import * as svgSprite from 'ui/shared/IconSvg';
import { inter, drukWide } from 'theme/foundations/typography';
class MyDocument extends Document {
static async getInitialProps(ctx: DocumentContext) {
const originalRenderPage = ctx.renderPage;
@@ -33,12 +30,11 @@ class MyDocument extends Document {
return initialProps;
}
// className={inter.className}
render() {
return (
<Html lang="en">
<Head>
{ /* FONTS */ }
<link
href={ config.UI.fonts.heading?.url ?? 'https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700&display=swap' }
rel="stylesheet"
@@ -60,7 +56,7 @@ class MyDocument extends Document {
<link rel="icon" type="image/png" sizes="192x192" href="/assets/favicon/android-chrome-192x192.png"/>
<link rel="preload" as="image" href={ svgSprite.href }/>
</Head>
<body className={`${inter.variable} ${drukWide.variable}`}>
<body>
<ColorModeScript initialColorMode={ theme.config.initialColorMode }/>
<Main/>
<NextScript/>
+5025 -3736
View File
File diff suppressed because it is too large Load Diff
+6
View File
@@ -0,0 +1,6 @@
# Icons
This directory contains SVG icons that are used by the app.
Everything in this directory is generated by running `icons build`.
View File
+2 -4
View File
@@ -5,8 +5,6 @@ import {
defineStyle,
} from '@chakra-ui/styled-system';
import luxColors from 'theme/foundations/lux-colors';
const { defineMultiStyleConfig, definePartsStyle } =
createMultiStyleConfigHelpers(parts.keys);
@@ -17,7 +15,7 @@ const baseStyleList = defineStyle({
[$bg.variable]: '#fff',
[$shadow.variable]: 'shadows.2xl',
_dark: {
[$bg.variable]: luxColors.colors.muted, //'colors.gray.900',
[$bg.variable]: 'colors.gray.900',
[$shadow.variable]: 'shadows.dark-lg',
},
borderWidth: '0',
@@ -38,7 +36,7 @@ const baseStyleItem = defineStyle({
[$bg.variable]: 'colors.whiteAlpha.100',
},
},
bg: luxColors.colors.level1,
bg: $bg.reference,
});
const baseStyle = definePartsStyle({
+9 -11
View File
@@ -1,25 +1,23 @@
import luxColors from './lux-colors';
const semanticTokens = {
colors: {
divider: {
'default': luxColors.colors.muted4,
_dark: luxColors.colors.muted4,
'default': 'blackAlpha.200',
_dark: 'whiteAlpha.200',
},
text: {
'default': luxColors.colors.foreground,
_dark: luxColors.colors.foreground,
'default': 'blackAlpha.800',
_dark: 'whiteAlpha.800',
},
text_secondary: {
'default': luxColors.colors.muted,
_dark: luxColors.colors.muted,
'default': 'gray.500',
_dark: 'gray.400',
},
link: {
'default': luxColors.colors.muted2,
_dark: luxColors.colors.muted2,
'default': 'blue.600',
_dark: 'blue.300',
},
link_hovered: {
'default': luxColors.colors.foreground, //'blue.400',
'default': 'blue.400',
},
icon_link_external: {
'default': 'gray.300',
+17 -23
View File
@@ -5,17 +5,23 @@ import config from 'configs/app';
export const BODY_TYPEFACE = config.UI.fonts.body?.name ?? 'Inter';
export const HEADING_TYPEFACE = config.UI.fonts.heading?.name ?? 'Poppins';
const drukWide = localFont({
src: [
{
path: './fonts/Druk-Wide-Bold.ttf',
weight: '700',
style: 'normal'
const typography = {
fonts: {
heading: `${ HEADING_TYPEFACE }, ${ theme.fonts.heading }`,
body: `${ BODY_TYPEFACE }, ${ theme.fonts.body }`,
},
textStyles: {
h2: {
fontSize: [ '32px' ],
fontWeight: '500',
lineHeight: '40px',
fontFamily: 'heading',
},
{
path: './fonts/Druk-Wide-Medium.ttf',
weight: '500',
style: 'normal',
h3: {
fontSize: '24px',
fontWeight: '500',
lineHeight: '32px',
fontFamily: 'heading',
},
h4: {
fontSize: 'md',
@@ -26,16 +32,4 @@ const drukWide = localFont({
},
};
const inter = Inter({ subsets: ['latin'], variable: '--font-inter' })
const fonts = {
heading: `${drukWide.style.fontFamily}, ${ theme.fonts.heading }`,
body: `${inter.style.fontFamily}, ${ theme.fonts.body }`,
}
export {
fonts as default,
drukWide,
inter
}
export default typography;
+2 -2
View File
@@ -10,8 +10,8 @@ const global = (props: StyleFunctionProps) => ({
body: {
bg: mode('white', 'black')(props),
...getDefaultTransitionProps(),
WebkitTapHighlightColor: 'transparent',
fontVariantLigatures: 'no-contextual',
'-webkit-tap-highlight-color': 'transparent',
'font-variant-ligatures': 'no-contextual',
},
mark: {
bgColor: mode('green.100', 'green.800')(props),
+2 -2
View File
@@ -7,12 +7,12 @@ import breakpoints from './foundations/breakpoints';
import colors from './foundations/colors';
import semanticTokens from './foundations/semanticTokens';
import transition from './foundations/transition';
import fonts from './foundations/typography';
import typography from './foundations/typography';
import zIndices from './foundations/zIndices';
import global from './global';
const overrides = {
fonts,
...typography,
...borders,
colors,
components,
+1 -4
View File
@@ -1,8 +1,6 @@
import type { StyleFunctionProps } from '@chakra-ui/theme-tools';
import { mode } from '@chakra-ui/theme-tools';
import luxColors from 'theme/foundations/lux-colors';
import getDefaultTransitionProps from './getDefaultTransitionProps';
import getFormStyles from './getFormStyles';
@@ -35,7 +33,7 @@ export default function getOutlinedFieldStyles(props: StyleFunctionProps) {
cursor: 'not-allowed',
':-webkit-autofill': {
// background color for disabled input which value was selected from browser autocomplete popup
WebkitBoxShadow: `0 0 0px 1000px ${ mode('rgba(16, 17, 18, 0.08)', 'rgba(255, 255, 255, 0.08)')(props) } inset`,
'-webkit-box-shadow': `0 0 0px 1000px ${ mode('rgba(16, 17, 18, 0.08)', 'rgba(255, 255, 255, 0.08)')(props) } inset`,
},
},
_invalid: {
@@ -49,7 +47,6 @@ export default function getOutlinedFieldStyles(props: StyleFunctionProps) {
...formStyles.input.focus,
zIndex: 1,
boxShadow: 'md',
color: luxColors.colors.muted2,
},
_placeholder: {
color: formStyles.placeholder.default.color,
+4
View File
@@ -39,6 +39,10 @@ export interface AddressZilliqaParams {
is_scilla_contract: boolean;
}
export interface AddressZilliqaParams {
is_scilla_contract: boolean;
}
export interface AddressCounters {
transactions_count: string;
token_transfers_count: string;
@@ -3,7 +3,6 @@ import { useRouter } from 'next/router';
import React from 'react';
import type { AddressImplementation } from 'types/api/addressParams';
import type { SmartContractProxyType } from 'types/api/contract';
import useApiQuery from 'lib/api/useApiQuery';
import getQueryParamString from 'lib/router/getQueryParamString';
@@ -19,10 +18,9 @@ import { formatAbi } from './utils';
interface Props {
implementations: Array<AddressImplementation>;
isLoading?: boolean;
proxyType?: SmartContractProxyType;
}
const ContractMethodsProxy = ({ implementations, isLoading: isInitialLoading, proxyType }: Props) => {
const ContractMethodsProxy = ({ implementations, isLoading: isInitialLoading }: Props) => {
const router = useRouter();
const sourceAddress = getQueryParamString(router.query.source_address);
const tab = getQueryParamString(router.query.tab);
@@ -50,7 +48,7 @@ const ContractMethodsProxy = ({ implementations, isLoading: isInitialLoading, pr
selectedItem={ selectedItem }
onItemSelect={ setSelectedItem }
isLoading={ isInitialLoading }
label={ proxyType === 'eip7702' ? 'Delegate address' : 'Implementation address' }
label="Implementation address"
mb={ 3 }
/>
<ContractMethodsFilters
+4 -11
View File
@@ -239,18 +239,16 @@ const AddressPageContent = () => {
addressQuery.data?.is_contract ? {
id: 'contract',
title: () => {
const tabName = addressQuery.data.proxy_type === 'eip7702' ? 'Code' : 'Contract';
if (addressQuery.data.is_verified) {
return (
<>
<span>{ tabName }</span>
<span>Contract</span>
<IconSvg name="status/success" boxSize="14px" color="green.500" ml={ 1 }/>
</>
);
}
return tabName;
return 'Contract';
},
component: (
<AddressContract
@@ -281,12 +279,7 @@ const AddressPageContent = () => {
config.features.validators.isEnabled && addressQuery.data?.has_validated_blocks ?
{ slug: 'validator', name: 'Validator', tagType: 'custom' as const, ordinal: PREDEFINED_TAG_PRIORITY } :
undefined,
addressQuery.data?.implementations?.length && addressQuery.data?.proxy_type !== 'eip7702' ?
{ slug: 'proxy', name: 'Proxy', tagType: 'custom' as const, ordinal: PREDEFINED_TAG_PRIORITY } :
undefined,
addressQuery.data?.implementations?.length && addressQuery.data?.proxy_type === 'eip7702' ?
{ slug: 'eip7702', name: 'EOA+code', tagType: 'custom' as const, ordinal: PREDEFINED_TAG_PRIORITY } :
undefined,
addressQuery.data?.implementations?.length ? { slug: 'proxy', name: 'Proxy', tagType: 'custom' as const, ordinal: PREDEFINED_TAG_PRIORITY } : undefined,
addressQuery.data?.token ? { slug: 'token', name: 'Token', tagType: 'custom' as const, ordinal: PREDEFINED_TAG_PRIORITY } : undefined,
isSafeAddress ? { slug: 'safe', name: 'Multisig: Safe', tagType: 'custom' as const, ordinal: -10 } : undefined,
addressProfileAPIFeature.isEnabled && usernameApiTag ? {
@@ -424,7 +417,7 @@ const AddressPageContent = () => {
<>
<TextAd mb={ 6 }/>
<PageTitle
title={ `${ addressQuery.data?.is_contract && addressQuery.data?.proxy_type !== 'eip7702' ? 'Contract' : 'Address' } details` }
title={ `${ addressQuery.data?.is_contract ? 'Contract' : 'Address' } details` }
backLink={ backLink }
contentAfter={ titleContentAfter }
secondRow={ titleSecondRow }
+3 -3
View File
@@ -15,7 +15,7 @@ import React, { useCallback, useEffect, useRef } from 'react';
import type { FontFace } from 'use-font-face-observer';
import useFontFaceObserver from 'use-font-face-observer';
import { drukWide, inter } from 'theme/foundations/typography';
import { BODY_TYPEFACE, HEADING_TYPEFACE } from 'theme/foundations/typography';
const TAIL_LENGTH = 4;
const HEAD_MIN_LENGTH = 4;
@@ -33,8 +33,8 @@ const HashStringShortenDynamic = ({ hash, fontWeight = '400', isTooltipDisabled,
const [ displayedString, setDisplayedString ] = React.useState(hash);
const isFontFaceLoaded = useFontFaceObserver([
{ family: inter.style.fontFamily, weight: String(fontWeight) as FontFace['weight'] },
{ family: drukWide.style.fontFamily, weight: String(fontWeight) as FontFace['weight'] },
{ family: BODY_TYPEFACE, weight: String(fontWeight) as FontFace['weight'] },
{ family: HEADING_TYPEFACE, weight: String(fontWeight) as FontFace['weight'] },
]);
const calculateString = useCallback(() => {
+2 -2
View File
@@ -4,7 +4,7 @@ import { debounce } from 'es-toolkit';
import React from 'react';
import useFontFaceObserver from 'use-font-face-observer';
import { inter } from 'theme/foundations/typography';
import { BODY_TYPEFACE } from 'theme/foundations/typography';
interface Props {
children: React.ReactNode;
@@ -18,7 +18,7 @@ const TruncatedTextTooltip = ({ children, label, placement }: Props) => {
const { isOpen, onToggle, onOpen, onClose } = useDisclosure();
const isFontFaceLoaded = useFontFaceObserver([
{ family: inter.style.fontFamily },
{ family: BODY_TYPEFACE },
]);
const updatedTruncateState = React.useCallback(() => {
+18 -18
View File
@@ -33,31 +33,31 @@ const ChartSelectionX = ({ anchorEl, height, scale, data, onSelect }: Props) =>
const drawSelection = React.useCallback((x0: number, x1: number) => {
const diffX = x1 - x0;
d3.select(ref.current).attr('opacity', 1);
d3.select(ref.current)
.attr('opacity', 1);
d3.select(ref.current).select('.ChartSelectionX__line_left').attr('x1', x0).attr('x2', x0);
d3.select(ref.current)
.select('.ChartSelectionX__line_left')
.attr('x1', x0)
.attr('x2', x0);
d3.select(ref.current).select('.ChartSelectionX__line_right').attr('x1', x1).attr('x2', x1);
d3.select(ref.current)
.select('.ChartSelectionX__line_right')
.attr('x1', x1)
.attr('x2', x1);
d3.select(ref.current).select('.ChartSelectionX__rect').attr('x', diffX > 0 ? x0 : diffX + x0).attr('width', Math.abs(diffX));
d3.select(ref.current)
.select('.ChartSelectionX__rect')
.attr('x', diffX > 0 ? x0 : diffX + x0)
.attr('width', Math.abs(diffX));
}, []);
const handleSelect = React.useCallback((x0: number, x1: number) => {
const startDate = scale.invert(x0);
const endDate = scale.invert(x1);
if (startDate && endDate && Math.abs(dayjs(startDate).diff(endDate, 'day')) > SELECTION_THRESHOLD) {
const startDayjs = dayjs(startDate);
const endDayjs = dayjs(endDate);
if (startDayjs.isValid() && endDayjs.isValid()) {
const minDate = dayjs.min(startDayjs, endDayjs);
const maxDate = dayjs.max(startDayjs, endDayjs);
if (minDate && maxDate) {
onSelect([ minDate.toDate(), maxDate.toDate() ]);
}
}
if (Math.abs(dayjs(startDate).diff(endDate, 'day')) > SELECTION_THRESHOLD) {
onSelect([ dayjs.min(dayjs(startDate), dayjs(endDate)).toDate(), dayjs.max(dayjs(startDate), dayjs(endDate)).toDate() ]);
}
}, [ onSelect, scale ]);
@@ -66,14 +66,14 @@ const ChartSelectionX = ({ anchorEl, height, scale, data, onSelect }: Props) =>
startX.current = undefined;
endX.current = undefined;
d3.select(ref.current).attr('opacity', 0);
}, []);
}, [ ]);
const handelMouseUp = React.useCallback(() => {
if (!isActive.current) {
return;
}
if (startX.current !== undefined && endX.current !== undefined) {
if (startX.current && endX.current) {
handleSelect(startX.current, endX.current);
}
+1 -3
View File
@@ -53,9 +53,7 @@ async function readEntriesPromise(directoryReader: FileSystemDirectoryReader): P
reject,
);
});
} catch (err) {
return undefined;
}
} catch (err) {}
}
export function convertFileEntryToFile(entry: FileSystemFileEntry, fullFilePath?: boolean): Promise<File> {
+11 -17
View File
@@ -57,23 +57,17 @@ const getChakraStyles: (colorMode: ColorMode) => ChakraStylesConfig<Option> = (c
py: 0,
mx: 0,
}),
valueContainer: (provided, state) => {
const size = state.selectProps.size as Size | undefined;
return {
...provided,
...getValueContainerStyles(size),
py: 0,
};
},
singleValue: (provided, state) => {
const size = state.selectProps.size as Size | undefined;
return {
...provided,
mx: 0,
transform: 'none',
...getSingleValueStyles(size),
};
},
valueContainer: (provided, state) => ({
...provided,
...getValueContainerStyles(state.selectProps.size),
py: 0,
}),
singleValue: (provided, state) => ({
...provided,
mx: 0,
transform: 'none',
...getSingleValueStyles(state.selectProps.size),
}),
};
};
+15 -9
View File
@@ -22,8 +22,8 @@ import getApiVersionUrl from './utils/getApiVersionUrl';
const MAX_LINKS_COLUMNS = 4;
const FRONT_VERSION_URL = `https://github.com/luxfi/explore/tree/${ config.UI.footer.frontendVersion }`;
const FRONT_COMMIT_URL = `https://github.com/luxfi/explore/commit/${ config.UI.footer.frontendCommit }`;
const FRONT_VERSION_URL = `https://github.com/blockscout/frontend/tree/${ config.UI.footer.frontendVersion }`;
const FRONT_COMMIT_URL = `https://github.com/blockscout/frontend/commit/${ config.UI.footer.frontendCommit }`;
const Footer = () => {
@@ -47,25 +47,31 @@ const Footer = () => {
icon: 'social/git' as const,
iconSize: '18px',
text: 'Contribute',
url: 'https://github.com/luxfi',
url: 'https://github.com/blockscout/blockscout',
},
{
icon: 'social/twitter' as const,
iconSize: '18px',
text: 'X',
url: 'https://x.com/luxdefi',
text: 'X (ex-Twitter)',
url: 'https://www.twitter.com/blockscoutcom',
},
{
icon: 'social/discord' as const,
iconSize: '24px',
text: 'Discord',
url: 'https://discord.gg/luxdefi',
url: 'https://discord.gg/blockscout',
},
{
icon: 'brands/blockscout' as const,
iconSize: '18px',
text: 'All chains',
url: 'https://www.blockscout.com/chains-and-projects',
},
{
icon: 'donate' as const,
iconSize: '20px',
text: 'Donate',
url: 'https://github.com/sponsors/luxfi',
url: 'https://github.com/sponsors/blockscout',
},
];
@@ -122,7 +128,7 @@ const Footer = () => {
</Link>
</Flex>
<Text mt={ 3 } fontSize="xs">
Explore is a tool for inspecting and analyzing EVM based blockchains. Blockchain explorer for Lux Network.
Explore is a tool for inspecting and analyzing EVM based blockchains. Blockchain explorer for Lux Networks.
</Text>
<Box mt={ 6 } alignItems="start" fontSize="xs" lineHeight={ 5 }>
{ apiVersionUrl && (
@@ -196,7 +202,7 @@ const Footer = () => {
>
{
([
{ title: 'Lux', links: BLOCKSCOUT_LINKS },
{ title: 'Blockscout', links: BLOCKSCOUT_LINKS },
...(linksData || []),
])
.slice(0, colNum)
@@ -6,8 +6,8 @@ export default function getApiVersionUrl(version: string | undefined): string |
const [ tag, commit ] = version.split('.+commit.');
if (commit) {
return `https://github.com/luxfi/explore/commit/${ commit }`;
return `https://github.com/blockscout/blockscout/commit/${ commit }`;
}
return `https://github.com/luxfi/explore/tree/${ tag }`;
return `https://github.com/blockscout/blockscout/tree/${ tag }`;
}
@@ -1,6 +1,7 @@
import luxColors from 'theme/foundations/lux-colors';
import getDefaultTransitionProps from 'theme/utils/getDefaultTransitionProps';
import useColors from './useColors';
type Props = {
isExpanded?: boolean;
isCollapsed?: boolean;
@@ -8,15 +9,16 @@ type Props = {
};
export default function useNavLinkProps({ isExpanded, isCollapsed, isActive }: Props) {
const colors = useColors();
return {
itemProps: {
py: '9px',
display: 'flex',
border: 'none',
color: isActive ? luxColors.colors.foreground : luxColors.colors.muted2,
bgColor: 'transparent',
_hover: { color: luxColors.colors.accent },
color: isActive ? colors.text.active : colors.text.default,
bgColor: isActive ? colors.bg.active : colors.bg.default,
_hover: { color: isActive ? colors.text.active : colors.text.hover },
borderRadius: 'base',
...getDefaultTransitionProps({ transitionProperty: 'width, padding' }),
},
textProps: {
+2 -3
View File
@@ -5,7 +5,6 @@ import type { ChangeEvent, FormEvent, FocusEvent } from 'react';
import { useScrollDirection } from 'lib/contexts/scrollDirection';
import useIsMobile from 'lib/hooks/useIsMobile';
import luxColors from 'theme/foundations/lux-colors';
import ClearButton from 'ui/shared/ClearButton';
import IconSvg from 'ui/shared/IconSvg';
@@ -164,9 +163,9 @@ const SearchBarInput = (
paddingRight: '36px',
},
}}
placeholder={ isMobile ? 'Search by address... ' : 'Search by address, txn hash, block, token... ' }
placeholder={ isMobile ? 'Search by address / ... ' : 'Search by address / txn hash / block / token... ' }
onChange={ handleChange }
border={ '2px solid ' + luxColors.colors.muted3 }
border={ isHomepage ? 'none' : '2px solid' }
borderColor={ useColorModeValue('blackAlpha.100', 'whiteAlpha.200') }
_focusWithin={{ _placeholder: { color: 'gray.300' } }}
color={ useColorModeValue('black', 'white') }
+18077
View File
File diff suppressed because it is too large Load Diff