diff --git a/package.json b/package.json index 0c63f995b..ee991b94a 100644 --- a/package.json +++ b/package.json @@ -89,6 +89,7 @@ "react": "18.2.0", "react-aria": "3.27.0", "react-cookie": "6.1.0", + "react-countup": "^6.4.2", "react-csv": "2.2.2", "react-dom": "18.2.0", "react-error-boundary": "4.0.11", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f67e263b9..447e719cc 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -203,6 +203,9 @@ dependencies: react-cookie: specifier: 6.1.0 version: 6.1.0(react@18.2.0) + react-countup: + specifier: ^6.4.2 + version: 6.4.2(@babel/core@7.20.12)(react@18.2.0) react-csv: specifier: 2.2.2 version: 2.2.2 @@ -476,7 +479,7 @@ packages: '@babel/parser': 7.20.13 '@babel/template': 7.20.7 '@babel/traverse': 7.20.13 - '@babel/types': 7.20.7 + '@babel/types': 7.23.0 convert-source-map: 1.8.0 debug: 4.3.4 gensync: 1.0.0-beta.2 @@ -502,7 +505,7 @@ packages: '@babel/parser': 7.20.13 '@babel/template': 7.20.7 '@babel/traverse': 7.20.13 - '@babel/types': 7.20.7 + '@babel/types': 7.23.0 convert-source-map: 1.8.0 debug: 4.3.4 gensync: 1.0.0-beta.2 @@ -538,7 +541,7 @@ packages: resolution: {integrity: sha512-oLcVCTeIFadUoArDTwpluncplrYBmTCCZZgXCbgNGvOBBiSDDK3eWO4b/+eOTli5tKv1lg+a5/NAXg+nTcei1w==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.20.7 + '@babel/types': 7.23.0 jsesc: 2.5.2 source-map: 0.5.7 dev: true @@ -555,7 +558,7 @@ packages: resolution: {integrity: sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.20.7 + '@babel/types': 7.23.0 dev: true /@babel/helper-builder-binary-assignment-operator-visitor@7.18.9: @@ -563,7 +566,7 @@ packages: engines: {node: '>=6.9.0'} dependencies: '@babel/helper-explode-assignable-expression': 7.18.6 - '@babel/types': 7.20.7 + '@babel/types': 7.23.0 dev: true /@babel/helper-compilation-targets@7.20.7(@babel/core@7.17.8): @@ -665,7 +668,7 @@ packages: resolution: {integrity: sha512-eyAYAsQmB80jNfg4baAtLeWAQHfHFiR483rzFK+BhETlGZaQC9bsfrugfXDCbRHLQbIA7U5NxhhOxN7p/dWIcg==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.20.7 + '@babel/types': 7.23.0 dev: true /@babel/helper-function-name@7.19.0: @@ -673,26 +676,26 @@ packages: engines: {node: '>=6.9.0'} dependencies: '@babel/template': 7.20.7 - '@babel/types': 7.20.7 + '@babel/types': 7.23.0 /@babel/helper-hoist-variables@7.18.6: resolution: {integrity: sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.20.7 + '@babel/types': 7.23.0 /@babel/helper-member-expression-to-functions@7.20.7: resolution: {integrity: sha512-9J0CxJLq315fEdi4s7xK5TQaNYjZw+nDVpVqr1axNGKzdrdwYBD5b4uKv3n75aABG0rCCTK8Im8Ww7eYfMrZgw==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.20.7 + '@babel/types': 7.23.0 dev: true /@babel/helper-module-imports@7.18.6: resolution: {integrity: sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.20.7 + '@babel/types': 7.23.0 /@babel/helper-module-transforms@7.20.11: resolution: {integrity: sha512-uRy78kN4psmji1s2QtbtcCSaj/LILFDp0f/ymhpQH5QY3nljUZCaNWz9X1dEj/8MBdBEFECs7yRhKn8i7NjZgg==} @@ -713,7 +716,7 @@ packages: resolution: {integrity: sha512-HP59oD9/fEHQkdcbgFCnbmgH5vIQTJbxh2yf+CdM89/glUNnuzr87Q8GIjGEnOktTROemO0Pe0iPAYbqZuOUiA==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.20.7 + '@babel/types': 7.23.0 dev: true /@babel/helper-plugin-utils@7.10.4: @@ -735,7 +738,7 @@ packages: '@babel/helper-annotate-as-pure': 7.18.6 '@babel/helper-environment-visitor': 7.18.9 '@babel/helper-wrap-function': 7.20.5 - '@babel/types': 7.20.7 + '@babel/types': 7.23.0 transitivePeerDependencies: - supports-color dev: true @@ -749,7 +752,7 @@ packages: '@babel/helper-optimise-call-expression': 7.18.6 '@babel/template': 7.20.7 '@babel/traverse': 7.20.13 - '@babel/types': 7.20.7 + '@babel/types': 7.23.0 transitivePeerDependencies: - supports-color dev: true @@ -758,20 +761,20 @@ packages: resolution: {integrity: sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.20.7 + '@babel/types': 7.23.0 /@babel/helper-skip-transparent-expression-wrappers@7.20.0: resolution: {integrity: sha512-5y1JYeNKfvnT8sZcK9DVRtpTbGiomYIHviSP3OQWmDPU3DeH4a1ZlT/N2lyQ5P8egjcRaT/Y9aNqUxK0WsnIIg==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.20.7 + '@babel/types': 7.23.0 dev: true /@babel/helper-split-export-declaration@7.18.6: resolution: {integrity: sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.20.7 + '@babel/types': 7.23.0 /@babel/helper-string-parser@7.19.4: resolution: {integrity: sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==} @@ -780,7 +783,6 @@ packages: /@babel/helper-string-parser@7.22.5: resolution: {integrity: sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==} engines: {node: '>=6.9.0'} - dev: true /@babel/helper-validator-identifier@7.19.1: resolution: {integrity: sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==} @@ -789,7 +791,6 @@ packages: /@babel/helper-validator-identifier@7.22.20: resolution: {integrity: sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==} engines: {node: '>=6.9.0'} - dev: true /@babel/helper-validator-option@7.18.6: resolution: {integrity: sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==} @@ -802,7 +803,7 @@ packages: '@babel/helper-function-name': 7.19.0 '@babel/template': 7.20.7 '@babel/traverse': 7.20.13 - '@babel/types': 7.20.7 + '@babel/types': 7.23.0 transitivePeerDependencies: - supports-color dev: true @@ -821,7 +822,7 @@ packages: resolution: {integrity: sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==} engines: {node: '>=6.9.0'} dependencies: - '@babel/helper-validator-identifier': 7.19.1 + '@babel/helper-validator-identifier': 7.22.20 chalk: 2.4.2 js-tokens: 4.0.0 @@ -838,7 +839,7 @@ packages: resolution: {integrity: sha512-9uJveS9eY9DJ0t64YbIBZICtJy8a5QrDEVdiLCG97fVLpDTpGX7t8mMSb6OWw6Lrnjqj4O8zwjELX3dhoMgiBg==} engines: {node: '>=6.0.0'} dependencies: - '@babel/types': 7.20.7 + '@babel/types': 7.23.0 dev: true /@babel/parser@7.20.13: @@ -1531,7 +1532,7 @@ packages: '@babel/helper-hoist-variables': 7.18.6 '@babel/helper-module-transforms': 7.20.11 '@babel/helper-plugin-utils': 7.20.2 - '@babel/helper-validator-identifier': 7.19.1 + '@babel/helper-validator-identifier': 7.22.20 transitivePeerDependencies: - supports-color dev: true @@ -1644,7 +1645,7 @@ packages: '@babel/helper-module-imports': 7.18.6 '@babel/helper-plugin-utils': 7.20.2 '@babel/plugin-syntax-jsx': 7.18.6(@babel/core@7.20.12) - '@babel/types': 7.20.7 + '@babel/types': 7.23.0 dev: true /@babel/plugin-transform-react-pure-annotations@7.18.6(@babel/core@7.20.12): @@ -1841,7 +1842,7 @@ packages: '@babel/plugin-transform-unicode-escapes': 7.18.10(@babel/core@7.20.12) '@babel/plugin-transform-unicode-regex': 7.18.6(@babel/core@7.20.12) '@babel/preset-modules': 0.1.5(@babel/core@7.20.12) - '@babel/types': 7.20.7 + '@babel/types': 7.23.0 babel-plugin-polyfill-corejs2: 0.3.3(@babel/core@7.20.12) babel-plugin-polyfill-corejs3: 0.6.0(@babel/core@7.20.12) babel-plugin-polyfill-regenerator: 0.4.1(@babel/core@7.20.12) @@ -1872,7 +1873,7 @@ packages: '@babel/helper-plugin-utils': 7.20.2 '@babel/plugin-proposal-unicode-property-regex': 7.18.6(@babel/core@7.20.12) '@babel/plugin-transform-dotall-regex': 7.18.6(@babel/core@7.20.12) - '@babel/types': 7.20.7 + '@babel/types': 7.23.0 esutils: 2.0.3 dev: true @@ -1971,7 +1972,7 @@ packages: '@babel/helper-hoist-variables': 7.18.6 '@babel/helper-split-export-declaration': 7.18.6 '@babel/parser': 7.20.13 - '@babel/types': 7.20.7 + '@babel/types': 7.23.0 debug: 4.3.4 globals: 11.12.0 transitivePeerDependencies: @@ -1999,7 +2000,7 @@ packages: resolution: {integrity: sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw==} engines: {node: '>=6.9.0'} dependencies: - '@babel/helper-validator-identifier': 7.19.1 + '@babel/helper-validator-identifier': 7.22.20 to-fast-properties: 2.0.0 dev: true @@ -2018,7 +2019,6 @@ packages: '@babel/helper-string-parser': 7.22.5 '@babel/helper-validator-identifier': 7.22.20 to-fast-properties: 2.0.0 - dev: true /@base2/pretty-print-object@1.0.1: resolution: {integrity: sha512-4iri8i1AqYHJE2DstZYkyEprg6Pq6sKx3xn5FpySk9sNhH7qN2LLlHJCfDTZRILNwQNPD7mATWM0TBui7uC1pA==} @@ -5729,6 +5729,24 @@ packages: reselect: 4.1.8 dev: false + /@rollup/plugin-babel@6.0.4(@babel/core@7.20.12): + resolution: {integrity: sha512-YF7Y52kFdFT/xVSuVdjkV5ZdX/3YtmX0QulG+x0taQOtJdHYzVU61aSSkAgVJ7NOv6qPkIYiJSgSWWN/DM5sGw==} + engines: {node: '>=14.0.0'} + peerDependencies: + '@babel/core': ^7.0.0 + '@types/babel__core': ^7.1.9 + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + '@types/babel__core': + optional: true + rollup: + optional: true + dependencies: + '@babel/core': 7.20.12 + '@babel/helper-module-imports': 7.18.6 + '@rollup/pluginutils': 5.0.2(rollup@2.78.0) + dev: false + /@rollup/plugin-commonjs@24.0.0(rollup@2.78.0): resolution: {integrity: sha512-0w0wyykzdyRRPHOb0cQt14mIBLujfAv6GgP6g8nvg/iBxEm112t3YPPq+Buqe2+imvElTka+bjNlJ/gB56TD8g==} engines: {node: '>=14.0.0'} @@ -7074,7 +7092,7 @@ packages: '@babel/plugin-transform-react-jsx': 7.20.13(@babel/core@7.20.12) '@babel/preset-env': 7.20.2(@babel/core@7.20.12) '@babel/traverse': 7.20.13 - '@babel/types': 7.20.7 + '@babel/types': 7.23.0 '@storybook/csf': 0.0.2--canary.4566f4d.1 '@storybook/mdx1-csf': 0.0.1(@babel/core@7.20.12) core-js: 3.27.2 @@ -7248,7 +7266,7 @@ packages: '@babel/generator': 7.20.7 '@babel/parser': 7.20.13 '@babel/preset-env': 7.20.2(@babel/core@7.20.12) - '@babel/types': 7.20.7 + '@babel/types': 7.23.0 '@mdx-js/mdx': 1.6.22 '@types/lodash': 4.14.191 js-string-escape: 1.0.1 @@ -7754,7 +7772,7 @@ packages: resolution: {integrity: sha512-WEOTgRsbYkvA/KCsDwVEGkd7WAr1e3g31VHQ8zy5gul/V1qKullU/BU5I68X5v7V3GnB9eotmom4v5a5gjxorw==} dependencies: '@babel/parser': 7.20.13 - '@babel/types': 7.20.7 + '@babel/types': 7.23.0 '@types/babel__generator': 7.6.4 '@types/babel__template': 7.4.1 '@types/babel__traverse': 7.18.0 @@ -7763,20 +7781,20 @@ packages: /@types/babel__generator@7.6.4: resolution: {integrity: sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==} dependencies: - '@babel/types': 7.20.7 + '@babel/types': 7.23.0 dev: true /@types/babel__template@7.4.1: resolution: {integrity: sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==} dependencies: '@babel/parser': 7.20.13 - '@babel/types': 7.20.7 + '@babel/types': 7.23.0 dev: true /@types/babel__traverse@7.18.0: resolution: {integrity: sha512-v4Vwdko+pgymgS+A2UIaJru93zQd85vIGWObM5ekZNdXCKtDYqATlEYnWgfo86Q6I1Lh0oXnksDnMU1cwmlPDw==} dependencies: - '@babel/types': 7.20.7 + '@babel/types': 7.23.0 dev: true /@types/bn.js@5.1.2: @@ -9421,7 +9439,7 @@ packages: engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} dependencies: '@babel/template': 7.20.7 - '@babel/types': 7.20.7 + '@babel/types': 7.23.0 '@types/babel__core': 7.1.19 '@types/babel__traverse': 7.18.0 dev: true @@ -10514,6 +10532,10 @@ packages: path-type: 4.0.0 yaml: 1.10.2 + /countup.js@2.8.0: + resolution: {integrity: sha512-f7xEhX0awl4NOElHulrl4XRfKoNH3rB+qfNSZZyjSZhaAoUk6elvhH+MNxMmlmuUJ2/QNTWPSA7U4mNtIAKljQ==} + dev: false + /cp-file@7.0.0: resolution: {integrity: sha512-0Cbj7gyvFVApzpK/uhCtQ/9kE9UnYpxMzaq5nQQC/Dh4iaj5fxp7iEFIullrYwzj8nf0qnsI1Qsx34hAeAebvw==} engines: {node: '>=8'} @@ -11795,7 +11817,7 @@ packages: engines: {node: '>=8.3.0'} dependencies: '@babel/traverse': 7.20.13 - '@babel/types': 7.20.7 + '@babel/types': 7.23.0 c8: 7.12.0 transitivePeerDependencies: - supports-color @@ -14298,7 +14320,7 @@ packages: '@babel/generator': 7.20.7 '@babel/plugin-syntax-typescript': 7.20.0(@babel/core@7.20.12) '@babel/traverse': 7.20.13 - '@babel/types': 7.20.7 + '@babel/types': 7.23.0 '@jest/expect-utils': 28.1.3 '@jest/transform': 28.1.3 '@jest/types': 28.1.3 @@ -16870,6 +16892,20 @@ packages: universal-cookie: 6.1.1 dev: false + /react-countup@6.4.2(@babel/core@7.20.12)(react@18.2.0): + resolution: {integrity: sha512-wdDrNb2lPFGbLb+i0FTgswPbWziubS6KZRII8NRpXmUCoZsi15PFbIHgBz60Dyxd4KPuRvwsK5aawIU4OPP3jA==} + peerDependencies: + react: '>= 16.3.0' + dependencies: + '@rollup/plugin-babel': 6.0.4(@babel/core@7.20.12) + countup.js: 2.8.0 + react: 18.2.0 + transitivePeerDependencies: + - '@babel/core' + - '@types/babel__core' + - rollup + dev: false + /react-csv@2.2.2: resolution: {integrity: sha512-RG5hOcZKZFigIGE8LxIEV/OgS1vigFQT4EkaHeKgyuCbUAu9Nbd/1RYq++bJcJJ9VOqO/n9TZRADsXNDR4VEpw==} dev: false diff --git a/src/app/HomeClient.tsx b/src/app/HomeClient.tsx index 536213770..958a7c37d 100644 --- a/src/app/HomeClient.tsx +++ b/src/app/HomeClient.tsx @@ -8,14 +8,19 @@ import * as React from 'react'; import { FC } from 'react'; import { DefaultTxListTabs } from './common/components/tx-lists/tabs/DefaultTxListTabs'; -import { BlocksList } from './components/BlockList'; +import { BlockList } from '@/features/blocks/components/BlockList'; import { Stats } from './stats/Stats'; export const HomeClientBase: FC = () => { console.log('[DEBUG] rendering home'); const { activeNetwork } = useGlobalContext(); return ( - + { {!activeNetwork.isSubnet && } - + + ); }; diff --git a/src/common/constants.ts b/src/common/constants.ts index 9e190d4eb..b282f547d 100644 --- a/src/common/constants.ts +++ b/src/common/constants.ts @@ -2,6 +2,7 @@ import { Transaction } from '@stacks/stacks-blockchain-api-types'; import packageJson from '../../package.json'; import { TxStatus } from './types/tx'; +import { NetworkModes } from '@/common/types/network'; export const MICROBLOCKS_ENABLED = true; @@ -111,3 +112,20 @@ export const SUBNETS_PARENT_NETWORK_IDS = { export const PAGE_MAX_WIDTH = '1280px'; export const REDIS_URL = process.env.REDIS_URL || ''; + +export const BLOCK_LIMIT: Record> = { + [NetworkModes.Mainnet]: { + write_length: 15_000_000, + write_count: 15_000, + read_length: 100_000_000, + read_count: 15_000, + runtime: 5_000_000_000, + }, + [NetworkModes.Testnet]: { + write_length: 15_0_000_000, + write_count: 5_0_000, + read_length: 1_000_000_000, + read_count: 5_0_000, + runtime: 100_000_000_000, + }, +}; diff --git a/src/components/section.tsx b/src/components/section.tsx index 94f563e09..b396c6159 100644 --- a/src/components/section.tsx +++ b/src/components/section.tsx @@ -62,3 +62,24 @@ export const Section: React.FC< ); } ); + +interface SectionWithControlsProps extends Omit { + title: string; + controls?: ReactNode; + footer?: ReactNode; +} + +export function SectionWithControls({ title, controls, footer }: SectionWithControlsProps) { + return ( + + + {title} + + {controls} + + + {footer} + + + ); +} diff --git a/src/features/block/useBlockFullness.ts b/src/features/block/useBlockFullness.ts new file mode 100644 index 000000000..0b276b104 --- /dev/null +++ b/src/features/block/useBlockFullness.ts @@ -0,0 +1,20 @@ +import { Block } from '@stacks/stacks-blockchain-api-types'; +import { BLOCK_LIMIT } from '@/common/constants'; +import { useGlobalContext } from '@/common/context/useAppContext'; + +export function useBlockFullness(block: Block) { + const network = useGlobalContext().activeNetwork; + const blockLimit = BLOCK_LIMIT[network.mode]; + const readCountFullness = block.execution_cost_read_count / blockLimit.read_count; + const readLengthFullness = block.execution_cost_read_length / blockLimit.read_length; + const runtimeFullness = block.execution_cost_runtime / blockLimit.runtime; + const writeCountFullness = block.execution_cost_write_count / blockLimit.write_count; + const writeLengthFullness = block.execution_cost_write_length / blockLimit.write_length; + return Math.max( + readCountFullness, + readLengthFullness, + runtimeFullness, + writeCountFullness, + writeLengthFullness + ); +} diff --git a/src/features/blocks-visualizer/index.tsx b/src/features/blocks-visualizer/index.tsx index 643220a11..ad9853b3a 100644 --- a/src/features/blocks-visualizer/index.tsx +++ b/src/features/blocks-visualizer/index.tsx @@ -14,6 +14,7 @@ import { TbCurrencyBitcoin } from 'react-icons/tb'; import { Block as BlockType } from '@stacks/stacks-blockchain-api-types'; import { useBlockListInfinite } from '../../app/common/queries/useBlockListInfinite'; +import { useBlockFullness } from '@/features/block/useBlockFullness'; const wrapperStyle = css` display: flex; @@ -196,6 +197,7 @@ const Block: React.FC = ({ const router = useRouter(); const network = useGlobalContext().activeNetwork; const colorMode = useColorMode().colorMode; + const blockFullness = useBlockFullness(block); return ( @@ -235,6 +237,9 @@ const Block: React.FC = ({ css={blockStyle} className={'block-box'} onClick={() => router.push(buildUrl(`/block/${encodeURIComponent(block.hash)}`, network))} + background={`linear-gradient(to right, var(--stacks-colors-brand-dark) ${ + Math.random() * 100 + }%, #d9d9d9 0);`} > {stxBlockHeight} diff --git a/src/features/blocks/components/BlockList.tsx b/src/features/blocks/components/BlockList.tsx new file mode 100644 index 000000000..8823b44f6 --- /dev/null +++ b/src/features/blocks/components/BlockList.tsx @@ -0,0 +1,207 @@ +import { SectionWithControls } from '@/components/section'; +import { Switch } from '@/ui/Switch'; +import { FormLabel } from '@/ui/FormLabel'; +import { FormControl } from '@/ui/FormControl'; +import React, { useEffect } from 'react'; +import { Stack } from '@/ui/Stack'; +import { Flex } from '@/ui/Flex'; +import { Text } from '@/ui/typography'; +import { Icon } from '@/ui/Icon'; +import { TfiReload } from 'react-icons/tfi'; +import { TextLink } from '@/ui/TextLink'; +import { useColorMode } from '@chakra-ui/react'; +import { keyframes } from '@emotion/css'; +import CountUp from 'react-countup'; +import { Button } from '@/ui/Button'; +import { HiOutlineHashtag } from 'react-icons/hi'; +import { BsGrid } from 'react-icons/bs'; +import { Tooltip } from '@/ui/Tooltip'; +import { HiMiniArrowUpRight } from 'react-icons/hi2'; + +const spin = keyframes` + from { transform: rotate(0deg); } + to { transform: rotate(360deg); } +`; + +export function BlockList() { + const colorMode = useColorMode().colorMode; + const [loading, setLoading] = React.useState(false); + const [oldBlocksCount, setOldBlocksCount] = React.useState(0); + const [newBlocksCount, setNewBlocksCount] = React.useState(16); + const [groupedByBtc, setGroupedByBtc] = React.useState(true); + const [liveUpdates, setLiveUpdates] = React.useState(false); + const [heightView, setHeightView] = React.useState(false); + const [blockView, setBlockView] = React.useState(true); + + useEffect(() => { + const intervalId = setInterval(() => { + setOldBlocksCount(newBlocksCount); + setNewBlocksCount(newBlocksCount + Math.floor(Math.random() * 50) + 3); + }, 5000); + + return () => { + clearInterval(intervalId); // Clear the interval when the component unmounts + }; + }, [newBlocksCount]); + return ( + + + + { + setGroupedByBtc(!groupedByBtc); + }} + isChecked={groupedByBtc} + /> + + Group by Bitcoin block + + + + + + + + + + + + + setLiveUpdates(!liveUpdates)} + isChecked={liveUpdates} + /> + + Live updates + + + + + + + {({ countUpRef, start }) => } + + {' '} + new Stacks blocks have come in + + { + console.log('clicked'); + setLoading(true); + setOldBlocksCount(newBlocksCount); + setNewBlocksCount(0); + setTimeout(() => { + setLoading(false); + }, 1250); + }} + > + + + Update + + + + + } + footer={ + <> + + + } + > + abc + + ); +} diff --git a/src/ui/Switch.tsx b/src/ui/Switch.tsx index abe674f3c..57a030dc5 100644 --- a/src/ui/Switch.tsx +++ b/src/ui/Switch.tsx @@ -18,6 +18,8 @@ export const Switch = forwardRef(({ children, size, ...rest minWidth={size || rest.minWidth} minHeight={size || rest.minHeight} borderColor={`border.${useColorMode().colorMode}`} + position={'relative'} + top={'1px'} {...rest} > {children}