Update routing (#265)
* update routing * debug routing * debug profile page * add app protocol * prefix nextjs api path * remove debug * debug routing * debug deploy * debug routing * fix after merge * delete port and protocol * hard reload page for nav links * fix logo * add marketplace to sokol * debug values for review * add login link * seamless page transition inside new ui app * logout link * debug values for review * add redirect from profile to auth * static assets * debug review workflow * update values for all envs Co-authored-by: Yuliya Sharafitdinova <[email protected]> Co-authored-by: tom <[email protected]>
@@ -29,6 +29,8 @@ NEXT_PUBLIC_FEATURED_NETWORKS=__PLACEHOLDER_FOR_NEXT_PUBLIC_FEATURED_NETWORKS__
|
||||
NEXT_PUBLIC_NETWORK_EXPLORERS=__PLACEHOLDER_FOR_NEXT_PUBLIC_NETWORK_EXPLORERS__
|
||||
NEXT_PUBLIC_MARKETPLACE_APP_LIST=__PLACEHOLDER_FOR_NEXT_PUBLIC_MARKETPLACE_APP_LIST__
|
||||
NEXT_PUBLIC_MARKETPLACE_SUBMIT_FORM=__PLACEHOLDER_FOR_NEXT_PUBLIC_MARKETPLACE_SUBMIT_FORM__
|
||||
NEXT_PUBLIC_LOGOUT_URL=__PLACEHOLDER_FOR_NEXT_PUBLIC_LOGOUT_URL__
|
||||
NEXT_PUBLIC_LOGOUT_RETURN_URL=__PLACEHOLDER_FOR_NEXT_PUBLIC_LOGOUT_RETURN_URL__
|
||||
|
||||
# api config
|
||||
NEXT_PUBLIC_API_ENDPOINT=__PLACEHOLDER_FOR_NEXT_PUBLIC_API_ENDPOINT__
|
||||
@@ -36,3 +38,4 @@ NEXT_PUBLIC_API_BASE_PATH=__PLACEHOLDER_FOR_NEXT_PUBLIC_API_BASE_PATH__
|
||||
|
||||
# external services config
|
||||
NEXT_PUBLIC_SENTRY_DSN=__PLACEHOLDER_FOR_NEXT_PUBLIC_SENTRY_DSN__
|
||||
NEXT_PUBLIC_AUTH0_CLIENT_ID=__PLACEHOLDER_FOR_NEXT_PUBLIC_AUTH0_CLIENT_ID__
|
||||
|
||||
@@ -11,5 +11,5 @@ jobs:
|
||||
cleanup:
|
||||
uses: blockscout/blockscout-ci-cd/.github/workflows/cleanup.yaml@master
|
||||
with:
|
||||
appNamespace: review-front-$GITHUB_HEAD_REF_SLUG
|
||||
appNamespace: review-front-$GITHUB_REF_SLUG
|
||||
secrets: inherit
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
name: Deploy review environment
|
||||
|
||||
on:
|
||||
# push:
|
||||
pull_request:
|
||||
# push:
|
||||
# branches-ignore:
|
||||
# - 'main'
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
@@ -67,9 +69,9 @@ jobs:
|
||||
uses: blockscout/blockscout-ci-cd/.github/workflows/deploy.yaml@master
|
||||
with:
|
||||
env_vars: VALUES_DIR=deploy/values/review,APP_NAME=bs-stack
|
||||
appNamespace: review-front-$GITHUB_HEAD_REF_SLUG
|
||||
appNamespace: review-front-$GITHUB_REF_SLUG
|
||||
blockscoutIngressHost: blockscout
|
||||
frontendIngressHost: frontend
|
||||
frontendIngressHost: blockscout
|
||||
frontendImage: ghcr.io/blockscout/frontend:prerelease-${{ needs.push_to_registry.outputs.shortSha }}
|
||||
gethIngressHost: geth
|
||||
scVerifierIngressHost: sc-verifier
|
||||
|
||||
@@ -71,6 +71,8 @@ The app instance could be customized by passing following variables to NodeJS en
|
||||
| NEXT_PUBLIC_MARKETPLACE_SUBMIT_FORM | `string` | Link to form where authors can submit their dapps to the marketplace | `https://airtable.com/shrqUAcjgGJ4jU88C` |
|
||||
| NEXT_PUBLIC_NETWORK_EXPLORERS | `Array<NetworkExplorer>` where `NetworkExplorer` can have following [properties](#network-explorer-configuration-properties) | Used to build up links to transactions, blocks, addresses in other chain explorers. | `[{'title':'Anyblock','baseUrl':'https://explorer.anyblock.tools','paths':{'tx':'/ethereum/poa/core/tx'}}]` |
|
||||
| NEXT_PUBLIC_NETWORK_VERIFICATION_TYPE | `validation` or `mining` *(optional)* | Verification type in the network | `mining` |
|
||||
| NEXT_PUBLIC_LOGOUT_URL | `string` *(optional)* | Account logout url | `https://blockscoutcom.us.auth0.com/v2/logout` |
|
||||
| NEXT_PUBLIC_LOGOUT_RETURN_URL | `string` *(optional)* | Account logout return url | `https://blockscout.com/poa/core/auth/logout` |
|
||||
|
||||
### App configuration
|
||||
|
||||
@@ -115,6 +117,7 @@ The app instance could be customized by passing following variables to NodeJS en
|
||||
| --- | --- | --- | --- |
|
||||
| NEXT_PUBLIC_SENTRY_DSN | `string` *(optional)* | Client key for your Sentry.io app | `<secret>` |
|
||||
| SENTRY_CSP_REPORT_URI | `string` *(optional)* | URL for sending CSP-reports to your Sentry.io app | `<secret>` |
|
||||
| NEXT_PUBLIC_AUTH0_CLIENT_ID | `string` *(optional)* | Client id for [Auth0](https://auth0.com/) provider | `<secret>` |
|
||||
|
||||
### Marketplace app configuration properties
|
||||
|
||||
|
||||
@@ -24,6 +24,24 @@ const baseUrl = [
|
||||
appPort && ':' + appPort,
|
||||
].filter(Boolean).join('');
|
||||
|
||||
const logoutUrl = (() => {
|
||||
try {
|
||||
const envUrl = getEnvValue(process.env.NEXT_PUBLIC_LOGOUT_URL);
|
||||
const auth0ClientId = getEnvValue(process.env.NEXT_PUBLIC_AUTH0_CLIENT_ID);
|
||||
const returnUrl = getEnvValue(process.env.NEXT_PUBLIC_LOGOUT_RETURN_URL);
|
||||
if (!envUrl || !auth0ClientId || !returnUrl) {
|
||||
throw Error();
|
||||
}
|
||||
|
||||
const url = new URL(envUrl);
|
||||
url.searchParams.set('client_id', auth0ClientId);
|
||||
url.searchParams.set('returnTo', returnUrl);
|
||||
return url.toString();
|
||||
} catch (error) {
|
||||
return;
|
||||
}
|
||||
})();
|
||||
|
||||
const networkType = getEnvValue(process.env.NEXT_PUBLIC_NETWORK_TYPE);
|
||||
const networkSubType = getEnvValue(process.env.NEXT_PUBLIC_NETWORK_SUBTYPE);
|
||||
|
||||
@@ -65,6 +83,7 @@ const config = Object.freeze({
|
||||
host: appHost,
|
||||
port: appPort,
|
||||
baseUrl,
|
||||
logoutUrl,
|
||||
api: {
|
||||
endpoint: getEnvValue(process.env.NEXT_PUBLIC_API_ENDPOINT) || 'https://blockscout.com',
|
||||
basePath: getEnvValue(process.env.NEXT_PUBLIC_API_BASE_PATH) || '',
|
||||
|
||||
@@ -10,6 +10,7 @@ async function rewrites() {
|
||||
// it seems like it's solved but it's not actually
|
||||
|
||||
return [
|
||||
{ source: '/node-api/:slug*', destination: '/api/:slug*' },
|
||||
{ source: '/astar/:slug*', destination: '/astar/mainnet/:slug*' },
|
||||
{ source: '/shiden/:slug*', destination: '/shiden/mainnet/:slug*' },
|
||||
];
|
||||
|
||||
@@ -15,9 +15,9 @@ blockscout:
|
||||
ACCOUNT_AUTH0_CLIENT_SECRET:
|
||||
_default: ENC[AES256_GCM,data:Nmajob/xrOfx3sZgGHWw4/VnSgoyehubNdhJSqasxLFInJeZgxCW/QXpu5KG6j1fDdALLOT89Es+m0IO9VrG8A==,iv:RxYWdOo5G6t0FFwHQfhvUTiCOsxRzJJT0Y1nc0F5sDc=,tag:6v6+yHaHgwnw0cDSD1hXwg==,type:str]
|
||||
ACCOUNT_AUTH0_CALLBACK_URL:
|
||||
_default: ENC[AES256_GCM,data:MkvI0EZaWmsd8tDMU+qiLLZ2anCl00PW3u3Og9GXNtnZ+a7CUyY6rdFBOfE3fSOh4haoNuBxMCyxsAhHk/x0MNRNVqKjqT9I3VBAfzUzM+Ft4g==,iv:RuHXRpEAYKlm2UwN3s6AofiGiSmuRkVyO531rnUIklc=,tag:L3NnykZU4WFOOfPGDCdMUg==,type:str]
|
||||
_default: ENC[AES256_GCM,data:DEyk+7A3zm2R0WXGbqsP5+NXRKQqZ6uaGJvwrniBiB816BCBV27bYWqmXutQPvCga1SLsWzliekc2iUAkTyxopDjODuUxDZlsHmjE5vRaCVTLfGCHf5k6eNN3a0=,iv:RKvqCitIB07FXXKOy8e5HXMkI3wr7HEl695Uylsu3kg=,tag:/3EhIIdlOFMXcbxJZ2N5bg==,type:str]
|
||||
ACCOUNT_AUTH0_LOGOUT_RETURN_URL:
|
||||
_default: ENC[AES256_GCM,data:9cWXw4j6LAg9qUzKTGevJE4U1leMV+i9DD26VDyFqlin4M6O1r/xzoWQtHfrHzxP1RRBuGPIjBqV/WCM1u9cVmhgrs2FQvzZkHk=,iv:Qrxdp4CfnSkCXMxhzMZvvpFSkglzdviq4UYGhffLDNk=,tag:RJhq0+B9Sa5D8k8cAhZW5A==,type:str]
|
||||
_default: ENC[AES256_GCM,data:f5O3nHg9ldCDDOZjUtyKqKNI6D+5eQpWjGxf6fKSh3y2neZ1d81M8Ljt4VF50Dy9QV2Rhu3lyZI47kV8E0BhwEqYNYJ24YBoB+cM2cttuCJxlHvI,iv:l75drqjzuNzNqMYPuLeF41D4bEaVskbHtX60liAuqNM=,tag:uGVjlN8kvR4h6VPwhOnZzA==,type:str]
|
||||
ACCOUNT_AUTH0_LOGOUT_URL:
|
||||
_default: ENC[AES256_GCM,data:6vj0qvxktXptFDX4Tq3kGIyhaJN7Adcwfgb3qWEYH78pWtmFprwfKNdPa/4=,iv:Eb3NcZP9oSmh0ZfY8vCWwR5Ciwe7Lr/QJmcNWXiir9E=,tag:uXoFnMfwo/GD9IPuvs/9Wg==,type:str]
|
||||
ACCOUNT_SENDGRID_API_KEY:
|
||||
@@ -70,14 +70,16 @@ frontend:
|
||||
_default: ENC[AES256_GCM,data:n/H2AH2n9ovn265iFbbrqeOOWS3s7FXgDv5FXJ2Dz133GuhTaqIU5psWjTraZ/Vh+dVM8M9zBLFfUanCWOz7cerq/QUoSVZjKvIvcyp6F072DGU=,iv:Co/pSR+U0vfkmWR+LDpxcQKDJl0WNbaEZihpzrRJcbc=,tag:HUiCX8WGJXWCDB59Y6iIbw==,type:str]
|
||||
SENTRY_CSP_REPORT_URI:
|
||||
_default: ENC[AES256_GCM,data:Hf4azYsGh2lysotK7afaHI85IaLBJeQmPlGE/lwokmX2eaQHVZJ/i5RsaoKoOCSiNyfAowr7P+6IBEC16BUTQMpbhYveBd7c/xjIsoomoHbTdoAdZA/QxNVpS4a2qVthruFudyT1BoZUHIGQ,iv:Mid+PfbslOyivrFSXopdeW96YvOcLP+g2RGcw1o7B98=,tag:IuPUsGdbZQodCMyi1DR04Q==,type:str]
|
||||
NEXT_PUBLIC_AUTH0_CLIENT_ID:
|
||||
_default: ENC[AES256_GCM,data:1doicz45IfwPza75+bYEe/3Ot1auCP3CtW1V1ilRevo=,iv:BlK5h1YRWAL00DuZnujnHWsKXrsTnP1G+F59+MNnHcU=,tag:gu/0BQ6mQXEmQhpWmBU3NQ==,type:str]
|
||||
sops:
|
||||
kms: []
|
||||
gcp_kms: []
|
||||
azure_kv: []
|
||||
hc_vault: []
|
||||
age: []
|
||||
lastmodified: "2022-10-25T09:55:15Z"
|
||||
mac: ENC[AES256_GCM,data:ZZqPTIRw4KvC7jNJMs6rtgKG4JuWmDZaW8NgMFTW1E6rgea3E4aFbJCM61wyncltYNcTdndc40YCkCHEXtO0gptBBJviL8fvo2bcc0m0V18X2zzjg8GU816t7PTKFQ79cALgtEPl5xLz75zJO83Gluskka47+AgPk5xBmG+sHAo=,iv:ZchfAH/GoMRQyqJNcGFSHMBreUQrkruQIhk2A/HcLjA=,tag:Id0YtPyVrXCxQit3mL43UQ==,type:str]
|
||||
lastmodified: "2022-10-27T18:39:52Z"
|
||||
mac: ENC[AES256_GCM,data:iOh30zo2Mew+RO/LeXNCVrtMR52cb2RhuvCN99AdiQWXMVShE8PdWWPW6V5m+LVtwPuxusZi1/fGzTCwpE4cOX3BF8HNI9B8sC6t9NR0SO9/g427p2+vevN/fPBZXkO196KosMLB0+SSh+znmtt0U5yTT8l8v9y2B6H+P89VhxI=,iv:kqwGAaJQihvD9vkFVJZuQTR5rb706mWP7gmBFC+0Pas=,tag:Kg9JHoy2s5avDmpnZaO9Ng==,type:str]
|
||||
pgp:
|
||||
- created_at: "2022-09-14T13:42:28Z"
|
||||
enc: |
|
||||
|
||||
@@ -2,9 +2,11 @@ global:
|
||||
env: e2e
|
||||
# enable Blockscout deploy
|
||||
blockscout:
|
||||
app: blockscout
|
||||
enabled: true
|
||||
image:
|
||||
_default: blockscout/blockscout:latest
|
||||
_default: blockscout/blockscout-sokol:latest
|
||||
#blockscout/blockscout:review-prerelease-9ad99cc8@sha256:608d335025a135f1cde6608b2449b8988b7cb8bfa6ea38e92ce1f184ec577781
|
||||
replicas:
|
||||
app: 1
|
||||
docker:
|
||||
@@ -16,12 +18,16 @@ blockscout:
|
||||
# enable ingress
|
||||
ingress:
|
||||
enabled: true
|
||||
annotations:
|
||||
- 'nginx.ingress.kubernetes.io/rewrite-target: /$2'
|
||||
host:
|
||||
_default: blockscout.test.blockscout.aws-k8s.blockscout.com
|
||||
# enable https
|
||||
#
|
||||
tls:
|
||||
enabled: true
|
||||
path:
|
||||
- "/poa/sokol(/|$)(.*)"
|
||||
- "/"
|
||||
# probes
|
||||
livenessProbe:
|
||||
@@ -43,7 +49,7 @@ blockscout:
|
||||
_default: "2"
|
||||
# enable service to connect to RDS
|
||||
rds:
|
||||
enable: false
|
||||
enabled: false
|
||||
endpoint:
|
||||
_default: <endpoint>.<region>.rds.amazonaws.com
|
||||
# node label
|
||||
@@ -83,15 +89,23 @@ blockscout:
|
||||
RUST_VERIFICATION_SERVICE_URL:
|
||||
_default: http://sc-verifier-svc:8043
|
||||
ACCOUNT_ENABLED:
|
||||
_default: true
|
||||
_default: 'true'
|
||||
DISABLE_REALTIME_INDEXER:
|
||||
_default: 'false'
|
||||
SOCKET_ROOT:
|
||||
_default: "/"
|
||||
_default: "/poa/sokol"
|
||||
NETWORK_PATH:
|
||||
_default: "/"
|
||||
_default: "/poa/sokol"
|
||||
API_PATH:
|
||||
_default: "/poa/sokol"
|
||||
ETHEREUM_JSONRPC_DISABLE_ARCHIVE_BALANCES:
|
||||
_default: 'true'
|
||||
API_BASE_PATH:
|
||||
_default: "/poa/sokol"
|
||||
APPS_MENU:
|
||||
_default: 'true'
|
||||
EXTERNAL_APPS:
|
||||
_default: '[{"title": "Marketplace", "url": "/poa/sokol/apps"}]'
|
||||
|
||||
postgres:
|
||||
enabled: true
|
||||
@@ -155,7 +169,7 @@ geth:
|
||||
ingress:
|
||||
enabled: true
|
||||
host:
|
||||
_default: asdfg-node.test.blockscout.aws-k8s.blockscout.com
|
||||
_default: node.test.blockscout.aws-k8s.blockscout.com
|
||||
# enable https
|
||||
tls:
|
||||
enabled: false
|
||||
@@ -182,7 +196,6 @@ scVerifier:
|
||||
enabled: true
|
||||
host:
|
||||
_default: verifier.test.blockscout.aws-k8s.blockscout.com
|
||||
testnet: asdfg-verifier.test.blockscout.aws-k8s.blockscout.com
|
||||
# enable https
|
||||
tls:
|
||||
enabled: true
|
||||
@@ -249,6 +262,7 @@ scVerifier:
|
||||
SMART_CONTRACT_VERIFIER__JAEGER__ENABLED:
|
||||
_default: 'false'
|
||||
frontend:
|
||||
app: blockscout
|
||||
enabled: true
|
||||
image:
|
||||
_default: ghcr.io/blockscout/frontend:main
|
||||
@@ -261,12 +275,14 @@ frontend:
|
||||
enabled: true
|
||||
host:
|
||||
_default: frontend.test.blockscout.aws-k8s.blockscout.com
|
||||
testnet: asdfg-frontend.test.blockscout.aws-k8s.blockscout.com
|
||||
# enable https
|
||||
tls:
|
||||
enabled: true
|
||||
path:
|
||||
- "/"
|
||||
- "/poa/sokol/(apps|auth/profile|account)"
|
||||
- "/_next"
|
||||
- "/node-api"
|
||||
- "/static"
|
||||
resources:
|
||||
limits:
|
||||
memory:
|
||||
@@ -283,22 +299,16 @@ frontend:
|
||||
enabled: true
|
||||
app: blockscout
|
||||
environment:
|
||||
NEXT_PUBLIC_APP_PROTOCOL:
|
||||
_default: http
|
||||
NEXT_PUBLIC_APP_HOST:
|
||||
_default: localhost
|
||||
NEXT_PUBLIC_APP_PORT:
|
||||
_default: 80
|
||||
NEXT_PUBLIC_BLOCKSCOUT_VERSION:
|
||||
_default: v4.1.8-beta
|
||||
NEXT_PUBLIC_FOOTER_GITHUB_LINK:
|
||||
_default: https://github.com/blockscout/blockscout
|
||||
NEXT_PUBLIC_FOOTER_TWITTER_LINK:
|
||||
_default: https://www.twitter.com/blockscoutcom
|
||||
NEXT_PUBLIC_APP_ENV:
|
||||
_default: preview
|
||||
NEXT_PUBLIC_APP_INSTANCE:
|
||||
_default: unknown
|
||||
NEXT_PUBLIC_APP_ENV:
|
||||
_default: e2e
|
||||
NEXT_PUBLIC_FOOTER_TELEGRAM_LINK:
|
||||
_default: https://t.me/poa_network
|
||||
NEXT_PUBLIC_FOOTER_STAKING_LINK:
|
||||
@@ -308,7 +318,7 @@ frontend:
|
||||
NEXT_PUBLIC_NETWORK_SHORT_NAME:
|
||||
_default: POA
|
||||
NEXT_PUBLIC_NETWORK_ASSETS_PATHNAME:
|
||||
_default: poa
|
||||
_default: sokol
|
||||
NEXT_PUBLIC_NETWORK_TYPE:
|
||||
_default: poa
|
||||
NEXT_PUBLIC_NETWORK_SUBTYPE:
|
||||
@@ -330,8 +340,12 @@ frontend:
|
||||
NEXT_PUBLIC_API_ENDPOINT:
|
||||
_default: https://blockscout.com
|
||||
NEXT_PUBLIC_API_BASE_PATH:
|
||||
_default: /
|
||||
_default: /poa/sokol
|
||||
NEXT_PUBLIC_MARKETPLACE_SUBMIT_FORM:
|
||||
_default: https://airtable.com/shrqUAcjgGJ4jU88C
|
||||
NEXT_PUBLIC_MARKETPLACE_APP_LIST:
|
||||
_default: "[{'author': 'Blockscout', 'id': 'token-approval-tracker', 'title': 'Token Approval Tracker', 'logo': 'https://approval-tracker.vercel.app/icon-192.png', 'categories': ['security', 'tools'], 'shortDescription': 'Token Approval Tracker shows all approvals for any ERC20-compliant tokens and NFTs and lets to revoke them or adjust the approved amount.', 'site': 'https://docs.blockscout.com/for-users/blockscout-apps/token-approval-tracker', 'description': 'Token Approval Tracker shows all approvals for any ERC20-compliant tokens and NFTs and lets to revoke them or adjust the approved amount.', 'url': 'https://approval-tracker.vercel.app/'}]"
|
||||
NEXT_PUBLIC_LOGOUT_URL:
|
||||
_default: https://blockscoutcom.us.auth0.com/v2/logout
|
||||
NEXT_PUBLIC_LOGOUT_RETURN_URL:
|
||||
_default: https://blockscout.com/poa/sokol/auth/logout
|
||||
|
||||
@@ -15,9 +15,9 @@ blockscout:
|
||||
ACCOUNT_AUTH0_CLIENT_SECRET:
|
||||
_default: ENC[AES256_GCM,data:Nmajob/xrOfx3sZgGHWw4/VnSgoyehubNdhJSqasxLFInJeZgxCW/QXpu5KG6j1fDdALLOT89Es+m0IO9VrG8A==,iv:RxYWdOo5G6t0FFwHQfhvUTiCOsxRzJJT0Y1nc0F5sDc=,tag:6v6+yHaHgwnw0cDSD1hXwg==,type:str]
|
||||
ACCOUNT_AUTH0_CALLBACK_URL:
|
||||
_default: ENC[AES256_GCM,data:MkvI0EZaWmsd8tDMU+qiLLZ2anCl00PW3u3Og9GXNtnZ+a7CUyY6rdFBOfE3fSOh4haoNuBxMCyxsAhHk/x0MNRNVqKjqT9I3VBAfzUzM+Ft4g==,iv:RuHXRpEAYKlm2UwN3s6AofiGiSmuRkVyO531rnUIklc=,tag:L3NnykZU4WFOOfPGDCdMUg==,type:str]
|
||||
_default: ENC[AES256_GCM,data:Eopmjs+pJxi0cV9eGzB5cv+uTR+PWd/4WzfEnvQUiwNiswB2G3gP0NoCNBcDR+2+ydeIHYndCcn42RaoM+i96eDbUPy1GWk704IpaYlZoUuhJ8XO9JPPj5ApfH8=,iv:Rc7fgf4rgd+nLh67hOZ9nvSMXZzBBeJ5pkOtybjbz1U=,tag:Xpb1CHELI96KWrpVF7XksQ==,type:str]
|
||||
ACCOUNT_AUTH0_LOGOUT_RETURN_URL:
|
||||
_default: ENC[AES256_GCM,data:9cWXw4j6LAg9qUzKTGevJE4U1leMV+i9DD26VDyFqlin4M6O1r/xzoWQtHfrHzxP1RRBuGPIjBqV/WCM1u9cVmhgrs2FQvzZkHk=,iv:Qrxdp4CfnSkCXMxhzMZvvpFSkglzdviq4UYGhffLDNk=,tag:RJhq0+B9Sa5D8k8cAhZW5A==,type:str]
|
||||
_default: ENC[AES256_GCM,data:13zluPWED9xcoPHZgJmhpKsSNR7JjwAYIoF73Dcs7R9rGGg9h++RWM6a0y3DQMYctKcxAm4u7l6jitmfFmkr6Tp6Urjyw+Fsu8+97CyvlBfWpEjc,iv:AC9+6neb4aHQLl1jDmPNtE/CGxEEv4GFe2k4a2QPh1w=,tag:MgiVG2oBMXG08Q4BtxlKhg==,type:str]
|
||||
ACCOUNT_AUTH0_LOGOUT_URL:
|
||||
_default: ENC[AES256_GCM,data:6vj0qvxktXptFDX4Tq3kGIyhaJN7Adcwfgb3qWEYH78pWtmFprwfKNdPa/4=,iv:Eb3NcZP9oSmh0ZfY8vCWwR5Ciwe7Lr/QJmcNWXiir9E=,tag:uXoFnMfwo/GD9IPuvs/9Wg==,type:str]
|
||||
ACCOUNT_SENDGRID_API_KEY:
|
||||
@@ -70,14 +70,16 @@ frontend:
|
||||
_default: ENC[AES256_GCM,data:n/H2AH2n9ovn265iFbbrqeOOWS3s7FXgDv5FXJ2Dz133GuhTaqIU5psWjTraZ/Vh+dVM8M9zBLFfUanCWOz7cerq/QUoSVZjKvIvcyp6F072DGU=,iv:Co/pSR+U0vfkmWR+LDpxcQKDJl0WNbaEZihpzrRJcbc=,tag:HUiCX8WGJXWCDB59Y6iIbw==,type:str]
|
||||
SENTRY_CSP_REPORT_URI:
|
||||
_default: ENC[AES256_GCM,data:Hf4azYsGh2lysotK7afaHI85IaLBJeQmPlGE/lwokmX2eaQHVZJ/i5RsaoKoOCSiNyfAowr7P+6IBEC16BUTQMpbhYveBd7c/xjIsoomoHbTdoAdZA/QxNVpS4a2qVthruFudyT1BoZUHIGQ,iv:Mid+PfbslOyivrFSXopdeW96YvOcLP+g2RGcw1o7B98=,tag:IuPUsGdbZQodCMyi1DR04Q==,type:str]
|
||||
NEXT_PUBLIC_AUTH0_CLIENT_ID:
|
||||
_default: ENC[AES256_GCM,data:cRcbMzOW2AFyDz/lqv4T9SpDCabXdBKLFN9dbq/rFg4=,iv:G9afggfvZ+BpuE5u31KDVfIxhlP38IE28Yt9pMQsd6E=,tag:t1kkjXPolc/58fuQVULLfA==,type:str]
|
||||
sops:
|
||||
kms: []
|
||||
gcp_kms: []
|
||||
azure_kv: []
|
||||
hc_vault: []
|
||||
age: []
|
||||
lastmodified: "2022-10-25T09:55:50Z"
|
||||
mac: ENC[AES256_GCM,data:dv6Xyf42vAfgKWe0p9mcxtesrdDMV8wF0E/rH6vUgGp1VXmFZnStjiX2Gu5qhKh6YXvuDfpTNdaj9WlnfyL5uX4hpMK+evkUzJk4cAwNPQ7F48khZQQ8T3CtmYgzBUxeKlVTSWg98w+Y6NydURB1Xp58Hi+72sskeJGNekGijkM=,iv:Fpv59cjv7MvG2cUIrNlCdgLaWuhfUJhALTmD2HGxYpc=,tag:5IILWg9gth2RZdTjk3IxyA==,type:str]
|
||||
lastmodified: "2022-10-27T18:39:43Z"
|
||||
mac: ENC[AES256_GCM,data:dQvWp8uP4LJ58Fagb0+e26UiHX5d27z04ei0Hz7EPBmFdEA2/1WTXFHBzJZhkxAU51JdbQxFLBWchO1Pv/26RqDi2zscZ53Ln1Ulc21gCMeY95/q1xENDEuss8srr9LtIDRVfr+KjpPnSer2t8er7B3lAaxPPtc0FMHVa3kf+Jw=,iv:kIL05arLDhqZQhECIeifyN0eH7EZbWt9/ltzsEuUONk=,tag:qkI3Z4vcnCK4tE+PnxPXfA==,type:str]
|
||||
pgp:
|
||||
- created_at: "2022-09-14T13:42:28Z"
|
||||
enc: |
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
global:
|
||||
env: e2e
|
||||
env: main
|
||||
# enable Blockscout deploy
|
||||
blockscout:
|
||||
app: blockscout
|
||||
enabled: true
|
||||
image:
|
||||
_default: blockscout/blockscout:review-prerelease-4dad4e9b@sha256:0afd8e344f7856eeb5326dff370f6258e588a77fa1611ecf16f8433944ddbaf9
|
||||
_default: blockscout/blockscout-sokol:latest
|
||||
#blockscout/blockscout:review-prerelease-9ad99cc8@sha256:608d335025a135f1cde6608b2449b8988b7cb8bfa6ea38e92ce1f184ec577781
|
||||
replicas:
|
||||
app: 1
|
||||
docker:
|
||||
@@ -103,7 +105,7 @@ blockscout:
|
||||
APPS_MENU:
|
||||
_default: 'true'
|
||||
EXTERNAL_APPS:
|
||||
_default: '[{"title": "Marketplace", "url": "..."}]'
|
||||
_default: '[{"title": "Marketplace", "url": "/poa/sokol/apps"}]'
|
||||
|
||||
postgres:
|
||||
enabled: true
|
||||
@@ -260,6 +262,7 @@ scVerifier:
|
||||
SMART_CONTRACT_VERIFIER__JAEGER__ENABLED:
|
||||
_default: 'false'
|
||||
frontend:
|
||||
app: blockscout
|
||||
enabled: true
|
||||
image:
|
||||
_default: ghcr.io/blockscout/frontend:main
|
||||
@@ -276,7 +279,10 @@ frontend:
|
||||
tls:
|
||||
enabled: true
|
||||
path:
|
||||
- "/"
|
||||
- "/poa/sokol/(apps|auth/profile|account)"
|
||||
- "/_next"
|
||||
- "/node-api"
|
||||
- "/static"
|
||||
resources:
|
||||
limits:
|
||||
memory:
|
||||
@@ -293,22 +299,16 @@ frontend:
|
||||
enabled: true
|
||||
app: blockscout
|
||||
environment:
|
||||
NEXT_PUBLIC_APP_PROTOCOL:
|
||||
_default: http
|
||||
NEXT_PUBLIC_APP_HOST:
|
||||
_default: localhost
|
||||
NEXT_PUBLIC_APP_PORT:
|
||||
_default: 80
|
||||
NEXT_PUBLIC_BLOCKSCOUT_VERSION:
|
||||
_default: v4.1.8-beta
|
||||
NEXT_PUBLIC_FOOTER_GITHUB_LINK:
|
||||
_default: https://github.com/blockscout/blockscout
|
||||
NEXT_PUBLIC_FOOTER_TWITTER_LINK:
|
||||
_default: https://www.twitter.com/blockscoutcom
|
||||
NEXT_PUBLIC_APP_ENV:
|
||||
_default: preview
|
||||
NEXT_PUBLIC_APP_INSTANCE:
|
||||
_default: unknown
|
||||
NEXT_PUBLIC_APP_ENV:
|
||||
_default: e2e
|
||||
NEXT_PUBLIC_FOOTER_TELEGRAM_LINK:
|
||||
_default: https://t.me/poa_network
|
||||
NEXT_PUBLIC_FOOTER_STAKING_LINK:
|
||||
@@ -318,7 +318,7 @@ frontend:
|
||||
NEXT_PUBLIC_NETWORK_SHORT_NAME:
|
||||
_default: POA
|
||||
NEXT_PUBLIC_NETWORK_ASSETS_PATHNAME:
|
||||
_default: poa
|
||||
_default: sokol
|
||||
NEXT_PUBLIC_NETWORK_TYPE:
|
||||
_default: poa
|
||||
NEXT_PUBLIC_NETWORK_SUBTYPE:
|
||||
@@ -345,3 +345,7 @@ frontend:
|
||||
_default: https://airtable.com/shrqUAcjgGJ4jU88C
|
||||
NEXT_PUBLIC_MARKETPLACE_APP_LIST:
|
||||
_default: "[{'author': 'Blockscout', 'id': 'token-approval-tracker', 'title': 'Token Approval Tracker', 'logo': 'https://approval-tracker.vercel.app/icon-192.png', 'categories': ['security', 'tools'], 'shortDescription': 'Token Approval Tracker shows all approvals for any ERC20-compliant tokens and NFTs and lets to revoke them or adjust the approved amount.', 'site': 'https://docs.blockscout.com/for-users/blockscout-apps/token-approval-tracker', 'description': 'Token Approval Tracker shows all approvals for any ERC20-compliant tokens and NFTs and lets to revoke them or adjust the approved amount.', 'url': 'https://approval-tracker.vercel.app/'}]"
|
||||
NEXT_PUBLIC_LOGOUT_URL:
|
||||
_default: https://blockscoutcom.us.auth0.com/v2/logout
|
||||
NEXT_PUBLIC_LOGOUT_RETURN_URL:
|
||||
_default: https://blockscout.com/poa/sokol/auth/logout
|
||||
|
||||
@@ -15,9 +15,9 @@ blockscout:
|
||||
ACCOUNT_AUTH0_CLIENT_SECRET:
|
||||
_default: ENC[AES256_GCM,data:Nmajob/xrOfx3sZgGHWw4/VnSgoyehubNdhJSqasxLFInJeZgxCW/QXpu5KG6j1fDdALLOT89Es+m0IO9VrG8A==,iv:RxYWdOo5G6t0FFwHQfhvUTiCOsxRzJJT0Y1nc0F5sDc=,tag:6v6+yHaHgwnw0cDSD1hXwg==,type:str]
|
||||
ACCOUNT_AUTH0_CALLBACK_URL:
|
||||
_default: ENC[AES256_GCM,data:MkvI0EZaWmsd8tDMU+qiLLZ2anCl00PW3u3Og9GXNtnZ+a7CUyY6rdFBOfE3fSOh4haoNuBxMCyxsAhHk/x0MNRNVqKjqT9I3VBAfzUzM+Ft4g==,iv:RuHXRpEAYKlm2UwN3s6AofiGiSmuRkVyO531rnUIklc=,tag:L3NnykZU4WFOOfPGDCdMUg==,type:str]
|
||||
_default: ENC[AES256_GCM,data:FgOUi6sp2SAAMQXtsll9HpIIGPcO+7AeOlZgcYHc5uWtDffQmcNtQSHqG72Aw5HeF3PSnwdeg2mLJDUHitE2usrdaE2SSV3ekBebBrobJjw9/4I57z8AJy0exEY=,iv:tqJV1VY4DPVeJBOa/LElmQ2AX5T83qzon4m4w+bGgYg=,tag:Lw0l3tjsZBwnv9Iu9Xxj5w==,type:str]
|
||||
ACCOUNT_AUTH0_LOGOUT_RETURN_URL:
|
||||
_default: ENC[AES256_GCM,data:9cWXw4j6LAg9qUzKTGevJE4U1leMV+i9DD26VDyFqlin4M6O1r/xzoWQtHfrHzxP1RRBuGPIjBqV/WCM1u9cVmhgrs2FQvzZkHk=,iv:Qrxdp4CfnSkCXMxhzMZvvpFSkglzdviq4UYGhffLDNk=,tag:RJhq0+B9Sa5D8k8cAhZW5A==,type:str]
|
||||
_default: ENC[AES256_GCM,data:vCwBiNb5aSfeBTY0ozEkxV8RForss9A/WeZ3jVKTHddBIJ73hEzo/QA0c8nktiwil+H2ZfKeTOFgwvvO7AQqMYrCd5erQmXksF8qGu617csDlYcH,iv:SbFuuJbFWYbz+BkUFT9oNYdYXiDThIBWGA7Owb/F+qk=,tag:v5uY+2Be4Z4AHmjd7Ua7FQ==,type:str]
|
||||
ACCOUNT_AUTH0_LOGOUT_URL:
|
||||
_default: ENC[AES256_GCM,data:6vj0qvxktXptFDX4Tq3kGIyhaJN7Adcwfgb3qWEYH78pWtmFprwfKNdPa/4=,iv:Eb3NcZP9oSmh0ZfY8vCWwR5Ciwe7Lr/QJmcNWXiir9E=,tag:uXoFnMfwo/GD9IPuvs/9Wg==,type:str]
|
||||
ACCOUNT_SENDGRID_API_KEY:
|
||||
@@ -70,14 +70,16 @@ frontend:
|
||||
_default: ENC[AES256_GCM,data:n/H2AH2n9ovn265iFbbrqeOOWS3s7FXgDv5FXJ2Dz133GuhTaqIU5psWjTraZ/Vh+dVM8M9zBLFfUanCWOz7cerq/QUoSVZjKvIvcyp6F072DGU=,iv:Co/pSR+U0vfkmWR+LDpxcQKDJl0WNbaEZihpzrRJcbc=,tag:HUiCX8WGJXWCDB59Y6iIbw==,type:str]
|
||||
SENTRY_CSP_REPORT_URI:
|
||||
_default: ENC[AES256_GCM,data:Hf4azYsGh2lysotK7afaHI85IaLBJeQmPlGE/lwokmX2eaQHVZJ/i5RsaoKoOCSiNyfAowr7P+6IBEC16BUTQMpbhYveBd7c/xjIsoomoHbTdoAdZA/QxNVpS4a2qVthruFudyT1BoZUHIGQ,iv:Mid+PfbslOyivrFSXopdeW96YvOcLP+g2RGcw1o7B98=,tag:IuPUsGdbZQodCMyi1DR04Q==,type:str]
|
||||
NEXT_PUBLIC_AUTH0_CLIENT_ID:
|
||||
_default: ENC[AES256_GCM,data:4cTeqxQnGcpzPK4bMqxZpLgMeFSSDbajN/fmb1UunH8=,iv:bPTQfahGfWF1OfArvYQeSQItMa0Ymkt6eUfDZFBQSOY=,tag:8xHe5AUkbH/rl6cOfkVAKg==,type:str]
|
||||
sops:
|
||||
kms: []
|
||||
gcp_kms: []
|
||||
azure_kv: []
|
||||
hc_vault: []
|
||||
age: []
|
||||
lastmodified: "2022-10-25T09:56:28Z"
|
||||
mac: ENC[AES256_GCM,data:RE31H3E5ADznpOUQWmXOfK3bEh/0sSsphOLdjP81fWOcYGlbPFfsmssFoN6GCGNNcM2lXCGnc+b9xuqzYH/A9zjALccoNhQTRl3q20YZAsD7zlRRjxDPFIivQaDKYB2lWYwlHeLUOgohHGTwzoFTC0LDxWqgYLxrVZQwtVEXPdE=,iv:xV9ubuTmHUmNetdox5lSV+mv+rXTJjVxNcurZyWueDw=,tag:lqj1wgDjybmKoRk6W8h37g==,type:str]
|
||||
lastmodified: "2022-10-27T08:40:17Z"
|
||||
mac: ENC[AES256_GCM,data:t9Ex5kGubl/kxcHhJK6uoh7BkMXSonHbZAQk9yB9Zm6NdYp9gINmfCrsloMW213KqPfsgBlxTsdYi7CeR96Zj1lnwUB/v4L13hUuA/tyb8G28gzHjQjHcBmD9AIh6UbTL77uAW+UqIOYnjdHX4Snwv1qTK+TWg+wLPClVSMsXcw=,iv:f3h9C77B6vEXhJ3OXHGnFUpiQV7igtiH961K757BKgk=,tag:eAQ8YwH55cDf8wh0wVdWJg==,type:str]
|
||||
pgp:
|
||||
- created_at: "2022-09-14T13:42:28Z"
|
||||
enc: |
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
global:
|
||||
env: e2e
|
||||
env: review
|
||||
# enable Blockscout deploy
|
||||
blockscout:
|
||||
app: blockscout
|
||||
enabled: true
|
||||
image:
|
||||
_default: blockscout/blockscout:latest
|
||||
_default: blockscout/blockscout-sokol:latest
|
||||
#blockscout/blockscout:review-prerelease-9ad99cc8@sha256:608d335025a135f1cde6608b2449b8988b7cb8bfa6ea38e92ce1f184ec577781
|
||||
replicas:
|
||||
app: 1
|
||||
docker:
|
||||
@@ -16,12 +18,16 @@ blockscout:
|
||||
# enable ingress
|
||||
ingress:
|
||||
enabled: true
|
||||
annotations:
|
||||
- 'nginx.ingress.kubernetes.io/rewrite-target: /$2'
|
||||
host:
|
||||
_default: blockscout.test.blockscout.aws-k8s.blockscout.com
|
||||
# enable https
|
||||
#
|
||||
tls:
|
||||
enabled: true
|
||||
path:
|
||||
- "/poa/sokol(/|$)(.*)"
|
||||
- "/"
|
||||
# probes
|
||||
livenessProbe:
|
||||
@@ -43,7 +49,7 @@ blockscout:
|
||||
_default: "2"
|
||||
# enable service to connect to RDS
|
||||
rds:
|
||||
enable: false
|
||||
enabled: false
|
||||
endpoint:
|
||||
_default: <endpoint>.<region>.rds.amazonaws.com
|
||||
# node label
|
||||
@@ -83,15 +89,23 @@ blockscout:
|
||||
RUST_VERIFICATION_SERVICE_URL:
|
||||
_default: http://sc-verifier-svc:8043
|
||||
ACCOUNT_ENABLED:
|
||||
_default: true
|
||||
_default: 'true'
|
||||
DISABLE_REALTIME_INDEXER:
|
||||
_default: 'false'
|
||||
SOCKET_ROOT:
|
||||
_default: "/"
|
||||
_default: "/poa/sokol"
|
||||
NETWORK_PATH:
|
||||
_default: "/"
|
||||
_default: "/poa/sokol"
|
||||
API_PATH:
|
||||
_default: "/poa/sokol"
|
||||
ETHEREUM_JSONRPC_DISABLE_ARCHIVE_BALANCES:
|
||||
_default: 'true'
|
||||
API_BASE_PATH:
|
||||
_default: "/poa/sokol"
|
||||
APPS_MENU:
|
||||
_default: 'true'
|
||||
EXTERNAL_APPS:
|
||||
_default: '[{"title": "Marketplace", "url": "/poa/sokol/apps"}]'
|
||||
|
||||
postgres:
|
||||
enabled: true
|
||||
@@ -155,7 +169,7 @@ geth:
|
||||
ingress:
|
||||
enabled: true
|
||||
host:
|
||||
_default: asdfg-node.test.blockscout.aws-k8s.blockscout.com
|
||||
_default: node.test.blockscout.aws-k8s.blockscout.com
|
||||
# enable https
|
||||
tls:
|
||||
enabled: false
|
||||
@@ -182,7 +196,6 @@ scVerifier:
|
||||
enabled: true
|
||||
host:
|
||||
_default: verifier.test.blockscout.aws-k8s.blockscout.com
|
||||
testnet: asdfg-verifier.test.blockscout.aws-k8s.blockscout.com
|
||||
# enable https
|
||||
tls:
|
||||
enabled: true
|
||||
@@ -249,6 +262,7 @@ scVerifier:
|
||||
SMART_CONTRACT_VERIFIER__JAEGER__ENABLED:
|
||||
_default: 'false'
|
||||
frontend:
|
||||
app: blockscout
|
||||
enabled: true
|
||||
image:
|
||||
_default: ghcr.io/blockscout/frontend:main
|
||||
@@ -261,12 +275,14 @@ frontend:
|
||||
enabled: true
|
||||
host:
|
||||
_default: frontend.test.blockscout.aws-k8s.blockscout.com
|
||||
testnet: asdfg-frontend.test.blockscout.aws-k8s.blockscout.com
|
||||
# enable https
|
||||
tls:
|
||||
enabled: true
|
||||
path:
|
||||
- "/"
|
||||
- "/poa/sokol/(apps|auth/profile|account)"
|
||||
- "/_next"
|
||||
- "/node-api"
|
||||
- "/static"
|
||||
resources:
|
||||
limits:
|
||||
memory:
|
||||
@@ -324,8 +340,12 @@ frontend:
|
||||
NEXT_PUBLIC_API_ENDPOINT:
|
||||
_default: https://blockscout.com
|
||||
NEXT_PUBLIC_API_BASE_PATH:
|
||||
_default: /
|
||||
_default: /poa/sokol
|
||||
NEXT_PUBLIC_MARKETPLACE_SUBMIT_FORM:
|
||||
_default: https://airtable.com/shrqUAcjgGJ4jU88C
|
||||
NEXT_PUBLIC_MARKETPLACE_APP_LIST:
|
||||
_default: "[{'author': 'Blockscout', 'id': 'token-approval-tracker', 'title': 'Token Approval Tracker', 'logo': 'https://approval-tracker.vercel.app/icon-192.png', 'categories': ['security', 'tools'], 'shortDescription': 'Token Approval Tracker shows all approvals for any ERC20-compliant tokens and NFTs and lets to revoke them or adjust the approved amount.', 'site': 'https://docs.blockscout.com/for-users/blockscout-apps/token-approval-tracker', 'description': 'Token Approval Tracker shows all approvals for any ERC20-compliant tokens and NFTs and lets to revoke them or adjust the approved amount.', 'url': 'https://approval-tracker.vercel.app/'}]"
|
||||
NEXT_PUBLIC_LOGOUT_URL:
|
||||
_default: https://blockscoutcom.us.auth0.com/v2/logout
|
||||
NEXT_PUBLIC_LOGOUT_RETURN_URL:
|
||||
_default: https://blockscout.com/poa/sokol/auth/logout
|
||||
|
||||
@@ -17,7 +17,7 @@ export default function useFetchProfileInfo() {
|
||||
const fetch = useFetch();
|
||||
|
||||
return useQuery<unknown, Error, UserInfo>([ QueryKeys.profile ], async() => {
|
||||
return fetch('/api/account/profile');
|
||||
return fetch('/node-api/account/profile');
|
||||
}, {
|
||||
refetchOnMount: false,
|
||||
enabled: Boolean(cookies.get(cookies.NAMES.API_TOKEN)),
|
||||
|
||||
@@ -23,11 +23,11 @@ export default function useNavItems() {
|
||||
|
||||
return React.useMemo(() => {
|
||||
const mainNavItems = [
|
||||
{ text: 'Blocks', url: link('blocks'), icon: blocksIcon, isActive: currentRoute.startsWith('block') },
|
||||
{ text: 'Transactions', url: link('txs'), icon: transactionsIcon, isActive: currentRoute.startsWith('tx') },
|
||||
{ text: 'Tokens', url: link('tokens'), icon: tokensIcon, isActive: currentRoute === 'tokens' },
|
||||
{ text: 'Blocks', url: link('blocks'), icon: blocksIcon, isActive: currentRoute.startsWith('block'), isNewUi: false },
|
||||
{ text: 'Transactions', url: link('txs'), icon: transactionsIcon, isActive: currentRoute.startsWith('tx'), isNewUi: false },
|
||||
{ text: 'Tokens', url: link('tokens'), icon: tokensIcon, isActive: currentRoute === 'tokens', isNewUi: false },
|
||||
isMarketplaceFilled ?
|
||||
{ text: 'Apps', url: link('apps'), icon: appsIcon, isActive: currentRoute === 'apps' } : null,
|
||||
{ text: 'Apps', url: link('apps'), icon: appsIcon, isActive: currentRoute === 'apps', isNewUi: true } : null,
|
||||
// there should be custom site sections like Stats, Faucet, More, etc but never an 'other'
|
||||
// examples https://explorer-edgenet.polygon.technology/ and https://explorer.celo.org/
|
||||
// at this stage custom menu items is under development, we will implement it later
|
||||
@@ -35,14 +35,14 @@ export default function useNavItems() {
|
||||
].filter(notEmpty);
|
||||
|
||||
const accountNavItems = [
|
||||
{ text: 'Watchlist', url: link('watchlist'), icon: watchlistIcon, isActive: currentRoute === 'watchlist' },
|
||||
{ text: 'Private tags', url: link('private_tags'), icon: privateTagIcon, isActive: currentRoute.startsWith('private_tags') },
|
||||
{ text: 'Public tags', url: link('public_tags'), icon: publicTagIcon, isActive: currentRoute === 'public_tags' },
|
||||
{ text: 'API keys', url: link('api_keys'), icon: apiKeysIcon, isActive: currentRoute === 'api_keys' },
|
||||
{ text: 'Custom ABI', url: link('custom_abi'), icon: abiIcon, isActive: currentRoute === 'custom_abi' },
|
||||
{ text: 'Watchlist', url: link('watchlist'), icon: watchlistIcon, isActive: currentRoute === 'watchlist', isNewUi: true },
|
||||
{ text: 'Private tags', url: link('private_tags'), icon: privateTagIcon, isActive: currentRoute.startsWith('private_tags'), isNewUi: true },
|
||||
{ text: 'Public tags', url: link('public_tags'), icon: publicTagIcon, isActive: currentRoute === 'public_tags', isNewUi: true },
|
||||
{ text: 'API keys', url: link('api_keys'), icon: apiKeysIcon, isActive: currentRoute === 'api_keys', isNewUi: true },
|
||||
{ text: 'Custom ABI', url: link('custom_abi'), icon: abiIcon, isActive: currentRoute === 'custom_abi', isNewUi: true },
|
||||
];
|
||||
|
||||
const profileItem = { text: 'My profile', url: link('profile'), icon: profileIcon, isActive: currentRoute === 'profile' };
|
||||
const profileItem = { text: 'My profile', url: link('profile'), icon: profileIcon, isActive: currentRoute === 'profile', isNewUi: true };
|
||||
|
||||
return { mainNavItems, accountNavItems, profileItem };
|
||||
}, [ isMarketplaceFilled, currentRoute ]);
|
||||
|
||||
@@ -21,8 +21,7 @@ const paths = {
|
||||
app_index: `${ BASE_PATH }/apps/[id]`,
|
||||
search_results: `${ BASE_PATH }/search-results`,
|
||||
other: `${ BASE_PATH }/search-results`,
|
||||
// no slash required, it is correct
|
||||
auth: `${ BASE_PATH }auth/auth0`,
|
||||
auth: `${ BASE_PATH }/auth/auth0`,
|
||||
};
|
||||
|
||||
module.exports = paths;
|
||||
|
||||
@@ -29,9 +29,10 @@ export function middleware(req: NextRequest) {
|
||||
|
||||
// we don't have any info from router here, so just do straight forward sub-string search (sorry)
|
||||
const isAccountRoute = req.nextUrl.pathname.includes('/account/');
|
||||
const isProfileRoute = req.nextUrl.pathname.includes('/auth/profile');
|
||||
const apiToken = req.cookies.get(NAMES.API_TOKEN);
|
||||
|
||||
if (isAccountRoute && !apiToken) {
|
||||
if ((isAccountRoute || isProfileRoute) && !apiToken) {
|
||||
const authUrl = link('auth', networkParams);
|
||||
return NextResponse.redirect(authUrl);
|
||||
}
|
||||
|
||||
@@ -13,10 +13,10 @@ class MyDocument extends Document {
|
||||
href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&display=swap"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
<link rel="icon" sizes="32x32" type="image/png" href="/favicon-32x32.png"/>
|
||||
<link rel="icon" sizes="16x16" type="image/png"href="/favicon-16x16.png"/>
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png"/>
|
||||
<link rel="mask-icon" href="/safari-pinned-tab.svg" color="#5bbad5"/>
|
||||
<link rel="icon" sizes="32x32" type="image/png" href="/static/favicon-32x32.png"/>
|
||||
<link rel="icon" sizes="16x16" type="image/png"href="/static/favicon-16x16.png"/>
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/static/apple-touch-icon.png"/>
|
||||
<link rel="mask-icon" href="/static/safari-pinned-tab.svg" color="#5bbad5"/>
|
||||
</Head>
|
||||
<body>
|
||||
<ColorModeScript initialColorMode={ theme.config.initialColorMode }/>
|
||||
|
||||
|
Before Width: | Height: | Size: 2.4 KiB |
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 769 B After Width: | Height: | Size: 769 B |
|
Before Width: | Height: | Size: 914 B After Width: | Height: | Size: 914 B |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 550 B |
|
Before Width: | Height: | Size: 983 B |
@@ -48,10 +48,10 @@ const ApiKeyForm: React.FC<Props> = ({ data, onClose, setAlertVisible }) => {
|
||||
const body = { name: data.name };
|
||||
|
||||
if (!data.token) {
|
||||
return fetch('/api/account/api-keys', { method: 'POST', body });
|
||||
return fetch('/node-api/account/api-keys', { method: 'POST', body });
|
||||
}
|
||||
|
||||
return fetch(`/api/account/api-keys/${ data.token }`, { method: 'PUT', body });
|
||||
return fetch(`/node-api/account/api-keys/${ data.token }`, { method: 'PUT', body });
|
||||
};
|
||||
|
||||
const mutation = useMutation(updateApiKey, {
|
||||
|
||||
@@ -19,7 +19,7 @@ const DeleteAddressModal: React.FC<Props> = ({ isOpen, onClose, data }) => {
|
||||
const fetch = useFetch();
|
||||
|
||||
const mutationFn = useCallback(() => {
|
||||
return fetch(`/api/account/api-keys/${ data.api_key }`, { method: 'DELETE' });
|
||||
return fetch(`/node-api/account/api-keys/${ data.api_key }`, { method: 'DELETE' });
|
||||
}, [ data.api_key, fetch ]);
|
||||
|
||||
const onSuccess = useCallback(async() => {
|
||||
|
||||
@@ -38,7 +38,7 @@ const BlockDetails = () => {
|
||||
|
||||
const { data, isLoading, isError, error } = useQuery<unknown, ErrorType<{ status: number }>, Block>(
|
||||
[ QueryKeys.block, router.query.id ],
|
||||
async() => await fetch(`/api/blocks/${ router.query.id }`),
|
||||
async() => await fetch(`/node-api/blocks/${ router.query.id }`),
|
||||
{
|
||||
enabled: Boolean(router.query.id),
|
||||
},
|
||||
|
||||
@@ -22,7 +22,7 @@ const BlocksContent = ({ type }: Props) => {
|
||||
|
||||
const { data, isLoading, isError } = useQuery<unknown, unknown, BlocksResponse>(
|
||||
[ QueryKeys.blocks, type ],
|
||||
async() => await fetch(`/api/blocks${ type ? `?type=${ type }` : '' }`),
|
||||
async() => await fetch(`/node-api/blocks${ type ? `?type=${ type }` : '' }`),
|
||||
);
|
||||
|
||||
if (isLoading) {
|
||||
|
||||
@@ -53,10 +53,10 @@ const CustomAbiForm: React.FC<Props> = ({ data, onClose, setAlertVisible }) => {
|
||||
const body = { name: data.name, contract_address_hash: data.contract_address_hash, abi: data.abi };
|
||||
|
||||
if (!data.id) {
|
||||
return fetch<CustomAbi, CustomAbiErrors>('/api/account/custom-abis', { method: 'POST', body });
|
||||
return fetch<CustomAbi, CustomAbiErrors>('/node-api/account/custom-abis', { method: 'POST', body });
|
||||
}
|
||||
|
||||
return fetch<CustomAbi, CustomAbiErrors>(`/api/account/custom-abis/${ data.id }`, { method: 'PUT', body });
|
||||
return fetch<CustomAbi, CustomAbiErrors>(`/node-api/account/custom-abis/${ data.id }`, { method: 'PUT', body });
|
||||
};
|
||||
|
||||
const formBackgroundColor = useColorModeValue('white', 'gray.900');
|
||||
|
||||
@@ -18,7 +18,7 @@ const DeleteCustomAbiModal: React.FC<Props> = ({ isOpen, onClose, data }) => {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
const mutationFn = useCallback(() => {
|
||||
return fetch(`/api/account/custom-abis/${ data.id }`, { method: 'DELETE' });
|
||||
return fetch(`/node-api/account/custom-abis/${ data.id }`, { method: 'DELETE' });
|
||||
}, [ data ]);
|
||||
|
||||
const onSuccess = useCallback(async() => {
|
||||
|
||||
@@ -31,7 +31,7 @@ const ApiKeysPage: React.FC = () => {
|
||||
const [ apiKeyModalData, setApiKeyModalData ] = useState<ApiKey>();
|
||||
const [ deleteModalData, setDeleteModalData ] = useState<ApiKey>();
|
||||
|
||||
const { data, isLoading, isError } = useQuery<unknown, unknown, ApiKeys>([ QueryKeys.apiKeys ], async() => await fetch('/api/account/api-keys'));
|
||||
const { data, isLoading, isError } = useQuery<unknown, unknown, ApiKeys>([ QueryKeys.apiKeys ], async() => await fetch('/node-api/account/api-keys'));
|
||||
|
||||
const onEditClick = useCallback((data: ApiKey) => {
|
||||
setApiKeyModalData(data);
|
||||
|
||||
@@ -32,7 +32,7 @@ const Apps = () => {
|
||||
|
||||
useQuery<unknown, unknown, JsonRpcUrlResponse>(
|
||||
[ 'json-rpc-url' ],
|
||||
async() => await fetch(`/api/config/json-rpc-url`),
|
||||
async() => await fetch(`/node-api/config/json-rpc-url`),
|
||||
);
|
||||
|
||||
return (
|
||||
|
||||
@@ -28,7 +28,8 @@ const CustomAbiPage: React.FC = () => {
|
||||
const [ customAbiModalData, setCustomAbiModalData ] = useState<CustomAbi>();
|
||||
const [ deleteModalData, setDeleteModalData ] = useState<CustomAbi>();
|
||||
|
||||
const { data, isLoading, isError } = useQuery<unknown, unknown, CustomAbis>([ QueryKeys.customAbis ], async() => await fetch('/api/account/custom-abis'));
|
||||
const { data, isLoading, isError } = useQuery<unknown, unknown, CustomAbis>([ QueryKeys.customAbis ], async() =>
|
||||
await fetch('/node-api/account/custom-abis'));
|
||||
|
||||
const onEditClick = useCallback((data: CustomAbi) => {
|
||||
setCustomAbiModalData(data);
|
||||
|
||||
@@ -28,7 +28,7 @@ const MarketplaceApp = ({ app, isLoading }: Props) => {
|
||||
|
||||
const { data: jsonRpcUrlResponse } = useQuery<unknown, unknown, JsonRpcUrlResponse>(
|
||||
[ 'json-rpc-url' ],
|
||||
async() => await fetch(`/api/config/json-rpc-url`),
|
||||
async() => await fetch(`/node-api/config/json-rpc-url`),
|
||||
{ refetchOnMount: false },
|
||||
);
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ import WatchlistTable from 'ui/watchlist/WatchlistTable/WatchlistTable';
|
||||
|
||||
const WatchList: React.FC = () => {
|
||||
const { data, isLoading, isError } =
|
||||
useQuery<unknown, unknown, TWatchlist>([ QueryKeys.watchlist ], async() => fetch('/api/account/watchlist/get-with-tokens'));
|
||||
useQuery<unknown, unknown, TWatchlist>([ QueryKeys.watchlist ], async() => fetch('/node-api/account/watchlist/get-with-tokens'));
|
||||
|
||||
const addressModalProps = useDisclosure();
|
||||
const deleteModalProps = useDisclosure();
|
||||
|
||||
@@ -54,10 +54,10 @@ const AddressForm: React.FC<Props> = ({ data, onClose, setAlertVisible }) => {
|
||||
|
||||
const isEdit = data?.id;
|
||||
if (isEdit) {
|
||||
return fetch(`/api/account/private-tags/address/${ data.id }`, { method: 'PUT', body });
|
||||
return fetch(`/node-api/account/private-tags/address/${ data.id }`, { method: 'PUT', body });
|
||||
}
|
||||
|
||||
return fetch('/api/account/private-tags/address', { method: 'POST', body });
|
||||
return fetch('/node-api/account/private-tags/address', { method: 'POST', body });
|
||||
}, {
|
||||
onError: (e: ErrorType<AddressTagErrors>) => {
|
||||
setPending(false);
|
||||
|
||||
@@ -23,7 +23,7 @@ const DeletePrivateTagModal: React.FC<Props> = ({ isOpen, onClose, data, type })
|
||||
const fetch = useFetch();
|
||||
|
||||
const mutationFn = useCallback(() => {
|
||||
return fetch(`/api/account/private-tags/${ type }/${ id }`, { method: 'DELETE' });
|
||||
return fetch(`/node-api/account/private-tags/${ type }/${ id }`, { method: 'DELETE' });
|
||||
}, [ fetch, type, id ]);
|
||||
|
||||
const onSuccess = useCallback(async() => {
|
||||
|
||||
@@ -19,7 +19,7 @@ import DeletePrivateTagModal from './DeletePrivateTagModal';
|
||||
|
||||
const PrivateAddressTags = () => {
|
||||
const { data: addressTagsData, isLoading, isError } =
|
||||
useQuery<unknown, unknown, AddressTags>([ QueryKeys.addressTags ], async() => fetch('/api/account/private-tags/address'), { refetchOnMount: false });
|
||||
useQuery<unknown, unknown, AddressTags>([ QueryKeys.addressTags ], async() => fetch('/node-api/account/private-tags/address'), { refetchOnMount: false });
|
||||
|
||||
const addressModalProps = useDisclosure();
|
||||
const deleteModalProps = useDisclosure();
|
||||
|
||||
@@ -21,7 +21,7 @@ const PrivateTransactionTags = () => {
|
||||
const { data: transactionTagsData, isLoading, isError } =
|
||||
useQuery<unknown, unknown, TransactionTags>(
|
||||
[ QueryKeys.transactionTags ],
|
||||
async() => fetch('/api/account/private-tags/transaction'), { refetchOnMount: false },
|
||||
async() => fetch('/node-api/account/private-tags/transaction'), { refetchOnMount: false },
|
||||
);
|
||||
|
||||
const transactionModalProps = useDisclosure();
|
||||
|
||||
@@ -54,10 +54,10 @@ const TransactionForm: React.FC<Props> = ({ data, onClose, setAlertVisible }) =>
|
||||
const isEdit = data?.id;
|
||||
|
||||
if (isEdit) {
|
||||
return fetch(`/api/account/private-tags/transaction/${ data.id }`, { method: 'PUT', body });
|
||||
return fetch(`/node-api/account/private-tags/transaction/${ data.id }`, { method: 'PUT', body });
|
||||
}
|
||||
|
||||
return fetch('/api/account/private-tags/transaction', { method: 'POST', body });
|
||||
return fetch('/node-api/account/private-tags/transaction', { method: 'POST', body });
|
||||
}, {
|
||||
onError: (e: ErrorType<TransactionTagErrors>) => {
|
||||
setPending(false);
|
||||
|
||||
@@ -28,7 +28,7 @@ const DeletePublicTagModal: React.FC<Props> = ({ isOpen, onClose, data, onDelete
|
||||
|
||||
const deleteApiKey = useCallback(() => {
|
||||
const body = { remove_reason: reason };
|
||||
return fetch(`/api/account/public-tags/${ data.id }`, { method: 'DELETE', body });
|
||||
return fetch(`/node-api/account/public-tags/${ data.id }`, { method: 'DELETE', body });
|
||||
}, [ data.id, fetch, reason ]);
|
||||
|
||||
const onSuccess = useCallback(async() => {
|
||||
|
||||
@@ -27,7 +27,8 @@ const PublicTagsData = ({ changeToFormScreen, onTagDelete }: Props) => {
|
||||
const isMobile = useIsMobile();
|
||||
const fetch = useFetch();
|
||||
|
||||
const { data, isLoading, isError } = useQuery<unknown, unknown, PublicTags>([ QueryKeys.publicTags ], async() => await fetch('/api/account/public-tags'));
|
||||
const { data, isLoading, isError } = useQuery<unknown, unknown, PublicTags>([ QueryKeys.publicTags ], async() =>
|
||||
await fetch('/node-api/account/public-tags'));
|
||||
|
||||
const onDeleteModalClose = useCallback(() => {
|
||||
setDeleteModalData(undefined);
|
||||
|
||||
@@ -99,10 +99,10 @@ const PublicTagsForm = ({ changeToDataScreen, data }: Props) => {
|
||||
};
|
||||
|
||||
if (!data?.id) {
|
||||
return fetch<PublicTag, PublicTagErrors>('/api/account/public-tags', { method: 'POST', body });
|
||||
return fetch<PublicTag, PublicTagErrors>('/node-api/account/public-tags', { method: 'POST', body });
|
||||
}
|
||||
|
||||
return fetch<PublicTag, PublicTagErrors>(`/api/account/public-tags/${ data.id }`, { method: 'PUT', body });
|
||||
return fetch<PublicTag, PublicTagErrors>(`/node-api/account/public-tags/${ data.id }`, { method: 'PUT', body });
|
||||
};
|
||||
|
||||
const mutation = useMutation(updatePublicTag, {
|
||||
|
||||
@@ -18,7 +18,7 @@ interface Props {
|
||||
const Page = ({ children, wrapChildren = true }: Props) => {
|
||||
const fetch = useFetch();
|
||||
|
||||
useQuery<unknown, unknown, unknown>([ QueryKeys.csrf ], async() => await fetch('/api/account/csrf'), {
|
||||
useQuery<unknown, unknown, unknown>([ QueryKeys.csrf ], async() => await fetch('/node-api/account/csrf'), {
|
||||
enabled: Boolean(cookies.get(cookies.NAMES.API_TOKEN)),
|
||||
});
|
||||
|
||||
|
||||
@@ -13,51 +13,61 @@ interface Props {
|
||||
text: string;
|
||||
icon: React.FunctionComponent<React.SVGAttributes<SVGElement>>;
|
||||
px?: string | number;
|
||||
isNewUi: boolean;
|
||||
}
|
||||
|
||||
const NavLink = ({ text, url, icon, isCollapsed, isActive, px }: Props) => {
|
||||
const NavLink = ({ text, url, icon, isCollapsed, isActive, px, isNewUi }: Props) => {
|
||||
const colors = useColors();
|
||||
|
||||
const isExpanded = isCollapsed === false;
|
||||
|
||||
const content = (
|
||||
<Link
|
||||
{ ...(isNewUi ? {} : { href: url }) }
|
||||
w={{ base: '100%', lg: isExpanded ? '180px' : '60px', xl: isCollapsed ? '60px' : '180px' }}
|
||||
px={ px || { base: 3, lg: isExpanded ? 3 : '15px', xl: isCollapsed ? '15px' : 3 } }
|
||||
py={ 2.5 }
|
||||
display="flex"
|
||||
color={ isActive ? colors.text.active : colors.text.default }
|
||||
bgColor={ isActive ? colors.bg.active : colors.bg.default }
|
||||
_hover={{ color: isActive ? colors.text.active : colors.text.hover }}
|
||||
borderRadius="base"
|
||||
whiteSpace="nowrap"
|
||||
{ ...getDefaultTransitionProps({ transitionProperty: 'width, padding' }) }
|
||||
>
|
||||
<Tooltip
|
||||
label={ text }
|
||||
hasArrow={ false }
|
||||
isDisabled={ !isCollapsed }
|
||||
placement="right"
|
||||
variant="nav"
|
||||
gutter={ 15 }
|
||||
color={ isActive ? colors.text.active : colors.text.hover }
|
||||
>
|
||||
<HStack spacing={ 3 }>
|
||||
<Icon as={ icon } boxSize="30px"/>
|
||||
<Text
|
||||
variant="inherit"
|
||||
fontSize="sm"
|
||||
lineHeight="20px"
|
||||
display={{ base: 'block', lg: isExpanded ? 'block' : 'none', xl: isCollapsed ? 'none' : 'block' }}
|
||||
>
|
||||
{ text }
|
||||
</Text>
|
||||
</HStack>
|
||||
</Tooltip>
|
||||
</Link>
|
||||
);
|
||||
|
||||
return (
|
||||
<Box as="li" listStyleType="none" w="100%">
|
||||
<NextLink href={ url } passHref>
|
||||
<Link
|
||||
w={{ base: '100%', lg: isExpanded ? '180px' : '60px', xl: isCollapsed ? '60px' : '180px' }}
|
||||
px={ px || { base: 3, lg: isExpanded ? 3 : '15px', xl: isCollapsed ? '15px' : 3 } }
|
||||
py={ 2.5 }
|
||||
display="flex"
|
||||
color={ isActive ? colors.text.active : colors.text.default }
|
||||
bgColor={ isActive ? colors.bg.active : colors.bg.default }
|
||||
_hover={{ color: isActive ? colors.text.active : colors.text.hover }}
|
||||
borderRadius="base"
|
||||
whiteSpace="nowrap"
|
||||
{ ...getDefaultTransitionProps({ transitionProperty: 'width, padding' }) }
|
||||
>
|
||||
<Tooltip
|
||||
label={ text }
|
||||
hasArrow={ false }
|
||||
isDisabled={ !isCollapsed }
|
||||
placement="right"
|
||||
variant="nav"
|
||||
gutter={ 15 }
|
||||
color={ isActive ? colors.text.active : colors.text.hover }
|
||||
>
|
||||
<HStack spacing={ 3 }>
|
||||
<Icon as={ icon } boxSize="30px"/>
|
||||
<Text
|
||||
variant="inherit"
|
||||
fontSize="sm"
|
||||
lineHeight="20px"
|
||||
display={{ base: 'block', lg: isExpanded ? 'block' : 'none', xl: isCollapsed ? 'none' : 'block' }}
|
||||
>
|
||||
{ text }
|
||||
</Text>
|
||||
</HStack>
|
||||
</Tooltip>
|
||||
</Link>
|
||||
</NextLink>
|
||||
{ /* why not NextLink in all cases? since prev UI and new one are hosting in the same domain and global routing is managed by nginx */ }
|
||||
{ /* we have to hard reload page on every transition between urls from different part of the app */ }
|
||||
{ isNewUi ? (
|
||||
<NextLink href={ url } passHref>
|
||||
{ content }
|
||||
</NextLink>
|
||||
) : content }
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { Icon, Box, Image, useColorModeValue } from '@chakra-ui/react';
|
||||
import NextLink from 'next/link';
|
||||
import React from 'react';
|
||||
import type { FunctionComponent, SVGAttributes } from 'react';
|
||||
|
||||
@@ -41,46 +40,50 @@ const NetworkLogo = ({ isCollapsed, onClick }: Props) => {
|
||||
if (logo && typeof logo === 'string') {
|
||||
logoEl = (
|
||||
<Image
|
||||
h="20px"
|
||||
w="auto"
|
||||
h="100%"
|
||||
src={ logo }
|
||||
alt={ `${ appConfig.network.name } network icon` }
|
||||
/>
|
||||
);
|
||||
} else if (typeof logo !== undefined) {
|
||||
} else if (typeof logo !== 'undefined') {
|
||||
logoEl = (
|
||||
<Icon
|
||||
as={ logo as FunctionComponent<SVGAttributes<SVGElement>> }
|
||||
width="auto"
|
||||
height="20px"
|
||||
height="100%"
|
||||
{ ...getDefaultTransitionProps() }
|
||||
style={ style }
|
||||
/>
|
||||
);
|
||||
} else {
|
||||
<Icon
|
||||
as={ blockscoutLogo }
|
||||
width="113px"
|
||||
height="20px"
|
||||
color={ logoColor }
|
||||
{ ...getDefaultTransitionProps() }
|
||||
style={ style }
|
||||
/>;
|
||||
logoEl = (
|
||||
<Icon
|
||||
as={ blockscoutLogo }
|
||||
width="auto"
|
||||
height="100%"
|
||||
color={ logoColor }
|
||||
{ ...getDefaultTransitionProps() }
|
||||
style={ style }
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<NextLink href={ href } passHref>
|
||||
<Box
|
||||
as="a"
|
||||
width={{ base: '113px', lg: isCollapsed === false ? '113px' : 0, xl: isCollapsed ? '0' : '113px' }}
|
||||
display="inline-flex"
|
||||
overflow="hidden"
|
||||
onClick={ onClick }
|
||||
{ ...getDefaultTransitionProps({ transitionProperty: 'width' }) }
|
||||
aria-label="Link to main page"
|
||||
>
|
||||
{ logoEl }
|
||||
</Box>
|
||||
</NextLink>
|
||||
// TODO switch to <NextLink href={ href } passHref> when main page for network will be ready
|
||||
<Box
|
||||
as="a"
|
||||
href={ href }
|
||||
width={{ base: 'auto', lg: isCollapsed === false ? '113px' : 0, xl: isCollapsed ? '0' : '113px' }}
|
||||
height="20px"
|
||||
display="inline-flex"
|
||||
overflow="hidden"
|
||||
onClick={ onClick }
|
||||
{ ...getDefaultTransitionProps({ transitionProperty: 'width' }) }
|
||||
aria-label="Link to main page"
|
||||
>
|
||||
{ logoEl }
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { Box, Flex, Icon, Text, Image } from '@chakra-ui/react';
|
||||
import NextLink from 'next/link';
|
||||
import React from 'react';
|
||||
|
||||
import type { FeaturedNetwork } from 'types/networks';
|
||||
@@ -31,38 +30,37 @@ const NetworkMenuLink = ({ title, icon, isActive, isMobile, url }: Props) => {
|
||||
|
||||
return (
|
||||
<Box as="li" listStyleType="none">
|
||||
<NextLink href={ url } passHref>
|
||||
<Flex
|
||||
as="a"
|
||||
px={ isMobile ? 3 : 4 }
|
||||
py={ 2 }
|
||||
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 }}
|
||||
<Flex
|
||||
as="a"
|
||||
href={ url }
|
||||
px={ isMobile ? 3 : 4 }
|
||||
py={ 2 }
|
||||
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 }}
|
||||
>
|
||||
{ iconEl }
|
||||
<Text
|
||||
marginLeft={ 3 }
|
||||
fontWeight="500"
|
||||
color="inherit"
|
||||
fontSize={ isMobile ? 'sm' : 'md' }
|
||||
lineHeight={ isMobile ? '20px' : '24px' }
|
||||
>
|
||||
{ iconEl }
|
||||
<Text
|
||||
marginLeft={ 3 }
|
||||
fontWeight="500"
|
||||
color="inherit"
|
||||
fontSize={ isMobile ? 'sm' : 'md' }
|
||||
lineHeight={ isMobile ? '20px' : '24px' }
|
||||
>
|
||||
{ title }
|
||||
</Text>
|
||||
{ isActive && (
|
||||
<Icon
|
||||
as={ checkIcon }
|
||||
boxSize="24px"
|
||||
marginLeft="auto"
|
||||
/>
|
||||
) }
|
||||
</Flex>
|
||||
</NextLink>
|
||||
{ title }
|
||||
</Text>
|
||||
{ isActive && (
|
||||
<Icon
|
||||
as={ checkIcon }
|
||||
boxSize="24px"
|
||||
marginLeft="auto"
|
||||
/>
|
||||
) }
|
||||
</Flex>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -3,6 +3,7 @@ import React from 'react';
|
||||
|
||||
import type { UserInfo } from 'types/api/account';
|
||||
|
||||
import appConfig from 'configs/app/config';
|
||||
import useNavItems from 'lib/hooks/useNavItems';
|
||||
import getDefaultTransitionProps from 'theme/utils/getDefaultTransitionProps';
|
||||
import NavLink from 'ui/snippets/navigation/NavLink';
|
||||
@@ -40,7 +41,7 @@ const ProfileMenuContent = ({ name, nickname, email }: Props) => {
|
||||
</VStack>
|
||||
</Box>
|
||||
<Box mt={ 2 } pt={ 3 } borderTopColor={ borderColor } borderTopWidth="1px" { ...getDefaultTransitionProps() }>
|
||||
<Button size="sm" width="full" variant="outline">Sign Out</Button>
|
||||
<Button size="sm" width="full" variant="outline" as="a" href={ appConfig.logoutUrl }>Sign Out</Button>
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
|
||||
@@ -2,16 +2,25 @@ import { Popover, PopoverContent, PopoverBody, PopoverTrigger, Button } from '@c
|
||||
import React from 'react';
|
||||
|
||||
import useFetchProfileInfo from 'lib/hooks/useFetchProfileInfo';
|
||||
import link from 'lib/link/link';
|
||||
import UserAvatar from 'ui/shared/UserAvatar';
|
||||
import ProfileMenuContent from 'ui/snippets/profileMenu/ProfileMenuContent';
|
||||
|
||||
const ProfileMenuDesktop = () => {
|
||||
const { data } = useFetchProfileInfo();
|
||||
const loginUrl = link('auth');
|
||||
|
||||
return (
|
||||
<Popover openDelay={ 300 } placement="bottom-end" gutter={ 10 } isLazy>
|
||||
<PopoverTrigger>
|
||||
<Button variant="unstyled" display="inline-flex" height="auto" flexShrink={ 0 }>
|
||||
<Button
|
||||
variant="unstyled"
|
||||
display="inline-flex"
|
||||
height="auto"
|
||||
flexShrink={ 0 }
|
||||
as={ data ? undefined : 'a' }
|
||||
href={ data ? undefined : loginUrl }
|
||||
>
|
||||
<UserAvatar size={ 50 } data={ data }/>
|
||||
</Button>
|
||||
</PopoverTrigger>
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { Flex, Box, Drawer, DrawerOverlay, DrawerContent, DrawerBody, useDisclosure } from '@chakra-ui/react';
|
||||
import { Flex, Box, Drawer, DrawerOverlay, DrawerContent, DrawerBody, useDisclosure, Button } from '@chakra-ui/react';
|
||||
import React from 'react';
|
||||
|
||||
import useFetchProfileInfo from 'lib/hooks/useFetchProfileInfo';
|
||||
import link from 'lib/link/link';
|
||||
import UserAvatar from 'ui/shared/UserAvatar';
|
||||
import ColorModeToggler from 'ui/snippets/header/ColorModeToggler';
|
||||
import ProfileMenuContent from 'ui/snippets/profileMenu/ProfileMenuContent';
|
||||
@@ -10,37 +11,38 @@ const ProfileMenuMobile = () => {
|
||||
const { isOpen, onOpen, onClose } = useDisclosure();
|
||||
|
||||
const { data } = useFetchProfileInfo();
|
||||
const loginUrl = link('auth');
|
||||
|
||||
return (
|
||||
<>
|
||||
<Box padding={ 2 } onClick={ onOpen }>
|
||||
<UserAvatar size={ 24 } data={ data }/>
|
||||
</Box>
|
||||
{ data && (
|
||||
<Drawer
|
||||
isOpen={ isOpen }
|
||||
placement="right"
|
||||
onClose={ onClose }
|
||||
autoFocus={ false }
|
||||
>
|
||||
<DrawerOverlay/>
|
||||
<DrawerContent maxWidth="260px">
|
||||
<DrawerBody p={ 6 }>
|
||||
<Flex
|
||||
justifyContent="space-between"
|
||||
alignItems="center"
|
||||
mb={ 6 }
|
||||
>
|
||||
<ColorModeToggler/>
|
||||
<Box onClick={ onClose }>
|
||||
<UserAvatar size={ 24 } data={ data }/>
|
||||
</Box>
|
||||
</Flex>
|
||||
<ProfileMenuContent { ...data }/>
|
||||
</DrawerBody>
|
||||
</DrawerContent>
|
||||
</Drawer>
|
||||
) }
|
||||
<Drawer
|
||||
isOpen={ isOpen }
|
||||
placement="right"
|
||||
onClose={ onClose }
|
||||
autoFocus={ false }
|
||||
>
|
||||
<DrawerOverlay/>
|
||||
<DrawerContent maxWidth="260px">
|
||||
<DrawerBody p={ 6 }>
|
||||
<Flex
|
||||
justifyContent="space-between"
|
||||
alignItems="center"
|
||||
mb={ 6 }
|
||||
>
|
||||
<ColorModeToggler/>
|
||||
<Box onClick={ onClose }>
|
||||
<UserAvatar size={ 24 } data={ data }/>
|
||||
</Box>
|
||||
</Flex>
|
||||
{ data ? <ProfileMenuContent { ...data }/> : (
|
||||
<Button size="sm" width="full" variant="outline" as="a" href={ loginUrl }>Sign In</Button>
|
||||
) }
|
||||
</DrawerBody>
|
||||
</DrawerContent>
|
||||
</Drawer>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -49,7 +49,7 @@ const TxDetails = () => {
|
||||
|
||||
const { data, isLoading, isError } = useQuery<unknown, unknown, Transaction>(
|
||||
[ QueryKeys.tx, router.query.id ],
|
||||
async() => await fetch(`/api/transactions/${ router.query.id }`),
|
||||
async() => await fetch(`/node-api/transactions/${ router.query.id }`),
|
||||
{
|
||||
enabled: Boolean(router.query.id),
|
||||
},
|
||||
|
||||
@@ -75,7 +75,7 @@ const TxInternals = () => {
|
||||
const [ sort, setSort ] = React.useState<Sort>();
|
||||
const { data, isLoading, isError } = useQuery<unknown, unknown, InternalTransactionsResponse>(
|
||||
[ QueryKeys.txInternals, router.query.id ],
|
||||
async() => await fetch(`/api/transactions/${ router.query.id }/internal-transactions`),
|
||||
async() => await fetch(`/node-api/transactions/${ router.query.id }/internal-transactions`),
|
||||
{
|
||||
enabled: Boolean(router.query.id),
|
||||
},
|
||||
|
||||
@@ -17,7 +17,7 @@ const TxLogs = () => {
|
||||
|
||||
const { data, isLoading, isError } = useQuery<unknown, unknown, LogsResponse>(
|
||||
[ QueryKeys.txLog, router.query.id ],
|
||||
async() => await fetch(`/api/transactions/${ router.query.id }/logs`),
|
||||
async() => await fetch(`/node-api/transactions/${ router.query.id }/logs`),
|
||||
{
|
||||
enabled: Boolean(router.query.id),
|
||||
},
|
||||
|
||||
@@ -16,7 +16,7 @@ const TxRawTrace = () => {
|
||||
|
||||
const { data, isLoading, isError } = useQuery<unknown, unknown, RawTracesResponse>(
|
||||
[ QueryKeys.txRawTrace, router.query.id ],
|
||||
async() => await fetch(`/api/transactions/${ router.query.id }/raw-trace`),
|
||||
async() => await fetch(`/node-api/transactions/${ router.query.id }/raw-trace`),
|
||||
{
|
||||
enabled: Boolean(router.query.id),
|
||||
},
|
||||
|
||||
@@ -97,11 +97,11 @@ const AddressForm: React.FC<Props> = ({ data, onClose, setAlertVisible }) => {
|
||||
};
|
||||
if (data) {
|
||||
// edit address
|
||||
return fetch<TWatchlistItem, WatchlistErrors>(`/api/account/watchlist/${ data.id }`, { method: 'PUT', body });
|
||||
return fetch<TWatchlistItem, WatchlistErrors>(`/node-api/account/watchlist/${ data.id }`, { method: 'PUT', body });
|
||||
|
||||
} else {
|
||||
// add address
|
||||
return fetch<TWatchlistItem, WatchlistErrors>('/api/account/watchlist', { method: 'POST', body });
|
||||
return fetch<TWatchlistItem, WatchlistErrors>('/node-api/account/watchlist', { method: 'POST', body });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ const DeleteAddressModal: React.FC<Props> = ({ isOpen, onClose, data }) => {
|
||||
const fetch = useFetch();
|
||||
|
||||
const mutationFn = useCallback(() => {
|
||||
return fetch(`/api/account1/watchlist/${ data?.id }`, { method: 'DELETE' });
|
||||
return fetch(`/node-api/account/watchlist/${ data?.id }`, { method: 'DELETE' });
|
||||
}, [ data?.id, fetch ]);
|
||||
|
||||
const onSuccess = useCallback(async() => {
|
||||
|
||||
@@ -27,7 +27,7 @@ const WatchListItem = ({ item, onEditClick, onDeleteClick }: Props) => {
|
||||
|
||||
const { mutate } = useMutation(() => {
|
||||
const data = { ...item, notification_methods: { email: !notificationEnabled } };
|
||||
return fetch(`/api/account/watchlist/${ item.id }`, { method: 'PUT', body: JSON.stringify(data) });
|
||||
return fetch(`/node-api/account/watchlist/${ item.id }`, { method: 'PUT', body: JSON.stringify(data) });
|
||||
}, {
|
||||
onError: () => {
|
||||
// eslint-disable-next-line no-console
|
||||
|
||||
@@ -52,7 +52,7 @@ const WatchlistTableItem = ({ item, onEditClick, onDeleteClick }: Props) => {
|
||||
setSwitchDisabled(true);
|
||||
const body = { ...item, notification_methods: { email: !notificationEnabled } };
|
||||
setNotificationEnabled(prevState => !prevState);
|
||||
return fetch(`/api/account1/watchlist/${ item.id }`, { method: 'PUT', body });
|
||||
return fetch(`/node-api/account/watchlist/${ item.id }`, { method: 'PUT', body });
|
||||
}, {
|
||||
onError: () => {
|
||||
showToast();
|
||||
|
||||