Commit 0c9eb30e authored by Igor Stuev's avatar Igor Stuev Committed by GitHub

Merge pull request #79 from blockscout/network-menu

network menu
parents a10fff5f 77242a63
<svg width="30" height="30" fill="currentColor" xmlns="http://www.w3.org/2000/svg"><g clip-path="url(#a)"><path d="M10.176 10.291a1.253 1.253 0 0 0-1.76.159L5.29 14.2a1.247 1.247 0 0 0 0 1.6l3.125 3.75a1.25 1.25 0 1 0 1.919-1.6L7.876 15l2.459-2.949a1.25 1.25 0 0 0-.159-1.76ZM16.494 7.525a1.261 1.261 0 0 0-1.47.981l-2.5 12.5a1.246 1.246 0 0 0 1.229 1.494 1.249 1.249 0 0 0 1.223-1.006l2.5-12.5a1.246 1.246 0 0 0-.982-1.469ZM24.709 14.2l-3.125-3.75a1.251 1.251 0 0 0-2.209.687 1.25 1.25 0 0 0 .29.914l2.459 2.95-2.459 2.948a1.248 1.248 0 0 0 .584 2 1.25 1.25 0 0 0 1.335-.398l3.125-3.75a1.247 1.247 0 0 0 0-1.601Z"/></g><defs><clipPath id="a"><path fill="#fff" transform="translate(5 5)" d="M0 0h20v20H0z"/></clipPath></defs></svg> <svg width="30" height="30" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
\ No newline at end of file <g clip-path="url(#abi-a)">
<path d="M10.176 10.291a1.253 1.253 0 0 0-1.76.159L5.29 14.2a1.247 1.247 0 0 0 0 1.6l3.125 3.75a1.25 1.25 0 1 0 1.919-1.6L7.876 15l2.459-2.949a1.25 1.25 0 0 0-.159-1.76Zm6.318-2.766a1.261 1.261 0 0 0-1.47.981l-2.5 12.5a1.246 1.246 0 0 0 1.229 1.494 1.249 1.249 0 0 0 1.223-1.006l2.5-12.5a1.246 1.246 0 0 0-.982-1.469Zm8.215 6.675-3.125-3.75a1.251 1.251 0 0 0-2.209.687 1.25 1.25 0 0 0 .29.914l2.459 2.95-2.459 2.948a1.248 1.248 0 0 0 .584 2 1.25 1.25 0 0 0 1.335-.398l3.125-3.75a1.247 1.247 0 0 0 0-1.601Z"/>
</g>
<defs>
<clipPath id="abi-a">
<path fill="#fff" transform="translate(5 5)" d="M0 0h20v20H0z"/>
</clipPath>
</defs>
</svg>
\ No newline at end of file
<svg width="24" height="24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M9.293 14.465a1 1 0 0 0 1.414 0l7.778-7.78A1 1 0 0 1 19.899 8.1l-9.192 9.193a1 1 0 0 1-1.414 0l-4.95-4.95a1 1 0 0 1 1.414-1.414l3.536 3.536Z" fill="currentColor"/>
</svg>
\ No newline at end of file
<svg width="30" height="30" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M11.77 1H1v6.588h10.77V1ZM29 1H18.23v6.588H29V1Zm0 15.922h-6.462v5.49h-4.307V29H29V16.922Zm-21.538 0H1V29h10.77v-6.588H7.461v-5.49Z" fill="#48A9A6"/>
</svg>
\ No newline at end of file
<svg width="30" height="30" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M1 16.736 10 8.5m-9 8.236L11 23M1 16.736 6.283 3.528M1 16.736 8.925 27.83M10 8.5 20.547 3M10 8.5 6.283 3.528M20.547 3l2.642 11M20.547 3 29 13.566M20.547 3l-14.264.528M23.189 14v12.774m0-12.774L29 13.566m-5.811 13.208L11 23m12.189 3.774L8.925 27.83m14.264-1.056L29 13.566M11 23l-2.075 4.83m9.509-16.905h-6.868l4.226 4.226-4.226 4.755h6.868" stroke="#129C6B" stroke-width="1.4" stroke-linejoin="round"/>
</svg>
\ No newline at end of file
<svg width="30" height="30" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="30" height="30" rx="15" fill="#328332"/>
<path opacity=".6" d="M8.625 15.958c2.337 1.241 4.776 2.54 6.66 3.546l6.604-3.546c-2.391 3.553-4.384 6.51-6.605 9.784-2.224-3.266-4.681-6.87-6.659-9.784Zm.254-.98 6.413-3.422 6.329 3.397-6.326 3.426-6.416-3.401Zm6.405-4.518-6.659 3.506 6.63-9.708 6.634 9.73-6.605-3.528Z" fill="#fff"/>
<path opacity=".7" d="m15.284 19.504 6.605-3.546a7441.882 7441.882 0 0 1-6.605 9.784v-6.238Zm.008-7.948 6.329 3.397-6.326 3.426-.003-6.823Zm-.008-1.096-.029-6.202 6.634 9.73-6.605-3.528Z" fill="#fff"/>
<path opacity=".7" d="m8.88 14.978 6.412.526 6.33-.548-6.326 3.426-6.417-3.404Z" fill="#fff"/>
<path d="m15.292 15.504 6.33-.548-6.326 3.426-.004-2.878Z" fill="#fff"/>
</svg>
\ No newline at end of file
<svg width="30" height="30" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="30" height="30" rx="15" fill="#627EEA"/>
<path d="M15.305 12.153V4.088c-.013 0-.02.006-.03.012-.013.01-.028.022-.066.022-.254.497-.524.975-.799 1.462-.108.192-.218.385-.327.582-.515.9-1.03 1.834-1.544 2.768a141.5 141.5 0 0 1-.844 1.52c-.28.497-.558.994-.83 1.491-.257.468-.522.935-.787 1.402-.266.468-.531.935-.788 1.403-.048.085-.096.161-.143.238a5.99 5.99 0 0 0-.147.246h.032c.02.021.028.016.038.01.007-.005.014-.01.027-.01.112-.052.233-.112.353-.173.121-.06.242-.121.354-.173.307-.165.584-.298.86-.43l.041-.02 1.062-.52.868-.415 1.062-.519c.225-.135.47-.249.704-.358.067-.03.133-.061.197-.092.116-.053.223-.107.331-.16.101-.05.203-.101.312-.152.032 0 .064-.034.064-.069ZM15.277 25.997a.08.08 0 0 0 .029.003v-5.435c0-.035 0-.07-.033-.07a7.196 7.196 0 0 0-.257-.155c-.088-.052-.177-.104-.257-.156a93.415 93.415 0 0 0-1.499-.96 91.637 91.637 0 0 1-1.525-.979 187.64 187.64 0 0 0-1.32-.83c-.442-.277-.884-.554-1.318-.83-.017 0-.025-.01-.033-.018-.008-.009-.016-.017-.032-.017 0 .017.008.026.016.034.008.009.016.017.016.034l.483.727c.389.618.79 1.22 1.19 1.818.227.342.454.681.676 1.021l1.93 2.908c.311.469.615.93.918 1.39.324.492.648.983.98 1.483.019.02.027.029.036.032Z" fill="#fff"/>
<path d="M15.3 4v11.307h6.3L15.3 4ZM9 15.175l6.3-3.024v7.1L9 15.175ZM15.3 20.566v5.39l6.177-9.203-6.177 3.813Z" fill="#C0CBF6"/>
<path d="M15.3 19.251v-7.1l6.3 3.156-6.3 3.944Z" fill="#8197EE"/>
</svg>
\ No newline at end of file
<svg width="30" height="30" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M2.467 7.495c.046.041.084.073.12.107.377.365.75.734 1.133 1.095.085.081.086.137.024.23-.8 1.21-1.09 2.537-.824 3.943.358 1.886 1.456 3.26 3.248 4.089 1.06.489 2.183.614 3.338.443a5.646 5.646 0 0 0 2.166-.788c.11-.068.17-.06.26.028.974.958 1.955 1.91 2.928 2.87.108.105.163.117.28.004 1.112-1.087 2.234-2.166 3.347-3.254.122-.12.199-.14.36-.047.973.568 2.033.795 3.167.744 2.25-.102 4.305-1.625 5.003-3.716.528-1.583.332-3.086-.529-4.515-.056-.093-.06-.15.025-.231.314-.293.619-.594.928-.891.028-.028.06-.052.092-.079 3.297 4.694 3.762 12.244-1.543 17.803-5.495 5.758-14.563 6.206-20.618 1.264-6.149-5.02-6.88-13.26-2.905-19.1Z" fill="#276749"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M25.318 5.632C19.417-.21 9.822.285 4.703 5.4c.03.033.059.067.09.098 3.383 3.283 6.766 6.564 10.145 9.848.096.093.15.082.236-.004.437-.429.878-.853 1.319-1.277 2.852-2.745 5.705-5.49 8.559-8.232.076-.073.17-.13.266-.2Zm-10.27 11.786L2.685 5.4c.03-.038.054-.075.083-.107 1.488-1.598 3.215-2.89 5.23-3.81A16.24 16.24 0 0 1 11.432.358a16.717 16.717 0 0 1 4.154-.341c2.04.088 3.992.54 5.858 1.347 2.243.97 4.137 2.386 5.745 4.176.093.103.04.15-.032.219-2 1.925-3.998 3.85-5.996 5.776l-5.982 5.767c-.036.035-.074.068-.13.117ZM9.733 14.608c-.837.742-2.699.914-3.931-.278-1.237-1.197-1.067-2.966-.255-3.886l4.186 4.164ZM20.563 14.32l4.193-4.072c.59.64.863 2.272-.158 3.476-1.136 1.338-3.01 1.33-4.035.596Z" fill="#276749"/>
</svg>
\ No newline at end of file
<svg width="30" height="30" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M2.467 7.495c.046.041.084.073.12.107.377.365.75.734 1.133 1.095.085.081.086.137.024.23-.8 1.21-1.09 2.537-.824 3.943.358 1.886 1.456 3.26 3.248 4.089 1.06.489 2.183.614 3.338.443a5.646 5.646 0 0 0 2.166-.788c.11-.068.17-.06.26.028.974.958 1.955 1.91 2.928 2.87.108.105.163.117.28.004 1.112-1.087 2.234-2.166 3.347-3.254.122-.12.199-.14.36-.047.973.568 2.033.795 3.167.744 2.25-.102 4.305-1.625 5.003-3.716.528-1.583.332-3.086-.529-4.515-.056-.093-.06-.15.025-.231.314-.293.619-.594.928-.891.028-.028.06-.052.092-.079 3.297 4.694 3.762 12.244-1.543 17.803-5.495 5.758-14.563 6.206-20.618 1.264-6.149-5.02-6.88-13.26-2.905-19.1Z" fill="#DD6B20"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M25.318 5.632C19.417-.21 9.822.285 4.703 5.4c.03.033.059.067.09.098 3.383 3.283 6.766 6.564 10.145 9.848.096.093.15.082.236-.004.437-.429.878-.853 1.319-1.277 2.852-2.745 5.705-5.49 8.559-8.232.076-.073.17-.13.266-.2Zm-10.27 11.786L2.685 5.4c.03-.038.054-.075.083-.107 1.488-1.598 3.215-2.89 5.23-3.81A16.24 16.24 0 0 1 11.432.358a16.717 16.717 0 0 1 4.154-.341c2.04.088 3.992.54 5.858 1.347 2.243.97 4.137 2.386 5.745 4.176.093.103.04.15-.032.219-2 1.925-3.998 3.85-5.996 5.776l-5.982 5.767c-.036.035-.074.068-.13.117ZM9.733 14.608c-.837.742-2.699.914-3.931-.278-1.237-1.197-1.067-2.966-.255-3.886l4.186 4.164ZM20.563 14.32l4.193-4.072c.59.64.863 2.272-.158 3.476-1.136 1.338-3.01 1.33-4.035.596Z" fill="#DD6B20"/>
</svg>
\ No newline at end of file
<svg width="30" height="30" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M12.285 3.6a1.6 1.6 0 0 0-1.6-1.6H8.298a1.6 1.6 0 0 0-1.6 1.6v2.217a1.6 1.6 0 0 1-1.6 1.6H3.6a1.6 1.6 0 0 0-1.6 1.6V26.4A1.6 1.6 0 0 0 3.6 28h2.387a1.6 1.6 0 0 0 1.6-1.6V9.017a1.6 1.6 0 0 1 1.6-1.6h1.498a1.6 1.6 0 0 0 1.6-1.6V3.6Zm11.212 0a1.6 1.6 0 0 0-1.6-1.6H19.51a1.6 1.6 0 0 0-1.6 1.6v2.217a1.6 1.6 0 0 0 1.6 1.6h1.303a1.6 1.6 0 0 1 1.6 1.6V26.4a1.6 1.6 0 0 0 1.6 1.6H26.4a1.6 1.6 0 0 0 1.6-1.6V9.017a1.6 1.6 0 0 0-1.6-1.6h-1.303a1.6 1.6 0 0 1-1.6-1.6V3.6Zm-5.665 10.37a1.6 1.6 0 0 0-1.6-1.6h-2.387a1.6 1.6 0 0 0-1.6 1.6v7.323a1.6 1.6 0 0 0 1.6 1.6h2.387a1.6 1.6 0 0 0 1.6-1.6v-7.324Z" fill="currentColor"/>
</svg>
\ No newline at end of file
<svg width="30" height="30" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M0 11a2 2 0 0 1 2-2h22.753a2 2 0 0 1 1.92 1.436L30 21.75H14.25l-1.125-5.25H0V11Zm0 8.75V18h12l.75 3.75H2a2 2 0 0 1-2-2Zm6-9.25H2.25l1.5 4.5H7.5L6 10.5Zm6 0H8.25l1.5 4.5h3.75L12 10.5Zm8.25 7.5h1.821l.429 1.5h-1.821L20.25 18Zm7.071 0H25.5l.429 1.5h1.821l-.429-1.5ZM17.25 10.5h7.5L27 17.25h-7.5l-2.25-6.75Z" fill="#38B2AC"/>
</svg>
\ No newline at end of file
<svg width="30" height="30" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M15.247 3h1.616a5 5 0 0 1 0 10h-1.116v1.5a.5.5 0 0 1-.5.5h-5.116a.5.5 0 0 1-.5-.5V3.06a.06.06 0 0 1 .06-.06h5.556ZM7.678 14.678a.5.5 0 0 1 .848 0l6.601 10.557a.5.5 0 0 1-.424.765H1.501a.5.5 0 0 1-.424-.765l6.601-10.557ZM22.373 27c3.66 0 6.625-2.91 6.625-6.5S26.032 14 22.373 14c-3.66 0-6.626 2.91-6.626 6.5s2.966 6.5 6.626 6.5Z" fill="#5B2DA4"/>
</svg>
\ No newline at end of file
<svg width="30" height="30" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M14.85 5.28c1.174 0 2.057-.905 2.057-1.94S16.024 1.4 14.85 1.4s-2.058.905-2.058 1.94c0 .247.05.486.143.707l.119.198-.018.01c.341.6 1.01 1.025 1.814 1.025Zm-3.058-1.92v-.02c0-1.624 1.37-2.94 3.058-2.94 1.688 0 3.057 1.316 3.057 2.94v.006l6 3.33.006-.002c1.462-.812 3.332-.33 4.177 1.076.844 1.406.343 3.204-1.12 4.016a3.129 3.129 0 0 1-.705.286v6.096c.241.065.479.16.706.286 1.462.812 1.963 2.61 1.12 4.016-.844 1.403-2.708 1.886-4.169 1.081l-6.015 3.341c-.006 1.618-1.373 2.928-3.057 2.928-1.689 0-3.058-1.316-3.058-2.94v-.005l-6-3.331-.005.002c-1.462.812-3.332.33-4.177-1.076-.844-1.406-.343-3.204 1.12-4.016.227-.126.464-.221.705-.286v-6.096a3.136 3.136 0 0 1-.705-.286C1.267 10.954.766 9.156 1.61 7.75c.845-1.406 2.715-1.888 4.177-1.076l.02.011 5.985-3.324ZM6.865 7.683l5.296-2.941a3.046 3.046 0 0 0 1.874 1.433v4.927c-.795.245-1.473.861-1.911 1.693L7.19 10.055c.25-.807.12-1.672-.326-2.373Zm4.79 6.55-5.251-2.916a3.1 3.1 0 0 1-1.542.786v5.996a3.092 3.092 0 0 1 1.615.858l5.23-2.903a4.98 4.98 0 0 1-.052-1.822Zm.602 3.213-5.038 2.797a2.85 2.85 0 0 1-.363 2.289l5.298 2.94c.39-.7 1.068-1.23 1.881-1.445v-5.123c-.718-.221-1.341-.746-1.778-1.458ZM15.564 24a3.049 3.049 0 0 1 1.989 1.484l5.298-2.943a2.85 2.85 0 0 1-.37-2.3l-5.103-2.834c-.44.736-1.078 1.277-1.814 1.5V24Zm2.351-7.992 5.308 2.947a3.092 3.092 0 0 1 1.615-.858v-5.996a3.1 3.1 0 0 1-1.541-.786l-5.332 2.96a5.037 5.037 0 0 1-.05 1.733Zm-.406-3.177 5-2.777a2.849 2.849 0 0 1 .334-2.385l-5.298-2.941a3.05 3.05 0 0 1-1.981 1.47v4.898c.813.246 1.505.879 1.945 1.735Zm-.832 13.139-.002.001.029.049c.13.257.203.543.203.839 0 1.035-.883 1.94-2.057 1.94s-2.058-.905-2.058-1.94c0-.253.053-.499.15-.725l.102-.17-.014-.007a2.064 2.064 0 0 1 1.82-1.038c.815 0 1.491.437 1.827 1.05Zm7.069-17.8-.015-.008a1.893 1.893 0 0 0-.153 1.873l.197.328c.593.795 1.745 1.064 2.68.545.997-.553 1.31-1.757.76-2.674s-1.791-1.257-2.787-.704a2.04 2.04 0 0 0-.597.498l-.085.142ZM6.12 10.038c.422-.891.088-1.987-.849-2.507-.995-.553-2.237-.212-2.787.704-.55.917-.236 2.121.76 2.674.936.52 2.09.25 2.681-.547l.195-.324ZM23.58 20.16l.194-.323c.591-.797 1.745-1.067 2.682-.547.996.553 1.31 1.757.76 2.674s-1.792 1.257-2.788.704c-.937-.52-1.27-1.616-.848-2.508Zm-20.336-.87c.937-.52 2.09-.25 2.683.547l.194.324c.422.891.088 1.987-.849 2.507-.996.553-2.237.213-2.787-.704-.55-.917-.237-2.121.76-2.674Zm10.791-4.19v2.716c-.768-.404-1.44-1.395-1.44-2.815 0-1.888 1.188-3.018 2.211-3.018s2.21 1.13 2.21 3.018c0 1.428-.678 2.422-1.452 2.822V15.1h-1.529Z" fill="#27AA8B"/>
</svg>
\ No newline at end of file
import { useRouter } from 'next/router';
export default function useBasePath() {
const router = useRouter();
return `/${ router.query.network_type }/${ router.query.network_sub_type }`;
}
import type { Network } from 'types/networks';
import arbitrumIcon from 'icons/networks/arbitrum.svg';
import artisIcon from 'icons/networks/artis.svg';
import ethereumClassicIcon from 'icons/networks/ethereum-classic.svg';
import ethereumIcon from 'icons/networks/ethereum.svg';
import gnosisIcon from 'icons/networks/gnosis.svg';
import optimismIcon from 'icons/networks/optimism.svg';
import poaSokolIcon from 'icons/networks/poa-sokol.svg';
import poaIcon from 'icons/networks/poa.svg';
import rskIcon from 'icons/networks/rsk.svg';
export const NETWORKS: Array<Network> = [
{
name: 'Gnosis Chain',
type: 'xdai',
subType: 'mainnet',
icon: gnosisIcon,
group: 'mainnets',
isAccountSupported: true,
isNewUiSupported: true,
},
{
name: 'Optimism on Gnosis Chain',
type: 'xdai',
subType: 'optimism',
icon: optimismIcon,
group: 'mainnets',
},
{
name: 'Arbitrum on xDai',
type: 'xdai',
subType: 'aox',
icon: arbitrumIcon,
group: 'mainnets',
},
{
name: 'Ethereum',
type: 'eth',
subType: 'mainnet',
icon: ethereumIcon,
group: 'mainnets',
},
{
name: 'Ethereum Classic',
type: 'etc',
subType: 'mainnet',
icon: ethereumClassicIcon,
group: 'mainnets',
},
{
name: 'POA',
type: 'poa',
subType: 'core',
icon: poaIcon,
group: 'mainnets',
},
{
name: 'RSK',
type: 'rsk',
subType: 'mainnet',
icon: rskIcon,
group: 'mainnets',
},
{
name: 'Gnosis Chain Testnet',
type: 'xdai',
subType: 'testnet',
icon: arbitrumIcon,
group: 'testnets',
isAccountSupported: true,
isNewUiSupported: true,
},
{
name: 'POA Sokol',
type: 'poa',
subType: 'sokol',
icon: poaSokolIcon,
group: 'testnets',
},
{
name: 'ARTIS Σ1',
type: 'artis',
subType: 'sigma1',
icon: artisIcon,
group: 'other',
},
{
name: 'LUKSO L14',
type: 'lukso',
subType: 'l14',
group: 'other',
},
];
export const ACCOUNT_ROUTES = [ '/watchlist', '/private-tags', '/public-tags', '/api-keys', '/custom-abi' ];
export function isAccountRoute(route: string) {
return ACCOUNT_ROUTES.includes(route);
}
...@@ -7,4 +7,13 @@ module.exports = withReactSvg({ ...@@ -7,4 +7,13 @@ module.exports = withReactSvg({
webpack(config) { webpack(config) {
return config; return config;
}, },
async redirects() {
return [
{
source: '/',
destination: '/xdai/mainnet',
permanent: true,
},
];
},
}); });
import { Center } from '@chakra-ui/react';
import type { NextPage } from 'next';
import { useRouter } from 'next/router';
import React from 'react';
import Page from 'ui/shared/Page/Page';
const Home: NextPage = () => {
const router = useRouter();
return (
<Page>
<Center h="100%">
home page for { router.query.network_type } { router.query.network_sub_type } network
</Center>
</Page>
);
};
export default Home;
import { Center } from '@chakra-ui/react';
import type { NextPage } from 'next'; import type { NextPage } from 'next';
import React from 'react';
import Page from 'ui/shared/Page/Page';
const Home: NextPage = () => { const Home: NextPage = () => {
return ( return null;
<Page>
<Center h="100%">
Home Page
</Center>
</Page>
);
}; };
export default Home; export default Home;
import { popoverAnatomy as parts } from '@chakra-ui/anatomy';
import type { PartsStyleFunction, SystemStyleFunction, SystemStyleObject } from '@chakra-ui/theme-tools';
import { cssVar, mode } from '@chakra-ui/theme-tools';
const $popperBg = cssVar('popper-bg');
const $arrowBg = cssVar('popper-arrow-bg');
const $arrowShadowColor = cssVar('popper-arrow-shadow-color');
const baseStylePopper: SystemStyleObject = {
zIndex: 10,
};
const baseStyleContent: SystemStyleFunction = (props) => {
const bg = mode('white', 'gray.900')(props);
const shadowColor = mode('gray.200', 'whiteAlpha.300')(props);
return {
[$popperBg.variable]: `colors.${ bg }`,
bg: $popperBg.reference,
[$arrowBg.variable]: $popperBg.reference,
[$arrowShadowColor.variable]: `colors.${ shadowColor }`,
width: 'xs',
border: 'none',
borderColor: 'inherit',
borderRadius: 'md',
boxShadow: '2xl',
zIndex: 'inherit',
_focusVisible: {
outline: 0,
boxShadow: '2xl',
},
};
};
const baseStyleHeader: SystemStyleObject = {
px: 3,
py: 2,
borderBottomWidth: '1px',
};
const baseStyleBody: SystemStyleObject = {
px: 4,
py: 4,
};
const baseStyleFooter: SystemStyleObject = {
px: 3,
py: 2,
borderTopWidth: '1px',
};
const baseStyleCloseButton: SystemStyleObject = {
position: 'absolute',
borderRadius: 'md',
top: 1,
insetEnd: 2,
padding: 2,
};
const baseStyle: PartsStyleFunction<typeof parts> = (props) => ({
popper: baseStylePopper,
content: baseStyleContent(props),
header: baseStyleHeader,
body: baseStyleBody,
footer: baseStyleFooter,
arrow: {},
closeButton: baseStyleCloseButton,
});
const Popover = {
parts: parts.keys,
baseStyle,
};
export default Popover;
...@@ -5,6 +5,7 @@ import Heading from './Heading'; ...@@ -5,6 +5,7 @@ import Heading from './Heading';
import Input from './Input'; import Input from './Input';
import Link from './Link'; import Link from './Link';
import Modal from './Modal'; import Modal from './Modal';
import Popover from './Popover';
import Radio from './Radio'; import Radio from './Radio';
import Table from './Table'; import Table from './Table';
import Tabs from './Tabs'; import Tabs from './Tabs';
...@@ -21,6 +22,7 @@ const components = { ...@@ -21,6 +22,7 @@ const components = {
Form, Form,
Link, Link,
Modal, Modal,
Popover,
Radio, Radio,
Tabs, Tabs,
Table, Table,
......
import type { FunctionComponent, SVGAttributes } from 'react';
export type NetworkGroup = 'mainnets' | 'testnets' | 'other';
export interface Network {
name: string;
// basePath = /<type>/<subType>, e.g. /xdai/mainnet
type: string;
subType: string;
group: 'mainnets' | 'testnets' | 'other';
icon?: FunctionComponent<SVGAttributes<SVGElement>>;
isAccountSupported?: boolean;
isNewUiSupported?: boolean;
}
...@@ -3,8 +3,11 @@ import { InputGroup, Input, InputLeftAddon, InputLeftElement, useColorModeValue ...@@ -3,8 +3,11 @@ import { InputGroup, Input, InputLeftAddon, InputLeftElement, useColorModeValue
import type { ChangeEvent, FormEvent } from 'react'; import type { ChangeEvent, FormEvent } from 'react';
import React from 'react'; import React from 'react';
import useBasePath from 'lib/hooks/useBasePath';
const SearchBar = () => { const SearchBar = () => {
const [ value, setValue ] = React.useState(''); const [ value, setValue ] = React.useState('');
const basePath = useBasePath();
const handleChange = React.useCallback((event: ChangeEvent<HTMLInputElement>) => { const handleChange = React.useCallback((event: ChangeEvent<HTMLInputElement>) => {
setValue(event.target.value); setValue(event.target.value);
...@@ -12,8 +15,8 @@ const SearchBar = () => { ...@@ -12,8 +15,8 @@ const SearchBar = () => {
const handleSubmit = React.useCallback((event: FormEvent<HTMLFormElement>) => { const handleSubmit = React.useCallback((event: FormEvent<HTMLFormElement>) => {
event.preventDefault(); event.preventDefault();
window.location.assign(`https://blockscout.com/xdai/mainnet/search-results?q=${ value }`); window.location.assign(`https://blockscout.com${ basePath }/search-results?q=${ value }`);
}, [ value ]); }, [ value, basePath ]);
return ( return (
<form noValidate onSubmit={ handleSubmit }> <form noValidate onSubmit={ handleSubmit }>
......
import { Link, Icon, Text, HStack, Tooltip } from '@chakra-ui/react'; import { Link, Icon, Text, HStack, Tooltip } from '@chakra-ui/react';
import NextLink from 'next/link'; import NextLink from 'next/link';
import { useRouter } from 'next/router';
import React from 'react'; import React from 'react';
import getDefaultTransitionProps from 'theme/utils/getDefaultTransitionProps'; import getDefaultTransitionProps from 'theme/utils/getDefaultTransitionProps';
...@@ -9,20 +8,17 @@ import useColors from './useColors'; ...@@ -9,20 +8,17 @@ import useColors from './useColors';
interface Props { interface Props {
isCollapsed: boolean; isCollapsed: boolean;
isActive: boolean;
pathname: string; pathname: string;
text: string; text: string;
icon: React.FunctionComponent<React.SVGAttributes<SVGElement>>; icon: React.FunctionComponent<React.SVGAttributes<SVGElement>>;
} }
const NavLink = ({ text, pathname, icon, isCollapsed }: Props) => { const NavLink = ({ text, pathname, icon, isCollapsed, isActive }: Props) => {
const router = useRouter();
const isActive = router.pathname === pathname;
const colors = useColors(); const colors = useColors();
return ( return (
<NextLink href={ pathname } passHref> <NextLink href={ pathname } passHref>
<Link <Link
as="li" as="li"
listStyleType="none" listStyleType="none"
......
import { ChevronLeftIcon } from '@chakra-ui/icons'; import { ChevronLeftIcon } from '@chakra-ui/icons';
import { Flex, Icon, Box, VStack, useColorModeValue } from '@chakra-ui/react'; import { Flex, Icon, Box, VStack, useColorModeValue } from '@chakra-ui/react';
import { useRouter } from 'next/router';
import React from 'react'; import React from 'react';
import abiIcon from 'icons/ABI.svg'; import abiIcon from 'icons/ABI.svg';
...@@ -8,35 +9,39 @@ import appsIcon from 'icons/apps.svg'; ...@@ -8,35 +9,39 @@ import appsIcon from 'icons/apps.svg';
import blocksIcon from 'icons/block.svg'; import blocksIcon from 'icons/block.svg';
import gearIcon from 'icons/gear.svg'; import gearIcon from 'icons/gear.svg';
import logoIcon from 'icons/logo.svg'; import logoIcon from 'icons/logo.svg';
import networksIcon from 'icons/networks.svg';
import privateTagIcon from 'icons/privattags.svg'; import privateTagIcon from 'icons/privattags.svg';
import publicTagIcon from 'icons/publictags.svg'; import publicTagIcon from 'icons/publictags.svg';
import tokensIcon from 'icons/token.svg'; import tokensIcon from 'icons/token.svg';
import transactionsIcon from 'icons/transactions.svg'; import transactionsIcon from 'icons/transactions.svg';
import watchlistIcon from 'icons/watchlist.svg'; import watchlistIcon from 'icons/watchlist.svg';
import * as cookies from 'lib/cookies'; import * as cookies from 'lib/cookies';
import useBasePath from 'lib/hooks/useBasePath';
import getDefaultTransitionProps from 'theme/utils/getDefaultTransitionProps'; import getDefaultTransitionProps from 'theme/utils/getDefaultTransitionProps';
import NavFooter from './NavFooter'; import NavFooter from './NavFooter';
import NavLink from './NavLink'; import NavLink from './NavLink';
import NetworkMenu from './networkMenu/NetworkMenu';
const mainNavItems = [ const Navigation = () => {
{ text: 'Blocks', pathname: '/blocks', icon: blocksIcon }, const router = useRouter();
{ text: 'Transactions', pathname: '/transactions', icon: transactionsIcon }, const basePath = useBasePath();
{ text: 'Tokens', pathname: '/tokens', icon: tokensIcon },
{ text: 'Apps', pathname: '/apps', icon: appsIcon },
{ text: 'Other', pathname: '/other', icon: gearIcon },
];
const accountNavItems = [ const mainNavItems = [
{ text: 'Watchlist', pathname: '/watchlist', icon: watchlistIcon }, { text: 'Blocks', pathname: basePath + '/blocks', icon: blocksIcon },
{ text: 'Private tags', pathname: '/private-tags', icon: privateTagIcon }, { text: 'Transactions', pathname: basePath + '/transactions', icon: transactionsIcon },
{ text: 'Public tags', pathname: '/public-tags', icon: publicTagIcon }, { text: 'Tokens', pathname: basePath + '/tokens', icon: tokensIcon },
{ text: 'API keys', pathname: '/api-keys', icon: apiKeysIcon }, { text: 'Apps', pathname: basePath + '/apps', icon: appsIcon },
{ text: 'Custom ABI', pathname: '/custom-abi', icon: abiIcon }, { text: 'Other', pathname: basePath + '/other', icon: gearIcon },
]; ];
const accountNavItems = [
{ text: 'Watchlist', pathname: basePath + '/watchlist', icon: watchlistIcon },
{ text: 'Private tags', pathname: basePath + '/private-tags', icon: privateTagIcon },
{ text: 'Public tags', pathname: basePath + '/public-tags', icon: publicTagIcon },
{ text: 'API keys', pathname: basePath + '/api-keys', icon: apiKeysIcon },
{ text: 'Custom ABI', pathname: basePath + '/custom-abi', icon: abiIcon },
];
const Navigation = () => {
const [ isCollapsed, setCollapsedState ] = React.useState(cookies.get(cookies.NAMES.NAV_BAR_COLLAPSED) === 'true'); const [ isCollapsed, setCollapsedState ] = React.useState(cookies.get(cookies.NAMES.NAV_BAR_COLLAPSED) === 'true');
const handleTogglerClick = React.useCallback(() => { const handleTogglerClick = React.useCallback(() => {
...@@ -82,23 +87,16 @@ const Navigation = () => { ...@@ -82,23 +87,16 @@ const Navigation = () => {
{ ...getDefaultTransitionProps() } { ...getDefaultTransitionProps() }
/> />
</Box> </Box>
<Icon <NetworkMenu isCollapsed={ isCollapsed }/>
as={ networksIcon }
width="16px"
height="16px"
color={ useColorModeValue('gray.500', 'white') }
marginLeft={ isCollapsed ? '0px' : '27px' }
{ ...getDefaultTransitionProps({ transitionProperty: 'margin' }) }
/>
</Box> </Box>
<Box as="nav" mt={ 14 }> <Box as="nav" mt={ 14 }>
<VStack as="ul" spacing="2" alignItems="flex-start" overflow="hidden"> <VStack as="ul" spacing="2" alignItems="flex-start" overflow="hidden">
{ mainNavItems.map((item) => <NavLink key={ item.text } { ...item } isCollapsed={ isCollapsed }/>) } { mainNavItems.map((item) => <NavLink key={ item.text } { ...item } isCollapsed={ isCollapsed } isActive={ router.asPath === item.pathname }/>) }
</VStack> </VStack>
</Box> </Box>
<Box as="nav" mt={ 12 }> <Box as="nav" mt={ 12 }>
<VStack as="ul" spacing="2" alignItems="flex-start" overflow="hidden"> <VStack as="ul" spacing="2" alignItems="flex-start" overflow="hidden">
{ accountNavItems.map((item) => <NavLink key={ item.text } { ...item } isCollapsed={ isCollapsed }/>) } { accountNavItems.map((item) => <NavLink key={ item.text } { ...item } isCollapsed={ isCollapsed } isActive={ router.asPath === item.pathname }/>) }
</VStack> </VStack>
</Box> </Box>
<NavFooter isCollapsed={ isCollapsed }/> <NavFooter isCollapsed={ isCollapsed }/>
......
import { Popover, PopoverTrigger, Icon, useColorModeValue, Button } from '@chakra-ui/react';
import React from 'react';
import networksIcon from 'icons/networks.svg';
import getDefaultTransitionProps from 'theme/utils/getDefaultTransitionProps';
import NetworkMenuPopup from './NetworkMenuPopup';
interface Props {
isCollapsed: boolean;
}
const NetworkMenu = ({ isCollapsed }: Props) => {
return (
<Popover openDelay={ 300 } placement="right-start" gutter={ 22 } isLazy>
<PopoverTrigger>
<Button variant="unstyled" display="inline-flex" alignSelf="stretch" alignItems="center">
<Icon
as={ networksIcon }
width="16px"
height="16px"
color={ useColorModeValue('gray.500', 'white') }
_hover={{ color: 'blue.400' }}
marginLeft={ isCollapsed ? '0px' : '27px' }
cursor="pointer"
{ ...getDefaultTransitionProps({ transitionProperty: 'margin' }) }
/>
</Button>
</PopoverTrigger>
<NetworkMenuPopup/>
</Popover>
);
};
export default React.memo(NetworkMenu);
import { Box, Flex, Icon, Text } from '@chakra-ui/react';
import NextLink from 'next/link';
import React from 'react';
import type { Network } from 'types/networks';
import checkIcon from 'icons/check.svg';
import placeholderIcon from 'icons/networks/placeholder.svg';
import { isAccountRoute } from 'lib/networks';
import useColors from './useColors';
interface Props extends Network {
isActive: boolean;
routeName: string;
}
const NetworkMenuLink = ({ name, type, subType, icon, isActive, routeName, isAccountSupported, isNewUiSupported }: Props) => {
const isAccount = isAccountRoute(routeName);
const localPath = (() => {
if (isAccount && isAccountSupported) {
return routeName;
}
if (isAccount && !isAccountSupported) {
return '';
}
// will change when blocks&transaction is implemented
return routeName;
})();
const pathName = `/${ type }/${ subType }${ localPath }`;
// will fix later after we agree on CI/CD workflow
const href = isNewUiSupported ? pathName : 'https://blockscout.com' + pathName;
const hasIcon = Boolean(icon);
const colors = useColors({ hasIcon });
return (
<Box as="li" listStyleType="none">
<NextLink href={ href } passHref>
<Flex
as="a"
px={ 4 }
py={ 3 }
alignItems="center"
cursor="pointer"
pointerEvents={ isActive ? 'none' : 'initial' }
borderRadius="base"
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 }}
>
<Icon
as={ hasIcon ? icon : placeholderIcon }
boxSize="30px"
color={ isActive ? colors.icon.active : colors.icon.default }
/>
<Text
marginLeft={ 3 }
fontWeight="500"
color="inherit"
>
{ name }
</Text>
{ isActive && (
<Icon
as={ checkIcon }
boxSize="24px"
marginLeft="auto"
/>
) }
</Flex>
</NextLink>
</Box>
);
};
export default React.memo(NetworkMenuLink);
import { PopoverContent, PopoverBody, Text, Tabs, TabList, TabPanels, TabPanel, Tab, VStack } from '@chakra-ui/react';
import { useRouter } from 'next/router';
import React from 'react';
import type { NetworkGroup } from 'types/networks';
import { NETWORKS } from 'lib/networks';
import NetworkMenuLink from './NetworkMenuLink';
const TABS: Array<NetworkGroup> = [ 'mainnets', 'testnets', 'other' ];
const NetworkMenuPopup = () => {
const router = useRouter();
const routeName = router.pathname.replace('/[network_type]/[network_sub_type]', '');
const selectedNetwork = NETWORKS.find((network) => router.query.network_type === network.type && router.query.network_sub_type === network.subType);
const selectedTab = TABS.findIndex((tab) => selectedNetwork?.group === tab);
return (
<PopoverContent w="382px">
<PopoverBody>
<Text as="h4" fontSize="18px" lineHeight="30px" fontWeight="500">Networks</Text>
<Tabs variant="soft-rounded" mt={ 4 } isLazy defaultIndex={ selectedTab !== -1 ? selectedTab : undefined }>
<TabList>
{ TABS.map((tab) => <Tab key={ tab } textTransform="capitalize">{ tab }</Tab>) }
</TabList>
<TabPanels mt={ 8 }>
{ TABS.map((tab) => (
<TabPanel key={ tab } p={ 0 }>
<VStack as="ul" spacing={ 2 } alignItems="stretch" mt={ 4 }>
{ NETWORKS
.filter((network) => network.group === tab)
.map((network) => (
<NetworkMenuLink
key={ network.name }
{ ...network }
isActive={ network.name === selectedNetwork?.name }
routeName={ routeName }
/>
)) }
</VStack>
</TabPanel>
)) }
</TabPanels>
</Tabs>
</PopoverBody>
</PopoverContent>
);
};
export default NetworkMenuPopup;
import type { FunctionComponent, SVGAttributes } from 'react';
export interface NetworkLink {
pathname: string;
name: string;
icon?: FunctionComponent<SVGAttributes<SVGElement>>;
isNewUi?: boolean;
}
import { useColorModeValue } from '@chakra-ui/react';
export default function useColors({ hasIcon }: {hasIcon: boolean}) {
const iconDefaultColor = useColorModeValue('blackAlpha.600', 'whiteAlpha.600');
const iconPlaceholderDefaultColor = useColorModeValue('blackAlpha.100', 'whiteAlpha.100');
return {
text: {
'default': useColorModeValue('gray.600', 'gray.400'),
active: useColorModeValue('gray.700', 'whiteAlpha.900'),
hover: useColorModeValue('blue.600', 'blue.400'),
},
icon: {
'default': hasIcon ? iconDefaultColor : iconPlaceholderDefaultColor,
active: useColorModeValue('blackAlpha.900', 'whiteAlpha.900'),
},
bg: {
'default': 'transparent',
active: useColorModeValue('blue.50', 'gray.800'),
},
border: {
'default': useColorModeValue('gray.200', 'whiteAlpha.200'),
active: useColorModeValue('blue.50', 'gray.800'),
},
};
}
...@@ -11,5 +11,9 @@ export default function useColors() { ...@@ -11,5 +11,9 @@ export default function useColors() {
'default': 'transparent', 'default': 'transparent',
active: useColorModeValue('blue.50', 'gray.800'), active: useColorModeValue('blue.50', 'gray.800'),
}, },
border: {
'default': useColorModeValue('gray.200', 'whiteAlpha.200'),
active: useColorModeValue('blue.50', 'gray.800'),
},
}; };
} }
...@@ -18,7 +18,7 @@ const WatchListAddressItem = ({ item }: {item: TWatchlistItem}) => { ...@@ -18,7 +18,7 @@ const WatchListAddressItem = ({ item }: {item: TWatchlistItem}) => {
<AddressLinkWithTooltip address={ item.address }/> <AddressLinkWithTooltip address={ item.address }/>
{ item.tokenBalance && ( { item.tokenBalance && (
<HStack spacing={ 0 } fontSize="sm" h={ 6 }> <HStack spacing={ 0 } fontSize="sm" h={ 6 }>
<Image src="./xdai.png" alt="chain-logo" marginRight="10px" w="16px" h="16px"/> <Image src="/xdai.png" alt="chain-logo" marginRight="10px" w="16px" h="16px"/>
<Text color={ mainTextColor }>{ `xDAI balance:${ nbsp }` + item.tokenBalance }</Text> <Text color={ mainTextColor }>{ `xDAI balance:${ nbsp }` + item.tokenBalance }</Text>
<Text variant="secondary">{ `${ nbsp }($${ item.tokenBalanceUSD } USD)` }</Text> <Text variant="secondary">{ `${ nbsp }($${ item.tokenBalanceUSD } USD)` }</Text>
</HStack> </HStack>
......
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