Commit c58a3fdf authored by tom goriunov's avatar tom goriunov Committed by GitHub

refactor page layout components (#1087)

* update csv export text

* fix pw tests

* base layout and customization for home page and search results page

* refactor rest of the pages

* refactor AppError

* move header padding to layout

* move nextjs utils to separate folder

* combine PageServer and Page

* make useQueryClientConfig hook

* add tests

* remove unused var

* fix envs for pw

* fix pw tests
parent e36711f2
......@@ -3,3 +3,5 @@ node_modules_linux
playwright/envs.js
deploy/tools/envs-validator/index.js
deploy/tools/feature-reporter/build/**
deploy/tools/feature-reporter/index.js
\ No newline at end of file
......@@ -199,7 +199,23 @@ module.exports = {
groups: [
'module',
'/types/',
[ '/^configs/', '/^data/', '/^deploy/', '/^icons/', '/^jest/', '/^lib/', '/^mocks/', '/^pages/', '/^playwright/', '/^stubs/', '/^theme/', '/^ui/' ],
[
'/^nextjs/',
],
[
'/^configs/',
'/^data/',
'/^deploy/',
'/^icons/',
'/^jest/',
'/^lib/',
'/^mocks/',
'/^pages/',
'/^playwright/',
'/^stubs/',
'/^theme/',
'/^ui/',
],
[ 'parent', 'sibling', 'index' ],
],
alphabetize: { order: 'asc', ignoreCase: true },
......
......@@ -46,6 +46,9 @@ NEXT_PUBLIC_MARKETPLACE_CONFIG_URL=https://localhost:3000/marketplace-config.jso
NEXT_PUBLIC_MARKETPLACE_SUBMIT_FORM=https://localhost:3000/marketplace-submit-form
NEXT_PUBLIC_IS_L2_NETWORK=false
NEXT_PUBLIC_IS_ACCOUNT_SUPPORTED=true
NEXT_PUBLIC_AUTH_URL=http://localhost:3100
NEXT_PUBLIC_LOGOUT_URL=https://blockscoutcom.us.auth0.com/v2/logout
NEXT_PUBLIC_AUTH0_CLIENT_ID=xxx
NEXT_PUBLIC_STATS_API_HOST=https://localhost:3004
NEXT_PUBLIC_CONTRACT_INFO_API_HOST=https://localhost:3005
NEXT_PUBLIC_ADMIN_SERVICE_API_HOST=https://localhost:3006
......
# Set of ENVs for Playwright components tests
#
# be aware that ALL ENVs should be present in order to make a correct variables list for the browser
# leave empty values for the ones that are not required
# app configuration
NEXT_PUBLIC_APP_PROTOCOL=http
......@@ -45,11 +48,15 @@ NEXT_PUBLIC_APP_INSTANCE=pw
NEXT_PUBLIC_MARKETPLACE_CONFIG_URL=https://localhost:3000/marketplace-config.json
NEXT_PUBLIC_MARKETPLACE_SUBMIT_FORM=https://localhost:3000/marketplace-submit-form
NEXT_PUBLIC_IS_L2_NETWORK=false
NEXT_PUBLIC_L1_BASE_URL=
NEXT_PUBLIC_L2_WITHDRAWAL_URL=
NEXT_PUBLIC_AD_BANNER_PROVIDER=slise
NEXT_PUBLIC_IS_ACCOUNT_SUPPORTED=true
NEXT_PUBLIC_AUTH_URL=http://localhost:3100
NEXT_PUBLIC_LOGOUT_URL=https://blockscoutcom.us.auth0.com/v2/logout
NEXT_PUBLIC_AUTH0_CLIENT_ID=xxx
NEXT_PUBLIC_STATS_API_HOST=https://localhost:3004
NEXT_PUBLIC_CONTRACT_INFO_API_HOST=https://localhost:3005
NEXT_PUBLIC_ADMIN_SERVICE_API_HOST=https://localhost:3006
NEXT_PUBLIC_RE_CAPTCHA_APP_SITE_KEY=xxx
NEXT_PUBLIC_HAS_BEACON_CHAIN=
......@@ -5,7 +5,7 @@
"module": "CommonJS",
"outDir": "./build",
"paths": {
"nextjs-routes": ["./types/nextjs-routes.d.ts"],
"nextjs-routes": ["./nextjs/nextjs-routes.d.ts"],
}
},
"include": [ "../../../configs/app/index.ts" ],
......
import { QueryClient } from '@tanstack/react-query';
import React from 'react';
import getErrorObjPayload from 'lib/errors/getErrorObjPayload';
import getErrorObjStatusCode from 'lib/errors/getErrorObjStatusCode';
export default function useQueryClientConfig() {
const [ queryClient ] = React.useState(() => new QueryClient({
defaultOptions: {
queries: {
refetchOnWindowFocus: false,
retry: (failureCount, error) => {
const errorPayload = getErrorObjPayload<{ status: number }>(error);
const status = errorPayload?.status || getErrorObjStatusCode(error);
if (status && status >= 400 && status < 500) {
// don't do retry for client error responses
return false;
}
return failureCount < 2;
},
useErrorBoundary: (error) => {
const status = getErrorObjStatusCode(error);
// don't catch error for "Too many requests" response
return status === 429;
},
},
},
}));
return queryClient;
}
import React, { createContext, useContext } from 'react';
import type { Props as PageProps } from 'lib/next/getServerSideProps';
import type { Props as PageProps } from 'nextjs/getServerSideProps';
type Props = {
children: React.ReactNode;
......
import { useRouter } from 'next/router';
import { route } from 'nextjs-routes';
import config from 'configs/app';
......
import type { Route } from 'nextjs-routes';
import type { ApiData } from './types';
import type { Route } from 'nextjs-routes';
import generate from './generate';
interface TestCase<R extends Route> {
......
import type { Route } from 'nextjs-routes';
import type { ApiData, Metadata } from './types';
import type { Route } from 'nextjs-routes';
import config from 'configs/app';
import getNetworkTitle from 'lib/networks/getNetworkTitle';
......
import type { Route } from 'nextjs-routes';
import type { ApiData } from './types';
import type { Route } from 'nextjs-routes';
import generate from './generate';
export default function update<R extends Route>(route: R, apiData: ApiData<R>) {
......
import type { NextRequest } from 'next/server';
import { NextResponse } from 'next/server';
import generateCspPolicy from 'lib/csp/generateCspPolicy';
import * as middlewares from 'lib/next/middlewares/index';
import generateCspPolicy from 'nextjs/csp/generateCspPolicy';
import * as middlewares from 'nextjs/middlewares/index';
const cspPolicy = generateCspPolicy();
......
......@@ -3,14 +3,15 @@ const withTM = require('next-transpile-modules')([
'swagger-client',
'swagger-ui-react',
]);
const path = require('path');
const withRoutes = require('nextjs-routes/config')({
outDir: 'types',
outDir: 'nextjs',
});
const path = require('path');
const headers = require('./configs/nextjs/headers');
const redirects = require('./configs/nextjs/redirects');
const rewrites = require('./configs/nextjs/rewrites');
const headers = require('./nextjs/headers');
const redirects = require('./nextjs/redirects');
const rewrites = require('./nextjs/rewrites');
const moduleExports = withTM({
include: path.resolve(__dirname, 'icons'),
......
import Head from 'next/head';
import type { Route } from 'nextjs-routes';
import React from 'react';
import type { Route } from 'nextjs-routes';
import useAdblockDetect from 'lib/hooks/useAdblockDetect';
import useConfigSentry from 'lib/hooks/useConfigSentry';
import useGetCsrfToken from 'lib/hooks/useGetCsrfToken';
import * as metadata from 'lib/metadata';
import * as mixpanel from 'lib/mixpanel';
type Props = Route & {
children: React.ReactNode;
}
const PageServer = (props: Props) => {
const PageNextJs = (props: Props) => {
const { title, description } = metadata.generate(props);
useGetCsrfToken();
useAdblockDetect();
useConfigSentry();
const isMixpanelInited = mixpanel.useInit();
mixpanel.useLogPageView(isMixpanelInited);
return (
<>
<Head>
......@@ -22,4 +34,4 @@ const PageServer = (props: Props) => {
);
};
export default React.memo(PageServer);
export default React.memo(PageNextJs);
import type { NextRequest } from 'next/server';
import { NextResponse } from 'next/server';
import { route } from 'nextjs-routes';
import config from 'configs/app';
......
import type { NextPage } from 'next';
// eslint-disable-next-line @typescript-eslint/ban-types
export type NextPageWithLayout<P = {}, IP = P> = NextPage<P, IP> & {
getLayout?: (page: React.ReactElement) => React.ReactNode;
}
import { compile } from 'path-to-regexp';
import config from 'configs/app';
import { RESOURCES } from 'lib/api/resources';
import type { ApiResource, ResourceName } from 'lib/api/resources';
import { RESOURCES } from './resources';
import type { ApiResource, ResourceName } from './resources';
export default function buildUrlNode(
export default function buildUrl(
_resource: ApiResource | ResourceName,
pathParams?: Record<string, string | undefined>,
queryParams?: Record<string, string | number | undefined>,
......
......@@ -4,7 +4,8 @@ import type { NextApiRequestCookies } from 'next/dist/server/api-utils';
import type { RequestInit, Response } from 'node-fetch';
import nodeFetch from 'node-fetch';
import { httpLogger } from 'lib/api/logger';
import { httpLogger } from 'nextjs/utils/logger';
import * as cookies from 'lib/cookies';
export default function fetchFactory(
......
import React from 'react';
import PageServer from 'lib/next/PageServer';
import type { NextPageWithLayout } from 'nextjs/types';
import PageNextJs from 'nextjs/PageNextJs';
import AppError from 'ui/shared/AppError/AppError';
import Page from 'ui/shared/Page/Page';
import LayoutError from 'ui/shared/layout/LayoutError';
const error = new Error('Not found', { cause: { status: 404 } });
const Page: NextPageWithLayout = () => {
return (
<PageNextJs pathname="/404">
<AppError error={ error }/>
</PageNextJs>
);
};
const Custom404 = () => {
Page.getLayout = function getLayout(page: React.ReactElement) {
return (
<PageServer pathname="/404">
<Page>
<AppError statusCode={ 404 } mt="50px"/>
</Page>
</PageServer>
<LayoutError>
{ page }
</LayoutError>
);
};
export default Custom404;
export default Page;
import type { ChakraProps } from '@chakra-ui/react';
import * as Sentry from '@sentry/react';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { QueryClientProvider } from '@tanstack/react-query';
import { ReactQueryDevtools } from '@tanstack/react-query-devtools';
import type { AppProps } from 'next/app';
import React, { useState } from 'react';
import React from 'react';
import type { NextPageWithLayout } from 'nextjs/types';
import config from 'configs/app';
import useQueryClientConfig from 'lib/api/useQueryClientConfig';
import { AppContextProvider } from 'lib/contexts/app';
import { ChakraProvider } from 'lib/contexts/chakra';
import { ScrollDirectionProvider } from 'lib/contexts/scrollDirection';
import getErrorCauseStatusCode from 'lib/errors/getErrorCauseStatusCode';
import getErrorObjPayload from 'lib/errors/getErrorObjPayload';
import getErrorObjStatusCode from 'lib/errors/getErrorObjStatusCode';
import useConfigSentry from 'lib/hooks/useConfigSentry';
import { SocketProvider } from 'lib/socket/context';
import theme from 'theme';
import AppError from 'ui/shared/AppError/AppError';
import AppErrorTooManyRequests from 'ui/shared/AppError/AppErrorTooManyRequests';
import ErrorBoundary from 'ui/shared/ErrorBoundary';
import AppErrorBoundary from 'ui/shared/AppError/AppErrorBoundary';
import GoogleAnalytics from 'ui/shared/GoogleAnalytics';
import Layout from 'ui/shared/layout/Layout';
import 'lib/setLocale';
function MyApp({ Component, pageProps }: AppProps) {
useConfigSentry();
const [ queryClient ] = useState(() => new QueryClient({
defaultOptions: {
queries: {
refetchOnWindowFocus: false,
retry: (failureCount, error) => {
const errorPayload = getErrorObjPayload<{ status: number }>(error);
const status = errorPayload?.status || getErrorObjStatusCode(error);
if (status && status >= 400 && status < 500) {
// don't do retry for client error responses
return false;
}
return failureCount < 2;
},
useErrorBoundary: (error) => {
const status = getErrorObjStatusCode(error);
// don't catch error for "Too many requests" response
return status === 429;
},
},
},
}));
const renderErrorScreen = React.useCallback((error?: Error) => {
const statusCode = getErrorCauseStatusCode(error) || getErrorObjStatusCode(error);
type AppPropsWithLayout = AppProps & {
Component: NextPageWithLayout;
}
const styles: ChakraProps = {
const ERROR_SCREEN_STYLES: ChakraProps = {
h: '100vh',
display: 'flex',
flexDirection: 'column',
......@@ -61,39 +34,36 @@ function MyApp({ Component, pageProps }: AppProps) {
maxW: '800px',
margin: '0 auto',
p: { base: 4, lg: 0 },
};
};
if (statusCode === 429) {
return <AppErrorTooManyRequests { ...styles }/>;
}
function MyApp({ Component, pageProps }: AppPropsWithLayout) {
return (
<AppError
statusCode={ statusCode || 500 }
{ ...styles }
/>
);
}, []);
const queryClient = useQueryClientConfig();
const handleError = React.useCallback((error: Error) => {
Sentry.captureException(error);
}, []);
const getLayout = Component.getLayout ?? ((page) => <Layout>{ page }</Layout>);
return (
<ChakraProvider theme={ theme } cookies={ pageProps.cookies }>
<ErrorBoundary renderErrorScreen={ renderErrorScreen } onError={ handleError }>
<AppErrorBoundary
{ ...ERROR_SCREEN_STYLES }
onError={ handleError }
>
<AppContextProvider pageProps={ pageProps }>
<QueryClientProvider client={ queryClient }>
<ScrollDirectionProvider>
<SocketProvider url={ `${ config.api.socket }${ config.api.basePath }/socket/v2` }>
<Component { ...pageProps }/>
{ getLayout(<Component { ...pageProps }/>) }
</SocketProvider>
</ScrollDirectionProvider>
<ReactQueryDevtools/>
<GoogleAnalytics/>
</QueryClientProvider>
</AppContextProvider>
</ErrorBoundary>
</AppErrorBoundary>
</ChakraProvider>
);
}
......
......@@ -3,8 +3,9 @@ import type { DocumentContext } from 'next/document';
import Document, { Html, Head, Main, NextScript } from 'next/document';
import React from 'react';
import * as serverTiming from 'nextjs/utils/serverTiming';
import config from 'configs/app';
import * as serverTiming from 'lib/next/serverTiming';
import theme from 'theme';
class MyDocument extends Document {
......
......@@ -21,10 +21,11 @@ import type { GetServerSideProps } from 'next';
import NextErrorComponent from 'next/error';
import React from 'react';
import type { Props as ServerSidePropsCommon } from 'nextjs/getServerSideProps';
import { base as getServerSidePropsCommon } from 'nextjs/getServerSideProps';
import sentryConfig from 'configs/sentry/nextjs';
import * as cookies from 'lib/cookies';
import type { Props as ServerSidePropsCommon } from 'lib/next/getServerSideProps';
import { base as getServerSidePropsCommon } from 'lib/next/getServerSideProps';
type Props = ServerSidePropsCommon & {
statusCode: number;
......
......@@ -2,21 +2,18 @@ import type { NextPage } from 'next';
import dynamic from 'next/dynamic';
import React from 'react';
import PageServer from 'lib/next/PageServer';
import Page from 'ui/shared/Page/Page';
import PageNextJs from 'nextjs/PageNextJs';
const ApiKeys = dynamic(() => import('ui/pages/ApiKeys'), { ssr: false });
const ApiKeysPage: NextPage = () => {
const Page: NextPage = () => {
return (
<PageServer pathname="/account/api-key">
<Page>
<PageNextJs pathname="/account/api-key">
<ApiKeys/>
</Page>
</PageServer>
</PageNextJs>
);
};
export default ApiKeysPage;
export default Page;
export { account as getServerSideProps } from 'lib/next/getServerSideProps';
export { account as getServerSideProps } from 'nextjs/getServerSideProps';
......@@ -2,21 +2,18 @@ import type { NextPage } from 'next';
import dynamic from 'next/dynamic';
import React from 'react';
import PageServer from 'lib/next/PageServer';
import Page from 'ui/shared/Page/Page';
import PageNextJs from 'nextjs/PageNextJs';
const CustomAbi = dynamic(() => import('ui/pages/CustomAbi'), { ssr: false });
const CustomAbiPage: NextPage = () => {
const Page: NextPage = () => {
return (
<PageServer pathname="/account/custom-abi">
<Page>
<PageNextJs pathname="/account/custom-abi">
<CustomAbi/>
</Page>
</PageServer>
</PageNextJs>
);
};
export default CustomAbiPage;
export default Page;
export { account as getServerSideProps } from 'lib/next/getServerSideProps';
export { account as getServerSideProps } from 'nextjs/getServerSideProps';
......@@ -2,21 +2,18 @@ import type { NextPage } from 'next';
import dynamic from 'next/dynamic';
import React from 'react';
import PageServer from 'lib/next/PageServer';
import Page from 'ui/shared/Page/Page';
import PageNextJs from 'nextjs/PageNextJs';
const PublicTags = dynamic(() => import('ui/pages/PublicTags'), { ssr: false });
const PublicTagsPage: NextPage = () => {
const Page: NextPage = () => {
return (
<PageServer pathname="/account/public-tags-request">
<Page>
<PageNextJs pathname="/account/public-tags-request">
<PublicTags/>
</Page>
</PageServer>
</PageNextJs>
);
};
export default PublicTagsPage;
export default Page;
export { account as getServerSideProps } from 'lib/next/getServerSideProps';
export { account as getServerSideProps } from 'nextjs/getServerSideProps';
......@@ -2,21 +2,18 @@ import type { NextPage } from 'next';
import dynamic from 'next/dynamic';
import React from 'react';
import PageServer from 'lib/next/PageServer';
import Page from 'ui/shared/Page/Page';
import PageNextJs from 'nextjs/PageNextJs';
const PrivateTags = dynamic(() => import('ui/pages/PrivateTags'), { ssr: false });
const PrivateTagsPage: NextPage = () => {
const Page: NextPage = () => {
return (
<PageServer pathname="/account/tag-address">
<Page>
<PageNextJs pathname="/account/tag-address">
<PrivateTags/>
</Page>
</PageServer>
</PageNextJs>
);
};
export default PrivateTagsPage;
export default Page;
export { account as getServerSideProps } from 'lib/next/getServerSideProps';
export { account as getServerSideProps } from 'nextjs/getServerSideProps';
......@@ -2,21 +2,18 @@ import type { NextPage } from 'next';
import dynamic from 'next/dynamic';
import React from 'react';
import PageServer from 'lib/next/PageServer';
import Page from 'ui/shared/Page/Page';
import PageNextJs from 'nextjs/PageNextJs';
const VerifiedAddresses = dynamic(() => import('ui/pages/VerifiedAddresses'), { ssr: false });
const VerifiedAddressesPage: NextPage = () => {
const Page: NextPage = () => {
return (
<PageServer pathname="/account/verified-addresses">
<Page>
<PageNextJs pathname="/account/verified-addresses">
<VerifiedAddresses/>
</Page>
</PageServer>
</PageNextJs>
);
};
export default VerifiedAddressesPage;
export default Page;
export { verifiedAddresses as getServerSideProps } from 'lib/next/getServerSideProps';
export { verifiedAddresses as getServerSideProps } from 'nextjs/getServerSideProps';
......@@ -2,21 +2,18 @@ import type { NextPage } from 'next';
import dynamic from 'next/dynamic';
import React from 'react';
import PageServer from 'lib/next/PageServer';
import Page from 'ui/shared/Page/Page';
import PageNextJs from 'nextjs/PageNextJs';
const WatchList = dynamic(() => import('ui/pages/Watchlist'), { ssr: false });
const WatchListPage: NextPage = () => {
const Page: NextPage = () => {
return (
<PageServer pathname="/account/watchlist">
<Page>
<PageNextJs pathname="/account/watchlist">
<WatchList/>
</Page>
</PageServer>
</PageNextJs>
);
};
export default WatchListPage;
export default Page;
export { account as getServerSideProps } from 'lib/next/getServerSideProps';
export { account as getServerSideProps } from 'nextjs/getServerSideProps';
......@@ -2,21 +2,18 @@ import type { NextPage } from 'next';
import dynamic from 'next/dynamic';
import React from 'react';
import PageServer from 'lib/next/PageServer';
import Page from 'ui/shared/Page/Page';
import PageNextJs from 'nextjs/PageNextJs';
const Accounts = dynamic(() => import('ui/pages/Accounts'), { ssr: false });
const AccountsPage: NextPage = () => {
const Page: NextPage = () => {
return (
<PageServer pathname="/accounts">
<Page>
<PageNextJs pathname="/accounts">
<Accounts/>
</Page>
</PageServer>
</PageNextJs>
);
};
export default AccountsPage;
export default Page;
export { base as getServerSideProps } from 'lib/next/getServerSideProps';
export { base as getServerSideProps } from 'nextjs/getServerSideProps';
import type { NextPage } from 'next';
import React from 'react';
import type { Props } from 'lib/next/getServerSideProps';
import PageServer from 'lib/next/PageServer';
import type { Props } from 'nextjs/getServerSideProps';
import PageNextJs from 'nextjs/PageNextJs';
import ContractVerification from 'ui/pages/ContractVerification';
import Page from 'ui/shared/Page/Page';
const ContractVerificationPage: NextPage<Props> = (props: Props) => {
const Page: NextPage<Props> = (props: Props) => {
return (
<PageServer pathname="/address/[hash]/contract-verification" query={ props }>
<Page>
<PageNextJs pathname="/address/[hash]/contract-verification" query={ props }>
<ContractVerification/>
</Page>
</PageServer>
</PageNextJs>
);
};
export default ContractVerificationPage;
export default Page;
export { base as getServerSideProps } from 'lib/next/getServerSideProps';
export { base as getServerSideProps } from 'nextjs/getServerSideProps';
......@@ -2,22 +2,19 @@ import type { NextPage } from 'next';
import dynamic from 'next/dynamic';
import React from 'react';
import type { Props } from 'lib/next/getServerSideProps';
import PageServer from 'lib/next/PageServer';
import Page from 'ui/shared/Page/Page';
import type { Props } from 'nextjs/getServerSideProps';
import PageNextJs from 'nextjs/PageNextJs';
const Address = dynamic(() => import('ui/pages/Address'), { ssr: false });
const AddressPage: NextPage<Props> = (props: Props) => {
const Page: NextPage<Props> = (props: Props) => {
return (
<PageServer pathname="/address/[hash]" query={ props }>
<Page>
<PageNextJs pathname="/address/[hash]" query={ props }>
<Address/>
</Page>
</PageServer>
</PageNextJs>
);
};
export default AddressPage;
export default Page;
export { base as getServerSideProps } from 'lib/next/getServerSideProps';
export { base as getServerSideProps } from 'nextjs/getServerSideProps';
import type { NextPage } from 'next';
import React from 'react';
import PageServer from 'lib/next/PageServer';
import PageNextJs from 'nextjs/PageNextJs';
import SwaggerUI from 'ui/apiDocs/SwaggerUI';
import Page from 'ui/shared/Page/Page';
import PageTitle from 'ui/shared/Page/PageTitle';
const APIDocsPage: NextPage = () => {
const Page: NextPage = () => {
return (
<PageServer pathname="/api-docs">
<Page>
<PageNextJs pathname="/api-docs">
<PageTitle title="API Documentation"/>
<SwaggerUI/>
</Page>
</PageServer>
</PageNextJs>
);
};
export default APIDocsPage;
export default Page;
export { apiDocs as getServerSideProps } from 'lib/next/getServerSideProps';
export { apiDocs as getServerSideProps } from 'nextjs/getServerSideProps';
import type { NextApiRequest, NextApiResponse } from 'next';
import buildUrlNode from 'lib/api/buildUrlNode';
import { httpLogger } from 'lib/api/logger';
import fetchFactory from 'lib/api/nodeFetch';
import buildUrl from 'nextjs/utils/buildUrl';
import fetchFactory from 'nextjs/utils/fetch';
import { httpLogger } from 'nextjs/utils/logger';
export default async function csrfHandler(_req: NextApiRequest, res: NextApiResponse) {
httpLogger(_req, res);
const url = buildUrlNode('csrf');
const url = buildUrl('csrf');
const response = await fetchFactory(_req)(url);
if (response.status === 200) {
......
import type { NextApiRequest, NextApiResponse } from 'next';
import nodeFetch from 'node-fetch';
import { httpLogger } from 'lib/api/logger';
import { httpLogger } from 'nextjs/utils/logger';
import getQueryParamString from 'lib/router/getQueryParamString';
export default async function mediaTypeHandler(req: NextApiRequest, res: NextApiResponse) {
......
......@@ -2,8 +2,9 @@ import _pick from 'lodash/pick';
import _pickBy from 'lodash/pickBy';
import type { NextApiRequest, NextApiResponse } from 'next';
import fetchFactory from 'nextjs/utils/fetch';
import config from 'configs/app';
import fetchFactory from 'lib/api/nodeFetch';
const handler = async(nextReq: NextApiRequest, nextRes: NextApiResponse) => {
if (!nextReq.url) {
......
import type { NextPage } from 'next';
import dynamic from 'next/dynamic';
import React from 'react';
import type { Props } from 'lib/next/getServerSideProps';
import PageServer from 'lib/next/PageServer';
import Page from 'ui/shared/Page/Page';
import type { NextPageWithLayout } from 'nextjs/types';
import type { Props } from 'nextjs/getServerSideProps';
import PageNextJs from 'nextjs/PageNextJs';
const MarketplaceApp = dynamic(() => import('ui/pages/MarketplaceApp'), { ssr: false });
const MarketplaceAppPage: NextPage<Props> = (props: Props) => {
const Page: NextPageWithLayout<Props> = (props: Props) => {
return (
<PageServer pathname="/apps/[id]" query={ props }>
<Page wrapChildren={ false }>
<PageNextJs pathname="/apps/[id]" query={ props }>
<MarketplaceApp/>
</Page>
</PageServer>
</PageNextJs>
);
};
export default MarketplaceAppPage;
export default Page;
export { marketplace as getServerSideProps } from 'lib/next/getServerSideProps';
export { marketplace as getServerSideProps } from 'nextjs/getServerSideProps';
......@@ -2,23 +2,23 @@ import type { NextPage } from 'next';
import dynamic from 'next/dynamic';
import React from 'react';
import PageServer from 'lib/next/PageServer';
import Page from 'ui/shared/Page/Page';
import PageNextJs from 'nextjs/PageNextJs';
import PageTitle from 'ui/shared/Page/PageTitle';
const Marketplace = dynamic(() => import('ui/pages/Marketplace'), { ssr: false });
const MarketplacePage: NextPage = () => {
const Page: NextPage = () => {
return (
<PageServer pathname="/apps">
<Page>
<PageNextJs pathname="/apps">
<>
<PageTitle title="Marketplace"/>
<Marketplace/>
</Page>
</PageServer>
</>
</PageNextJs>
);
};
export default MarketplacePage;
export default Page;
export { marketplace as getServerSideProps } from 'lib/next/getServerSideProps';
export { marketplace as getServerSideProps } from 'nextjs/getServerSideProps';
import type { NextPage } from 'next';
const Auth0Page: NextPage = () => {
const Page: NextPage = () => {
return null;
};
export default Auth0Page;
export default Page;
export async function getServerSideProps() {
return {
......
import type { NextPage } from 'next';
import React from 'react';
import PageServer from 'lib/next/PageServer';
import PageNextJs from 'nextjs/PageNextJs';
import MyProfile from 'ui/pages/MyProfile';
import Page from 'ui/shared/Page/Page';
const MyProfilePage: NextPage = () => {
const Page: NextPage = () => {
return (
<PageServer pathname="/auth/profile">
<Page>
<PageNextJs pathname="/auth/profile">
<MyProfile/>
</Page>
</PageServer>
</PageNextJs>
);
};
export default MyProfilePage;
export default Page;
export { account as getServerSideProps } from 'lib/next/getServerSideProps';
export { account as getServerSideProps } from 'nextjs/getServerSideProps';
import type { NextPage } from 'next';
import React from 'react';
import PageServer from 'lib/next/PageServer';
import PageNextJs from 'nextjs/PageNextJs';
import UnverifiedEmail from 'ui/pages/UnverifiedEmail';
import Page from 'ui/shared/Page/Page';
const UnverifiedEmailPage: NextPage = () => {
const Page: NextPage = () => {
return (
<PageServer pathname="/auth/unverified-email">
<Page>
<PageNextJs pathname="/auth/unverified-email">
<UnverifiedEmail/>
</Page>
</PageServer>
</PageNextJs>
);
};
export default UnverifiedEmailPage;
export default Page;
export { account as getServerSideProps } from 'lib/next/getServerSideProps';
export { account as getServerSideProps } from 'nextjs/getServerSideProps';
......@@ -2,22 +2,19 @@ import type { NextPage } from 'next';
import dynamic from 'next/dynamic';
import React from 'react';
import type { Props } from 'lib/next/getServerSideProps';
import PageServer from 'lib/next/PageServer';
import Page from 'ui/shared/Page/Page';
import type { Props } from 'nextjs/getServerSideProps';
import PageNextJs from 'nextjs/PageNextJs';
const Block = dynamic(() => import('ui/pages/Block'), { ssr: false });
const BlockPage: NextPage<Props> = (props: Props) => {
const Page: NextPage<Props> = (props: Props) => {
return (
<PageServer pathname="/block/[height_or_hash]" query={ props }>
<Page>
<PageNextJs pathname="/block/[height_or_hash]" query={ props }>
<Block/>
</Page>
</PageServer>
</PageNextJs>
);
};
export default BlockPage;
export default Page;
export { base as getServerSideProps } from 'lib/next/getServerSideProps';
export { base as getServerSideProps } from 'nextjs/getServerSideProps';
......@@ -2,21 +2,18 @@ import type { NextPage } from 'next';
import dynamic from 'next/dynamic';
import React from 'react';
import PageServer from 'lib/next/PageServer';
import Page from 'ui/shared/Page/Page';
import PageNextJs from 'nextjs/PageNextJs';
const Blocks = dynamic(() => import('ui/pages/Blocks'), { ssr: false });
const BlockPage: NextPage = () => {
const Page: NextPage = () => {
return (
<PageServer pathname="/blocks">
<Page>
<PageNextJs pathname="/blocks">
<Blocks/>
</Page>
</PageServer>
</PageNextJs>
);
};
export default BlockPage;
export default Page;
export { base as getServerSideProps } from 'lib/next/getServerSideProps';
export { base as getServerSideProps } from 'nextjs/getServerSideProps';
import type { NextPage } from 'next';
import React from 'react';
import PageServer from 'lib/next/PageServer';
import PageNextJs from 'nextjs/PageNextJs';
import CsvExport from 'ui/pages/CsvExport';
const CsvExportPage: NextPage = () => {
const Page: NextPage = () => {
return (
<PageServer pathname="/csv-export">
<PageNextJs pathname="/csv-export">
<CsvExport/>
</PageServer>
</PageNextJs>
);
};
export default CsvExportPage;
export default Page;
export { csvExport as getServerSideProps } from 'lib/next/getServerSideProps';
export { csvExport as getServerSideProps } from 'nextjs/getServerSideProps';
......@@ -2,9 +2,9 @@ import type { NextPage } from 'next';
import dynamic from 'next/dynamic';
import React from 'react';
import PageServer from 'lib/next/PageServer';
import PageNextJs from 'nextjs/PageNextJs';
import ContentLoader from 'ui/shared/ContentLoader';
import Page from 'ui/shared/Page/Page';
import PageTitle from 'ui/shared/Page/PageTitle';
const GraphQL = dynamic(() => import('ui/graphQL/GraphQL'), {
......@@ -12,18 +12,16 @@ const GraphQL = dynamic(() => import('ui/graphQL/GraphQL'), {
ssr: false,
});
const GraphiqlPage: NextPage = () => {
const Page: NextPage = () => {
return (
<PageServer pathname="/graphiql">
<Page>
<PageNextJs pathname="/graphiql">
<PageTitle title="GraphQL playground"/>
<GraphQL/>
</Page>
</PageServer>
</PageNextJs>
);
};
export default GraphiqlPage;
export default Page;
export { base as getServerSideProps } from 'lib/next/getServerSideProps';
export { base as getServerSideProps } from 'nextjs/getServerSideProps';
import type { NextPage } from 'next';
import React from 'react';
import PageServer from 'lib/next/PageServer';
import type { NextPageWithLayout } from 'nextjs/types';
import PageNextJs from 'nextjs/PageNextJs';
import Home from 'ui/pages/Home';
import LayoutHome from 'ui/shared/layout/LayoutHome';
const HomePage: NextPage = () => {
const Page: NextPageWithLayout = () => {
return (
<PageServer pathname="/">
<PageNextJs pathname="/">
<Home/>
</PageServer>
</PageNextJs>
);
};
Page.getLayout = function getLayout(page: React.ReactElement) {
return (
<LayoutHome>
{ page }
</LayoutHome>
);
};
export default HomePage;
export default Page;
export { base as getServerSideProps } from 'lib/next/getServerSideProps';
export { base as getServerSideProps } from 'nextjs/getServerSideProps';
......@@ -2,21 +2,18 @@ import type { NextPage } from 'next';
import dynamic from 'next/dynamic';
import React from 'react';
import PageServer from 'lib/next/PageServer';
import Page from 'ui/shared/Page/Page';
import PageNextJs from 'nextjs/PageNextJs';
const L2Deposits = dynamic(() => import('ui/pages/L2Deposits'), { ssr: false });
const DepositsPage: NextPage = () => {
const Page: NextPage = () => {
return (
<PageServer pathname="/l2-deposits">
<Page>
<PageNextJs pathname="/l2-deposits">
<L2Deposits/>
</Page>
</PageServer>
</PageNextJs>
);
};
export default DepositsPage;
export default Page;
export { L2 as getServerSideProps } from 'lib/next/getServerSideProps';
export { L2 as getServerSideProps } from 'nextjs/getServerSideProps';
......@@ -2,21 +2,18 @@ import type { NextPage } from 'next';
import dynamic from 'next/dynamic';
import React from 'react';
import PageServer from 'lib/next/PageServer';
import Page from 'ui/shared/Page/Page';
import PageNextJs from 'nextjs/PageNextJs';
const L2OutputRoots = dynamic(() => import('ui/pages/L2OutputRoots'), { ssr: false });
const OutputRootsPage: NextPage = () => {
const Page: NextPage = () => {
return (
<PageServer pathname="/l2-output-roots">
<Page>
<PageNextJs pathname="/l2-output-roots">
<L2OutputRoots/>
</Page>
</PageServer>
</PageNextJs>
);
};
export default OutputRootsPage;
export default Page;
export { L2 as getServerSideProps } from 'lib/next/getServerSideProps';
export { L2 as getServerSideProps } from 'nextjs/getServerSideProps';
......@@ -2,21 +2,18 @@ import type { NextPage } from 'next';
import dynamic from 'next/dynamic';
import React from 'react';
import PageServer from 'lib/next/PageServer';
import Page from 'ui/shared/Page/Page';
import PageNextJs from 'nextjs/PageNextJs';
const L2TxnBatches = dynamic(() => import('ui/pages/L2TxnBatches'), { ssr: false });
const TxnBatchesPage: NextPage = () => {
const Page: NextPage = () => {
return (
<PageServer pathname="/l2-txn-batches">
<Page>
<PageNextJs pathname="/l2-txn-batches">
<L2TxnBatches/>
</Page>
</PageServer>
</PageNextJs>
);
};
export default TxnBatchesPage;
export default Page;
export { L2 as getServerSideProps } from 'lib/next/getServerSideProps';
export { L2 as getServerSideProps } from 'nextjs/getServerSideProps';
......@@ -2,21 +2,18 @@ import type { NextPage } from 'next';
import dynamic from 'next/dynamic';
import React from 'react';
import PageServer from 'lib/next/PageServer';
import Page from 'ui/shared/Page/Page';
import PageNextJs from 'nextjs/PageNextJs';
const L2Withdrawals = dynamic(() => import('ui/pages/L2Withdrawals'), { ssr: false });
const WithdrawalsPage: NextPage = () => {
const Page: NextPage = () => {
return (
<PageServer pathname="/l2-withdrawals">
<Page>
<PageNextJs pathname="/l2-withdrawals">
<L2Withdrawals/>
</Page>
</PageServer>
</PageNextJs>
);
};
export default WithdrawalsPage;
export default Page;
export { L2 as getServerSideProps } from 'lib/next/getServerSideProps';
export { L2 as getServerSideProps } from 'nextjs/getServerSideProps';
import type { NextPage } from 'next';
import React from 'react';
import PageServer from 'lib/next/PageServer';
import PageNextJs from 'nextjs/PageNextJs';
import Login from 'ui/pages/Login';
const LoginPage: NextPage = () => {
const Page: NextPage = () => {
return (
<PageServer pathname="/login">
<PageNextJs pathname="/login">
<Login/>
</PageServer>
</PageNextJs>
);
};
export default LoginPage;
export default Page;
export { base as getServerSideProps } from 'lib/next/getServerSideProps';
export { base as getServerSideProps } from 'nextjs/getServerSideProps';
import type { NextPage } from 'next';
import dynamic from 'next/dynamic';
import React from 'react';
import type { Props } from 'lib/next/getServerSideProps';
import PageServer from 'lib/next/PageServer';
import type { NextPageWithLayout } from 'nextjs/types';
import type { Props } from 'nextjs/getServerSideProps';
import PageNextJs from 'nextjs/PageNextJs';
import LayoutSearchResults from 'ui/shared/layout/LayoutSearchResults';
const SearchResults = dynamic(() => import('ui/pages/SearchResults'), { ssr: false });
const SearchResultsPage: NextPage<Props> = (props: Props) => {
const Page: NextPageWithLayout<Props> = (props: Props) => {
return (
<PageServer pathname="/search-results" query={ props }>
<PageNextJs pathname="/search-results" query={ props }>
<SearchResults/>
</PageServer>
</PageNextJs>
);
};
Page.getLayout = function getLayout(page: React.ReactElement) {
return (
<LayoutSearchResults>
{ page }
</LayoutSearchResults>
);
};
export default SearchResultsPage;
export default Page;
export { base as getServerSideProps } from 'lib/next/getServerSideProps';
export { base as getServerSideProps } from 'nextjs/getServerSideProps';
import type { NextPage } from 'next';
import React from 'react';
import PageServer from 'lib/next/PageServer';
import PageNextJs from 'nextjs/PageNextJs';
import Stats from '../ui/pages/Stats';
import Stats from 'ui/pages/Stats';
const StatsPage: NextPage = () => {
const Page: NextPage = () => {
return (
<PageServer pathname="/stats">
<PageNextJs pathname="/stats">
<Stats/>
</PageServer>
</PageNextJs>
);
};
export default StatsPage;
export default Page;
export { stats as getServerSideProps } from 'lib/next/getServerSideProps';
export { stats as getServerSideProps } from 'nextjs/getServerSideProps';
......@@ -2,22 +2,19 @@ import type { NextPage } from 'next';
import dynamic from 'next/dynamic';
import React from 'react';
import type { Props } from 'lib/next/getServerSideProps';
import PageServer from 'lib/next/PageServer';
import Page from 'ui/shared/Page/Page';
import type { Props } from 'nextjs/getServerSideProps';
import PageNextJs from 'nextjs/PageNextJs';
const Token = dynamic(() => import('ui/pages/Token'), { ssr: false });
const TokenPage: NextPage<Props> = (props: Props) => {
const Page: NextPage<Props> = (props: Props) => {
return (
<PageServer pathname="/token/[hash]" query={ props }>
<Page>
<PageNextJs pathname="/token/[hash]" query={ props }>
<Token/>
</Page>
</PageServer>
</PageNextJs>
);
};
export default TokenPage;
export default Page;
export { base as getServerSideProps } from 'lib/next/getServerSideProps';
export { base as getServerSideProps } from 'nextjs/getServerSideProps';
......@@ -2,22 +2,19 @@ import type { NextPage } from 'next';
import dynamic from 'next/dynamic';
import React from 'react';
import type { Props } from 'lib/next/getServerSideProps';
import PageServer from 'lib/next/PageServer';
import Page from 'ui/shared/Page/Page';
import type { Props } from 'nextjs/getServerSideProps';
import PageNextJs from 'nextjs/PageNextJs';
const TokenInstance = dynamic(() => import('ui/pages/TokenInstance'), { ssr: false });
const TokenInstancePage: NextPage<Props> = (props: Props) => {
const Page: NextPage<Props> = (props: Props) => {
return (
<PageServer pathname="/token/[hash]/instance/[id]" query={ props }>
<Page>
<PageNextJs pathname="/token/[hash]/instance/[id]" query={ props }>
<TokenInstance/>
</Page>
</PageServer>
</PageNextJs>
);
};
export default TokenInstancePage;
export default Page;
export { base as getServerSideProps } from 'lib/next/getServerSideProps';
export { base as getServerSideProps } from 'nextjs/getServerSideProps';
......@@ -2,21 +2,18 @@ import type { NextPage } from 'next';
import dynamic from 'next/dynamic';
import React from 'react';
import PageServer from 'lib/next/PageServer';
import Page from 'ui/shared/Page/Page';
import PageNextJs from 'nextjs/PageNextJs';
const Tokens = dynamic(() => import('ui/pages/Tokens'), { ssr: false });
const TokensPage: NextPage = () => {
const Page: NextPage = () => {
return (
<PageServer pathname="/tokens">
<Page>
<PageNextJs pathname="/tokens">
<Tokens/>
</Page>
</PageServer>
</PageNextJs>
);
};
export default TokensPage;
export default Page;
export { base as getServerSideProps } from 'lib/next/getServerSideProps';
export { base as getServerSideProps } from 'nextjs/getServerSideProps';
......@@ -2,22 +2,19 @@ import type { NextPage } from 'next';
import dynamic from 'next/dynamic';
import React from 'react';
import type { Props } from 'lib/next/getServerSideProps';
import PageServer from 'lib/next/PageServer';
import Page from 'ui/shared/Page/Page';
import type { Props } from 'nextjs/getServerSideProps';
import PageNextJs from 'nextjs/PageNextJs';
const Transaction = dynamic(() => import('ui/pages/Transaction'), { ssr: false });
const TransactionPage: NextPage<Props> = (props: Props) => {
const Page: NextPage<Props> = (props: Props) => {
return (
<PageServer pathname="/tx/[hash]" query={ props }>
<Page>
<PageNextJs pathname="/tx/[hash]" query={ props }>
<Transaction/>
</Page>
</PageServer>
</PageNextJs>
);
};
export default TransactionPage;
export default Page;
export { base as getServerSideProps } from 'lib/next/getServerSideProps';
export { base as getServerSideProps } from 'nextjs/getServerSideProps';
......@@ -2,21 +2,18 @@ import type { NextPage } from 'next';
import dynamic from 'next/dynamic';
import React from 'react';
import PageServer from 'lib/next/PageServer';
import Page from 'ui/shared/Page/Page';
import PageNextJs from 'nextjs/PageNextJs';
const Transactions = dynamic(() => import('ui/pages/Transactions'), { ssr: false });
const TxsPage: NextPage = () => {
const Page: NextPage = () => {
return (
<PageServer pathname="/txs">
<Page>
<PageNextJs pathname="/txs">
<Transactions/>
</Page>
</PageServer>
</PageNextJs>
);
};
export default TxsPage;
export default Page;
export { base as getServerSideProps } from 'lib/next/getServerSideProps';
export { base as getServerSideProps } from 'nextjs/getServerSideProps';
......@@ -2,21 +2,18 @@ import type { NextPage } from 'next';
import dynamic from 'next/dynamic';
import React from 'react';
import PageServer from 'lib/next/PageServer';
import Page from 'ui/shared/Page/Page';
import PageNextJs from 'nextjs/PageNextJs';
const VerifiedContracts = dynamic(() => import('ui/pages/VerifiedContracts'), { ssr: false });
const VerifiedContractsPage: NextPage = () => {
const Page: NextPage = () => {
return (
<PageServer pathname="/verified-contracts">
<Page>
<PageNextJs pathname="/verified-contracts">
<VerifiedContracts/>
</Page>
</PageServer>
</PageNextJs>
);
};
export default VerifiedContractsPage;
export default Page;
export { base as getServerSideProps } from 'lib/next/getServerSideProps';
export { base as getServerSideProps } from 'nextjs/getServerSideProps';
import type { NextPage } from 'next';
import React from 'react';
import PageServer from 'lib/next/PageServer';
import PageNextJs from 'nextjs/PageNextJs';
import Sol2Uml from 'ui/pages/Sol2Uml';
const Sol2UmlPage: NextPage = () => {
const Page: NextPage = () => {
return (
<PageServer pathname="/visualize/sol2uml">
<PageNextJs pathname="/visualize/sol2uml">
<Sol2Uml/>
</PageServer>
</PageNextJs>
);
};
export default Sol2UmlPage;
export default Page;
export { base as getServerSideProps } from 'lib/next/getServerSideProps';
export { base as getServerSideProps } from 'nextjs/getServerSideProps';
......@@ -2,21 +2,18 @@ import type { NextPage } from 'next';
import dynamic from 'next/dynamic';
import React from 'react';
import PageServer from 'lib/next/PageServer';
import Page from 'ui/shared/Page/Page';
import PageNextJs from 'nextjs/PageNextJs';
const Withdrawals = dynamic(() => import('ui/pages/Withdrawals'), { ssr: false });
const WithdrawalsPage: NextPage = () => {
const Page: NextPage = () => {
return (
<PageServer pathname="/withdrawals">
<Page>
<PageNextJs pathname="/withdrawals">
<Withdrawals/>
</Page>
</PageServer>
</PageNextJs>
);
};
export default WithdrawalsPage;
export default Page;
export { beaconChain as getServerSideProps } from 'lib/next/getServerSideProps';
export { beaconChain as getServerSideProps } from 'nextjs/getServerSideProps';
......@@ -5,8 +5,9 @@ import React from 'react';
import { configureChains, createConfig, WagmiConfig } from 'wagmi';
import { mainnet } from 'wagmi/chains';
import type { Props as PageProps } from 'nextjs/getServerSideProps';
import { AppContextProvider } from 'lib/contexts/app';
import type { Props as PageProps } from 'lib/next/getServerSideProps';
import { SocketProvider } from 'lib/socket/context';
import * as app from 'playwright/utils/app';
import theme from 'theme';
......
......@@ -8,3 +8,14 @@ export const viewport = {
export const maskColor = '#4299E1'; // blue.400
export const adsBannerSelector = '.adsbyslise';
export const featureEnvs = {
beaconChain: [
{ name: 'NEXT_PUBLIC_HAS_BEACON_CHAIN', value: 'true' },
],
rollup: [
{ name: 'NEXT_PUBLIC_IS_L2_NETWORK', value: 'true' },
{ name: 'NEXT_PUBLIC_L1_BASE_URL', value: 'https://localhost:3101' },
{ name: 'NEXT_PUBLIC_L2_WITHDRAWAL_URL', value: 'https://localhost:3102' },
],
};
import type { Route } from 'nextjs-routes';
import type React from 'react';
import type { Route } from 'nextjs-routes';
type NavIconOrComponent = {
icon?: React.FunctionComponent<React.SVGAttributes<SVGElement>>;
} | {
......
import { chakra, Icon, Tooltip, Hide, Skeleton, Flex } from '@chakra-ui/react';
import { route } from 'nextjs-routes';
import React from 'react';
import type { CsvExportParams } from 'types/client/address';
import { route } from 'nextjs-routes';
import config from 'configs/app';
import svgFileIcon from 'icons/files/csv.svg';
import useIsInitialLoading from 'lib/hooks/useIsInitialLoading';
......
import { Box, Text, Grid, Skeleton } from '@chakra-ui/react';
import type { UseQueryResult } from '@tanstack/react-query';
import { useRouter } from 'next/router';
import { route } from 'nextjs-routes';
import React from 'react';
import type { Address as TAddress } from 'types/api/address';
import { route } from 'nextjs-routes';
import blockIcon from 'icons/block.svg';
import type { ResourceError } from 'lib/api/resources';
import useApiQuery from 'lib/api/useApiQuery';
......
import { Flex, Skeleton } from '@chakra-ui/react';
import BigNumber from 'bignumber.js';
import { route } from 'nextjs-routes';
import React from 'react';
import type { Block } from 'types/api/block';
import { route } from 'nextjs-routes';
import config from 'configs/app';
import getBlockTotalReward from 'lib/block/getBlockTotalReward';
import useTimeAgoIncrement from 'lib/hooks/useTimeAgoIncrement';
......
import { Td, Tr, Flex, Skeleton } from '@chakra-ui/react';
import BigNumber from 'bignumber.js';
import { route } from 'nextjs-routes';
import React from 'react';
import type { Block } from 'types/api/block';
import { route } from 'nextjs-routes';
import getBlockTotalReward from 'lib/block/getBlockTotalReward';
import useTimeAgoIncrement from 'lib/hooks/useTimeAgoIncrement';
import LinkInternal from 'ui/shared/LinkInternal';
......
import { Text, Stat, StatHelpText, StatArrow, Flex, Skeleton } from '@chakra-ui/react';
import BigNumber from 'bignumber.js';
import { route } from 'nextjs-routes';
import React from 'react';
import type { AddressCoinBalanceHistoryItem } from 'types/api/address';
import { route } from 'nextjs-routes';
import config from 'configs/app';
import { WEI, ZERO } from 'lib/consts';
import useTimeAgoIncrement from 'lib/hooks/useTimeAgoIncrement';
......
import { Td, Tr, Text, Stat, StatHelpText, StatArrow, Skeleton } from '@chakra-ui/react';
import BigNumber from 'bignumber.js';
import { route } from 'nextjs-routes';
import React from 'react';
import type { AddressCoinBalanceHistoryItem } from 'types/api/address';
import { route } from 'nextjs-routes';
import { WEI, ZERO } from 'lib/consts';
import useTimeAgoIncrement from 'lib/hooks/useTimeAgoIncrement';
import Address from 'ui/shared/address/Address';
......
import { Flex, Skeleton, Button, Grid, GridItem, Alert, Link, chakra, Box } from '@chakra-ui/react';
import { useQueryClient } from '@tanstack/react-query';
import { route } from 'nextjs-routes';
import React from 'react';
import type { SocketMessage } from 'lib/socket/types';
import type { Address as AddressInfo } from 'types/api/address';
import { route } from 'nextjs-routes';
import useApiQuery, { getResourceKey } from 'lib/api/useApiQuery';
import dayjs from 'lib/date/dayjs';
import useSocketChannel from 'lib/socket/useSocketChannel';
......
import { AccordionButton, AccordionIcon, AccordionItem, AccordionPanel, Box, Icon, Tooltip, useClipboard, useDisclosure } from '@chakra-ui/react';
import { route } from 'nextjs-routes';
import React from 'react';
import { Element } from 'react-scroll';
import type { SmartContractMethod } from 'types/api/contract';
import { route } from 'nextjs-routes';
import config from 'configs/app';
import iconLink from 'icons/link.svg';
import Hint from 'ui/shared/Hint';
......
import { Box, Flex, Select, Skeleton, Text, Tooltip } from '@chakra-ui/react';
import { route } from 'nextjs-routes';
import React from 'react';
import type { SmartContract } from 'types/api/contract';
import type { ArrayElement } from 'types/utils';
import { route } from 'nextjs-routes';
import useApiQuery from 'lib/api/useApiQuery';
import * as stubs from 'stubs/contract';
import CopyToClipboard from 'ui/shared/CopyToClipboard';
......
import { Box, chakra, Spinner } from '@chakra-ui/react';
import { route } from 'nextjs-routes';
import React from 'react';
import type { ContractMethodWriteResult } from './types';
import { route } from 'nextjs-routes';
import LinkInternal from 'ui/shared/LinkInternal';
interface Props {
......
import { Skeleton } from '@chakra-ui/react';
import type { UseQueryResult } from '@tanstack/react-query';
import BigNumber from 'bignumber.js';
import { route } from 'nextjs-routes';
import React from 'react';
import type { AddressCounters } from 'types/api/address';
import { route } from 'nextjs-routes';
import LinkInternal from 'ui/shared/LinkInternal';
interface Props {
......
import { Flex, Box, HStack, Skeleton } from '@chakra-ui/react';
import BigNumber from 'bignumber.js';
import { route } from 'nextjs-routes';
import React from 'react';
import type { InternalTransaction } from 'types/api/internalTransaction';
import { route } from 'nextjs-routes';
import config from 'configs/app';
import eastArrowIcon from 'icons/arrows/east.svg';
import dayjs from 'lib/date/dayjs';
......
import { Tr, Td, Box, Flex, Skeleton } from '@chakra-ui/react';
import BigNumber from 'bignumber.js';
import { route } from 'nextjs-routes';
import React from 'react';
import type { InternalTransaction } from 'types/api/internalTransaction';
import { route } from 'nextjs-routes';
import config from 'configs/app';
import rightArrowIcon from 'icons/arrows/east.svg';
import useTimeAgoIncrement from 'lib/hooks/useTimeAgoIncrement';
......
import { chakra, Flex, Text, useColorModeValue } from '@chakra-ui/react';
import BigNumber from 'bignumber.js';
import { route } from 'nextjs-routes';
import React from 'react';
import { route } from 'nextjs-routes';
import TokenSnippet from 'ui/shared/TokenSnippet/TokenSnippet';
import TruncatedValue from 'ui/shared/TruncatedValue';
......
import { Flex, Link, Text, LinkBox, LinkOverlay, useColorModeValue, Skeleton } from '@chakra-ui/react';
import { route } from 'nextjs-routes';
import React from 'react';
import type { AddressTokenBalance } from 'types/api/address';
import { route } from 'nextjs-routes';
import NftMedia from 'ui/shared/nft/NftMedia';
import TokenLogo from 'ui/shared/TokenLogo';
import TruncatedTextTooltip from 'ui/shared/TruncatedTextTooltip';
......
import { Alert, Box, Button, Flex } from '@chakra-ui/react';
import { route } from 'nextjs-routes';
import React from 'react';
import type { SubmitHandler } from 'react-hook-form';
import { useForm } from 'react-hook-form';
......@@ -12,6 +11,8 @@ import type {
RootFields,
} from '../types';
import { route } from 'nextjs-routes';
import config from 'configs/app';
import type { ResourceError } from 'lib/api/resources';
import useApiFetch from 'lib/api/useApiFetch';
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment